Example usage for org.objectweb.asm Opcodes ACC_FINAL

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

Introduction

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

Prototype

int ACC_FINAL

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

Click Source Link

Usage

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

License:Apache License

private void printField(PrintWriter out, FieldNode fieldNode, boolean isInterface) {
    if ((fieldNode.getModifiers() & Opcodes.ACC_PRIVATE) != 0)
        return;/*from   w w  w  .j  a  v  a 2s.  com*/
    printAnnotations(out, fieldNode);
    if (!isInterface) {
        printModifiers(out, fieldNode.getModifiers());
    }

    ClassNode type = fieldNode.getType();
    printType(out, type);

    out.print(" ");
    out.print(fieldNode.getName());
    if (isInterface || (fieldNode.getModifiers() & Opcodes.ACC_FINAL) != 0) {
        out.print(" = ");
        Expression valueExpr = fieldNode.getInitialValueExpression();
        if (valueExpr instanceof ConstantExpression) {
            valueExpr = Verifier.transformToPrimitiveConstantIfPossible((ConstantExpression) valueExpr);
        }
        if (valueExpr instanceof ConstantExpression && fieldNode.isStatic() && fieldNode.isFinal()
                && ClassHelper.isStaticConstantInitializerType(valueExpr.getType())
                && valueExpr.getType().equals(fieldNode.getType())) {
            // GROOVY-5150 : Initialize value with a dummy constant so that Java cross compiles correctly
            if (ClassHelper.STRING_TYPE.equals(valueExpr.getType())) {
                out.print(formatString(valueExpr.getText()));
            } else if (ClassHelper.char_TYPE.equals(valueExpr.getType())) {
                out.print("'" + valueExpr.getText() + "'");
            } else {
                ClassNode constantType = valueExpr.getType();
                out.print('(');
                printType(out, type);
                out.print(") ");
                out.print(valueExpr.getText());
                if (ClassHelper.Long_TYPE.equals(ClassHelper.getWrapper(constantType)))
                    out.print('L');
            }
        } else if (ClassHelper.isPrimitiveType(type)) {
            String val = type == ClassHelper.boolean_TYPE ? "false" : "0";
            out.print("new " + ClassHelper.getWrapper(type) + "((" + type + ")" + val + ")");
        } else {
            out.print("null");
        }
    }
    out.println(";");
}

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.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.StaticTypeCheckingVisitor.java

License:Apache License

/**
 * Checks whether a property exists on the receiver, or on any of the possible receiver classes (found in the
 * temporary type information table)/*from  w  w w.j  a v  a 2 s .  c o m*/
 *
 * @param pexp     a property expression
 * @param readMode if true, look for property read, else for property set
 * @param visitor  if not null, when the property node is found, visit it with the provided visitor
 * @return true if the property is defined in any of the possible receiver classes
 */
