diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java @ 16851:2db61eddcb97

Truffle-DSL: argument syntax support for guards
author Christian Humer <christian.humer@gmail.com>
date Mon, 18 Aug 2014 18:41:16 +0200
parents 21e0ab3c1395
children 09d99d3c0c95
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java	Mon Aug 18 17:44:42 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java	Mon Aug 18 18:41:16 2014 +0200
@@ -190,12 +190,18 @@
                     continue;
                 }
                 TypeElement typeElement = ElementUtils.fromTypeMirror(importGuardClass);
-                if (!typeElement.getModifiers().contains(Modifier.PUBLIC)) {
+
+                // hack to reload type is necessary for incremental compiling in eclipse.
+                // otherwise methods inside of import guard types are just not found.
+                typeElement = ElementUtils.fromTypeMirror(context.reloadType(typeElement.asType()));
+
+                if (typeElement.getEnclosingElement().getKind().isClass() && !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;
@@ -883,53 +889,70 @@
     }
 
     private void initializeGuards(List<? extends Element> elements, NodeData node) {
-        Map<String, List<GuardData>> guards = new HashMap<>();
+        Map<String, List<ExecutableElement>> potentialGuards = new HashMap<>();
         for (SpecializationData specialization : node.getSpecializations()) {
             for (GuardExpression exp : specialization.getGuards()) {
-                guards.put(exp.getGuardName(), null);
+                potentialGuards.put(exp.getGuardName(), null);
             }
         }
 
-        GuardParser parser = new GuardParser(context, node, null, guards.keySet());
-        List<GuardData> resolvedGuards = parser.parse(elements);
-        for (GuardData guard : resolvedGuards) {
-            List<GuardData> groupedGuards = guards.get(guard.getMethodName());
-            if (groupedGuards == null) {
-                groupedGuards = new ArrayList<>();
-                guards.put(guard.getMethodName(), groupedGuards);
+        TypeMirror booleanType = context.getType(boolean.class);
+        for (ExecutableElement potentialGuard : ElementFilter.methodsIn(elements)) {
+            if (potentialGuard.getModifiers().contains(Modifier.PRIVATE)) {
+                continue;
+            }
+            String methodName = potentialGuard.getSimpleName().toString();
+            if (!potentialGuards.containsKey(methodName)) {
+                continue;
             }
-            groupedGuards.add(guard);
+
+            if (!ElementUtils.typeEquals(potentialGuard.getReturnType(), booleanType)) {
+                continue;
+            }
+
+            List<ExecutableElement> potentialMethods = potentialGuards.get(methodName);
+            if (potentialMethods == null) {
+                potentialMethods = new ArrayList<>();
+                potentialGuards.put(methodName, potentialMethods);
+            }
+            potentialMethods.add(potentialGuard);
         }
 
         for (SpecializationData specialization : node.getSpecializations()) {
             for (GuardExpression exp : specialization.getGuards()) {
-                resolveGuardExpression(node, specialization, guards, exp);
+                resolveGuardExpression(node, specialization, potentialGuards, exp);
             }
         }
     }
 
-    private void resolveGuardExpression(NodeData node, TemplateMethod source, Map<String, List<GuardData>> guards, GuardExpression expression) {
-        List<GuardData> availableGuards = guards.get(expression.getGuardName());
+    private void resolveGuardExpression(NodeData node, TemplateMethod source, Map<String, List<ExecutableElement>> guards, GuardExpression expression) {
+        List<ExecutableElement> availableGuards = guards.get(expression.getGuardName());
         if (availableGuards == null) {
-            source.addError("No compatible guard with method name '%s' found. Please note that all signature types of the method guard must be declared in the type system.", expression.getGuardName());
+            source.addError("No compatible guard with method name '%s' found.", expression.getGuardName());
             return;
         }
-        List<ExecutableElement> guardMethods = new ArrayList<>();
-        for (GuardData guard : availableGuards) {
-            guardMethods.add(guard.getMethod());
+
+        String[] childNames = expression.getChildNames();
+        if (childNames != null) {
+            NodeExecutionData[] resolvedExecutions = new NodeExecutionData[childNames.length];
+            for (int i = 0; i < childNames.length; i++) {
+                String childName = childNames[i];
+                NodeExecutionData execution = node.findExecutionByExpression(childName);
+                if (execution == null) {
+                    source.addError("Guard parameter '%s' for guard '%s' could not be mapped to a declared child node.", childName, expression.getGuardName());
+                    return;
+                }
+                resolvedExecutions[i] = execution;
+            }
+            expression.setResolvedChildren(resolvedExecutions);
         }
-        GuardParser parser = new GuardParser(context, node, source, null);
-        List<GuardData> matchingGuards = parser.parse(guardMethods);
+
+        GuardParser parser = new GuardParser(context, node, source, expression);
+        List<GuardData> matchingGuards = parser.parse(availableGuards);
         if (!matchingGuards.isEmpty()) {
             GuardData guard = matchingGuards.get(0);
             // use the shared instance of the guard data
-            for (GuardData guardData : availableGuards) {
-                if (guardData.getMethod() == guard.getMethod()) {
-                    expression.setGuard(guardData);
-                    return;
-                }
-            }
-            throw new AssertionError("Should not reach here.");
+            expression.setResolvedGuard(guard);
         } else {
             MethodSpec spec = parser.createSpecification(source.getMethod(), source.getMarkerAnnotation());
             spec.applyTypeDefinitions("types");