use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy-core by groovy.
the class MarkupBuilderCodeTransformer method tryTransformInclude.
private Expression tryTransformInclude(final MethodCallExpression exp) {
Expression arguments = exp.getArguments();
if (arguments instanceof TupleExpression) {
List<Expression> expressions = ((TupleExpression) arguments).getExpressions();
if (expressions.size() == 1 && expressions.get(0) instanceof MapExpression) {
MapExpression map = (MapExpression) expressions.get(0);
List<MapEntryExpression> entries = map.getMapEntryExpressions();
if (entries.size() == 1) {
MapEntryExpression mapEntry = entries.get(0);
Expression keyExpression = mapEntry.getKeyExpression();
try {
IncludeType includeType = IncludeType.valueOf(keyExpression.getText().toLowerCase());
MethodCallExpression call = new MethodCallExpression(exp.getObjectExpression(), includeType.getMethodName(), new ArgumentListExpression(mapEntry.getValueExpression()));
call.setImplicitThis(true);
call.setSafe(exp.isSafe());
call.setSpreadSafe(exp.isSpreadSafe());
call.setSourcePosition(exp);
return call;
} catch (IllegalArgumentException e) {
// not a valid import type, do not modify the code
}
}
}
}
return super.transform(exp);
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy-core by groovy.
the class ConstructorCallTransformer method transformConstructorCall.
Expression transformConstructorCall(final ConstructorCallExpression expr) {
ConstructorNode node = (ConstructorNode) expr.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
if (node == null)
return expr;
if (node.getParameters().length == 1 && StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(node.getParameters()[0].getType(), ClassHelper.MAP_TYPE) && node.getCode() == StaticTypeCheckingVisitor.GENERATED_EMPTY_STATEMENT) {
Expression arguments = expr.getArguments();
if (arguments instanceof TupleExpression) {
TupleExpression tupleExpression = (TupleExpression) arguments;
List<Expression> expressions = tupleExpression.getExpressions();
if (expressions.size() == 1) {
Expression expression = expressions.get(0);
if (expression instanceof MapExpression) {
MapExpression map = (MapExpression) expression;
// check that the node doesn't belong to the list of declared constructors
ClassNode declaringClass = node.getDeclaringClass();
for (ConstructorNode constructorNode : declaringClass.getDeclaredConstructors()) {
if (constructorNode == node) {
return staticCompilationTransformer.superTransform(expr);
}
}
// replace this call with a call to <init>() + appropriate setters
// for example, foo(x:1, y:2) is replaced with:
// { def tmp = new Foo(); tmp.x = 1; tmp.y = 2; return tmp }()
MapStyleConstructorCall result = new MapStyleConstructorCall(staticCompilationTransformer, declaringClass, map, expr);
return result;
}
}
}
}
return staticCompilationTransformer.superTransform(expr);
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy-core by groovy.
the class MethodCallExpressionTransformer method transformMethodCallExpression.
Expression transformMethodCallExpression(final MethodCallExpression expr) {
Expression trn = tryTransformIsToCompareIdentity(expr);
if (trn != null) {
return trn;
}
ClassNode superCallReceiver = expr.getNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED);
if (superCallReceiver != null) {
return transformMethodCallExpression(transformToMopSuperCall(superCallReceiver, expr));
}
Expression objectExpression = expr.getObjectExpression();
ClassNode type = staticCompilationTransformer.getTypeChooser().resolveType(objectExpression, staticCompilationTransformer.getClassNode());
if (isCallOnClosure(expr)) {
FieldNode field = staticCompilationTransformer.getClassNode().getField(expr.getMethodAsString());
if (field != null) {
VariableExpression vexp = new VariableExpression(field);
MethodCallExpression result = new MethodCallExpression(vexp, "call", staticCompilationTransformer.transform(expr.getArguments()));
result.setImplicitThis(false);
result.setSourcePosition(expr);
result.setSafe(expr.isSafe());
result.setSpreadSafe(expr.isSpreadSafe());
result.setMethodTarget(StaticTypeCheckingVisitor.CLOSURE_CALL_VARGS);
return result;
}
}
if (type != null && type.isArray()) {
String method = expr.getMethodAsString();
ClassNode componentType = type.getComponentType();
if ("getAt".equals(method)) {
Expression arguments = expr.getArguments();
if (arguments instanceof TupleExpression) {
List<Expression> argList = ((TupleExpression) arguments).getExpressions();
if (argList.size() == 1) {
Expression indexExpr = argList.get(0);
ClassNode argType = staticCompilationTransformer.getTypeChooser().resolveType(indexExpr, staticCompilationTransformer.getClassNode());
ClassNode indexType = ClassHelper.getWrapper(argType);
if (componentType.isEnum() && ClassHelper.Number_TYPE == indexType) {
// workaround for generated code in enums which use .next() returning a Number
indexType = ClassHelper.Integer_TYPE;
}
if (argType != null && ClassHelper.Integer_TYPE == indexType) {
BinaryExpression binaryExpression = new BinaryExpression(objectExpression, Token.newSymbol("[", indexExpr.getLineNumber(), indexExpr.getColumnNumber()), indexExpr);
binaryExpression.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, componentType);
return staticCompilationTransformer.transform(binaryExpression);
}
}
}
} else if ("putAt".equals(method)) {
Expression arguments = expr.getArguments();
if (arguments instanceof TupleExpression) {
List<Expression> argList = ((TupleExpression) arguments).getExpressions();
if (argList.size() == 2) {
Expression indexExpr = argList.get(0);
Expression objExpr = argList.get(1);
ClassNode argType = staticCompilationTransformer.getTypeChooser().resolveType(indexExpr, staticCompilationTransformer.getClassNode());
if (argType != null && ClassHelper.Integer_TYPE == ClassHelper.getWrapper(argType)) {
BinaryExpression arrayGet = new BinaryExpression(objectExpression, Token.newSymbol("[", indexExpr.getLineNumber(), indexExpr.getColumnNumber()), indexExpr);
arrayGet.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, componentType);
BinaryExpression assignment = new BinaryExpression(arrayGet, Token.newSymbol("=", objExpr.getLineNumber(), objExpr.getColumnNumber()), objExpr);
return staticCompilationTransformer.transform(assignment);
}
}
}
}
}
return staticCompilationTransformer.superTransform(expr);
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy-core by groovy.
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.TupleExpression in project groovy by apache.
the class AstBuilder method visitCreator.
// } primary ---------------------------------------------------------------
@Override
public Expression visitCreator(final CreatorContext ctx) {
ClassNode classNode = this.visitCreatedName(ctx.createdName());
if (asBoolean(ctx.arguments())) {
// create instance of class
Expression arguments = this.visitArguments(ctx.arguments());
Expression enclosingInstanceExpression = ctx.getNodeMetaData(ENCLOSING_INSTANCE_EXPRESSION);
if (enclosingInstanceExpression != null) {
if (arguments instanceof ArgumentListExpression) {
((ArgumentListExpression) arguments).getExpressions().add(0, enclosingInstanceExpression);
} else if (arguments instanceof TupleExpression) {
throw createParsingFailedException("Creating instance of non-static class does not support named parameters", arguments);
} else if (arguments instanceof NamedArgumentListExpression) {
throw createParsingFailedException("Unexpected arguments", arguments);
} else {
// should never reach here
throw createParsingFailedException("Unsupported arguments", arguments);
}
if (enclosingInstanceExpression instanceof ConstructorCallExpression && classNode.getName().indexOf('.') < 0) {
// GROOVY-8947
classNode.setName(enclosingInstanceExpression.getType().getName() + '.' + classNode.getName());
}
}
if (asBoolean(ctx.anonymousInnerClassDeclaration())) {
ctx.anonymousInnerClassDeclaration().putNodeMetaData(ANONYMOUS_INNER_CLASS_SUPER_CLASS, classNode);
InnerClassNode anonymousInnerClassNode = this.visitAnonymousInnerClassDeclaration(ctx.anonymousInnerClassDeclaration());
List<InnerClassNode> anonymousInnerClassList = anonymousInnerClassesDefinedInMethodStack.peek();
if (anonymousInnerClassList != null) {
// if the anonymous class is created in a script, no anonymousInnerClassList is available.
anonymousInnerClassList.add(anonymousInnerClassNode);
}
ConstructorCallExpression constructorCallExpression = new ConstructorCallExpression(anonymousInnerClassNode, arguments);
constructorCallExpression.setUsingAnonymousInnerClass(true);
return configureAST(constructorCallExpression, ctx);
}
return configureAST(new ConstructorCallExpression(classNode, arguments), ctx);
}
if (asBoolean(ctx.dim())) {
// create array
ArrayExpression arrayExpression;
List<Tuple3<Expression, List<AnnotationNode>, TerminalNode>> dimList = ctx.dim().stream().map(this::visitDim).collect(Collectors.toList());
TerminalNode invalidDimLBrack = null;
Boolean exprEmpty = null;
List<Tuple3<Expression, List<AnnotationNode>, TerminalNode>> emptyDimList = new LinkedList<>();
List<Tuple3<Expression, List<AnnotationNode>, TerminalNode>> dimWithExprList = new LinkedList<>();
Tuple3<Expression, List<AnnotationNode>, TerminalNode> latestDim = null;
for (Tuple3<Expression, List<AnnotationNode>, TerminalNode> dim : dimList) {
if (null == dim.getV1()) {
emptyDimList.add(dim);
exprEmpty = Boolean.TRUE;
} else {
if (Boolean.TRUE.equals(exprEmpty)) {
invalidDimLBrack = latestDim.getV3();
}
dimWithExprList.add(dim);
exprEmpty = Boolean.FALSE;
}
latestDim = dim;
}
if (asBoolean(ctx.arrayInitializer())) {
if (!dimWithExprList.isEmpty()) {
throw createParsingFailedException("dimension should be empty", dimWithExprList.get(0).getV3());
}
ClassNode elementType = classNode;
for (int i = 0, n = emptyDimList.size() - 1; i < n; i += 1) {
elementType = this.createArrayType(elementType);
}
arrayExpression = new ArrayExpression(elementType, this.visitArrayInitializer(ctx.arrayInitializer()));
} else {
if (null != invalidDimLBrack) {
throw createParsingFailedException("dimension cannot be empty", invalidDimLBrack);
}
if (dimWithExprList.isEmpty() && !emptyDimList.isEmpty()) {
throw createParsingFailedException("dimensions cannot be all empty", emptyDimList.get(0).getV3());
}
Expression[] empties;
if (asBoolean(emptyDimList)) {
empties = new Expression[emptyDimList.size()];
Arrays.fill(empties, ConstantExpression.EMPTY_EXPRESSION);
} else {
empties = Expression.EMPTY_ARRAY;
}
arrayExpression = new ArrayExpression(classNode, null, Stream.concat(dimWithExprList.stream().map(Tuple3::getV1), Arrays.stream(empties)).collect(Collectors.toList()));
}
arrayExpression.setType(this.createArrayType(classNode, dimList.stream().map(Tuple3::getV2).collect(Collectors.toList())));
return configureAST(arrayExpression, ctx);
}
throw createParsingFailedException("Unsupported creator: " + ctx.getText(), ctx);
}
Aggregations