use of org.codehaus.groovy.ast.Parameter in project groovy by apache.
the class VariableScopeVisitor method visitConstructorOrMethod.
@Override
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
pushState(node.isStatic());
inConstructor = isConstructor;
node.setVariableScope(currentScope);
visitAnnotations(node);
for (Parameter parameter : node.getParameters()) {
visitAnnotations(parameter);
}
// to prevent the use of parameters in annotation attributes
for (Parameter parameter : node.getParameters()) {
if (parameter.hasInitialExpression()) {
parameter.getInitialExpression().visit(this);
}
declare(parameter, node);
}
visitClassCodeContainer(node.getCode());
popState();
}
use of org.codehaus.groovy.ast.Parameter in project groovy by apache.
the class ClosureWriter method createClosureClass.
protected ClassNode createClosureClass(final ClosureExpression expression, final int modifiers) {
ClassNode classNode = controller.getClassNode();
ClassNode outerClass = controller.getOutermostClass();
String name = genClosureClassName();
Parameter[] parameters = expression.getParameters();
if (parameters == null) {
parameters = Parameter.EMPTY_ARRAY;
} else if (parameters.length == 0) {
// let's create a default 'it' parameter
Parameter it = param(ClassHelper.OBJECT_TYPE, "it", nullX());
parameters = new Parameter[] { it };
Variable ref = expression.getVariableScope().getDeclaredVariable("it");
if (ref != null)
it.setClosureSharedVariable(ref.isClosureSharedVariable());
}
Parameter[] localVariableParams = getClosureSharedVariables(expression);
removeInitialValues(localVariableParams);
// GROOVY-9971: closure return type is mapped to Groovy cast by classgen
ClassNode returnType = expression.getNodeMetaData(INFERRED_RETURN_TYPE);
if (// not STC or unknown path
returnType == null)
// not STC or unknown path
returnType = ClassHelper.OBJECT_TYPE;
else if (returnType.isPrimaryClassNode())
returnType = returnType.getPlainNodeReference();
else if (ClassHelper.isPrimitiveType(returnType))
returnType = ClassHelper.getWrapper(returnType);
else if (GenericsUtils.hasUnresolvedGenerics(returnType))
returnType = GenericsUtils.nonGeneric(returnType);
InnerClassNode answer = new InnerClassNode(classNode, name, modifiers, ClassHelper.CLOSURE_TYPE.getPlainNodeReference());
answer.setEnclosingMethod(controller.getMethodNode());
answer.setScriptBody(controller.isInScriptBody());
answer.setSourcePosition(expression);
answer.setStaticClass(controller.isStaticMethod() || classNode.isStaticClass());
answer.setSynthetic(true);
answer.setUsingGenerics(outerClass.isUsingGenerics());
MethodNode method = answer.addMethod("doCall", ACC_PUBLIC, returnType, parameters, ClassNode.EMPTY_ARRAY, expression.getCode());
method.setSourcePosition(expression);
VariableScope varScope = expression.getVariableScope();
if (varScope == null) {
throw new RuntimeException("Must have a VariableScope by now! for expression: " + expression + " class: " + name);
} else {
method.setVariableScope(varScope.copy());
}
if (parameters.length > 1 || (parameters.length == 1 && parameters[0].getType() != null && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType()) && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType().getComponentType()))) {
// let's add a typesafe call method
MethodNode call = new MethodNode("call", ACC_PUBLIC, returnType, parameters, ClassNode.EMPTY_ARRAY, returnS(callThisX("doCall", args(parameters))));
addGeneratedMethod(answer, call, true);
call.setSourcePosition(expression);
}
// let's make the constructor
BlockStatement block = createBlockStatementForConstructor(expression, outerClass, classNode);
// let's assign all the parameter fields from the outer context
addFieldsAndGettersForLocalVariables(answer, localVariableParams);
addConstructor(expression, localVariableParams, answer, block);
correctAccessedVariable(answer, expression);
return answer;
}
use of org.codehaus.groovy.ast.Parameter in project groovy by apache.
the class ClosureWriter method addConstructor.
protected ConstructorNode addConstructor(final ClosureExpression expression, final Parameter[] localVariableParams, final InnerClassNode answer, final BlockStatement block) {
Parameter[] params = new Parameter[2 + localVariableParams.length];
params[0] = param(ClassHelper.OBJECT_TYPE, OUTER_INSTANCE);
params[1] = param(ClassHelper.OBJECT_TYPE, THIS_OBJECT);
System.arraycopy(localVariableParams, 0, params, 2, localVariableParams.length);
ConstructorNode constructorNode = answer.addConstructor(ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, block);
constructorNode.setSourcePosition(expression);
return constructorNode;
}
use of org.codehaus.groovy.ast.Parameter in project groovy by apache.
the class ClosureWriter method addFieldsAndGettersForLocalVariables.
protected void addFieldsAndGettersForLocalVariables(final InnerClassNode answer, final Parameter[] localVariableParams) {
for (Parameter param : localVariableParams) {
String paramName = param.getName();
ClassNode type = param.getType();
VariableExpression initialValue = varX(paramName);
initialValue.setAccessedVariable(param);
initialValue.setUseReferenceDirectly(true);
ClassNode realType = type;
type = ClassHelper.makeReference();
param.setType(ClassHelper.makeReference());
FieldNode paramField = answer.addField(paramName, ACC_PRIVATE | ACC_SYNTHETIC, type, initialValue);
paramField.setOriginType(ClassHelper.getWrapper(param.getOriginType()));
paramField.setHolder(true);
String methodName = Verifier.capitalize(paramName);
// let's add a getter & setter
Expression fieldExp = fieldX(paramField);
markAsGenerated(answer, answer.addMethod("get" + methodName, ACC_PUBLIC, realType.getPlainNodeReference(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(fieldExp)), true);
}
}
use of org.codehaus.groovy.ast.Parameter in project groovy by apache.
the class ClosureWriter method addGeneratedClosureConstructorCall.
public boolean addGeneratedClosureConstructorCall(final ConstructorCallExpression call) {
ClassNode classNode = controller.getClassNode();
if (!classNode.declaresInterface(ClassHelper.GENERATED_CLOSURE_Type))
return false;
AsmClassGenerator acg = controller.getAcg();
OperandStack operandStack = controller.getOperandStack();
MethodVisitor mv = controller.getMethodVisitor();
mv.visitVarInsn(ALOAD, 0);
ClassNode callNode = classNode.getSuperClass();
TupleExpression arguments = (TupleExpression) call.getArguments();
if (arguments.getExpressions().size() != 2)
throw new GroovyBugError("expected 2 arguments for closure constructor super call, but got" + arguments.getExpressions().size());
arguments.getExpression(0).visit(acg);
operandStack.box();
arguments.getExpression(1).visit(acg);
operandStack.box();
// TODO: replace with normal String, p not needed
Parameter p = param(ClassHelper.OBJECT_TYPE, "_p");
String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, new Parameter[] { p, p });
mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false);
operandStack.remove(2);
return true;
}
Aggregations