comparison truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java @ 22516:687bc1dda125

Truffle-DSL: fix wrong resolution when multiple public static methods are imported from a cached type.
author Christian Humer <christian.humer@oracle.com>
date Fri, 18 Dec 2015 14:41:06 +0100
parents 4a43dc00a654
children
comparison
equal deleted inserted replaced
22515:d51cc0af8612 22516:687bc1dda125
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any 20 * or visit www.oracle.com if you need additional information or have any
21 * questions. 21 * questions.
22 */ 22 */
23 package com.oracle.truffle.dsl.processor.parser; 23 package com.oracle.truffle.dsl.processor.parser;
24
25 import java.lang.annotation.Annotation;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Comparator;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.ListIterator;
36 import java.util.Map;
37 import java.util.Objects;
38 import java.util.Set;
39
40 import javax.lang.model.element.AnnotationMirror;
41 import javax.lang.model.element.AnnotationValue;
42 import javax.lang.model.element.Element;
43 import javax.lang.model.element.ElementKind;
44 import javax.lang.model.element.ExecutableElement;
45 import javax.lang.model.element.Modifier;
46 import javax.lang.model.element.TypeElement;
47 import javax.lang.model.element.VariableElement;
48 import javax.lang.model.type.DeclaredType;
49 import javax.lang.model.type.TypeKind;
50 import javax.lang.model.type.TypeMirror;
51 import javax.lang.model.util.ElementFilter;
52 import javax.tools.Diagnostic.Kind;
24 53
25 import com.oracle.truffle.api.Assumption; 54 import com.oracle.truffle.api.Assumption;
26 import com.oracle.truffle.api.dsl.Cached; 55 import com.oracle.truffle.api.dsl.Cached;
27 import com.oracle.truffle.api.dsl.CreateCast; 56 import com.oracle.truffle.api.dsl.CreateCast;
28 import com.oracle.truffle.api.dsl.Fallback; 57 import com.oracle.truffle.api.dsl.Fallback;
65 import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind; 94 import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind;
66 import com.oracle.truffle.dsl.processor.model.SpecializationThrowsData; 95 import com.oracle.truffle.dsl.processor.model.SpecializationThrowsData;
67 import com.oracle.truffle.dsl.processor.model.TemplateMethod; 96 import com.oracle.truffle.dsl.processor.model.TemplateMethod;
68 import com.oracle.truffle.dsl.processor.model.TypeSystemData; 97 import com.oracle.truffle.dsl.processor.model.TypeSystemData;
69 98
70 import java.lang.annotation.Annotation;
71 import java.util.ArrayList;
72 import java.util.Arrays;
73 import java.util.Collection;
74 import java.util.Collections;
75 import java.util.HashMap;
76 import java.util.HashSet;
77 import java.util.Iterator;
78 import java.util.List;
79 import java.util.ListIterator;
80 import java.util.Map;
81 import java.util.Objects;
82 import java.util.Set;
83
84 import javax.lang.model.element.AnnotationMirror;
85 import javax.lang.model.element.AnnotationValue;
86 import javax.lang.model.element.Element;
87 import javax.lang.model.element.ElementKind;
88 import javax.lang.model.element.ExecutableElement;
89 import javax.lang.model.element.Modifier;
90 import javax.lang.model.element.TypeElement;
91 import javax.lang.model.element.VariableElement;
92 import javax.lang.model.type.DeclaredType;
93 import javax.lang.model.type.TypeKind;
94 import javax.lang.model.type.TypeMirror;
95 import javax.lang.model.util.ElementFilter;
96 import javax.tools.Diagnostic.Kind;
97
98 @DSLOptions 99 @DSLOptions
99 public class NodeParser extends AbstractParser<NodeData> { 100 public class NodeParser extends AbstractParser<NodeData> {
100 101
101 public static final List<Class<? extends Annotation>> ANNOTATIONS = Arrays.asList(Fallback.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, NodeChild.class, 102 public static final List<Class<? extends Annotation>> ANNOTATIONS = Arrays.asList(Fallback.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, NodeChild.class,
102 NodeChildren.class); 103 NodeChildren.class);
352 // hack to reload type is necessary for incremental compiling in eclipse. 353 // hack to reload type is necessary for incremental compiling in eclipse.
353 // otherwise methods inside of import guard types are just not found. 354 // otherwise methods inside of import guard types are just not found.
354 TypeElement typeElement = ElementUtils.fromTypeMirror(context.reloadType(importGuardClass.asType())); 355 TypeElement typeElement = ElementUtils.fromTypeMirror(context.reloadType(importGuardClass.asType()));
355 356
356 List<Element> members = new ArrayList<>(); 357 List<Element> members = new ArrayList<>();
358
357 for (Element importElement : processingEnv.getElementUtils().getAllMembers(typeElement)) { 359 for (Element importElement : processingEnv.getElementUtils().getAllMembers(typeElement)) {
358 if (!importElement.getModifiers().contains(Modifier.PUBLIC)) { 360 if (!importElement.getModifiers().contains(Modifier.PUBLIC)) {
359 continue; 361 continue;
360 } 362 }
361 363
370 ElementKind kind = importElement.getKind(); 372 ElementKind kind = importElement.getKind();
371 if (kind.isField() || kind == ElementKind.METHOD) { 373 if (kind.isField() || kind == ElementKind.METHOD) {
372 members.add(importElement); 374 members.add(importElement);
373 } 375 }
374 } 376 }
377
378 /*
379 * Sort elements by enclosing type to ensure that duplicate static methods are used from the
380 * most concrete subtype.
381 */
382 Collections.sort(members, new Comparator<Element>() {
383 Map<TypeMirror, Set<String>> cachedQualifiedNames = new HashMap<>();
384
385 public int compare(Element o1, Element o2) {
386 TypeMirror e1 = o1.getEnclosingElement() != null ? o1.getEnclosingElement().asType() : null;
387 TypeMirror e2 = o2.getEnclosingElement() != null ? o2.getEnclosingElement().asType() : null;
388
389 Set<String> e1SuperTypes = getCachedSuperTypes(e1);
390 Set<String> e2SuperTypes = getCachedSuperTypes(e2);
391 return ElementUtils.compareByTypeHierarchy(e1, e1SuperTypes, e2, e2SuperTypes);
392 }
393
394 private Set<String> getCachedSuperTypes(TypeMirror e) {
395 if (e == null) {
396 return Collections.emptySet();
397 }
398 Set<String> superTypes = cachedQualifiedNames.get(e);
399 if (superTypes == null) {
400 superTypes = new HashSet<>(ElementUtils.getQualifiedSuperTypeNames(ElementUtils.fromTypeMirror(e)));
401 cachedQualifiedNames.put(e, superTypes);
402 }
403 return superTypes;
404 }
405 });
406
375 return members; 407 return members;
376 } 408 }
377 409
378 private NodeData parseNodeData(TypeElement templateType, List<TypeElement> typeHierarchy) { 410 private NodeData parseNodeData(TypeElement templateType, List<TypeElement> typeHierarchy) {
379 AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class); 411 AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class);