Example usage for org.objectweb.asm Opcodes ACC_STATIC

List of usage examples for org.objectweb.asm Opcodes ACC_STATIC

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes ACC_STATIC.

Prototype

int ACC_STATIC

To view the source code for org.objectweb.asm Opcodes ACC_STATIC.

Click Source Link

Usage

From source file:org.codehaus.groovy.runtime.callsite.CallSiteGenerator.java

License:Apache License

public static byte[] genPogoMetaMethodSite(CachedMethod cachedMethod, ClassWriter cw, String name) {
    String internalName = name.replace('.', '/');
    classHeader(cw, internalName, "org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite");
    cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "__constructor__", "Ljava/lang/reflect/Constructor;",
            null, null);/*  ww  w.j a  v  a 2  s. c  o  m*/

    genConstructor(cw, "org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite", internalName);

    genCallXxxWithArray(cw, "Current", "org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite", cachedMethod,
            "groovy/lang/GroovyObject");
    genCallXxxWithArray(cw, "", "org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite", cachedMethod,
            "java/lang/Object");

    genCallWithFixedParams(cw, "Current", "org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite",
            cachedMethod, "groovy/lang/GroovyObject");
    genCallWithFixedParams(cw, "", "org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite", cachedMethod,
            "java/lang/Object");

    cw.visitEnd();

    return cw.toByteArray();
}

From source file:org.codehaus.groovy.runtime.callsite.CallSiteGenerator.java

License:Apache License

public static byte[] genPojoMetaMethodSite(CachedMethod cachedMethod, ClassWriter cw, String name) {
    String internalName = name.replace('.', '/');
    classHeader(cw, internalName, "org/codehaus/groovy/runtime/callsite/PojoMetaMethodSite");
    cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "__constructor__", "Ljava/lang/reflect/Constructor;",
            null, null);/*w ww .j a  v a 2s .co  m*/

    genConstructor(cw, "org/codehaus/groovy/runtime/callsite/PojoMetaMethodSite", internalName);

    genCallXxxWithArray(cw, "", "org/codehaus/groovy/runtime/callsite/PojoMetaMethodSite", cachedMethod,
            "java/lang/Object");
    genCallWithFixedParams(cw, "", "org/codehaus/groovy/runtime/callsite/PojoMetaMethodSite", cachedMethod,
            "java/lang/Object");

    cw.visitEnd();

    return cw.toByteArray();
}

From source file:org.codehaus.groovy.runtime.callsite.CallSiteGenerator.java

License:Apache License

public static byte[] genStaticMetaMethodSite(CachedMethod cachedMethod, ClassWriter cw, String name) {
    String internalName = name.replace('.', '/');
    classHeader(cw, internalName, "org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite");
    cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "__constructor__", "Ljava/lang/reflect/Constructor;",
            null, null);//  w ww.j a  va  2 s .  c  om

    genConstructor(cw, "org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite", internalName);

    genCallXxxWithArray(cw, "", "org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite", cachedMethod,
            "java/lang/Object");
    genCallXxxWithArray(cw, "Static", "org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite", cachedMethod,
            "java/lang/Class");
    genCallWithFixedParams(cw, "", "org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite", cachedMethod,
            "java/lang/Object");
    genCallWithFixedParams(cw, "Static", "org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite",
            cachedMethod, "java/lang/Class");

    cw.visitEnd();

    return cw.toByteArray();
}

From source file:org.codehaus.groovy.tools.javac.JavaStubGenerator.java

License:Apache License

private static void printModifiers(PrintWriter out, int modifiers) {
    if ((modifiers & Opcodes.ACC_PUBLIC) != 0)
        out.print("public ");

    if ((modifiers & Opcodes.ACC_PROTECTED) != 0)
        out.print("protected ");

    if ((modifiers & Opcodes.ACC_PRIVATE) != 0)
        out.print("private ");

    if ((modifiers & Opcodes.ACC_STATIC) != 0)
        out.print("static ");

    if ((modifiers & Opcodes.ACC_SYNCHRONIZED) != 0)
        out.print("synchronized ");

    if ((modifiers & Opcodes.ACC_FINAL) != 0)
        out.print("final ");

    if ((modifiers & Opcodes.ACC_ABSTRACT) != 0)
        out.print("abstract ");
}

From source file:org.codehaus.groovy.transform.CategoryASTTransformation.java

License:Apache License

/**
 * Property invocations done on 'this' reference are transformed so that the invocations at runtime are
 * done on the additional parameter 'self'
 *//* ww w  . j  a  va  2  s .  com*/
