use of org.codehaus.groovy.ast.expr.CastExpression in project groovy by apache.
the class TraitComposer method createSuperFallback.
private static Statement createSuperFallback(MethodNode forwarderMethod, ClassNode returnType) {
ArgumentListExpression args = new ArgumentListExpression();
Parameter[] forwarderMethodParameters = forwarderMethod.getParameters();
for (final Parameter forwarderMethodParameter : forwarderMethodParameters) {
args.addExpression(new VariableExpression(forwarderMethodParameter));
}
BinaryExpression instanceOfExpr = new BinaryExpression(new VariableExpression("this"), Token.newSymbol(Types.KEYWORD_INSTANCEOF, -1, -1), new ClassExpression(Traits.GENERATED_PROXY_CLASSNODE));
MethodCallExpression superCall = new MethodCallExpression(new VariableExpression("super"), forwarderMethod.getName(), args);
superCall.setImplicitThis(false);
CastExpression proxyReceiver = new CastExpression(Traits.GENERATED_PROXY_CLASSNODE, new VariableExpression("this"));
MethodCallExpression getProxy = new MethodCallExpression(proxyReceiver, "getProxyTarget", ArgumentListExpression.EMPTY_ARGUMENTS);
getProxy.setImplicitThis(true);
StaticMethodCallExpression proxyCall = new StaticMethodCallExpression(ClassHelper.make(InvokerHelper.class), "invokeMethod", new ArgumentListExpression(getProxy, new ConstantExpression(forwarderMethod.getName()), new ArrayExpression(ClassHelper.OBJECT_TYPE, args.getExpressions())));
IfStatement stmt = new IfStatement(new BooleanExpression(instanceOfExpr), new ExpressionStatement(new CastExpression(returnType, proxyCall)), new ExpressionStatement(superCall));
return stmt;
}
use of org.codehaus.groovy.ast.expr.CastExpression in project groovy by apache.
the class TraitComposer method createForwarderMethod.
private static void createForwarderMethod(ClassNode trait, ClassNode targetNode, MethodNode helperMethod, MethodNode originalMethod, ClassNode helperClassNode, Map<String, ClassNode> genericsSpec, Parameter[] helperMethodParams, Parameter[] traitMethodParams, Parameter[] forwarderParams, ArgumentListExpression helperMethodArgList) {
MethodCallExpression mce = new MethodCallExpression(new ClassExpression(helperClassNode), helperMethod.getName(), helperMethodArgList);
mce.setImplicitThis(false);
genericsSpec = GenericsUtils.addMethodGenerics(helperMethod, genericsSpec);
ClassNode[] exceptionNodes = correctToGenericsSpecRecurse(genericsSpec, copyExceptions(helperMethod.getExceptions()));
ClassNode fixedReturnType = correctToGenericsSpecRecurse(genericsSpec, helperMethod.getReturnType());
boolean noCastRequired = genericsSpec.isEmpty() || fixedReturnType.getName().equals(ClassHelper.VOID_TYPE.getName());
Expression forwardExpression = noCastRequired ? mce : new CastExpression(fixedReturnType, mce);
int access = helperMethod.getModifiers();
// we could rely on the first parameter name ($static$self) but that information is not
// guaranteed to be always present
boolean isHelperForStaticMethod = helperMethodParams[0].getOriginType().equals(ClassHelper.CLASS_Type);
if (Modifier.isPrivate(access) && !isHelperForStaticMethod) {
// see GROOVY-7213
return;
}
if (!isHelperForStaticMethod) {
access = access ^ Opcodes.ACC_STATIC;
}
MethodNode forwarder = new MethodNode(helperMethod.getName(), access, fixedReturnType, forwarderParams, exceptionNodes, new ExpressionStatement(forwardExpression));
List<AnnotationNode> copied = new LinkedList<AnnotationNode>();
// at this point, should *always* stay empty
List<AnnotationNode> notCopied = Collections.emptyList();
GeneralUtils.copyAnnotatedNodeAnnotations(helperMethod, copied, notCopied);
if (!copied.isEmpty()) {
forwarder.addAnnotations(copied);
}
if (originalMethod != null) {
GenericsType[] newGt = GenericsUtils.applyGenericsContextToPlaceHolders(genericsSpec, originalMethod.getGenericsTypes());
newGt = removeNonPlaceHolders(newGt);
forwarder.setGenericsTypes(newGt);
} else {
// null indicates a static method which may still need generics correction
GenericsType[] genericsTypes = helperMethod.getGenericsTypes();
if (genericsTypes != null) {
Map<String, ClassNode> methodSpec = new HashMap<String, ClassNode>();
methodSpec = GenericsUtils.addMethodGenerics(helperMethod, methodSpec);
GenericsType[] newGt = GenericsUtils.applyGenericsContextToPlaceHolders(methodSpec, helperMethod.getGenericsTypes());
forwarder.setGenericsTypes(newGt);
}
}
// add a helper annotation indicating that it is a bridge method
AnnotationNode bridgeAnnotation = new AnnotationNode(Traits.TRAITBRIDGE_CLASSNODE);
bridgeAnnotation.addMember("traitClass", new ClassExpression(trait));
bridgeAnnotation.addMember("desc", new ConstantExpression(BytecodeHelper.getMethodDescriptor(helperMethod.getReturnType(), traitMethodParams)));
forwarder.addAnnotation(bridgeAnnotation);
if (!shouldSkipMethod(targetNode, forwarder.getName(), forwarderParams)) {
targetNode.addMethod(forwarder);
}
createSuperForwarder(targetNode, forwarder, genericsSpec);
}
use of org.codehaus.groovy.ast.expr.CastExpression 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.CastExpression in project gradle by gradle.
the class GradleResolveVisitor method transformBinaryExpression.
protected Expression transformBinaryExpression(BinaryExpression be) {
Expression left = transform(be.getLeftExpression());
int type = be.getOperation().getType();
if ((type == Types.ASSIGNMENT_OPERATOR || type == Types.EQUAL) && left instanceof ClassExpression) {
ClassExpression ce = (ClassExpression) left;
String error = "you tried to assign a value to the class '" + ce.getType().getName() + "'";
if (ce.getType().isScript()) {
error += ". Do you have a script with this name?";
}
addError(error, be.getLeftExpression());
return be;
}
if (left instanceof ClassExpression && isLeftSquareBracket(type)) {
if (be.getRightExpression() instanceof ListExpression) {
ListExpression list = (ListExpression) be.getRightExpression();
if (list.getExpressions().isEmpty()) {
// we have C[] if the list is empty -> should be an array then!
final ClassExpression ce = new ClassExpression(left.getType().makeArray());
ce.setSourcePosition(be);
return ce;
} else {
// may be we have C[k1:v1, k2:v2] -> should become (C)([k1:v1, k2:v2])
boolean map = true;
for (Expression expression : list.getExpressions()) {
if (!(expression instanceof MapEntryExpression)) {
map = false;
break;
}
}
if (map) {
final MapExpression me = new MapExpression();
for (Expression expression : list.getExpressions()) {
me.addMapEntryExpression((MapEntryExpression) transform(expression));
}
me.setSourcePosition(list);
final CastExpression ce = new CastExpression(left.getType(), me);
ce.setSourcePosition(be);
return ce;
}
}
} else if (be.getRightExpression() instanceof SpreadMapExpression) {
// we have C[*:map] -> should become (C) map
SpreadMapExpression mapExpression = (SpreadMapExpression) be.getRightExpression();
Expression right = transform(mapExpression.getExpression());
Expression ce = new CastExpression(left.getType(), right);
ce.setSourcePosition(be);
return ce;
}
if (be.getRightExpression() instanceof MapEntryExpression) {
// may be we have C[k1:v1] -> should become (C)([k1:v1])
final MapExpression me = new MapExpression();
me.addMapEntryExpression((MapEntryExpression) transform(be.getRightExpression()));
me.setSourcePosition(be.getRightExpression());
final CastExpression ce = new CastExpression(left.getType(), me);
ce.setSourcePosition(be);
return ce;
}
}
Expression right = transform(be.getRightExpression());
be.setLeftExpression(left);
be.setRightExpression(right);
return be;
}
Aggregations