Search in sources :

Example 1 with NodeFieldData

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

the class NodeParser method verifyMissingAbstractMethods.

private static void verifyMissingAbstractMethods(NodeData nodeData, List<? extends Element> originalElements) {
    if (!nodeData.needsFactory()) {
        // if we need go generate factory for it.
        return;
    }
    List<Element> elements = newElementList(originalElements);
    Set<Element> unusedElements = new HashSet<>(elements);
    for (ExecutableElement method : nodeData.getAllTemplateMethods()) {
        unusedElements.remove(method);
    }
    for (NodeFieldData field : nodeData.getFields()) {
        if (field.getGetter() != null) {
            unusedElements.remove(field.getGetter());
        }
    }
    for (NodeChildData child : nodeData.getChildren()) {
        if (child.getAccessElement() != null) {
            unusedElements.remove(child.getAccessElement());
        }
    }
    Map<String, List<ExecutableElement>> methodsByName = null;
    outer: for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) {
        if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) {
            // group by method name to avoid N^2 worst case complexity.
            if (methodsByName == null) {
                methodsByName = new HashMap<>();
                for (ExecutableElement m : ElementFilter.methodsIn(unusedElements)) {
                    String name = m.getSimpleName().toString();
                    List<ExecutableElement> groupedElements = methodsByName.get(name);
                    if (groupedElements == null) {
                        groupedElements = new ArrayList<>();
                        methodsByName.put(name, groupedElements);
                    }
                    groupedElements.add(m);
                }
            }
            for (ExecutableElement otherMethod : methodsByName.get(unusedMethod.getSimpleName().toString())) {
                if (unusedMethod == otherMethod) {
                    continue;
                }
                if (ProcessorContext.getInstance().getEnvironment().getElementUtils().overrides(otherMethod, unusedMethod, nodeData.getTemplateType())) {
                    // -> the method does not need an implementation.
                    continue outer;
                }
            }
            nodeData.addError("The type %s must implement the inherited abstract method %s.", ElementUtils.getSimpleName(nodeData.getTemplateType()), ElementUtils.getReadableSignature(unusedMethod));
        }
    }
}
Also used : NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) NodeChildData(com.oracle.truffle.dsl.processor.model.NodeChildData) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 2 with NodeFieldData

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

the class NodeParser method parseExecutions.

private List<NodeExecutionData> parseExecutions(List<NodeFieldData> fields, List<NodeChildData> children, List<? extends Element> elements) {
    List<ExecutableElement> methods = ElementFilter.methodsIn(elements);
    boolean hasVarArgs = false;
    int maxSignatureSize = 0;
    if (!children.isEmpty()) {
        int lastIndex = children.size() - 1;
        hasVarArgs = children.get(lastIndex).getCardinality() == Cardinality.MANY;
        if (hasVarArgs) {
            maxSignatureSize = lastIndex;
        } else {
            maxSignatureSize = children.size();
        }
    }
    List<NodeFieldData> nonGetterFields = new ArrayList<>();
    for (NodeFieldData field : fields) {
        if (field.getGetter() == null && field.isGenerated()) {
            nonGetterFields.add(field);
        }
    }
    TypeMirror cacheAnnotation = context.getType(Cached.class);
    List<TypeMirror> frameTypes = context.getFrameTypes();
    // pre-parse specializations to find signature size
    for (ExecutableElement method : methods) {
        AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, Specialization.class);
        if (mirror == null) {
            continue;
        }
        int currentArgumentIndex = 0;
        parameter: for (VariableElement var : method.getParameters()) {
            TypeMirror type = var.asType();
            if (currentArgumentIndex == 0) {
                // skip optionals
                for (TypeMirror frameType : frameTypes) {
                    if (ElementUtils.typeEquals(type, frameType)) {
                        continue parameter;
                    }
                }
            }
            if (currentArgumentIndex < nonGetterFields.size()) {
                for (NodeFieldData field : nonGetterFields) {
                    if (ElementUtils.typeEquals(var.asType(), field.getType())) {
                        continue parameter;
                    }
                }
            }
            if (ElementUtils.findAnnotationMirror(var.getAnnotationMirrors(), cacheAnnotation) != null) {
                continue parameter;
            }
            currentArgumentIndex++;
        }
        maxSignatureSize = Math.max(maxSignatureSize, currentArgumentIndex);
    }
    List<NodeExecutionData> executions = new ArrayList<>();
    for (int i = 0; i < maxSignatureSize; i++) {
        boolean varArgParameter = false;
        int childIndex = i;
        if (i >= children.size() - 1) {
            if (hasVarArgs) {
                varArgParameter = hasVarArgs;
                childIndex = Math.min(i, children.size() - 1);
            } else if (i >= children.size()) {
                childIndex = -1;
            }
        }
        int varArgsIndex = -1;
        NodeChildData child = null;
        if (childIndex != -1) {
            varArgsIndex = varArgParameter ? Math.abs(childIndex - i) : -1;
            child = children.get(childIndex);
        }
        executions.add(new NodeExecutionData(child, i, varArgsIndex));
    }
    return executions;
}
Also used : NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) NodeChildData(com.oracle.truffle.dsl.processor.model.NodeChildData) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) AnnotationMirror(javax.lang.model.element.AnnotationMirror) NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror)

