@Override
public void visitForLoop(ForStatement forLoop) {
Expression exp = forLoop.getCollectionExpression();
exp.visit(this);
Parameter loopParam = forLoop.getVariable();
if (loopParam != null) {
varStack.getLast().add(loopParam.getName());
}
super.visitForLoop(forLoop);
}
@Override
public void visitExpressionStatement(ExpressionStatement es) {
// GROOVY-3543: visit the declaration expressions so that declaration variables get added on the varStack
Expression exp = es.getExpression();
if (exp instanceof DeclarationExpression) {
exp.visit(this);
}
super.visitExpressionStatement(es);
}
@Override
public Expression transform(Expression exp) {
if (exp instanceof VariableExpression) {
VariableExpression ve = (VariableExpression) exp;
if (ve.getName().equals("this"))
return thisExpression;
else {
if (!varStack.getLast().contains(ve.getName())) {
return new PropertyExpression(thisExpression, ve.getName());
}
}
} else if (exp instanceof PropertyExpression) {
PropertyExpression pe = (PropertyExpression) exp;
if (pe.getObjectExpression() instanceof VariableExpression) {
VariableExpression vex = (VariableExpression) pe.getObjectExpression();
if (vex.isThisExpression()) {
pe.setObjectExpression(thisExpression);
return pe;
}
}
} else if (exp instanceof ClosureExpression) {
ClosureExpression ce = (ClosureExpression) exp;
ce.getVariableScope().putReferencedLocalVariable((Parameter) parameter.get());
Parameter[] params = ce.getParameters();
if (params == null) {
params = new Parameter[0];
} else if (params.length == 0) {
params = new Parameter[]{
new Parameter(ClassHelper.OBJECT_TYPE, "it")
};
}
addVariablesToStack(params);
ce.getCode().visit(this);
varStack.removeLast();
}
return super.transform(exp);
}
};
for (MethodNode method : parent.getMethods()) {
if (!method.isStatic()) {
method.setModifiers(method.getModifiers() | Opcodes.ACC_STATIC);
final Parameter[] origParams = method.getParameters();
final Parameter[] newParams = new Parameter[origParams.length + 1];
Parameter p = new Parameter(targetClass, "$this");
p.setClosureSharedVariable(true);
newParams[0] = p;
parameter.set(p);
System.arraycopy(origParams, 0, newParams, 1, origParams.length);
method.setParameters(newParams);