public void visit(ASTNode[] nodes, final SourceUnit source) {
    if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof ClassNode)) {
        source.getErrorCollector()
                .addError(new SyntaxErrorMessage(new SyntaxException(
                        "@Category can only be added to a ClassNode but got: "
                                + (nodes.length == 2 ? nodes[1] : "nothing"),
                        nodes[0].getLineNumber(), nodes[0].getColumnNumber()), source));
    }

    AnnotationNode annotation = (AnnotationNode) nodes[0];
    ClassNode parent = (ClassNode) nodes[1];

    ClassNode targetClass = getTargetClass(source, annotation);
    thisExpression.setType(targetClass);

    final LinkedList<Set<String>> varStack = new LinkedList<Set<String>>();
    if (!ensureNoInstanceFieldOrProperty(source, parent))
        return;

    Set<String> names = new HashSet<String>();
    for (FieldNode field : parent.getFields()) {
        names.add(field.getName());
    }
    for (PropertyNode field : parent.getProperties()) {
        names.add(field.getName());
    }
    varStack.add(names);

    final Reference parameter = new Reference();
    final ClassCodeExpressionTransformer expressionTransformer = new ClassCodeExpressionTransformer() {
        protected SourceUnit getSourceUnit() {
            return source;
        }

        private void addVariablesToStack(Parameter[] params) {
            Set<String> names = new HashSet<String>(varStack.getLast());
            for (Parameter param : params) {
                names.add(param.getName());
            }
            varStack.add(names);
        }

        @Override
        public void visitCatchStatement(CatchStatement statement) {
            varStack.getLast().add(statement.getVariable().getName());
            super.visitCatchStatement(statement);
            varStack.getLast().remove(statement.getVariable().getName());
        }

        @Override
        public void visitMethod(MethodNode node) {
            addVariablesToStack(node.getParameters());
            super.visitMethod(node);
            varStack.removeLast();
        }

        @Override
        public void visitBlockStatement(BlockStatement block) {
            Set<String> names = new HashSet<String>(varStack.getLast());
            varStack.add(names);
            super.visitBlockStatement(block);
            varStack.remove(names);
        }

        @Override
        public void visitClosureExpression(ClosureExpression ce) {
            addVariablesToStack(getParametersSafe(ce));
            super.visitClosureExpression(ce);
            varStack.removeLast();
        }

        @Override
        public void visitDeclarationExpression(DeclarationExpression expression) {
            if (expression.isMultipleAssignmentDeclaration()) {
                TupleExpression te = expression.getTupleExpression();
                List<Expression> list = te.getExpressions();
                for (Expression arg : list) {
                    VariableExpression ve = (VariableExpression) arg;
                    varStack.getLast().add(ve.getName());
                }
            } else {
                VariableExpression ve = expression.getVariableExpression();
                varStack.getLast().add(ve.getName());
            }
            super.visitDeclarationExpression(expression);
        }

        @Override
        public void visitForLoop(ForStatement forLoop) {
            Expression exp = forLoop.getCollectionExpression();
            exp.visit(this);
            Parameter loopParam = forLoop.getVariable();
            if (loopParam != null) {
                varStack.getLast().add(loopParam.getName());
            }
            super.visitForLoop(forLoop);
        }

        @Override
        public void visitExpressionStatement(ExpressionStatement es) {
            // GROOVY-3543: visit the declaration expressions so that declaration variables get added on the varStack
            Expression exp = es.getExpression();
            if (exp instanceof DeclarationExpression) {
                exp.visit(this);
            }
            super.visitExpressionStatement(es);
        }

        @Override
        public Expression transform(Expression exp) {
            if (exp instanceof VariableExpression) {
                VariableExpression ve = (VariableExpression) exp;
                if (ve.getName().equals("this"))
                    return thisExpression;
                else {
                    if (!varStack.getLast().contains(ve.getName())) {
                        return new PropertyExpression(thisExpression, ve.getName());
                    }
                }
            } else if (exp instanceof PropertyExpression) {
                PropertyExpression pe = (PropertyExpression) exp;
                if (pe.getObjectExpression() instanceof VariableExpression) {
                    VariableExpression vex = (VariableExpression) pe.getObjectExpression();
                    if (vex.isThisExpression()) {
                        pe.setObjectExpression(thisExpression);
                        return pe;
                    }
                }
            } else if (exp instanceof ClosureExpression) {
                ClosureExpression ce = (ClosureExpression) exp;
                ce.getVariableScope().putReferencedLocalVariable((Parameter) parameter.get());
                addVariablesToStack(hasImplicitParameter(ce) ? params(param(ClassHelper.OBJECT_TYPE, "it"))
                        : getParametersSafe(ce));
                ce.getCode().visit(this);
                varStack.removeLast();
            }
            return super.transform(exp);
        }
    };

    for (MethodNode method : parent.getMethods()) {
        if (!method.isStatic()) {
            method.setModifiers(method.getModifiers() | Opcodes.ACC_STATIC);
            final Parameter[] origParams = method.getParameters();
            final Parameter[] newParams = new Parameter[origParams.length + 1];
            Parameter p = new Parameter(targetClass, "$this");
            p.setClosureSharedVariable(true);
            newParams[0] = p;
            parameter.set(p);
            System.arraycopy(origParams, 0, newParams, 1, origParams.length);
            method.setParameters(newParams);

            expressionTransformer.visitMethod(method);
        }
    }
    new VariableScopeVisitor(source, true).visitClass(parent);
}

From source file:org.codehaus.groovy.transform.LogASTTransformation.java

License:Apache License