protected boolean existsProperty(final PropertyExpression pexp, final boolean readMode,
        final ClassCodeVisitorSupport visitor) {
    super.visitPropertyExpression(pexp);

    String propertyName = pexp.getPropertyAsString();
    if (propertyName == null)
        return false;

    Expression objectExpression = pexp.getObjectExpression();
    ClassNode objectExpressionType = getType(objectExpression);
    List<ClassNode> enclosingTypes = typeCheckingContext.getEnclosingClassNodes();

    boolean staticOnlyAccess = isClassClassNodeWrappingConcreteType(objectExpressionType);
    if (staticOnlyAccess && "this".equals(propertyName)) {
        // handle "Outer.this" for any level of nesting
        ClassNode outer = objectExpressionType.getGenericsTypes()[0].getType();

        ClassNode found = null;
        for (ClassNode enclosingType : enclosingTypes) {
            if (!enclosingType.isStaticClass() && outer.equals(enclosingType.getOuterClass())) {
                found = enclosingType;
                break;
            }
        }
        if (found != null) {
            storeType(pexp, outer);
            return true;
        }
    }

    boolean foundGetterOrSetter = false;
    String capName = capitalize(propertyName);
    Set<ClassNode> handledNodes = new HashSet<>();
    List<Receiver<String>> receivers = new LinkedList<>();
    addReceivers(receivers, makeOwnerList(objectExpression), pexp.isImplicitThis());

    for (Receiver<String> receiver : receivers) {
        ClassNode testClass = receiver.getType();

        if (testClass.isArray() && "length".equals(propertyName)) {
            storeType(pexp, int_TYPE);
            if (visitor != null) {
                PropertyNode length = new PropertyNode("length", Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL,
                        int_TYPE, testClass, null, null, null);
                visitor.visitProperty(length);
            }
            return true;
        }

        Queue<ClassNode> queue = new LinkedList<>();
        queue.add(testClass);
        if (isPrimitiveType(testClass)) {
            queue.add(getWrapper(testClass));
        }
        while (!queue.isEmpty()) {
            ClassNode current = queue.remove();
            if (!handledNodes.add(current))
                continue;

            // in case of a lookup on Class we look for instance methods on Class
            // as well, since in case of a static property access we have the class
            // itself in the list of receivers already;
            boolean staticOnly;
            if (isClassClassNodeWrappingConcreteType(current)) {
                staticOnly = false;
            } else {
                staticOnly = staticOnlyAccess;
            }

            FieldNode field = current.getDeclaredField(propertyName);
            field = allowStaticAccessToMember(field, staticOnly);

            // skip property/accessor checks for "x.@field"
            if (field != null && pexp instanceof AttributeExpression) {
                if (storeField(field, pexp, current, visitor, receiver.getData(), !readMode)) {
                    pexp.removeNodeMetaData(READONLY_PROPERTY);
                    return true;
                }
            }

            // skip property/accessor checks for "field", "this.field", "this.with { field }", etc. in declaring class of field
            if (field != null && enclosingTypes.contains(current)) {
                if (storeField(field, pexp, receiver.getType(), visitor, receiver.getData(), !readMode)) {
                    pexp.removeNodeMetaData(READONLY_PROPERTY);
                    return true;
                }
            }

            MethodNode getter = findGetter(current, "get" + capName, pexp.isImplicitThis());
            getter = allowStaticAccessToMember(getter, staticOnly);
            if (getter == null)
                getter = findGetter(current, "is" + capName, pexp.isImplicitThis());
            getter = allowStaticAccessToMember(getter, staticOnly);
            List<MethodNode> setters = findSetters(current, "set" + capName, false);
            setters = allowStaticAccessToMember(setters, staticOnly);

            // need to visit even if we only look for setters for compatibility
            if (visitor != null && getter != null)
                visitor.visitMethod(getter);

            PropertyNode property = current.getProperty(propertyName);
            property = allowStaticAccessToMember(property, staticOnly);
            // prefer explicit getter or setter over property if receiver is not 'this'
            if (property == null || !enclosingTypes.contains(objectExpressionType)) {
                if (readMode) {
                    if (getter != null) {
                        ClassNode returnType = inferReturnTypeGenerics(current, getter,
                                ArgumentListExpression.EMPTY_ARGUMENTS);
                        storeInferredTypeForPropertyExpression(pexp, returnType);
                        storeTargetMethod(pexp, getter);
                        String delegationData = receiver.getData();
                        if (delegationData != null) {
                            pexp.putNodeMetaData(IMPLICIT_RECEIVER, delegationData);
                        }
                        return true;
                    }
                } else {
                    if (!setters.isEmpty()) {
                        if (visitor != null) {
                            if (field != null) {
                                visitor.visitField(field);
                            } else {
                                for (MethodNode setter : setters) {
                                    ClassNode setterType = setter.getParameters()[0].getOriginType();
                                    FieldNode virtual = new FieldNode(propertyName, 0, setterType, current,
                                            EmptyExpression.INSTANCE);
                                    visitor.visitField(virtual);
                                }
                            }
                        }
                        SetterInfo info = new SetterInfo(current, "set" + capName, setters);
                        BinaryExpression enclosingBinaryExpression = typeCheckingContext
                                .getEnclosingBinaryExpression();
                        if (enclosingBinaryExpression != null) {
                            putSetterInfo(enclosingBinaryExpression.getLeftExpression(), info);
                        }
                        String delegationData = receiver.getData();
                        if (delegationData != null) {
                            pexp.putNodeMetaData(IMPLICIT_RECEIVER, delegationData);
                        }
                        pexp.removeNodeMetaData(READONLY_PROPERTY);
                        return true;
                    } else if (property == null) {
                        if (field != null
                                && hasAccessToField(typeCheckingContext.getEnclosingClassNode(), field)) {
                            pexp.removeNodeMetaData(READONLY_PROPERTY);
                        } else if (getter != null) {
                            pexp.putNodeMetaData(READONLY_PROPERTY, Boolean.TRUE);
                        }
                    }
                }
            }
            foundGetterOrSetter = (foundGetterOrSetter || !setters.isEmpty() || getter != null);

            if (property != null && storeProperty(property, pexp, current, visitor, receiver.getData()))
                return true;

            if (field != null && storeField(field, pexp, current, visitor, receiver.getData(), !readMode))
                return true;

            // check the super types
            if (current.getSuperClass() != null) {
                queue.add(current.getUnresolvedSuperClass());
            }
            for (ClassNode face : current.getAllInterfaces()) {
                queue.add(GenericsUtils.parameterizeType(current, face));
            }
        }

        // GROOVY-5568: the property may be defined by DGM
        List<ClassNode> dgmReceivers = new ArrayList<>(2);
        dgmReceivers.add(testClass);
        if (isPrimitiveType(testClass))
            dgmReceivers.add(getWrapper(testClass));
        for (ClassNode dgmReceiver : dgmReceivers) {
            List<MethodNode> methods = findDGMMethodsByNameAndArguments(getTransformLoader(), dgmReceiver,
                    "get" + capName, ClassNode.EMPTY_ARRAY);
            for (MethodNode method : findDGMMethodsByNameAndArguments(getTransformLoader(), dgmReceiver,
                    "is" + capName, ClassNode.EMPTY_ARRAY)) {
                if (Boolean_TYPE.equals(getWrapper(method.getReturnType())))
                    methods.add(method);
            }
            if (!methods.isEmpty()) {
                List<MethodNode> bestMethods = chooseBestMethod(dgmReceiver, methods, ClassNode.EMPTY_ARRAY);
                if (bestMethods.size() == 1) {
                    MethodNode getter = bestMethods.get(0);
                    if (visitor != null) {
                        visitor.visitMethod(getter);
                    }
                    ClassNode returnType = inferReturnTypeGenerics(dgmReceiver, getter,
                            ArgumentListExpression.EMPTY_ARGUMENTS);
                    storeInferredTypeForPropertyExpression(pexp, returnType);
                    if (readMode)
                        storeTargetMethod(pexp, getter);
                    return true;
                }
            }
        }

        // GROOVY-7996: check if receiver implements get(String)/set(String,Object) or propertyMissing(String)
        if (!testClass.isArray() && !isPrimitiveType(getUnwrapper(testClass)) && pexp.isImplicitThis()
                && typeCheckingContext.getEnclosingClosure() != null) {
            MethodNode mopMethod;
            if (readMode) {
                mopMethod = testClass.getMethod("get", new Parameter[] { new Parameter(STRING_TYPE, "name") });
            } else {
                mopMethod = testClass.getMethod("set", new Parameter[] { new Parameter(STRING_TYPE, "name"),
                        new Parameter(OBJECT_TYPE, "value") });
            }
            if (mopMethod == null)
                mopMethod = testClass.getMethod("propertyMissing",
                        new Parameter[] { new Parameter(STRING_TYPE, "propertyName") });

            if (mopMethod != null) {
                pexp.putNodeMetaData(DYNAMIC_RESOLUTION, Boolean.TRUE);
                pexp.removeNodeMetaData(DECLARATION_INFERRED_TYPE);
                pexp.removeNodeMetaData(INFERRED_TYPE);
                return true;
            }
        }
    }

    for (Receiver<String> receiver : receivers) {
        ClassNode testClass = receiver.getType();
        ClassNode propertyType = getTypeForMapPropertyExpression(testClass, objectExpressionType, pexp);
        if (propertyType == null)
            propertyType = getTypeForListPropertyExpression(testClass, objectExpressionType, pexp);
        if (propertyType == null)
            propertyType = getTypeForSpreadExpression(testClass, objectExpressionType, pexp);
        if (propertyType == null)
            continue;
        if (visitor != null) {
            // TODO: type inference on maps and lists, if possible
            PropertyNode node = new PropertyNode(propertyName, Opcodes.ACC_PUBLIC, propertyType,
                    receiver.getType(), null, null, null);
            node.setDeclaringClass(receiver.getType());
            visitor.visitProperty(node);
        }
        storeType(pexp, propertyType);
        String delegationData = receiver.getData();
        if (delegationData != null)
            pexp.putNodeMetaData(IMPLICIT_RECEIVER, delegationData);
        return true;
    }

    return foundGetterOrSetter;
}

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

