changeset 9227:6d92fdf1c999

Fixes several minor issues.
author Christian Humer <christian.humer@gmail.com>
date Mon, 22 Apr 2013 12:52:00 +0200
parents e27f125147d6
children bc82cde765b9
files graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ProcessorContext.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeChildData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java
diffstat 9 files changed, 157 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ProcessorContext.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ProcessorContext.java	Mon Apr 22 12:52:00 2013 +0200
@@ -29,7 +29,9 @@
 import javax.annotation.processing.*;
 import javax.lang.model.element.*;
 import javax.lang.model.type.*;
+import javax.lang.model.util.*;
 
+import com.oracle.truffle.codegen.processor.ast.*;
 import com.oracle.truffle.codegen.processor.ast.CodeTypeMirror.ArrayCodeTypeMirror;
 import com.oracle.truffle.codegen.processor.template.*;
 
@@ -185,4 +187,26 @@
 
     }
 
+    public TypeMirror reloadTypeElement(TypeElement type) {
+        return getType(type.getQualifiedName().toString());
+    }
+
+    public TypeMirror reloadType(TypeMirror type) {
+        if (type instanceof CodeTypeMirror) {
+            return type;
+        } else if (type.getKind().isPrimitive()) {
+            return type;
+        }
+        Types types = getEnvironment().getTypeUtils();
+
+        switch (type.getKind()) {
+            case ARRAY:
+                return types.getArrayType(reloadType(((ArrayType) type).getComponentType()));
+            case WILDCARD:
+                return types.getWildcardType(((WildcardType) type).getExtendsBound(), ((WildcardType) type).getSuperBound());
+            case DECLARED:
+                return reloadTypeElement((TypeElement) (((DeclaredType) type).asElement()));
+        }
+        return type;
+    }
 }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java	Mon Apr 22 12:52:00 2013 +0200
@@ -145,33 +145,100 @@
         }
     }
 
