From 55634c987a1b08f8a8c9ac993ce5dada67ee25ec Mon Sep 17 00:00:00 2001 From: Jonathan Schneider Date: Sun, 24 Sep 2023 15:37:56 -0400 Subject: [PATCH] GroovyParser handles Jenkinsfile, and fix inside parentheses of ternary/binary/literal --- .../groovy/GroovyParserVisitor.java | 225 +++++++++--------- .../openrewrite/groovy/GroovyParserTest.java | 122 ++++++++++ .../openrewrite/groovy/tree/BinaryTest.java | 13 + .../openrewrite/groovy/tree/LiteralTest.java | 9 + .../groovy/tree/ParenthesisTest.java | 56 ----- .../openrewrite/groovy/tree/TernaryTest.java | 19 +- 6 files changed, 269 insertions(+), 175 deletions(-) create mode 100644 rewrite-groovy/src/test/java/org/openrewrite/groovy/GroovyParserTest.java delete mode 100644 rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/ParenthesisTest.java diff --git a/rewrite-groovy/src/main/java/org/openrewrite/groovy/GroovyParserVisitor.java b/rewrite-groovy/src/main/java/org/openrewrite/groovy/GroovyParserVisitor.java index 8b85a276346..2e6b59f5975 100644 --- a/rewrite-groovy/src/main/java/org/openrewrite/groovy/GroovyParserVisitor.java +++ b/rewrite-groovy/src/main/java/org/openrewrite/groovy/GroovyParserVisitor.java @@ -35,16 +35,17 @@ import org.openrewrite.internal.lang.Nullable; import org.openrewrite.java.internal.JavaTypeCache; import org.openrewrite.java.marker.ImplicitReturn; +import org.openrewrite.java.marker.Semicolon; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.Statement; import org.openrewrite.java.tree.*; -import org.openrewrite.java.marker.Semicolon; import org.openrewrite.marker.Markers; import java.math.BigDecimal; import java.nio.charset.Charset; import java.nio.file.Path; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -69,7 +70,6 @@ public class GroovyParserVisitor { private final Charset charset; private final boolean charsetBomMarked; private final GroovyTypeMapping typeMapping; - private final ExecutionContext ctx; private int cursor = 0; @@ -83,6 +83,7 @@ public class GroovyParserVisitor { */ private int columnOffset; + @SuppressWarnings("unused") public GroovyParserVisitor(Path sourcePath, @Nullable FileAttributes fileAttributes, EncodingDetectingInputStream source, JavaTypeCache typeCache, ExecutionContext ctx) { this.sourcePath = sourcePath; this.fileAttributes = fileAttributes; @@ -90,7 +91,6 @@ public GroovyParserVisitor(Path sourcePath, @Nullable FileAttributes fileAttribu this.charset = source.getCharset(); this.charsetBomMarked = source.isCharsetBomMarked(); this.typeMapping = new GroovyTypeMapping(typeCache); - this.ctx = ctx; } public G.CompilationUnit visit(SourceUnit unit, ModuleNode ast) throws GroovyParsingException { @@ -581,10 +581,21 @@ private List> visitRightPadded(ASTNode[] nodes, @Nullable St return ts; } - private void visitParenthesized(ASTNode node, Space fmt) { - skip("("); - queue.add(new J.Parentheses(randomId(), fmt, Markers.EMPTY, - convert(node, t -> sourceBefore(")")))); + private Expression insideParentheses(ASTNode node, Function parenthesizedTree) { + AtomicInteger insideParenthesesLevel = node.getNodeMetaData("_INSIDE_PARENTHESES_LEVEL"); + if (insideParenthesesLevel != null) { + Stack openingParens = new Stack<>(); + for (int i = 0; i < insideParenthesesLevel.get(); i++) { + openingParens.push(sourceBefore("(")); + } + Expression parenthesized = parenthesizedTree.apply(whitespace()); + for (int i = 0; i < insideParenthesesLevel.get(); i++) { + parenthesized = new J.Parentheses<>(randomId(), openingParens.pop(), Markers.EMPTY, + padRight(parenthesized, sourceBefore(")"))); + } + return parenthesized; + } + return parenthesizedTree.apply(whitespace()); } @Override @@ -690,19 +701,15 @@ public void visitClassExpression(ClassExpression clazz) { @Override public void visitBinaryExpression(BinaryExpression binary) { - Space fmt = whitespace(); - - if (source.charAt(cursor) == '(') { - visitParenthesized(binary, fmt); - } else { + queue.add(insideParentheses(binary, fmt -> { Expression left = visit(binary.getLeftExpression()); - Space opPrefix = whitespace(); boolean assignment = false; boolean instanceOf = false; J.AssignmentOperation.Type assignOp = null; J.Binary.Type binaryOp = null; G.Binary.Type gBinaryOp = null; + switch (binary.getOperation().getText()) { case "+": binaryOp = J.Binary.Type.Addition; @@ -818,31 +825,32 @@ public void visitBinaryExpression(BinaryExpression binary) { Expression right = visit(binary.getRightExpression()); if (assignment) { - queue.add(new J.Assignment(randomId(), fmt, Markers.EMPTY, + return new J.Assignment(randomId(), fmt, Markers.EMPTY, left, JLeftPadded.build(right).withBefore(opPrefix), - typeMapping.type(binary.getType()))); + typeMapping.type(binary.getType())); } else if (instanceOf) { - queue.add(new J.InstanceOf(randomId(), fmt, Markers.EMPTY, + return new J.InstanceOf(randomId(), fmt, Markers.EMPTY, JRightPadded.build(left).withAfter(opPrefix), right, null, - typeMapping.type(binary.getType()))); + typeMapping.type(binary.getType())); } else if (assignOp != null) { - queue.add(new J.AssignmentOperation(randomId(), fmt, Markers.EMPTY, + return new J.AssignmentOperation(randomId(), fmt, Markers.EMPTY, left, JLeftPadded.build(assignOp).withBefore(opPrefix), - right, typeMapping.type(binary.getType()))); + right, typeMapping.type(binary.getType())); } else if (binaryOp != null) { - queue.add(new J.Binary(randomId(), fmt, Markers.EMPTY, + return new J.Binary(randomId(), fmt, Markers.EMPTY, left, JLeftPadded.build(binaryOp).withBefore(opPrefix), - right, typeMapping.type(binary.getType()))); + right, typeMapping.type(binary.getType())); } else if (gBinaryOp != null) { Space after = EMPTY; if (gBinaryOp == G.Binary.Type.Access) { after = sourceBefore("]"); } - queue.add(new G.Binary(randomId(), fmt, Markers.EMPTY, + return new G.Binary(randomId(), fmt, Markers.EMPTY, left, JLeftPadded.build(gBinaryOp).withBefore(opPrefix), - right, after, typeMapping.type(binary.getType()))); + right, after, typeMapping.type(binary.getType())); } - } + throw new IllegalStateException("Unknown binary expression " + binary.getClass().getSimpleName()); + })); } @Override @@ -950,7 +958,7 @@ public void visitCaseStatement(CaseStatement statement) { null, JContainer.build(singletonList(JRightPadded.build(visit(statement.getExpression())))), JContainer.build(sourceBefore(":"), - convertStatements(((BlockStatement) statement.getCode()).getStatements(), t -> Space.EMPTY), Markers.EMPTY), + convertStatements(((BlockStatement) statement.getCode()).getStatements(), t -> Space.EMPTY), Markers.EMPTY), null ) ); @@ -996,7 +1004,7 @@ public void visitClosureExpression(ClosureExpression expression) { Space prefix = whitespace(); LambdaStyle ls = new LambdaStyle(randomId(), expression instanceof LambdaExpression, true); boolean parenthesized = false; - if(source.charAt(cursor) == '(') { + if (source.charAt(cursor) == '(') { parenthesized = true; cursor += 1; // skip '(' } else if (source.charAt(cursor) == '{') { @@ -1031,12 +1039,12 @@ null, emptyList(), } } else { Space argPrefix = EMPTY; - if(parenthesized) { + if (parenthesized) { argPrefix = whitespace(); } paramExprs = singletonList(JRightPadded.build(new J.Empty(randomId(), argPrefix, Markers.EMPTY))); } - if(parenthesized) { + if (parenthesized) { cursor += 1; } J.Lambda.Parameters params = new J.Lambda.Parameters(randomId(), EMPTY, Markers.EMPTY, parenthesized, paramExprs); @@ -1054,7 +1062,7 @@ null, emptyList(), arrowPrefix, body, closureType)); - if(cursor < source.length() && source.charAt(cursor) == '}') { + if (cursor < source.length() && source.charAt(cursor) == '}') { cursor++; } } @@ -1074,83 +1082,78 @@ public void visitClosureListExpression(ClosureListExpression closureListExpressi @Override public void visitConstantExpression(ConstantExpression expression) { - Space prefix = whitespace(); - - JavaType.Primitive jType; - // The unaryPlus is not included in the expression and must be handled through the source. - String text = expression.getText(); - Object value = expression.getValue(); - ClassNode type = expression.getType(); - if (type == ClassHelper.BigDecimal_TYPE) { - // TODO: Proper support for BigDecimal literals - jType = JavaType.Primitive.Double; - value = ((BigDecimal) value).doubleValue(); - } else if (type == ClassHelper.boolean_TYPE) { - jType = JavaType.Primitive.Boolean; - } else if (type == ClassHelper.byte_TYPE) { - jType = JavaType.Primitive.Byte; - } else if (type == ClassHelper.char_TYPE) { - jType = JavaType.Primitive.Char; - } else if (type == ClassHelper.double_TYPE || "java.lang.Double".equals(type.getName())) { - jType = JavaType.Primitive.Double; - if (expression.getNodeMetaData().get("_FLOATING_POINT_LITERAL_TEXT") instanceof String) { - text = (String) expression.getNodeMetaData().get("_FLOATING_POINT_LITERAL_TEXT"); - } - } else if (type == ClassHelper.float_TYPE || "java.lang.Float".equals(type.getName())) { - jType = JavaType.Primitive.Float; - if (expression.getNodeMetaData().get("_FLOATING_POINT_LITERAL_TEXT") instanceof String) { - text = (String) expression.getNodeMetaData().get("_FLOATING_POINT_LITERAL_TEXT"); - } - } else if (type == ClassHelper.int_TYPE || "java.lang.Integer".equals(type.getName())) { - jType = JavaType.Primitive.Int; - if (expression.getNodeMetaData().get("_INTEGER_LITERAL_TEXT") instanceof String) { - text = (String) expression.getNodeMetaData().get("_INTEGER_LITERAL_TEXT"); - } - } else if (type == ClassHelper.long_TYPE || "java.lang.Long".equals(type.getName())) { - if (expression.getNodeMetaData().get("_INTEGER_LITERAL_TEXT") instanceof String) { - text = (String) expression.getNodeMetaData().get("_INTEGER_LITERAL_TEXT"); - } - jType = JavaType.Primitive.Long; - } else if (type == ClassHelper.short_TYPE || "java.lang.Short".equals(type.getName())) { - jType = JavaType.Primitive.Short; - } else if (type == ClassHelper.STRING_TYPE) { - jType = JavaType.Primitive.String; - // String literals value returned by getValue()/getText() has already processed sequences like "\\" -> "\" - int length = sourceLengthOfNext(expression); - text = source.substring(cursor, cursor + length); - int delimiterLength = 0; - if (text.startsWith("$/")) { - delimiterLength = 2; - } else if (text.startsWith("\"\"\"") || text.startsWith("'''")) { - delimiterLength = 3; - } else if (text.startsWith("/") || text.startsWith("\"") || text.startsWith("'")) { - delimiterLength = 1; - } - value = text.substring(delimiterLength, text.length() - delimiterLength); - } else if (expression.isNullExpression()) { - if(source.startsWith("null", cursor)) { - text = "null"; + queue.add(insideParentheses(expression, fmt -> { + JavaType.Primitive jType; + // The unaryPlus is not included in the expression and must be handled through the source. + String text = expression.getText(); + Object value = expression.getValue(); + ClassNode type = expression.getType(); + if (type == ClassHelper.BigDecimal_TYPE) { + // TODO: Proper support for BigDecimal literals + jType = JavaType.Primitive.Double; + value = ((BigDecimal) value).doubleValue(); + } else if (type == ClassHelper.boolean_TYPE) { + jType = JavaType.Primitive.Boolean; + } else if (type == ClassHelper.byte_TYPE) { + jType = JavaType.Primitive.Byte; + } else if (type == ClassHelper.char_TYPE) { + jType = JavaType.Primitive.Char; + } else if (type == ClassHelper.double_TYPE || "java.lang.Double".equals(type.getName())) { + jType = JavaType.Primitive.Double; + if (expression.getNodeMetaData().get("_FLOATING_POINT_LITERAL_TEXT") instanceof String) { + text = (String) expression.getNodeMetaData().get("_FLOATING_POINT_LITERAL_TEXT"); + } + } else if (type == ClassHelper.float_TYPE || "java.lang.Float".equals(type.getName())) { + jType = JavaType.Primitive.Float; + if (expression.getNodeMetaData().get("_FLOATING_POINT_LITERAL_TEXT") instanceof String) { + text = (String) expression.getNodeMetaData().get("_FLOATING_POINT_LITERAL_TEXT"); + } + } else if (type == ClassHelper.int_TYPE || "java.lang.Integer".equals(type.getName())) { + jType = JavaType.Primitive.Int; + if (expression.getNodeMetaData().get("_INTEGER_LITERAL_TEXT") instanceof String) { + text = (String) expression.getNodeMetaData().get("_INTEGER_LITERAL_TEXT"); + } + } else if (type == ClassHelper.long_TYPE || "java.lang.Long".equals(type.getName())) { + if (expression.getNodeMetaData().get("_INTEGER_LITERAL_TEXT") instanceof String) { + text = (String) expression.getNodeMetaData().get("_INTEGER_LITERAL_TEXT"); + } + jType = JavaType.Primitive.Long; + } else if (type == ClassHelper.short_TYPE || "java.lang.Short".equals(type.getName())) { + jType = JavaType.Primitive.Short; + } else if (type == ClassHelper.STRING_TYPE) { + jType = JavaType.Primitive.String; + // String literals value returned by getValue()/getText() has already processed sequences like "\\" -> "\" + int length = sourceLengthOfNext(expression); + text = source.substring(cursor, cursor + length); + int delimiterLength = 0; + if (text.startsWith("$/")) { + delimiterLength = 2; + } else if (text.startsWith("\"\"\"") || text.startsWith("'''")) { + delimiterLength = 3; + } else if (text.startsWith("/") || text.startsWith("\"") || text.startsWith("'")) { + delimiterLength = 1; + } + value = text.substring(delimiterLength, text.length() - delimiterLength); + } else if (expression.isNullExpression()) { + if (source.startsWith("null", cursor)) { + text = "null"; + } else { + text = ""; + } + jType = JavaType.Primitive.Null; } else { - text = ""; + throw new IllegalStateException("Unexpected constant type " + type); } - jType = JavaType.Primitive.Null; - } else { - ctx.getOnError().accept(new IllegalStateException("Unexpected constant type " + type)); - return; - } - if (source.charAt(cursor) == '(') { - visitParenthesized(expression, prefix); - } else { if (source.charAt(cursor) == '+' && !text.startsWith("+")) { // A unaryPlus operator is implied on numerics and needs to be manually detected / added via the source. text = "+" + text; } cursor += text.length(); - queue.add(new J.Literal(randomId(), prefix, Markers.EMPTY, value, text, - null, jType)); - } + return new J.Literal(randomId(), fmt, Markers.EMPTY, value, text, + null, jType); + })); } @Override @@ -1374,8 +1377,8 @@ public void visitGStringExpression(GStringExpression gstring) { } else { columnOffset--; } - strings.add(new G.GString.Value(randomId(), Markers.EMPTY, visit(e), inCurlies ? sourceBefore("}") : Space.EMPTY, inCurlies)); - if(!inCurlies) { + strings.add(new G.GString.Value(randomId(), Markers.EMPTY, visit(e), inCurlies ? sourceBefore("}") : Space.EMPTY, inCurlies)); + if (!inCurlies) { columnOffset++; } } else if (e instanceof ConstantExpression) { @@ -1704,7 +1707,7 @@ public void visitSwitch(SwitchStatement statement) { randomId(), sourceBefore("{"), Markers.EMPTY, JRightPadded.build(false), ListUtils.concat( - convertAll(statement.getCaseStatements(), t -> Space.EMPTY, t -> Space.EMPTY), + convertAll(statement.getCaseStatements(), t -> Space.EMPTY, t -> Space.EMPTY), statement.getDefaultStatement().isEmpty() ? null : JRightPadded.build(visitDefaultCaseStatement((BlockStatement) statement.getDefaultStatement())) ), sourceBefore("}")))); @@ -1721,17 +1724,11 @@ public void visitSynchronizedStatement(SynchronizedStatement statement) { @Override public void visitTernaryExpression(TernaryExpression ternary) { - Space prefix = whitespace(); - - if (source.charAt(cursor) == '(') { - visitParenthesized(ternary, prefix); - } else { - queue.add(new J.Ternary(randomId(), prefix, Markers.EMPTY, - visit(ternary.getBooleanExpression()), - padLeft(sourceBefore("?"), visit(ternary.getTrueExpression())), - padLeft(sourceBefore(":"), visit(ternary.getFalseExpression())), - typeMapping.type(ternary.getType()))); - } + queue.add(insideParentheses(ternary, fmt -> new J.Ternary(randomId(), fmt, Markers.EMPTY, + visit(ternary.getBooleanExpression()), + padLeft(sourceBefore("?"), visit(ternary.getTrueExpression())), + padLeft(sourceBefore(":"), visit(ternary.getFalseExpression())), + typeMapping.type(ternary.getType())))); } @Override @@ -2136,9 +2133,9 @@ private T typeTree(@Nullable ClassNode classNo assert expr != null; if (classNode != null) { - if(classNode.isUsingGenerics() && !classNode.isGenericsPlaceHolder()) { + if (classNode.isUsingGenerics() && !classNode.isGenericsPlaceHolder()) { expr = new J.ParameterizedType(randomId(), EMPTY, Markers.EMPTY, (NameTree) expr, visitTypeParameterizations(classNode.getGenericsTypes()), typeMapping.type(classNode)); - } else if(classNode.isArray()) { + } else if (classNode.isArray()) { expr = new J.ArrayType(randomId(), EMPTY, Markers.EMPTY, (TypeTree) expr, arrayDimensionsFrom(classNode)); } } @@ -2147,7 +2144,7 @@ private T typeTree(@Nullable ClassNode classNo private List> arrayDimensionsFrom(ClassNode classNode) { List> result = new ArrayList<>(); - while(classNode != null && classNode.isArray()) { + while (classNode != null && classNode.isArray()) { classNode = classNode.getComponentType(); result.add(JRightPadded.build(sourceBefore("[")).withAfter(sourceBefore("]"))); } diff --git a/rewrite-groovy/src/test/java/org/openrewrite/groovy/GroovyParserTest.java b/rewrite-groovy/src/test/java/org/openrewrite/groovy/GroovyParserTest.java new file mode 100644 index 00000000000..f86c2ba3e34 --- /dev/null +++ b/rewrite-groovy/src/test/java/org/openrewrite/groovy/GroovyParserTest.java @@ -0,0 +1,122 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.groovy; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.groovy.Assertions.groovy; + +public class GroovyParserTest implements RewriteTest { + + @Test + void jenkinsfile() { + // the Jenkinsfile from spring-projects/spring-data-release + rewriteRun( + groovy( + """ + def p = [:] + node { + checkout scm + p = readProperties interpolate: true, file: 'ci/release.properties' + } + pipeline { + agent none + triggers { + pollSCM 'H/10 * * * *' + } + options { + disableConcurrentBuilds() + buildDiscarder(logRotator(numToKeepStr: '14')) + } + stages { + stage('Build the Spring Data release tools container') { + when { + anyOf { + changeset 'ci/Dockerfile' + changeset 'ci/java-tools.properties' + } + } + agent { + label 'data' + } + steps { + script { + def image = docker.build("springci/spring-data-release-tools:0.12", "ci") + docker.withRegistry('', 'hub.docker.com-springbuildmaster') { + image.push() + } + } + } + } + stage('Ship It') { + when { + branch 'release' + } + agent { + docker { + image 'springci/spring-data-release-tools:0.12' + } + } + options { timeout(time: 4, unit: 'HOURS') } + environment { + GITHUB = credentials('3a20bcaa-d8ad-48e3-901d-9fbc941376ee') + GITHUB_TOKEN = credentials('7b3ebbea-7001-479b-8578-b8c464dab973') + REPO_SPRING_IO = credentials('repo_spring_io-jenkins-release-token') + ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c') + STAGING_PROFILE_ID = credentials('spring-data-release-deployment-maven-central-staging-profile-id') + MAVEN_SIGNING_KEY = credentials('spring-gpg-private-key') + MAVEN_SIGNING_KEY_PASSWORD = credentials('spring-gpg-passphrase') + GIT_SIGNING_KEY = credentials('spring-gpg-github-private-key-jenkins') + GIT_SIGNING_KEY_PASSWORD = credentials('spring-gpg-github-passphrase-jenkins') + SONATYPE = credentials('oss-login') + } + steps { + script { + sh "ci/build-spring-data-release-cli.bash" + sh "ci/build-and-distribute.bash ${p['release.version']}" + slackSend( + color: (currentBuild.currentResult == 'SUCCESS') ? 'good' : 'danger', + channel: '#spring-data-dev', + message: (currentBuild.currentResult == 'SUCCESS') + ? "`${env.BUILD_URL}` - Build and distribute ${p['release.version']} passed! Release the build (if needed)." + : "`${env.BUILD_URL}` - Build and distribute ${p['release.version']} failed!") + } + } + } + } + post { + changed { + script { + slackSend( + color: (currentBuild.currentResult == 'SUCCESS') ? 'good' : 'danger', + channel: '#spring-data-dev', + message: "${currentBuild.fullDisplayName} - `${currentBuild.currentResult}`\\n${env.BUILD_URL}") + emailext( + subject: "[${currentBuild.fullDisplayName}] ${currentBuild.currentResult}", + mimeType: 'text/html', + recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']], + body: "${currentBuild.fullDisplayName} is reported as ${currentBuild.currentResult}") + } + } + } + } + """, + spec -> spec.path("Jenkinsfile") + ) + ); + } +} diff --git a/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/BinaryTest.java b/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/BinaryTest.java index bc10ffe9a34..05d62e5b00f 100644 --- a/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/BinaryTest.java +++ b/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/BinaryTest.java @@ -24,6 +24,19 @@ @SuppressWarnings({"GroovyUnusedAssignment", "GrUnnecessarySemicolon", "UnnecessaryQualifiedReference"}) class BinaryTest implements RewriteTest { + @SuppressWarnings("GroovyConstantConditional") + @Test + void insideParentheses() { + rewriteRun( + groovy("(1 + 1)"), + groovy("((1 + 1))"), + + // NOT inside parentheses, but verifies the parser's + // test for "inside parentheses" condition + groovy("(1) + 1") + ); + } + @Test void equals() { rewriteRun( diff --git a/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/LiteralTest.java b/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/LiteralTest.java index bc7f16319f6..f5dc61dd4dd 100644 --- a/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/LiteralTest.java +++ b/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/LiteralTest.java @@ -30,6 +30,15 @@ @SuppressWarnings("GroovyUnusedAssignment") class LiteralTest implements RewriteTest { + @SuppressWarnings("GroovyConstantConditional") + @Test + void insideParentheses() { + rewriteRun( + groovy("(1)"), + groovy("((1))") + ); + } + @Test void string() { rewriteRun( diff --git a/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/ParenthesisTest.java b/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/ParenthesisTest.java deleted file mode 100644 index 7c764e7b957..00000000000 --- a/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/ParenthesisTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.openrewrite.groovy.tree; - -import org.junit.jupiter.api.Test; -import org.openrewrite.test.RewriteTest; - -import static org.openrewrite.groovy.Assertions.groovy; - -class ParenthesisTest implements RewriteTest { - @Test - void parentheses() { - rewriteRun( - groovy( - """ - int n = (0) - """ - ) - ); - } - - @Test - void binary() { - rewriteRun( - groovy( - """ - int n = (1 + 1) - """ - ) - ); - } - - @Test - void ternary() { - rewriteRun( - groovy( - """ - boolean b = (1 == 2 ? true : false) - """ - ) - ); - } -} diff --git a/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/TernaryTest.java b/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/TernaryTest.java index e7c15d882ff..a5f3fb26683 100644 --- a/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/TernaryTest.java +++ b/rewrite-groovy/src/test/java/org/openrewrite/groovy/tree/TernaryTest.java @@ -22,14 +22,23 @@ class TernaryTest implements RewriteTest { + @SuppressWarnings("GroovyConstantConditional") + @Test + void insideParentheses() { + rewriteRun( + groovy("(true ? 1 : 2)"), + groovy("((true ? 1 : 2))"), + + // NOT inside parentheses, but verifies the parser's + // test for "inside parentheses" condition + groovy("(true) ? 1 : 2") + ); + } + @Test void ternary() { rewriteRun( - groovy( - """ - 1 == 2 ? /no it isn't/ : /yes it is/ - """ - ) + groovy("1 == 2 ? /no it isn't/ : /yes it is/") ); }