License:Apache License

protected boolean checkCast(final ClassNode targetType, final Expression source) {
    boolean sourceIsNull = isNullConstant(source);
    ClassNode expressionType = getType(source);
    if (targetType.isArray() && expressionType.isArray()) {
        return checkCast(targetType.getComponentType(), varX("foo", expressionType.getComponentType()));
    } else if (targetType.equals(char_TYPE) && expressionType == STRING_TYPE
            && source instanceof ConstantExpression && source.getText().length() == 1) {
        // ex: (char) 'c'
    } else if (targetType.equals(Character_TYPE) && (expressionType == STRING_TYPE || sourceIsNull)
            && (sourceIsNull || source instanceof ConstantExpression && source.getText().length() == 1)) {
        // ex : (Character) 'c'
    } else if (isNumberCategory(getWrapper(targetType))
            && (isNumberCategory(getWrapper(expressionType)) || char_TYPE == expressionType)) {
        // ex: short s = (short) 0
    } else if (sourceIsNull && !isPrimitiveType(targetType)) {
        // ex: (Date)null
    } else if (char_TYPE == targetType && isPrimitiveType(expressionType) && isNumberType(expressionType)) {
        // char c = (char) ...
    } else if (sourceIsNull && isPrimitiveType(targetType) && !boolean_TYPE.equals(targetType)) {
        return false;
    } else if ((expressionType.getModifiers() & Opcodes.ACC_FINAL) == 0 && targetType.isInterface()) {
        return true;
    } else if ((targetType.getModifiers() & Opcodes.ACC_FINAL) == 0 && expressionType.isInterface()) {
        return true;
    } else if (!isAssignableTo(targetType, expressionType)
            && !implementsInterfaceOrIsSubclassOf(expressionType, targetType)) {
        return false;
    }//from  w w w . j a  v  a2  s .  co m
    return true;
}

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) {/*  www  .  j av  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")))));
}

From source file:org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration.java

License:Open Source License

/**
 * Build JDT TypeDeclarations for the groovy type declarations that were parsed from the source file.
 *//*from   w w  w  . j av a2s. c om*/
private void createTypeDeclarations(ModuleNode moduleNode) {
    List<ClassNode> moduleClassNodes = moduleNode.getClasses();
    List<TypeDeclaration> typeDeclarations = new ArrayList<TypeDeclaration>();
    Map<ClassNode, TypeDeclaration> fromClassNodeToDecl = new HashMap<ClassNode, TypeDeclaration>();

    char[] mainName = toMainName(compilationResult.getFileName());
    boolean isInner = false;
    List<ClassNode> classNodes = null;
    classNodes = moduleClassNodes;
    Map<ClassNode, List<TypeDeclaration>> innersToRecord = new HashMap<ClassNode, List<TypeDeclaration>>();
    for (ClassNode classNode : classNodes) {
        if (!classNode.isPrimaryClassNode()) {
            continue;
        }

        GroovyTypeDeclaration typeDeclaration = new GroovyTypeDeclaration(compilationResult, classNode);

        typeDeclaration.annotations = transformAnnotations(classNode.getAnnotations());
        // FIXASC duplicates code further down, tidy this up
        if (classNode instanceof InnerClassNode) {
            InnerClassNode innerClassNode = (InnerClassNode) classNode;
            ClassNode outerClass = innerClassNode.getOuterClass();
            String outername = outerClass.getNameWithoutPackage();
            String newInner = innerClassNode.getNameWithoutPackage().substring(outername.length() + 1);
            typeDeclaration.name = newInner.toCharArray();
            isInner = true;
        } else {
            typeDeclaration.name = classNode.getNameWithoutPackage().toCharArray();
            isInner = false;
        }

        // classNode.getInnerClasses();
        // classNode.
        boolean isInterface = classNode.isInterface();
        int mods = classNode.getModifiers();
        if ((mods & Opcodes.ACC_ENUM) != 0) {
            // remove final
            mods = mods & ~Opcodes.ACC_FINAL;
        }
        // FIXASC should this modifier be set?
        // mods |= Opcodes.ACC_PUBLIC;
        // FIXASC should not do this for inner classes, just for top level types
        // FIXASC does this make things visible that shouldn't be?
        mods = mods & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
        if (!isInner) {
            if ((mods & Opcodes.ACC_STATIC) != 0) {
                mods = mods & ~(Opcodes.ACC_STATIC);
            }
        }
        typeDeclaration.modifiers = mods & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0);

        if (!(classNode instanceof InnerClassNode)) {
            if (!CharOperation.equals(typeDeclaration.name, mainName)) {
                typeDeclaration.bits |= ASTNode.IsSecondaryType;
            }
        }

        fixupSourceLocationsForTypeDeclaration(typeDeclaration, classNode);

        if (classNode.getGenericsTypes() != null) {
            GenericsType[] genericInfo = classNode.getGenericsTypes();
            // Example case here: Foo<T extends Number & I>
            // the type parameter is T, the 'type' is Number and the bounds for the type parameter are just the extra bound
            // I.
            typeDeclaration.typeParameters = new TypeParameter[genericInfo.length];
            for (int tp = 0; tp < genericInfo.length; tp++) {
                TypeParameter typeParameter = new TypeParameter();
                typeParameter.name = genericInfo[tp].getName().toCharArray();
                ClassNode[] upperBounds = genericInfo[tp].getUpperBounds();
                if (upperBounds != null) {
                    // FIXASC (M3) Positional info for these references?
                    typeParameter.type = createTypeReferenceForClassNode(upperBounds[0]);
                    typeParameter.bounds = (upperBounds.length > 1 ? new TypeReference[upperBounds.length - 1]
                            : null);
                    for (int b = 1, max = upperBounds.length; b < max; b++) {
                        typeParameter.bounds[b - 1] = createTypeReferenceForClassNode(upperBounds[b]);
                        typeParameter.bounds[b - 1].bits |= ASTNode.IsSuperType;
                    }
                }
                typeDeclaration.typeParameters[tp] = typeParameter;
            }
        }

        boolean isEnum = (classNode.getModifiers() & Opcodes.ACC_ENUM) != 0;
        configureSuperClass(typeDeclaration, classNode.getSuperClass(), isEnum);
        configureSuperInterfaces(typeDeclaration, classNode);
        typeDeclaration.methods = createMethodAndConstructorDeclarations(classNode, isEnum, compilationResult);
        typeDeclaration.fields = createFieldDeclarations(classNode);
        typeDeclaration.properties = classNode.getProperties();
        if (classNode instanceof InnerClassNode) {
            InnerClassNode innerClassNode = (InnerClassNode) classNode;
            ClassNode outerClass = innerClassNode.getOuterClass();
            String outername = outerClass.getNameWithoutPackage();
            String newInner = innerClassNode.getNameWithoutPackage().substring(outername.length() + 1);
            typeDeclaration.name = newInner.toCharArray();

            // Record that we need to set the parent of this inner type later
            List<TypeDeclaration> inners = innersToRecord.get(outerClass);
            if (inners == null) {
                inners = new ArrayList<TypeDeclaration>();
                innersToRecord.put(outerClass, inners);
            }
            inners.add(typeDeclaration);
        } else {
            typeDeclarations.add(typeDeclaration);
        }
        fromClassNodeToDecl.put(classNode, typeDeclaration);
    }

    // For inner types, now attach them to their parents. This was not done earlier as sometimes the types are processed in
    // such an order that inners are dealt with before outers
    for (Map.Entry<ClassNode, List<TypeDeclaration>> innersToRecordEntry : innersToRecord.entrySet()) {
        TypeDeclaration outerTypeDeclaration = fromClassNodeToDecl.get(innersToRecordEntry.getKey());
        // Check if there is a problem locating the parent for the inner
        if (outerTypeDeclaration == null) {
            throw new GroovyEclipseBug(
                    "Failed to find the type declaration for " + innersToRecordEntry.getKey().getName());
        }
        List<TypeDeclaration> newInnersList = innersToRecordEntry.getValue();
        outerTypeDeclaration.memberTypes = newInnersList.toArray(new TypeDeclaration[newInnersList.size()]);
    }

    types = typeDeclarations.toArray(new TypeDeclaration[typeDeclarations.size()]);
}

