Search in sources :

Example 91 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.

the class JavaStubGenerator method getAnnotationValue.

private String getAnnotationValue(Object memberValue) {
    String val = "null";
    if (memberValue instanceof ListExpression) {
        StringBuilder sb = new StringBuilder("{");
        boolean first = true;
        ListExpression le = (ListExpression) memberValue;
        for (Expression e : le.getExpressions()) {
            if (first)
                first = false;
            else
                sb.append(",");
            sb.append(getAnnotationValue(e));
        }
        sb.append("}");
        val = sb.toString();
    } else if (memberValue instanceof ConstantExpression) {
        ConstantExpression ce = (ConstantExpression) memberValue;
        Object constValue = ce.getValue();
        if (constValue instanceof AnnotationNode) {
            StringWriter writer = new StringWriter();
            PrintWriter out = new PrintWriter(writer);
            printAnnotation(out, (AnnotationNode) constValue);
            val = writer.toString();
        } else if (constValue instanceof Number || constValue instanceof Boolean)
            val = constValue.toString();
        else
            val = "\"" + escapeSpecialChars(constValue.toString()) + "\"";
    } else if (memberValue instanceof PropertyExpression || memberValue instanceof VariableExpression) {
        // assume must be static class field or enum value or class that Java can resolve
        val = ((Expression) memberValue).getText();
    } else if (memberValue instanceof ClosureExpression) {
        // annotation closure; replaced with this specific class literal to cover the
        // case where annotation type uses Class<? extends Closure> for the closure's type
        val = "groovy.lang.Closure.class";
    } else if (memberValue instanceof ClassExpression) {
        val = ((Expression) memberValue).getText() + ".class";
    }
    return val;
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) StringWriter(java.io.StringWriter) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) PrintWriter(java.io.PrintWriter)

Example 92 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.

the class ImmutableASTTransformation method getKnownImmutables.

