private Expression transformMethodCallExpression(final MethodCallExpression exp) { Expression objectExpression = transform(exp.getObjectExpression()); ClassNode traitReceiver = objectExpression.getNodeMetaData(SuperCallTraitTransformer.class); if (traitReceiver != null) { TraitHelpersTuple helpers = Traits.findHelpers(traitReceiver); // (SomeTrait.super).foo() --> SomeTrait$Helper.foo(this) ClassExpression receiver = new ClassExpression(helpers.getHelper()); 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(arguments); } MethodCallExpression result = new MethodCallExpression(receiver, exp.getMethod(), newArgs); result.setImplicitThis(false); result.setSpreadSafe(exp.isSpreadSafe()); result.setSafe(exp.isSafe()); result.setSourcePosition(exp); return result; } return super.transform(exp); }
/** * Evaluates a constraints closure and returns metadata about the constraints configured in the * closure. The Map returned has property names as keys and the value associated with each of * those property names is a Map<String, Expression> which has constraint names as keys and the * Expression associated with that constraint as values * * @param closureExpression the closure expression to evaluate * @return the Map as described above */ public static Map<String, Map<String, Expression>> getConstraintMetadata( final ClosureExpression closureExpression) { final List<MethodCallExpression> methodExpressions = new ArrayList<MethodCallExpression>(); final Map<String, Map<String, Expression>> results = new LinkedHashMap<String, Map<String, Expression>>(); final Statement closureCode = closureExpression.getCode(); if (closureCode instanceof BlockStatement) { final List<Statement> closureStatements = ((BlockStatement) closureCode).getStatements(); for (final Statement closureStatement : closureStatements) { if (closureStatement instanceof ExpressionStatement) { final Expression expression = ((ExpressionStatement) closureStatement).getExpression(); if (expression instanceof MethodCallExpression) { methodExpressions.add((MethodCallExpression) expression); } } else if (closureStatement instanceof ReturnStatement) { final ReturnStatement returnStatement = (ReturnStatement) closureStatement; Expression expression = returnStatement.getExpression(); if (expression instanceof MethodCallExpression) { methodExpressions.add((MethodCallExpression) expression); } } for (final MethodCallExpression methodCallExpression : methodExpressions) { final Expression objectExpression = methodCallExpression.getObjectExpression(); if (objectExpression instanceof VariableExpression && "this".equals(((VariableExpression) objectExpression).getName())) { final Expression methodCallArguments = methodCallExpression.getArguments(); if (methodCallArguments instanceof TupleExpression) { final List<Expression> methodCallArgumentExpressions = ((TupleExpression) methodCallArguments).getExpressions(); if (methodCallArgumentExpressions != null && methodCallArgumentExpressions.size() == 1 && methodCallArgumentExpressions.get(0) instanceof NamedArgumentListExpression) { final Map<String, Expression> constraintNameToExpression = new LinkedHashMap<String, Expression>(); final List<MapEntryExpression> mapEntryExpressions = ((NamedArgumentListExpression) methodCallArgumentExpressions.get(0)) .getMapEntryExpressions(); for (final MapEntryExpression mapEntryExpression : mapEntryExpressions) { final Expression keyExpression = mapEntryExpression.getKeyExpression(); if (keyExpression instanceof ConstantExpression) { final Object value = ((ConstantExpression) keyExpression).getValue(); if (value instanceof String) { constraintNameToExpression.put( (String) value, mapEntryExpression.getValueExpression()); } } } results.put(methodCallExpression.getMethodAsString(), constraintNameToExpression); } } } } } } return results; }
Expression transformMethodCallExpression(final MethodCallExpression expr) { Expression objectExpression = expr.getObjectExpression(); if (expr.isSafe()) { MethodCallExpression notSafe = new MethodCallExpression(objectExpression, expr.getMethod(), expr.getArguments()); notSafe.copyNodeMetaData(expr); notSafe.setSpreadSafe(expr.isSpreadSafe()); notSafe.setSourcePosition(expr); notSafe.setMethodTarget(expr.getMethodTarget()); TernaryExpression texpr = new TernaryExpression( new BooleanExpression( new BinaryExpression( objectExpression, Token.newSymbol( "!=", objectExpression.getLineNumber(), objectExpression.getColumnNumber()), ConstantExpression.NULL)), notSafe, ConstantExpression.NULL); return staticCompilationTransformer.transform(texpr); } ClassNode type = staticCompilationTransformer .getTypeChooser() .resolveType(objectExpression, staticCompilationTransformer.getClassNode()); 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); } } } } 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); }
protected Expression transformMethodCallExpression(MethodCallExpression mce) { Expression args = transform(mce.getArguments()); Expression method = transform(mce.getMethod()); Expression object = transform(mce.getObjectExpression()); boolean isExplicitThisOrSuper = false; boolean isExplicitSuper = false; if (object instanceof VariableExpression) { VariableExpression ve = (VariableExpression) object; isExplicitThisOrSuper = !mce.isImplicitThis() && (ve.isThisExpression() || ve.isSuperExpression()); isExplicitSuper = ve.isSuperExpression(); } if (mce.isImplicitThis() || isExplicitThisOrSuper) { if (mce.isImplicitThis()) { Expression ret = findStaticMethodImportFromModule(method, args); if (ret != null) { setSourcePosition(ret, mce); return ret; } if (method instanceof ConstantExpression && !inLeftExpression) { // could be a closure field String methodName = (String) ((ConstantExpression) method).getValue(); ret = findStaticFieldOrPropAccessorImportFromModule(methodName); if (ret != null) { ret = new MethodCallExpression(ret, "call", args); setSourcePosition(ret, mce); return ret; } } } else if (currentMethod != null && currentMethod.isStatic() && isExplicitSuper) { MethodCallExpression ret = new MethodCallExpression( new ClassExpression(currentClass.getSuperClass()), method, args); setSourcePosition(ret, mce); return ret; } if (method instanceof ConstantExpression) { ConstantExpression ce = (ConstantExpression) method; Object value = ce.getValue(); if (value instanceof String) { String methodName = (String) value; boolean lookForPossibleStaticMethod = !methodName.equals("call"); if (currentMethod != null && !currentMethod.isStatic()) { if (currentClass.hasPossibleMethod(methodName, args)) { lookForPossibleStaticMethod = false; } } if (!inClosure && (inSpecialConstructorCall || (lookForPossibleStaticMethod && currentClass.hasPossibleStaticMethod(methodName, args)))) { StaticMethodCallExpression smce = new StaticMethodCallExpression(currentClass, methodName, args); setSourcePosition(smce, mce); return smce; } } } } MethodCallExpression result = new MethodCallExpression(object, method, args); result.setSafe(mce.isSafe()); result.setImplicitThis(mce.isImplicitThis()); result.setSpreadSafe(mce.isSpreadSafe()); result.setMethodTarget(mce.getMethodTarget()); // GROOVY-6757 result.setGenericsTypes(mce.getGenericsTypes()); setSourcePosition(result, mce); return result; }
public void visitMethodCallExpression(MethodCallExpression call) { call.getObjectExpression().visit(this); call.getMethod().visit(this); call.getArguments().visit(this); }
protected Expression transformMethodCallExpression(MethodCallExpression mce) { Expression args = transform(mce.getArguments()); Expression method = transform(mce.getMethod()); Expression object = transform(mce.getObjectExpression()); boolean isExplicitThisOrSuper = false; if (object instanceof VariableExpression) { VariableExpression ve = (VariableExpression) object; isExplicitThisOrSuper = !mce.isImplicitThis() && (ve.getName().equals("this") || ve.getName().equals("super")); } if (mce.isImplicitThis() || isExplicitThisOrSuper) { if (mce.isImplicitThis()) { Expression ret = findStaticMethodImportFromModule(method, args); if (ret != null) { // GRECLIPSE add if (!((StaticMethodCallExpression) ret).getMethod().equals(method.getText())) { // store the identifier to facilitate organizing static imports ret.setNodeMetaData("static.import.alias", method.getText()); } // GRECLIPSE end setSourcePosition(ret, mce); return ret; } if (method instanceof ConstantExpression && !inLeftExpression) { // could be a closure field String methodName = (String) ((ConstantExpression) method).getValue(); ret = findStaticFieldOrPropAccessorImportFromModule(methodName); if (ret != null) { ret = new MethodCallExpression(ret, "call", args); setSourcePosition(ret, mce); return ret; } } } if (method instanceof ConstantExpression) { ConstantExpression ce = (ConstantExpression) method; Object value = ce.getValue(); if (value instanceof String) { String methodName = (String) value; boolean lookForPossibleStaticMethod = !methodName.equals("call"); if (currentMethod != null && !currentMethod.isStatic()) { if (currentClass.hasPossibleMethod(methodName, args)) { lookForPossibleStaticMethod = false; } } if (inSpecialConstructorCall || (lookForPossibleStaticMethod && currentClass.hasPossibleStaticMethod(methodName, args))) { StaticMethodCallExpression smce = new StaticMethodCallExpression(currentClass, methodName, args); setSourcePosition(smce, mce); return smce; } } } } MethodCallExpression result = new MethodCallExpression(object, method, args); result.setSafe(mce.isSafe()); result.setImplicitThis(mce.isImplicitThis()); result.setSpreadSafe(mce.isSpreadSafe()); result.setMethodTarget(mce.getMethodTarget()); // GROOVY-6757 result.setGenericsTypes(mce.getGenericsTypes()); setSourcePosition(result, mce); return result; }
public static boolean targetIsThis(MethodCallExpression call) { Expression target = call.getObjectExpression(); return target instanceof VariableExpression && target.getText().equals("this"); }