From source file:org.elasticsearch.painless.node.SSource.java

License:Apache License

public void write() {
    // Create the ClassWriter.

    int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS;
    int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL;
    String classBase = BASE_CLASS_TYPE.getInternalName();
    String className = CLASS_TYPE.getInternalName();
    String classInterfaces[] = reserved.usesScore()
            ? new String[] { WriterConstants.NEEDS_SCORE_TYPE.getInternalName() }
            : null;/*from   w w w .j a v a2  s  .  c  om*/

    ClassWriter writer = new ClassWriter(classFrames);
    ClassVisitor visitor = writer;

    // if picky is enabled, turn on some checks. instead of VerifyError at the end, you get a helpful stacktrace.
    if (settings.isPicky()) {
        visitor = new SimpleChecksAdapter(visitor);
    }

    if (debugStream != null) {
        visitor = new TraceClassVisitor(visitor, debugStream, null);
    }
    visitor.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, classBase, classInterfaces);
    visitor.visitSource(Location.computeSourceName(name, source), null);

    // Write the constructor:
    MethodWriter constructor = new MethodWriter(Opcodes.ACC_PUBLIC, CONSTRUCTOR, visitor,
            globals.getStatements(), settings);
    constructor.visitCode();
    constructor.loadThis();
    constructor.loadArgs();
    constructor.invokeConstructor(org.objectweb.asm.Type.getType(Executable.class), CONSTRUCTOR);
    constructor.returnValue();
    constructor.endMethod();

    // Write the execute method:
    MethodWriter execute = new MethodWriter(Opcodes.ACC_PUBLIC, EXECUTE, visitor, globals.getStatements(),
            settings);
    execute.visitCode();
    write(execute, globals);
    execute.endMethod();

    // Write all functions:
    for (SFunction function : functions) {
        function.write(visitor, settings, globals);
    }

    // Write all synthetic functions. Note that this process may add more :)
    while (!globals.getSyntheticMethods().isEmpty()) {
        List<SFunction> current = new ArrayList<>(globals.getSyntheticMethods().values());
        globals.getSyntheticMethods().clear();
        for (SFunction function : current) {
            function.write(visitor, settings, globals);
        }
    }

    // Write the constants
    if (false == globals.getConstantInitializers().isEmpty()) {
        Collection<Constant> inits = globals.getConstantInitializers().values();

        // Fields
        for (Constant constant : inits) {
            visitor.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, constant.name,
                    constant.type.getDescriptor(), null, null).visitEnd();
        }

        // Initialize the constants in a static initializer
        final MethodWriter clinit = new MethodWriter(Opcodes.ACC_STATIC, WriterConstants.CLINIT, visitor,
                globals.getStatements(), settings);
        clinit.visitCode();
        for (Constant constant : inits) {
            constant.initializer.accept(clinit);
            clinit.putStatic(CLASS_TYPE, constant.name, constant.type);
        }
        clinit.returnValue();
        clinit.endMethod();
    }

    // End writing the class and store the generated bytes.

    visitor.visitEnd();
    bytes = writer.toByteArray();
}

