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