Search in sources :

Example 1 with GenerateOverrideVisitor

use of com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor in project graal by oracle.

the class OptionProcessor method generateOptionDescriptor.

private void generateOptionDescriptor(OptionsInfo info) {
    Element element = info.type;
    ProcessorContext context = ProcessorContext.getInstance();
    CodeTypeElement unit = generateDescriptors(context, element, info);
    DeclaredType overrideType = (DeclaredType) context.getType(Override.class);
    DeclaredType suppressedWarnings = (DeclaredType) context.getType(SuppressWarnings.class);
    unit.accept(new GenerateOverrideVisitor(overrideType), null);
    unit.accept(new FixWarningsVisitor(context.getEnvironment(), suppressedWarnings, overrideType), null);
    try {
        unit.accept(new CodeWriter(context.getEnvironment(), element), null);
    } catch (RuntimeException e) {
        if (e.getCause() instanceof FilerException) {
            // ignore spurious errors of source file already created in Eclipse.
            if (e.getCause().getMessage().startsWith("Source file already created")) {
                return;
            }
        }
    }
}
Also used : CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) PackageElement(javax.lang.model.element.PackageElement) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) GenerateOverrideVisitor(com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor) FixWarningsVisitor(com.oracle.truffle.dsl.processor.java.transform.FixWarningsVisitor) FilerException(javax.annotation.processing.FilerException) DeclaredType(javax.lang.model.type.DeclaredType)

Example 2 with GenerateOverrideVisitor

use of com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor in project graal by oracle.

the class AnnotationProcessor method process.

@SuppressWarnings({ "unchecked" })
public void process(Element element, boolean callback) {
    if (!(element instanceof TypeElement)) {
        return;
    }
    // we check for already processed elements to avoid errors when writing files.
    if (!callback) {
        String qualifiedName = ElementUtils.getQualifiedName((TypeElement) element);
        if (processedElements.contains(qualifiedName)) {
            return;
        }
        processedElements.add(qualifiedName);
    }
    ProcessorContext context = ProcessorContext.getInstance();
    TypeElement type = (TypeElement) element;
    M model = (M) context.getTemplate(type.asType(), false);
    boolean firstRun = !context.containsTemplate(type);
    if (firstRun || !callback) {
        context.registerTemplate(type, null);
        model = parser.parse(element);
        context.registerTemplate(type, model);
        if (model != null) {
            CodeTypeElement unit;
            try {
                unit = factory.create(ProcessorContext.getInstance(), model);
            } catch (Throwable e) {
                throw new RuntimeException(String.format("Failed to write code for %s. Parserdump:%s.", ElementUtils.getQualifiedName(type), ""), e);
            }
            if (unit == null) {
                return;
            }
            unit.setGeneratorAnnotationMirror(model.getTemplateTypeAnnotation());
            unit.setGeneratorElement(model.getTemplateType());
            DeclaredType overrideType = (DeclaredType) context.getType(Override.class);
            DeclaredType unusedType = (DeclaredType) context.getType(SuppressWarnings.class);
            unit.accept(new GenerateOverrideVisitor(overrideType), null);
            unit.accept(new FixWarningsVisitor(context.getEnvironment(), unusedType, overrideType), null);
            if (!callback) {
                unit.accept(new CodeWriter(context.getEnvironment(), element), null);
            }
        }
    }
}
Also used : CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) TypeElement(javax.lang.model.element.TypeElement) FixWarningsVisitor(com.oracle.truffle.dsl.processor.java.transform.FixWarningsVisitor) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) GenerateOverrideVisitor(com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor) DeclaredType(javax.lang.model.type.DeclaredType)

Example 3 with GenerateOverrideVisitor

use of com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor in project graal by oracle.

the class InstrumentableProcessor method processLegacyInstrumentable.

/*
     * TO BE REMOVED WITH DEPRECATIONS
     */