-    /**
-     * True if t1 is assignable to t2.
-     */
-    public static boolean isAssignable(TypeMirror t1, TypeMirror t2) {
-        if (typeEquals(t1, t2)) {
+    public static boolean isAssignable(ProcessorContext context, TypeMirror from, TypeMirror to) {
+        if (!(from instanceof CodeTypeMirror) && !(to instanceof CodeTypeMirror)) {
+            return context.getEnvironment().getTypeUtils().isAssignable(context.reloadType(from), context.reloadType(to));
+        } else {
+            return isAssignableImpl(context, from, to);
+        }
+    }
+
+    private static boolean isAssignableImpl(ProcessorContext context, TypeMirror from, TypeMirror to) {
+        // JLS 5.1.1 identity conversion
+        if (Utils.typeEquals(from, to)) {
             return true;
         }
-        if (isPrimitive(t1) || isPrimitive(t2)) {
-            // non-equal primitive types
+
+        // JLS 5.1.2 widening primitives
+        if (Utils.isPrimitive(from) && Utils.isPrimitive(to)) {
+            TypeKind fromKind = from.getKind();
+            TypeKind toKind = to.getKind();
+            switch (fromKind) {
+                case BYTE:
+                    switch (toKind) {
+                        case SHORT:
+                        case INT:
+                        case LONG:
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case SHORT:
+                    switch (toKind) {
+                        case INT:
+                        case LONG:
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case CHAR:
+                    switch (toKind) {
+                        case INT:
+                        case LONG:
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case INT:
+                    switch (toKind) {
+                        case LONG:
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case LONG:
+                    switch (toKind) {
+                        case FLOAT:
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+                case FLOAT:
+                    switch (toKind) {
+                        case DOUBLE:
+                            return true;
+                    }
+                    break;
+
+            }
             return false;
-        }
-        if (t1 instanceof ArrayType && t2 instanceof ArrayType) {
-            return isAssignable(((ArrayType) t1).getComponentType(), ((ArrayType) t2).getComponentType());
-        }
-
-        TypeElement e1 = fromTypeMirror(t1);
-        TypeElement e2 = fromTypeMirror(t2);
-        if (e1 == null || e2 == null) {
+        } else if (Utils.isPrimitive(from) || Utils.isPrimitive(to)) {
             return false;
         }
 
-        List<TypeElement> superTypes = getSuperTypes(e1);
+        if (from instanceof ArrayType && to instanceof ArrayType) {
+            return isAssignable(context, ((ArrayType) from).getComponentType(), ((ArrayType) to).getComponentType());
+        }
+
+        TypeElement fromType = Utils.fromTypeMirror(from);
+        TypeElement toType = Utils.fromTypeMirror(to);
+        if (fromType == null || toType == null) {
+            return false;
+        }
+        // JLS 5.1.6 narrowing reference conversion
+
+        List<TypeElement> superTypes = Utils.getSuperTypes(fromType);
         for (TypeElement superType : superTypes) {
-            if (typeEquals(superType.asType(), t2)) {
+            if (Utils.typeEquals(superType.asType(), to)) {
                 return true;
             }
         }
+
+        // TODO more spec
         return false;
     }
 
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeChildData.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeChildData.java	Mon Apr 22 12:52:00 2013 +0200
@@ -82,7 +82,9 @@
 
     void setNode(NodeData nodeData) {
         this.nodeData = nodeData;
-        getMessages().addAll(nodeData.collectMessages());
+        if (nodeData != null) {
+            getMessages().addAll(nodeData.collectMessages());
+        }
     }
 
     public Element getAccessElement() {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Mon Apr 22 12:52:00 2013 +0200
@@ -137,7 +137,7 @@
         }
     }
 
-    private static CodeTree createTemplateMethodCall(CodeTreeBuilder parent, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName) {
+    private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName) {
         CodeTreeBuilder builder = parent.create();
 
         boolean castedValues = sourceMethod != targetMethod;
@@ -150,7 +150,7 @@
         TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement());
         NodeData node = (NodeData) targetMethod.getTemplate();
 
-        boolean accessible = targetMethod.canBeAccessedByInstanceOf(node.getNodeType());
+        boolean accessible = targetMethod.canBeAccessedByInstanceOf(getContext(), node.getNodeType());
         if (accessible) {
             if (builder.findMethod().getModifiers().contains(STATIC)) {
                 if (method.getModifiers().contains(STATIC)) {
@@ -353,7 +353,7 @@
         return builder.getRoot();
     }
 
-    private static CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
+    private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
         String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
         if (guardedSpecialization.getGuards().size() > 0) {
@@ -568,6 +568,14 @@
 
             for (NodeChildData child : node.getChildren()) {
                 clazz.add(createChildField(child));
+
+                if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) {
+                    ExecutableElement getter = (ExecutableElement) child.getAccessElement();
+                    CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), getter);
+                    method.getModifiers().remove(Modifier.ABSTRACT);
+                    method.createBuilder().startReturn().string("this.").string(child.getName()).end();
+                    clazz.add(method);
+                }
             }
 
             createConstructors(node, clazz);
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Mon Apr 22 12:52:00 2013 +0200
@@ -115,8 +115,11 @@
         if (shortCircuits != null) {
             containerChildren.addAll(shortCircuits);
         }
-        if (containerChildren != null) {
-            containerChildren.addAll(containerChildren);
+        if (children != null) {
+            containerChildren.addAll(children);
+        }
+        if (fields != null) {
+            containerChildren.addAll(fields);
         }
         return containerChildren;
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeMethodParser.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeMethodParser.java	Mon Apr 22 12:52:00 2013 +0200
@@ -123,7 +123,7 @@
     protected void resolveAndAddImplicitThis(MethodSpec methodSpec, ExecutableElement method) {
         TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType();
 
-        if (!method.getModifiers().contains(Modifier.STATIC) && !Utils.isAssignable(declaredType, getContext().getTruffleTypes().getNode())) {
+        if (!method.getModifiers().contains(Modifier.STATIC) && !Utils.isAssignable(getContext(), declaredType, getContext().getTruffleTypes().getNode())) {
             methodSpec.addImplicitRequiredType(getNode().getTemplateType().asType());
         }
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Mon Apr 22 12:52:00 2013 +0200
@@ -41,7 +41,7 @@
 public class NodeParser extends TemplateParser<NodeData> {
 
     public static final List<Class<? extends Annotation>> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, SpecializationListener.class,
-                    ExecuteChildren.class, NodeClass.class, NodeId.class);
+                    ExecuteChildren.class, NodeClass.class, NodeChild.class, NodeChildren.class, NodeId.class);
 
     private Map<String, NodeData> parsedNodes;
 
@@ -120,23 +120,21 @@
         return rootNode;
     }
 
-    private NodeData parseNode(TypeElement templateType) {
-        if (Utils.findAnnotationMirror(processingEnv, templateType, GeneratedBy.class) != null) {
+    private NodeData parseNode(TypeElement originalTemplateType) {
+        // reloading the type elements is needed for ecj
+        TypeElement templateType = Utils.fromTypeMirror(context.reloadTypeElement(originalTemplateType));
+
+        if (Utils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) {
             // generated nodes should not get called again.
             return null;
         }
 
-        AnnotationMirror methodNodes = Utils.findAnnotationMirror(processingEnv, templateType, NodeClass.class);
-        if (methodNodes == null && !Utils.isAssignable(templateType.asType(), context.getTruffleTypes().getNode())) {
-            return null; // not a node
-        }
-
         List<TypeElement> lookupTypes = findSuperClasses(new ArrayList<TypeElement>(), templateType);
         Collections.reverse(lookupTypes);
 
         AnnotationMirror nodeClass = findFirstAnnotation(lookupTypes, NodeClass.class);
         TypeMirror nodeType = null;
-        if (Utils.isAssignable(templateType.asType(), context.getTruffleTypes().getNode())) {
+        if (Utils.isAssignable(context, templateType.asType(), context.getTruffleTypes().getNode())) {
             nodeType = templateType.asType();
         }
         if (nodeClass != null) {
@@ -144,8 +142,13 @@
         }
 
         if (nodeType == null) {
-            // FIXME error
-            return null;
+            if (nodeClass == null) {
+                // no node
+                return null;
+            } else {
+                // FIXME nodeType not specified error
+                return null;
+            }
         }
 
         Set<Element> elementSet = new HashSet<>(context.getEnvironment().getElementUtils().getAllMembers(templateType));
@@ -323,7 +326,12 @@
                     assert paramType != null;
                     actualType = paramType.getType();
                 }
-                parameters.add(new ActualParameter(parameterSpec, actualType, specializationParameter.getIndex(), specializationParameter.isImplicit()));
+
+                if (actualType != null) {
+                    parameters.add(new ActualParameter(parameterSpec, actualType, specializationParameter.getIndex(), specializationParameter.isImplicit()));
+                } else {
+                    parameters.add(new ActualParameter(parameterSpec, specializationParameter.getType(), specializationParameter.getIndex(), specializationParameter.isImplicit()));
+                }
             }
             TemplateMethod genericMethod = new TemplateMethod("Generic", node, specification, null, null, returnType, parameters);
             genericSpecialization = new SpecializationData(genericMethod, true, false);
@@ -544,7 +552,7 @@
         TypeMirror typeSytemType = Utils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
         final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSytemType, true);
         if (typeSystem == null) {
-            nodeData.addError("The used type system '%s' is invalid.", Utils.getQualifiedName(typeSytemType));
+            nodeData.addError("The used type system '%s' is invalid or not a Node.", Utils.getQualifiedName(typeSytemType));
             return nodeData;
         }
 
@@ -562,7 +570,7 @@
         parsedNodes.put(Utils.getQualifiedName(templateType), nodeData);
 
         // parseChildren invokes cyclic parsing.
-        nodeData.setChildren(parseChildren(elements, lookupTypes));
+        nodeData.setChildren(parseChildren(templateType, elements, lookupTypes));
 
         return nodeData;
     }
@@ -699,7 +707,7 @@
         return fields;
     }
 
-    private List<NodeChildData> parseChildren(List<? extends Element> elements, final List<TypeElement> typeHierarchy) {
+    private List<NodeChildData> parseChildren(TypeElement templateType, List<? extends Element> elements, final List<TypeElement> typeHierarchy) {
         Set<String> shortCircuits = new HashSet<>();
         for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
             AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class);
@@ -716,7 +724,7 @@
             AnnotationMirror nodeChildrenMirror = Utils.findAnnotationMirror(processingEnv, type, NodeChildren.class);
 
             TypeMirror nodeClassType = type.getSuperclass();
-            if (!Utils.isAssignable(nodeClassType, context.getTruffleTypes().getNode())) {
+            if (!Utils.isAssignable(context, nodeClassType, context.getTruffleTypes().getNode())) {
                 nodeClassType = null;
             }
 
@@ -742,7 +750,7 @@
                     kind = ExecutionKind.SHORT_CIRCUIT;
                 }
 
-                NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, getter, cardinality, kind);
+                NodeChildData nodeChild = new NodeChildData(templateType, childMirror, name, childType, getter, cardinality, kind);
 
                 parsedChildren.add(nodeChild);
 
@@ -753,9 +761,8 @@
 
                 NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(childType));
                 nodeChild.setNode(fieldNodeData);
-
                 if (fieldNodeData == null) {
-                    nodeChild.addError("Node type '%s' is invalid.", Utils.getQualifiedName(type));
+                    nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(childType));
                 } else if (fieldNodeData.findGenericExecutableTypes(context).isEmpty()) {
                     nodeChild.addError("No executable generic types found for node '%s'.", Utils.getQualifiedName(type));
                 }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java	Mon Apr 22 12:52:00 2013 +0200
@@ -75,7 +75,7 @@
             builder.string("this.");
             builder.string(fieldName);
             builder.string(" = ");
-            if (isAssignable(field.asType(), getContext().getTruffleTypes().getNode())) {
+            if (isAssignable(getContext(), field.asType(), getContext().getTruffleTypes().getNode())) {
                 builder.string("adoptChild(").string(fieldName).string(")");
             } else {
                 builder.string(fieldName);
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Sat Apr 20 12:45:07 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Mon Apr 22 12:52:00 2013 +0200
@@ -151,9 +151,9 @@
         return Collections.unmodifiableList(allParameters);
     }
 
-    public boolean canBeAccessedByInstanceOf(TypeMirror type) {
+    public boolean canBeAccessedByInstanceOf(ProcessorContext context, TypeMirror type) {
         TypeMirror methodType = Utils.findNearestEnclosingType(getMethod()).asType();
-        return Utils.isAssignable(type, methodType) || Utils.isAssignable(methodType, type);
+        return Utils.isAssignable(context, type, methodType) || Utils.isAssignable(context, methodType, type);
     }
 
     public ExecutableElement getMethod() {