diff --git a/base/org.codehaus.groovy25/.checkstyle b/base/org.codehaus.groovy25/.checkstyle
index 1275132b0a..726127d6c3 100644
--- a/base/org.codehaus.groovy25/.checkstyle
+++ b/base/org.codehaus.groovy25/.checkstyle
@@ -29,6 +29,7 @@
def (x, y) = [1, 2]
.
+ *
+ * You can access the left hand side of a declaration using the
+ * "Expression getLeftExpression()
" method. In which case you might then
+ * use instanceof
and casting to perform operations specific to a
+ * single local variable (VariableExpression
) or for the multiple
+ * assignment case (TupleExpression
).
+ *
+ * Alternatively, if isMultipleAssignmentDeclaration()
is false
+ * you can use the method "VariableExpression getVariableExpression()
" method.
+ * Similarly, if isMultipleAssignmentDeclaration()
is true
+ * you can use the method "TupleExpression getTupleExpression()
" method.
+ * Calling either of these expression getters when the "isMultipleAssignment" condition
+ * is not appropriate is unsafe and will result in a ClassCastException
.
+ */
+public class DeclarationExpression extends BinaryExpression {
+
+ /**
+ * 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(final VariableExpression left, final Token operation, final Expression right) {
+ this((Expression) 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.
+ * @param operation
+ * the operation, typically an assignment operator
+ * @param right
+ * the right hand side of a declaration
+ */
+ public DeclarationExpression(final Expression left, final Token operation, final Expression right) {
+ super(left, Token.newSymbol("=", operation.getStartLine(), operation.getStartColumn()), right);
+ check(left);
+ }
+
+ private static void check(Expression left) {
+ if (left instanceof VariableExpression) {
+ //nothing
+ } else if (left instanceof TupleExpression) {
+ TupleExpression tuple = (TupleExpression) left;
+ if (tuple.getExpressions().isEmpty()) throw new GroovyBugError("one element required for left side");
+ } else {
+ throw new GroovyBugError("illegal left expression for declaration: "+left);
+ }
+ }
+
+ @Override
+ public void visit(GroovyCodeVisitor visitor) {
+ visitor.visitDeclarationExpression(this);
+ }
+
+ /**
+ * 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.
+ * If that method returns true then this method is safe to call.
+ *
+ * @return left hand side of normal variable declarations
+ * @throws ClassCastException if the left hand side is not a VariableExpression (and is probably a multiple assignment statement).
+ */
+ public VariableExpression getVariableExpression() {
+ return (VariableExpression) this.getLeftExpression();
+ }
+
+ /**
+ * 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.
+ * @return
+ * left hand side of multiple assignment declarations
+ * @throws ClassCastException
+ * if the left hand side is not a TupleExpression (and is probably a VariableExpression).
+ *
+ */
+ public TupleExpression getTupleExpression() {
+ return (TupleExpression) this.getLeftExpression();
+ }
+
+ @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.
+ * @param leftExpression
+ * 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()));
+ ret.setSourcePosition(this);
+ ret.addAnnotations(getAnnotations());
+ ret.setDeclaringClass(getDeclaringClass());
+ ret.copyNodeMetaData(this);
+ return ret;
+ }
+
+ /**
+ * 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()".
+ * @return
+ * true if this declaration is a multiple assignment declaration, which means the
+ * left hand side is an ArgumentListExpression.
+ */
+ public boolean isMultipleAssignmentDeclaration() {
+ return getLeftExpression() instanceof TupleExpression;
+ }
+}
diff --git a/base/org.codehaus.groovy30/.checkstyle b/base/org.codehaus.groovy30/.checkstyle
index 74cfae7e8d..022636b69d 100644
--- a/base/org.codehaus.groovy30/.checkstyle
+++ b/base/org.codehaus.groovy30/.checkstyle
@@ -34,6 +34,7 @@
def (x, y) = [1, 2]
.
+ *
+ * You can access the left hand side of a declaration using the
+ * "Expression getLeftExpression()
" method. In which case you might then
+ * use instanceof
and casting to perform operations specific to a
+ * single local variable (VariableExpression
) or for the multiple
+ * assignment case (TupleExpression
).
+ *
+ * Alternatively, if isMultipleAssignmentDeclaration()
is false
+ * you can use the method "VariableExpression getVariableExpression()
" method.
+ * Similarly, if isMultipleAssignmentDeclaration()
is true
+ * you can use the method "TupleExpression getTupleExpression()
" method.
+ * Calling either of these expression getters when the "isMultipleAssignment" condition
+ * is not appropriate is unsafe and will result in a ClassCastException
.
+ */
+public class DeclarationExpression extends BinaryExpression {
+
+ /**
+ * 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(final VariableExpression left, final Token operation, final Expression right) {
+ this((Expression) 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.
+ * @param operation
+ * the operation, typically an assignment operator
+ * @param right
+ * the right hand side of a declaration
+ */
+ public DeclarationExpression(final Expression left, final Token operation, final Expression right) {
+ super(left, Token.newSymbol("=", operation.getStartLine(), operation.getStartColumn()), right);
+ check(left);
+ }
+
+ private static void check(Expression left) {
+ if (left instanceof VariableExpression) {
+ //nothing
+ } else if (left instanceof TupleExpression) {
+ TupleExpression tuple = (TupleExpression) left;
+ if (tuple.getExpressions().isEmpty()) throw new GroovyBugError("one element required for left side");
+ } else {
+ throw new GroovyBugError("illegal left expression for declaration: "+left);
+ }
+ }
+
+ @Override
+ public void visit(GroovyCodeVisitor visitor) {
+ visitor.visitDeclarationExpression(this);
+ }
+
+ /**
+ * 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.
+ * If that method returns true then this method is safe to call.
+ *
+ * @return left hand side of normal variable declarations
+ * @throws ClassCastException if the left hand side is not a VariableExpression (and is probably a multiple assignment statement).
+ */
+ public VariableExpression getVariableExpression() {
+ Expression leftExpression = this.getLeftExpression();
+
+ return leftExpression instanceof VariableExpression
+ ? (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.
+ * @return
+ * left hand side of multiple assignment declarations
+ * @throws ClassCastException
+ * if the left hand side is not a TupleExpression (and is probably a VariableExpression).
+ *
+ */
+ public TupleExpression getTupleExpression() {
+ Expression leftExpression = this.getLeftExpression();
+
+ return leftExpression instanceof TupleExpression
+ ? (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.
+ * @param leftExpression
+ * 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()));
+ ret.setSourcePosition(this);
+ ret.addAnnotations(getAnnotations());
+ ret.setDeclaringClass(getDeclaringClass());
+ ret.copyNodeMetaData(this);
+ return ret;
+ }
+
+ /**
+ * 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()".
+ * @return
+ * true if this declaration is a multiple assignment declaration, which means the
+ * left hand side is an ArgumentListExpression.
+ */
+ public boolean isMultipleAssignmentDeclaration() {
+ return getLeftExpression() instanceof TupleExpression;
+ }
+}
diff --git a/base/org.codehaus.groovy40/.checkstyle b/base/org.codehaus.groovy40/.checkstyle
index 0f7c7d6a8d..c567e09e42 100644
--- a/base/org.codehaus.groovy40/.checkstyle
+++ b/base/org.codehaus.groovy40/.checkstyle
@@ -32,6 +32,7 @@
def (x, y) = [1, 2]
.
+ *
+ * You can access the left hand side of a declaration using the
+ * "Expression getLeftExpression()
" method. In which case you might then
+ * use instanceof
and casting to perform operations specific to a
+ * single local variable (VariableExpression
) or for the multiple
+ * assignment case (TupleExpression
).
+ *
+ * Alternatively, if isMultipleAssignmentDeclaration()
is false
+ * you can use the method "VariableExpression getVariableExpression()
" method.
+ * Similarly, if isMultipleAssignmentDeclaration()
is true
+ * you can use the method "TupleExpression getTupleExpression()
" method.
+ * Calling either of these expression getters when the "isMultipleAssignment" condition
+ * is not appropriate is unsafe and will result in a ClassCastException
.
+ */
+public class DeclarationExpression extends BinaryExpression {
+
+ /**
+ * 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(final VariableExpression left, final Token operation, final Expression right) {
+ this((Expression) 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.
+ * @param operation
+ * the operation, typically an assignment operator
+ * @param right
+ * the right hand side of a declaration
+ */
+ public DeclarationExpression(final Expression left, final Token operation, final Expression right) {
+ super(left, Token.newSymbol("=", operation.getStartLine(), operation.getStartColumn()), right);
+ check(left);
+ }
+
+ private static void check(Expression left) {
+ if (left instanceof VariableExpression) {
+ //nothing
+ } else if (left instanceof TupleExpression) {
+ TupleExpression tuple = (TupleExpression) left;
+ if (tuple.getExpressions().isEmpty()) throw new GroovyBugError("one element required for left side");
+ } else {
+ throw new GroovyBugError("illegal left expression for declaration: "+left);
+ }
+ }
+
+ @Override
+ public void visit(GroovyCodeVisitor visitor) {
+ visitor.visitDeclarationExpression(this);
+ }
+
+ /**
+ * 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.
+ * If that method returns true then this method is safe to call.
+ *
+ * @return left hand side of normal variable declarations
+ * @throws ClassCastException if the left hand side is not a VariableExpression (and is probably a multiple assignment statement).
+ */
+ public VariableExpression getVariableExpression() {
+ Expression leftExpression = this.getLeftExpression();
+
+ return leftExpression instanceof VariableExpression
+ ? (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.
+ * @return
+ * left hand side of multiple assignment declarations
+ * @throws ClassCastException
+ * if the left hand side is not a TupleExpression (and is probably a VariableExpression).
+ *
+ */
+ public TupleExpression getTupleExpression() {
+ Expression leftExpression = this.getLeftExpression();
+
+ return leftExpression instanceof TupleExpression
+ ? (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.
+ * @param leftExpression
+ * 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()));
+ ret.setSourcePosition(this);
+ ret.addAnnotations(getAnnotations());
+ ret.setDeclaringClass(getDeclaringClass());
+ ret.copyNodeMetaData(this);
+ return ret;
+ }
+
+ /**
+ * 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()".
+ * @return
+ * true if this declaration is a multiple assignment declaration, which means the
+ * left hand side is an ArgumentListExpression.
+ */
+ public boolean isMultipleAssignmentDeclaration() {
+ return getLeftExpression() instanceof TupleExpression;
+ }
+}