Example 3 with NodeFieldData

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

the class NodeParser method parseFields.

private List<NodeFieldData> parseFields(List<TypeElement> typeHierarchy, List<? extends Element> elements) {
    Set<String> names = new HashSet<>();
    List<NodeFieldData> fields = new ArrayList<>();
    for (VariableElement field : ElementFilter.fieldsIn(elements)) {
        if (field.getModifiers().contains(Modifier.STATIC)) {
            continue;
        } else if (field.getAnnotation(Executed.class) != null) {
            continue;
        }
        if (field.getModifiers().contains(Modifier.PUBLIC) || field.getModifiers().contains(Modifier.PROTECTED)) {
            String name = field.getSimpleName().toString();
            fields.add(new NodeFieldData(field, null, field, false));
            names.add(name);
        }
    }
    List<TypeElement> reversedTypeHierarchy = new ArrayList<>(typeHierarchy);
    Collections.reverse(reversedTypeHierarchy);
    for (TypeElement typeElement : reversedTypeHierarchy) {
        AnnotationMirror nodeChildrenMirror = ElementUtils.findAnnotationMirror(processingEnv, typeElement, NodeFields.class);
        List<AnnotationMirror> children = ElementUtils.collectAnnotations(context, nodeChildrenMirror, "value", typeElement, NodeField.class);
        for (AnnotationMirror mirror : children) {
            String name = ElementUtils.firstLetterLowerCase(ElementUtils.getAnnotationValue(String.class, mirror, "name"));
            TypeMirror type = ElementUtils.getAnnotationValue(TypeMirror.class, mirror, "type");
            if (type != null) {
                NodeFieldData field = new NodeFieldData(typeElement, mirror, new CodeVariableElement(type, name), true);
                if (name.isEmpty()) {
                    field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Field name cannot be empty.");
                } else if (names.contains(name)) {
                    field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Duplicate field name '%s'.", name);
                }
                names.add(name);
                fields.add(field);
            } else {
            // Type is null here. This indicates that the type could not be resolved.
            // The Java compiler will subsequently raise the appropriate error.
            }
        }
    }
    for (NodeFieldData nodeFieldData : fields) {
        nodeFieldData.setGetter(findGetter(elements, nodeFieldData.getName(), nodeFieldData.getType()));
    }
    return fields;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) AnnotationMirror(javax.lang.model.element.AnnotationMirror) NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) HashSet(java.util.HashSet)

Example 4 with NodeFieldData

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

the class NodeParser method initializeExpressions.

private void initializeExpressions(List<? extends Element> elements, NodeData node) {
    List<Element> members = filterNotAccessibleElements(node.getTemplateType(), elements);
    List<VariableElement> fields = new ArrayList<>();
    for (NodeFieldData field : node.getFields()) {
        fields.add(field.getVariable());
    }
    for (SpecializationData specialization : node.getSpecializations()) {
        if (specialization.getMethod() == null) {
            continue;
        }
        List<Element> specializationMembers = new ArrayList<>(members.size() + specialization.getParameters().size() + fields.size());
        for (Parameter p : specialization.getParameters()) {
            specializationMembers.add(p.getVariableElement());
        }
        specializationMembers.addAll(fields);
        specializationMembers.addAll(members);
        DSLExpressionResolver resolver = new DSLExpressionResolver(context, specializationMembers);
        initializeCaches(specialization, resolver);
        initializeGuards(specialization, resolver);
        if (specialization.hasErrors()) {
            continue;
        }
        initializeLimit(specialization, resolver);
        initializeAssumptions(specialization, resolver);
    }
}
Also used : NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) TypeElement(javax.lang.model.element.TypeElement) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) DSLExpressionResolver(com.oracle.truffle.dsl.processor.expression.DSLExpressionResolver)

Example 5 with NodeFieldData

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

the class NodeMethodParser method addDefaultFieldMethodSpec.

protected void addDefaultFieldMethodSpec(MethodSpec methodSpec) {
    for (NodeFieldData field : getNode().getFields()) {
        if (field.getGetter() == null) {
            ParameterSpec spec = new ParameterSpec(field.getName(), field.getType());
            spec.setLocal(true);
            methodSpec.addOptional(spec);
        }
    }
}
Also used : NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) ParameterSpec(com.oracle.truffle.dsl.processor.model.ParameterSpec)

Aggregations

NodeFieldData (com.oracle.truffle.dsl.processor.model.NodeFieldData)6 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)5 ArrayList (java.util.ArrayList)5 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)4 ExecutableElement (javax.lang.model.element.ExecutableElement)4 VariableElement (javax.lang.model.element.VariableElement)4 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)3 NodeChildData (com.oracle.truffle.dsl.processor.model.NodeChildData)3 TypeElement (javax.lang.model.element.TypeElement)3 TypeMirror (javax.lang.model.type.TypeMirror)3 NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)2 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)2 HashSet (java.util.HashSet)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 Element (javax.lang.model.element.Element)2 Child (com.oracle.truffle.api.nodes.Node.Child)1 NodeInfo (com.oracle.truffle.api.nodes.NodeInfo)1 DSLExpressionResolver (com.oracle.truffle.dsl.processor.expression.DSLExpressionResolver)1 CodeTypeElement (com.oracle.truffle.dsl.processor.java.model.CodeTypeElement)1 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)1