diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java @ 20938:18c0f02fa4d2

Truffle-DSL: make type systems optional.
author Christian Humer <christian.humer@gmail.com>
date Tue, 14 Apr 2015 15:12:48 +0200
parents 3648df587223
children f83fd99b2962
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java	Tue Apr 14 22:12:03 2015 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java	Tue Apr 14 15:12:48 2015 +0200
@@ -225,8 +225,14 @@
     }
 
     public static boolean isAssignable(TypeMirror from, TypeMirror to) {
+        if (typeEquals(from, to)) {
+            return true;
+        } else if (isVoid(to)) {
+            return true;
+        } else if (isObject(to)) {
+            return true;
+        }
         ProcessorContext context = ProcessorContext.getInstance();
-
         if (!(from instanceof CodeTypeMirror) && !(to instanceof CodeTypeMirror)) {
             return context.getEnvironment().getTypeUtils().isAssignable(context.reloadType(from), context.reloadType(to));
         } else {
@@ -1122,4 +1128,82 @@
             throw new AssertionError("unsupported element type");
         }
     }
+
+    public static List<TypeMirror> sortTypes(List<TypeMirror> list) {
+        Collections.sort(list, new Comparator<TypeMirror>() {
+            public int compare(TypeMirror o1, TypeMirror o2) {
+                return compareType(o1, o2);
+            }
+        });
+        return list;
+    }
+
+    public static int compareType(TypeMirror signature1, TypeMirror signature2) {
+        if (signature1 == null) {
+            return 1;
+        } else if (signature2 == null) {
+            return -1;
+        }
+
+        if (ElementUtils.typeEquals(signature1, signature2)) {
+            return 0;
+        }
+
+        if (signature1.getKind() == TypeKind.DECLARED && signature2.getKind() == TypeKind.DECLARED) {
+            TypeElement element1 = ElementUtils.fromTypeMirror(signature1);
+            TypeElement element2 = ElementUtils.fromTypeMirror(signature2);
+
+            if (ElementUtils.getDirectSuperTypes(element1).contains(element2)) {
+                return -1;
+            } else if (ElementUtils.getDirectSuperTypes(element2).contains(element1)) {
+                return 1;
+            }
+        }
+        return ElementUtils.getSimpleName(signature1).compareTo(ElementUtils.getSimpleName(signature2));
+    }
+
+    public static List<TypeMirror> uniqueSortedTypes(Collection<TypeMirror> types) {
+        if (types.isEmpty()) {
+            return Collections.emptyList();
+        } else if (types.size() <= 1) {
+            if (types instanceof List) {
+                return (List<TypeMirror>) types;
+            } else {
+                return new ArrayList<>(types);
+            }
+        }
+        Map<String, TypeMirror> sourceTypes = new HashMap<>();
+        for (TypeMirror type : types) {
+            sourceTypes.put(ElementUtils.getTypeId(type), type);
+        }
+        return sortTypes(new ArrayList<>(sourceTypes.values()));
+    }
+
+    public static int compareMethod(ExecutableElement method1, ExecutableElement method2) {
+        List<? extends VariableElement> parameters1 = method1.getParameters();
+        List<? extends VariableElement> parameters2 = method2.getParameters();
+        if (parameters1.size() != parameters2.size()) {
+            return Integer.compare(parameters1.size(), parameters2.size());
+        }
+
+        int result = 0;
+        for (int i = 0; i < parameters1.size(); i++) {
+            VariableElement var1 = parameters1.get(i);
+            VariableElement var2 = parameters2.get(i);
+            result = compareType(var1.asType(), var2.asType());
+            if (result != 0) {
+                return result;
+            }
+        }
+
+        result = method1.getSimpleName().toString().compareTo(method2.getSimpleName().toString());
+        if (result == 0) {
+            // if still no difference sort by enclosing type name
+            TypeElement enclosingType1 = ElementUtils.findNearestEnclosingType(method1);
+            TypeElement enclosingType2 = ElementUtils.findNearestEnclosingType(method2);
+            result = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString());
+        }
+        return result;
+    }
+
 }