use of org.codehaus.groovy.ast.stmt.Statement in project groovy by apache.
the class TraitComposer method createDelegatingForwarder.
private static Statement createDelegatingForwarder(final MethodNode forwarderMethod, final ClassNode next) {
// generates --> next$Trait$Helper.method(this, arg1, arg2)
TraitHelpersTuple helpers = Traits.findHelpers(next);
ArgumentListExpression args = new ArgumentListExpression();
args.addExpression(new VariableExpression("this"));
Parameter[] forwarderMethodParameters = forwarderMethod.getParameters();
for (final Parameter forwarderMethodParameter : forwarderMethodParameters) {
args.addExpression(new VariableExpression(forwarderMethodParameter));
}
StaticMethodCallExpression delegateCall = new StaticMethodCallExpression(helpers.getHelper(), forwarderMethod.getName(), args);
Statement result;
if (ClassHelper.VOID_TYPE.equals(forwarderMethod.getReturnType())) {
BlockStatement stmt = new BlockStatement();
stmt.addStatement(new ExpressionStatement(delegateCall));
stmt.addStatement(new ReturnStatement(new ConstantExpression(null)));
result = stmt;
} else {
result = new ReturnStatement(delegateCall);
}
return result;
}
use of org.codehaus.groovy.ast.stmt.Statement in project groovy by apache.
the class Verifier method addInitialization.
protected void addInitialization(ClassNode node, ConstructorNode constructorNode) {
Statement firstStatement = constructorNode.getFirstStatement();
// if some transformation decided to generate constructor then it probably knows who it does
if (firstStatement instanceof BytecodeSequence)
return;
ConstructorCallExpression first = getFirstIfSpecialConstructorCall(firstStatement);
// in case of this(...) let the other constructor do the init
if (first != null && (first.isThisCall()))
return;
List<Statement> statements = new ArrayList<Statement>();
List<Statement> staticStatements = new ArrayList<Statement>();
final boolean isEnum = node.isEnum();
List<Statement> initStmtsAfterEnumValuesInit = new ArrayList<Statement>();
Set<String> explicitStaticPropsInEnum = new HashSet<String>();
if (isEnum) {
for (PropertyNode propNode : node.getProperties()) {
if (!propNode.isSynthetic() && propNode.getField().isStatic()) {
explicitStaticPropsInEnum.add(propNode.getField().getName());
}
}
for (FieldNode fieldNode : node.getFields()) {
if (!fieldNode.isSynthetic() && fieldNode.isStatic() && fieldNode.getType() != node) {
explicitStaticPropsInEnum.add(fieldNode.getName());
}
}
}
if (!Traits.isTrait(node)) {
for (FieldNode fn : node.getFields()) {
addFieldInitialization(statements, staticStatements, fn, isEnum, initStmtsAfterEnumValuesInit, explicitStaticPropsInEnum);
}
}
statements.addAll(node.getObjectInitializerStatements());
Statement code = constructorNode.getCode();
BlockStatement block = new BlockStatement();
List<Statement> otherStatements = block.getStatements();
if (code instanceof BlockStatement) {
block = (BlockStatement) code;
otherStatements = block.getStatements();
} else if (code != null) {
otherStatements.add(code);
}
if (!otherStatements.isEmpty()) {
if (first != null) {
// it is super(..) since this(..) is already covered
otherStatements.remove(0);
statements.add(0, firstStatement);
}
Statement stmtThis$0 = getImplicitThis$0StmtIfInnerClass(otherStatements);
if (stmtThis$0 != null) {
// since there can be field init statements that depend on method/property dispatching
// that uses this$0, it needs to bubble up before the super call itself (GROOVY-4471)
statements.add(0, stmtThis$0);
}
statements.addAll(otherStatements);
}
BlockStatement newBlock = new BlockStatement(statements, block.getVariableScope());
newBlock.setSourcePosition(block);
constructorNode.setCode(newBlock);
if (!staticStatements.isEmpty()) {
if (isEnum) {
/*
* GROOVY-3161: initialize statements for explicitly declared static fields
* inside an enum should come after enum values are initialized
*/
staticStatements.removeAll(initStmtsAfterEnumValuesInit);
node.addStaticInitializerStatements(staticStatements, true);
if (!initStmtsAfterEnumValuesInit.isEmpty()) {
node.positionStmtsAfterEnumInitStmts(initStmtsAfterEnumValuesInit);
}
} else {
node.addStaticInitializerStatements(staticStatements, true);
}
}
}
use of org.codehaus.groovy.ast.stmt.Statement in project groovy by apache.
the class InnerClassCompletionVisitor method addThisReference.
private void addThisReference(ConstructorNode node) {
if (!shouldHandleImplicitThisForInnerClass(classNode))
return;
Statement code = node.getCode();
// add "this$0" field init
//add this parameter to node
Parameter[] params = node.getParameters();
Parameter[] newParams = new Parameter[params.length + 1];
System.arraycopy(params, 0, newParams, 1, params.length);
String name = getUniqueName(params, node);
Parameter thisPara = new Parameter(classNode.getOuterClass().getPlainNodeReference(), name);
newParams[0] = thisPara;
node.setParameters(newParams);
BlockStatement block = null;
if (code == null) {
block = new BlockStatement();
} else if (!(code instanceof BlockStatement)) {
block = new BlockStatement();
block.addStatement(code);
} else {
block = (BlockStatement) code;
}
BlockStatement newCode = new BlockStatement();
addFieldInit(thisPara, thisField, newCode);
ConstructorCallExpression cce = getFirstIfSpecialConstructorCall(block);
if (cce == null) {
cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression());
block.getStatements().add(0, new ExpressionStatement(cce));
}
if (shouldImplicitlyPassThisPara(cce)) {
// add thisPara to this(...)
TupleExpression args = (TupleExpression) cce.getArguments();
List<Expression> expressions = args.getExpressions();
VariableExpression ve = new VariableExpression(thisPara.getName());
ve.setAccessedVariable(thisPara);
expressions.add(0, ve);
}
if (cce.isSuperCall()) {
// we have a call to super here, so we need to add
// our code after that
block.getStatements().add(1, newCode);
}
node.setCode(block);
}
use of org.codehaus.groovy.ast.stmt.Statement in project groovy by apache.
the class InnerClassCompletionVisitor method getFirstIfSpecialConstructorCall.
private static ConstructorCallExpression getFirstIfSpecialConstructorCall(BlockStatement code) {
if (code == null)
return null;
final List<Statement> statementList = code.getStatements();
if (statementList.isEmpty())
return null;
final Statement statement = statementList.get(0);
if (!(statement instanceof ExpressionStatement))
return null;
Expression expression = ((ExpressionStatement) statement).getExpression();
if (!(expression instanceof ConstructorCallExpression))
return null;
ConstructorCallExpression cce = (ConstructorCallExpression) expression;
if (cce.isSpecialCall())
return cce;
return null;
}
use of org.codehaus.groovy.ast.stmt.Statement in project groovy by apache.
the class VariableScopeVisitor method visitConstructorCallExpression.
public void visitConstructorCallExpression(ConstructorCallExpression call) {
isSpecialConstructorCall = call.isSpecialCall();
super.visitConstructorCallExpression(call);
isSpecialConstructorCall = false;
if (!call.isUsingAnonymousInnerClass())
return;
pushState();
InnerClassNode innerClass = (InnerClassNode) call.getType();
innerClass.setVariableScope(currentScope);
for (MethodNode method : innerClass.getMethods()) {
Parameter[] parameters = method.getParameters();
// null means no implicit "it"
if (parameters.length == 0)
parameters = null;
ClosureExpression cl = new ClosureExpression(parameters, method.getCode());
visitClosureExpression(cl);
}
for (FieldNode field : innerClass.getFields()) {
final Expression expression = field.getInitialExpression();
pushState(field.isStatic());
if (expression != null) {
if (expression instanceof VariableExpression) {
VariableExpression vexp = (VariableExpression) expression;
if (vexp.getAccessedVariable() instanceof Parameter) {
// workaround for GROOVY-6834: accessing a parameter which is not yet seen in scope
popState();
continue;
}
}
expression.visit(this);
}
popState();
}
for (Statement statement : innerClass.getObjectInitializerStatements()) {
statement.visit(this);
}
markClosureSharedVariables();
popState();
}
Aggregations