private int lookupLogFieldModifiers(AnnotatedNode targetClass, AnnotationNode logAnnotation) {
    int modifiers = getVisibility(logAnnotation, targetClass, ClassNode.class, Opcodes.ACC_PRIVATE);
    return Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | modifiers;
}

From source file:org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.java

License:Apache License

/**
 * A helper method that can be used to evaluate expressions as found in annotation
 * parameters. For example, it will evaluate a constant, be it referenced directly as
 * an integer or as a reference to a field.
 * <p>/*from  w w w.ja  va 2  s  . com*/
 * If this method throws an exception, then the expression cannot be evaluated on its own.
 *
 * @param expr   the expression to be evaluated
 * @param config the compiler configuration
 * @return the result of the expression
 */
public static Object evaluateExpression(Expression expr, CompilerConfiguration config) {
    String className = "Expression$" + UUID.randomUUID().toString().replace('-', '$');
    ClassNode node = new ClassNode(className, Opcodes.ACC_PUBLIC, OBJECT_TYPE);
    ReturnStatement code = new ReturnStatement(expr);
    addGeneratedMethod(node, "eval", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, OBJECT_TYPE,
            Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, code);
    CompilerConfiguration copyConf = new CompilerConfiguration(config);
    CompilationUnit cu = new CompilationUnit(copyConf);
    cu.addClassNode(node);
    cu.compile(Phases.CLASS_GENERATION);
    List<GroovyClass> classes = cu.getClasses();
    Class<?> aClass = cu.getClassLoader().defineClass(className, classes.get(0).getBytes());
    try {
        return aClass.getMethod("eval").invoke(null);
    } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
        throw new GroovyBugError(e);
    }
}

From source file:org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.java

License:Apache License

