diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java @ 16832:13cf9b6b325c

Truffle-DSL: implemented import guards feature.
author Christian Humer <christian.humer@gmail.com>
date Thu, 14 Aug 2014 16:49:18 +0200
parents c3c07046a74b
children 21e0ab3c1395
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java	Thu Aug 14 15:02:17 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java	Thu Aug 14 16:49:18 2014 +0200
@@ -125,6 +125,7 @@
         return node;
     }
 
+    @SuppressWarnings("unchecked")
     private NodeData parseNode(TypeElement originalTemplateType) {
         // reloading the type elements is needed for ecj
         TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType));
@@ -141,6 +142,9 @@
         List<? extends Element> elements = CompilerFactory.getCompiler(templateType).getAllMembersInDeclarationOrder(context.getEnvironment(), templateType);
 
         NodeData node = parseNodeData(templateType, elements, lookupTypes);
+
+        parseImportGuards(node, lookupTypes, (List<Element>) elements);
+
         if (node.hasErrors()) {
             return node; // error sync point
         }
@@ -169,6 +173,40 @@
         return node;
     }
 
+    private void parseImportGuards(NodeData node, List<TypeElement> lookupTypes, List<Element> elements) {
+        for (TypeElement lookupType : lookupTypes) {
+            AnnotationMirror importAnnotation = ElementUtils.findAnnotationMirror(processingEnv, lookupType, ImportGuards.class);
+            if (importAnnotation == null) {
+                continue;
+            }
+            AnnotationValue importClassesValue = ElementUtils.getAnnotationValue(importAnnotation, "value");
+            List<TypeMirror> importClasses = ElementUtils.getAnnotationValueList(TypeMirror.class, importAnnotation, "value");
+            if (importClasses.isEmpty()) {
+                node.addError(importAnnotation, importClassesValue, "At least import guard classes must be specified.");
+                continue;
+            }
+            for (TypeMirror importGuardClass : importClasses) {
+                if (importGuardClass.getKind() != TypeKind.DECLARED) {
+                    node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' is not a declared type.", ElementUtils.getQualifiedName(importGuardClass));
+                    continue;
+                }
+                TypeElement typeElement = ElementUtils.fromTypeMirror(importGuardClass);
+                if (!typeElement.getModifiers().contains(Modifier.PUBLIC)) {
+                    node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' must be public.", ElementUtils.getQualifiedName(importGuardClass));
+                    continue;
+                }
+
+                List<? extends ExecutableElement> importMethods = ElementFilter.methodsIn(processingEnv.getElementUtils().getAllMembers(typeElement));
+                for (ExecutableElement importMethod : importMethods) {
+                    if (!importMethod.getModifiers().contains(Modifier.PUBLIC) || !importMethod.getModifiers().contains(Modifier.STATIC)) {
+                        continue;
+                    }
+                    elements.add(importMethod);
+                }
+            }
+        }
+    }
+
     private NodeData parseNodeData(TypeElement templateType, List<? extends Element> elements, List<TypeElement> typeHierarchy) {
         AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class);
         if (typeSystemMirror == null) {