private List<String> getKnownImmutables(AnnotationNode node) {
    final ArrayList<String> immutables = new ArrayList<String>();
    final Expression expression = node.getMember(MEMBER_KNOWN_IMMUTABLES);
    if (expression == null)
        return immutables;
    if (!(expression instanceof ListExpression)) {
        addError("Use the Groovy list notation [el1, el2] to specify known immutable property names via \"" + MEMBER_KNOWN_IMMUTABLES + "\"", node);
        return immutables;
    }
    final ListExpression listExpression = (ListExpression) expression;
    for (Expression listItemExpression : listExpression.getExpressions()) {
        if (listItemExpression instanceof ConstantExpression) {
            immutables.add((String) ((ConstantExpression) listItemExpression).getValue());
        }
    }
    return immutables;
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ArrayList(java.util.ArrayList) ToStringASTTransformation.createToString(org.codehaus.groovy.transform.ToStringASTTransformation.createToString)

Example 93 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.

the class GrabAnnotationTransformation method callGrabAsStaticInitIfNeeded.

private void callGrabAsStaticInitIfNeeded(ClassNode classNode, ClassNode grapeClassNode, List<Map<String, Object>> grabMapsInit, List<Map<String, Object>> grabExcludeMaps) {
    List<Statement> grabInitializers = new ArrayList<Statement>();
    MapExpression basicArgs = new MapExpression();
    if (autoDownload != null) {
        basicArgs.addMapEntryExpression(new ConstantExpression(AUTO_DOWNLOAD_SETTING), new ConstantExpression(autoDownload));
    }
    if (disableChecksums != null) {
        basicArgs.addMapEntryExpression(new ConstantExpression(DISABLE_CHECKSUMS_SETTING), new ConstantExpression(disableChecksums));
    }
    if (!grabExcludeMaps.isEmpty()) {
        ListExpression list = new ListExpression();
        for (Map<String, Object> map : grabExcludeMaps) {
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            MapExpression inner = new MapExpression();
            for (Map.Entry<String, Object> entry : entries) {
                inner.addMapEntryExpression(new ConstantExpression(entry.getKey()), new ConstantExpression(entry.getValue()));
            }
            list.addExpression(inner);
        }
        basicArgs.addMapEntryExpression(new ConstantExpression("excludes"), list);
    }
    List<Expression> argList = new ArrayList<Expression>();
    argList.add(basicArgs);
    if (grabMapsInit.size() == 0)
        return;
    for (Map<String, Object> grabMap : grabMapsInit) {
        // add Grape.grab(excludeArgs, [group:group, module:module, version:version, classifier:classifier])
        // or Grape.grab([group:group, module:module, version:version, classifier:classifier])
        MapExpression dependencyArg = new MapExpression();
        for (String s : GRAB_REQUIRED) {
            dependencyArg.addMapEntryExpression(new ConstantExpression(s), new ConstantExpression(grabMap.get(s)));
        }
        for (String s : GRAB_OPTIONAL) {
            if (grabMap.containsKey(s))
                dependencyArg.addMapEntryExpression(new ConstantExpression(s), new ConstantExpression(grabMap.get(s)));
        }
        argList.add(dependencyArg);
    }
    ArgumentListExpression grabArgs = new ArgumentListExpression(argList);
    grabInitializers.add(new ExpressionStatement(new StaticMethodCallExpression(grapeClassNode, "grab", grabArgs)));
    // insert at beginning so we have the classloader set up before the class is called
    classNode.addStaticInitializerStatements(grabInitializers, true);
}
Also used : MapExpression(org.codehaus.groovy.ast.expr.MapExpression) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 94 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.

the class GrabAnnotationTransformation method visit.

public void visit(ASTNode[] nodes, SourceUnit source) {
    sourceUnit = source;
    loader = null;
    initContextClassLoader = false;
    ModuleNode mn = (ModuleNode) nodes[0];
    allowShortGrab = true;
    allowShortGrabExcludes = true;
    allowShortGrabConfig = true;
    allowShortGrapes = true;
    allowShortGrabResolver = true;
    grabAliases = new HashSet<String>();
    grabExcludeAliases = new HashSet<String>();
    grabConfigAliases = new HashSet<String>();
    grapesAliases = new HashSet<String>();
    grabResolverAliases = new HashSet<String>();
    for (ImportNode im : mn.getImports()) {
        String alias = im.getAlias();
        String className = im.getClassName();
        if ((className.endsWith(GRAB_DOT_NAME) && ((alias == null) || (alias.length() == 0))) || (GRAB_CLASS_NAME.equals(alias))) {
            allowShortGrab = false;
        } else if (GRAB_CLASS_NAME.equals(className)) {
            grabAliases.add(im.getAlias());
        }
        if ((className.endsWith(GRAPES_DOT_NAME) && ((alias == null) || (alias.length() == 0))) || (GRAPES_CLASS_NAME.equals(alias))) {
            allowShortGrapes = false;
        } else if (GRAPES_CLASS_NAME.equals(className)) {
            grapesAliases.add(im.getAlias());
        }
        if ((className.endsWith(GRABRESOLVER_DOT_NAME) && ((alias == null) || (alias.length() == 0))) || (GRABRESOLVER_CLASS_NAME.equals(alias))) {
            allowShortGrabResolver = false;
        } else if (GRABRESOLVER_CLASS_NAME.equals(className)) {
            grabResolverAliases.add(im.getAlias());
        }
    }
    List<Map<String, Object>> grabMaps = new ArrayList<Map<String, Object>>();
    List<Map<String, Object>> grabMapsInit = new ArrayList<Map<String, Object>>();
    List<Map<String, Object>> grabExcludeMaps = new ArrayList<Map<String, Object>>();
    for (ClassNode classNode : sourceUnit.getAST().getClasses()) {
        grabAnnotations = new ArrayList<AnnotationNode>();
        grabExcludeAnnotations = new ArrayList<AnnotationNode>();
        grabConfigAnnotations = new ArrayList<AnnotationNode>();
        grapesAnnotations = new ArrayList<AnnotationNode>();
        grabResolverAnnotations = new ArrayList<AnnotationNode>();
        visitClass(classNode);
        ClassNode grapeClassNode = ClassHelper.make(Grape.class);
        List<Statement> grabResolverInitializers = new ArrayList<Statement>();
        if (!grapesAnnotations.isEmpty()) {
            for (AnnotationNode node : grapesAnnotations) {
                Expression init = node.getMember("initClass");
                Expression value = node.getMember("value");
                if (value instanceof ListExpression) {
                    for (Object o : ((ListExpression) value).getExpressions()) {
                        if (o instanceof ConstantExpression) {
                            extractGrab(init, (ConstantExpression) o);
                        }
                    }
                } else if (value instanceof ConstantExpression) {
                    extractGrab(init, (ConstantExpression) value);
                }
            // don't worry if it's not a ListExpression, or AnnotationConstant, etc.
            // the rest of GroovyC will flag it as a syntax error later, so we don't
            // need to raise the error ourselves
            }
        }
        if (!grabResolverAnnotations.isEmpty()) {
            grabResolverAnnotationLoop: for (AnnotationNode node : grabResolverAnnotations) {
                Map<String, Object> grabResolverMap = new HashMap<String, Object>();
                String sval = getMemberStringValue(node, "value");
                if (sval != null && sval.length() > 0) {
                    for (String s : GRABRESOLVER_REQUIRED) {
                        String mval = getMemberStringValue(node, s);
                        if (mval != null && mval.isEmpty())
                            mval = null;
                        if (mval != null) {
                            addError("The attribute \"" + s + "\" conflicts with attribute 'value' in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
                            continue grabResolverAnnotationLoop;
                        }
                    }
                    grabResolverMap.put("name", sval);
                    grabResolverMap.put("root", sval);
                } else {
                    for (String s : GRABRESOLVER_REQUIRED) {
                        String mval = getMemberStringValue(node, s);
                        if (mval != null && mval.isEmpty())
                            mval = null;
                        Expression member = node.getMember(s);
                        if (member == null || mval == null) {
                            addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
                            continue grabResolverAnnotationLoop;
                        } else if (mval == null) {
                            addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant String in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
                            continue grabResolverAnnotationLoop;
                        }
                        grabResolverMap.put(s, mval);
                    }
                }
                // If no scheme is specified for the repository root,
                // then turn it into a URI relative to that of the source file.
                String root = (String) grabResolverMap.get("root");
                if (root != null && !root.contains(":")) {
                    URI sourceURI = null;
                    // and those are not hierarchical we can't use them for making an absolute URI.
                    if (!(getSourceUnit().getSource() instanceof StringReaderSource)) {
                        // Otherwise let's trust the source to know where it is from.
                        // And actually InputStreamReaderSource doesn't know what to do and so returns null.
                        sourceURI = getSourceUnit().getSource().getURI();
                    }
                    // then let's use the current working directory, since the repo can be relative to that.
                    if (sourceURI == null) {
                        sourceURI = new File(".").toURI();
                    }
                    try {
                        URI rootURI = sourceURI.resolve(new URI(root));
                        grabResolverMap.put("root", rootURI.toString());
                    } catch (URISyntaxException e) {
                    // We'll be silent here.
                    // If the URI scheme is unknown or not hierarchical, then we just can't help them and shouldn't cause any trouble either.
                    // addError("Attribute \"root\" has value '" + root + "' which can't be turned into a valid URI relative to it's source '" + getSourceUnit().getName() + "' @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
                    }
                }
                Grape.addResolver(grabResolverMap);
                addGrabResolverAsStaticInitIfNeeded(grapeClassNode, node, grabResolverInitializers, grabResolverMap);
            }
        }
        if (!grabConfigAnnotations.isEmpty()) {
            for (AnnotationNode node : grabConfigAnnotations) {
                checkForClassLoader(node);
                checkForInitContextClassLoader(node);
                checkForAutoDownload(node);
                checkForDisableChecksums(node);
            }
            addInitContextClassLoaderIfNeeded(classNode);
        }
        if (!grabExcludeAnnotations.isEmpty()) {
            grabExcludeAnnotationLoop: for (AnnotationNode node : grabExcludeAnnotations) {
                Map<String, Object> grabExcludeMap = new HashMap<String, Object>();
                checkForConvenienceForm(node, true);
                for (String s : GRABEXCLUDE_REQUIRED) {
                    Expression member = node.getMember(s);
                    if (member == null) {
                        addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
                        continue grabExcludeAnnotationLoop;
                    } else if (member != null && !(member instanceof ConstantExpression)) {
                        addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
                        continue grabExcludeAnnotationLoop;
                    }
                    grabExcludeMap.put(s, ((ConstantExpression) member).getValue());
                }
                grabExcludeMaps.add(grabExcludeMap);
            }
        }
        if (!grabAnnotations.isEmpty()) {
            grabAnnotationLoop: for (AnnotationNode node : grabAnnotations) {
                Map<String, Object> grabMap = new HashMap<String, Object>();
                checkForConvenienceForm(node, false);
                for (String s : GRAB_ALL) {
                    Expression member = node.getMember(s);
                    String mval = getMemberStringValue(node, s);
                    if (mval != null && mval.isEmpty())
                        member = null;
                    if (member == null && !GRAB_OPTIONAL.contains(s)) {
                        addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
                        continue grabAnnotationLoop;
                    } else if (member != null && !(member instanceof ConstantExpression)) {
                        addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
                        continue grabAnnotationLoop;
                    }
                    if (node.getMember(s) != null) {
                        grabMap.put(s, ((ConstantExpression) member).getValue());
                    }
                }
                grabMaps.add(grabMap);
                if ((node.getMember("initClass") == null) || (node.getMember("initClass") == ConstantExpression.TRUE)) {
                    grabMapsInit.add(grabMap);
                }
            }
            callGrabAsStaticInitIfNeeded(classNode, grapeClassNode, grabMapsInit, grabExcludeMaps);
        }
        if (!grabResolverInitializers.isEmpty()) {
            classNode.addStaticInitializerStatements(grabResolverInitializers, true);
        }
    }
    if (!grabMaps.isEmpty()) {
        Map<String, Object> basicArgs = new HashMap<String, Object>();
        basicArgs.put("classLoader", loader != null ? loader : sourceUnit.getClassLoader());
        if (!grabExcludeMaps.isEmpty())
            basicArgs.put("excludes", grabExcludeMaps);
        if (autoDownload != null)
            basicArgs.put(AUTO_DOWNLOAD_SETTING, autoDownload);
        if (disableChecksums != null)
            basicArgs.put(DISABLE_CHECKSUMS_SETTING, disableChecksums);
        try {
            Grape.grab(basicArgs, grabMaps.toArray(new Map[grabMaps.size()]));
            // grab may have added more transformations through new URLs added to classpath, so do one more scan
            if (compilationUnit != null) {
                ASTTransformationVisitor.addGlobalTransformsAfterGrab(compilationUnit.getASTTransformationsContext());
            }
        } catch (RuntimeException re) {
            // Decided against syntax exception since this is not a syntax error.
            // The down side is we lose line number information for the offending
            // @Grab annotation.
            source.addException(re);
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) StringReaderSource(org.codehaus.groovy.control.io.StringReaderSource) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ImportNode(org.codehaus.groovy.ast.ImportNode) File(java.io.File) ModuleNode(org.codehaus.groovy.ast.ModuleNode)

Example 95 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.

the class BinaryExpressionTransformer method transformBinaryExpression.

Expression transformBinaryExpression(final BinaryExpression bin) {
    if (bin instanceof DeclarationExpression) {
        Expression optimized = transformDeclarationExpression(bin);
        if (optimized != null) {
            return optimized;
        }
    }
    Object[] list = bin.getNodeMetaData(BINARY_EXP_TARGET);
    Token operation = bin.getOperation();
    int operationType = operation.getType();
    Expression rightExpression = bin.getRightExpression();
    Expression leftExpression = bin.getLeftExpression();
    if (bin instanceof DeclarationExpression && leftExpression instanceof VariableExpression) {
        ClassNode declarationType = ((VariableExpression) leftExpression).getOriginType();
        if (rightExpression instanceof ConstantExpression) {
            ClassNode unwrapper = ClassHelper.getUnwrapper(declarationType);
            ClassNode wrapper = ClassHelper.getWrapper(declarationType);
            if (!rightExpression.getType().equals(declarationType) && wrapper.isDerivedFrom(ClassHelper.Number_TYPE) && WideningCategories.isDoubleCategory(unwrapper)) {
                ConstantExpression constant = (ConstantExpression) rightExpression;
                if (constant.getValue() != null) {
                    return optimizeConstantInitialization(bin, operation, constant, leftExpression, declarationType);
                }
            }
        }
    }
    if (operationType == Types.EQUAL && leftExpression instanceof PropertyExpression) {
        MethodNode directMCT = leftExpression.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
        if (directMCT != null) {
            return transformPropertyAssignmentToSetterCall((PropertyExpression) leftExpression, rightExpression, directMCT);
        }
    }
    if (operationType == Types.COMPARE_EQUAL || operationType == Types.COMPARE_NOT_EQUAL) {
        // let's check if one of the operands is the null constant
        CompareToNullExpression compareToNullExpression = null;
        if (isNullConstant(leftExpression)) {
            compareToNullExpression = new CompareToNullExpression(staticCompilationTransformer.transform(rightExpression), operationType == Types.COMPARE_EQUAL);
        } else if (isNullConstant(rightExpression)) {
            compareToNullExpression = new CompareToNullExpression(staticCompilationTransformer.transform(leftExpression), operationType == Types.COMPARE_EQUAL);
        }
        if (compareToNullExpression != null) {
            compareToNullExpression.setSourcePosition(bin);
            return compareToNullExpression;
        }
    } else if (operationType == Types.KEYWORD_IN) {
        return convertInOperatorToTernary(bin, rightExpression, leftExpression);
    }
    if (list != null) {
        if (operationType == Types.COMPARE_TO) {
            StaticTypesTypeChooser typeChooser = staticCompilationTransformer.getTypeChooser();
            ClassNode classNode = staticCompilationTransformer.getClassNode();
            ClassNode leftType = typeChooser.resolveType(leftExpression, classNode);
            if (leftType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
                ClassNode rightType = typeChooser.resolveType(rightExpression, classNode);
                if (rightType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
                    Expression left = staticCompilationTransformer.transform(leftExpression);
                    Expression right = staticCompilationTransformer.transform(rightExpression);
                    MethodCallExpression call = new MethodCallExpression(left, "compareTo", new ArgumentListExpression(right));
                    call.setImplicitThis(false);
                    call.setMethodTarget(COMPARE_TO_METHOD);
                    CompareIdentityExpression compareIdentity = new CompareIdentityExpression(left, right);
                    compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.boolean_TYPE);
                    TernaryExpression result = new TernaryExpression(// a==b
                    new BooleanExpression(compareIdentity), CONSTANT_ZERO, new TernaryExpression(// a==null
                    new BooleanExpression(new CompareToNullExpression(left, true)), CONSTANT_MINUS_ONE, new TernaryExpression(// b==null
                    new BooleanExpression(new CompareToNullExpression(right, true)), CONSTANT_ONE, call)));
                    compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.int_TYPE);
                    result.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
                    TernaryExpression expr = (TernaryExpression) result.getFalseExpression();
                    expr.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
                    expr.getFalseExpression().putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
                    return result;
                }
            }
        }
        boolean isAssignment = StaticTypeCheckingSupport.isAssignment(operationType);
        MethodCallExpression call;
        MethodNode node = (MethodNode) list[0];
        String name = (String) list[1];
        Expression left = staticCompilationTransformer.transform(leftExpression);
        Expression right = staticCompilationTransformer.transform(rightExpression);
        BinaryExpression optimized = tryOptimizeCharComparison(left, right, bin);
        if (optimized != null) {
            optimized.removeNodeMetaData(BINARY_EXP_TARGET);
            return transformBinaryExpression(optimized);
        }
        call = new MethodCallExpression(left, name, new ArgumentListExpression(right));
        call.setImplicitThis(false);
        call.setMethodTarget(node);
        MethodNode adapter = StaticCompilationTransformer.BYTECODE_BINARY_ADAPTERS.get(operationType);
        if (adapter != null) {
            ClassExpression sba = new ClassExpression(StaticCompilationTransformer.BYTECODE_ADAPTER_CLASS);
            // replace with compareEquals
            call = new MethodCallExpression(sba, "compareEquals", new ArgumentListExpression(left, right));
            call.setMethodTarget(adapter);
            call.setImplicitThis(false);
        }
        if (!isAssignment)
            return call;
        // the method represents the operation type only, and we must add an assignment
        return new BinaryExpression(left, Token.newSymbol("=", operation.getStartLine(), operation.getStartColumn()), call);
    }
    if (bin.getOperation().getType() == Types.EQUAL && leftExpression instanceof TupleExpression && rightExpression instanceof ListExpression) {
        // multiple assignment
        ListOfExpressionsExpression cle = new ListOfExpressionsExpression();
        boolean isDeclaration = bin instanceof DeclarationExpression;
        List<Expression> leftExpressions = ((TupleExpression) leftExpression).getExpressions();
        List<Expression> rightExpressions = ((ListExpression) rightExpression).getExpressions();
        Iterator<Expression> leftIt = leftExpressions.iterator();
        Iterator<Expression> rightIt = rightExpressions.iterator();
        if (isDeclaration) {
            while (leftIt.hasNext()) {
                Expression left = leftIt.next();
                if (rightIt.hasNext()) {
                    Expression right = rightIt.next();
                    BinaryExpression bexp = new DeclarationExpression(left, bin.getOperation(), right);
                    bexp.setSourcePosition(right);
                    cle.addExpression(bexp);
                }
            }
        } else {
            // (next, result) = [ result, next+result ]
            // -->
            // def tmp1 = result
            // def tmp2 = next+result
            // next = tmp1
            // result = tmp2
            int size = rightExpressions.size();
            List<Expression> tmpAssignments = new ArrayList<Expression>(size);
            List<Expression> finalAssignments = new ArrayList<Expression>(size);
            for (int i = 0; i < Math.min(size, leftExpressions.size()); i++) {
                Expression left = leftIt.next();
                Expression right = rightIt.next();
                VariableExpression tmpVar = new VariableExpression("$tmpVar$" + tmpVarCounter++);
                BinaryExpression bexp = new DeclarationExpression(tmpVar, bin.getOperation(), right);
                bexp.setSourcePosition(right);
                tmpAssignments.add(bexp);
                bexp = new BinaryExpression(left, bin.getOperation(), new VariableExpression(tmpVar));
                bexp.setSourcePosition(left);
                finalAssignments.add(bexp);
            }
            for (Expression tmpAssignment : tmpAssignments) {
                cle.addExpression(tmpAssignment);
            }
            for (Expression finalAssignment : finalAssignments) {
                cle.addExpression(finalAssignment);
            }
        }
        return staticCompilationTransformer.transform(cle);
    }
    return staticCompilationTransformer.superTransform(bin);
}
Also used : TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArrayList(java.util.ArrayList) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) Token(org.codehaus.groovy.syntax.Token) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) ListOfExpressionsExpression(org.codehaus.groovy.transform.sc.ListOfExpressionsExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClassNode(org.codehaus.groovy.ast.ClassNode) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ListOfExpressionsExpression(org.codehaus.groovy.transform.sc.ListOfExpressionsExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) StaticTypesTypeChooser(org.codehaus.groovy.classgen.asm.sc.StaticTypesTypeChooser)

Aggregations

ListExpression (org.codehaus.groovy.ast.expr.ListExpression)103 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)77 Expression (org.codehaus.groovy.ast.expr.Expression)77 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)70 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)53 ClassNode (org.codehaus.groovy.ast.ClassNode)49 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)43 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)42 MapExpression (org.codehaus.groovy.ast.expr.MapExpression)38 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)38 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)37 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)32 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)32 ArrayList (java.util.ArrayList)31 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)30 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)28 AnnotationConstantExpression (org.codehaus.groovy.ast.expr.AnnotationConstantExpression)25 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)25 MapEntryExpression (org.codehaus.groovy.ast.expr.MapEntryExpression)23 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)22