@Override
public void visitMethodCallExpression(final MethodCallExpression call) {
    String name = call.getMethodAsString();
    if (name == null) {
        addStaticTypeError("cannot resolve dynamic method name at compile time.", call.getMethod());
        return;/*  w  w w  .  java2  s. c  om*/
    }
    if (extension.beforeMethodCall(call)) {
        extension.afterMethodCall(call);
        return;
    }
    typeCheckingContext.pushEnclosingMethodCall(call);
    Expression objectExpression = call.getObjectExpression();

    objectExpression.visit(this);
    call.getMethod().visit(this);

    // if the call expression is a spread operator call, then we must make sure that
    // the call is made on a collection type
    if (call.isSpreadSafe()) {
        //TODO check if this should not be change to iterator based call logic
        ClassNode expressionType = getType(objectExpression);
        if (!implementsInterfaceOrIsSubclassOf(expressionType, Collection_TYPE) && !expressionType.isArray()) {
            addStaticTypeError("Spread operator can only be used on collection types", objectExpression);
            return;
        } else {
            // type check call as if it was made on component type
            ClassNode componentType = inferComponentType(expressionType, int_TYPE);
            MethodCallExpression subcall = callX(castX(componentType, EmptyExpression.INSTANCE), name,
                    call.getArguments());
            subcall.setLineNumber(call.getLineNumber());
            subcall.setColumnNumber(call.getColumnNumber());
            subcall.setImplicitThis(call.isImplicitThis());
            visitMethodCallExpression(subcall);
            // the inferred type here should be a list of what the subcall returns
            ClassNode subcallReturnType = getType(subcall);
            ClassNode listNode = LIST_TYPE.getPlainNodeReference();
            listNode.setGenericsTypes(
                    new GenericsType[] { new GenericsType(wrapTypeIfNecessary(subcallReturnType)) });
            storeType(call, listNode);
            // store target method
            storeTargetMethod(call, subcall.getNodeMetaData(DIRECT_METHOD_CALL_TARGET));
            typeCheckingContext.popEnclosingMethodCall();
            return;
        }
    }

    Expression callArguments = call.getArguments();
    ArgumentListExpression argumentList = InvocationWriter.makeArgumentList(callArguments);

    checkForbiddenSpreadArgument(argumentList);

    // for arguments, we need to visit closures *after* the method has been chosen

    ClassNode receiver = getType(objectExpression);
    visitMethodCallArguments(receiver, argumentList, false, null);

    ClassNode[] args = getArgumentTypes(argumentList);
    boolean isCallOnClosure = isClosureCall(name, objectExpression, callArguments);

    try {
        boolean callArgsVisited = false;
        if (isCallOnClosure) {
            // this is a closure.call() call
            if (isThisExpression(objectExpression)) {
                // isClosureCall() check verified earlier that a field exists
                FieldNode field = typeCheckingContext.getEnclosingClassNode().getDeclaredField(name);
                GenericsType[] genericsTypes = field.getType().getGenericsTypes();
                if (genericsTypes != null) {
                    ClassNode closureReturnType = genericsTypes[0].getType();
                    Object data = field.getNodeMetaData(CLOSURE_ARGUMENTS);
                    if (data != null) {
                        Parameter[] parameters = (Parameter[]) data;
                        typeCheckClosureCall(callArguments, args, parameters);
                    }
                    storeType(call, closureReturnType);
                }
            } else if (objectExpression instanceof VariableExpression) {
                Variable variable = findTargetVariable((VariableExpression) objectExpression);
                if (variable instanceof ASTNode) {
                    Object data = ((ASTNode) variable).getNodeMetaData(CLOSURE_ARGUMENTS);
                    if (data != null) {
                        Parameter[] parameters = (Parameter[]) data;
                        typeCheckClosureCall(callArguments, args, parameters);
                    }
                    ClassNode type = getType(((ASTNode) variable));
                    if (type != null && type.equals(CLOSURE_TYPE)) {
                        GenericsType[] genericsTypes = type.getGenericsTypes();
                        type = OBJECT_TYPE;
                        if (genericsTypes != null) {
                            if (!genericsTypes[0].isPlaceholder()) {
                                type = genericsTypes[0].getType();
                            }
                        }
                    }
                    if (type != null) {
                        storeType(call, type);
                    }
                }
            } else if (objectExpression instanceof ClosureExpression) {
                // we can get actual parameters directly
                Parameter[] parameters = ((ClosureExpression) objectExpression).getParameters();
                typeCheckClosureCall(callArguments, args, parameters);
                ClassNode data = getInferredReturnType(objectExpression);
                if (data != null) {
                    storeType(call, data);
                }
            }

            int nbOfArgs;
            if (callArguments instanceof ArgumentListExpression) {
                ArgumentListExpression list = (ArgumentListExpression) callArguments;
                nbOfArgs = list.getExpressions().size();
            } else {
                // todo : other cases
                nbOfArgs = 0;
            }
            storeTargetMethod(call, nbOfArgs == 0 ? CLOSURE_CALL_NO_ARG
                    : nbOfArgs == 1 ? CLOSURE_CALL_ONE_ARG : CLOSURE_CALL_VARGS);
        } else {
            // method call receivers are :
            //   - possible "with" receivers
            //   - the actual receiver as found in the method call expression
            //   - any of the potential receivers found in the instanceof temporary table
            // in that order
            List<Receiver<String>> receivers = new LinkedList<>();
            List<Receiver<String>> owners = makeOwnerList(objectExpression);
            addReceivers(receivers, owners, call.isImplicitThis());
            List<MethodNode> mn = null;
            Receiver<String> chosenReceiver = null;
            for (Receiver<String> currentReceiver : receivers) {
                ClassNode receiverType = currentReceiver.getType();
                mn = findMethod(receiverType, name, args);

                // if the receiver is "this" or "implicit this", then we must make sure that the compatible
                // methods are only static if we are in a static context
                // if we are not in a static context but the current receiver is a static class, we must
                // ensure that all methods are either static or declared by the current receiver or a superclass
                if (!mn.isEmpty() && (call.isImplicitThis() || isThisExpression(objectExpression))
                        && (typeCheckingContext.isInStaticContext
                                || (receiverType.getModifiers() & Opcodes.ACC_STATIC) != 0)) {
                    // we create separate method lists just to be able to print out
                    // a nice error message to the user
                    // a method is accessible if it is static, or if we are not in a static context and it is
                    // declared by the current receiver or a superclass
                    List<MethodNode> accessibleMethods = new LinkedList<>();
                    List<MethodNode> inaccessibleMethods = new LinkedList<>();
                    for (final MethodNode node : mn) {
                        if (node.isStatic() || (!typeCheckingContext.isInStaticContext
                                && implementsInterfaceOrIsSubclassOf(receiverType, node.getDeclaringClass()))) {
                            accessibleMethods.add(node);
                        } else {
                            inaccessibleMethods.add(node);
                        }
                    }
                    mn = accessibleMethods;
                    if (accessibleMethods.isEmpty()) {
                        // choose an arbitrary method to display an error message
                        MethodNode node = inaccessibleMethods.get(0);
                        ClassNode owner = node.getDeclaringClass();
                        addStaticTypeError("Non static method " + owner.getName() + "#" + node.getName()
                                + " cannot be called from static context", call);
                    }
                }

                if (!mn.isEmpty()) {
                    chosenReceiver = currentReceiver;
                    break;
                }
            }
            if (mn.isEmpty() && typeCheckingContext.getEnclosingClosure() != null && args.length == 0) {
                // add special handling of getDelegate() and getOwner()
                if ("getDelegate".equals(name)) {
                    mn = Collections.singletonList(GET_DELEGATE);
                } else if ("getOwner".equals(name)) {
                    mn = Collections.singletonList(GET_OWNER);
                } else if ("getThisObject".equals(name)) {
                    mn = Collections.singletonList(GET_THISOBJECT);
                }
            }
            if (mn.isEmpty()) {
                mn = extension.handleMissingMethod(receiver, name, argumentList, args, call);
            }
            if (mn.isEmpty()) {
                addNoMatchingMethodError(receiver, name, args, call);
            } else {
                if (areCategoryMethodCalls(mn, name, args)) {
                    addCategoryMethodCallError(call);
                }
                mn = disambiguateMethods(mn, chosenReceiver != null ? chosenReceiver.getType() : null, args,
                        call);

                if (mn.size() == 1) {
                    MethodNode directMethodCallCandidate = mn.get(0);
                    if (call.getNodeMetaData(DYNAMIC_RESOLUTION) == null
                            && !directMethodCallCandidate.isStatic()
                            && objectExpression instanceof ClassExpression && !"java.lang.Class"
                                    .equals(directMethodCallCandidate.getDeclaringClass().getName())) {
                        ClassNode owner = directMethodCallCandidate.getDeclaringClass();
                        addStaticTypeError("Non static method " + owner.getName() + "#"
                                + directMethodCallCandidate.getName() + " cannot be called from static context",
                                call);
                    }
                    if (chosenReceiver == null) {
                        chosenReceiver = Receiver.make(directMethodCallCandidate.getDeclaringClass());
                    }

                    ClassNode returnType = getType(directMethodCallCandidate);
                    if (isUsingGenericsOrIsArrayUsingGenerics(returnType)) {
                        visitMethodCallArguments(chosenReceiver.getType(), argumentList, true,
                                directMethodCallCandidate);
                        ClassNode irtg = inferReturnTypeGenerics(chosenReceiver.getType(),
                                directMethodCallCandidate, callArguments, call.getGenericsTypes());
                        returnType = (irtg != null && implementsInterfaceOrIsSubclassOf(irtg, returnType) ? irtg
                                : returnType);
                        callArgsVisited = true;
                    }
                    if (directMethodCallCandidate == GET_DELEGATE
                            && typeCheckingContext.getEnclosingClosure() != null) {
                        DelegationMetadata md = getDelegationMetadata(
                                typeCheckingContext.getEnclosingClosure().getClosureExpression());
                        returnType = typeCheckingContext.getEnclosingClassNode();
                        if (md != null) {
                            returnType = md.getType();
                        }
                    }
                    if (typeCheckMethodsWithGenericsOrFail(chosenReceiver.getType(), args, mn.get(0), call)) {
                        returnType = adjustWithTraits(directMethodCallCandidate, chosenReceiver.getType(), args,
                                returnType);

                        storeType(call, returnType);
                        storeTargetMethod(call, directMethodCallCandidate);

                        String data = chosenReceiver.getData();
                        if (data != null) {
                            // the method which has been chosen is supposed to be a call on delegate or owner
                            // so we store the information so that the static compiler may reuse it
                            call.putNodeMetaData(IMPLICIT_RECEIVER, data);
                        }
                        // if the object expression is a closure shared variable, we will have to perform a second pass
                        if (objectExpression instanceof VariableExpression) {
                            VariableExpression var = (VariableExpression) objectExpression;
                            if (var.isClosureSharedVariable()) {
                                SecondPassExpression<ClassNode[]> wrapper = new SecondPassExpression<>(call,
                                        args);
                                typeCheckingContext.secondPassExpressions.add(wrapper);
                            }
                        }
                    }
                } else {
                    addAmbiguousErrorMessage(mn, name, args, call);
                }
            }
        }
        // adjust typing for explicit math methods which have special handling - operator variants handled elsewhere
        if (NUMBER_OPS.containsKey(name) && isNumberType(receiver) && argumentList.getExpressions().size() == 1
                && isNumberType(getType(argumentList.getExpression(0)))) {
            ClassNode right = getType(argumentList.getExpression(0));
            ClassNode resultType = getMathResultType(NUMBER_OPS.get(name), receiver, right, name);
            if (resultType != null) {
                storeType(call, resultType);
            }
        }

        // now that a method has been chosen, we are allowed to visit the closures
        MethodNode target = call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
        if (!callArgsVisited) {
            visitMethodCallArguments(receiver, argumentList, true, target);
        }
        if (target != null) {
            List<Expression> argExpressions = argumentList.getExpressions();
            Parameter[] parameters = target.getParameters();
            for (int i = 0; i < argExpressions.size() && i < parameters.length; i += 1) {
                Expression arg = argExpressions.get(i);
                ClassNode aType = getType(arg), pType = parameters[i].getType();
                if (CLOSURE_TYPE.equals(aType) && CLOSURE_TYPE.equals(pType) && !isAssignableTo(aType, pType)) {
                    addNoMatchingMethodError(receiver, name, getArgumentTypes(argumentList), call);
                    call.removeNodeMetaData(DIRECT_METHOD_CALL_TARGET);
                }
            }
        }

        inferMethodReferenceType(call, receiver, argumentList);
    } finally {
        typeCheckingContext.popEnclosingMethodCall();
        extension.afterMethodCall(call);
    }
}

