Search in sources :

Example 1 with Verifier

use of org.codehaus.groovy.classgen.Verifier in project ratpack by ratpack.

the class ScriptEngine method createClassLoader.

private GroovyClassLoader createClassLoader(final Path scriptPath) {
    final CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
    if (!scriptBaseClass.equals(Script.class)) {
        compilerConfiguration.setScriptBaseClass(scriptBaseClass.getName());
    }
    compilerConfiguration.addCompilationCustomizers(new CompilationCustomizer(CompilePhase.CONVERSION) {

        @Override
        public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
            if (staticCompile) {
                classNode.addAnnotation(new AnnotationNode(new ClassNode(CompileStatic.class)));
            }
            classNode.addAnnotation(new AnnotationNode(new ClassNode(InheritConstructors.class)));
            if (scriptPath != null) {
                AnnotationNode scriptPathAnnotation = new AnnotationNode(new ClassNode(ScriptPath.class));
                scriptPathAnnotation.addMember("value", new ConstantExpression(scriptPath.toUri().toString()));
                classNode.addAnnotation(scriptPathAnnotation);
            }
        }
    });
    return new GroovyClassLoader(parentLoader, compilerConfiguration) {

        @Override
        protected CompilationUnit createCompilationUnit(CompilerConfiguration config, CodeSource source) {
            return new CompilationUnit(config, source, this) {

                {
                    verifier = new Verifier() {

                        @Override
                        public void visitClass(ClassNode node) {
                            if (node.implementsInterface(ClassHelper.GENERATED_CLOSURE_Type)) {
                                AnnotationNode lineNumberAnnotation = new AnnotationNode(LINE_NUMBER_CLASS_NODE);
                                lineNumberAnnotation.addMember("value", new ConstantExpression(node.getLineNumber(), true));
                                node.addAnnotation(lineNumberAnnotation);
                            }
                            super.visitClass(node);
                        }
                    };
                }
            };
        }
    };
}
Also used : Script(groovy.lang.Script) ClassNode(org.codehaus.groovy.ast.ClassNode) InheritConstructors(groovy.transform.InheritConstructors) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) CompileStatic(groovy.transform.CompileStatic) GeneratorContext(org.codehaus.groovy.classgen.GeneratorContext) CodeSource(java.security.CodeSource) Verifier(org.codehaus.groovy.classgen.Verifier) GroovyClassLoader(groovy.lang.GroovyClassLoader) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) CompilationCustomizer(org.codehaus.groovy.control.customizers.CompilationCustomizer)

Example 2 with Verifier

use of org.codehaus.groovy.classgen.Verifier in project groovy-core by groovy.

the class JavaStubGenerator method printClassContents.

