You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2023/01/10 23:05:15 UTC
[groovy] branch master updated: visit annotation(s) of multiple-variable declaration
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 29de7e506e visit annotation(s) of multiple-variable declaration
29de7e506e is described below
commit 29de7e506ec44c5a899e2c98aa536eb3ae5360ff
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Jan 10 17:04:30 2023 -0600
visit annotation(s) of multiple-variable declaration
---
.../apache/groovy/parser/antlr4/AstBuilder.java | 154 ++++-------
.../codehaus/groovy/classgen/ExtendedVerifier.java | 12 +-
.../groovy/parser/antlr4/util/AstDumper.groovy | 291 +++++++++++----------
.../console/ui/AstNodeToScriptAdapter.groovy | 191 ++++++--------
.../console/ui/AstNodeToScriptAdapterTest.groovy | 6 +-
.../console/ui/ScriptToTreeNodeAdapterTest.groovy | 2 +-
6 files changed, 307 insertions(+), 349 deletions(-)
diff --git a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index d35969cc80..33e66eb473 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -35,7 +35,6 @@ import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
-import org.apache.groovy.parser.antlr4.GroovyParser.*;
import org.apache.groovy.parser.antlr4.internal.DescriptiveErrorStrategy;
import org.apache.groovy.parser.antlr4.internal.atnmanager.AtnManager;
import org.apache.groovy.parser.antlr4.util.StringUtils;
@@ -132,6 +131,7 @@ import org.objectweb.asm.Opcodes;
import java.io.BufferedReader;
import java.io.IOException;
+import java.lang.annotation.Annotation;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
@@ -148,34 +148,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static groovy.lang.Tuple.tuple;
-import static org.apache.groovy.parser.antlr4.GroovyParser.ADD;
-import static org.apache.groovy.parser.antlr4.GroovyParser.ARROW;
-import static org.apache.groovy.parser.antlr4.GroovyParser.AS;
-import static org.apache.groovy.parser.antlr4.GroovyParser.CASE;
-import static org.apache.groovy.parser.antlr4.GroovyParser.DEC;
-import static org.apache.groovy.parser.antlr4.GroovyParser.DEF;
-import static org.apache.groovy.parser.antlr4.GroovyParser.DEFAULT;
-import static org.apache.groovy.parser.antlr4.GroovyParser.FINAL;
-import static org.apache.groovy.parser.antlr4.GroovyParser.GE;
-import static org.apache.groovy.parser.antlr4.GroovyParser.GT;
-import static org.apache.groovy.parser.antlr4.GroovyParser.IN;
-import static org.apache.groovy.parser.antlr4.GroovyParser.INC;
-import static org.apache.groovy.parser.antlr4.GroovyParser.INSTANCEOF;
-import static org.apache.groovy.parser.antlr4.GroovyParser.LE;
-import static org.apache.groovy.parser.antlr4.GroovyParser.LT;
-import static org.apache.groovy.parser.antlr4.GroovyParser.NON_SEALED;
-import static org.apache.groovy.parser.antlr4.GroovyParser.NOT_IN;
-import static org.apache.groovy.parser.antlr4.GroovyParser.NOT_INSTANCEOF;
-import static org.apache.groovy.parser.antlr4.GroovyParser.PRIVATE;
-import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_FULL;
-import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_LEFT;
-import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_RIGHT;
-import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_INCLUSIVE;
-import static org.apache.groovy.parser.antlr4.GroovyParser.SAFE_INDEX;
-import static org.apache.groovy.parser.antlr4.GroovyParser.SEALED;
-import static org.apache.groovy.parser.antlr4.GroovyParser.STATIC;
-import static org.apache.groovy.parser.antlr4.GroovyParser.SUB;
-import static org.apache.groovy.parser.antlr4.GroovyParser.VAR;
+import static org.apache.groovy.parser.antlr4.GroovyParser.*;
import static org.apache.groovy.parser.antlr4.util.PositionConfigureUtils.configureAST;
import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
@@ -367,7 +340,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
if (hasStatic) {
if (hasStar) { // e.g. import static java.lang.Math.*
String qualifiedName = this.visitQualifiedName(ctx.qualifiedName());
- ClassNode type = ClassHelper.make(qualifiedName);
+ ClassNode type = makeClassNode(qualifiedName);
configureAST(type, ctx);
moduleNode.addStaticStarImport(type.getText(), type, annotationNodeList);
@@ -378,7 +351,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
int identifierListSize = identifierList.size();
String name = identifierList.get(identifierListSize - 1).getText();
ClassNode classNode =
- ClassHelper.make(
+ makeClassNode(
identifierList.stream()
.limit(identifierListSize - 1)
.map(ParseTree::getText)
@@ -402,7 +375,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
} else { // e.g. import java.util.Map
String qualifiedName = this.visitQualifiedName(ctx.qualifiedName());
String name = last(ctx.qualifiedName().qualifiedNameElement()).getText();
- ClassNode classNode = ClassHelper.make(qualifiedName);
+ ClassNode classNode = makeClassNode(qualifiedName);
String alias = hasAlias
? ctx.alias.getText()
: name;
@@ -417,6 +390,18 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
return configureAST(importNode, ctx);
}
+ private static AnnotationNode makeAnnotationNode(final Class<? extends Annotation> type) {
+ AnnotationNode node = new AnnotationNode(ClassHelper.make(type));
+ // TODO: source offsets
+ return node;
+ }
+
+ private static ClassNode makeClassNode(final String name) {
+ ClassNode node = ClassHelper.make(name);
+ // TODO: shared instances
+ return node;
+ }
+
// statement { -------------------------------------------------------------
@Override
@@ -1020,8 +1005,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
}
private int switchExpressionVariableSeq;
- @Override
- @SuppressWarnings("unchecked")
+ @Override @SuppressWarnings("unchecked")
public Tuple3<List<Statement>, Boolean, Boolean> visitSwitchBlockStatementExpressionGroup(SwitchBlockStatementExpressionGroupContext ctx) {
int labelCnt = ctx.switchExpressionLabel().size();
List<Token> firstLabelHolder = new ArrayList<>(1);
@@ -1212,7 +1196,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
public ClassNode visitClassDeclaration(final ClassDeclarationContext ctx) {
String packageName = Optional.ofNullable(moduleNode.getPackageName()).orElse("");
String className = this.visitIdentifier(ctx.identifier());
- if (VAR_STR.equals(className)) {
+ if ("var".equals(className)) {
throw createParsingFailedException("var cannot be used for type declarations", ctx.identifier());
}
@@ -1333,7 +1317,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
boolean isInterfaceWithDefaultMethods = (isInterface && this.containsDefaultMethods(ctx));
if (isSealed) {
- AnnotationNode sealedAnnotationNode = new AnnotationNode(ClassHelper.makeCached(Sealed.class));
+ AnnotationNode sealedAnnotationNode = makeAnnotationNode(Sealed.class);
if (asBoolean(ctx.ps)) {
ListExpression permittedSubclassesListExpression =
listX(Arrays.stream(this.visitTypeList(ctx.ps))
@@ -1345,15 +1329,15 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
}
classNode.addAnnotation(sealedAnnotationNode);
} else if (isNonSealed) {
- classNode.addAnnotation(new AnnotationNode(ClassHelper.makeCached(NonSealed.class)));
+ classNode.addAnnotation(makeAnnotationNode(NonSealed.class));
}
if (isInterfaceWithDefaultMethods || asBoolean(ctx.TRAIT())) {
- classNode.addAnnotation(new AnnotationNode(ClassHelper.makeCached(Trait.class)));
+ classNode.addAnnotation(makeAnnotationNode(Trait.class));
}
classNode.addAnnotations(modifierManager.getAnnotations());
if (isRecord && classNode.getAnnotations().stream().noneMatch(a ->
a.getClassNode().getName().equals(RECORD_TYPE_NAME))) {
- classNode.addAnnotation(new AnnotationNode(ClassHelper.makeWithoutCaching(RECORD_TYPE_NAME)));
+ classNode.addAnnotation(new AnnotationNode(ClassHelper.makeWithoutCaching(RECORD_TYPE_NAME))); // TODO: makeAnnotationNode(RecordType.class)
}
if (isInterfaceWithDefaultMethods) {
@@ -1424,7 +1408,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
return classNode;
}
- private void transformRecordHeaderToProperties(ClassDeclarationContext ctx, ClassNode classNode) {
+ private void transformRecordHeaderToProperties(final ClassDeclarationContext ctx, final ClassNode classNode) {
Parameter[] parameters = this.visitFormalParameters(ctx.formalParameters());
classNode.putNodeMetaData(RECORD_HEADER, parameters);
@@ -1433,9 +1417,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
Parameter parameter = parameters[i];
FormalParameterContext parameterCtx = parameter.getNodeMetaData(PARAMETER_CONTEXT);
ModifierManager parameterModifierManager = parameter.getNodeMetaData(PARAMETER_MODIFIER_MANAGER);
- ClassNode originType = parameter.getOriginType();
- PropertyNode propertyNode = declareProperty(parameterCtx, parameterModifierManager, originType,
- classNode, i, parameter, parameter.getName(), parameter.getModifiers(), parameter.getInitialExpression());
+ PropertyNode propertyNode = declareProperty(parameterCtx, parameterModifierManager, parameter.getType(), classNode, i,
+ parameter, parameter.getName(), parameter.getModifiers() | Opcodes.ACC_FINAL, parameter.getInitialExpression());
propertyNode.getField().putNodeMetaData(IS_RECORD_GENERATED, Boolean.TRUE);
}
}
@@ -1598,7 +1581,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
this.visitMemberDeclaration(ctx.memberDeclaration());
} else if (asBoolean(ctx.block())) {
Statement statement = this.visitBlock(ctx.block());
-
if (asBoolean(ctx.STATIC())) { // e.g. static { }
classNode.addStaticInitializerStatements(Collections.singletonList(statement), false);
} else { // e.g. { }
@@ -1749,14 +1731,11 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
}
});
- ClassNode tupleConstructor = ClassHelper.makeCached(TupleConstructor.class);
- List<AnnotationNode> annos = classNode.getAnnotations(tupleConstructor);
+ List<AnnotationNode> annos = classNode.getAnnotations(ClassHelper.make(TupleConstructor.class));
+ AnnotationNode tupleConstructor = annos.isEmpty() ? makeAnnotationNode(TupleConstructor.class) : annos.get(0);
+ tupleConstructor.setMember("pre", closureX(code));
if (annos.isEmpty()) {
- AnnotationNode tcAnnotation = new AnnotationNode(tupleConstructor);
- tcAnnotation.setMember("pre", closureX(code));
- classNode.addAnnotation(tcAnnotation);
- } else {
- annos.get(0).setMember("pre", closureX(code));
+ classNode.addAnnotation(tupleConstructor);
}
return null;
@@ -1987,31 +1966,17 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
}
private DeclarationListStatement createMultiAssignmentDeclarationListStatement(final VariableDeclarationContext ctx, final ModifierManager modifierManager) {
- /*
- if (!modifierManager.contains(DEF)) {
- throw createParsingFailedException("keyword def is required to declare tuple, e.g. def (int a, int b) = [1, 2]", ctx);
- }
- */
+ List<Expression> elist = this.visitTypeNamePairs(ctx.typeNamePairs());
+ for (Expression e : elist)
+ modifierManager.processVariableExpression((VariableExpression) e);
- return configureAST(
- new DeclarationListStatement(
- configureAST(
- modifierManager.attachAnnotations(
- new DeclarationExpression(
- new ArgumentListExpression(
- this.visitTypeNamePairs(ctx.typeNamePairs()).stream()
- .peek(e -> modifierManager.processVariableExpression((VariableExpression) e))
- .collect(Collectors.toList())
- ),
- this.createGroovyTokenByType(ctx.ASSIGN().getSymbol(), Types.ASSIGN),
- this.visitVariableInitializer(ctx.variableInitializer())
- )
- ),
- ctx
- )
- ),
- ctx
- );
+ DeclarationExpression de = new DeclarationExpression(
+ configureAST(new TupleExpression(elist), ctx.typeNamePairs()),
+ createGroovyTokenByType(ctx.ASSIGN().getSymbol(), Types.ASSIGN),
+ visitVariableInitializer(ctx.variableInitializer()) );
+
+ configureAST(modifierManager.attachAnnotations(de), ctx);
+ return configureAST(new DeclarationListStatement(de), ctx);
}
@Override
@@ -2037,21 +2002,17 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
return createFieldDeclarationListStatement(ctx, modifierManager, variableType, declarationExpressionList, classNode);
}
- declarationExpressionList.forEach(e -> {
- VariableExpression variableExpression = (VariableExpression) e.getLeftExpression();
-
- modifierManager.processVariableExpression(variableExpression);
- modifierManager.attachAnnotations(e);
- });
-
int size = declarationExpressionList.size();
if (size > 0) {
- DeclarationExpression declarationExpression = declarationExpressionList.get(0);
+ for (DeclarationExpression e : declarationExpressionList) {
+ modifierManager.processVariableExpression(e.getVariableExpression());
+ modifierManager.attachAnnotations(e);
+ }
- if (1 == size) {
+ DeclarationExpression declarationExpression = declarationExpressionList.get(0);
+ if (size == 1) {
configureAST(declarationExpression, ctx);
- } else {
- // Tweak start of first declaration
+ } else { // adjust start of first declaration
declarationExpression.setLineNumber(ctx.getStart().getLine());
declarationExpression.setColumnNumber(ctx.getStart().getCharPositionInLine() + 1);
}
@@ -2125,7 +2086,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
fieldNode.setInitialValueExpression(initialValue);
}
modifierManager.attachAnnotations(propertyNode);
- propertyNode.addAnnotation(new AnnotationNode(ClassHelper.make(CompileStatic.class)));
+ propertyNode.addAnnotation(makeAnnotationNode(CompileStatic.class));
// expand properties early so AST transforms will be handled correctly
PropertyExpander expander = new PropertyExpander(classNode);
expander.visitProperty(propertyNode);
@@ -2170,7 +2131,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
classNode.getFields().remove(propertyNode.getField());
fieldNode = new FieldNode(fieldName, modifiers, variableType, classNode.redirect(), propertyNode.hasInitialExpression() ? propertyNode.getInitialExpression() : initialValue);
propertyNode.setField(fieldNode);
- propertyNode.addAnnotation(new AnnotationNode(ClassHelper.make(CompileStatic.class)));
+ propertyNode.addAnnotation(makeAnnotationNode(CompileStatic.class));
classNode.addField(fieldNode);
// expand properties early so AST transforms will be handled correctly
PropertyExpander expander = new PropertyExpander(classNode);
@@ -4278,7 +4239,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
@Override
public AnnotationNode visitAnnotation(final AnnotationContext ctx) {
String annotationName = this.visitAnnotationName(ctx.annotationName());
- AnnotationNode annotationNode = new AnnotationNode(ClassHelper.make(annotationName));
+ AnnotationNode annotationNode = new AnnotationNode(makeClassNode(annotationName));
List<Tuple2<String, Expression>> annotationElementValues = this.visitElementValues(ctx.elementValues());
annotationElementValues.forEach(e -> annotationNode.addMember(e.getV1(), e.getV2()));
@@ -4413,7 +4374,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
}
private ClassNode createClassNode(final GroovyParserRuleContext ctx) {
- ClassNode result = ClassHelper.make(ctx.getText());
+ ClassNode result = makeClassNode(ctx.getText());
if (!isTrue(ctx, IS_INSIDE_INSTANCEOF_EXPR)) { // type in the "instanceof" expression should not have proxy to redirect to it
result = this.proxyClassNode(result);
@@ -4727,17 +4688,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
}
private boolean isTrue(final NodeMetaDataHandler nodeMetaDataHandler, final String key) {
- Object nmd = nodeMetaDataHandler.getNodeMetaData(key);
-
- if (null == nmd) {
- return false;
- }
-
- if (!(nmd instanceof Boolean)) {
- throw new GroovyBugError(nodeMetaDataHandler + " node meta data[" + key + "] is not an instance of Boolean");
- }
-
- return (Boolean) nmd;
+ return Boolean.TRUE.equals(nodeMetaDataHandler.getNodeMetaData(key));
}
private CompilationFailedException createParsingFailedException(final String msg, final GroovyParserRuleContext ctx) {
@@ -4914,7 +4865,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
private static final String SQ_STR = "'";
private static final String DQ_STR = "\"";
private static final String DOLLAR_SLASH_STR = "$/";
- private static final String VAR_STR = "var";
private static final Map<String, String> QUOTATION_MAP = Maps.of(
DQ_STR, DQ_STR,
diff --git a/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java b/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
index 1319c1e829..4b26543d7d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
@@ -63,6 +63,7 @@ import static org.codehaus.groovy.ast.AnnotationNode.RECORD_COMPONENT_TARGET;
import static org.codehaus.groovy.ast.AnnotationNode.TYPE_PARAMETER_TARGET;
import static org.codehaus.groovy.ast.AnnotationNode.TYPE_TARGET;
import static org.codehaus.groovy.ast.AnnotationNode.TYPE_USE_TARGET;
+import static org.codehaus.groovy.ast.ClassHelper.DEPRECATED_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.makeCached;
import static org.codehaus.groovy.ast.tools.GeneralUtils.getInterfacesAndSuperInterfaces;
import static org.codehaus.groovy.ast.tools.GeneralUtils.listX;
@@ -146,10 +147,11 @@ public class ExtendedVerifier extends ClassCodeVisitorSupport {
@Override
public void visitDeclarationExpression(DeclarationExpression expression) {
- VariableExpression varx = expression.getVariableExpression();
- if (varx != null) {
- visitAnnotations(expression, LOCAL_VARIABLE_TARGET);
- ClassNode type = varx.getType();
+ visitAnnotations(expression, LOCAL_VARIABLE_TARGET);
+ if (expression.isMultipleAssignmentDeclaration()) {
+ expression.getTupleExpression().forEach(e -> visitTypeAnnotations(e.getType()));
+ } else {
+ ClassNode type = expression.getLeftExpression().getType();
visitTypeAnnotations(type);
extractTypeUseAnnotations(expression.getAnnotations(), type, LOCAL_VARIABLE_TARGET);
}
@@ -393,7 +395,7 @@ public class ExtendedVerifier extends ClassCodeVisitorSupport {
}
private static void visitDeprecation(AnnotatedNode node, AnnotationNode visited) {
- if (visited.getClassNode().isResolved() && visited.getClassNode().getName().equals("java.lang.Deprecated")) {
+ if (visited.getClassNode().isResolved() && visited.getClassNode().equals(DEPRECATED_TYPE)) {
if (node instanceof MethodNode) {
MethodNode mn = (MethodNode) node;
mn.setModifiers(mn.getModifiers() | Opcodes.ACC_DEPRECATED);
diff --git a/src/test/org/apache/groovy/parser/antlr4/util/AstDumper.groovy b/src/test/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
index f67e01e6c6..48adb6a442 100644
--- a/src/test/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
+++ b/src/test/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
@@ -18,8 +18,9 @@
*/
package org.apache.groovy.parser.antlr4.util
+import groovy.transform.AutoFinal
+import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
-import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.AnnotationNode
import org.codehaus.groovy.ast.ClassHelper
import org.codehaus.groovy.ast.ClassNode
@@ -96,6 +97,7 @@ import org.codehaus.groovy.classgen.Verifier
import org.codehaus.groovy.control.CompilationUnit
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.control.io.ReaderSource
+import org.codehaus.groovy.syntax.Types
import java.lang.reflect.Modifier
@@ -142,11 +144,11 @@ class AstDumper {
*
* An adapter from ASTNode tree to source code.
*/
-@CompileStatic
+@AutoFinal @CompileStatic
class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperation, GroovyClassVisitor, GroovyCodeVisitor {
private final Writer _out
- Stack<String> classNameStack = new Stack<String>()
+ Stack<String> classNameStack = []
String _indent = ''
boolean readyToIndent = true
boolean showScriptFreeForm
@@ -176,7 +178,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
}
}
- private def visitAllImports(SourceUnit source) {
+ private void visitAllImports(SourceUnit source) {
boolean staticImportsPresent = false
boolean importsPresent = false
@@ -206,7 +208,6 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
}
}
-
void print(parameter) {
def output = parameter.toString()
@@ -298,6 +299,8 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
if (node.isInterface()) print node.name
else print "class $node.name"
visitGenerics node?.genericsTypes
+ print ' extends '
+ visitType node.unresolvedSuperClass
boolean first = true
node.unresolvedInterfaces?.each {
if (!first) {
@@ -308,8 +311,6 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
first = false
visitType it
}
- print ' extends '
- visitType node.unresolvedSuperClass
print ' { '
printDoubleBreak()
@@ -378,26 +379,24 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
visitMethod(node)
}
- private String visitParameters(parameters) {
- boolean first = true
-
- parameters.each { Parameter it ->
- if (!first) {
+ private void visitParameters(Parameter[] parameters) {
+ int i = 0
+ for (p in parameters) {
+ if (i++ != 0) {
print ', '
}
- first = false
- it.annotations?.each {
- visitAnnotationNode(it)
- print(' ')
+ for (a in p.annotations) {
+ visitAnnotationNode a
+ print ' '
}
- visitModifiers(it.modifiers)
- visitType it.type
- print ' ' + it.name
- if (it.initialExpression && !(it.initialExpression instanceof EmptyExpression)) {
+ visitModifiers(p.modifiers)
+ visitType p.type
+ print ' ' + p.name
+ if (p.initialExpression && p.initialExpression !instanceof EmptyExpression) {
print ' = '
- it.initialExpression.visit this
+ p.initialExpression.visit this
}
}
}
@@ -412,7 +411,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
visitModifiers(node.modifiers)
if (node.name == '<init>') {
print "${classNameStack.peek()}("
- visitParameters(node.parameters)
+ visitParameters node.parameters
print ') {'
printLineBreak()
} else if (node.name == '<clinit>') {
@@ -421,7 +420,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
} else {
visitType node.returnType
print " $node.name("
- visitParameters(node.parameters)
+ visitParameters node.parameters
print ')'
if (node.exceptions) {
boolean first = true
@@ -472,7 +471,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
// GROOVY-5150: final constants may be initialized directly
print ' = '
if (ClassHelper.STRING_TYPE == type) {
- print "'" + node.initialValueExpression.text.replaceAll("'", "\\\\'") + "'"
+ print "'" + node.initialValueExpression.text.replace("'", "\\'") + "'"
} else if (ClassHelper.char_TYPE == type) {
print "'${node.initialValueExpression.text}'"
} else {
@@ -535,7 +534,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
printStatementLabels(statement)
print 'for ('
if (statement?.variable != ForStatement.FOR_LOOP_DUMMY) {
- visitParameters([statement.variable])
+ visitParameters statement.variable
print ' : '
}
@@ -600,7 +599,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
statement?.caseStatements?.each {
visitCaseStatement it
}
- if (statement?.defaultStatement) {
+ if (statement?.defaultStatement !instanceof EmptyStatement) {
print 'default: '
printLineBreak()
statement?.defaultStatement?.visit this
@@ -641,12 +640,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitMethodCallExpression(MethodCallExpression expression) {
- Expression objectExp = expression.objectExpression
- if (objectExp instanceof VariableExpression) {
- visitVariableExpression(objectExp, false)
- } else {
- objectExp.visit(this)
- }
+ printExpression expression.objectExpression
if (expression.spreadSafe) {
print '*'
}
@@ -665,9 +659,9 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitStaticMethodCallExpression(StaticMethodCallExpression expression) {
+ boolean parens = expression?.arguments instanceof MethodCallExpression
+ || expression?.arguments instanceof VariableExpression
print expression?.ownerType?.name + '.' + expression?.method
- boolean parens = expression?.arguments instanceof VariableExpression
- || expression?.arguments instanceof MethodCallExpression
if (parens) print '('
expression?.arguments?.visit this
if (parens) print ')'
@@ -688,37 +682,51 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitBinaryExpression(BinaryExpression expression) {
- expression?.leftExpression?.visit this
- print " $expression.operation.text "
- expression.rightExpression.visit this
-
- if (expression?.operation?.text == '[') {
- print ']'
+ if (expression !instanceof DeclarationExpression && expression?.leftExpression instanceof VariableExpression) {
+ visitVariableExpression((VariableExpression) expression.leftExpression, false)
+ } else {
+ expression?.leftExpression?.visit this
+ }
+ boolean isAssign = expression?.operation?.type == Types.ASSIGN
+ boolean isAccess = expression?.operation?.type == Types.LEFT_SQUARE_BRACKET
+ if (!isAssign || expression?.rightExpression !instanceof EmptyExpression) {
+ print isAccess ? '[' : " ${expression?.operation?.text} "
+ expression?.rightExpression?.visit this
+ if (isAccess) {
+ print ']'
+ }
}
}
@Override
void visitPostfixExpression(PostfixExpression expression) {
- print '('
- expression?.expression?.visit this
- print ')'
+ if (expression?.expression instanceof VariableExpression) {
+ visitVariableExpression((VariableExpression) expression?.expression, false)
+ } else {
+ print '('
+ expression?.expression?.visit this
+ print ')'
+ }
print expression?.operation?.text
}
@Override
void visitPrefixExpression(PrefixExpression expression) {
print expression?.operation?.text
- print '('
- expression?.expression?.visit this
- print ')'
+ if (expression?.expression instanceof VariableExpression) {
+ visitVariableExpression((VariableExpression) expression?.expression, false)
+ } else {
+ print '('
+ expression?.expression?.visit this
+ print ')'
+ }
}
-
@Override
void visitClosureExpression(ClosureExpression expression) {
print '{ '
if (expression?.parameters) {
- visitParameters(expression?.parameters)
+ visitParameters expression?.parameters
print ' ->'
}
printLineBreak()
@@ -730,9 +738,9 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitLambdaExpression(LambdaExpression expression) {
- print '( '
+ print '('
if (expression?.parameters) {
- visitParameters(expression?.parameters)
+ visitParameters expression?.parameters
}
print ') -> {'
printLineBreak()
@@ -745,7 +753,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitTupleExpression(TupleExpression expression) {
print '('
- visitExpressionsAndCommaSeparate(expression?.expressions)
+ printExpressions expression?.expressions
print ')'
}
@@ -760,7 +768,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitPropertyExpression(PropertyExpression expression) {
- expression?.objectExpression?.visit this
+ printExpression expression?.objectExpression
if (expression?.spreadSafe) {
print '*'
} else if (expression?.isSafe()) {
@@ -784,6 +792,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
print expression?.field?.name
}
+ @Override
void visitConstantExpression(ConstantExpression expression, boolean unwrapQuotes = false) {
if (expression.value instanceof String && !unwrapQuotes) {
// string reverse escaping is very naive
@@ -799,8 +808,8 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
print expression.text
}
+ @Override
void visitVariableExpression(VariableExpression expression, boolean spacePad = true) {
-
if (spacePad) {
print ' ' + expression.name + ' '
} else {
@@ -810,20 +819,22 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitDeclarationExpression(DeclarationExpression expression) {
- // handle multiple assignment expressions
- if (expression?.leftExpression instanceof ArgumentListExpression) {
- print 'def '
- visitArgumentlistExpression((ArgumentListExpression) expression?.leftExpression, true)
- print " $expression.operation.text "
- expression.rightExpression.visit this
-
- if (expression?.operation?.text == '[') {
- print ']'
- }
- } else {
- visitType expression?.leftExpression?.type
- visitBinaryExpression expression // is a BinaryExpression
+ if (!expression.isMultipleAssignmentDeclaration()) {
+ visitType expression.leftExpression.type
+ visitBinaryExpression expression
+ return
}
+
+ print 'def ('
+ int i = 0
+ for (e in expression.tupleExpression) {
+ if (i++ != 0) print ', '
+ visitType e.type
+ print ' '
+ printExpression e
+ }
+ print ') = '
+ expression.rightExpression.visit this
}
@Override
@@ -837,35 +848,57 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
expression?.expression?.visit this
}
+ @CompileDynamic
+ private void printUnaryExpression(String opText, Expression expression) {
+ print opText
+ if (expression?.expression instanceof VariableExpression) {
+ visitVariableExpression((VariableExpression) expression?.expression, false)
+ } else if (expression?.expression instanceof PropertyExpression) {
+ expression?.expression?.visit this
+ } else {
+ print '('
+ expression?.expression?.visit this
+ print ')'
+ }
+ }
+
@Override
void visitNotExpression(NotExpression expression) {
- print '!('
- expression?.expression?.visit this
- print ')'
+ printUnaryExpression('!', expression)
}
@Override
void visitUnaryMinusExpression(UnaryMinusExpression expression) {
- print '-('
- expression?.expression?.visit this
- print ')'
+ printUnaryExpression('-', expression)
}
@Override
void visitUnaryPlusExpression(UnaryPlusExpression expression) {
- print '+('
- expression?.expression?.visit this
- print ')'
+ printUnaryExpression('+', expression)
}
@Override
void visitCastExpression(CastExpression expression) {
- print '(('
- expression?.expression?.visit this
- print ') as '
- visitType(expression?.type)
+ print '('
+ if (expression?.coerce) {
+ boolean isVariableExpressionOrPropertyExpression =
+ expression?.expression instanceof VariableExpression || expression?.expression instanceof PropertyExpression
+ if (!isVariableExpressionOrPropertyExpression) {
+ print '('
+ }
+ printExpression(expression?.expression)
+ if (!isVariableExpressionOrPropertyExpression) {
+ print ')'
+ }
+ print ' as '
+ visitType(expression?.type)
+ } else {
+ print '('
+ visitType(expression?.type)
+ print ') '
+ printExpression(expression?.expression)
+ }
print ')'
-
}
/**
@@ -883,41 +916,19 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
visitGenerics classNode?.genericsTypes
}
- void visitArgumentlistExpression(ArgumentListExpression expression, boolean showTypes = false) {
- print '('
- int count = expression?.expressions?.size()
- expression.expressions.each {
- if (showTypes) {
- visitType it.type
- print ' '
- }
- if (it instanceof VariableExpression) {
- visitVariableExpression it, false
- } else if (it instanceof ConstantExpression) {
- visitConstantExpression it, false
- } else {
- it.visit this
- }
- count--
- if (count) print ', '
- }
- print ')'
- }
-
@Override
void visitBytecodeExpression(BytecodeExpression expression) {
print '/*BytecodeExpression*/'
printLineBreak()
}
-
@Override
void visitMapExpression(MapExpression expression) {
print '['
- if (expression?.mapEntryExpressions?.size() == 0) {
+ if (!expression?.mapEntryExpressions) {
print ':'
} else {
- visitExpressionsAndCommaSeparate((List) expression?.mapEntryExpressions)
+ printExpressions expression.mapEntryExpressions
}
print ']'
}
@@ -936,7 +947,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitListExpression(ListExpression expression) {
print '['
- visitExpressionsAndCommaSeparate(expression?.expressions)
+ printExpressions expression?.expressions
print ']'
}
@@ -954,13 +965,15 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
statement?.catchStatements?.each { CatchStatement catchStatement ->
visitCatchStatement(catchStatement)
}
- print 'finally { '
- printLineBreak()
- indented {
- statement?.finallyStatement?.visit this
+ if (statement?.finallyStatement !instanceof EmptyStatement) {
+ print 'finally { '
+ printLineBreak()
+ indented {
+ statement?.finallyStatement?.visit this
+ }
+ print '} '
+ printLineBreak()
}
- print '} '
- printLineBreak()
}
@Override
@@ -994,12 +1007,12 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitShortTernaryExpression(ElvisOperatorExpression expression) {
- visitTernaryExpression(expression)
+ visitTernaryExpression expression
}
@Override
void visitBooleanExpression(BooleanExpression expression) {
- expression?.expression?.visit this
+ printExpression expression?.expression
}
@Override
@@ -1034,7 +1047,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitCatchStatement(CatchStatement statement) {
print 'catch ('
- visitParameters([statement.variable])
+ visitParameters statement.variable
print ') {'
printLineBreak()
indented {
@@ -1059,15 +1072,22 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
statement?.messageExpression?.visit this
}
+ @Override
+ void visitArgumentlistExpression(ArgumentListExpression expression) {
+ visitTupleExpression expression
+ }
+
@Override
void visitClosureListExpression(ClosureListExpression expression) {
- boolean first = true
- expression?.expressions?.each {
- if (!first) {
+ int i = 0
+ for (e in expression?.expressions) {
+ if (i++ != 0) {
print ';'
+ if (e !instanceof EmptyExpression) {
+ print ' '
+ }
}
- first = false
- it.visit this
+ e.visit this
}
}
@@ -1090,27 +1110,36 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
print 'new '
visitType expression?.elementType
print '['
- visitExpressionsAndCommaSeparate(expression?.sizeExpression)
+ printExpressions expression?.sizeExpression
print ']'
}
- private void visitExpressionsAndCommaSeparate(List<? super Expression> expressions) {
- boolean first = true
- expressions?.each {
- if (!first) {
- print ', '
- }
- first = false
- ((ASTNode) it).visit this
- }
- }
-
@Override
void visitSpreadMapExpression(SpreadMapExpression expression) {
print '*:'
expression?.expression?.visit this
}
+ //--------------------------------------------------------------------------
+
+ private void printExpression(Expression expression) {
+ if (expression instanceof VariableExpression) {
+ visitVariableExpression expression, false
+ } else {
+ expression?.visit this
+ }
+ }
+
+ private void printExpressions(List<? extends Expression> expressions) {
+ int i = 0
+ for (e in expressions) {
+ if (i++ != 0) {
+ print ', '
+ }
+ printExpression e
+ }
+ }
+
/**
* Prints all labels for the given statement. The labels will be printed on a single
* line and line break will be added.
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/AstNodeToScriptAdapter.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/AstNodeToScriptAdapter.groovy
index dd5be0ed3c..050c9bed65 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/AstNodeToScriptAdapter.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/AstNodeToScriptAdapter.groovy
@@ -186,7 +186,7 @@ and [compilephase] is a valid Integer based org.codehaus.groovy.control.CompileP
class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperation, GroovyClassVisitor, GroovyCodeVisitor {
private final Writer _out
- Stack<String> classNameStack = new Stack<>()
+ Stack<String> classNameStack = []
String _indent = ''
boolean readyToIndent = true
boolean showScriptFreeForm
@@ -200,6 +200,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
this.scriptHasBeenVisited = false
}
+ @Override
void call(SourceUnit source, GeneratorContext context, ClassNode classNode) {
visitPackage(source?.getAST()?.getPackage())
@@ -215,7 +216,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
}
}
- private def visitAllImports(SourceUnit source) {
+ private void visitAllImports(SourceUnit source) {
boolean staticImportsPresent = false
boolean importsPresent = false
@@ -245,7 +246,6 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
}
}
-
void print(parameter) {
def output = parameter.toString()
@@ -417,26 +417,24 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
visitMethod(node)
}
- private String visitParameters(parameters) {
- boolean first = true
-
- parameters.each { Parameter it ->
- if (!first) {
+ private void visitParameters(Parameter[] parameters) {
+ int i = 0
+ for (p in parameters) {
+ if (i++ != 0) {
print ', '
}
- first = false
- it.annotations?.each {
- visitAnnotationNode(it)
- print(' ')
+ for (a in p.annotations) {
+ visitAnnotationNode a
+ print ' '
}
- visitModifiers(it.modifiers)
- visitType it.type
- print ' ' + it.name
- if (it.initialExpression && !(it.initialExpression instanceof EmptyExpression)) {
+ visitModifiers(p.modifiers)
+ visitType p.type
+ print ' ' + p.name
+ if (p.initialExpression && p.initialExpression !instanceof EmptyExpression) {
print ' = '
- it.initialExpression.visit this
+ p.initialExpression.visit this
}
}
}
@@ -451,7 +449,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
visitModifiers(node.modifiers)
if (node.name == '<init>') {
print "${classNameStack.peek()}("
- visitParameters(node.parameters)
+ visitParameters node.parameters
print ') {'
printLineBreak()
} else if (node.name == '<clinit>') {
@@ -460,7 +458,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
} else {
visitType node.returnType
print " $node.name("
- visitParameters(node.parameters)
+ visitParameters node.parameters
print ')'
if (node.exceptions) {
boolean first = true
@@ -574,7 +572,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
printStatementLabels(statement)
print 'for ('
if (statement?.variable != ForStatement.FOR_LOOP_DUMMY) {
- visitParameters([statement.variable])
+ visitParameters statement.variable
print ' : '
}
@@ -680,8 +678,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitMethodCallExpression(MethodCallExpression expression) {
- Expression objectExpr = expression.objectExpression
- printExpression(objectExpr)
+ printExpression expression.objectExpression
if (expression.spreadSafe) {
print '*'
}
@@ -704,7 +701,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
|| expression?.arguments instanceof VariableExpression
print expression?.ownerType?.name + '.' + expression?.method
if (parens) print '('
- expression?.arguments?.visit(this)
+ expression?.arguments?.visit this
if (parens) print ')'
}
@@ -724,20 +721,16 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitBinaryExpression(BinaryExpression expression) {
if (expression !instanceof DeclarationExpression && expression?.leftExpression instanceof VariableExpression) {
- visitVariableExpression((VariableExpression) expression?.leftExpression, false)
+ visitVariableExpression((VariableExpression) expression.leftExpression, false)
} else {
expression?.leftExpression?.visit this
}
- if (!(expression.rightExpression instanceof EmptyExpression) || expression.operation.type != Types.ASSIGN) {
- String opText = expression?.operation?.text
- boolean isSubscriptOp = opText == '['
- if (isSubscriptOp) {
- print "["
- } else {
- print " $opText "
- }
- expression.rightExpression.visit this
- if (isSubscriptOp) {
+ boolean isAssign = expression?.operation?.type == Types.ASSIGN
+ boolean isAccess = expression?.operation?.type == Types.LEFT_SQUARE_BRACKET
+ if (!isAssign || expression?.rightExpression !instanceof EmptyExpression) {
+ print isAccess ? '[' : " ${expression?.operation?.text} "
+ expression?.rightExpression?.visit this
+ if (isAccess) {
print ']'
}
}
@@ -771,7 +764,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
void visitClosureExpression(ClosureExpression expression) {
print '{ '
if (expression?.parameters) {
- visitParameters(expression?.parameters)
+ visitParameters expression?.parameters
print ' ->'
}
printLineBreak()
@@ -785,7 +778,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
void visitLambdaExpression(LambdaExpression expression) {
print '('
if (expression?.parameters) {
- visitParameters(expression?.parameters)
+ visitParameters expression?.parameters
}
print ') -> {'
printLineBreak()
@@ -798,7 +791,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitTupleExpression(TupleExpression expression) {
print '('
- visitExpressionsAndCommaSeparate(expression?.expressions)
+ printExpressions expression?.expressions
print ')'
}
@@ -813,8 +806,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitPropertyExpression(PropertyExpression expression) {
- printExpression(expression?.objectExpression)
-
+ printExpression expression?.objectExpression
if (expression?.spreadSafe) {
print '*'
} else if (expression?.isSafe()) {
@@ -838,6 +830,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
print expression?.field?.name
}
+ @Override
void visitConstantExpression(ConstantExpression expression, boolean unwrapQuotes = false) {
if (expression.value instanceof String && !unwrapQuotes) {
// string reverse escaping is very naive
@@ -864,20 +857,22 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitDeclarationExpression(DeclarationExpression expression) {
- // handle multiple assignment expressions
- if (expression?.leftExpression instanceof ArgumentListExpression) {
- print 'def '
- visitArgumentlistExpression((ArgumentListExpression) expression?.leftExpression, true)
- print " $expression.operation.text "
- expression.rightExpression.visit this
-
- if (expression?.operation?.text == '[') {
- print ']'
- }
- } else {
- visitType expression?.leftExpression?.type
- visitBinaryExpression expression // is a BinaryExpression
+ if (!expression.isMultipleAssignmentDeclaration()) {
+ visitType expression.leftExpression.type
+ visitBinaryExpression expression
+ return
}
+
+ print 'def ('
+ int i = 0
+ for (e in expression.tupleExpression) {
+ if (i++ != 0) print ', '
+ visitType e.type
+ print ' '
+ printExpression e
+ }
+ print ') = '
+ expression.rightExpression.visit this
}
@Override
@@ -959,27 +954,6 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
visitGenerics classNode?.genericsTypes
}
- void visitArgumentlistExpression(ArgumentListExpression expression, boolean showTypes = false) {
- print '('
- int count = expression?.expressions?.size()
- expression.expressions.each {
- if (showTypes) {
- visitType it.type
- print ' '
- }
- if (it instanceof VariableExpression) {
- visitVariableExpression it, false
- } else if (it instanceof ConstantExpression) {
- visitConstantExpression it, false
- } else {
- it.visit this
- }
- count--
- if (count) print ', '
- }
- print ')'
- }
-
@Override
void visitBytecodeExpression(BytecodeExpression expression) {
print '/*BytecodeExpression*/'
@@ -989,10 +963,10 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitMapExpression(MapExpression expression) {
print '['
- if (expression?.mapEntryExpressions?.size() == 0) {
+ if (!expression?.mapEntryExpressions) {
print ':'
} else {
- visitExpressionsAndCommaSeparate((List) expression?.mapEntryExpressions)
+ printExpressions expression.mapEntryExpressions
}
print ']'
}
@@ -1011,7 +985,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitListExpression(ListExpression expression) {
print '['
- visitExpressionsAndCommaSeparate(expression?.expressions)
+ printExpressions expression?.expressions
print ']'
}
@@ -1071,12 +1045,12 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitShortTernaryExpression(ElvisOperatorExpression expression) {
- visitTernaryExpression(expression)
+ visitTernaryExpression expression
}
@Override
void visitBooleanExpression(BooleanExpression expression) {
- printExpression(expression?.expression)
+ printExpression expression?.expression
}
@Override
@@ -1111,7 +1085,7 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
@Override
void visitCatchStatement(CatchStatement statement) {
print 'catch ('
- visitParameters([statement.variable])
+ visitParameters statement.variable
print ') {'
printLineBreak()
indented {
@@ -1136,18 +1110,22 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
statement?.messageExpression?.visit this
}
+ @Override
+ void visitArgumentlistExpression(ArgumentListExpression expression) {
+ visitTupleExpression expression
+ }
+
@Override
void visitClosureListExpression(ClosureListExpression expression) {
- boolean first = true
- expression?.expressions?.each {
- if (!first) {
+ int i = 0
+ for (e in expression?.expressions) {
+ if (i++ != 0) {
print ';'
- if (it !instanceof EmptyExpression) {
+ if (e !instanceof EmptyExpression) {
print ' '
}
}
- first = false
- it.visit this
+ e.visit this
}
}
@@ -1170,29 +1148,36 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
print 'new '
visitType expression?.elementType
print '['
- visitExpressionsAndCommaSeparate(expression?.sizeExpression)
+ printExpressions expression?.sizeExpression
print ']'
}
- private void visitExpressionsAndCommaSeparate(List<? extends Expression> expressions) {
- if (expressions) {
- boolean first = true
- for (e in expressions) {
- if (!first) {
- print ', '
- }
- first = false
- e.visit(this)
- }
- }
- }
-
@Override
void visitSpreadMapExpression(SpreadMapExpression expression) {
print '*:'
expression?.expression?.visit this
}
+ //--------------------------------------------------------------------------
+
+ private void printExpression(Expression expression) {
+ if (expression instanceof VariableExpression) {
+ visitVariableExpression expression, false
+ } else {
+ expression?.visit this
+ }
+ }
+
+ private void printExpressions(List<? extends Expression> expressions) {
+ int i = 0
+ for (e in expressions) {
+ if (i++ != 0) {
+ print ', '
+ }
+ printExpression e
+ }
+ }
+
/**
* Prints all labels for the given statement. The labels will be printed on a single
* line and line break will be added.
@@ -1211,12 +1196,4 @@ class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperati
}
return true
}
-
- private void printExpression(Expression expression) {
- if (expression instanceof VariableExpression) {
- visitVariableExpression((VariableExpression) expression, false)
- } else {
- expression?.visit this
- }
- }
}
diff --git a/subprojects/groovy-console/src/test/groovy/groovy/console/ui/AstNodeToScriptAdapterTest.groovy b/subprojects/groovy-console/src/test/groovy/groovy/console/ui/AstNodeToScriptAdapterTest.groovy
index 7da2ede8ba..1d60b0954e 100644
--- a/subprojects/groovy-console/src/test/groovy/groovy/console/ui/AstNodeToScriptAdapterTest.groovy
+++ b/subprojects/groovy-console/src/test/groovy/groovy/console/ui/AstNodeToScriptAdapterTest.groovy
@@ -287,7 +287,7 @@ final class AstNodeToScriptAdapterTest extends GroovyTestCase {
['foo': 'bar', 'baz': bif + qux]'''
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
- assert result.contains("['foo', \"\$bar\", x , java.lang.Math.min(5, 3)]")
+ assert result.contains("['foo', \"\$bar\", x, java.lang.Math.min(5, 3)]")
assert result.contains("((['foo', \"\$bar\"]) as java.lang.String[])")
assert result.contains("['foo': 'bar', 'baz': bif + qux ]")
}
@@ -866,8 +866,8 @@ final class AstNodeToScriptAdapterTest extends GroovyTestCase {
String result = compileToScript(script, CompilePhase.SEMANTIC_ANALYSIS)
assert result.contains('java.lang.Object c1 = new MyClass()')
assert result.contains('java.lang.Object c2 = new MyClass()')
- assert result.contains('assert [ c1 , c2 ]*.getA() == [c1.getA(), c2.getA()] : null')
- assert result.contains("assert [ c1 , c2 ]*.getA() == ['abc', 'abc'] : null")
+ assert result.contains('assert [c1, c2]*.getA() == [c1.getA(), c2.getA()] : null')
+ assert result.contains("assert [c1, c2]*.getA() == ['abc', 'abc'] : null")
}
void testVisitSafeMethodCall() {
diff --git a/subprojects/groovy-console/src/test/groovy/groovy/console/ui/ScriptToTreeNodeAdapterTest.groovy b/subprojects/groovy-console/src/test/groovy/groovy/console/ui/ScriptToTreeNodeAdapterTest.groovy
index b63e878d08..73595d7c28 100644
--- a/subprojects/groovy-console/src/test/groovy/groovy/console/ui/ScriptToTreeNodeAdapterTest.groovy
+++ b/subprojects/groovy-console/src/test/groovy/groovy/console/ui/ScriptToTreeNodeAdapterTest.groovy
@@ -258,7 +258,7 @@ final class ScriptToTreeNodeAdapterTest extends GroovyTestCase {
startsWith('BlockStatement'),
startsWith('ExpressionStatement'),
eq('Declaration - def (x, y) = [1, 2]'),
- eq('ArgumentList - (x, y)'),
+ eq('Tuple - (x, y)'),
]
)
}