From source file:org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.java

License:Apache License

protected List<MethodNode> findMethod(ClassNode receiver, final String name, final ClassNode... args) {
    if (isPrimitiveType(receiver))
        receiver = getWrapper(receiver);
    List<MethodNode> methods;
    if (!receiver.isInterface() && "<init>".equals(name)) {
        methods = addGeneratedMethods(receiver, new ArrayList<>(receiver.getDeclaredConstructors()));
        if (methods.isEmpty()) {
            MethodNode node = new ConstructorNode(Opcodes.ACC_PUBLIC, Parameter.EMPTY_ARRAY,
                    ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
            node.setDeclaringClass(receiver);
            methods = Collections.singletonList(node);
            if (receiver.isArray()) {
                // No need to check the arguments against an array constructor: it just needs to exist. The array is
                // created through coercion or by specifying its dimension(s), anyway, and would not match an
                // arbitrary number of parameters.
                return methods;
            }/*from  www.  ja  va 2  s  .  co m*/
        }
    } else {
        methods = findMethodsWithGenerated(receiver, name);
        if (receiver.isInterface()) {
            collectAllInterfaceMethodsByName(receiver, name, methods);
            methods.addAll(OBJECT_TYPE.getMethods(name));

            if ("call".equals(name) && isFunctionalInterface(receiver)) {
                MethodNode sam = findSAM(receiver);
                MethodNode callMethodNode = new MethodNode("call", sam.getModifiers(), sam.getReturnType(),
                        sam.getParameters(), sam.getExceptions(), sam.getCode());
                callMethodNode.setDeclaringClass(sam.getDeclaringClass());
                callMethodNode.setSourcePosition(sam);

                methods.addAll(Collections.singletonList(callMethodNode));
            }
        }
        // TODO: investigate the trait exclusion a bit further, needed otherwise
        // CallMethodOfTraitInsideClosureAndClosureParamTypeInference fails saying
        // not static method can't be called from a static context
        if (typeCheckingContext.getEnclosingClosure() == null
                || (receiver.getOuterClass() != null && !receiver.getName().endsWith("$Trait$Helper"))) {
            // not in a closure or within an inner class
            ClassNode parent = receiver;
            while (parent.getOuterClass() != null && !parent.isStaticClass()) {
                parent = parent.getOuterClass();
                methods.addAll(findMethodsWithGenerated(parent, name));
            }
        }
        if (methods.isEmpty()) {
            addArrayMethods(methods, receiver, name, args);
        }
        if (methods.isEmpty() && (args == null || args.length == 0)) {
            // check if it's a property
            String pname = extractPropertyNameFromMethodName("get", name);
            if (pname == null) {
                pname = extractPropertyNameFromMethodName("is", name);
            }
            if (pname != null) {
                // we don't use property exists there because findMethod is called on super clases recursively
                PropertyNode property = null;
                ClassNode curNode = receiver;
                while (property == null && curNode != null) {
                    property = curNode.getProperty(pname);
                    ClassNode svCur = curNode;
                    while (property == null && svCur.getOuterClass() != null && !svCur.isStaticClass()) {
                        svCur = svCur.getOuterClass();
                        property = svCur.getProperty(pname);
                        if (property != null) {
                            receiver = svCur;
                            break;
                        }
                    }
                    curNode = curNode.getSuperClass();
                }
                if (property != null) {
                    MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC, property.getType(),
                            Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
                    if (property.isStatic()) {
                        node.setModifiers(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC);
                    }
                    node.setDeclaringClass(receiver);
                    return Collections.singletonList(node);

                }
            }
        } else if (methods.isEmpty() && args != null && args.length == 1) {
            // maybe we are looking for a setter ?
            String pname = extractPropertyNameFromMethodName("set", name);
            if (pname != null) {
                ClassNode curNode = receiver;
                PropertyNode property = null;
                while (property == null && curNode != null) {
                    property = curNode.getProperty(pname);
                    curNode = curNode.getSuperClass();
                }
                if (property != null) {
                    ClassNode type = property.getOriginType();
                    if (implementsInterfaceOrIsSubclassOf(wrapTypeIfNecessary(args[0]),
                            wrapTypeIfNecessary(type))) {
                        MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC, VOID_TYPE,
                                new Parameter[] { new Parameter(type, "arg") }, ClassNode.EMPTY_ARRAY,
                                GENERATED_EMPTY_STATEMENT);
                        if (property.isStatic()) {
                            node.setModifiers(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC);
                        }
                        node.setDeclaringClass(receiver);
                        return Collections.singletonList(node);
                    }
                }
            }
        }
    }

    if (methods.isEmpty()) {
        // look at the interfaces, there's a chance that a method is not implemented and we should not hide the
        // error from the compiler
        collectAllInterfaceMethodsByName(receiver, name, methods);
    }

    // lookup in DGM methods too
    findDGMMethodsByNameAndArguments(getTransformLoader(), receiver, name, args, methods);
    methods = filterMethodsByVisibility(methods);
    List<MethodNode> chosen = chooseBestMethod(receiver, methods, args);
    if (!chosen.isEmpty())
        return chosen;

    // GROOVY-5566
    if (receiver instanceof InnerClassNode && ((InnerClassNode) receiver).isAnonymous() && methods.size() == 1
            && args != null && "<init>".equals(name)) {
        MethodNode constructor = methods.get(0);
        if (constructor.getParameters().length == args.length) {
            return methods;
        }
    }

    if (receiver.equals(CLASS_Type) && receiver.getGenericsTypes() != null) {
        List<MethodNode> result = findMethod(receiver.getGenericsTypes()[0].getType(), name, args);
        if (!result.isEmpty())
            return result;
    }

    if (GSTRING_TYPE.equals(receiver))
        return findMethod(STRING_TYPE, name, args);

    if (isBeingCompiled(receiver)) {
        chosen = findMethod(GROOVY_OBJECT_TYPE, name, args);
        if (!chosen.isEmpty())
            return chosen;
    }

    return EMPTY_METHODNODE_LIST;
}

