use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.
the class SuperCallTraitTransformer method transformMethodCallExpression.
private Expression transformMethodCallExpression(final MethodCallExpression exp) {
if (isTraitSuperPropertyExpression(exp.getObjectExpression())) {
Expression objectExpression = exp.getObjectExpression();
ClassNode traitReceiver = ((PropertyExpression) objectExpression).getObjectExpression().getType();
if (traitReceiver != null) {
// (SomeTrait.super).foo() --> SomeTrait$Helper.foo(this)
ClassExpression receiver = new ClassExpression(getHelper(traitReceiver));
ArgumentListExpression newArgs = new ArgumentListExpression();
Expression arguments = exp.getArguments();
newArgs.addExpression(new VariableExpression("this"));
if (arguments instanceof TupleExpression) {
List<Expression> expressions = ((TupleExpression) arguments).getExpressions();
for (Expression expression : expressions) {
newArgs.addExpression(transform(expression));
}
} else {
newArgs.addExpression(transform(arguments));
}
MethodCallExpression result = new MethodCallExpression(receiver, transform(exp.getMethod()), newArgs);
result.setImplicitThis(false);
result.setSpreadSafe(exp.isSpreadSafe());
result.setSafe(exp.isSafe());
result.setSourcePosition(exp);
return result;
}
}
return super.transform(exp);
}
use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.
the class CallSiteWriter method makeCallSite.
public void makeCallSite(Expression receiver, String message, Expression arguments, boolean safe, boolean implicitThis, boolean callCurrent, boolean callStatic) {
prepareSiteAndReceiver(receiver, message, implicitThis);
CompileStack compileStack = controller.getCompileStack();
compileStack.pushImplicitThis(implicitThis);
compileStack.pushLHS(false);
boolean constructor = message.equals(CONSTRUCTOR);
OperandStack operandStack = controller.getOperandStack();
// arguments
boolean containsSpreadExpression = AsmClassGenerator.containsSpreadExpression(arguments);
int numberOfArguments = containsSpreadExpression ? -1 : AsmClassGenerator.argumentSize(arguments);
int operandsToReplace = 1;
if (numberOfArguments > MethodCallerMultiAdapter.MAX_ARGS || containsSpreadExpression) {
ArgumentListExpression ae;
if (arguments instanceof ArgumentListExpression) {
ae = (ArgumentListExpression) arguments;
} else if (arguments instanceof TupleExpression) {
TupleExpression te = (TupleExpression) arguments;
ae = new ArgumentListExpression(te.getExpressions());
} else {
ae = new ArgumentListExpression();
ae.addExpression(arguments);
}
controller.getCompileStack().pushImplicitThis(false);
if (containsSpreadExpression) {
numberOfArguments = -1;
controller.getAcg().despreadList(ae.getExpressions(), true);
} else {
numberOfArguments = ae.getExpressions().size();
for (int i = 0; i < numberOfArguments; i++) {
Expression argument = ae.getExpression(i);
argument.visit(controller.getAcg());
operandStack.box();
if (argument instanceof CastExpression)
controller.getAcg().loadWrapper(argument);
}
operandsToReplace += numberOfArguments;
}
controller.getCompileStack().popImplicitThis();
}
controller.getCompileStack().popLHS();
controller.getCompileStack().popImplicitThis();
MethodVisitor mv = controller.getMethodVisitor();
if (numberOfArguments > 4) {
final String createArraySignature = getCreateArraySignature(numberOfArguments);
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/ArrayUtil", "createArray", createArraySignature, false);
//TODO: use pre-generated Object[]
operandStack.replace(ClassHelper.OBJECT_TYPE.makeArray(), numberOfArguments);
operandsToReplace = operandsToReplace - numberOfArguments + 1;
}
final String desc = getDescForParamNum(numberOfArguments);
if (callStatic) {
mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callStatic", "(Ljava/lang/Class;" + desc, true);
} else if (constructor) {
mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callConstructor", "(Ljava/lang/Object;" + desc, true);
} else if (callCurrent) {
mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callCurrent", "(Lgroovy/lang/GroovyObject;" + desc, true);
} else if (safe) {
mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callSafe", "(Ljava/lang/Object;" + desc, true);
} else {
mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "call", "(Ljava/lang/Object;" + desc, true);
}
operandStack.replace(ClassHelper.OBJECT_TYPE, operandsToReplace);
}
use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.
the class StaticTypesClosureWriter method createDirectCallMethod.
private static void createDirectCallMethod(final ClassNode closureClass, final MethodNode doCallMethod) {
// in case there is no "call" method on the closure, we can create a "fast invocation" paths
// to avoid going through ClosureMetaClass by call(Object...) method
// we can't have a specialized version of call(Object...) because the dispatch logic in ClosureMetaClass
// is too complex!
// call(Object)
Parameter args = new Parameter(ClassHelper.OBJECT_TYPE, "args");
MethodCallExpression doCall1arg = new MethodCallExpression(new VariableExpression("this", closureClass), "doCall", new ArgumentListExpression(new VariableExpression(args)));
doCall1arg.setImplicitThis(true);
doCall1arg.setMethodTarget(doCallMethod);
closureClass.addMethod(new MethodNode("call", Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, new Parameter[] { args }, ClassNode.EMPTY_ARRAY, new ReturnStatement(doCall1arg)));
// call()
MethodCallExpression doCallNoArgs = new MethodCallExpression(new VariableExpression("this", closureClass), "doCall", new ArgumentListExpression(new ConstantExpression(null)));
doCallNoArgs.setImplicitThis(true);
doCallNoArgs.setMethodTarget(doCallMethod);
closureClass.addMethod(new MethodNode("call", Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new ReturnStatement(doCallNoArgs)));
}
use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.
the class StaticTypesStatementWriter method writeIteratorBasedForEachLoop.
private void writeIteratorBasedForEachLoop(CompileStack compileStack, OperandStack operandStack, MethodVisitor mv, ForStatement loop, Expression collectionExpression, ClassNode collectionType, Parameter loopVariable) {
// Declare the loop counter.
BytecodeVariable variable = compileStack.defineVariable(loopVariable, false);
if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(collectionType, ITERABLE_CLASSNODE)) {
MethodCallExpression iterator = new MethodCallExpression(collectionExpression, "iterator", new ArgumentListExpression());
iterator.setMethodTarget(collectionType.getMethod("iterator", Parameter.EMPTY_ARRAY));
iterator.setImplicitThis(false);
iterator.visit(controller.getAcg());
} else {
collectionExpression.visit(controller.getAcg());
mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "iterator", "(Ljava/lang/Object;)Ljava/util/Iterator;", false);
operandStack.replace(ClassHelper.Iterator_TYPE);
}
// Then get the iterator and generate the loop control
int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.Iterator_TYPE, true);
Label continueLabel = compileStack.getContinueLabel();
Label breakLabel = compileStack.getBreakLabel();
mv.visitLabel(continueLabel);
mv.visitVarInsn(ALOAD, iteratorIdx);
writeIteratorHasNext(mv);
// note: ifeq tests for ==0, a boolean is 0 if it is false
mv.visitJumpInsn(IFEQ, breakLabel);
mv.visitVarInsn(ALOAD, iteratorIdx);
writeIteratorNext(mv);
operandStack.push(ClassHelper.OBJECT_TYPE);
operandStack.storeVar(variable);
// Generate the loop body
loop.getLoopBlock().visit(controller.getAcg());
mv.visitJumpInsn(GOTO, continueLabel);
mv.visitLabel(breakLabel);
compileStack.removeVar(iteratorIdx);
}
use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.
the class DelegateASTTransformation method addDelegateMethod.
private void addDelegateMethod(DelegateDescription delegate, List<MethodNode> ownMethods, MethodNode candidate, boolean includeDeprecated, boolean allNames) {
if (!candidate.isPublic() || candidate.isStatic() || 0 != (candidate.getModifiers() & ACC_SYNTHETIC))
return;
if (!candidate.getAnnotations(DEPRECATED_TYPE).isEmpty() && !includeDeprecated)
return;
if (shouldSkip(candidate.getName(), delegate.excludes, delegate.includes, allNames))
return;
Map<String, ClassNode> genericsSpec = createGenericsSpec(delegate.owner);
genericsSpec = addMethodGenerics(candidate, genericsSpec);
extractSuperClassGenerics(delegate.type, candidate.getDeclaringClass(), genericsSpec);
if ((delegate.excludeTypes != null && !delegate.excludeTypes.isEmpty()) || delegate.includeTypes != null) {
MethodNode correctedMethodNode = correctToGenericsSpec(genericsSpec, candidate);
boolean checkReturn = delegate.type.getMethods().contains(candidate);
if (shouldSkipOnDescriptorUndefinedAware(checkReturn, genericsSpec, correctedMethodNode, delegate.excludeTypes, delegate.includeTypes))
return;
}
// ignore methods from GroovyObject
for (MethodNode mn : GROOVYOBJECT_TYPE.getMethods()) {
if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor())) {
return;
}
}
// ignore methods already in owner
for (MethodNode mn : delegate.owner.getMethods()) {
if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor())) {
return;
}
}
// give precedence to methods of self (but not abstract or static superclass methods)
// also allows abstract or static self methods to be selected for overriding but they are ignored later
MethodNode existingNode = null;
for (MethodNode mn : ownMethods) {
if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor()) && !mn.isAbstract() && !mn.isStatic()) {
existingNode = mn;
break;
}
}
if (existingNode == null || existingNode.getCode() == null) {
final ArgumentListExpression args = new ArgumentListExpression();
final Parameter[] params = candidate.getParameters();
final Parameter[] newParams = new Parameter[params.length];
List<String> currentMethodGenPlaceholders = genericPlaceholderNames(candidate);
for (int i = 0; i < newParams.length; i++) {
ClassNode newParamType = correctToGenericsSpecRecurse(genericsSpec, params[i].getType(), currentMethodGenPlaceholders);
Parameter newParam = new Parameter(newParamType, getParamName(params, i, delegate.name));
newParam.setInitialExpression(params[i].getInitialExpression());
if (memberHasValue(delegate.annotation, MEMBER_PARAMETER_ANNOTATIONS, true)) {
newParam.addAnnotations(copyAnnotatedNodeAnnotations(params[i], MY_TYPE_NAME));
}
newParams[i] = newParam;
args.addExpression(varX(newParam));
}
boolean alsoLazy = !delegate.delegate.getAnnotations(LAZY_TYPE).isEmpty();
// addMethod will ignore attempts to override abstract or static methods with same signature on self
MethodCallExpression mce = callX(// use propX when lazy, because lazy is only allowed on fields/properties
alsoLazy ? propX(varX("this"), delegate.name.substring(1)) : delegate.getOp, candidate.getName(), args);
mce.setSourcePosition(delegate.delegate);
ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, candidate.getReturnType(), currentMethodGenPlaceholders);
MethodNode newMethod = delegate.owner.addMethod(candidate.getName(), candidate.getModifiers() & (~ACC_ABSTRACT) & (~ACC_NATIVE), returnType, newParams, candidate.getExceptions(), stmt(mce));
newMethod.setGenericsTypes(candidate.getGenericsTypes());
if (memberHasValue(delegate.annotation, MEMBER_METHOD_ANNOTATIONS, true)) {
newMethod.addAnnotations(copyAnnotatedNodeAnnotations(candidate, MY_TYPE_NAME));
}
}
}
Aggregations