use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy-core by groovy.
the class StaticCompilationVisitor method addPrivateBridgeMethods.
/**
* This method is used to add "bridge" methods for private methods of an inner/outer
* class, so that the outer class is capable of calling them. It does basically
* the same job as access$000 like methods in Java.
*
* @param node an inner/outer class node for which to generate bridge methods
*/
@SuppressWarnings("unchecked")
private void addPrivateBridgeMethods(final ClassNode node) {
Set<ASTNode> accessedMethods = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_METHODS_ACCESS);
if (accessedMethods == null)
return;
List<MethodNode> methods = new ArrayList<MethodNode>(node.getAllDeclaredMethods());
Map<MethodNode, MethodNode> privateBridgeMethods = (Map<MethodNode, MethodNode>) node.getNodeMetaData(PRIVATE_BRIDGE_METHODS);
if (privateBridgeMethods != null) {
// private bridge methods already added
return;
}
privateBridgeMethods = new HashMap<MethodNode, MethodNode>();
int i = -1;
final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
for (MethodNode method : methods) {
if (accessedMethods.contains(method)) {
List<String> methodSpecificGenerics = methodSpecificGenerics(method);
i++;
ClassNode declaringClass = method.getDeclaringClass();
Map<String, ClassNode> genericsSpec = createGenericsSpec(node);
genericsSpec = addMethodGenerics(method, genericsSpec);
extractSuperClassGenerics(node, declaringClass, genericsSpec);
Parameter[] methodParameters = method.getParameters();
Parameter[] newParams = new Parameter[methodParameters.length + 1];
for (int j = 1; j < newParams.length; j++) {
Parameter orig = methodParameters[j - 1];
newParams[j] = new Parameter(correctToGenericsSpecRecurse(genericsSpec, orig.getOriginType(), methodSpecificGenerics), orig.getName());
}
newParams[0] = new Parameter(node.getPlainNodeReference(), "$that");
Expression arguments;
if (method.getParameters() == null || method.getParameters().length == 0) {
arguments = ArgumentListExpression.EMPTY_ARGUMENTS;
} else {
List<Expression> args = new LinkedList<Expression>();
for (Parameter parameter : methodParameters) {
args.add(new VariableExpression(parameter));
}
arguments = new ArgumentListExpression(args);
}
Expression receiver = method.isStatic() ? new ClassExpression(node) : new VariableExpression(newParams[0]);
MethodCallExpression mce = new MethodCallExpression(receiver, method.getName(), arguments);
mce.setMethodTarget(method);
ExpressionStatement returnStatement = new ExpressionStatement(mce);
MethodNode bridge = node.addMethod("access$" + i, access, correctToGenericsSpecRecurse(genericsSpec, method.getReturnType(), methodSpecificGenerics), newParams, method.getExceptions(), returnStatement);
GenericsType[] origGenericsTypes = method.getGenericsTypes();
if (origGenericsTypes != null) {
bridge.setGenericsTypes(applyGenericsContextToPlaceHolders(genericsSpec, origGenericsTypes));
}
privateBridgeMethods.put(method, bridge);
bridge.addAnnotation(new AnnotationNode(COMPILESTATIC_CLASSNODE));
}
}
if (!privateBridgeMethods.isEmpty()) {
node.setNodeMetaData(PRIVATE_BRIDGE_METHODS, privateBridgeMethods);
}
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy-core by groovy.
the class CategoryASTTransformation method visit.
/**
* Property invocations done on 'this' reference are transformed so that the invocations at runtime are
* done on the additional parameter 'self'
*/
public void visit(ASTNode[] nodes, final SourceUnit source) {
if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof ClassNode)) {
source.getErrorCollector().addError(new SyntaxErrorMessage(new SyntaxException("@Category can only be added to a ClassNode but got: " + (nodes.length == 2 ? nodes[1] : "nothing"), nodes[0].getLineNumber(), nodes[0].getColumnNumber()), source));
}
AnnotationNode annotation = (AnnotationNode) nodes[0];
ClassNode parent = (ClassNode) nodes[1];
ClassNode targetClass = getTargetClass(source, annotation);
thisExpression.setType(targetClass);
final LinkedList<Set<String>> varStack = new LinkedList<Set<String>>();
if (!ensureNoInstanceFieldOrProperty(source, parent))
return;
Set<String> names = new HashSet<String>();
for (FieldNode field : parent.getFields()) {
names.add(field.getName());
}
for (PropertyNode field : parent.getProperties()) {
names.add(field.getName());
}
varStack.add(names);
final Reference parameter = new Reference();
final ClassCodeExpressionTransformer expressionTransformer = new ClassCodeExpressionTransformer() {
protected SourceUnit getSourceUnit() {
return source;
}
private void addVariablesToStack(Parameter[] params) {
Set<String> names = new HashSet<String>();
names.addAll(varStack.getLast());
for (Parameter param : params) {
names.add(param.getName());
}
varStack.add(names);
}
@Override
public void visitCatchStatement(CatchStatement statement) {
varStack.getLast().add(statement.getVariable().getName());
super.visitCatchStatement(statement);
varStack.getLast().remove(statement.getVariable().getName());
}
@Override
public void visitMethod(MethodNode node) {
addVariablesToStack(node.getParameters());
super.visitMethod(node);
varStack.removeLast();
}
@Override
public void visitBlockStatement(BlockStatement block) {
Set<String> names = new HashSet<String>();
names.addAll(varStack.getLast());
varStack.add(names);
super.visitBlockStatement(block);
varStack.remove(names);
}
@Override
public void visitClosureExpression(ClosureExpression ce) {
addVariablesToStack(ce.getParameters());
super.visitClosureExpression(ce);
varStack.removeLast();
}
@Override
public void visitDeclarationExpression(DeclarationExpression expression) {
if (expression.isMultipleAssignmentDeclaration()) {
TupleExpression te = expression.getTupleExpression();
List<Expression> list = te.getExpressions();
for (Expression arg : list) {
VariableExpression ve = (VariableExpression) arg;
varStack.getLast().add(ve.getName());
}
} else {
VariableExpression ve = expression.getVariableExpression();
varStack.getLast().add(ve.getName());
}
super.visitDeclarationExpression(expression);
}
@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 = Parameter.EMPTY_ARRAY;
} 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);
expressionTransformer.visitMethod(method);
}
}
new VariableScopeVisitor(source, true).visitClass(parent);
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project grails-core by grails.
the class TagLibraryTransformer method addAttributesAndStringBodyMethod.
private void addAttributesAndStringBodyMethod(ClassNode classNode, String tagName) {
BlockStatement methodBody = new BlockStatement();
ArgumentListExpression arguments = new ArgumentListExpression();
ArgumentListExpression constructorArgs = new ArgumentListExpression();
constructorArgs.addExpression(BODY_EXPRESSION);
arguments.addExpression(new CastExpression(ClassHelper.make(Map.class), ATTRS_EXPRESSION)).addExpression(new ConstructorCallExpression(new ClassNode(TagOutput.ConstantClosure.class), constructorArgs));
methodBody.addStatement(new ExpressionStatement(new MethodCallExpression(new VariableExpression("this"), tagName, arguments)));
classNode.addMethod(new MethodNode(tagName, Modifier.PUBLIC, GrailsASTUtils.OBJECT_CLASS_NODE, MAP_CHARSEQUENCE_PARAMETERS, null, methodBody));
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy-core by groovy.
the class GrabAnnotationTransformation method addGrabResolverAsStaticInitIfNeeded.
private void addGrabResolverAsStaticInitIfNeeded(ClassNode grapeClassNode, AnnotationNode node, List<Statement> grabResolverInitializers, Map<String, Object> grabResolverMap) {
if ((node.getMember("initClass") == null) || (node.getMember("initClass") == ConstantExpression.TRUE)) {
MapExpression resolverArgs = new MapExpression();
for (Map.Entry<String, Object> next : grabResolverMap.entrySet()) {
resolverArgs.addMapEntryExpression(new ConstantExpression(next.getKey()), new ConstantExpression(next.getValue()));
}
grabResolverInitializers.add(new ExpressionStatement(new StaticMethodCallExpression(grapeClassNode, "addResolver", new ArgumentListExpression(resolverArgs))));
}
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy-core by groovy.
the class GrabAnnotationTransformation method addInitContextClassLoaderIfNeeded.
private void addInitContextClassLoaderIfNeeded(ClassNode classNode) {
if (initContextClassLoader) {
Statement initStatement = new ExpressionStatement(new MethodCallExpression(new StaticMethodCallExpression(THREAD_CLASSNODE, "currentThread", ArgumentListExpression.EMPTY_ARGUMENTS), "setContextClassLoader", new MethodCallExpression(new MethodCallExpression(VariableExpression.THIS_EXPRESSION, "getClass", MethodCallExpression.NO_ARGUMENTS), "getClassLoader", ArgumentListExpression.EMPTY_ARGUMENTS)));
classNode.addObjectInitializerStatements(initStatement);
}
}
Aggregations