@SuppressWarnings("deprecation")
private void processLegacyInstrumentable(RoundEnvironment roundEnv, ProcessorContext context) {
    for (Element element : roundEnv.getElementsAnnotatedWith(com.oracle.truffle.api.instrumentation.Instrumentable.class)) {
        if (!element.getKind().isClass() && !element.getKind().isInterface()) {
            continue;
        }
        try {
            if (element.getKind() != ElementKind.CLASS) {
                emitError(element, String.format("Only classes can be annotated with %s.", com.oracle.truffle.api.instrumentation.Instrumentable.class.getSimpleName()));
                continue;
            }
            AnnotationMirror generateWrapperMirror = ElementUtils.findAnnotationMirror(element.getAnnotationMirrors(), context.getType(GenerateWrapper.class));
            if (generateWrapperMirror != null) {
                continue;
            }
            TypeMirror instrumentableType = context.getType(com.oracle.truffle.api.instrumentation.Instrumentable.class);
            AnnotationMirror instrumentable = ElementUtils.findAnnotationMirror(element.getAnnotationMirrors(), instrumentableType);
            if (instrumentable == null) {
                continue;
            } else {
                final boolean generateWrapper;
                TypeMirror factoryType = ElementUtils.getAnnotationValue(TypeMirror.class, instrumentable, "factory");
                if (factoryType == null || factoryType.getKind() == TypeKind.ERROR) {
                    // factory type is erroneous or null (can mean error in javac)
                    // generate it
                    generateWrapper = true;
                } else {
                    TypeElement type = context.getEnvironment().getElementUtils().getTypeElement("com.oracle.truffle.api.instrumentation.test.TestErrorFactory");
                    if (type != null && ElementUtils.typeEquals(factoryType, type.asType())) {
                        generateWrapper = true;
                    } else {
                        // factory is user defined or already generated
                        generateWrapper = false;
                    }
                }
                if (!generateWrapper) {
                    continue;
                }
            }
            CodeTypeElement unit = generateWrapperAndFactory(context, element);
            if (unit == null) {
                continue;
            }
            DeclaredType overrideType = (DeclaredType) context.getType(Override.class);
            DeclaredType unusedType = (DeclaredType) context.getType(SuppressWarnings.class);
            unit.accept(new GenerateOverrideVisitor(overrideType), null);
            unit.accept(new FixWarningsVisitor(context.getEnvironment(), unusedType, overrideType), null);
            unit.accept(new CodeWriter(context.getEnvironment(), element), null);
        } catch (Throwable e) {
            // never throw annotation processor exceptions to the compiler
            // it might screw up its state.
            handleThrowable(e, element);
        }
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) PackageElement(javax.lang.model.element.PackageElement) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) GenerateWrapper(com.oracle.truffle.api.instrumentation.GenerateWrapper) FixWarningsVisitor(com.oracle.truffle.dsl.processor.java.transform.FixWarningsVisitor) CodeAnnotationMirror(com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror) AnnotationMirror(javax.lang.model.element.AnnotationMirror) CodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) GenerateOverrideVisitor(com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor) DeclaredType(javax.lang.model.type.DeclaredType)

Example 4 with GenerateOverrideVisitor

use of com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor in project graal by oracle.