From source file:org.elasticsearch.painless.PainlessScriptEngine.java

License:Apache License

/**
 * Generates a stateful factory class that will return script instances.  Acts as a middle man between
 * the {@link ScriptContext#factoryClazz} and the {@link ScriptContext#instanceClazz} when used so that
 * the stateless factory can be used for caching and the stateful factory can act as a cache for new
 * script instances.  Uses the newInstance method from a {@link ScriptContext#statefulFactoryClazz} to
 * define the factory method to create new instances of the {@link ScriptContext#instanceClazz}.
 * @param loader The {@link ClassLoader} that is used to define the factory class and script class.
 * @param context The {@link ScriptContext}'s semantics are used to define the factory class.
 * @param <T> The factory class./*from  w w  w .  j  ava 2  s.c o  m*/
 * @return A factory class that will return script instances.
 */
private <T> Type generateStatefulFactory(Loader loader, ScriptContext<T> context, MainMethodReserved reserved) {
    int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS;
    int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL;
    String interfaceBase = Type.getType(context.statefulFactoryClazz).getInternalName();
    String className = interfaceBase + "$StatefulFactory";
    String classInterfaces[] = new String[] { interfaceBase };

    ClassWriter writer = new ClassWriter(classFrames);
    writer.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, OBJECT_TYPE.getInternalName(),
            classInterfaces);

    Method newFactory = null;

    for (Method method : context.factoryClazz.getMethods()) {
        if ("newFactory".equals(method.getName())) {
            newFactory = method;

            break;
        }
    }

    for (int count = 0; count < newFactory.getParameterTypes().length; ++count) {
        writer.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "$arg" + count,
                Type.getType(newFactory.getParameterTypes()[count]).getDescriptor(), null, null).visitEnd();
    }

    org.objectweb.asm.commons.Method base = new org.objectweb.asm.commons.Method("<init>",
            MethodType.methodType(void.class).toMethodDescriptorString());
    org.objectweb.asm.commons.Method init = new org.objectweb.asm.commons.Method("<init>",
            MethodType.methodType(void.class, newFactory.getParameterTypes()).toMethodDescriptorString());

    GeneratorAdapter constructor = new GeneratorAdapter(Opcodes.ASM5, init,
            writer.visitMethod(Opcodes.ACC_PUBLIC, init.getName(), init.getDescriptor(), null, null));
    constructor.visitCode();
    constructor.loadThis();
    constructor.invokeConstructor(OBJECT_TYPE, base);

    for (int count = 0; count < newFactory.getParameterTypes().length; ++count) {
        constructor.loadThis();
        constructor.loadArg(count);
        constructor.putField(Type.getType(className), "$arg" + count,
                Type.getType(newFactory.getParameterTypes()[count]));
    }

    constructor.returnValue();
    constructor.endMethod();

    Method newInstance = null;

    for (Method method : context.statefulFactoryClazz.getMethods()) {
        if ("newInstance".equals(method.getName())) {
            newInstance = method;

            break;
        }
    }

    org.objectweb.asm.commons.Method instance = new org.objectweb.asm.commons.Method(newInstance.getName(),
            MethodType.methodType(newInstance.getReturnType(), newInstance.getParameterTypes())
                    .toMethodDescriptorString());

    List<Class<?>> parameters = new ArrayList<>(Arrays.asList(newFactory.getParameterTypes()));
    parameters.addAll(Arrays.asList(newInstance.getParameterTypes()));

    org.objectweb.asm.commons.Method constru = new org.objectweb.asm.commons.Method("<init>", MethodType
            .methodType(void.class, parameters.toArray(new Class<?>[] {})).toMethodDescriptorString());

    GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ASM5, instance, writer.visitMethod(
            Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, instance.getName(), instance.getDescriptor(), null, null));
    adapter.visitCode();
    adapter.newInstance(WriterConstants.CLASS_TYPE);
    adapter.dup();

    for (int count = 0; count < newFactory.getParameterTypes().length; ++count) {
        adapter.loadThis();
        adapter.getField(Type.getType(className), "$arg" + count,
                Type.getType(newFactory.getParameterTypes()[count]));
    }

    adapter.loadArgs();
    adapter.invokeConstructor(WriterConstants.CLASS_TYPE, constru);
    adapter.returnValue();
    adapter.endMethod();

    writeNeedsMethods(context.statefulFactoryClazz, writer, reserved);
    writer.visitEnd();

    loader.defineFactory(className.replace('/', '.'), writer.toByteArray());

    return Type.getType(className);
}