From source file:org.codehaus.groovy.transform.trait.TraitComposer.java

License:Apache License

private static void applyTrait(final ClassNode trait, final ClassNode cNode, final TraitHelpersTuple helpers,
        SourceUnit unit) {/*from  w  w w .j a v  a 2  s.  c  om*/
    ClassNode helperClassNode = helpers.getHelper();
    ClassNode fieldHelperClassNode = helpers.getFieldHelper();
    ClassNode staticFieldHelperClassNode = helpers.getStaticFieldHelper();
    Map<String, ClassNode> genericsSpec = GenericsUtils.createGenericsSpec(trait,
            GenericsUtils.createGenericsSpec(cNode));

    for (MethodNode methodNode : helperClassNode.getAllDeclaredMethods()) {
        String name = methodNode.getName();
        Parameter[] helperMethodParams = methodNode.getParameters();
        int nParams = helperMethodParams.length;
        if (nParams > 0 && !methodNode.isAbstract() && ((methodNode.getModifiers() & Opcodes.ACC_STATIC) != 0)
                && (!name.contains("$") || (methodNode.getModifiers() & Opcodes.ACC_SYNTHETIC) == 0)) {
            ArgumentListExpression argList = new ArgumentListExpression();
            argList.addExpression(new VariableExpression("this"));
            Parameter[] origParams = new Parameter[nParams - 1];
            Parameter[] params = new Parameter[nParams - 1];
            System.arraycopy(methodNode.getParameters(), 1, params, 0, params.length);
            MethodNode originalMethod = trait.getMethod(name, params);
            Map<String, ClassNode> methodGenericsSpec = Optional.ofNullable(originalMethod)
                    .map(m -> GenericsUtils.addMethodGenerics(m, genericsSpec)).orElse(genericsSpec);
            for (int i = 1; i < nParams; i += 1) {
                Parameter parameter = helperMethodParams[i];
                ClassNode originType = parameter.getOriginType();
                ClassNode fixedType = correctToGenericsSpecRecurse(methodGenericsSpec, originType);
                Parameter newParam = new Parameter(fixedType, parameter.getName());
                List<AnnotationNode> copied = new LinkedList<>();
                List<AnnotationNode> notCopied = new LinkedList<>();
                GeneralUtils.copyAnnotatedNodeAnnotations(parameter, copied, notCopied);
                newParam.addAnnotations(copied);
                params[i - 1] = newParam;
                origParams[i - 1] = parameter;
                argList.addExpression(new VariableExpression(newParam));
            }
            createForwarderMethod(trait, cNode, methodNode, originalMethod, helperClassNode, methodGenericsSpec,
                    helperMethodParams, origParams, params, argList, unit);
        }
    }
    MethodCallExpression staticInitCall = new MethodCallExpression(new ClassExpression(helperClassNode),
            Traits.STATIC_INIT_METHOD, new ArgumentListExpression(new ClassExpression(cNode)));
    MethodNode staticInitMethod = new MethodNode(Traits.STATIC_INIT_METHOD,
            Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, ClassHelper.VOID_TYPE,
            new Parameter[] { new Parameter(ClassHelper.CLASS_Type, "clazz") }, ClassNode.EMPTY_ARRAY,
            EmptyStatement.INSTANCE);
    staticInitMethod.setDeclaringClass(helperClassNode);
    staticInitCall.setMethodTarget(staticInitMethod);
    cNode.addStaticInitializerStatements(
            Collections.<Statement>singletonList(new ExpressionStatement(staticInitCall)), false);
    if (fieldHelperClassNode != null && !cNode.declaresInterface(fieldHelperClassNode)) {
        // we should implement the field helper interface too
        cNode.addInterface(fieldHelperClassNode);
        // implementation of methods
        List<MethodNode> declaredMethods = new LinkedList<>();
        for (MethodNode declaredMethod : fieldHelperClassNode.getAllDeclaredMethods()) {
            if (declaredMethod.getName().endsWith(Traits.DIRECT_GETTER_SUFFIX)) {
                declaredMethods.add(0, declaredMethod);
            } else {
                declaredMethods.add(declaredMethod);
            }
        }

        if (staticFieldHelperClassNode != null) {
            for (MethodNode declaredMethod : staticFieldHelperClassNode.getAllDeclaredMethods()) {
                if (declaredMethod.getName().endsWith(Traits.DIRECT_GETTER_SUFFIX)) {
                    declaredMethods.add(0, declaredMethod);
                } else {
                    declaredMethods.add(declaredMethod);
                }
            }
        }

        for (MethodNode methodNode : declaredMethods) {
            String fieldName = methodNode.getName();
            if (fieldName.endsWith(Traits.DIRECT_GETTER_SUFFIX)
                    || fieldName.endsWith(Traits.DIRECT_SETTER_SUFFIX)) {
                int suffixIdx = fieldName.lastIndexOf("$");
                fieldName = fieldName.substring(0, suffixIdx);
                String operation = methodNode.getName().substring(suffixIdx + 1);
                boolean getter = "get".equals(operation);
                ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, methodNode.getReturnType());
                int fieldMods = 0;
                int isStatic = 0;
                boolean publicField = true;
                FieldNode helperField = null;
                fieldMods = 0;
                isStatic = 0;

                // look first for field with encoded modifier information
                for (Integer mod : Traits.FIELD_PREFIXES) {
                    helperField = fieldHelperClassNode.getField(String.format("$0x%04x", mod) + fieldName);
                    if (helperField != null) {
                        if ((mod & Opcodes.ACC_STATIC) != 0)
                            isStatic = Opcodes.ACC_STATIC;
                        fieldMods = fieldMods | mod;
                        break;
                    }
                }

                if (helperField == null) {
                    // look for possible legacy fields (trait compiled pre 2.4.8)
                    helperField = fieldHelperClassNode
                            .getField(Traits.FIELD_PREFIX + Traits.PUBLIC_FIELD_PREFIX + fieldName);
                    if (helperField == null) {
                        publicField = false;
                        helperField = fieldHelperClassNode
                                .getField(Traits.FIELD_PREFIX + Traits.PRIVATE_FIELD_PREFIX + fieldName);
                    }
                    if (helperField == null) {
                        publicField = true;
                        // try to find a static one
                        helperField = fieldHelperClassNode
                                .getField(Traits.STATIC_FIELD_PREFIX + Traits.PUBLIC_FIELD_PREFIX + fieldName);
                        if (helperField == null) {
                            publicField = false;
                            helperField = fieldHelperClassNode.getField(
                                    Traits.STATIC_FIELD_PREFIX + Traits.PRIVATE_FIELD_PREFIX + fieldName);
                        }
                        fieldMods = fieldMods | Opcodes.ACC_STATIC;
                        isStatic = Opcodes.ACC_STATIC;
                    }
                    fieldMods = fieldMods | (publicField ? Opcodes.ACC_PUBLIC : Opcodes.ACC_PRIVATE);
                }
                if (getter) {
                    // add field
                    if (helperField != null) {
                        List<AnnotationNode> copied = new LinkedList<>();
                        List<AnnotationNode> notCopied = new LinkedList<>();
                        GeneralUtils.copyAnnotatedNodeAnnotations(helperField, copied, notCopied);
                        FieldNode fieldNode = cNode.addField(fieldName, fieldMods, returnType, null);
                        fieldNode.addAnnotations(copied);
                        // getInitialExpression above will be null if not in same source unit
                        // so instead set within (static) initializer
                        if (fieldNode.isFinal()) {
                            String baseName = fieldNode.isStatic() ? Traits.STATIC_INIT_METHOD
                                    : Traits.INIT_METHOD;
                            StaticMethodCallExpression mce = callX(helperClassNode,
                                    baseName + fieldNode.getName(), args(varX("this")));
                            if (helperClassNode.hasPossibleStaticMethod(mce.getMethod(), mce.getArguments())) {
                                Statement stmt = stmt(
                                        assignX(varX(fieldNode.getName(), fieldNode.getType()), mce));
                                if (isStatic == 0) {
                                    cNode.addObjectInitializerStatements(stmt);
                                } else {
                                    List<Statement> staticStatements = new ArrayList<Statement>();
                                    staticStatements.add(stmt);
                                    cNode.addStaticInitializerStatements(staticStatements, true);
                                }
                            }
                        }
                    }
                }
                Parameter[] newParams;
                if (getter) {
                    newParams = Parameter.EMPTY_ARRAY;
                } else {
                    ClassNode originType = methodNode.getParameters()[0].getOriginType();
                    ClassNode fixedType = originType.isGenericsPlaceHolder() ? ClassHelper.OBJECT_TYPE
                            : correctToGenericsSpecRecurse(genericsSpec, originType);
                    newParams = new Parameter[] { new Parameter(fixedType, "val") };
                }

                Expression fieldExpr = varX(cNode.getField(fieldName));
                boolean finalSetter = !getter && (fieldMods & Opcodes.ACC_FINAL) != 0;
                Statement body = getter ? returnS(fieldExpr)
                        : (finalSetter ? null
                                : stmt(new BinaryExpression(fieldExpr, Token.newSymbol(Types.EQUAL, 0, 0),
                                        varX(newParams[0]))));
                // add getter/setter even though setter not strictly needed for final fields
                // but add empty body for setter for legacy compatibility
                MethodNode impl = new MethodNode(methodNode.getName(), Opcodes.ACC_PUBLIC | isStatic,
                        returnType, newParams, ClassNode.EMPTY_ARRAY, body);
                AnnotationNode an = new AnnotationNode(COMPILESTATIC_CLASSNODE);
                impl.addAnnotation(an);
                cNode.addTransform(StaticCompileTransformation.class, an);
                cNode.addMethod(impl);
            }
        }
    }
    cNode.addObjectInitializerStatements(
            new ExpressionStatement(new MethodCallExpression(new ClassExpression(helperClassNode),
                    Traits.INIT_METHOD, new ArgumentListExpression(new VariableExpression("this")))));
}