Mercurial > hg > graal-compiler
comparison 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 |
comparison
equal
deleted
inserted
replaced
16850:d6c002f4d2a9 | 16851:2db61eddcb97 |
---|---|
188 if (importGuardClass.getKind() != TypeKind.DECLARED) { | 188 if (importGuardClass.getKind() != TypeKind.DECLARED) { |
189 node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' is not a declared type.", ElementUtils.getQualifiedName(importGuardClass)); | 189 node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' is not a declared type.", ElementUtils.getQualifiedName(importGuardClass)); |
190 continue; | 190 continue; |
191 } | 191 } |
192 TypeElement typeElement = ElementUtils.fromTypeMirror(importGuardClass); | 192 TypeElement typeElement = ElementUtils.fromTypeMirror(importGuardClass); |
193 if (!typeElement.getModifiers().contains(Modifier.PUBLIC)) { | 193 |
194 // hack to reload type is necessary for incremental compiling in eclipse. | |
195 // otherwise methods inside of import guard types are just not found. | |
196 typeElement = ElementUtils.fromTypeMirror(context.reloadType(typeElement.asType())); | |
197 | |
198 if (typeElement.getEnclosingElement().getKind().isClass() && !typeElement.getModifiers().contains(Modifier.PUBLIC)) { | |
194 node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' must be public.", ElementUtils.getQualifiedName(importGuardClass)); | 199 node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' must be public.", ElementUtils.getQualifiedName(importGuardClass)); |
195 continue; | 200 continue; |
196 } | 201 } |
197 | 202 |
198 List<? extends ExecutableElement> importMethods = ElementFilter.methodsIn(processingEnv.getElementUtils().getAllMembers(typeElement)); | 203 List<? extends ExecutableElement> importMethods = ElementFilter.methodsIn(processingEnv.getElementUtils().getAllMembers(typeElement)); |
204 | |
199 for (ExecutableElement importMethod : importMethods) { | 205 for (ExecutableElement importMethod : importMethods) { |
200 if (!importMethod.getModifiers().contains(Modifier.PUBLIC) || !importMethod.getModifiers().contains(Modifier.STATIC)) { | 206 if (!importMethod.getModifiers().contains(Modifier.PUBLIC) || !importMethod.getModifiers().contains(Modifier.STATIC)) { |
201 continue; | 207 continue; |
202 } | 208 } |
203 elements.add(importMethod); | 209 elements.add(importMethod); |
881 | 887 |
882 return signatures; | 888 return signatures; |
883 } | 889 } |
884 | 890 |
885 private void initializeGuards(List<? extends Element> elements, NodeData node) { | 891 private void initializeGuards(List<? extends Element> elements, NodeData node) { |
886 Map<String, List<GuardData>> guards = new HashMap<>(); | 892 Map<String, List<ExecutableElement>> potentialGuards = new HashMap<>(); |
887 for (SpecializationData specialization : node.getSpecializations()) { | 893 for (SpecializationData specialization : node.getSpecializations()) { |
888 for (GuardExpression exp : specialization.getGuards()) { | 894 for (GuardExpression exp : specialization.getGuards()) { |
889 guards.put(exp.getGuardName(), null); | 895 potentialGuards.put(exp.getGuardName(), null); |
890 } | 896 } |
891 } | 897 } |
892 | 898 |
893 GuardParser parser = new GuardParser(context, node, null, guards.keySet()); | 899 TypeMirror booleanType = context.getType(boolean.class); |
894 List<GuardData> resolvedGuards = parser.parse(elements); | 900 for (ExecutableElement potentialGuard : ElementFilter.methodsIn(elements)) { |
895 for (GuardData guard : resolvedGuards) { | 901 if (potentialGuard.getModifiers().contains(Modifier.PRIVATE)) { |
896 List<GuardData> groupedGuards = guards.get(guard.getMethodName()); | 902 continue; |
897 if (groupedGuards == null) { | 903 } |
898 groupedGuards = new ArrayList<>(); | 904 String methodName = potentialGuard.getSimpleName().toString(); |
899 guards.put(guard.getMethodName(), groupedGuards); | 905 if (!potentialGuards.containsKey(methodName)) { |
900 } | 906 continue; |
901 groupedGuards.add(guard); | 907 } |
908 | |
909 if (!ElementUtils.typeEquals(potentialGuard.getReturnType(), booleanType)) { | |
910 continue; | |
911 } | |
912 | |
913 List<ExecutableElement> potentialMethods = potentialGuards.get(methodName); | |
914 if (potentialMethods == null) { | |
915 potentialMethods = new ArrayList<>(); | |
916 potentialGuards.put(methodName, potentialMethods); | |
917 } | |
918 potentialMethods.add(potentialGuard); | |
902 } | 919 } |
903 | 920 |
904 for (SpecializationData specialization : node.getSpecializations()) { | 921 for (SpecializationData specialization : node.getSpecializations()) { |
905 for (GuardExpression exp : specialization.getGuards()) { | 922 for (GuardExpression exp : specialization.getGuards()) { |
906 resolveGuardExpression(node, specialization, guards, exp); | 923 resolveGuardExpression(node, specialization, potentialGuards, exp); |
907 } | 924 } |
908 } | 925 } |
909 } | 926 } |
910 | 927 |
911 private void resolveGuardExpression(NodeData node, TemplateMethod source, Map<String, List<GuardData>> guards, GuardExpression expression) { | 928 private void resolveGuardExpression(NodeData node, TemplateMethod source, Map<String, List<ExecutableElement>> guards, GuardExpression expression) { |
912 List<GuardData> availableGuards = guards.get(expression.getGuardName()); | 929 List<ExecutableElement> availableGuards = guards.get(expression.getGuardName()); |
913 if (availableGuards == null) { | 930 if (availableGuards == null) { |
914 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()); | 931 source.addError("No compatible guard with method name '%s' found.", expression.getGuardName()); |
915 return; | 932 return; |
916 } | 933 } |
917 List<ExecutableElement> guardMethods = new ArrayList<>(); | 934 |
918 for (GuardData guard : availableGuards) { | 935 String[] childNames = expression.getChildNames(); |
919 guardMethods.add(guard.getMethod()); | 936 if (childNames != null) { |
920 } | 937 NodeExecutionData[] resolvedExecutions = new NodeExecutionData[childNames.length]; |
921 GuardParser parser = new GuardParser(context, node, source, null); | 938 for (int i = 0; i < childNames.length; i++) { |
922 List<GuardData> matchingGuards = parser.parse(guardMethods); | 939 String childName = childNames[i]; |
940 NodeExecutionData execution = node.findExecutionByExpression(childName); | |
941 if (execution == null) { | |
942 source.addError("Guard parameter '%s' for guard '%s' could not be mapped to a declared child node.", childName, expression.getGuardName()); | |
943 return; | |
944 } | |
945 resolvedExecutions[i] = execution; | |
946 } | |
947 expression.setResolvedChildren(resolvedExecutions); | |
948 } | |
949 | |
950 GuardParser parser = new GuardParser(context, node, source, expression); | |
951 List<GuardData> matchingGuards = parser.parse(availableGuards); | |
923 if (!matchingGuards.isEmpty()) { | 952 if (!matchingGuards.isEmpty()) { |
924 GuardData guard = matchingGuards.get(0); | 953 GuardData guard = matchingGuards.get(0); |
925 // use the shared instance of the guard data | 954 // use the shared instance of the guard data |
926 for (GuardData guardData : availableGuards) { | 955 expression.setResolvedGuard(guard); |
927 if (guardData.getMethod() == guard.getMethod()) { | |
928 expression.setGuard(guardData); | |
929 return; | |
930 } | |
931 } | |
932 throw new AssertionError("Should not reach here."); | |
933 } else { | 956 } else { |
934 MethodSpec spec = parser.createSpecification(source.getMethod(), source.getMarkerAnnotation()); | 957 MethodSpec spec = parser.createSpecification(source.getMethod(), source.getMarkerAnnotation()); |
935 spec.applyTypeDefinitions("types"); | 958 spec.applyTypeDefinitions("types"); |
936 source.addError("No guard with name '%s' matched the required signature. Expected signature: %n%s", expression.getGuardName(), spec.toSignatureString("guard")); | 959 source.addError("No guard with name '%s' matched the required signature. Expected signature: %n%s", expression.getGuardName(), spec.toSignatureString("guard")); |
937 } | 960 } |