-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1cbd11a
commit dfe164d
Showing
6 changed files
with
604 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
195 changes: 195 additions & 0 deletions
195
base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/expr/DeclarationExpression.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
/* | ||
* 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.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, | ||
* the multiple assignment feature allows you to create two or more variables using | ||
* an expression like: <code>def (x, y) = [1, 2]</code>. | ||
* <p> | ||
* You can access the left hand side of a declaration using the | ||
* "<code>Expression getLeftExpression()</code>" method. In which case you might then | ||
* use <code>instanceof</code> and casting to perform operations specific to a | ||
* single local variable (<code>VariableExpression</code>) or for the multiple | ||
* assignment case (<code>TupleExpression</code>). | ||
* <p> | ||
* Alternatively, if <code>isMultipleAssignmentDeclaration()</code> is <code>false</code> | ||
* you can use the method "<code>VariableExpression getVariableExpression()</code>" method. | ||
* Similarly, if <code>isMultipleAssignmentDeclaration()</code> is <code>true</code> | ||
* you can use the method "<code>TupleExpression getTupleExpression()</code>" method. | ||
* Calling either of these expression getters when the "isMultipleAssignment" condition | ||
* 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'". | ||
* @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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.