use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy by apache.
the class ModuleNode method createStatementsClass.
protected ClassNode createStatementsClass() {
ClassNode classNode = getScriptClassDummy();
if (classNode.getName().endsWith("package-info")) {
return classNode;
}
handleMainMethodIfPresent(methods);
// return new Foo(new ShellContext(args)).run()
classNode.addMethod(new MethodNode("main", ACC_PUBLIC | ACC_STATIC, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(ClassHelper.STRING_TYPE.makeArray(), "args") }, ClassNode.EMPTY_ARRAY, new ExpressionStatement(new MethodCallExpression(new ClassExpression(ClassHelper.make(InvokerHelper.class)), "runScript", new ArgumentListExpression(new ClassExpression(classNode), new VariableExpression("args"))))));
MethodNode methodNode = new MethodNode("run", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, statementBlock);
methodNode.setIsScriptBody();
classNode.addMethod(methodNode);
classNode.addConstructor(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement());
Statement stmt;
// (like @BaseScript) that could change this. But this is cautious and anticipates possible compiler changes.
if (classNode.getSuperClass().getDeclaredConstructor(SCRIPT_CONTEXT_CTOR) != null) {
stmt = new ExpressionStatement(new ConstructorCallExpression(ClassNode.SUPER, new ArgumentListExpression(new VariableExpression("context"))));
} else {
// Fallback for non-standard base "script" classes with no context (Binding) constructor.
stmt = new ExpressionStatement(new MethodCallExpression(new VariableExpression("super"), "setBinding", new ArgumentListExpression(new VariableExpression("context"))));
}
classNode.addConstructor(ACC_PUBLIC, new Parameter[] { new Parameter(ClassHelper.make(Binding.class), "context") }, ClassNode.EMPTY_ARRAY, stmt);
for (MethodNode node : methods) {
int modifiers = node.getModifiers();
if ((modifiers & ACC_ABSTRACT) != 0) {
throw new RuntimeException("Cannot use abstract methods in a script, they are only available inside classes. Method: " + node.getName());
}
// br: the old logic seems to add static to all def f().... in a script, which makes enclosing
// inner classes (including closures) in a def function difficult. Comment it out.
node.setModifiers(modifiers);
classNode.addMethod(node);
}
return classNode;
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy by apache.
the class ConstructorNode method firstStatementIsSpecialConstructorCall.
public boolean firstStatementIsSpecialConstructorCall() {
Statement code = getFirstStatement();
if (code == null || !(code instanceof ExpressionStatement))
return false;
Expression expression = ((ExpressionStatement) code).getExpression();
if (!(expression instanceof ConstructorCallExpression))
return false;
ConstructorCallExpression cce = (ConstructorCallExpression) expression;
return cce.isSpecialCall();
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy by apache.
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 static 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());
methods.addAll(node.getDeclaredConstructors());
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());
}
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);
}
MethodNode bridge;
if (method instanceof ConstructorNode) {
// create constructor with a nested class as the first parameter, creating one if necessary
ClassNode thatType = null;
Iterator<InnerClassNode> innerClasses = node.getInnerClasses();
if (innerClasses.hasNext()) {
thatType = innerClasses.next();
} else {
thatType = new InnerClassNode(node.redirect(), node.getName() + "$1", ACC_STATIC | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE);
node.getModule().addClass(thatType);
}
newParams[0] = new Parameter(thatType.getPlainNodeReference(), "$that");
Expression cce = new ConstructorCallExpression(ClassNode.THIS, arguments);
Statement body = new ExpressionStatement(cce);
bridge = node.addConstructor(ACC_SYNTHETIC, newParams, ClassNode.EMPTY_ARRAY, body);
} else {
newParams[0] = new Parameter(node.getPlainNodeReference(), "$that");
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);
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 by apache.
the class StaticCompilationVisitor method addPrivateFieldsAccessors.
/**
* Adds special accessors and mutators for private fields so that inner classes can get/set them
*/
@SuppressWarnings("unchecked")
private static void addPrivateFieldsAccessors(ClassNode node) {
Set<ASTNode> accessedFields = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS);
Set<ASTNode> mutatedFields = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_FIELDS_MUTATION);
if (accessedFields == null && mutatedFields == null)
return;
Map<String, MethodNode> privateFieldAccessors = (Map<String, MethodNode>) node.getNodeMetaData(PRIVATE_FIELDS_ACCESSORS);
Map<String, MethodNode> privateFieldMutators = (Map<String, MethodNode>) node.getNodeMetaData(PRIVATE_FIELDS_MUTATORS);
if (privateFieldAccessors != null || privateFieldMutators != null) {
// already added
return;
}
int acc = -1;
privateFieldAccessors = accessedFields != null ? new HashMap<String, MethodNode>() : null;
privateFieldMutators = mutatedFields != null ? new HashMap<String, MethodNode>() : null;
final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
for (FieldNode fieldNode : node.getFields()) {
boolean generateAccessor = accessedFields != null && accessedFields.contains(fieldNode);
boolean generateMutator = mutatedFields != null && mutatedFields.contains(fieldNode);
if (generateAccessor) {
acc++;
Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
Expression receiver = fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param);
Statement stmt = new ExpressionStatement(new PropertyExpression(receiver, fieldNode.getName()));
MethodNode accessor = node.addMethod("pfaccess$" + acc, access, fieldNode.getOriginType(), new Parameter[] { param }, ClassNode.EMPTY_ARRAY, stmt);
privateFieldAccessors.put(fieldNode.getName(), accessor);
}
if (generateMutator) {
//increment acc if it hasn't been incremented in the current iteration
if (!generateAccessor)
acc++;
Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
Expression receiver = fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param);
Parameter value = new Parameter(fieldNode.getOriginType(), "$value");
Statement stmt = GeneralUtils.assignS(new PropertyExpression(receiver, fieldNode.getName()), new VariableExpression(value));
MethodNode mutator = node.addMethod("pfaccess$0" + acc, access, fieldNode.getOriginType(), new Parameter[] { param, value }, ClassNode.EMPTY_ARRAY, stmt);
privateFieldMutators.put(fieldNode.getName(), mutator);
}
}
if (privateFieldAccessors != null)
node.setNodeMetaData(PRIVATE_FIELDS_ACCESSORS, privateFieldAccessors);
if (privateFieldMutators != null)
node.setNodeMetaData(PRIVATE_FIELDS_MUTATORS, privateFieldMutators);
}
use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy by apache.
the class MarkupBuilderCodeTransformer method transformMethodCall.
private Expression transformMethodCall(final MethodCallExpression exp) {
String name = exp.getMethodAsString();
if (exp.isImplicitThis() && "include".equals(name)) {
return tryTransformInclude(exp);
} else if (exp.isImplicitThis() && name.startsWith(":")) {
List<Expression> args;
if (exp.getArguments() instanceof ArgumentListExpression) {
args = ((ArgumentListExpression) exp.getArguments()).getExpressions();
} else {
args = Collections.singletonList(exp.getArguments());
}
Expression newArguments = transform(new ArgumentListExpression(new ConstantExpression(name.substring(1)), new ArrayExpression(ClassHelper.OBJECT_TYPE, args)));
MethodCallExpression call = new MethodCallExpression(new VariableExpression("this"), "methodMissing", newArguments);
call.setImplicitThis(true);
call.setSafe(exp.isSafe());
call.setSpreadSafe(exp.isSpreadSafe());
call.setSourcePosition(exp);
return call;
} else if (name != null && name.startsWith("$")) {
MethodCallExpression reformatted = new MethodCallExpression(exp.getObjectExpression(), name.substring(1), exp.getArguments());
reformatted.setImplicitThis(exp.isImplicitThis());
reformatted.setSafe(exp.isSafe());
reformatted.setSpreadSafe(exp.isSpreadSafe());
reformatted.setSourcePosition(exp);
// wrap in a stringOf { ... } closure call
ClosureExpression clos = new ClosureExpression(Parameter.EMPTY_ARRAY, new ExpressionStatement(reformatted));
clos.setVariableScope(new VariableScope());
MethodCallExpression stringOf = new MethodCallExpression(new VariableExpression("this"), "stringOf", clos);
stringOf.setImplicitThis(true);
stringOf.setSourcePosition(reformatted);
return stringOf;
}
return super.transform(exp);
}
Aggregations