From source file:org.elasticsearch.painless.PainlessScriptEngine.java

License:Apache License

/**
 * Generates a factory class that will return script instances or stateful factories.
 * Uses the newInstance method from a {@link ScriptContext#factoryClazz} to define the factory method
 * to create new instances of the {@link ScriptContext#instanceClazz} or uses the newFactory method
 * to create new factories of the {@link ScriptContext#statefulFactoryClazz}.
 * @param loader The {@link ClassLoader} that is used to define the factory class and script class.
 * @param context The {@link ScriptContext}'s semantics are used to define the factory class.
 * @param classType The type to be instaniated in the newFactory or newInstance method.  Depends
 *                  on whether a {@link ScriptContext#statefulFactoryClazz} is specified.
 * @param <T> The factory class.//from  ww  w  .j  a  v a 2  s  .c o  m
 * @return A factory class that will return script instances.
 */
private <T> T generateFactory(Loader loader, ScriptContext<T> context, MainMethodReserved reserved,
        Type classType) {
    int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS;
    int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL;
    String interfaceBase = Type.getType(context.factoryClazz).getInternalName();
    String className = interfaceBase + "$Factory";
    String classInterfaces[] = new String[] { interfaceBase };

    ClassWriter writer = new ClassWriter(classFrames);
    writer.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, OBJECT_TYPE.getInternalName(),
            classInterfaces);

    org.objectweb.asm.commons.Method init = new org.objectweb.asm.commons.Method("<init>",
            MethodType.methodType(void.class).toMethodDescriptorString());

    GeneratorAdapter constructor = new GeneratorAdapter(Opcodes.ASM5, init,
            writer.visitMethod(Opcodes.ACC_PUBLIC, init.getName(), init.getDescriptor(), null, null));
    constructor.visitCode();
    constructor.loadThis();
    constructor.invokeConstructor(OBJECT_TYPE, init);
    constructor.returnValue();
    constructor.endMethod();

    Method reflect = null;

    for (Method method : context.factoryClazz.getMethods()) {
        if ("newInstance".equals(method.getName())) {
            reflect = method;

            break;
        } else if ("newFactory".equals(method.getName())) {
            reflect = method;

            break;
        }
    }

    org.objectweb.asm.commons.Method instance = new org.objectweb.asm.commons.Method(reflect.getName(),
            MethodType.methodType(reflect.getReturnType(), reflect.getParameterTypes())
                    .toMethodDescriptorString());
    org.objectweb.asm.commons.Method constru = new org.objectweb.asm.commons.Method("<init>",
            MethodType.methodType(void.class, reflect.getParameterTypes()).toMethodDescriptorString());

    GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ASM5, instance, writer.visitMethod(
            Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, instance.getName(), instance.getDescriptor(), null, null));
    adapter.visitCode();
    adapter.newInstance(classType);
    adapter.dup();
    adapter.loadArgs();
    adapter.invokeConstructor(classType, constru);
    adapter.returnValue();
    adapter.endMethod();

    writeNeedsMethods(context.factoryClazz, writer, reserved);
    writer.visitEnd();

    Class<?> factory = loader.defineFactory(className.replace('/', '.'), writer.toByteArray());

    try {
        return context.factoryClazz.cast(factory.getConstructor().newInstance());
    } catch (Exception exception) { // Catch everything to let the user know this is something caused internally.
        throw new IllegalStateException(
                "An internal error occurred attempting to define the factory class [" + className + "].",
                exception);
    }
}