Mercurial > hg > truffle
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); |