You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2019/07/07 09:00:52 UTC
[groovy] 01/02: Override getText() in DeclarationExpression to
provide type info
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 <er...@thomsonreuters.com>
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]'
+ }
+}