# HG changeset patch # User Christian Humer # Date 1407765185 -7200 # Node ID f78eafd5ba9e80846996463332b9698b3f547687 # Parent 0e05342037d7b384c70c27ba948118903b4362d8 Truffle-DSL: the processor compiler abstraction now supports declaration oder for enclosed elements of types for JDT which is not conforming to specification. diff -r 0e05342037d7 -r f78eafd5ba9e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java Mon Aug 11 15:53:05 2014 +0200 @@ -42,7 +42,23 @@ if (o == null) { return null; } - Field field = o.getClass().getField(fieldName); + Class clazz = o.getClass(); + Field field = null; + try { + field = clazz.getField(fieldName); + } catch (NoSuchFieldException e) { + while (clazz != null) { + try { + field = clazz.getDeclaredField(fieldName); + break; + } catch (NoSuchFieldException e1) { + clazz = clazz.getSuperclass(); + } + } + if (field == null) { + throw e; + } + } field.setAccessible(true); return field.get(o); } diff -r 0e05342037d7 -r f78eafd5ba9e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/Compiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/Compiler.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/Compiler.java Mon Aug 11 15:53:05 2014 +0200 @@ -33,6 +33,8 @@ String getHeaderComment(ProcessingEnvironment env, Element type); - List getEnclosedElementsDeclarationOrder(TypeElement type); + List getEnclosedElementsInDeclarationOrder(TypeElement type); + + List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type); } diff -r 0e05342037d7 -r f78eafd5ba9e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java Mon Aug 11 15:53:05 2014 +0200 @@ -26,6 +26,7 @@ import javax.annotation.processing.*; import javax.lang.model.element.*; +import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; @@ -40,24 +41,28 @@ } } - public List getEnclosedElementsDeclarationOrder(TypeElement type) { - try { - Object binding = field(type, "_binding"); + public List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type) { + return sortBySourceOrder(new ArrayList<>(environment.getElementUtils().getAllMembers(type))); + } - Class sourceTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding"); + public List getEnclosedElementsInDeclarationOrder(TypeElement type) { + return sortBySourceOrder(new ArrayList<>(type.getEnclosedElements())); + } + + private static List sortBySourceOrder(List elements) { + final Map> declarationOrders = new HashMap<>(); - final List declarationOrder; - if (sourceTypeBinding.isAssignableFrom(binding.getClass())) { - declarationOrder = findSourceOrder(binding); - } else { - return null; - } + Collections.sort(elements, new Comparator() { + public int compare(Element o1, Element o2) { + try { + TypeMirror enclosing1 = o1.getEnclosingElement().asType(); + TypeMirror enclosing2 = o2.getEnclosingElement().asType(); - List enclosedElements = new ArrayList<>(type.getEnclosedElements()); - Collections.sort(enclosedElements, new Comparator() { - - public int compare(Element o1, Element o2) { - try { + if (Utils.typeEquals(enclosing1, enclosing2)) { + List declarationOrder = lookupDeclarationOrder(declarationOrders, (TypeElement) o1.getEnclosingElement()); + if (declarationOrder == null) { + return 0; + } Object o1Binding = field(o1, "_binding"); Object o2Binding = field(o2, "_binding"); @@ -65,19 +70,127 @@ int i2 = declarationOrder.indexOf(o2Binding); return i1 - i2; - } catch (Exception e) { - return 0; + } else { + if (Utils.isSubtype(enclosing1, enclosing2)) { + return 1; + } else if (Utils.isSubtype(enclosing2, enclosing1)) { + return -1; + } else { + return 0; + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + return elements; + } + + private static List lookupDeclarationOrder(Map> declarationOrders, TypeElement type) throws Exception, ClassNotFoundException { + if (declarationOrders.containsKey(type)) { + return declarationOrders.get(type); + } + + Object binding = field(type, "_binding"); + Class sourceTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding"); + Class binaryTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding"); + + List declarationOrder = null; + if (sourceTypeBinding.isAssignableFrom(binding.getClass())) { + declarationOrder = findSourceTypeOrder(binding); + } else if (binaryTypeBinding.isAssignableFrom(binding.getClass())) { + declarationOrder = findBinaryTypeOrder(binding); + } + + declarationOrders.put(type, declarationOrder); + + return declarationOrder; + } + + private static List findBinaryTypeOrder(Object binding) throws Exception { + Object binaryType = lookupBinaryType(binding); + final Object[] sortedMethods = (Object[]) method(binaryType, "getMethods"); + + List sortedElements = new ArrayList<>(); + if (sortedMethods != null) { + sortedElements.addAll(Arrays.asList(sortedMethods)); + } + final Object[] sortedFields = (Object[]) method(binaryType, "getFields"); + if (sortedFields != null) { + sortedElements.addAll(Arrays.asList(sortedFields)); + } + final Object[] sortedTypes = (Object[]) method(binaryType, "getMemberTypes", new Class[0]); + if (sortedTypes != null) { + sortedElements.addAll(Arrays.asList(sortedTypes)); + } + + Collections.sort(sortedElements, new Comparator() { + public int compare(Object o1, Object o2) { + try { + int structOffset1 = (int) field(o1, "structOffset"); + int structOffset2 = (int) field(o2, "structOffset"); + return structOffset1 - structOffset2; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + + Class binaryMethod = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryMethod"); + Class binaryField = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryField"); + Class nestedType = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryNestedType"); + + List bindings = new ArrayList<>(); + for (Object sortedElement : sortedElements) { + Class elementClass = sortedElement.getClass(); + if (binaryMethod.isAssignableFrom(elementClass)) { + char[] selector = (char[]) method(sortedElement, "getSelector"); + Object[] foundBindings = (Object[]) method(binding, "getMethods", new Class[]{char[].class}, selector); + if (foundBindings == null || foundBindings.length == 0) { + continue; + } else if (foundBindings.length == 1) { + bindings.add(foundBindings[0]); + } else { + char[] idescriptor = (char[]) method(sortedElement, "getMethodDescriptor"); + for (Object foundBinding : foundBindings) { + char[] descriptor = (char[]) method(foundBinding, "signature"); + if (descriptor == null && idescriptor == null || Arrays.equals(descriptor, idescriptor)) { + bindings.add(foundBinding); + break; + } } } + } else if (binaryField.isAssignableFrom(elementClass)) { + char[] selector = (char[]) method(sortedElement, "getName"); + Object foundField = method(binding, "getField", new Class[]{char[].class, boolean.class}, selector, true); + if (foundField != null) { + bindings.add(foundField); + } + } else if (nestedType.isAssignableFrom(elementClass)) { + char[] selector = (char[]) method(sortedElement, "getSourceName"); + Object foundType = method(binding, "getMemberType", new Class[]{char[].class}, selector); + if (foundType != null) { + bindings.add(foundType); + } + } else { + throw new AssertionError("Unexpected encountered type " + elementClass); + } + } - }); - return enclosedElements; - } catch (Exception e) { - return null; - } + return bindings; } - private static List findSourceOrder(Object binding) throws Exception { + private static Object lookupBinaryType(Object binding) throws Exception { + Object lookupEnvironment = field(binding, "environment"); + Object compoundClassName = field(binding, "compoundName"); + Object nameEnvironment = field(lookupEnvironment, "nameEnvironment"); + Object nameEnvironmentAnswer = method(nameEnvironment, "findType", new Class[]{char[][].class}, compoundClassName); + Object binaryType = method(nameEnvironmentAnswer, "getBinaryType", new Class[0]); + return binaryType; + } + + private static List findSourceTypeOrder(Object binding) throws Exception { Object referenceContext = field(field(binding, "scope"), "referenceContext"); TreeMap orderedBindings = new TreeMap<>(); diff -r 0e05342037d7 -r f78eafd5ba9e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java Mon Aug 11 15:53:05 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java Mon Aug 11 15:53:05 2014 +0200 @@ -40,10 +40,14 @@ } } - public List getEnclosedElementsDeclarationOrder(TypeElement type) { + public List getEnclosedElementsInDeclarationOrder(TypeElement type) { return type.getEnclosedElements(); } + public List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type) { + return environment.getElementUtils().getAllMembers(type); + } + private static final Class[] getTreeAndTopLevelSignature = new Class[]{Element.class, AnnotationMirror.class, AnnotationValue.class}; private static final Class[] getCharContentSignature = new Class[]{boolean.class};