use of org.codehaus.groovy.ast.stmt.ReturnStatement in project groovy-core by groovy.
the class InnerClassVisitorHelper method setMethodDispatcherCode.
protected static void setMethodDispatcherCode(BlockStatement block, Expression thiz, Parameter[] parameters) {
List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
gStringStrings.add(new ConstantExpression(""));
gStringStrings.add(new ConstantExpression(""));
List<Expression> gStringValues = new ArrayList<Expression>();
gStringValues.add(new VariableExpression(parameters[0]));
block.addStatement(new ReturnStatement(new MethodCallExpression(thiz, new GStringExpression("$name", gStringStrings, gStringValues), new ArgumentListExpression(new SpreadExpression(new VariableExpression(parameters[1]))))));
}
use of org.codehaus.groovy.ast.stmt.ReturnStatement in project groovy-core by groovy.
the class InnerClassVisitorHelper method setPropertyGetterDispatcher.
protected static void setPropertyGetterDispatcher(BlockStatement block, Expression thiz, Parameter[] parameters) {
List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
gStringStrings.add(new ConstantExpression(""));
gStringStrings.add(new ConstantExpression(""));
List<Expression> gStringValues = new ArrayList<Expression>();
gStringValues.add(new VariableExpression(parameters[0]));
block.addStatement(new ReturnStatement(new PropertyExpression(thiz, new GStringExpression("$name", gStringStrings, gStringValues))));
}
use of org.codehaus.groovy.ast.stmt.ReturnStatement in project groovy-core by groovy.
the class MemberSignatureParser method createMethodNode.
static MethodNode createMethodNode(final AsmReferenceResolver resolver, MethodStub method) {
GenericsType[] typeParameters = null;
Type[] argumentTypes = Type.getArgumentTypes(method.desc);
final ClassNode[] parameterTypes = new ClassNode[argumentTypes.length];
for (int i = 0; i < argumentTypes.length; i++) {
parameterTypes[i] = resolver.resolveType(argumentTypes[i]);
}
final ClassNode[] exceptions = new ClassNode[method.exceptions.length];
for (int i = 0; i < method.exceptions.length; i++) {
exceptions[i] = resolver.resolveClass(AsmDecompiler.fromInternalName(method.exceptions[i]));
}
final ClassNode[] returnType = { resolver.resolveType(Type.getReturnType(method.desc)) };
if (method.signature != null) {
FormalParameterParser v = new FormalParameterParser(resolver) {
int paramIndex = 0;
@Override
public SignatureVisitor visitParameterType() {
return new TypeSignatureParser(resolver) {
@Override
void finished(ClassNode result) {
parameterTypes[paramIndex] = applyErasure(result, parameterTypes[paramIndex]);
paramIndex++;
}
};
}
@Override
public SignatureVisitor visitReturnType() {
return new TypeSignatureParser(resolver) {
@Override
void finished(ClassNode result) {
returnType[0] = applyErasure(result, returnType[0]);
}
};
}
int exceptionIndex = 0;
@Override
public SignatureVisitor visitExceptionType() {
return new TypeSignatureParser(resolver) {
@Override
void finished(ClassNode result) {
exceptions[exceptionIndex] = applyErasure(result, exceptions[exceptionIndex]);
exceptionIndex++;
}
};
}
};
new SignatureReader(method.signature).accept(v);
typeParameters = v.getTypeParameters();
}
Parameter[] parameters = new Parameter[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
parameters[i] = new Parameter(parameterTypes[i], "param" + i);
}
if (method.parameterAnnotations != null) {
for (Map.Entry<Integer, List<AnnotationStub>> entry : method.parameterAnnotations.entrySet()) {
for (AnnotationStub stub : entry.getValue()) {
AnnotationNode annotationNode = Annotations.createAnnotationNode(stub, resolver);
if (annotationNode != null) {
parameters[entry.getKey()].addAnnotation(annotationNode);
}
}
}
}
MethodNode result;
if ("<init>".equals(method.methodName)) {
result = new ConstructorNode(method.accessModifiers, parameters, exceptions, null);
} else {
result = new MethodNode(method.methodName, method.accessModifiers, returnType[0], parameters, exceptions, null);
if (method.annotationDefault != null) {
result.setCode(new ReturnStatement(new ConstantExpression(method.annotationDefault)));
result.setAnnotationDefault(true);
} else {
// Seems wrong but otherwise some tests fail (e.g. TestingASTTransformsTest)
result.setCode(new ReturnStatement(ConstantExpression.NULL));
}
}
if (typeParameters != null && typeParameters.length > 0) {
result.setGenericsTypes(typeParameters);
}
return result;
}
use of org.codehaus.groovy.ast.stmt.ReturnStatement in project groovy-core by groovy.
the class TraitComposer method createDelegatingForwarder.
private static Statement createDelegatingForwarder(final MethodNode forwarderMethod, final ClassNode next) {
// generates --> next$Trait$Helper.method(this, arg1, arg2)
TraitHelpersTuple helpers = Traits.findHelpers(next);
ArgumentListExpression args = new ArgumentListExpression();
args.addExpression(new VariableExpression("this"));
Parameter[] forwarderMethodParameters = forwarderMethod.getParameters();
for (final Parameter forwarderMethodParameter : forwarderMethodParameters) {
args.addExpression(new VariableExpression(forwarderMethodParameter));
}
StaticMethodCallExpression delegateCall = new StaticMethodCallExpression(helpers.getHelper(), forwarderMethod.getName(), args);
Statement result;
if (ClassHelper.VOID_TYPE.equals(forwarderMethod.getReturnType())) {
BlockStatement stmt = new BlockStatement();
stmt.addStatement(new ExpressionStatement(delegateCall));
stmt.addStatement(new ReturnStatement(new ConstantExpression(null)));
result = stmt;
} else {
result = new ReturnStatement(delegateCall);
}
return result;
}
use of org.codehaus.groovy.ast.stmt.ReturnStatement in project groovy-core by groovy.
the class TraitComposer method applyTrait.
private static void applyTrait(final ClassNode trait, final ClassNode cNode, final TraitHelpersTuple helpers) {
ClassNode helperClassNode = helpers.getHelper();
ClassNode fieldHelperClassNode = helpers.getFieldHelper();
Map<String, ClassNode> genericsSpec = GenericsUtils.createGenericsSpec(cNode);
genericsSpec = GenericsUtils.createGenericsSpec(trait, genericsSpec);
for (MethodNode methodNode : helperClassNode.getAllDeclaredMethods()) {
String name = methodNode.getName();
Parameter[] helperMethodParams = methodNode.getParameters();
boolean isAbstract = methodNode.isAbstract();
if (!isAbstract && helperMethodParams.length > 0 && ((methodNode.getModifiers() & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC) && !name.contains("$")) {
ArgumentListExpression argList = new ArgumentListExpression();
argList.addExpression(new VariableExpression("this"));
Parameter[] origParams = new Parameter[helperMethodParams.length - 1];
Parameter[] params = new Parameter[helperMethodParams.length - 1];
System.arraycopy(methodNode.getParameters(), 1, params, 0, params.length);
Map<String, ClassNode> methodGenericsSpec = new LinkedHashMap<String, ClassNode>(genericsSpec);
MethodNode originalMethod = trait.getMethod(name, params);
// Original method may be null in case of a private method
if (originalMethod != null) {
methodGenericsSpec = GenericsUtils.addMethodGenerics(originalMethod, methodGenericsSpec);
}
for (int i = 1; i < helperMethodParams.length; i++) {
Parameter parameter = helperMethodParams[i];
ClassNode originType = parameter.getOriginType();
ClassNode fixedType = correctToGenericsSpecRecurse(methodGenericsSpec, originType);
Parameter newParam = new Parameter(fixedType, "arg" + i);
List<AnnotationNode> copied = new LinkedList<AnnotationNode>();
List<AnnotationNode> notCopied = new LinkedList<AnnotationNode>();
GeneralUtils.copyAnnotatedNodeAnnotations(parameter, copied, notCopied);
newParam.addAnnotations(copied);
params[i - 1] = newParam;
origParams[i - 1] = parameter;
argList.addExpression(new VariableExpression(params[i - 1]));
}
createForwarderMethod(trait, cNode, methodNode, originalMethod, helperClassNode, methodGenericsSpec, helperMethodParams, origParams, params, argList);
}
}
cNode.addObjectInitializerStatements(new ExpressionStatement(new MethodCallExpression(new ClassExpression(helperClassNode), Traits.INIT_METHOD, new ArgumentListExpression(new VariableExpression("this")))));
MethodCallExpression staticInitCall = new MethodCallExpression(new ClassExpression(helperClassNode), Traits.STATIC_INIT_METHOD, new ArgumentListExpression(new ClassExpression(cNode)));
MethodNode staticInitMethod = new MethodNode(Traits.STATIC_INIT_METHOD, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(ClassHelper.CLASS_Type, "clazz") }, ClassNode.EMPTY_ARRAY, EmptyStatement.INSTANCE);
staticInitMethod.setDeclaringClass(helperClassNode);
staticInitCall.setMethodTarget(staticInitMethod);
cNode.addStaticInitializerStatements(Collections.<Statement>singletonList(new ExpressionStatement(staticInitCall)), false);
if (fieldHelperClassNode != null && !cNode.declaresInterface(fieldHelperClassNode)) {
// we should implement the field helper interface too
cNode.addInterface(fieldHelperClassNode);
// implementation of methods
List<MethodNode> declaredMethods = fieldHelperClassNode.getAllDeclaredMethods();
Collections.sort(declaredMethods, GETTER_FIRST_COMPARATOR);
for (MethodNode methodNode : declaredMethods) {
String fieldName = methodNode.getName();
if (fieldName.endsWith(Traits.DIRECT_GETTER_SUFFIX) || fieldName.endsWith(Traits.DIRECT_SETTER_SUFFIX)) {
int suffixIdx = fieldName.lastIndexOf("$");
fieldName = fieldName.substring(0, suffixIdx);
String operation = methodNode.getName().substring(suffixIdx + 1);
boolean getter = "get".equals(operation);
ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, methodNode.getReturnType());
int isStatic = 0;
boolean publicField = true;
FieldNode helperField = fieldHelperClassNode.getField(Traits.FIELD_PREFIX + Traits.PUBLIC_FIELD_PREFIX + fieldName);
if (helperField == null) {
publicField = false;
helperField = fieldHelperClassNode.getField(Traits.FIELD_PREFIX + Traits.PRIVATE_FIELD_PREFIX + fieldName);
}
if (helperField == null) {
publicField = true;
// try to find a static one
helperField = fieldHelperClassNode.getField(Traits.STATIC_FIELD_PREFIX + Traits.PUBLIC_FIELD_PREFIX + fieldName);
if (helperField == null) {
publicField = false;
helperField = fieldHelperClassNode.getField(Traits.STATIC_FIELD_PREFIX + Traits.PRIVATE_FIELD_PREFIX + fieldName);
}
isStatic = Opcodes.ACC_STATIC;
}
if (getter) {
// add field
if (helperField != null) {
List<AnnotationNode> copied = new LinkedList<AnnotationNode>();
List<AnnotationNode> notCopied = new LinkedList<AnnotationNode>();
GeneralUtils.copyAnnotatedNodeAnnotations(helperField, copied, notCopied);
FieldNode fieldNode = cNode.addField(fieldName, (publicField ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE) | isStatic, returnType, null);
fieldNode.addAnnotations(copied);
}
}
Parameter[] newParams;
if (getter) {
newParams = Parameter.EMPTY_ARRAY;
} else {
ClassNode originType = methodNode.getParameters()[0].getOriginType();
ClassNode fixedType = originType.isGenericsPlaceHolder() ? ClassHelper.OBJECT_TYPE : correctToGenericsSpecRecurse(genericsSpec, originType);
newParams = new Parameter[] { new Parameter(fixedType, "val") };
}
Expression fieldExpr = new VariableExpression(cNode.getField(fieldName));
Statement body = getter ? new ReturnStatement(fieldExpr) : new ExpressionStatement(new BinaryExpression(fieldExpr, Token.newSymbol(Types.EQUAL, 0, 0), new VariableExpression(newParams[0])));
MethodNode impl = new MethodNode(methodNode.getName(), Opcodes.ACC_PUBLIC | isStatic, returnType, newParams, ClassNode.EMPTY_ARRAY, body);
AnnotationNode an = new AnnotationNode(COMPILESTATIC_CLASSNODE);
impl.addAnnotation(an);
cNode.addTransform(StaticCompileTransformation.class, an);
cNode.addMethod(impl);
}
}
}
}
Aggregations