This is an automated email from the ASF dual-hosted git repository. paulk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/groovy.git
commit d3177e870f774a4cc82032eb214218fa063892f5 Author: Eric Milles <[email protected]> AuthorDate: Sat Jul 6 19:13:57 2019 -0500 Override getText() in DeclarationExpression to provide type info --- .../groovy/ast/expr/DeclarationExpression.java | 92 +++++++++++++++------- .../ast/expr/DeclarationExpressionTest.groovy | 69 ++++++++++++++++ 2 files changed, 134 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/ast/expr/DeclarationExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/DeclarationExpression.java index e5aebda..074a0b4 100644 --- a/src/main/java/org/codehaus/groovy/ast/expr/DeclarationExpression.java +++ b/src/main/java/org/codehaus/groovy/ast/expr/DeclarationExpression.java @@ -22,9 +22,11 @@ import org.codehaus.groovy.GroovyBugError; import org.codehaus.groovy.ast.GroovyCodeVisitor; import org.codehaus.groovy.syntax.Token; +import static org.apache.groovy.ast.tools.ClassNodeUtils.formatTypeName; + /** * Represents one or more local variables. Typically it is a single local variable - * declared by name with an expression like "def foo" or with type "String foo". However, + * declared by name with an expression like "def foo" or with type "String foo". However, * the multiple assignment feature allows you to create two or more variables using * an expression like: <code>def (x, y) = [1, 2]</code>. * <p> @@ -42,35 +44,35 @@ import org.codehaus.groovy.syntax.Token; * is not appropriate is unsafe and will result in a <code>ClassCastException</code>. */ public class DeclarationExpression extends BinaryExpression { - + /** - * Creates a DeclarationExpression for VariableExpressions like "def x" or "String y = 'foo'". + * Creates a DeclarationExpression for VariableExpressions like "def x" or "String y = 'foo'". * @param left * the left hand side of a variable declaration * @param operation * the operation, typically an assignment operator * @param right * the right hand side of a declaration - */ + */ public DeclarationExpression(VariableExpression left, Token operation, Expression right) { super(left,operation,right); } - + /** * Creates a DeclarationExpression for Expressions like "def (x, y) = [1, 2]" * @param left - * the left hand side of a declaration. Must be either a VariableExpression or - * a TupleExpression with at least one element. + * the left hand side of a declaration. Must be either a VariableExpression or + * a TupleExpression with at least one element. * @param operation * the operation, typically an assignment operator * @param right * the right hand side of a declaration - */ + */ public DeclarationExpression(Expression left, Token operation, Expression right) { super(left,operation,right); check(left); } - + private static void check(Expression left) { if (left instanceof VariableExpression) { //nothing @@ -82,6 +84,7 @@ public class DeclarationExpression extends BinaryExpression { } } + @Override public void visit(GroovyCodeVisitor visitor) { visitor.visitDeclarationExpression(this); } @@ -90,7 +93,7 @@ public class DeclarationExpression extends BinaryExpression { * This method returns the left hand side of the declaration cast to the VariableExpression type. * This is an unsafe method to call. In a multiple assignment statement, the left hand side will * be a TupleExpression and a ClassCastException will occur. If you invoke this method then - * be sure to invoke isMultipleAssignmentDeclaration() first to check that it is safe to do so. + * be sure to invoke isMultipleAssignmentDeclaration() first to check that it is safe to do so. * If that method returns true then this method is safe to call. * * @return left hand side of normal variable declarations @@ -103,16 +106,16 @@ public class DeclarationExpression extends BinaryExpression { ? (VariableExpression) leftExpression : null; } - + /** * This method returns the left hand side of the declaration cast to the TupleExpression type. * This is an unsafe method to call. In a single assignment statement, the left hand side will * be a VariableExpression and a ClassCastException will occur. If you invoke this method then - * be sure to invoke isMultipleAssignmentDeclaration() first to check that it is safe to do so. - * If that method returns true then this method is safe to call. + * be sure to invoke isMultipleAssignmentDeclaration() first to check that it is safe to do so. + * If that method returns true then this method is safe to call. * @return * left hand side of multiple assignment declarations - * @throws ClassCastException + * @throws ClassCastException * if the left hand side is not a TupleExpression (and is probably a VariableExpression). * */ @@ -123,22 +126,58 @@ public class DeclarationExpression extends BinaryExpression { ? (TupleExpression) leftExpression : null; } - + + @Override + public String getText() { + StringBuilder text = new StringBuilder(); + + if (!isMultipleAssignmentDeclaration()) { + VariableExpression v = getVariableExpression(); + if (v.isDynamicTyped()) { + text.append("def"); + } else { + text.append(formatTypeName(v.getType())); + } + text.append(' ').append(v.getText()); + } else { + TupleExpression t = getTupleExpression(); + text.append("def ("); + for (Expression e : t.getExpressions()) { + if (e instanceof VariableExpression) { + VariableExpression v = (VariableExpression) e; + if (!v.isDynamicTyped()) { + text.append(formatTypeName(v.getType())).append(' '); + } + } + text.append(e.getText()).append(", "); + } + text.setLength(text.length() - 2); + text.append(')'); + } + text.append(' ').append(getOperation().getText()); + text.append(' ').append(getRightExpression().getText()); + + return text.toString(); + } + /** * This method sets the leftExpression for this BinaryExpression. The parameter must be - * either a VariableExpression or a TupleExpression with one or more elements. + * either a VariableExpression or a TupleExpression with one or more elements. * @param leftExpression - * either a VariableExpression or a TupleExpression with one or more elements. - */ + * either a VariableExpression or a TupleExpression with one or more elements. + */ + @Override public void setLeftExpression(Expression leftExpression) { check(leftExpression); super.setLeftExpression(leftExpression); } - + + @Override public void setRightExpression(Expression rightExpression) { super.setRightExpression(rightExpression); } - + + @Override public Expression transformExpression(ExpressionTransformer transformer) { Expression ret = new DeclarationExpression(transformer.transform(getLeftExpression()), getOperation(), transformer.transform(getRightExpression())); @@ -148,18 +187,17 @@ public class DeclarationExpression extends BinaryExpression { ret.copyNodeMetaData(this); return ret; } - + /** - * This method tells you if this declaration is a multiple assignment declaration, which + * This method tells you if this declaration is a multiple assignment declaration, which * has the form "def (x, y) = ..." in Groovy. If this method returns true, then the left - * hand side is an ArgumentListExpression. Do not call "getVariableExpression()" on this - * object if this method returns true, instead use "getLeftExpression()". + * hand side is an ArgumentListExpression. Do not call "getVariableExpression()" on this + * object if this method returns true, instead use "getLeftExpression()". * @return * true if this declaration is a multiple assignment declaration, which means the - * left hand side is an ArgumentListExpression. - */ + * left hand side is an ArgumentListExpression. + */ public boolean isMultipleAssignmentDeclaration() { return getLeftExpression() instanceof TupleExpression; } } - diff --git a/src/test/org/codehaus/groovy/ast/expr/DeclarationExpressionTest.groovy b/src/test/org/codehaus/groovy/ast/expr/DeclarationExpressionTest.groovy new file mode 100644 index 0000000..caa8961 --- /dev/null +++ b/src/test/org/codehaus/groovy/ast/expr/DeclarationExpressionTest.groovy @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.codehaus.groovy.ast.expr + +import org.junit.Test + +final class DeclarationExpressionTest { + + @Test + void getTextForBasicDeclaration() { + def ast = macro { + String greeting = 'hello' + } + + assert ast.text == 'String greeting = hello' + } + + @Test + void getTextForDynamicDeclaration() { + def ast = macro { + def greeting = 'hello' + } + + assert ast.text == 'def greeting = hello' + } + + @Test + void getTextForMultipleDeclaration() { + def ast = macro { + def (one, two) = ['1', '2'] + } + + assert ast.text == 'def (one, two) = [1, 2]' + } + + @Test + void getTextForMultipleMixedDeclaration() { + def ast = macro { + def (String one, two) = ['1', '2'] + } + + assert ast.text == 'def (String one, two) = [1, 2]' + } + + @Test + void getTextForMultipleTypedDeclaration() { + def ast = macro { + def (String one, CharSequence two) = ['1', '2'] + } + + assert ast.text == 'def (String one, CharSequence two) = [1, 2]' + } +}