the class InstrumentableProcessor method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    if (roundEnv.processingOver()) {
        return false;
    }
    try {
        ProcessorContext context = new ProcessorContext(processingEnv, null);
        ProcessorContext.setThreadLocalInstance(context);
        DeclaredType instrumentableNode = context.getDeclaredType(InstrumentableNode.class);
        ExecutableElement createWrapper = ElementUtils.findExecutableElement(instrumentableNode, CREATE_WRAPPER_NAME);
        for (Element element : roundEnv.getElementsAnnotatedWith(GenerateWrapper.class)) {
            if (!element.getKind().isClass() && !element.getKind().isInterface()) {
                continue;
            }
            try {
                if (element.getKind() != ElementKind.CLASS) {
                    emitError(element, String.format("Only classes can be annotated with %s.", GenerateWrapper.class.getSimpleName()));
                    continue;
                }
                if (createWrapper == null) {
                    emitError(element, String.format("Fatal %s.%s not found.", InstrumentableNode.class.getSimpleName(), CREATE_WRAPPER_NAME));
                    continue;
                }
                if (!ElementUtils.isAssignable(element.asType(), instrumentableNode)) {
                    emitError(element, String.format("Classes annotated with @%s must implement %s.", GenerateWrapper.class.getSimpleName(), InstrumentableNode.class.getSimpleName()));
                    continue;
                } else {
                    boolean createWrapperFound = false;
                    for (ExecutableElement declaredMethod : ElementFilter.methodsIn(element.getEnclosedElements())) {
                        if (ElementUtils.signatureEquals(declaredMethod, createWrapper)) {
                            createWrapperFound = true;
                            break;
                        }
                    }
                    if (!createWrapperFound) {
                        emitError(element, String.format("Classes annotated with @%s must declare/override %s.%s and return a new instance of the generated wrapper class called %s." + " You may copy the following generated implementation: %n" + "  @Override public %s createWrapper(%s probeNode) {%n" + "    return new %s(this, probeNode);%n" + "  }", GenerateWrapper.class.getSimpleName(), InstrumentableNode.class.getSimpleName(), CREATE_WRAPPER_NAME, createWrapperClassName((TypeElement) element), com.oracle.truffle.api.instrumentation.InstrumentableNode.WrapperNode.class.getSimpleName(), ProbeNode.class.getSimpleName(), createWrapperClassName((TypeElement) element)));
                        continue;
                    }
                    if (!ElementUtils.isAssignable(element.asType(), context.getType(Node.class))) {
                        emitError(element, String.format("Classes annotated with @%s must extend %s.", GenerateWrapper.class.getSimpleName(), Node.class.getSimpleName()));
                        continue;
                    }
                }
                AnnotationMirror generateWrapperMirror = ElementUtils.findAnnotationMirror(element.getAnnotationMirrors(), context.getType(GenerateWrapper.class));
                if (generateWrapperMirror == null) {
                    continue;
                }
                CodeTypeElement unit = generateWrapperOnly(context, element);
                if (unit == null) {
                    continue;
                }
                DeclaredType overrideType = (DeclaredType) context.getType(Override.class);
                DeclaredType unusedType = (DeclaredType) context.getType(SuppressWarnings.class);
                unit.accept(new GenerateOverrideVisitor(overrideType), null);
                unit.accept(new FixWarningsVisitor(context.getEnvironment(), unusedType, overrideType), null);
                unit.accept(new CodeWriter(context.getEnvironment(), element), null);
            } catch (Throwable e) {
                // never throw annotation processor exceptions to the compiler
                // it might screw up its state.
                handleThrowable(e, element);
            }
        }
        // remove with deprecations
        processLegacyInstrumentable(roundEnv, context);
        return true;
    } finally {
        ProcessorContext.setThreadLocalInstance(null);
    }
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) PackageElement(javax.lang.model.element.PackageElement) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) GenerateWrapper(com.oracle.truffle.api.instrumentation.GenerateWrapper) FixWarningsVisitor(com.oracle.truffle.dsl.processor.java.transform.FixWarningsVisitor) InstrumentableNode(com.oracle.truffle.api.instrumentation.InstrumentableNode) CodeAnnotationMirror(com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror) AnnotationMirror(javax.lang.model.element.AnnotationMirror) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) GenerateOverrideVisitor(com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

CodeTypeElement (com.oracle.truffle.dsl.processor.java.model.CodeTypeElement)4 FixWarningsVisitor (com.oracle.truffle.dsl.processor.java.transform.FixWarningsVisitor)4 GenerateOverrideVisitor (com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor)4 TypeElement (javax.lang.model.element.TypeElement)4 DeclaredType (javax.lang.model.type.DeclaredType)4 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)3 Element (javax.lang.model.element.Element)3 ExecutableElement (javax.lang.model.element.ExecutableElement)3 PackageElement (javax.lang.model.element.PackageElement)3 VariableElement (javax.lang.model.element.VariableElement)3 GenerateWrapper (com.oracle.truffle.api.instrumentation.GenerateWrapper)2 CodeAnnotationMirror (com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror)2 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 InstrumentableNode (com.oracle.truffle.api.instrumentation.InstrumentableNode)1 CodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror)1 FilerException (javax.annotation.processing.FilerException)1 TypeMirror (javax.lang.model.type.TypeMirror)1