use of org.codehaus.groovy.ast.VariableScope in project groovy-core by groovy.
the class InnerClassVisitor method visitConstructorCallExpression.
@Override
public void visitConstructorCallExpression(ConstructorCallExpression call) {
super.visitConstructorCallExpression(call);
if (!call.isUsingAnonymousInnerClass()) {
passThisReference(call);
return;
}
InnerClassNode innerClass = (InnerClassNode) call.getType();
ClassNode outerClass = innerClass.getOuterClass();
ClassNode superClass = innerClass.getSuperClass();
if (superClass instanceof InnerClassNode && !superClass.isInterface() && !(superClass.isStaticClass() || ((superClass.getModifiers() & ACC_STATIC) == ACC_STATIC))) {
insertThis0ToSuperCall(call, innerClass);
}
if (!innerClass.getDeclaredConstructors().isEmpty())
return;
if ((innerClass.getModifiers() & ACC_STATIC) != 0)
return;
VariableScope scope = innerClass.getVariableScope();
if (scope == null)
return;
// expressions = constructor call arguments
List<Expression> expressions = ((TupleExpression) call.getArguments()).getExpressions();
// block = init code for the constructor we produce
BlockStatement block = new BlockStatement();
// parameters = parameters of the constructor
final int additionalParamCount = 1 + scope.getReferencedLocalVariablesCount();
List<Parameter> parameters = new ArrayList<Parameter>(expressions.size() + additionalParamCount);
// superCallArguments = arguments for the super call == the constructor call arguments
List<Expression> superCallArguments = new ArrayList<Expression>(expressions.size());
// first we add a super() call for all expressions given in the
// constructor call expression
int pCount = additionalParamCount;
for (Expression expr : expressions) {
pCount++;
// add one parameter for each expression in the
// constructor call
Parameter param = new Parameter(ClassHelper.OBJECT_TYPE, "p" + pCount);
parameters.add(param);
// add to super call
superCallArguments.add(new VariableExpression(param));
}
// add the super call
ConstructorCallExpression cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression(superCallArguments));
block.addStatement(new ExpressionStatement(cce));
// we need to add "this" to access unknown methods/properties
// this is saved in a field named this$0
pCount = 0;
expressions.add(pCount, VariableExpression.THIS_EXPRESSION);
boolean isStatic = isStaticThis(innerClass, scope);
ClassNode outerClassType = getClassNode(outerClass, isStatic);
if (!isStatic && inClosure)
outerClassType = ClassHelper.CLOSURE_TYPE;
outerClassType = outerClassType.getPlainNodeReference();
Parameter thisParameter = new Parameter(outerClassType, "p" + pCount);
parameters.add(pCount, thisParameter);
thisField = innerClass.addField("this$0", PUBLIC_SYNTHETIC, outerClassType, null);
addFieldInit(thisParameter, thisField, block);
// for each shared variable we add a reference and save it as field
for (Iterator it = scope.getReferencedLocalVariablesIterator(); it.hasNext(); ) {
pCount++;
org.codehaus.groovy.ast.Variable var = (org.codehaus.groovy.ast.Variable) it.next();
VariableExpression ve = new VariableExpression(var);
ve.setClosureSharedVariable(true);
ve.setUseReferenceDirectly(true);
expressions.add(pCount, ve);
ClassNode rawReferenceType = ClassHelper.REFERENCE_TYPE.getPlainNodeReference();
Parameter p = new Parameter(rawReferenceType, "p" + pCount);
parameters.add(pCount, p);
p.setOriginType(var.getOriginType());
final VariableExpression initial = new VariableExpression(p);
initial.setSynthetic(true);
initial.setUseReferenceDirectly(true);
final FieldNode pField = innerClass.addFieldFirst(ve.getName(), PUBLIC_SYNTHETIC, rawReferenceType, initial);
pField.setHolder(true);
pField.setOriginType(ClassHelper.getWrapper(var.getOriginType()));
}
innerClass.addConstructor(ACC_SYNTHETIC, parameters.toArray(new Parameter[parameters.size()]), ClassNode.EMPTY_ARRAY, block);
}
use of org.codehaus.groovy.ast.VariableScope in project groovy-core by groovy.
the class ReturnAdder method addReturnsIfNeeded.
private Statement addReturnsIfNeeded(Statement statement, VariableScope scope) {
if (statement instanceof ReturnStatement || statement instanceof BytecodeSequence || statement instanceof ThrowStatement) {
return statement;
}
if (statement instanceof EmptyStatement) {
final ReturnStatement returnStatement = new ReturnStatement(ConstantExpression.NULL);
listener.returnStatementAdded(returnStatement);
return returnStatement;
}
if (statement instanceof ExpressionStatement) {
ExpressionStatement expStmt = (ExpressionStatement) statement;
Expression expr = expStmt.getExpression();
ReturnStatement ret = new ReturnStatement(expr);
ret.setSourcePosition(expr);
ret.setStatementLabel(statement.getStatementLabel());
listener.returnStatementAdded(ret);
return ret;
}
if (statement instanceof SynchronizedStatement) {
SynchronizedStatement sync = (SynchronizedStatement) statement;
final Statement code = addReturnsIfNeeded(sync.getCode(), scope);
if (doAdd)
sync.setCode(code);
return sync;
}
if (statement instanceof IfStatement) {
IfStatement ifs = (IfStatement) statement;
final Statement ifBlock = addReturnsIfNeeded(ifs.getIfBlock(), scope);
final Statement elseBlock = addReturnsIfNeeded(ifs.getElseBlock(), scope);
if (doAdd) {
ifs.setIfBlock(ifBlock);
ifs.setElseBlock(elseBlock);
}
return ifs;
}
if (statement instanceof SwitchStatement) {
SwitchStatement swi = (SwitchStatement) statement;
for (CaseStatement caseStatement : swi.getCaseStatements()) {
final Statement code = adjustSwitchCaseCode(caseStatement.getCode(), scope, false);
if (doAdd)
caseStatement.setCode(code);
}
final Statement defaultStatement = adjustSwitchCaseCode(swi.getDefaultStatement(), scope, true);
if (doAdd)
swi.setDefaultStatement(defaultStatement);
return swi;
}
if (statement instanceof TryCatchStatement) {
TryCatchStatement trys = (TryCatchStatement) statement;
final boolean[] missesReturn = new boolean[1];
new ReturnAdder(new ReturnStatementListener() {
@Override
public void returnStatementAdded(ReturnStatement returnStatement) {
missesReturn[0] = true;
}
}).addReturnsIfNeeded(trys.getFinallyStatement(), scope);
boolean hasFinally = !(trys.getFinallyStatement() instanceof EmptyStatement);
// there is nothing to do
if (hasFinally && !missesReturn[0])
return trys;
// add returns to try and catch blocks
final Statement tryStatement = addReturnsIfNeeded(trys.getTryStatement(), scope);
if (doAdd)
trys.setTryStatement(tryStatement);
final int len = trys.getCatchStatements().size();
for (int i = 0; i != len; ++i) {
final CatchStatement catchStatement = trys.getCatchStatement(i);
final Statement code = addReturnsIfNeeded(catchStatement.getCode(), scope);
if (doAdd)
catchStatement.setCode(code);
}
return trys;
}
if (statement instanceof BlockStatement) {
BlockStatement block = (BlockStatement) statement;
final List list = block.getStatements();
if (!list.isEmpty()) {
int idx = list.size() - 1;
Statement last = addReturnsIfNeeded((Statement) list.get(idx), block.getVariableScope());
if (doAdd)
list.set(idx, last);
if (!statementReturns(last)) {
final ReturnStatement returnStatement = new ReturnStatement(ConstantExpression.NULL);
listener.returnStatementAdded(returnStatement);
if (doAdd)
list.add(returnStatement);
}
} else {
ReturnStatement ret = new ReturnStatement(ConstantExpression.NULL);
ret.setSourcePosition(block);
listener.returnStatementAdded(ret);
return ret;
}
BlockStatement newBlock = new BlockStatement(list, block.getVariableScope());
newBlock.setSourcePosition(block);
return newBlock;
}
if (statement == null) {
final ReturnStatement returnStatement = new ReturnStatement(ConstantExpression.NULL);
listener.returnStatementAdded(returnStatement);
return returnStatement;
} else {
final List list = new ArrayList();
list.add(statement);
final ReturnStatement returnStatement = new ReturnStatement(ConstantExpression.NULL);
listener.returnStatementAdded(returnStatement);
list.add(returnStatement);
BlockStatement newBlock = new BlockStatement(list, new VariableScope(scope));
newBlock.setSourcePosition(statement);
return newBlock;
}
}
use of org.codehaus.groovy.ast.VariableScope in project groovy-core by groovy.
the class AutoNewLineTransformer method visitClosureExpression.
@Override
public void visitClosureExpression(final ClosureExpression expression) {
super.visitClosureExpression(expression);
if (inBuilderMethod) {
Statement oldCode = expression.getCode();
BlockStatement block = oldCode instanceof BlockStatement ? ((BlockStatement) oldCode) : new BlockStatement(Arrays.asList(oldCode), new VariableScope());
List<Statement> statements = block.getStatements();
if (!statements.isEmpty()) {
Statement first = statements.get(0);
Statement last = statements.get(statements.size() - 1);
if (expression.getLineNumber() < first.getLineNumber()) {
// there's a new line between { -> ... and the first statement
statements.add(0, createNewLine(expression));
}
if (expression.getLastLineNumber() > last.getLastLineNumber()) {
// there's a new line between { -> ... and the first statement
statements.add(createNewLine(expression));
}
}
expression.setCode(block);
}
}
use of org.codehaus.groovy.ast.VariableScope in project groovy-core by groovy.
the class AutoCloneASTTransformation method createCloneSerialization.
private void createCloneSerialization(ClassNode cNode) {
final BlockStatement body = new BlockStatement();
// def baos = new ByteArrayOutputStream()
final Expression baos = varX("baos");
body.addStatement(declS(baos, ctorX(BAOS_TYPE)));
// baos.withObjectOutputStream{ it.writeObject(this) }
MethodCallExpression writeObject = callX(castX(OOS_TYPE, varX("it")), "writeObject", varX("this"));
writeObject.setImplicitThis(false);
ClosureExpression writeClos = closureX(block(stmt(writeObject)));
writeClos.setVariableScope(new VariableScope());
body.addStatement(stmt(callX(baos, "withObjectOutputStream", args(writeClos))));
// def bais = new ByteArrayInputStream(baos.toByteArray())
final Expression bais = varX("bais");
body.addStatement(declS(bais, ctorX(BAIS_TYPE, args(callX(baos, "toByteArray")))));
// return bais.withObjectInputStream(getClass().classLoader){ (<type>) it.readObject() }
MethodCallExpression readObject = callX(castX(OIS_TYPE, varX("it")), "readObject");
readObject.setImplicitThis(false);
ClosureExpression readClos = closureX(block(stmt(castX(GenericsUtils.nonGeneric(cNode), readObject))));
readClos.setVariableScope(new VariableScope());
Expression classLoader = callX(callThisX("getClass"), "getClassLoader");
body.addStatement(returnS(callX(bais, "withObjectInputStream", args(classLoader, readClos))));
new VariableScopeVisitor(sourceUnit, true).visitClass(cNode);
ClassNode[] exceptions = { make(CloneNotSupportedException.class) };
cNode.addMethod("clone", ACC_PUBLIC, GenericsUtils.nonGeneric(cNode), Parameter.EMPTY_ARRAY, exceptions, body);
}
use of org.codehaus.groovy.ast.VariableScope in project spring-boot by spring-projects.
the class ResolveDependencyCoordinatesTransformationTests method transformationOfAnnotationOnLocalVariable.
@Test
public void transformationOfAnnotationOnLocalVariable() {
ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
this.moduleNode.addClass(classNode);
DeclarationExpression declarationExpression = new DeclarationExpression(new VariableExpression("test"), null, new ConstantExpression("test"));
declarationExpression.addAnnotation(this.grabAnnotation);
BlockStatement code = new BlockStatement(Arrays.asList((Statement) new ExpressionStatement(declarationExpression)), new VariableScope());
MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class), new Parameter[0], new ClassNode[0], code);
classNode.addMethod(methodNode);
assertGrabAnnotationHasBeenTransformed();
}
Aggregations