Search in sources :

Example 11 with CodeTypeElement

use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement 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)

Example 12 with CodeTypeElement

use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.

the class FlatNodeGenFactory method create.

public CodeTypeElement create(CodeTypeElement clazz) {
    for (NodeChildData child : node.getChildren()) {
        clazz.addOptional(createAccessChildMethod(child));
    }
    for (NodeFieldData field : node.getFields()) {
        if (!field.isGenerated()) {
            continue;
        }
        clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), field.getType(), field.getName()));
        if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) {
            CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), field.getGetter());
            method.getModifiers().remove(Modifier.ABSTRACT);
            method.createBuilder().startReturn().string("this.").string(field.getName()).end();
            clazz.add(method);
        }
    }
    for (ExecutableElement superConstructor : GeneratorUtils.findUserConstructors(node.getTemplateType().asType())) {
        clazz.add(createNodeConstructor(clazz, superConstructor));
    }
    for (NodeExecutionData execution : node.getChildExecutions()) {
        if (execution.getChild() != null && execution.getChild().needsGeneratedField()) {
            clazz.add(createNodeField(PRIVATE, execution.getNodeType(), nodeFieldName(execution), Child.class));
        }
    }
    createFields(clazz);
    TypeMirror genericReturnType = node.getPolymorphicSpecialization().getReturnType().getType();
    List<ExecutableTypeData> executableTypes = filterExecutableTypes(node.getExecutableTypes(), reachableSpecializations);
    List<ExecutableTypeData> genericExecutableTypes = new ArrayList<>();
    List<ExecutableTypeData> specializedExecutableTypes = new ArrayList<>();
    List<ExecutableTypeData> voidExecutableTypes = new ArrayList<>();
    for (ExecutableTypeData type : executableTypes) {
        if (ElementUtils.isVoid(type.getReturnType())) {
            voidExecutableTypes.add(type);
        } else if (type.hasUnexpectedValue(context) && !ElementUtils.typeEquals(genericReturnType, type.getReturnType())) {
            specializedExecutableTypes.add(type);
        } else {
            genericExecutableTypes.add(type);
        }
    }
    if (genericExecutableTypes.size() > 1) {
        boolean hasGenericTypeMatch = false;
        for (ExecutableTypeData genericExecutable : genericExecutableTypes) {
            if (ElementUtils.typeEquals(genericExecutable.getReturnType(), genericReturnType)) {
                hasGenericTypeMatch = true;
                break;
            }
        }
        if (hasGenericTypeMatch) {
            for (ListIterator<ExecutableTypeData> iterator = genericExecutableTypes.listIterator(); iterator.hasNext(); ) {
                ExecutableTypeData executableTypeData = iterator.next();
                if (!ElementUtils.typeEquals(genericReturnType, executableTypeData.getReturnType())) {
                    iterator.remove();
                    specializedExecutableTypes.add(executableTypeData);
                }
            }
        }
    }
    SpecializationData fallback = node.getGenericSpecialization();
    if (fallback.getMethod() != null && fallback.isReachable()) {
        clazz.add(createFallbackGuard());
    }
    for (ExecutableTypeData type : genericExecutableTypes) {
        createExecute(clazz, type, Collections.<ExecutableTypeData>emptyList());
    }
    for (ExecutableTypeData type : specializedExecutableTypes) {
        createExecute(clazz, type, genericExecutableTypes);
    }
    for (ExecutableTypeData type : voidExecutableTypes) {
        List<ExecutableTypeData> genericAndSpecialized = new ArrayList<>();
        genericAndSpecialized.addAll(genericExecutableTypes);
        genericAndSpecialized.addAll(specializedExecutableTypes);
        createExecute(clazz, type, genericAndSpecialized);
    }
    clazz.addOptional(createExecuteAndSpecialize());
    if (shouldReportPolymorphism(node, reachableSpecializations)) {
        clazz.addOptional(createCheckForPolymorphicSpecialize());
        if (requiresCacheCheck()) {
            clazz.addOptional(createCountCaches());
        }
    }
    NodeInfo nodeInfo = node.getTemplateType().getAnnotation(NodeInfo.class);
    if (nodeInfo == null || nodeInfo.cost() == NodeCost.MONOMORPHIC) /* the default */
    {
        clazz.add(createGetCostMethod());
    }
    for (TypeMirror type : ElementUtils.uniqueSortedTypes(expectedTypes, false)) {
        if (!typeSystem.hasType(type)) {
            clazz.addOptional(TypeSystemCodeGenerator.createExpectMethod(PRIVATE, typeSystem, context.getType(Object.class), type));
        }
    }
    for (TypeMirror assumptionType : isValidSignatures.values()) {
        clazz.add(createIsValid(assumptionType));
    }
    clazz.getEnclosedElements().addAll(removeThisMethods.values());
    for (SpecializationData specialization : specializationClasses.keySet()) {
        CodeTypeElement type = specializationClasses.get(specialization);
        if (getInsertAccessorSet(true).contains(specialization)) {
            type.add(createInsertAccessor(true));
        } else if (getInsertAccessorSet(false).contains(specialization)) {
            type.add(createInsertAccessor(false));
        }
    }
    if (node.isReflectable()) {
        generateReflectionInfo(clazz);
    }
    return clazz;
}
Also used : ExecutableTypeData(com.oracle.truffle.dsl.processor.model.ExecutableTypeData) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) NodeChildData(com.oracle.truffle.dsl.processor.model.NodeChildData) NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) DeclaredCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) GeneratedTypeMirror(com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) NodeInfo(com.oracle.truffle.api.nodes.NodeInfo) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) Child(com.oracle.truffle.api.nodes.Node.Child)

