http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java new file mode 100644 index 0000000..4ddf07b --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java @@ -0,0 +1,199 @@ +/* + * 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.ast.ClassHelper; +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.Variable; + +/** + * Represents a local variable name, the simplest form of expression. e.g. "foo". + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class VariableExpression extends Expression implements Variable { + // The following fields are only used internally; every occurrence of a user-defined expression of the same kind + // has its own instance so as to preserve line information. Consequently, to test for such an expression, don't + // compare against the field but call isXXXExpression() instead. + public static final VariableExpression THIS_EXPRESSION = new VariableExpression("this", ClassHelper.DYNAMIC_TYPE); + public static final VariableExpression SUPER_EXPRESSION = new VariableExpression("super", ClassHelper.DYNAMIC_TYPE); + + private final String variable; + private int modifiers; + private boolean inStaticContext; + private boolean isDynamicTyped=false; + private Variable accessedVariable; + boolean closureShare=false; + boolean useRef=false; + private final ClassNode originType; + + public Variable getAccessedVariable() { + return accessedVariable; + } + + public void setAccessedVariable(Variable origin) { + this.accessedVariable = origin; + } + + public VariableExpression(String variable, ClassNode type) { + this.variable = variable; + originType = type; + setType(ClassHelper.getWrapper(type)); + } + + public VariableExpression(String variable) { + this(variable, ClassHelper.DYNAMIC_TYPE); + } + + public VariableExpression(Variable variable) { + this(variable.getName(), variable.getOriginType()); + setAccessedVariable(variable); + setModifiers(variable.getModifiers()); + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitVariableExpression(this); + } + + public Expression transformExpression(ExpressionTransformer transformer) { + return this; + } + + public String getText() { + return variable; + } + + public String getName() { + return variable; + } + + public String toString() { + return super.toString() + "[variable: " + variable + (this.isDynamicTyped() ? "" : " type: " + getType()) + "]"; + } + + public Expression getInitialExpression() { + return null; + } + + public boolean hasInitialExpression() { + return false; + } + + public boolean isInStaticContext() { + if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.isInStaticContext(); + return inStaticContext; + } + + public void setInStaticContext(boolean inStaticContext) { + this.inStaticContext = inStaticContext; + } + + /** + * Set the type of this variable. If you call this method from an AST transformation and that + * the {@link #getAccessedVariable() accessed variable} is ({@link #isClosureSharedVariable() shared}, + * this operation is unsafe and may lead to a verify error at compile time. Instead, set the type of + * the {@link #getAccessedVariable() accessed variable} + * @param cn the type to be set on this variable + */ + public void setType(ClassNode cn){ + super.setType(cn); + isDynamicTyped |= ClassHelper.DYNAMIC_TYPE==cn; + } + + public boolean isDynamicTyped() { + if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.isDynamicTyped(); + return isDynamicTyped; + } + + /** + * Tells if this variable or the accessed variable is used in a closure context, like in the following + * example : + * <pre>def str = 'Hello' + * def cl = { println str } + * </pre> + * The "str" variable is closure shared. + * @return true if this variable is used in a closure + */ + public boolean isClosureSharedVariable() { + if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.isClosureSharedVariable(); + return closureShare; + } + + /** + * Use this method to tell if a variable is used in a closure, like in the following example: + * <pre>def str = 'Hello' + * def cl = { println str } + * </pre> + * The "str" variable is closure shared. The variable expression inside the closure references an + * accessed variable "str" which must have the closure shared flag set. + * @param inClosure tells if this variable is later referenced in a closure + */ + public void setClosureSharedVariable(boolean inClosure) { + closureShare = inClosure; + } + + public int getModifiers() { + return modifiers; + } + + /** + * For internal use only. This flag is used by compiler internals and should probably + * be converted to a node metadata in future. + * @param useRef + */ + public void setUseReferenceDirectly(boolean useRef) { + this.useRef = useRef; + } + + /** + * For internal use only. This flag is used by compiler internals and should probably + * be converted to a node metadata in future. + */ + public boolean isUseReferenceDirectly() { + return useRef; + } + + public ClassNode getType() { + if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.getType(); + return super.getType(); + } + + /** + * Returns the type which was used when this variable expression was created. For example, + * {@link #getType()} may return a boxed type while this method would return the primitive type. + * @return the type which was used to define this variable expression + */ + public ClassNode getOriginType() { + if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.getOriginType(); + return originType; + } + + public boolean isThisExpression() { + return "this".equals(variable); + } + + public boolean isSuperExpression() { + return "super".equals(variable); + } + + public void setModifiers(int modifiers) { + this.modifiers = modifiers; + } +}
http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/expr/package.html ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/expr/package.html b/src/main/java/org/codehaus/groovy/ast/expr/package.html new file mode 100644 index 0000000..806854e --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/expr/package.html @@ -0,0 +1,28 @@ +<!-- + + 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. + +--> +<html> + <head> + <title>package org.codehaus.groovy.ast.expr.*</title> + </head> + <body> + <p>AST nodes for Groovy expressions</p> + </body> +</html> http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/package.html ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/package.html b/src/main/java/org/codehaus/groovy/ast/package.html new file mode 100644 index 0000000..f8f132a --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/package.html @@ -0,0 +1,28 @@ +<!-- + + 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. + +--> +<html> + <head> + <title>package org.codehaus.groovy.ast.*</title> + </head> + <body> + <p>Groovy AST nodes for the syntax of the language</p> + </body> +</html> http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/AssertStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/AssertStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/AssertStatement.java new file mode 100644 index 0000000..3f1fb33 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/AssertStatement.java @@ -0,0 +1,66 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.BooleanExpression; +import org.codehaus.groovy.ast.expr.ConstantExpression; +import org.codehaus.groovy.ast.expr.Expression; + +/** + * Represents an assert statement. + * E.g.: + * <code> + * assert i != 0 : "should never be zero"; + * </code> + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class AssertStatement extends Statement { + + private BooleanExpression booleanExpression; + private Expression messageExpression; + + public AssertStatement(BooleanExpression booleanExpression) { + this(booleanExpression, ConstantExpression.NULL); + } + + public AssertStatement(BooleanExpression booleanExpression, Expression messageExpression) { + this.booleanExpression = booleanExpression; + this.messageExpression = messageExpression; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitAssertStatement(this); + } + + public Expression getMessageExpression() { + return messageExpression; + } + + public BooleanExpression getBooleanExpression() { + return booleanExpression; + } + public void setBooleanExpression(BooleanExpression booleanExpression) { + this.booleanExpression = booleanExpression; + } + public void setMessageExpression(Expression messageExpression) { + this.messageExpression = messageExpression; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/BlockStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/BlockStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/BlockStatement.java new file mode 100644 index 0000000..5013726 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/BlockStatement.java @@ -0,0 +1,117 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.VariableScope; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * A list of statements and a scope. + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class BlockStatement extends Statement { + + private List<Statement> statements = new ArrayList<Statement>(); + private VariableScope scope; + + public BlockStatement() { + this(new ArrayList<Statement>(), new VariableScope()); + } + + /** + * Creates a BlockStatement with a scope and children statements. + * @param statements + * the statements. Do not pass null. If you do, no exception will occur, + * but a NullPointerException will eventually occur later. Also, a reference + * to the list is kept, so modifying the List later does effect this class. + * @param scope + * the scope + */ + public BlockStatement(List<Statement> statements, VariableScope scope) { + this.statements = statements; + this.scope = scope; + } + + /** + * Creates a BlockStatement with a scope and children statements. + * @param statements + * the statements, which cannot be null or an exception occurs. No reference + * to the array is held, so modifying the array later has no effect on this + * class. + * @param scope + * the scope + */ + public BlockStatement(Statement[] statements, VariableScope scope) { + this.statements.addAll(Arrays.asList(statements)); + this.scope = scope; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitBlockStatement(this); + } + + public List<Statement> getStatements() { + return statements; + } + + public void addStatement(Statement statement) { + statements.add(statement); + } + + public void addStatements(List<Statement> listOfStatements) { + statements.addAll(listOfStatements); + } + + public String toString() { + return super.toString() + statements; + } + + public String getText() { + StringBuilder buffer = new StringBuilder("{ "); + boolean first = true; + for (Statement statement : statements) { + if (first) { + first = false; + } + else { + buffer.append("; "); + } + buffer.append(statement.getText()); + } + buffer.append(" }"); + return buffer.toString(); + } + + public boolean isEmpty() { + return statements.isEmpty(); + } + + public void setVariableScope(VariableScope scope) { + this.scope = scope; + } + + public VariableScope getVariableScope() { + return scope; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/BreakStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/BreakStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/BreakStatement.java new file mode 100644 index 0000000..5257991 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/BreakStatement.java @@ -0,0 +1,48 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; + + +/** + * Represents a break statement in a switch or loop statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class BreakStatement extends Statement { + + private String label; + + public BreakStatement() { + this(null); + } + + public BreakStatement(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitBreakStatement(this); + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/CaseStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/CaseStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/CaseStatement.java new file mode 100644 index 0000000..7c06e69 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/CaseStatement.java @@ -0,0 +1,63 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.Expression; + + +/** + * Represents a case statement in a switch statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class CaseStatement extends Statement { + + private Statement code; + private Expression expression; + + public CaseStatement(Expression expression, Statement code) { + this.expression = expression; + this.code = code; + } + + public Statement getCode() { + return code; + } + + public void setCode(Statement code) { + this.code = code; + } + + public Expression getExpression() { + return expression; + } + + public void setExpression(Expression e) { + expression=e; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitCaseStatement(this); + } + + public String toString() { + return super.toString() + "[expression: " + expression + "; code: " + code + "]"; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/CatchStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/CatchStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/CatchStatement.java new file mode 100644 index 0000000..3f40957 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/CatchStatement.java @@ -0,0 +1,61 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.Parameter; + + +/** + * Represents a catch (Exception var) { } statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class CatchStatement extends Statement { + + private Parameter variable; + + private Statement code; + + public CatchStatement(Parameter variable, Statement code) { + this.variable = variable; + this.code = code; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitCatchStatement(this); + } + + public Statement getCode() { + return code; + } + + public ClassNode getExceptionType() { + return variable.getType(); + } + + public Parameter getVariable() { + return variable; + } + + public void setCode(Statement code) { + this.code = code; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/ContinueStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ContinueStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ContinueStatement.java new file mode 100644 index 0000000..034dcf2 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/ContinueStatement.java @@ -0,0 +1,48 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; + + +/** + * Represents a continue statement in a loop statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class ContinueStatement extends Statement { + + private String label; + + public ContinueStatement() { + this(null); + } + + public ContinueStatement(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitContinueStatement(this); + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/DoWhileStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/DoWhileStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/DoWhileStatement.java new file mode 100644 index 0000000..a7b518b --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/DoWhileStatement.java @@ -0,0 +1,58 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.BooleanExpression; + +/** + * Represents a do { ... } while (condition) loop in Groovy + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class DoWhileStatement extends Statement implements LoopingStatement { + + private BooleanExpression booleanExpression; + private Statement loopBlock; + + + public DoWhileStatement(BooleanExpression booleanExpression, Statement loopBlock) { + this.booleanExpression = booleanExpression; + this.loopBlock = loopBlock; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitDoWhileLoop(this); + } + + public BooleanExpression getBooleanExpression() { + return booleanExpression; + } + + public Statement getLoopBlock() { + return loopBlock; + } + public void setBooleanExpression(BooleanExpression booleanExpression) { + this.booleanExpression = booleanExpression; + } + + public void setLoopBlock(Statement loopBlock) { + this.loopBlock = loopBlock; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java new file mode 100644 index 0000000..2ef78af --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java @@ -0,0 +1,115 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.ASTNode; +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.NodeMetaDataHandler; + +import java.util.Map; + +/** + * Represents an empty statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ + +public class EmptyStatement extends Statement { + public static final EmptyStatement INSTANCE = new EmptyStatement(); + + /** + * use EmptyStatement.INSTANCE instead + */ +// @Deprecated + private EmptyStatement() { + // org.spockframework.compiler.ConditionRewriter will create EmptyStatement via calling the constructor + // so we keep the constructor for the time being, but it will be removed finally. + } + + public void visit(GroovyCodeVisitor visitor) { + } + + public boolean isEmpty() { + return true; + } + + @Override + public void setStatementLabel(String label) { + throw createUnsupportedOperationException(); + } + + @Override + public void addStatementLabel(String label) { + throw createUnsupportedOperationException(); + } + + @Override + public void setLineNumber(int lineNumber) { + throw createUnsupportedOperationException(); + } + + @Override + public void setColumnNumber(int columnNumber) { + throw createUnsupportedOperationException(); + } + + @Override + public void setLastLineNumber(int lastLineNumber) { + throw createUnsupportedOperationException(); + } + + @Override + public void setLastColumnNumber(int lastColumnNumber) { + throw createUnsupportedOperationException(); + } + + @Override + public void setSourcePosition(ASTNode node) { + throw createUnsupportedOperationException(); + } + + @Override + public void copyNodeMetaData(NodeMetaDataHandler other) { + throw createUnsupportedOperationException(); + } + + @Override + public void setNodeMetaData(Object key, Object value) { + throw createUnsupportedOperationException(); + } + + @Override + public Object putNodeMetaData(Object key, Object value) { + throw createUnsupportedOperationException(); + } + + @Override + public void removeNodeMetaData(Object key) { + throw createUnsupportedOperationException(); + } + + @Override + public void setMetaDataMap(Map<?, ?> metaDataMap) { + throw createUnsupportedOperationException(); + } + + private UnsupportedOperationException createUnsupportedOperationException() { + return new UnsupportedOperationException("EmptyStatement.INSTANCE is immutable"); + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/ExpressionStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ExpressionStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ExpressionStatement.java new file mode 100644 index 0000000..c6376b2 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/ExpressionStatement.java @@ -0,0 +1,61 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.Expression; + + +/** + * A simple statement such as a method call where the return value is ignored + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class ExpressionStatement extends Statement { + + private Expression expression; + + public ExpressionStatement(Expression expression) { + if (expression == null) { + throw new IllegalArgumentException("expression cannot be null"); + } + this.expression = expression; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitExpressionStatement(this); + } + + public Expression getExpression() { + return expression; + } + + public void setExpression(Expression expression) { + this.expression = expression; + } + + public String getText() { + return expression.getText(); + } + + public String toString() { + return super.toString() + "[expression:" + expression + "]"; + } + +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/ForStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ForStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ForStatement.java new file mode 100644 index 0000000..072ee6e --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/ForStatement.java @@ -0,0 +1,83 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.ClassHelper; +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.Parameter; +import org.codehaus.groovy.ast.VariableScope; +import org.codehaus.groovy.ast.expr.Expression; + +/** + * Represents a standard for loop in Groovy + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class ForStatement extends Statement implements LoopingStatement { + public static final Parameter FOR_LOOP_DUMMY = new Parameter(ClassHelper.OBJECT_TYPE,"forLoopDummyParameter"); + + private Parameter variable; + private Expression collectionExpression; + private Statement loopBlock; + private VariableScope scope; + + + public ForStatement(Parameter variable, Expression collectionExpression, Statement loopBlock) { + this.variable = variable; + this.collectionExpression = collectionExpression; + this.loopBlock = loopBlock; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitForLoop(this); + } + + public Expression getCollectionExpression() { + return collectionExpression; + } + + public Statement getLoopBlock() { + return loopBlock; + } + + public Parameter getVariable() { + return variable; + } + + public ClassNode getVariableType() { + return variable.getType(); + } + + public void setCollectionExpression(Expression collectionExpression) { + this.collectionExpression = collectionExpression; + } + + public void setVariableScope(VariableScope variableScope) { + scope = variableScope; + } + + public VariableScope getVariableScope() { + return scope; + } + + public void setLoopBlock(Statement loopBlock) { + this.loopBlock = loopBlock; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java new file mode 100644 index 0000000..3f614cc --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java @@ -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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.BooleanExpression; + +/** + * Represents an if (condition) { ... } else { ... } statement in Groovy + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class IfStatement extends Statement { + + private BooleanExpression booleanExpression; + private Statement ifBlock; + private Statement elseBlock; + + + public IfStatement(BooleanExpression booleanExpression, Statement ifBlock, Statement elseBlock) { + this.booleanExpression = booleanExpression; + this.ifBlock = ifBlock; + this.elseBlock = elseBlock; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitIfElse(this); + } + + public BooleanExpression getBooleanExpression() { + return booleanExpression; + } + + public Statement getIfBlock() { + return ifBlock; + } + + public Statement getElseBlock() { + return elseBlock; + } + + public void setBooleanExpression(BooleanExpression booleanExpression) { + this.booleanExpression = booleanExpression; + } + + public void setIfBlock(Statement statement) { + ifBlock = statement; + } + + public void setElseBlock(Statement statement) { + elseBlock = statement; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/LoopingStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/LoopingStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/LoopingStatement.java new file mode 100644 index 0000000..4568103 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/LoopingStatement.java @@ -0,0 +1,38 @@ +/* + * 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.stmt; + +/** +* This is an AST Node that provides some sort of looping mechanism. Typically +* in the form of a block that will be executed repeatedly. +* DoWhileStatements, WhileStatements, and ForStatements are all examples of LoopingStatements. +* +* @author Hamlet D'Arcy +*/ +public interface LoopingStatement { + + /** + * Gets the loop block. + */ + Statement getLoopBlock(); + /** + * Sets the loop block. + */ + void setLoopBlock(Statement loopBlock); +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/ReturnStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ReturnStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ReturnStatement.java new file mode 100644 index 0000000..9e08ebd --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/ReturnStatement.java @@ -0,0 +1,72 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.ConstantExpression; +import org.codehaus.groovy.ast.expr.Expression; + +/** + * A return statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class ReturnStatement extends Statement { + /** + * Only used for synthetic return statements emitted by the compiler. + * For comparisons use isReturningNullOrVoid() instead. + */ + public static final ReturnStatement RETURN_NULL_OR_VOID = new ReturnStatement(ConstantExpression.NULL); + + private Expression expression; + + public ReturnStatement(ExpressionStatement statement) { + this(statement.getExpression()); + setStatementLabel(statement.getStatementLabel()); + } + + public ReturnStatement(Expression expression) { + this.expression = expression; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitReturnStatement(this); + } + + public Expression getExpression() { + return expression; + } + + public String getText() { + return "return " + expression.getText(); + } + + public void setExpression(Expression expression) { + this.expression = expression; + } + + public boolean isReturningNullOrVoid() { + return expression instanceof ConstantExpression + && ((ConstantExpression)expression).isNullExpression(); + } + + public String toString() { + return super.toString() + "[expression:" + expression + "]"; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/Statement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/Statement.java b/src/main/java/org/codehaus/groovy/ast/stmt/Statement.java new file mode 100644 index 0000000..80dbc4d --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/Statement.java @@ -0,0 +1,64 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.ASTNode; + +import java.util.LinkedList; +import java.util.List; + +/** + * Base class for any statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class Statement extends ASTNode { + + private List<String> statementLabels; + + public Statement() { + statementLabels = null; + } + + public List<String> getStatementLabels() { + return statementLabels; + } + + // TODO @Deprecated + public String getStatementLabel() { + // last label by default which is added first by APP + return statementLabels == null ? null : statementLabels.get(0); + } + + // TODO @Deprecated + public void setStatementLabel(String label) { + if (statementLabels == null) statementLabels = new LinkedList<String>(); + statementLabels.add(label); + } + + public void addStatementLabel(String label) { + if (statementLabels == null) statementLabels = new LinkedList<String>(); + statementLabels.add(label); + } + + public boolean isEmpty() { + return false; + } + +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/SwitchStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/SwitchStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/SwitchStatement.java new file mode 100644 index 0000000..bad0194 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/SwitchStatement.java @@ -0,0 +1,91 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.Expression; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a switch (object) { case value: ... case [1, 2, 3]: ... default: ... } statement in Groovy. + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class SwitchStatement extends Statement { + + private Expression expression; + private List<CaseStatement> caseStatements = new ArrayList<CaseStatement>(); + private Statement defaultStatement; + + + public SwitchStatement(Expression expression) { + this(expression, EmptyStatement.INSTANCE); + } + + public SwitchStatement(Expression expression, Statement defaultStatement) { + this.expression = expression; + this.defaultStatement = defaultStatement; + } + + public SwitchStatement(Expression expression, List<CaseStatement> caseStatements, Statement defaultStatement) { + this.expression = expression; + this.caseStatements = caseStatements; + this.defaultStatement = defaultStatement; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitSwitch(this); + } + + public List<CaseStatement> getCaseStatements() { + return caseStatements; + } + + public Expression getExpression() { + return expression; + } + + public void setExpression(Expression e) { + expression=e; + } + + public Statement getDefaultStatement() { + return defaultStatement; + } + + public void setDefaultStatement(Statement defaultStatement) { + this.defaultStatement = defaultStatement; + } + + public void addCase(CaseStatement caseStatement) { + caseStatements.add(caseStatement); + } + + /** + * @return the case statement of the given index or null + */ + public CaseStatement getCaseStatement(int idx) { + if (idx >= 0 && idx < caseStatements.size()) { + return caseStatements.get(idx); + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/SynchronizedStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/SynchronizedStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/SynchronizedStatement.java new file mode 100644 index 0000000..1fd3e5c --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/SynchronizedStatement.java @@ -0,0 +1,58 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.Expression; + + +/** + * Represents a synchronized statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class SynchronizedStatement extends Statement { + + private Statement code; + private Expression expression; + + public SynchronizedStatement(Expression expression, Statement code) { + this.expression = expression; + this.code = code; + } + + public Statement getCode() { + return code; + } + + public void setCode(Statement statement) { + code = statement; + } + + public Expression getExpression() { + return expression; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitSynchronizedStatement(this); + } + public void setExpression(Expression expression) { + this.expression = expression; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/ThrowStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ThrowStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ThrowStatement.java new file mode 100644 index 0000000..a217840 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/ThrowStatement.java @@ -0,0 +1,54 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.Expression; + + +/** + * Represents a throw statement + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class ThrowStatement extends Statement { + + private Expression expression; + + public ThrowStatement(Expression expression) { + this.expression = expression; + } + + public Expression getExpression() { + return expression; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitThrowStatement(this); + } + public void setExpression(Expression expression) { + this.expression = expression; + } + + @Override + public String getText() { + return "throw " + expression.getText(); + } + +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java new file mode 100644 index 0000000..f05460f --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java @@ -0,0 +1,108 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.DeclarationExpression; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a try { ... } catch () finally {} statement in Groovy + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class TryCatchStatement extends Statement { + + private Statement tryStatement; + private List<ExpressionStatement> resourceStatements = new ArrayList<ExpressionStatement>(); + private List<CatchStatement> catchStatements = new ArrayList<CatchStatement>(); + private Statement finallyStatement; + + + public TryCatchStatement(Statement tryStatement, Statement finallyStatement) { + this.tryStatement = tryStatement; + this.finallyStatement = finallyStatement; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitTryCatchFinally(this); + } + + public List<ExpressionStatement> getResourceStatements() { + return resourceStatements; + } + + public List<CatchStatement> getCatchStatements() { + return catchStatements; + } + + public Statement getFinallyStatement() { + return finallyStatement; + } + + public Statement getTryStatement() { + return tryStatement; + } + + public void addResource(ExpressionStatement resourceStatement) { + if (!(resourceStatement.getExpression() instanceof DeclarationExpression)) { + throw new IllegalArgumentException("resourceStatement should be a variable declaration statement"); + } + + resourceStatements.add(resourceStatement); + } + + public void addCatch(CatchStatement catchStatement) { + catchStatements.add(catchStatement); + } + + /** + * @return the catch statement of the given index or null + */ + public CatchStatement getCatchStatement(int idx) { + if (idx >= 0 && idx < catchStatements.size()) { + return catchStatements.get(idx); + } + return null; + } + + /** + * @return the resource statement of the given index or null + */ + public ExpressionStatement getResourceStatement(int idx) { + if (idx >= 0 && idx < resourceStatements.size()) { + return resourceStatements.get(idx); + } + return null; + } + + public void setTryStatement(Statement tryStatement) { + this.tryStatement = tryStatement; + } + + public void setCatchStatement(int idx, CatchStatement catchStatement) { + catchStatements.set(idx, catchStatement); + } + + public void setFinallyStatement(Statement finallyStatement) { + this.finallyStatement = finallyStatement; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/WhileStatement.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/WhileStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/WhileStatement.java new file mode 100644 index 0000000..e325481 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/WhileStatement.java @@ -0,0 +1,59 @@ +/* + * 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.stmt; + +import org.codehaus.groovy.ast.GroovyCodeVisitor; +import org.codehaus.groovy.ast.expr.BooleanExpression; + +/** + * Represents a while (condition) { ... } loop in Groovy + * + * @author <a href="mailto:[email protected]">James Strachan</a> + */ +public class WhileStatement extends Statement implements LoopingStatement { + + private BooleanExpression booleanExpression; + private Statement loopBlock; + + + public WhileStatement(BooleanExpression booleanExpression, Statement loopBlock) { + this.booleanExpression = booleanExpression; + this.loopBlock = loopBlock; + } + + public void visit(GroovyCodeVisitor visitor) { + visitor.visitWhileLoop(this); + } + + public BooleanExpression getBooleanExpression() { + return booleanExpression; + } + + public Statement getLoopBlock() { + return loopBlock; + } + + public void setBooleanExpression(BooleanExpression booleanExpression) { + this.booleanExpression = booleanExpression; + } + + public void setLoopBlock(Statement loopBlock) { + this.loopBlock = loopBlock; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/stmt/package.html ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/package.html b/src/main/java/org/codehaus/groovy/ast/stmt/package.html new file mode 100644 index 0000000..8226776 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/stmt/package.html @@ -0,0 +1,28 @@ +<!-- + + 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. + +--> +<html> + <head> + <title>package org.codehaus.groovy.ast.stmt.*</title> + </head> + <body> + <p>AST nodes for Groovy statements</p> + </body> +</html> http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java new file mode 100644 index 0000000..32d4a81 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java @@ -0,0 +1,120 @@ +/* + * 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.tools; + +import org.codehaus.groovy.ast.ClassHelper; +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.MethodNode; +import org.codehaus.groovy.ast.PropertyNode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static java.beans.Introspector.decapitalize; + +public class BeanUtils { + static final String GET_PREFIX = "get"; + static final String IS_PREFIX = "is"; + + /** + * Get all properties including JavaBean pseudo properties matching getter conventions. + * + * @param type the ClassNode + * @param includeSuperProperties whether to include super properties + * @param includeStatic whether to include static properties + * @param includePseudoGetters whether to include JavaBean pseudo (getXXX/isYYY) properties with no corresponding field + * @return the list of found property nodes + */ + public static List<PropertyNode> getAllProperties(ClassNode type, boolean includeSuperProperties, boolean includeStatic, boolean includePseudoGetters) { + // TODO add generics support so this can be used for @EAHC + // TODO add an includePseudoSetters so this can be used for @TupleConstructor + ClassNode node = type; + List<PropertyNode> result = new ArrayList<PropertyNode>(); + Set<String> names = new HashSet<String>(); + while (node != null) { + addExplicitProperties(node, result, names, includeStatic); + if (!includeSuperProperties) break; + node = node.getSuperClass(); + } + addPseudoProperties(type, result, names, includeStatic, includePseudoGetters, includeSuperProperties); + return result; + } + + private static void addExplicitProperties(ClassNode cNode, List<PropertyNode> result, Set<String> names, boolean includeStatic) { + for (PropertyNode pNode : cNode.getProperties()) { + if (includeStatic || !pNode.isStatic()) { + if (!names.contains(pNode.getName())) { + result.add(pNode); + names.add(pNode.getName()); + } + } + } + } + + private static void addPseudoProperties(ClassNode cNode, List<PropertyNode> result, Set<String> names, boolean includeStatic, boolean includePseudoGetters, boolean includeSuperProperties) { + if (!includePseudoGetters) return; + List<MethodNode> methods = cNode.getAllDeclaredMethods(); + ClassNode node = cNode.getSuperClass(); + if (includeSuperProperties) { + while (node != null) { + for (MethodNode next : node.getAllDeclaredMethods()) { + if (!next.isPrivate()) { + methods.add(next); + } + } + node = node.getSuperClass(); + } + } + for (MethodNode mNode : methods) { + if (!includeStatic && mNode.isStatic()) continue; + String name = mNode.getName(); + if ((name.length() <= 3 && !name.startsWith(IS_PREFIX)) || name.equals("getClass") || name.equals("getMetaClass") || name.equals("getDeclaringClass")) { + // Optimization: skip invalid propertyNames + continue; + } + if (mNode.getDeclaringClass() != cNode && mNode.isPrivate()) { + // skip private super methods + continue; + } + int paramCount = mNode.getParameters().length; + ClassNode returnType = mNode.getReturnType(); + if (paramCount == 0) { + if (name.startsWith(GET_PREFIX)) { + // Simple getter + String propName = decapitalize(name.substring(3)); + if (!names.contains(propName)) { + result.add(new PropertyNode(propName, mNode.getModifiers(), returnType, cNode, null, mNode.getCode(), null)); + names.add(propName); + } + } else { + if (name.startsWith(IS_PREFIX) && returnType.equals(ClassHelper.boolean_TYPE)) { + // boolean getter + String propName = decapitalize(name.substring(2)); + if (!names.contains(propName)) { + names.add(propName); + result.add(new PropertyNode(propName, mNode.getModifiers(), returnType, cNode, null, mNode.getCode(), null)); + } + } + } + } + } + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/tools/ClassNodeUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/tools/ClassNodeUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/ClassNodeUtils.java new file mode 100644 index 0000000..5c43586 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/tools/ClassNodeUtils.java @@ -0,0 +1,80 @@ +/* + * 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.tools; + +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.MethodNode; +import org.codehaus.groovy.ast.PropertyNode; +import org.codehaus.groovy.ast.expr.Expression; + +import java.util.Map; + +@Deprecated +public class ClassNodeUtils { + @Deprecated + public static void addInterfaceMethods(ClassNode cNode, Map<String, MethodNode> methodsMap) { + org.apache.groovy.ast.tools.ClassNodeUtils.addDeclaredMethodsFromInterfaces(cNode, methodsMap); + } + + @Deprecated + public static Map<String, MethodNode> getDeclaredMethodMapsFromInterfaces(ClassNode cNode) { + return org.apache.groovy.ast.tools.ClassNodeUtils.getDeclaredMethodsFromInterfaces(cNode); + } + + @Deprecated + public static void addDeclaredMethodMapsFromSuperInterfaces(ClassNode cNode, Map<String, MethodNode> methodsMap) { + org.apache.groovy.ast.tools.ClassNodeUtils.addDeclaredMethodsFromAllInterfaces(cNode, methodsMap); + } + + @Deprecated + public static boolean hasPossibleStaticMethod(ClassNode cNode, String name, Expression arguments, boolean trySpread) { + return org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticMethod(cNode, name, arguments, trySpread); + } + + @Deprecated + public static boolean hasPossibleStaticProperty(ClassNode cNode, String methodName) { + return org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticProperty(cNode, methodName); + } + + @Deprecated + public static String getPropNameForAccessor(String accessorName) { + return org.apache.groovy.ast.tools.ClassNodeUtils.getPropNameForAccessor(accessorName); + } + + @Deprecated + public static boolean isValidAccessorName(String accessorName) { + return org.apache.groovy.ast.tools.ClassNodeUtils.isValidAccessorName(accessorName); + } + + @Deprecated + public static boolean hasStaticProperty(ClassNode cNode, String propName) { + return org.apache.groovy.ast.tools.ClassNodeUtils.hasStaticProperty(cNode, propName); + } + + @Deprecated + public static PropertyNode getStaticProperty(ClassNode cNode, String propName) { + return org.apache.groovy.ast.tools.ClassNodeUtils.getStaticProperty(cNode, propName); + } + + @Deprecated + public static boolean isInnerClass(ClassNode cNode) { + return org.apache.groovy.ast.tools.ClassNodeUtils.isInnerClass(cNode); + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/0edfcde9/src/main/java/org/codehaus/groovy/ast/tools/ClosureUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/codehaus/groovy/ast/tools/ClosureUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/ClosureUtils.java new file mode 100644 index 0000000..06d4995 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/ast/tools/ClosureUtils.java @@ -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.tools; + +import groovy.lang.Closure; +import org.codehaus.groovy.ast.expr.ClosureExpression; +import org.codehaus.groovy.control.io.ReaderSource; +/** + * Handy methods when working with Closure AST data structures. + */ + +public class ClosureUtils { + + /** + * Converts a ClosureExpression into the String source. + * + * @param readerSource a source + * @param expression a closure. Can't be null + * @return the source the closure was created from + * @throws java.lang.IllegalArgumentException when expression is null + * @throws java.lang.Exception when closure can't be read from source + */ + public static String convertClosureToSource(ReaderSource readerSource, ClosureExpression expression) throws Exception { + String source = GeneralUtils.convertASTToSource(readerSource, expression); + if (!source.startsWith("{")) { + throw new Exception("Error converting ClosureExpression into source code. Closures must start with {. Found: " + source); + } + return source; + } + + /** + * Does the Closure have a single char-like (char or Character) argument. + * @param c a Closure + * @return true if it has exactly one argument and the type is char or Character + */ + public static boolean hasSingleCharacterArg(Closure c) { + if (c.getMaximumNumberOfParameters() != 1) return false; + String typeName = c.getParameterTypes()[0].getName(); + return typeName.equals("char") || typeName.equals("java.lang.Character"); + } + + /** + * Does the Closure have a single String argument. + * @param c a Closure + * @return true if it has exactly one argument and the type is String + */ + public static boolean hasSingleStringArg(Closure c) { + if (c.getMaximumNumberOfParameters() != 1) return false; + String typeName = c.getParameterTypes()[0].getName(); + return typeName.equals("java.lang.String"); + } + +}
