Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 8310:89006c76f737
Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Fri, 15 Mar 2013 21:18:33 +0100 |
parents | 97ee911c4c74 |
children | 676fa31bd3f0 |
comparison
equal
deleted
inserted
replaced
8280:2ddf84436009 | 8310:89006c76f737 |
---|---|
66 name += "Node"; | 66 name += "Node"; |
67 return name; | 67 return name; |
68 } | 68 } |
69 | 69 |
70 private static String valueName(ActualParameter param) { | 70 private static String valueName(ActualParameter param) { |
71 return param.getName(); | 71 return param.getLocalName(); |
72 } | 72 } |
73 | 73 |
74 private static String castValueName(ActualParameter parameter) { | 74 private static String castValueName(ActualParameter parameter) { |
75 return valueName(parameter) + "Cast"; | 75 return valueName(parameter) + "Cast"; |
76 } | 76 } |
77 | 77 |
78 private void addValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean includeHidden) { | 78 private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame) { |
79 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { | 79 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { |
80 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); | 80 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); |
81 } | 81 } |
82 for (ActualParameter parameter : specialization.getParameters()) { | 82 for (ActualParameter parameter : specialization.getParameters()) { |
83 ParameterSpec spec = parameter.getSpecification(); | 83 ParameterSpec spec = parameter.getSpecification(); |
84 if (forceFrame && spec.getName().equals("frame")) { | 84 if (forceFrame && spec.getName().equals("frame")) { |
85 continue; | 85 continue; |
86 } | 86 } |
87 if (!includeHidden && parameter.isHidden()) { | 87 if (spec.isLocal()) { |
88 continue; | 88 continue; |
89 } | 89 } |
90 | 90 |
91 method.addParameter(new CodeVariableElement(parameter.getActualType(), valueName(parameter))); | 91 method.addParameter(new CodeVariableElement(parameter.getActualType(), valueName(parameter))); |
92 } | 92 } |
93 } | 93 } |
94 | 94 |
95 private static void addValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeHidden) { | 95 private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeImplicit) { |
96 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { | 96 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { |
97 builder.string("frameValue"); | 97 builder.string("frameValue"); |
98 } | 98 } |
99 for (ActualParameter parameter : specialization.getParameters()) { | 99 for (ActualParameter parameter : specialization.getParameters()) { |
100 ParameterSpec spec = parameter.getSpecification(); | 100 ParameterSpec spec = parameter.getSpecification(); |
101 if (forceFrame && spec.getName().equals("frame")) { | 101 if (forceFrame && spec.getName().equals("frame")) { |
102 continue; | 102 continue; |
103 } | 103 } |
104 | 104 |
105 if (!includeHidden && parameter.isHidden()) { | 105 if (!includeImplicit && (parameter.isImplicit())) { |
106 continue; | 106 continue; |
107 } | 107 } |
108 | 108 if (parameter.getSpecification().isLocal()) { |
109 if (unexpectedValueName != null && parameter.getName().equals(unexpectedValueName)) { | 109 continue; |
110 builder.string("ex.getResult()"); | 110 } |
111 | |
112 if (unexpectedValueName != null && parameter.getLocalName().equals(unexpectedValueName)) { | |
113 builder.cast(parameter.getActualType(), CodeTreeBuilder.singleString("ex.getResult()")); | |
111 } else { | 114 } else { |
112 builder.string(valueName(parameter)); | 115 builder.string(valueName(parameter)); |
113 } | 116 } |
114 } | 117 } |
115 } | 118 } |
116 | 119 |
117 private static void addValueParameterNamesWithCasts(CodeTreeBuilder body, SpecializationData valueSpecialization, SpecializationData targetSpecialization, boolean includeHidden) { | 120 private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, TemplateMethod target, TemplateMethod sourceMethod, TemplateMethod castMethod, String unexpectedValueName) { |
118 NodeData node = targetSpecialization.getNode(); | 121 CodeTreeBuilder builder = parent.create(); |
122 | |
123 boolean castedValues = sourceMethod != castMethod; | |
124 | |
125 builder.startGroup(); | |
126 ExecutableElement method = target.getMethod(); | |
127 if (method == null) { | |
128 throw new IllegalStateException("Cannot call synthtetic operation methods."); | |
129 } | |
130 TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement()); | |
131 NodeData node = (NodeData) castMethod.getTemplate(); | |
119 TypeSystemData typeSystem = node.getTypeSystem(); | 132 TypeSystemData typeSystem = node.getTypeSystem(); |
120 | 133 |
121 for (ActualParameter targetParameter : targetSpecialization.getParameters()) { | 134 boolean accessible = target.canBeAccessedByInstanceOf(node.getNodeType()); |
122 ActualParameter valueParameter = valueSpecialization.findParameter(targetParameter.getName()); | 135 if (accessible) { |
136 if (builder.findMethod().getModifiers().contains(STATIC)) { | |
137 builder.string(THIS_NODE_LOCAL_VAR_NAME); | |
138 } else { | |
139 builder.string("super"); | |
140 } | |
141 } else { | |
142 if (method.getModifiers().contains(STATIC)) { | |
143 builder.type(targetClass.asType()); | |
144 } else { | |
145 ActualParameter parameter = null; | |
146 for (ActualParameter searchParameter : target.getParameters()) { | |
147 if (!searchParameter.getSpecification().isOptional()) { | |
148 parameter = searchParameter; | |
149 break; | |
150 } | |
151 } | |
152 assert parameter != null; | |
153 | |
154 if (castedValues) { | |
155 NodeFieldData field = node.findField(parameter.getSpecification().getName()); | |
156 if (field == null) { | |
157 builder.string(valueName(parameter)); | |
158 } else { | |
159 NodeData fieldNode = field.getNodeData(); | |
160 ExecutableTypeData execType = fieldNode.findExecutableType(parameter.getActualTypeData(node.getTypeSystem())); | |
161 if (execType.hasUnexpectedValue(getContext())) { | |
162 builder.string(castValueName(parameter)); | |
163 } else { | |
164 builder.string(valueName(parameter)); | |
165 } | |
166 } | |
167 } else { | |
168 builder.string(valueName(parameter)); | |
169 } | |
170 } | |
171 } | |
172 builder.string("."); | |
173 builder.startCall(method.getSimpleName().toString()); | |
174 | |
175 for (ActualParameter targetParameter : castMethod.getParameters()) { | |
176 ActualParameter valueParameter = sourceMethod.findParameter(targetParameter.getLocalName()); | |
177 if (valueParameter == null) { | |
178 continue; | |
179 } | |
123 TypeData targetType = targetParameter.getActualTypeData(typeSystem); | 180 TypeData targetType = targetParameter.getActualTypeData(typeSystem); |
124 | 181 |
125 if (!includeHidden && (targetParameter.isHidden() || valueParameter.isHidden())) { | 182 if (targetParameter.isImplicit() || valueParameter.isImplicit()) { |
126 continue; | 183 continue; |
127 } | 184 } |
128 | 185 |
129 TypeData valueType = null; | 186 TypeData valueType = null; |
130 if (valueParameter != null) { | 187 if (valueParameter != null) { |
131 valueType = valueParameter.getActualTypeData(typeSystem); | 188 valueType = valueParameter.getActualTypeData(typeSystem); |
132 } | 189 } |
133 | 190 |
134 if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) { | 191 if (targetParameter.getSpecification().isLocal()) { |
135 body.string(valueName(targetParameter)); | 192 builder.startGroup(); |
136 } else { | 193 if (builder.findMethod().getModifiers().contains(Modifier.STATIC)) { |
137 body.string(castValueName(targetParameter)); | 194 builder.string(THIS_NODE_LOCAL_VAR_NAME).string("."); |
138 } | 195 } else { |
139 } | 196 builder.string("this."); |
197 } | |
198 builder.string(targetParameter.getSpecification().getName()); | |
199 builder.end(); | |
200 } else if (unexpectedValueName != null && targetParameter.getLocalName().equals(unexpectedValueName)) { | |
201 builder.string("ex.getResult()"); | |
202 } else if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) { | |
203 builder.string(valueName(targetParameter)); | |
204 } else { | |
205 builder.string(castValueName(targetParameter)); | |
206 } | |
207 } | |
208 | |
209 builder.end().end(); | |
210 | |
211 return builder.getRoot(); | |
140 } | 212 } |
141 | 213 |
142 private static String genClassName(Template operation) { | 214 private static String genClassName(Template operation) { |
143 return getSimpleName(operation.getTemplateType()) + "Gen"; | 215 return getSimpleName(operation.getTemplateType()) + "Gen"; |
144 } | |
145 | |
146 private void startCallOperationMethod(CodeTreeBuilder body, TemplateMethod templateMethod, boolean castedValues) { | |
147 body.startGroup(); | |
148 ExecutableElement method = templateMethod.getMethod(); | |
149 if (method == null) { | |
150 throw new IllegalStateException("Cannot call synthtetic operation methods."); | |
151 } | |
152 TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement()); | |
153 NodeData node = (NodeData) templateMethod.getTemplate(); | |
154 | |
155 boolean accessible = templateMethod.canBeAccessedByInstanceOf(node.getNodeType()); | |
156 if (accessible) { | |
157 if (body.findMethod().getModifiers().contains(STATIC)) { | |
158 body.string(THIS_NODE_LOCAL_VAR_NAME); | |
159 } else { | |
160 body.string("super"); | |
161 } | |
162 } else { | |
163 if (method.getModifiers().contains(STATIC)) { | |
164 body.type(targetClass.asType()); | |
165 } else { | |
166 ActualParameter parameter = templateMethod.getParameters().get(0); | |
167 if (castedValues) { | |
168 NodeFieldData field = node.findField(parameter.getSpecification().getName()); | |
169 NodeData fieldNode = field.getNodeData(); | |
170 ExecutableTypeData execType = fieldNode.findExecutableType(parameter.getActualTypeData(node.getTypeSystem())); | |
171 if (execType.hasUnexpectedValue(getContext())) { | |
172 body.string(castValueName(parameter)); | |
173 } else { | |
174 body.string(valueName(parameter)); | |
175 } | |
176 } else { | |
177 body.string(valueName(parameter)); | |
178 } | |
179 } | |
180 } | |
181 body.string("."); | |
182 body.startCall(method.getSimpleName().toString()); | |
183 } | 216 } |
184 | 217 |
185 private String generatedGenericMethodName(SpecializationData specialization) { | 218 private String generatedGenericMethodName(SpecializationData specialization) { |
186 final String prefix = "generic"; | 219 final String prefix = "generic"; |
187 | 220 |
275 if (guardedSpecialization.getGuards().size() > 0) { | 308 if (guardedSpecialization.getGuards().size() > 0) { |
276 // Explicitly specified guards | 309 // Explicitly specified guards |
277 for (SpecializationGuardData guard : guardedSpecialization.getGuards()) { | 310 for (SpecializationGuardData guard : guardedSpecialization.getGuards()) { |
278 if ((guard.isOnSpecialization() && onSpecialization) || (guard.isOnExecution() && !onSpecialization)) { | 311 if ((guard.isOnSpecialization() && onSpecialization) || (guard.isOnExecution() && !onSpecialization)) { |
279 builder.string(andOperator); | 312 builder.string(andOperator); |
280 | 313 builder.tree(createTemplateMethodCall(parent, guard.getGuardDeclaration(), valueSpecialization, guardedSpecialization, null)); |
281 startCallOperationMethod(builder, guard.getGuardDeclaration(), true); | |
282 addValueParameterNamesWithCasts(builder, valueSpecialization, guardedSpecialization, false); | |
283 | |
284 builder.end().end(); // call | |
285 andOperator = " && "; | 314 andOperator = " && "; |
286 } | 315 } |
287 } | 316 } |
288 } | 317 } |
289 | 318 |
293 private CodeTree createCasts(CodeTreeBuilder parent, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { | 322 private CodeTree createCasts(CodeTreeBuilder parent, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { |
294 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 323 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
295 // Implict guards based on method signature | 324 // Implict guards based on method signature |
296 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) { | 325 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) { |
297 NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName()); | 326 NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName()); |
298 if (field == null) { | 327 if (field == null || field.getKind() == FieldKind.FIELD) { |
299 continue; | 328 continue; |
300 } | 329 } |
301 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getName()); | 330 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName()); |
302 | 331 |
303 CodeTree cast = createCast(parent, field, valueParam, guardedParam); | 332 CodeTree cast = createCast(parent, field, valueParam, guardedParam); |
304 if (cast == null) { | 333 if (cast == null) { |
305 continue; | 334 continue; |
306 } | 335 } |
314 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 343 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
315 // Implict guards based on method signature | 344 // Implict guards based on method signature |
316 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : ""; | 345 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : ""; |
317 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) { | 346 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) { |
318 NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName()); | 347 NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName()); |
319 if (field == null) { | 348 if (field == null || field.getKind() == FieldKind.FIELD) { |
320 continue; | 349 continue; |
321 } | 350 } |
322 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getName()); | 351 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName()); |
323 | 352 |
324 CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam); | 353 CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam); |
325 if (implicitGuard == null) { | 354 if (implicitGuard == null) { |
326 continue; | 355 continue; |
327 } | 356 } |
612 assert !node.getSpecializations().isEmpty(); | 641 assert !node.getSpecializations().isEmpty(); |
613 SpecializationData data = node.getSpecializations().get(0); | 642 SpecializationData data = node.getSpecializations().get(0); |
614 for (ActualParameter parameter : data.getParameters()) { | 643 for (ActualParameter parameter : data.getParameters()) { |
615 ParameterSpec spec = parameter.getSpecification(); | 644 ParameterSpec spec = parameter.getSpecification(); |
616 NodeFieldData field = node.findField(spec.getName()); | 645 NodeFieldData field = node.findField(spec.getName()); |
617 if (field == null) { | 646 if (field == null || field.getKind() == FieldKind.FIELD) { |
618 continue; | 647 continue; |
619 } | 648 } |
620 | 649 |
621 TypeMirror type; | 650 TypeMirror type; |
622 if (field.getKind() == FieldKind.CHILDREN && field.getType().getKind() == TypeKind.ARRAY) { | 651 if (field.getKind() == FieldKind.CHILDREN && field.getType().getKind() == TypeKind.ARRAY) { |
914 | 943 |
915 private CodeExecutableElement createSpecializeMethod(NodeData node) { | 944 private CodeExecutableElement createSpecializeMethod(NodeData node) { |
916 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getNodeType(), "specialize"); | 945 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getNodeType(), "specialize"); |
917 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); | 946 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); |
918 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState")); | 947 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState")); |
919 addValueParameters(method, node.getGenericSpecialization(), false, true); | 948 addInternalValueParameters(method, node.getGenericSpecialization(), false); |
920 | 949 |
921 CodeTreeBuilder body = method.createBuilder(); | 950 CodeTreeBuilder body = method.createBuilder(); |
922 body.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end(); | 951 body.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end(); |
923 | 952 |
924 for (int i = 1; i < node.getSpecializations().size(); i++) { | 953 for (int i = 1; i < node.getSpecializations().size(); i++) { |
952 continue; | 981 continue; |
953 } else { | 982 } else { |
954 String methodName = generatedGenericMethodName(current); | 983 String methodName = generatedGenericMethodName(current); |
955 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, methodName); | 984 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, methodName); |
956 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); | 985 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); |
957 addValueParameters(method, node.getGenericSpecialization(), true, true); | 986 addInternalValueParameters(method, node.getGenericSpecialization(), true); |
958 | 987 |
959 emitGeneratedGenericSpecialization(method.createBuilder(), current, next); | 988 emitGeneratedGenericSpecialization(method.createBuilder(), current, next); |
960 | 989 |
961 methods.add(method); | 990 methods.add(method); |
962 } | 991 } |
965 | 994 |
966 return methods; | 995 return methods; |
967 } else { | 996 } else { |
968 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, generatedGenericMethodName(null)); | 997 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, generatedGenericMethodName(null)); |
969 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); | 998 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); |
970 addValueParameters(method, node.getGenericSpecialization(), true, true); | 999 addInternalValueParameters(method, node.getGenericSpecialization(), true); |
971 emitInvokeDoMethod(method.createBuilder(), node.getGenericSpecialization(), 0); | 1000 emitInvokeDoMethod(method.createBuilder(), node.getGenericSpecialization(), 0); |
972 return Arrays.asList(method); | 1001 return Arrays.asList(method); |
973 } | 1002 } |
974 } | 1003 } |
975 | 1004 |
981 if (next != null) { | 1010 if (next != null) { |
982 CodeTreeBuilder nextBuilder = builder.create(); | 1011 CodeTreeBuilder nextBuilder = builder.create(); |
983 | 1012 |
984 nextBuilder.startReturn().startCall(generatedGenericMethodName(next)); | 1013 nextBuilder.startReturn().startCall(generatedGenericMethodName(next)); |
985 nextBuilder.string(THIS_NODE_LOCAL_VAR_NAME); | 1014 nextBuilder.string(THIS_NODE_LOCAL_VAR_NAME); |
986 addValueParameterNames(nextBuilder, next, null, true, true); | 1015 addInternalValueParameterNames(nextBuilder, next, null, true, true); |
987 nextBuilder.end().end(); | 1016 nextBuilder.end().end(); |
988 | 1017 |
989 invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, false, invokeMethod, nextBuilder.getRoot()); | 1018 invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, false, invokeMethod, nextBuilder.getRoot()); |
990 } | 1019 } |
991 | 1020 |
1003 | 1032 |
1004 if (specialization.getMethod() == null) { | 1033 if (specialization.getMethod() == null) { |
1005 emitEncounteredSynthetic(builder); | 1034 emitEncounteredSynthetic(builder); |
1006 } else { | 1035 } else { |
1007 builder.startReturn(); | 1036 builder.startReturn(); |
1008 startCallOperationMethod(builder, specialization, true); | 1037 builder.tree(createTemplateMethodCall(builder, specialization, specialization.getNode().getGenericSpecialization(), specialization, null)); |
1009 addValueParameterNamesWithCasts(builder, specialization.getNode().getGenericSpecialization(), specialization, false); | |
1010 builder.end().end(); // start call operation | |
1011 builder.end(); // return | 1038 builder.end(); // return |
1012 } | 1039 } |
1013 | 1040 |
1014 if (!specialization.getExceptions().isEmpty()) { | 1041 if (!specialization.getExceptions().isEmpty()) { |
1015 for (SpecializationThrowsData exception : specialization.getExceptions()) { | 1042 for (SpecializationThrowsData exception : specialization.getExceptions()) { |
1016 builder.end().startCatchBlock(exception.getJavaClass(), "ex" + level); | 1043 builder.end().startCatchBlock(exception.getJavaClass(), "ex" + level); |
1017 | 1044 |
1018 builder.startReturn().startCall(generatedGenericMethodName(exception.getTransitionTo())); | 1045 builder.startReturn().startCall(generatedGenericMethodName(exception.getTransitionTo())); |
1019 builder.string(THIS_NODE_LOCAL_VAR_NAME); | 1046 builder.string(THIS_NODE_LOCAL_VAR_NAME); |
1020 addValueParameterNames(builder, exception.getTransitionTo(), null, true, true); | 1047 addInternalValueParameterNames(builder, exception.getTransitionTo(), null, true, true); |
1021 builder.end().end(); | 1048 builder.end().end(); |
1022 } | 1049 } |
1023 builder.end(); | 1050 builder.end(); |
1024 } | 1051 } |
1025 } | 1052 } |
1198 builder.startCall("replace"); | 1225 builder.startCall("replace"); |
1199 if (node.needsRewrites(getContext())) { | 1226 if (node.needsRewrites(getContext())) { |
1200 builder.startCall(factoryClassName(node), "specialize"); | 1227 builder.startCall(factoryClassName(node), "specialize"); |
1201 builder.string("this"); | 1228 builder.string("this"); |
1202 builder.typeLiteral(builder.findMethod().getEnclosingElement().asType()); | 1229 builder.typeLiteral(builder.findMethod().getEnclosingElement().asType()); |
1203 addValueParameterNames(builder, specialization, null, false, true); | 1230 addInternalValueParameterNames(builder, specialization, null, false, true); |
1204 builder.end(); // call replace, call specialize | 1231 builder.end(); // call replace, call specialize |
1205 } else { | 1232 } else { |
1206 builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end(); | 1233 builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end(); |
1207 } | 1234 } |
1208 builder.end().end(); | 1235 builder.end().end(); |
1226 genericMethodName = generatedGenericMethodName(null); | 1253 genericMethodName = generatedGenericMethodName(null); |
1227 } | 1254 } |
1228 | 1255 |
1229 builder.startReturn().startCall(factoryClassName(node), genericMethodName); | 1256 builder.startReturn().startCall(factoryClassName(node), genericMethodName); |
1230 builder.string("this"); | 1257 builder.string("this"); |
1231 addValueParameterNames(builder, specialization, null, true, true); | 1258 addInternalValueParameterNames(builder, specialization, null, true, true); |
1232 builder.end().end(); | 1259 builder.end().end(); |
1233 } else { | 1260 } else { |
1234 builder.startReturn(); | 1261 builder.startReturn(); |
1235 | 1262 builder.tree(createTemplateMethodCall(builder, specialization, specialization, specialization, null)); |
1236 startCallOperationMethod(builder, specialization, false); | |
1237 addValueParameterNames(builder, specialization, null, false, false); | |
1238 | |
1239 builder.end().end(); // operation call | |
1240 builder.end(); // return | 1263 builder.end(); // return |
1241 } | 1264 } |
1242 | 1265 |
1243 if (!specialization.getExceptions().isEmpty()) { | 1266 if (!specialization.getExceptions().isEmpty()) { |
1244 for (SpecializationThrowsData exception : specialization.getExceptions()) { | 1267 for (SpecializationThrowsData exception : specialization.getExceptions()) { |
1253 private CodeTree createExecuteChildren(CodeTreeBuilder parent, SpecializationData specialization) { | 1276 private CodeTree createExecuteChildren(CodeTreeBuilder parent, SpecializationData specialization) { |
1254 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 1277 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
1255 | 1278 |
1256 for (ActualParameter parameter : specialization.getParameters()) { | 1279 for (ActualParameter parameter : specialization.getParameters()) { |
1257 NodeFieldData field = specialization.getNode().findField(parameter.getSpecification().getName()); | 1280 NodeFieldData field = specialization.getNode().findField(parameter.getSpecification().getName()); |
1258 if (field == null) { | 1281 if (field == null || field.getKind() == FieldKind.FIELD) { |
1259 continue; | 1282 continue; |
1260 } | 1283 } |
1261 | 1284 |
1262 buildFieldExecute(builder, specialization, parameter, field, null); | 1285 buildFieldExecute(builder, specialization, parameter, field, null); |
1263 } | 1286 } |
1265 } | 1288 } |
1266 | 1289 |
1267 private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) { | 1290 private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) { |
1268 for (TemplateMethod listener : node.getSpecializationListeners()) { | 1291 for (TemplateMethod listener : node.getSpecializationListeners()) { |
1269 builder.startStatement(); | 1292 builder.startStatement(); |
1270 startCallOperationMethod(builder, listener, false); | 1293 builder.tree(createTemplateMethodCall(builder, listener, listener, listener, null)); |
1271 addValueParameterNames(builder, listener, null, false, false); | |
1272 builder.end().end(); | |
1273 builder.end(); // statement | 1294 builder.end(); // statement |
1274 } | 1295 } |
1275 } | 1296 } |
1276 | 1297 |
1277 private void buildFieldExecute(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter param, NodeFieldData field, ActualParameter exceptionParam) { | 1298 private void buildFieldExecute(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter param, NodeFieldData field, ActualParameter exceptionParam) { |
1299 builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); | 1320 builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); |
1300 SpecializationData generic = specialization.getNode().getGenericSpecialization(); | 1321 SpecializationData generic = specialization.getNode().getGenericSpecialization(); |
1301 boolean execute = false; | 1322 boolean execute = false; |
1302 for (ActualParameter exParam : generic.getParameters()) { | 1323 for (ActualParameter exParam : generic.getParameters()) { |
1303 NodeFieldData exField = generic.getNode().findField(exParam.getSpecification().getName()); | 1324 NodeFieldData exField = generic.getNode().findField(exParam.getSpecification().getName()); |
1304 if (exField == null) { | 1325 if (exField == null || field.getKind() == FieldKind.FIELD) { |
1305 continue; | 1326 continue; |
1306 } | 1327 } |
1307 if (execute) { | 1328 if (execute) { |
1308 buildFieldExecute(builder, specialization.getNode().getGenericSpecialization(), exParam, exField, param); | 1329 buildFieldExecute(builder, specialization.getNode().getGenericSpecialization(), exParam, exField, param); |
1309 } else if (exParam.getName().equals(param.getName())) { | 1330 } else if (exParam.getLocalName().equals(param.getLocalName())) { |
1310 execute = true; | 1331 execute = true; |
1311 } | 1332 } |
1312 } | 1333 } |
1313 builder.tree(createReturnSpecializeAndExecute(builder, specialization.findNextSpecialization(), param)); | 1334 builder.tree(createReturnSpecializeAndExecute(builder, specialization.findNextSpecialization(), param)); |
1314 builder.end(); // catch block | 1335 builder.end(); // catch block |
1363 } | 1384 } |
1364 | 1385 |
1365 builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = "); | 1386 builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = "); |
1366 ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex); | 1387 ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex); |
1367 | 1388 |
1368 startCallOperationMethod(builder, shortCircuitData, false); | 1389 builder.tree(createTemplateMethodCall(builder, shortCircuitData, shortCircuitData, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null)); |
1369 addValueParameterNames(builder, shortCircuitData, exceptionParam != null ? exceptionParam.getName() : null, false, false); | |
1370 builder.end().end(); // call operation | |
1371 | 1390 |
1372 builder.end(); // statement | 1391 builder.end(); // statement |
1373 | 1392 |
1374 builder.declaration(parameter.getActualType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType())); | 1393 builder.declaration(parameter.getActualType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType())); |
1375 builder.startIf().string(shortCircuitParam.getName()).end(); | 1394 builder.startIf().string(shortCircuitParam.getLocalName()).end(); |
1376 builder.startBlock(); | 1395 builder.startBlock(); |
1377 | 1396 |
1378 return true; | 1397 return true; |
1379 } | 1398 } |
1380 | 1399 |
1386 | 1405 |
1387 private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, SpecializationData nextSpecialization, ActualParameter exceptionParam) { | 1406 private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, SpecializationData nextSpecialization, ActualParameter exceptionParam) { |
1388 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); | 1407 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); |
1389 specializeCall.startCall("specializeAndExecute"); | 1408 specializeCall.startCall("specializeAndExecute"); |
1390 specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class"); | 1409 specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class"); |
1391 addValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getName() : null, true, true); | 1410 addInternalValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, true); |
1392 specializeCall.end().end(); | 1411 specializeCall.end().end(); |
1393 | 1412 |
1394 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 1413 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
1395 builder.startReturn(); | 1414 builder.startReturn(); |
1396 builder.tree(specializeCall.getRoot()); | 1415 builder.tree(specializeCall.getRoot()); |
1407 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE), returnType.getPrimitiveType(), "specializeAndExecute"); | 1426 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE), returnType.getPrimitiveType(), "specializeAndExecute"); |
1408 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState")); | 1427 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState")); |
1409 if (canThrowUnexpected) { | 1428 if (canThrowUnexpected) { |
1410 method.addThrownType(getUnexpectedValueException()); | 1429 method.addThrownType(getUnexpectedValueException()); |
1411 } | 1430 } |
1412 addValueParameters(method, specialization.getNode().getGenericSpecialization(), true, true); | 1431 addInternalValueParameters(method, specialization.getNode().getGenericSpecialization(), true); |
1413 clazz.add(method); | 1432 clazz.add(method); |
1414 | 1433 |
1415 CodeTreeBuilder builder = method.createBuilder(); | 1434 CodeTreeBuilder builder = method.createBuilder(); |
1416 | 1435 |
1417 builder.tree(createDeoptimize(builder)); | 1436 builder.tree(createDeoptimize(builder)); |
1418 emitSpecializationListeners(builder, specialization.getNode()); | 1437 emitSpecializationListeners(builder, specialization.getNode()); |
1419 | 1438 |
1420 builder.startStatement(); | 1439 builder.startStatement(); |
1421 builder.startCall("replace"); | 1440 builder.startCall("replace"); |
1422 builder.startCall(factoryClassName(specialization.getNode()), "specialize").string("this").string("minimumState"); | 1441 builder.startCall(factoryClassName(specialization.getNode()), "specialize").string("this").string("minimumState"); |
1423 addValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false, true); | 1442 addInternalValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false, true); |
1424 builder.end(); | 1443 builder.end(); |
1425 builder.end(); // call replace | 1444 builder.end(); // call replace |
1426 builder.end(); // statement | 1445 builder.end(); // statement |
1427 | 1446 |
1428 String generatedMethodName = generatedGenericMethodName(specialization.findNextSpecialization()); | 1447 String generatedMethodName = generatedGenericMethodName(specialization.findNextSpecialization()); |
1429 ExecutableElement generatedGeneric = clazz.getEnclosingClass().getMethod(generatedMethodName); | 1448 ExecutableElement generatedGeneric = clazz.getEnclosingClass().getMethod(generatedMethodName); |
1430 | 1449 |
1431 CodeTreeBuilder genericExecute = CodeTreeBuilder.createBuilder(); | 1450 CodeTreeBuilder genericExecute = CodeTreeBuilder.createBuilder(); |
1432 genericExecute.startCall(factoryClassName(specialization.getNode()), generatedMethodName); | 1451 genericExecute.startCall(factoryClassName(specialization.getNode()), generatedMethodName); |
1433 genericExecute.string("this"); | 1452 genericExecute.string("this"); |
1434 addValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true, true); | 1453 addInternalValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true, true); |
1435 genericExecute.end(); // call generated generic | 1454 genericExecute.end(); // call generated generic |
1436 | 1455 |
1437 CodeTree genericInvocation = createExpectType(node, returnExecutableType, genericExecute.getRoot()); | 1456 CodeTree genericInvocation = createExpectType(node, returnExecutableType, genericExecute.getRoot()); |
1438 | 1457 |
1439 if (generatedGeneric != null && Utils.isVoid(generatedGeneric.getReturnType())) { | 1458 if (generatedGeneric != null && Utils.isVoid(generatedGeneric.getReturnType())) { |