Mercurial > hg > truffle
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java @ 19283:08aa0372dad4
Truffle-DSL: implement new guard expression syntax.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Fri, 23 Jan 2015 02:55:23 +0100 |
parents | ae81dd154fb6 |
children | 259a416388d7 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java Thu Jan 22 20:44:24 2015 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java Fri Jan 23 02:55:23 2015 +0100 @@ -33,6 +33,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.dsl.processor.*; +import com.oracle.truffle.dsl.processor.expression.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.compiler.*; import com.oracle.truffle.dsl.processor.model.*; @@ -174,8 +175,10 @@ return node; } - private ArrayList<Element> loadMembers(TypeElement templateType) { - return new ArrayList<>(CompilerFactory.getCompiler(templateType).getAllMembersInDeclarationOrder(context.getEnvironment(), templateType)); + private List<Element> loadMembers(TypeElement templateType) { + List<Element> members = new ArrayList<>(CompilerFactory.getCompiler(templateType).getAllMembersInDeclarationOrder(context.getEnvironment(), templateType)); + + return members; } private boolean containsSpecializations(List<Element> elements) { @@ -687,7 +690,11 @@ return; } - initializeGuards(elements, node); + initializeExpressions(elements, node); + if (node.hasErrors()) { + return; + } + initializeGeneric(node); initializeUninitialized(node); initializeOrder(node); @@ -775,11 +782,11 @@ AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "contains"); if (foundSpecialization.compareTo(specialization) > 0) { specialization.addError(value, "The contained specialization '%s' must be declared before the containing specialization.", includeName); - } else { - specialization.addError(value, - "The contained specialization '%s' is not fully compatible. The contained specialization must be strictly more generic than the containing one.", - includeName); - } + }/* + * else { specialization.addError(value, + * "The contained specialization '%s' is not fully compatible. The contained specialization must be strictly more generic than the containing one." + * , includeName); } + */ } resolvedSpecializations.add(foundSpecialization); @@ -925,74 +932,68 @@ return changed; } - private void initializeGuards(List<? extends Element> elements, NodeData node) { - Map<String, List<ExecutableElement>> potentialGuards = new HashMap<>(); - for (SpecializationData specialization : node.getSpecializations()) { - for (GuardExpression exp : specialization.getGuards()) { - potentialGuards.put(exp.getGuardName(), null); - } - } + private void initializeExpressions(List<? extends Element> elements, NodeData node) { + List<Element> members = filterNotAccessibleElements(node.getTemplateType(), elements); - 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; - } + final TypeMirror booleanType = context.getType(boolean.class); - if (!ElementUtils.typeEquals(potentialGuard.getReturnType(), booleanType)) { + for (SpecializationData specialization : node.getSpecializations()) { + if (specialization.getMethod() == null) { continue; } - List<ExecutableElement> potentialMethods = potentialGuards.get(methodName); - if (potentialMethods == null) { - potentialMethods = new ArrayList<>(); - potentialGuards.put(methodName, potentialMethods); + List<Element> specializationMembers = new ArrayList<>(); + for (Parameter p : specialization.getParameters()) { + VariableElement variableElement = p.getVariableElement(); + if (variableElement == null) { + throw new AssertionError("All parameters must be resolved for " + specialization); + } + + specializationMembers.add(variableElement); } - potentialMethods.add(potentialGuard); - } + specializationMembers.addAll(members); - for (SpecializationData specialization : node.getSpecializations()) { - for (GuardExpression exp : specialization.getGuards()) { - resolveGuardExpression(node, specialization, potentialGuards, exp); + DSLExpressionResolver resolver = new DSLExpressionResolver(context, specializationMembers); + List<String> guardDefinitions = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards"); + List<GuardExpression> guardExpressions = new ArrayList<>(); + for (String guard : guardDefinitions) { + GuardExpression guardExpression; + DSLExpression expression = null; + try { + expression = DSLExpression.parse(guard); + expression.accept(resolver); + guardExpression = new GuardExpression(specialization, expression); + if (!ElementUtils.typeEquals(expression.getResolvedType(), booleanType)) { + guardExpression.addError("Incompatible return type %s. Guard expressions must return boolean.", ElementUtils.getSimpleName(expression.getResolvedType())); + } +// guardExpression.addWarning("Expression:%s", expression.toString()); + } catch (InvalidExpressionException e) { + guardExpression = new GuardExpression(specialization, null); + guardExpression.addError("Error parsing expression '%s': %s", guard, e.getMessage()); + } + guardExpressions.add(guardExpression); } + specialization.setGuards(guardExpressions); } } - 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.", expression.getGuardName()); - return; - } + private static List<Element> filterNotAccessibleElements(TypeElement templateType, List<? extends Element> elements) { + String packageName = ElementUtils.getPackageName(templateType); + List<Element> filteredElements = new ArrayList<>(elements); + for (Element element : elements) { + Modifier visibility = ElementUtils.getVisibility(element.getModifiers()); + if (visibility == Modifier.PRIVATE) { + continue; + } else if (visibility == null) { + String elementPackageName = ElementUtils.getPackageName(element.getEnclosingElement().asType()); + if (!Objects.equals(packageName, elementPackageName) && !elementPackageName.equals("java.lang")) { + continue; + } + } - 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); + filteredElements.add(element); } - - GuardParser parser = new GuardParser(context, node, source, expression); - List<GuardData> matchingGuards = parser.parse(availableGuards); - if (!matchingGuards.isEmpty() && matchingGuards.get(0) != null) { - expression.setResolvedGuard(matchingGuards.get(0)); - } else { - MethodSpec spec = parser.createSpecification(source.getMethod(), source.getMarkerAnnotation()); - spec.applyTypeDefinitions("types"); - source.addError("No guard with name '%s' matched the required signature. Expected signature: %n%s", expression.getGuardName(), spec.toSignatureString("guard")); - } + return filteredElements; } private void initializeGeneric(final NodeData node) {