Example 13 with CodeTypeElement

use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.

the class GeneratorUtils method isCopyConstructor.

static boolean isCopyConstructor(ExecutableElement element) {
    if (element.getParameters().size() != 1) {
        return false;
    }
    VariableElement var = element.getParameters().get(0);
    TypeElement enclosingType = ElementUtils.findNearestEnclosingType(var);
    if (ElementUtils.typeEquals(var.asType(), enclosingType.asType())) {
        return true;
    }
    List<TypeElement> types = ElementUtils.getDirectSuperTypes(enclosingType);
    for (TypeElement type : types) {
        if (!(type instanceof CodeTypeElement)) {
            // no copy constructors which are not generated types
            return false;
        }
        if (ElementUtils.typeEquals(var.asType(), type.asType())) {
            return true;
        }
    }
    return false;
}
Also used : CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) TypeElement(javax.lang.model.element.TypeElement) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) VariableElement(javax.lang.model.element.VariableElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)

Example 14 with CodeTypeElement

use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.

the class NodeCodeGenerator method create.

@Override
public CodeTypeElement create(ProcessorContext context, NodeData node) {
    List<CodeTypeElement> enclosedTypes = new ArrayList<>();
    for (NodeData childNode : node.getEnclosingNodes()) {
        CodeTypeElement type = create(context, childNode);
        if (type != null) {
            enclosedTypes.add(type);
        }
    }
    List<CodeTypeElement> generatedNodes = generateNodes(context, node);
    if (!generatedNodes.isEmpty() || !enclosedTypes.isEmpty()) {
        CodeTypeElement type;
        if (generatedNodes.isEmpty()) {
            type = createContainer(node);
        } else {
            type = wrapGeneratedNodes(context, node, generatedNodes);
        }
        for (CodeTypeElement enclosedFactory : enclosedTypes) {
            type.add(makeInnerClass(enclosedFactory));
        }
        if (node.getDeclaringNode() == null && enclosedTypes.size() > 0) {
            ExecutableElement getFactories = createGetFactories(context, node);
            if (getFactories != null) {
                type.add(getFactories);
            }
        }
        return type;
    } else {
        return null;
    }
}
Also used : CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) NodeData(com.oracle.truffle.dsl.processor.model.NodeData)

Example 15 with CodeTypeElement

use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.

the class NodeFactoryFactory method create.

public CodeTypeElement create() {
    Modifier visibility = ElementUtils.getVisibility(node.getTemplateType().getModifiers());
    TypeMirror nodeFactory = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(context.getType(NodeFactory.class)), node.getNodeType());
    CodeTypeElement clazz = GeneratorUtils.createClass(node, null, modifiers(), factoryClassName(node), null);
    if (visibility != null) {
        clazz.getModifiers().add(visibility);
    }
    clazz.getModifiers().add(Modifier.FINAL);
    if (createdFactoryElement != null) {
        clazz.getImplements().add(nodeFactory);
        CodeAnnotationMirror supressWarnings = new CodeAnnotationMirror(context.getDeclaredType(SuppressWarnings.class));
        supressWarnings.setElementValue(supressWarnings.findExecutableElement("value"), new CodeAnnotationValue(Arrays.asList(new CodeAnnotationValue("unchecked"), new CodeAnnotationValue("rawtypes"))));
        clazz.getAnnotationMirrors().add(supressWarnings);
        clazz.add(createNodeFactoryConstructor());
        clazz.add(createCreateGetNodeClass());
        clazz.add(createCreateGetExecutionSignature());
        clazz.add(createCreateGetNodeSignatures());
        clazz.add(createCreateNodeMethod());
        clazz.add(createGetInstanceMethod(visibility));
        clazz.add(createInstanceConstant(clazz.asType()));
        createFactoryMethods(clazz);
    }
    return clazz;
}
Also used : CodeAnnotationMirror(com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) Modifier(javax.lang.model.element.Modifier) CodeAnnotationValue(com.oracle.truffle.dsl.processor.java.model.CodeAnnotationValue)

Aggregations

CodeTypeElement (com.oracle.truffle.dsl.processor.java.model.CodeTypeElement)21 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)12 TypeElement (javax.lang.model.element.TypeElement)11 ExecutableElement (javax.lang.model.element.ExecutableElement)10 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)8 PackageElement (javax.lang.model.element.PackageElement)7 TypeMirror (javax.lang.model.type.TypeMirror)7 Modifier (javax.lang.model.element.Modifier)6 VariableElement (javax.lang.model.element.VariableElement)6 DeclaredType (javax.lang.model.type.DeclaredType)6 CodeAnnotationMirror (com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror)5 CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)4 FixWarningsVisitor (com.oracle.truffle.dsl.processor.java.transform.FixWarningsVisitor)4 GenerateOverrideVisitor (com.oracle.truffle.dsl.processor.java.transform.GenerateOverrideVisitor)4 ArrayList (java.util.ArrayList)4 CodeAnnotationValue (com.oracle.truffle.dsl.processor.java.model.CodeAnnotationValue)3 CodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror)3 AnnotationMirror (javax.lang.model.element.AnnotationMirror)3 Element (javax.lang.model.element.Element)3 GenerateWrapper (com.oracle.truffle.api.instrumentation.GenerateWrapper)2