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())) {