private void printClassContents(PrintWriter out, ClassNode classNode) throws FileNotFoundException {
    if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) {
        // if it is an anonymous inner class, don't generate the stub code for it.
        return;
    }
    try {
        Verifier verifier = new Verifier() {

            @Override
            public void visitClass(final ClassNode node) {
                List<Statement> savedStatements = new ArrayList<Statement>(node.getObjectInitializerStatements());
                super.visitClass(node);
                node.getObjectInitializerStatements().addAll(savedStatements);
            }

            @Override
            protected FinalVariableAnalyzer.VariableNotFinalCallback getFinalVariablesCallback() {
                return null;
            }

            public void addCovariantMethods(ClassNode cn) {
            }

            protected void addTimeStamp(ClassNode node) {
            }

            protected void addInitialization(ClassNode node) {
            }

            protected void addPropertyMethod(MethodNode method) {
                doAddMethod(method);
            }

            protected void addReturnIfNeeded(MethodNode node) {
            }

            protected void addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
                doAddMethod(new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
            }

            protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) {
                if (code instanceof ExpressionStatement) {
                    // GROOVY-4508
                    Statement temp = code;
                    code = new BlockStatement();
                    ((BlockStatement) code).addStatement(temp);
                }
                ConstructorNode ctrNode = new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code);
                ctrNode.setDeclaringClass(node);
                constructors.add(ctrNode);
            }

            protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) {
                final Parameter[] parameters = method.getParameters();
                final Expression[] saved = new Expression[parameters.length];
                for (int i = 0; i < parameters.length; i++) {
                    if (parameters[i].hasInitialExpression())
                        saved[i] = parameters[i].getInitialExpression();
                }
                super.addDefaultParameters(action, method);
                for (int i = 0; i < parameters.length; i++) {
                    if (saved[i] != null)
                        parameters[i].setInitialExpression(saved[i]);
                }
            }

            private void doAddMethod(MethodNode method) {
                String sig = method.getTypeDescriptor();
                if (propertyMethodsWithSigs.containsKey(sig))
                    return;
                propertyMethods.add(method);
                propertyMethodsWithSigs.put(sig, method);
            }

            @Override
            protected void addDefaultConstructor(ClassNode node) {
            // not required for stub generation
            }
        };
        verifier.visitClass(classNode);
        currentModule = classNode.getModule();
        boolean isInterface = isInterfaceOrTrait(classNode);
        boolean isEnum = (classNode.getModifiers() & Opcodes.ACC_ENUM) != 0;
        boolean isAnnotationDefinition = classNode.isAnnotationDefinition();
        printAnnotations(out, classNode);
        printModifiers(out, classNode.getModifiers() & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0) & ~(isEnum ? Opcodes.ACC_FINAL : 0));
        if (isInterface) {
            if (isAnnotationDefinition) {
                out.print("@");
            }
            out.print("interface ");
        } else if (isEnum) {
            out.print("enum ");
        } else {
            out.print("class ");
        }
        String className = classNode.getNameWithoutPackage();
        if (classNode instanceof InnerClassNode)
            className = className.substring(className.lastIndexOf("$") + 1);
        out.println(className);
        printGenericsBounds(out, classNode, true);
        ClassNode superClass = classNode.getUnresolvedSuperClass(false);
        if (!isInterface && !isEnum) {
            out.print("  extends ");
            printType(out, superClass);
        }
        ClassNode[] interfaces = classNode.getInterfaces();
        if (interfaces != null && interfaces.length > 0 && !isAnnotationDefinition) {
            if (isInterface) {
                out.println("  extends");
            } else {
                out.println("  implements");
            }
            for (int i = 0; i < interfaces.length - 1; ++i) {
                out.print("    ");
                printType(out, interfaces[i]);
                out.print(",");
            }
            out.print("    ");
            printType(out, interfaces[interfaces.length - 1]);
        }
        out.println(" {");
        printFields(out, classNode);
        printMethods(out, classNode, isEnum);
        for (Iterator<InnerClassNode> inner = classNode.getInnerClasses(); inner.hasNext(); ) {
            // GROOVY-4004: Clear the methods from the outer class so that they don't get duplicated in inner ones
            propertyMethods.clear();
            propertyMethodsWithSigs.clear();
            constructors.clear();
            printClassContents(out, inner.next());
        }
        out.println("}");
    } finally {
        propertyMethods.clear();
        propertyMethodsWithSigs.clear();
        constructors.clear();
        currentModule = null;
    }
}
Also used : Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Verifier(org.codehaus.groovy.classgen.Verifier) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) FinalVariableAnalyzer(org.codehaus.groovy.classgen.FinalVariableAnalyzer)

Example 3 with Verifier

use of org.codehaus.groovy.classgen.Verifier in project groovy by apache.

the class JavaStubGenerator method printClassContents.

