comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java @ 16753:f78eafd5ba9e

Truffle-DSL: the processor compiler abstraction now supports declaration oder for enclosed elements of types for JDT which is not conforming to specification.
author Christian Humer <christian.humer@gmail.com>
date Mon, 11 Aug 2014 15:53:05 +0200
parents ae6b8ec920e2
children
comparison
equal deleted inserted replaced
16752:0e05342037d7 16753:f78eafd5ba9e
24 24
25 import java.util.*; 25 import java.util.*;
26 26
27 import javax.annotation.processing.*; 27 import javax.annotation.processing.*;
28 import javax.lang.model.element.*; 28 import javax.lang.model.element.*;
29 import javax.lang.model.type.*;
29 30
30 import com.oracle.truffle.dsl.processor.*; 31 import com.oracle.truffle.dsl.processor.*;
31 32
32 public class JDTCompiler extends AbstractCompiler { 33 public class JDTCompiler extends AbstractCompiler {
33 34
38 } catch (ClassNotFoundException e) { 39 } catch (ClassNotFoundException e) {
39 return false; 40 return false;
40 } 41 }
41 } 42 }
42 43
43 public List<? extends Element> getEnclosedElementsDeclarationOrder(TypeElement type) { 44 public List<? extends Element> getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type) {
44 try { 45 return sortBySourceOrder(new ArrayList<>(environment.getElementUtils().getAllMembers(type)));
45 Object binding = field(type, "_binding"); 46 }
46 47
47 Class<?> sourceTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding"); 48 public List<? extends Element> getEnclosedElementsInDeclarationOrder(TypeElement type) {
48 49 return sortBySourceOrder(new ArrayList<>(type.getEnclosedElements()));
49 final List<Object> declarationOrder; 50 }
50 if (sourceTypeBinding.isAssignableFrom(binding.getClass())) { 51
51 declarationOrder = findSourceOrder(binding); 52 private static List<? extends Element> sortBySourceOrder(List<Element> elements) {
52 } else { 53 final Map<TypeElement, List<Object>> declarationOrders = new HashMap<>();
53 return null; 54
54 } 55 Collections.sort(elements, new Comparator<Element>() {
55 56 public int compare(Element o1, Element o2) {
56 List<Element> enclosedElements = new ArrayList<>(type.getEnclosedElements()); 57 try {
57 Collections.sort(enclosedElements, new Comparator<Element>() { 58 TypeMirror enclosing1 = o1.getEnclosingElement().asType();
58 59 TypeMirror enclosing2 = o2.getEnclosingElement().asType();
59 public int compare(Element o1, Element o2) { 60
60 try { 61 if (Utils.typeEquals(enclosing1, enclosing2)) {
62 List<Object> declarationOrder = lookupDeclarationOrder(declarationOrders, (TypeElement) o1.getEnclosingElement());
63 if (declarationOrder == null) {
64 return 0;
65 }
61 Object o1Binding = field(o1, "_binding"); 66 Object o1Binding = field(o1, "_binding");
62 Object o2Binding = field(o2, "_binding"); 67 Object o2Binding = field(o2, "_binding");
63 68
64 int i1 = declarationOrder.indexOf(o1Binding); 69 int i1 = declarationOrder.indexOf(o1Binding);
65 int i2 = declarationOrder.indexOf(o2Binding); 70 int i2 = declarationOrder.indexOf(o2Binding);
66 71
67 return i1 - i2; 72 return i1 - i2;
68 } catch (Exception e) { 73 } else {
69 return 0; 74 if (Utils.isSubtype(enclosing1, enclosing2)) {
75 return 1;
76 } else if (Utils.isSubtype(enclosing2, enclosing1)) {
77 return -1;
78 } else {
79 return 0;
80 }
70 } 81 }
71 } 82 } catch (Exception e) {
72 83 throw new RuntimeException(e);
73 }); 84 }
74 return enclosedElements; 85 }
75 } catch (Exception e) { 86 });
76 return null; 87 return elements;
77 } 88 }
78 } 89
79 90 private static List<Object> lookupDeclarationOrder(Map<TypeElement, List<Object>> declarationOrders, TypeElement type) throws Exception, ClassNotFoundException {
80 private static List<Object> findSourceOrder(Object binding) throws Exception { 91 if (declarationOrders.containsKey(type)) {
92 return declarationOrders.get(type);
93 }
94
95 Object binding = field(type, "_binding");
96 Class<?> sourceTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding");
97 Class<?> binaryTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding");
98
99 List<Object> declarationOrder = null;
100 if (sourceTypeBinding.isAssignableFrom(binding.getClass())) {
101 declarationOrder = findSourceTypeOrder(binding);
102 } else if (binaryTypeBinding.isAssignableFrom(binding.getClass())) {
103 declarationOrder = findBinaryTypeOrder(binding);
104 }
105
106 declarationOrders.put(type, declarationOrder);
107
108 return declarationOrder;
109 }
110
111 private static List<Object> findBinaryTypeOrder(Object binding) throws Exception {
112 Object binaryType = lookupBinaryType(binding);
113 final Object[] sortedMethods = (Object[]) method(binaryType, "getMethods");
114
115 List<Object> sortedElements = new ArrayList<>();
116 if (sortedMethods != null) {
117 sortedElements.addAll(Arrays.asList(sortedMethods));
118 }
119 final Object[] sortedFields = (Object[]) method(binaryType, "getFields");
120 if (sortedFields != null) {
121 sortedElements.addAll(Arrays.asList(sortedFields));
122 }
123 final Object[] sortedTypes = (Object[]) method(binaryType, "getMemberTypes", new Class[0]);
124 if (sortedTypes != null) {
125 sortedElements.addAll(Arrays.asList(sortedTypes));
126 }
127
128 Collections.sort(sortedElements, new Comparator<Object>() {
129 public int compare(Object o1, Object o2) {
130 try {
131 int structOffset1 = (int) field(o1, "structOffset");
132 int structOffset2 = (int) field(o2, "structOffset");
133 return structOffset1 - structOffset2;
134 } catch (Exception e) {
135 throw new RuntimeException(e);
136 }
137 }
138 });
139
140 Class<?> binaryMethod = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryMethod");
141 Class<?> binaryField = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryField");
142 Class<?> nestedType = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryNestedType");
143
144 List<Object> bindings = new ArrayList<>();
145 for (Object sortedElement : sortedElements) {
146 Class<?> elementClass = sortedElement.getClass();
147 if (binaryMethod.isAssignableFrom(elementClass)) {
148 char[] selector = (char[]) method(sortedElement, "getSelector");
149 Object[] foundBindings = (Object[]) method(binding, "getMethods", new Class[]{char[].class}, selector);
150 if (foundBindings == null || foundBindings.length == 0) {
151 continue;
152 } else if (foundBindings.length == 1) {
153 bindings.add(foundBindings[0]);
154 } else {
155 char[] idescriptor = (char[]) method(sortedElement, "getMethodDescriptor");
156 for (Object foundBinding : foundBindings) {
157 char[] descriptor = (char[]) method(foundBinding, "signature");
158 if (descriptor == null && idescriptor == null || Arrays.equals(descriptor, idescriptor)) {
159 bindings.add(foundBinding);
160 break;
161 }
162 }
163 }
164 } else if (binaryField.isAssignableFrom(elementClass)) {
165 char[] selector = (char[]) method(sortedElement, "getName");
166 Object foundField = method(binding, "getField", new Class[]{char[].class, boolean.class}, selector, true);
167 if (foundField != null) {
168 bindings.add(foundField);
169 }
170 } else if (nestedType.isAssignableFrom(elementClass)) {
171 char[] selector = (char[]) method(sortedElement, "getSourceName");
172 Object foundType = method(binding, "getMemberType", new Class[]{char[].class}, selector);
173 if (foundType != null) {
174 bindings.add(foundType);
175 }
176 } else {
177 throw new AssertionError("Unexpected encountered type " + elementClass);
178 }
179 }
180
181 return bindings;
182 }
183
184 private static Object lookupBinaryType(Object binding) throws Exception {
185 Object lookupEnvironment = field(binding, "environment");
186 Object compoundClassName = field(binding, "compoundName");
187 Object nameEnvironment = field(lookupEnvironment, "nameEnvironment");
188 Object nameEnvironmentAnswer = method(nameEnvironment, "findType", new Class[]{char[][].class}, compoundClassName);
189 Object binaryType = method(nameEnvironmentAnswer, "getBinaryType", new Class[0]);
190 return binaryType;
191 }
192
193 private static List<Object> findSourceTypeOrder(Object binding) throws Exception {
81 Object referenceContext = field(field(binding, "scope"), "referenceContext"); 194 Object referenceContext = field(field(binding, "scope"), "referenceContext");
82 195
83 TreeMap<Integer, Object> orderedBindings = new TreeMap<>(); 196 TreeMap<Integer, Object> orderedBindings = new TreeMap<>();
84 197
85 collectSourceOrder(orderedBindings, referenceContext, "methods"); 198 collectSourceOrder(orderedBindings, referenceContext, "methods");