private void printClassContents(PrintWriter out, ClassNode classNode) {
    if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) {
        // if it is an anonymous inner class, don't generate the stub code for it.
        return;
    }
    try {
        Verifier verifier = new Verifier() {

            @Override
            public void visitClass(ClassNode node) {
                List<Statement> savedStatements = new ArrayList<>(node.getObjectInitializerStatements());
                super.visitClass(node);
                node.getObjectInitializerStatements().addAll(savedStatements);
                for (ClassNode trait : findTraits(node)) {
                    // GROOVY-9031: replace property type placeholder with resolved type from trait generics
                    Map<String, ClassNode> generics = trait.isUsingGenerics() ? createGenericsSpec(trait) : null;
                    for (PropertyNode traitProperty : trait.getProperties()) {
                        ClassNode traitPropertyType = traitProperty.getType();
                        traitProperty.setType(correctToGenericsSpecRecurse(generics, traitPropertyType));
                        super.visitProperty(traitProperty);
                        traitProperty.setType(traitPropertyType);
                    }
                }
            }

            @Override
            public void visitConstructor(ConstructorNode node) {
                Statement stmt = node.getCode();
                if (stmt != null) {
                    stmt.visit(new VerifierCodeVisitor(getClassNode()));
                }
            }

            @Override
            public void visitProperty(PropertyNode node) {
                // GROOVY-8233 skip static properties for traits since they don't make the interface
                if (!node.isStatic() || !Traits.isTrait(node.getDeclaringClass())) {
                    super.visitProperty(node);
                }
            }

            @Override
            public void addCovariantMethods(ClassNode cn) {
            }

            @Override
            protected void addInitialization(ClassNode node) {
            }

            @Override
            protected void addPropertyMethod(MethodNode method) {
                doAddMethod(method);
            }

            @Override
            protected void addReturnIfNeeded(MethodNode node) {
            }

            @Override
            protected MethodNode addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
                return doAddMethod(new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
            }

            @Override
            protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) {
                if (code instanceof ExpressionStatement) {
                    // GROOVY-4508
                    Statement temp = code;
                    code = new BlockStatement();
                    ((BlockStatement) code).addStatement(temp);
                }
                ConstructorNode ctrNode = new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code);
                ctrNode.setDeclaringClass(node);
                constructors.add(ctrNode);
            }

            @Override
            protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) {
                final Parameter[] parameters = method.getParameters();
                final Expression[] saved = new Expression[parameters.length];
                for (int i = 0; i < parameters.length; i++) {
                    if (parameters[i].hasInitialExpression())
                        saved[i] = parameters[i].getInitialExpression();
                }
                super.addDefaultParameters(action, method);
                for (int i = 0; i < parameters.length; i++) {
                    if (saved[i] != null)
                        parameters[i].setInitialExpression(saved[i]);
                }
            }

            private MethodNode doAddMethod(MethodNode method) {
                String sig = method.getTypeDescriptor();
                if (propertyMethodsWithSigs.containsKey(sig))
                    return method;
                propertyMethods.add(method);
                propertyMethodsWithSigs.put(sig, method);
                return method;
            }

            @Override
            protected void addDefaultConstructor(ClassNode node) {
            // not required for stub generation
            }

            @Override
            protected FinalVariableAnalyzer.VariableNotFinalCallback getFinalVariablesCallback() {
                return null;
            }
        };
        int origNumConstructors = classNode.getDeclaredConstructors().size();
        verifier.visitClass(classNode);
        // undo unwanted side-effect of verifier
        if (origNumConstructors == 0 && classNode.getDeclaredConstructors().size() == 1) {
            classNode.getDeclaredConstructors().clear();
        }
        boolean isInterface = isInterfaceOrTrait(classNode);
        boolean isEnum = classNode.isEnum();
        boolean isAnnotationDefinition = classNode.isAnnotationDefinition();
        printAnnotations(out, classNode);
        printModifiers(out, classNode.getModifiers() & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0) & ~(isEnum ? Opcodes.ACC_FINAL | Opcodes.ACC_ABSTRACT : 0));
        if (isInterface) {
            if (isAnnotationDefinition) {
                out.print("@");
            }
            out.print("interface ");
        } else if (isEnum) {
            out.print("enum ");
        } else {
            out.print("class ");
        }
        String className = classNode.getNameWithoutPackage();
        if (classNode instanceof InnerClassNode)
            className = className.substring(className.lastIndexOf('$') + 1);
        out.println(className);
        printGenericsBounds(out, classNode, true);
        ClassNode superClass = classNode.getUnresolvedSuperClass(false);
        if (!isInterface && !isEnum) {
            out.print("  extends ");
            printType(out, superClass);
        }
        ClassNode[] interfaces = classNode.getInterfaces();
        if (interfaces != null && interfaces.length > 0 && !isAnnotationDefinition) {
            if (isInterface) {
                out.println("  extends");
            } else {
                out.println("  implements");
            }
            for (int i = 0; i < interfaces.length - 1; ++i) {
                out.print("    ");
                printType(out, interfaces[i]);
                out.print(",");
            }
            out.print("    ");
            printType(out, interfaces[interfaces.length - 1]);
        }
        out.println(" {");
        printFields(out, classNode);
        printMethods(out, classNode, isEnum);
        for (Iterator<InnerClassNode> inner = classNode.getInnerClasses(); inner.hasNext(); ) {
            // GROOVY-4004: Clear the methods from the outer class so that they don't get duplicated in inner ones
            propertyMethods.clear();
            propertyMethodsWithSigs.clear();
            constructors.clear();
            printClassContents(out, inner.next());
        }
        out.println("}");
    } finally {
        propertyMethods.clear();
        propertyMethodsWithSigs.clear();
        constructors.clear();
    }
}
Also used : DecompiledClassNode(org.codehaus.groovy.ast.decompiled.DecompiledClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Verifier(org.codehaus.groovy.classgen.Verifier) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) VerifierCodeVisitor(org.codehaus.groovy.classgen.VerifierCodeVisitor) MethodNode(org.codehaus.groovy.ast.MethodNode) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) PropertyNode(org.codehaus.groovy.ast.PropertyNode) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) FinalVariableAnalyzer(org.codehaus.groovy.classgen.FinalVariableAnalyzer)

Aggregations

ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)3 Verifier (org.codehaus.groovy.classgen.Verifier)3 ArrayList (java.util.ArrayList)2 ClassNode (org.codehaus.groovy.ast.ClassNode)2 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)2 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)2 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)2 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)2 Expression (org.codehaus.groovy.ast.expr.Expression)2 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)2 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)2 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)2 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)2 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)2 Statement (org.codehaus.groovy.ast.stmt.Statement)2 FinalVariableAnalyzer (org.codehaus.groovy.classgen.FinalVariableAnalyzer)2 GroovyClassLoader (groovy.lang.GroovyClassLoader)1 Script (groovy.lang.Script)1 CompileStatic (groovy.transform.CompileStatic)1 InheritConstructors (groovy.transform.InheritConstructors)1