annotate graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 8592:a80bf36c6a1e

Refactor to shared template method signature comparison.
author Christian Humer <christian.humer@gmail.com>
date Mon, 01 Apr 2013 11:52:38 +0200
parents 676fa31bd3f0
children 8a1115c92271
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1 /*
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
4 *
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
7 * published by the Free Software Foundation.
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
8 *
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
13 * accompanied this code).
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
14 *
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
18 *
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
21 * questions.
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
22 */
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
23 package com.oracle.truffle.codegen.processor.node;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
24
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
25 import static com.oracle.truffle.codegen.processor.Utils.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
26 import static javax.lang.model.element.Modifier.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
27
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
28 import java.util.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
29
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
30 import javax.lang.model.element.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
31 import javax.lang.model.type.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
32 import javax.lang.model.util.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
33
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
34 import com.oracle.truffle.api.codegen.*;
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
35 import com.oracle.truffle.codegen.processor.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
36 import com.oracle.truffle.codegen.processor.ast.*;
8251
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
37 import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind;
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
38 import com.oracle.truffle.codegen.processor.node.NodeFieldData.FieldKind;
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
39 import com.oracle.truffle.codegen.processor.template.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
40 import com.oracle.truffle.codegen.processor.typesystem.*;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
41
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
42 public class NodeCodeGenerator extends CompilationUnitFactory<NodeData> {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
43
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
44 private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode";
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
45
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
46 public NodeCodeGenerator(ProcessorContext context) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
47 super(context);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
48 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
49
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
50 private TypeMirror getUnexpectedValueException() {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
51 return getContext().getTruffleTypes().getUnexpectedValueException();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
52 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
53
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
54 private static String factoryClassName(NodeData node) {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
55 return node.getNodeId() + "Factory";
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
56 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
57
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
58 private static String nodeSpecializationClassName(SpecializationData specialization) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
59 String nodeid = specialization.getNode().getNodeId();
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
60 if (nodeid.endsWith("Node") && !nodeid.equals("Node")) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
61 nodeid = nodeid.substring(0, nodeid.length() - 4);
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
62 }
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
63
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
64 String name = Utils.firstLetterUpperCase(nodeid);
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
65 name += Utils.firstLetterUpperCase(specialization.getId());
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
66 name += "Node";
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
67 return name;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
68 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
69
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
70 private static String valueName(ActualParameter param) {
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
71 return param.getLocalName();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
72 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
73
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
74 private static String castValueName(ActualParameter parameter) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
75 return valueName(parameter) + "Cast";
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
76 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
77
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
78 private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame) {
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
79 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
80 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue"));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
81 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
82 for (ActualParameter parameter : specialization.getParameters()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
83 ParameterSpec spec = parameter.getSpecification();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
84 if (forceFrame && spec.getName().equals("frame")) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
85 continue;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
86 }
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
87 if (spec.isLocal()) {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
88 continue;
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
89 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
90
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
91 method.addParameter(new CodeVariableElement(parameter.getActualType(), valueName(parameter)));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
92 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
93 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
94
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
95 private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeImplicit) {
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
96 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
97 builder.string("frameValue");
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
98 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
99 for (ActualParameter parameter : specialization.getParameters()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
100 ParameterSpec spec = parameter.getSpecification();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
101 if (forceFrame && spec.getName().equals("frame")) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
102 continue;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
103 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
104
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
105 if (!includeImplicit && (parameter.isImplicit())) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
106 continue;
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
107 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
108 if (parameter.getSpecification().isLocal()) {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
109 continue;
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
110 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
111
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
112 if (unexpectedValueName != null && parameter.getLocalName().equals(unexpectedValueName)) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
113 builder.cast(parameter.getActualType(), CodeTreeBuilder.singleString("ex.getResult()"));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
114 } else {
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
115 builder.string(valueName(parameter));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
116 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
117 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
118 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
119
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
120 private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, TemplateMethod target, TemplateMethod sourceMethod, TemplateMethod castMethod, String unexpectedValueName) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
121 CodeTreeBuilder builder = parent.create();
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
122
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
123 boolean castedValues = sourceMethod != castMethod;
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
124
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
125 builder.startGroup();
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
126 ExecutableElement method = target.getMethod();
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
127 if (method == null) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
128 throw new IllegalStateException("Cannot call synthtetic operation methods.");
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
129 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
130 TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement());
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
131 NodeData node = (NodeData) castMethod.getTemplate();
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
132 TypeSystemData typeSystem = node.getTypeSystem();
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
133
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
134 boolean accessible = target.canBeAccessedByInstanceOf(node.getNodeType());
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
135 if (accessible) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
136 if (builder.findMethod().getModifiers().contains(STATIC)) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
137 builder.string(THIS_NODE_LOCAL_VAR_NAME);
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
138 } else {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
139 builder.string("super");
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
140 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
141 } else {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
142 if (method.getModifiers().contains(STATIC)) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
143 builder.type(targetClass.asType());
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
144 } else {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
145 ActualParameter parameter = null;
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
146 for (ActualParameter searchParameter : target.getParameters()) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
147 if (!searchParameter.getSpecification().isOptional()) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
148 parameter = searchParameter;
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
149 break;
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
150 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
151 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
152 assert parameter != null;
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
153
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
154 if (castedValues) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
155 NodeFieldData field = node.findField(parameter.getSpecification().getName());
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
156 if (field == null) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
157 builder.string(valueName(parameter));
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
158 } else {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
159 NodeData fieldNode = field.getNodeData();
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
160 ExecutableTypeData execType = fieldNode.findExecutableType(parameter.getActualTypeData(node.getTypeSystem()));
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
161 if (execType.hasUnexpectedValue(getContext())) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
162 builder.string(castValueName(parameter));
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
163 } else {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
164 builder.string(valueName(parameter));
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
165 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
166 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
167 } else {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
168 builder.string(valueName(parameter));
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
169 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
170 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
171 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
172 builder.string(".");
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
173 builder.startCall(method.getSimpleName().toString());
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
174
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
175 for (ActualParameter targetParameter : castMethod.getParameters()) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
176 ActualParameter valueParameter = sourceMethod.findParameter(targetParameter.getLocalName());
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
177 if (valueParameter == null) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
178 continue;
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
179 }
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
180 TypeData targetType = targetParameter.getActualTypeData(typeSystem);
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
181
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
182 if (targetParameter.isImplicit() || valueParameter.isImplicit()) {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
183 continue;
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
184 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
185
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
186 TypeData valueType = null;
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
187 if (valueParameter != null) {
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
188 valueType = valueParameter.getActualTypeData(typeSystem);
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
189 }
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
190
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
191 if (targetParameter.getSpecification().isLocal()) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
192 builder.startGroup();
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
193 if (builder.findMethod().getModifiers().contains(Modifier.STATIC)) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
194 builder.string(THIS_NODE_LOCAL_VAR_NAME).string(".");
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
195 } else {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
196 builder.string("this.");
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
197 }
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
198 builder.string(targetParameter.getSpecification().getName());
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
199 builder.end();
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
200 } else if (unexpectedValueName != null && targetParameter.getLocalName().equals(unexpectedValueName)) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
201 builder.string("ex.getResult()");
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
202 } else if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) {
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
203 builder.string(valueName(targetParameter));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
204 } else {
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
205 builder.string(castValueName(targetParameter));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
206 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
207 }
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
208
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
209 builder.end().end();
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
210
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
211 return builder.getRoot();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
212 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
213
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
214 private static String genClassName(Template operation) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
215 return getSimpleName(operation.getTemplateType()) + "Gen";
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
216 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
217
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
218 private String generatedGenericMethodName(SpecializationData specialization) {
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
219 final String prefix = "generic";
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
220
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
221 if (specialization == null) {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
222 return prefix;
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
223 }
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
224
8277
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
225 if (!specialization.getNode().needsRewrites(context)) {
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
226 return prefix;
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
227 }
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
228
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
229 SpecializationData prev = null;
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
230 for (SpecializationData current : specialization.getNode().getSpecializations()) {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
231 if (specialization == current) {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
232 if (prev == null || prev.isUninitialized()) {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
233 return prefix;
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
234 } else {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
235 return prefix + current.getId();
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
236 }
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
237 }
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
238 prev = current;
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
239 }
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
240 return prefix;
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
241 }
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
242
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
243 private static CodeTree createCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder parent, NodeData node, String methodName, String value) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
244 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
245 startCallTypeSystemMethod(context, builder, node, methodName);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
246 builder.string(value);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
247 builder.end().end();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
248 return builder.getRoot();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
249 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
250
7530
5e3d1a68664e applied mx eclipseformat to all Java files
Doug Simon <doug.simon@oracle.com>
parents: 7502
diff changeset
251 private static void startCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder body, NodeData node, String methodName) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
252 VariableElement singleton = TypeSystemCodeGenerator.findSingleton(context, node.getTypeSystem());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
253 assert singleton != null;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
254
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
255 body.startGroup();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
256 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
257 body.string(".").startCall(methodName);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
258 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
259
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
260 private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean onSpecialization,
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
261 CodeTree guardedStatements, CodeTree elseStatements) {
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
262
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
263 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
264 CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, valueSpecialization, guardedSpecialization);
8592
a80bf36c6a1e Refactor to shared template method signature comparison.
Christian Humer <christian.humer@gmail.com>
parents: 8361
diff changeset
265 CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, valueSpecialization, guardedSpecialization);
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
266
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
267 int ifCount = 0;
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
268
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
269 if (implicitGuards != null) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
270 builder.startIf();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
271 builder.tree(implicitGuards);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
272 builder.end();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
273 builder.startBlock();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
274 ifCount++;
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
275 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
276
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
277 if (explicitGuards != null || !onSpecialization) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
278 builder.tree(createCasts(parent, valueSpecialization, guardedSpecialization));
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
279 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
280
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
281 if (explicitGuards != null) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
282 builder.startIf();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
283 builder.tree(explicitGuards);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
284 builder.end();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
285 builder.startBlock();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
286 ifCount++;
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
287 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
288
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
289 if (implicitGuards == null && explicitGuards == null && conditionPrefix != null && !conditionPrefix.isEmpty()) {
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
290 builder.startIf();
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
291 builder.string(conditionPrefix);
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
292 builder.end().startBlock();
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
293 ifCount++;
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
294 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
295
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
296 builder.tree(guardedStatements);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
297
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
298 builder.end(ifCount);
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
299 if (elseStatements != null && ifCount > 0) {
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
300 builder.tree(elseStatements);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
301 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
302 return builder.getRoot();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
303 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
304
8592
a80bf36c6a1e Refactor to shared template method signature comparison.
Christian Humer <christian.humer@gmail.com>
parents: 8361
diff changeset
305 private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
306 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
307 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
308 if (guardedSpecialization.getGuards().size() > 0) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
309 // Explicitly specified guards
8592
a80bf36c6a1e Refactor to shared template method signature comparison.
Christian Humer <christian.humer@gmail.com>
parents: 8361
diff changeset
310 for (GuardData guard : guardedSpecialization.getGuards()) {
a80bf36c6a1e Refactor to shared template method signature comparison.
Christian Humer <christian.humer@gmail.com>
parents: 8361
diff changeset
311 builder.string(andOperator);
a80bf36c6a1e Refactor to shared template method signature comparison.
Christian Humer <christian.humer@gmail.com>
parents: 8361
diff changeset
312 builder.tree(createTemplateMethodCall(parent, guard, valueSpecialization, guardedSpecialization, null));
a80bf36c6a1e Refactor to shared template method signature comparison.
Christian Humer <christian.humer@gmail.com>
parents: 8361
diff changeset
313 andOperator = " && ";
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
314 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
315 }
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
316
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
317 return builder.isEmpty() ? null : builder.getRoot();
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
318 }
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
319
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
320 private CodeTree createCasts(CodeTreeBuilder parent, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
321 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
322 // Implict guards based on method signature
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
323 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
324 NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName());
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
325 if (field == null || field.getKind() == FieldKind.FIELD) {
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
326 continue;
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
327 }
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
328 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
329
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
330 CodeTree cast = createCast(parent, field, valueParam, guardedParam);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
331 if (cast == null) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
332 continue;
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
333 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
334 builder.tree(cast);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
335 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
336
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
337 return builder.getRoot();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
338 }
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
339
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
340 private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
341 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
342 // Implict guards based on method signature
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
343 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
344 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
345 NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName());
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
346 if (field == null || field.getKind() == FieldKind.FIELD) {
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
347 continue;
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
348 }
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
349 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
350
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
351 CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
352 if (implicitGuard == null) {
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
353 continue;
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
354 }
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
355
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
356 builder.string(andOperator);
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
357 builder.tree(implicitGuard);
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
358 andOperator = " && ";
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
359 }
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
360
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
361 return builder.isEmpty() ? null : builder.getRoot();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
362 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
363
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
364 private CodeTree createImplicitGuard(CodeTreeBuilder parent, NodeFieldData field, ActualParameter source, ActualParameter target) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
365 NodeData node = field.getNodeData();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
366 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
367
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
368 TypeData targetType = target.getActualTypeData(node.getTypeSystem());
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
369 TypeData sourceType = source.getActualTypeData(node.getTypeSystem());
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
370
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
371 if (targetType.equalsType(sourceType) || targetType.isGeneric()) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
372 return null;
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
373 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
374
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
375 builder.startGroup();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
376
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
377 if (field.isShortCircuit()) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
378 ActualParameter shortCircuit = target.getPreviousParameter();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
379 assert shortCircuit != null;
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
380 builder.string("(");
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
381 builder.string("!").string(valueName(shortCircuit));
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
382 builder.string(" || ");
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
383 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
384
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
385 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(target.getActualTypeData(node.getTypeSystem())));
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
386 builder.string(valueName(source));
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
387 builder.end().end(); // call
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
388
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
389 if (field.isShortCircuit()) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
390 builder.string(")");
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
391 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
392
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
393 builder.end(); // group
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
394
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
395 return builder.getRoot();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
396 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
397
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
398 private CodeTree createCast(CodeTreeBuilder parent, NodeFieldData field, ActualParameter source, ActualParameter target) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
399 NodeData node = field.getNodeData();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
400 TypeSystemData typeSystem = node.getTypeSystem();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
401
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
402 TypeData sourceType = source.getActualTypeData(typeSystem);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
403 TypeData targetType = target.getActualTypeData(typeSystem);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
404
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
405 if (targetType.equalsType(sourceType) || targetType.isGeneric()) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
406 return null;
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
407 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
408
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
409 CodeTree condition = null;
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
410 if (field.isShortCircuit()) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
411 ActualParameter shortCircuit = target.getPreviousParameter();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
412 assert shortCircuit != null;
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
413 condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
414 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
415
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
416 CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), valueName(target));
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
417
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
418 return createLazyAssignment(parent, castValueName(target), target.getActualType(), condition, value);
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
419 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
420
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
421 /**
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
422 * <pre>
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
423 * variant1 $condition != null
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
424 *
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
425 * $type $name = defaultValue($type);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
426 * if ($condition) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
427 * $name = $value;
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
428 * }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
429 *
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
430 * variant2 $condition != null
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
431 * $type $name = $value;
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
432 * </pre>
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
433 *
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
434 * .
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
435 */
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
436 private static CodeTree createLazyAssignment(CodeTreeBuilder parent, String name, TypeMirror type, CodeTree condition, CodeTree value) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
437 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
438 if (condition == null) {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
439 builder.declaration(type, name, value);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
440 } else {
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
441 builder.declaration(type, name, new CodeTreeBuilder(parent).defaultValue(type).getRoot());
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
442
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
443 builder.startIf().tree(condition).end();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
444 builder.startBlock();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
445 builder.startStatement();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
446 builder.string(name);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
447 builder.string(" = ");
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
448 builder.tree(value);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
449 builder.end(); // statement
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
450 builder.end(); // block
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
451 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
452 return builder.getRoot();
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
453 }
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
454
8251
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
455 private void emitEncounteredSynthetic(CodeTreeBuilder builder) {
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
456 builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).end().end();
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
457 }
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
458
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
459 @Override
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
460 protected void createChildren(NodeData node) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
461 Map<NodeData, List<TypeElement>> childTypes = new LinkedHashMap<>();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
462 if (node.getDeclaredChildren() != null && !node.getDeclaredChildren().isEmpty()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
463 for (NodeData nodeChild : node.getDeclaredChildren()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
464 NodeCodeGenerator generator = new NodeCodeGenerator(getContext());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
465 childTypes.put(nodeChild, generator.process(null, nodeChild).getEnclosedElements());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
466 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
467 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
468
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
469 if (node.getExtensionElements() != null && !node.getExtensionElements().isEmpty()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
470 NodeGenFactory factory = new NodeGenFactory(context);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
471 add(factory, node);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
472 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
473
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
474 if (node.needsFactory() || node.getNodeChildren().size() > 0) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
475 add(new NodeFactoryFactory(context, childTypes), node);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
476 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
477 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
478
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
479 private class NodeGenFactory extends ClassElementFactory<NodeData> {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
480
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
481 public NodeGenFactory(ProcessorContext context) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
482 super(context);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
483 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
484
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
485 @Override
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
486 protected CodeTypeElement create(NodeData node) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
487 CodeTypeElement clazz = createClass(node, modifiers(PUBLIC, ABSTRACT), genClassName(node), node.getTemplateType().asType(), false);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
488
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
489 for (ExecutableElement executable : ElementFilter.constructorsIn(node.getTemplateType().getEnclosedElements())) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
490 CodeExecutableElement superConstructor = createSuperConstructor(clazz, executable);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
491
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
492 if (superConstructor != null) {
7530
5e3d1a68664e applied mx eclipseformat to all Java files
Doug Simon <doug.simon@oracle.com>
parents: 7502
diff changeset
493 if (superConstructor.getParameters().size() == 1 && Utils.typeEquals(superConstructor.getParameters().get(0).asType(), node.getTemplateType().asType())) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
494 String originalName = superConstructor.getParameters().get(0).getSimpleName().toString();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
495 superConstructor.getParameters().clear();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
496 superConstructor.getParameters().add(new CodeVariableElement(clazz.asType(), originalName));
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
497 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
498 clazz.add(superConstructor);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
499 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
500 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
501
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
502 if (node.getExtensionElements() != null) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
503 clazz.getEnclosedElements().addAll(node.getExtensionElements());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
504 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
505
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
506 node.setNodeType(clazz.asType());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
507
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
508 return clazz;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
509 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
510
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
511 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
512
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
513 private class NodeFactoryFactory extends ClassElementFactory<NodeData> {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
514
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
515 private final Map<NodeData, List<TypeElement>> childTypes;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
516
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
517 public NodeFactoryFactory(ProcessorContext context, Map<NodeData, List<TypeElement>> childElements) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
518 super(context);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
519 this.childTypes = childElements;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
520 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
521
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
522 @Override
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
523 protected CodeTypeElement create(NodeData node) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
524 Modifier visibility = Utils.getVisibility(node.getTemplateType().getModifiers());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
525 CodeTypeElement clazz = createClass(node, modifiers(), factoryClassName(node), null, false);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
526 if (visibility != null) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
527 clazz.getModifiers().add(visibility);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
528 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
529 clazz.getModifiers().add(Modifier.FINAL);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
530 clazz.add(createConstructorUsingFields(modifiers(PRIVATE), clazz));
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
531 return clazz;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
532 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
533
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
534 @Override
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
535 protected void createChildren(NodeData node) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
536 CodeTypeElement clazz = getElement();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
537
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
538 Modifier createVisibility = Utils.getVisibility(clazz.getModifiers());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
539
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
540 if (node.needsFactory()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
541 createFactoryMethods(node, clazz, createVisibility);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
542
8242
ac4e8c16ffdf Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings.
Christian Humer <christian.humer@gmail.com>
parents: 8237
diff changeset
543 if (node.getSpecializations().size() > 1) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
544 clazz.add(createCreateSpecializedMethod(node, createVisibility));
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
545 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
546
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
547 if (node.needsRewrites(context)) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
548 clazz.add(createSpecializeMethod(node));
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
549 }
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
550
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
551 if (node.getGenericSpecialization() != null) {
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
552 List<CodeExecutableElement> genericMethods = createGeneratedGenericMethod(node);
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
553 for (CodeExecutableElement method : genericMethods) {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
554 clazz.add(method);
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
555 }
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
556 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
557
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
558 for (SpecializationData specialization : node.getSpecializations()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
559 add(new SpecializedNodeFactory(context), specialization);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
560 }
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
561
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
562 TypeMirror nodeFactory = getContext().getEnvironment().getTypeUtils().getDeclaredType(Utils.fromTypeMirror(getContext().getType(NodeFactory.class)), node.getNodeType());
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
563 clazz.getImplements().add(nodeFactory);
7859
3c68170fc9b0 Fixed a visibility bug in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7858
diff changeset
564 clazz.add(createCreateNodeMethod(node));
3c68170fc9b0 Fixed a visibility bug in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7858
diff changeset
565 clazz.add(createCreateNodeSpecializedMethod(node));
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
566 clazz.add(createGetNodeClassMethod(node));
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
567 clazz.add(createGetNodeSignaturesMethod(node));
8248
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
568 clazz.add(createGetChildrenSignatureMethod(node));
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
569 clazz.add(createGetInstanceMethod(node, createVisibility));
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
570 clazz.add(createInstanceConstant(node, clazz.asType()));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
571 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
572
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
573 for (NodeData childNode : childTypes.keySet()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
574 if (childNode.getTemplateType().getModifiers().contains(Modifier.PRIVATE)) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
575 continue;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
576 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
577
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
578 for (TypeElement type : childTypes.get(childNode)) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
579 Set<Modifier> typeModifiers = ((CodeTypeElement) type).getModifiers();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
580 Modifier visibility = Utils.getVisibility(type.getModifiers());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
581 typeModifiers.clear();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
582 if (visibility != null) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
583 typeModifiers.add(visibility);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
584 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
585
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
586 typeModifiers.add(Modifier.STATIC);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
587 typeModifiers.add(Modifier.FINAL);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
588 clazz.add(type);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
589 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
590 }
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
591
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
592 List<NodeData> children = node.getNodeChildren();
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
593 if (node.getParent() == null && children.size() > 0) {
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
594 clazz.add(createGetFactories(node));
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
595 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
596
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
597 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
598
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
599 private CodeExecutableElement createGetNodeClassMethod(NodeData node) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
600 Types types = getContext().getEnvironment().getTypeUtils();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
601 TypeMirror returnType = types.getDeclaredType(Utils.fromTypeMirror(getContext().getType(Class.class)), node.getNodeType());
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
602 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getNodeClass");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
603 CodeTreeBuilder builder = method.createBuilder();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
604 builder.startReturn().typeLiteral(node.getNodeType()).end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
605 return method;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
606 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
607
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
608 private CodeExecutableElement createGetNodeSignaturesMethod(NodeData node) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
609 Types types = getContext().getEnvironment().getTypeUtils();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
610 TypeElement listType = Utils.fromTypeMirror(getContext().getType(List.class));
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
611 TypeMirror classType = getContext().getType(Class.class);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
612 TypeMirror returnType = types.getDeclaredType(listType, types.getDeclaredType(listType, classType));
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
613 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getNodeSignatures");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
614 CodeTreeBuilder builder = method.createBuilder();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
615 builder.startReturn();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
616 builder.startStaticCall(getContext().getType(Arrays.class), "asList");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
617 List<ExecutableElement> constructors = findUserConstructors(node);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
618 for (ExecutableElement constructor : constructors) {
8248
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
619 builder.tree(createAsList(builder, Utils.asTypeMirrors(constructor.getParameters()), classType));
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
620 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
621 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
622 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
623 return method;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
624 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
625
8248
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
626 private CodeExecutableElement createGetChildrenSignatureMethod(NodeData node) {
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
627 Types types = getContext().getEnvironment().getTypeUtils();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
628 TypeElement listType = Utils.fromTypeMirror(getContext().getType(List.class));
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
629 TypeMirror classType = getContext().getType(Class.class);
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
630 TypeMirror nodeType = getContext().getTruffleTypes().getNode();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
631 TypeMirror wildcardNodeType = types.getWildcardType(nodeType, null);
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
632 classType = types.getDeclaredType(Utils.fromTypeMirror(classType), wildcardNodeType);
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
633 TypeMirror returnType = types.getDeclaredType(listType, classType);
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
634
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
635 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getExecutionSignature");
8248
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
636 CodeTreeBuilder builder = method.createBuilder();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
637
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
638 List<TypeMirror> signatureTypes = new ArrayList<>();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
639 assert !node.getSpecializations().isEmpty();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
640 SpecializationData data = node.getSpecializations().get(0);
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
641 for (ActualParameter parameter : data.getParameters()) {
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
642 ParameterSpec spec = parameter.getSpecification();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
643 NodeFieldData field = node.findField(spec.getName());
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
644 if (field == null || field.getKind() == FieldKind.FIELD) {
8248
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
645 continue;
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
646 }
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
647
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
648 TypeMirror type;
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
649 if (field.getKind() == FieldKind.CHILDREN && field.getType().getKind() == TypeKind.ARRAY) {
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
650 type = ((ArrayType) field.getType()).getComponentType();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
651 } else {
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
652 type = field.getType();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
653 }
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
654
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
655 signatureTypes.add(type);
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
656 }
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
657
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
658 builder.startReturn().tree(createAsList(builder, signatureTypes, classType)).end();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
659 return method;
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
660 }
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
661
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
662 private CodeTree createAsList(CodeTreeBuilder parent, List<TypeMirror> types, TypeMirror elementClass) {
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
663 CodeTreeBuilder builder = parent.create();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
664 builder.startGroup();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
665 builder.type(getContext().getType(Arrays.class));
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
666 builder.string(".<").type(elementClass).string(">");
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
667 builder.startCall("asList");
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
668 for (TypeMirror typeMirror : types) {
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
669 builder.typeLiteral(typeMirror);
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
670 }
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
671 builder.end().end();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
672 return builder.getRoot();
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
673 }
c4c3f50fa9c2 Fixes for codegen builtins support.
Christian Humer <christian.humer@gmail.com>
parents: 8245
diff changeset
674
7859
3c68170fc9b0 Fixed a visibility bug in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7858
diff changeset
675 private CodeExecutableElement createCreateNodeMethod(NodeData node) {
3c68170fc9b0 Fixed a visibility bug in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7858
diff changeset
676 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode");
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
677 CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Object.class), "arguments");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
678 method.setVarArgs(true);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
679 method.addParameter(arguments);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
680
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
681 CodeTreeBuilder builder = method.createBuilder();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
682 List<ExecutableElement> signatures = findUserConstructors(node);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
683 boolean ifStarted = false;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
684
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
685 for (ExecutableElement element : signatures) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
686 ifStarted = builder.startIf(ifStarted);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
687 builder.string("arguments.length == " + element.getParameters().size());
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
688
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
689 int index = 0;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
690 for (VariableElement param : element.getParameters()) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
691 builder.string(" && ");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
692 if (!param.asType().getKind().isPrimitive()) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
693 builder.string("(arguments[" + index + "] == null || ");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
694 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
695 builder.string("arguments[" + index + "] instanceof ");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
696 builder.type(Utils.boxType(getContext(), param.asType()));
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
697 if (!param.asType().getKind().isPrimitive()) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
698 builder.string(")");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
699 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
700 index++;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
701 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
702 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
703 builder.startBlock();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
704
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
705 builder.startReturn().startCall("create");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
706 index = 0;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
707 for (VariableElement param : element.getParameters()) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
708 builder.startGroup();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
709 builder.string("(").type(param.asType()).string(") ");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
710 builder.string("arguments[").string(String.valueOf(index)).string("]");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
711 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
712 index++;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
713 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
714 builder.end().end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
715
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
716 builder.end(); // block
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
717 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
718
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
719 builder.startElseBlock();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
720 builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class));
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
721 builder.doubleQuote("Invalid create signature.");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
722 builder.end().end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
723 builder.end(); // else block
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
724 return method;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
725 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
726
7859
3c68170fc9b0 Fixed a visibility bug in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7858
diff changeset
727 private CodeExecutableElement createCreateNodeSpecializedMethod(NodeData node) {
3c68170fc9b0 Fixed a visibility bug in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7858
diff changeset
728 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNodeSpecialized");
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
729 CodeVariableElement nodeParam = new CodeVariableElement(node.getNodeType(), "thisNode");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
730 CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Class.class), "types");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
731 method.addParameter(nodeParam);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
732 method.addParameter(arguments);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
733 method.setVarArgs(true);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
734
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
735 CodeTreeBuilder builder = method.createBuilder();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
736 if (!node.needsRewrites(getContext())) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
737 builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).end().end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
738 } else {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
739 builder.startIf();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
740 builder.string("types.length == 1");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
741 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
742 builder.startBlock();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
743
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
744 builder.startReturn().startCall("createSpecialized");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
745 builder.string("thisNode");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
746 builder.string("types[0]");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
747 builder.end().end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
748
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
749 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
750 builder.startElseBlock();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
751 builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class));
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
752 builder.doubleQuote("Invalid createSpecialized signature.");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
753 builder.end().end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
754 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
755 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
756
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
757 return method;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
758 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
759
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
760 private ExecutableElement createGetInstanceMethod(NodeData node, Modifier visibility) {
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
761 Types types = getContext().getEnvironment().getTypeUtils();
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
762 TypeElement nodeFactoryType = Utils.fromTypeMirror(getContext().getType(NodeFactory.class));
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
763 TypeMirror returnType = types.getDeclaredType(nodeFactoryType, node.getNodeType());
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
764
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
765 CodeExecutableElement method = new CodeExecutableElement(modifiers(), returnType, "getInstance");
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
766 if (visibility != null) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
767 method.getModifiers().add(visibility);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
768 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
769 method.getModifiers().add(Modifier.STATIC);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
770
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
771 String varName = instanceVarName(node);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
772
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
773 CodeTreeBuilder builder = method.createBuilder();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
774 builder.startIf();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
775 builder.string(varName).string(" == null");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
776 builder.end().startBlock();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
777
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
778 builder.startStatement();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
779 builder.string(varName);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
780 builder.string(" = ");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
781 builder.startNew(factoryClassName(node)).end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
782 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
783
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
784 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
785 builder.startReturn().string(varName).end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
786 return method;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
787 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
788
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
789 private String instanceVarName(NodeData node) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
790 if (node.getParent() != null) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
791 return Utils.firstLetterLowerCase(factoryClassName(node)) + "Instance";
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
792 } else {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
793 return "instance";
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
794 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
795 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
796
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
797 private CodeVariableElement createInstanceConstant(NodeData node, TypeMirror factoryType) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
798 String varName = instanceVarName(node);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
799 CodeVariableElement var = new CodeVariableElement(modifiers(), factoryType, varName);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
800 var.getModifiers().add(Modifier.PRIVATE);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
801 var.getModifiers().add(Modifier.STATIC);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
802 return var;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
803 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
804
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
805 private ExecutableElement createGetFactories(NodeData node) {
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
806 List<NodeData> children = node.getNodeChildren();
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
807 if (node.needsFactory()) {
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
808 children.add(node);
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
809 }
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
810
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
811 List<TypeMirror> nodeTypesList = new ArrayList<>();
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
812 TypeMirror prev = null;
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
813 boolean allSame = true;
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
814 for (NodeData child : children) {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
815 nodeTypesList.add(child.getNodeType());
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
816 if (prev != null && !Utils.typeEquals(child.getNodeType(), prev)) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
817 allSame = false;
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
818 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
819 prev = child.getNodeType();
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
820 }
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
821 TypeMirror commonNodeSuperType = Utils.getCommonSuperType(getContext(), nodeTypesList.toArray(new TypeMirror[nodeTypesList.size()]));
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
822
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
823 Types types = getContext().getEnvironment().getTypeUtils();
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
824 TypeMirror factoryType = getContext().getType(NodeFactory.class);
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
825 TypeMirror baseType;
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
826 if (allSame) {
7858
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
827 baseType = types.getDeclaredType(Utils.fromTypeMirror(factoryType), commonNodeSuperType);
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
828 } else {
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
829 baseType = types.getDeclaredType(Utils.fromTypeMirror(factoryType), types.getWildcardType(commonNodeSuperType, null));
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
830 }
4958cbdbf360 Fixed minor bugs in NodeFactory generation.
Christian Humer <christian.humer@gmail.com>
parents: 7855
diff changeset
831 TypeMirror listType = types.getDeclaredType(Utils.fromTypeMirror(getContext().getType(List.class)), baseType);
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
832
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
833 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), listType, "getFactories");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
834
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
835 CodeTreeBuilder builder = method.createBuilder();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
836 builder.startReturn();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
837 builder.startStaticCall(getContext().getType(Arrays.class), "asList");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
838
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
839 for (NodeData child : children) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
840 builder.startGroup();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
841 NodeData childNode = child;
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
842 List<NodeData> factories = new ArrayList<>();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
843 while (childNode.getParent() != null) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
844 factories.add(childNode);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
845 childNode = childNode.getParent();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
846 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
847 Collections.reverse(factories);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
848 for (NodeData nodeData : factories) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
849 builder.string(factoryClassName(nodeData)).string(".");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
850 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
851 builder.string("getInstance()");
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
852 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
853 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
854 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
855 builder.end();
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
856 return method;
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
857 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
858
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
859 private void createFactoryMethods(NodeData node, CodeTypeElement clazz, Modifier createVisibility) {
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
860 List<ExecutableElement> constructors = findUserConstructors(node);
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
861 for (ExecutableElement constructor : constructors) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
862 clazz.add(createCreateMethod(node, createVisibility, constructor));
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
863 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
864 }
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
865
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
866 private List<ExecutableElement> findUserConstructors(NodeData node) {
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
867 List<ExecutableElement> constructors = new ArrayList<>();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
868 for (ExecutableElement constructor : ElementFilter.constructorsIn(Utils.fromTypeMirror(node.getNodeType()).getEnclosedElements())) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
869 if (constructor.getModifiers().contains(PRIVATE)) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
870 continue;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
871 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
872
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
873 // skip node rewrite constructor
7530
5e3d1a68664e applied mx eclipseformat to all Java files
Doug Simon <doug.simon@oracle.com>
parents: 7502
diff changeset
874 if (constructor.getParameters().size() == 1 && typeEquals(constructor.getParameters().get(0).asType(), node.getNodeType())) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
875 continue;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
876 }
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
877 constructors.add(constructor);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
878 }
7855
6e4fb0ccebb1 Generated factories implement the new NodeFactory interface.
Christian Humer <christian.humer@gmail.com>
parents: 7847
diff changeset
879 return constructors;
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
880 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
881
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
882 private CodeExecutableElement createCreateMethod(NodeData node, Modifier visibility, ExecutableElement constructor) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
883 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), constructor);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
884 method.setSimpleName(CodeNames.of("create"));
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
885 method.getModifiers().clear();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
886 if (visibility != null) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
887 method.getModifiers().add(visibility);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
888 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
889 method.getModifiers().add(Modifier.STATIC);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
890 method.setReturnType(node.getNodeType());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
891
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
892 CodeTreeBuilder body = method.createBuilder();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
893 body.startReturn();
8242
ac4e8c16ffdf Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings.
Christian Humer <christian.humer@gmail.com>
parents: 8237
diff changeset
894 if (node.getSpecializations().isEmpty()) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
895 body.null_();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
896 } else {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
897 body.startNew(nodeSpecializationClassName(node.getSpecializations().get(0)));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
898 for (VariableElement var : method.getParameters()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
899 body.string(var.getSimpleName().toString());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
900 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
901 body.end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
902 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
903 body.end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
904 return method;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
905 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
906
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
907 private CodeExecutableElement createCreateSpecializedMethod(NodeData node, Modifier visibility) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
908 CodeExecutableElement method = new CodeExecutableElement(modifiers(), node.getNodeType(), "createSpecialized");
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
909 if (visibility != null) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
910 method.getModifiers().add(visibility);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
911 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
912 method.getModifiers().add(Modifier.STATIC);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
913
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
914 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
915 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "specializationClass"));
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
916
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
917 CodeTreeBuilder body = method.createBuilder();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
918 boolean first = true;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
919 for (TypeData type : node.getTypeSystem().getTypes()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
920 SpecializationData specialization = node.findUniqueSpecialization(type);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
921 if (specialization != null && !type.isGeneric()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
922 if (first) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
923 body.startIf();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
924 first = false;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
925 } else {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
926 body.startElseIf();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
927 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
928 body.string("specializationClass == ").type(type.getBoxedType()).string(".class").end().startBlock();
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
929 body.startReturn().startNew(nodeSpecializationClassName(specialization));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
930 body.string(THIS_NODE_LOCAL_VAR_NAME);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
931 body.end().end(); // new, return
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
932
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
933 body.end(); // if
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
934 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
935 }
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
936 body.startReturn().startNew(nodeSpecializationClassName(node.getGenericSpecialization()));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
937 body.string(THIS_NODE_LOCAL_VAR_NAME);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
938 body.end().end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
939 return method;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
940 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
941
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
942 private CodeExecutableElement createSpecializeMethod(NodeData node) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
943 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getNodeType(), "specialize");
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
944 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
945 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState"));
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
946 addInternalValueParameters(method, node.getGenericSpecialization(), false);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
947
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
948 CodeTreeBuilder body = method.createBuilder();
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
949 body.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
950
8242
ac4e8c16ffdf Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings.
Christian Humer <christian.humer@gmail.com>
parents: 8237
diff changeset
951 for (int i = 1; i < node.getSpecializations().size(); i++) {
ac4e8c16ffdf Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings.
Christian Humer <christian.humer@gmail.com>
parents: 8237
diff changeset
952 SpecializationData specialization = node.getSpecializations().get(i);
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
953 body.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(specialization)).string(".class)").end();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
954
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
955 CodeTreeBuilder guarded = new CodeTreeBuilder(body);
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
956 guarded.startReturn().startNew(nodeSpecializationClassName(specialization));
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
957 guarded.string(THIS_NODE_LOCAL_VAR_NAME);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
958 guarded.end().end();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
959
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
960 body.tree(createGuardAndCast(body, "allowed", node.getGenericSpecialization(), specialization, true, guarded.getRoot(), null));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
961 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
962 body.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
963
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
964 return method;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
965 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
966
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
967 private List<CodeExecutableElement> createGeneratedGenericMethod(NodeData node) {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
968 TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getActualType();
8277
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
969 if (node.needsRewrites(context)) {
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
970 List<CodeExecutableElement> methods = new ArrayList<>();
7751
ef1b41ea0a90 Implemented an option to turn off generated generic generation using specializations in @Generic.
Christian Humer <christian.humer@gmail.com>
parents: 7750
diff changeset
971
8242
ac4e8c16ffdf Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings.
Christian Humer <christian.humer@gmail.com>
parents: 8237
diff changeset
972 List<SpecializationData> specializations = node.getSpecializations();
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
973 SpecializationData prev = null;
8242
ac4e8c16ffdf Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings.
Christian Humer <christian.humer@gmail.com>
parents: 8237
diff changeset
974 for (int i = 0; i < specializations.size(); i++) {
ac4e8c16ffdf Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings.
Christian Humer <christian.humer@gmail.com>
parents: 8237
diff changeset
975 SpecializationData current = specializations.get(i);
ac4e8c16ffdf Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings.
Christian Humer <christian.humer@gmail.com>
parents: 8237
diff changeset
976 SpecializationData next = i + 1 < specializations.size() ? specializations.get(i + 1) : null;
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
977 if (prev == null || current.isUninitialized()) {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
978 prev = current;
7751
ef1b41ea0a90 Implemented an option to turn off generated generic generation using specializations in @Generic.
Christian Humer <christian.humer@gmail.com>
parents: 7750
diff changeset
979 continue;
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
980 } else {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
981 String methodName = generatedGenericMethodName(current);
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
982 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, methodName);
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
983 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
984 addInternalValueParameters(method, node.getGenericSpecialization(), true);
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
985
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
986 emitGeneratedGenericSpecialization(method.createBuilder(), current, next);
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
987
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
988 methods.add(method);
7751
ef1b41ea0a90 Implemented an option to turn off generated generic generation using specializations in @Generic.
Christian Humer <christian.humer@gmail.com>
parents: 7750
diff changeset
989 }
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
990 prev = current;
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
991 }
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
992
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
993 return methods;
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
994 } else {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
995 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, generatedGenericMethodName(null));
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
996 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
997 addInternalValueParameters(method, node.getGenericSpecialization(), true);
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
998 emitInvokeDoMethod(method.createBuilder(), node.getGenericSpecialization(), 0);
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
999 return Arrays.asList(method);
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1000 }
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1001 }
7751
ef1b41ea0a90 Implemented an option to turn off generated generic generation using specializations in @Generic.
Christian Humer <christian.humer@gmail.com>
parents: 7750
diff changeset
1002
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1003 private void emitGeneratedGenericSpecialization(CodeTreeBuilder builder, SpecializationData current, SpecializationData next) {
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1004 CodeTreeBuilder invokeMethodBuilder = new CodeTreeBuilder(builder);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1005 emitInvokeDoMethod(invokeMethodBuilder, current, 0);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1006 CodeTree invokeMethod = invokeMethodBuilder.getRoot();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1007
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1008 if (next != null) {
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
1009 CodeTreeBuilder nextBuilder = builder.create();
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
1010
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
1011 nextBuilder.startReturn().startCall(generatedGenericMethodName(next));
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
1012 nextBuilder.string(THIS_NODE_LOCAL_VAR_NAME);
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1013 addInternalValueParameterNames(nextBuilder, next, null, true, true);
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
1014 nextBuilder.end().end();
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
1015
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
1016 invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, false, invokeMethod, nextBuilder.getRoot());
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1017 }
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1018
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1019 builder.tree(invokeMethod);
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1020
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1021 if (next != null) {
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1022 builder.end();
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1023 }
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1024 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1025
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1026 private void emitInvokeDoMethod(CodeTreeBuilder builder, SpecializationData specialization, int level) {
8243
d81ff782fa1a Removed @SpecializationThrows from codegen API. Replaced it by a simplier version in @Specialization.
Christian Humer <christian.humer@gmail.com>
parents: 8242
diff changeset
1027 if (!specialization.getExceptions().isEmpty()) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1028 builder.startTryBlock();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1029 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1030
8256
4dc7034317ec Cleanup.
Christian Humer <christian.humer@gmail.com>
parents: 8252
diff changeset
1031 if (specialization.getMethod() == null) {
8251
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
1032 emitEncounteredSynthetic(builder);
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
1033 } else {
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
1034 builder.startReturn();
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1035 builder.tree(createTemplateMethodCall(builder, specialization, specialization.getNode().getGenericSpecialization(), specialization, null));
8251
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
1036 builder.end(); // return
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
1037 }
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1038
8243
d81ff782fa1a Removed @SpecializationThrows from codegen API. Replaced it by a simplier version in @Specialization.
Christian Humer <christian.humer@gmail.com>
parents: 8242
diff changeset
1039 if (!specialization.getExceptions().isEmpty()) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1040 for (SpecializationThrowsData exception : specialization.getExceptions()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1041 builder.end().startCatchBlock(exception.getJavaClass(), "ex" + level);
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1042
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1043 builder.startReturn().startCall(generatedGenericMethodName(exception.getTransitionTo()));
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1044 builder.string(THIS_NODE_LOCAL_VAR_NAME);
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1045 addInternalValueParameterNames(builder, exception.getTransitionTo(), null, true, true);
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1046 builder.end().end();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1047 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1048 builder.end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1049 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1050 }
8251
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
1051
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1052 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1053
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1054 private class SpecializedNodeFactory extends ClassElementFactory<SpecializationData> {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1055
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1056 public SpecializedNodeFactory(ProcessorContext context) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1057 super(context);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1058 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1059
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1060 @Override
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1061 public CodeTypeElement create(SpecializationData specialization) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1062 NodeData node = specialization.getNode();
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1063 CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), node.getNodeType(), false);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1064 return clazz;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1065 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1066
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1067 @Override
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1068 protected void createChildren(SpecializationData specialization) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1069 CodeTypeElement clazz = getElement();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1070 NodeData node = specialization.getNode();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1071
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1072 TypeElement superTypeElement = Utils.fromTypeMirror(clazz.getSuperclass());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1073 for (ExecutableElement constructor : ElementFilter.constructorsIn(superTypeElement.getEnclosedElements())) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1074 ExecutableElement superConstructor = createSuperConstructor(clazz, constructor);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1075 if (superConstructor != null) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1076 clazz.add(superConstructor);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1077 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1078 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1079
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1080 for (ExecutableTypeData execType : node.getExecutableTypes()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1081 if (execType.isFinal()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1082 continue;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1083 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1084 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1085 if (method.getParameters().size() == 1) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1086 CodeVariableElement var = CodeVariableElement.clone(method.getParameters().get(0));
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1087 var.setName("frameValue");
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1088 method.getParameters().set(0, var);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1089 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1090 method.getModifiers().remove(Modifier.ABSTRACT);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1091 clazz.add(method);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1092
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1093 TypeData primaryType = specialization.getReturnType().getActualTypeData(node.getTypeSystem());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1094 if (primaryType == execType.getType()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1095 buildFunctionalExecuteMethod(method.createBuilder(), specialization);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1096 } else {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1097 buildCastingExecuteMethod(method.createBuilder(), specialization, execType.getType());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1098 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1099 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1100
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1101 if (node.needsRewrites(getContext()) && !specialization.isGeneric() && !specialization.isUninitialized()) {
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1102 buildSpecializeAndExecute(clazz, specialization);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1103 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1104 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1105
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1106 private void buildCastingExecuteMethod(CodeTreeBuilder builder, SpecializationData specialization, TypeData type) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1107 NodeData node = specialization.getNode();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1108 TypeSystemData typeSystem = node.getTypeSystem();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1109
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1110 ExecutableTypeData castedType = node.findExecutableType(type);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1111 TypeData primaryType = specialization.getReturnType().getActualTypeData(typeSystem);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1112 ExecutableTypeData execType = specialization.getNode().findExecutableType(primaryType);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1113
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1114 boolean needsTry = execType.hasUnexpectedValue(getContext());
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1115 boolean returnVoid = type.isVoid();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1116
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1117 CodeTree primaryExecuteCall = null;
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1118
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1119 CodeTreeBuilder executeBuilder = CodeTreeBuilder.createBuilder();
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1120 buildExecute(executeBuilder, null, null, execType);
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1121 primaryExecuteCall = executeBuilder.getRoot();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1122
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1123 if (needsTry) {
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1124 if (!returnVoid) {
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1125 builder.declaration(primaryType.getPrimitiveType(), "value");
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1126 }
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1127 builder.startTryBlock();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1128
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1129 if (returnVoid) {
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1130 builder.statement(primaryExecuteCall);
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1131 } else {
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1132 builder.startStatement();
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1133 builder.string("value = ");
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1134 builder.tree(primaryExecuteCall);
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1135 builder.end();
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1136 }
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1137
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1138 builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1139 if (returnVoid) {
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1140 builder.string("// ignore").newLine();
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1141 } else {
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1142 builder.startReturn();
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1143 builder.tree(createExpectType(node, castedType, CodeTreeBuilder.singleString("ex.getResult()")));
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1144 builder.end();
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1145 }
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1146 builder.end();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1147
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1148 if (!returnVoid) {
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1149 builder.startReturn();
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1150 builder.tree(createExpectType(node, castedType, CodeTreeBuilder.singleString("value")));
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1151 builder.end();
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1152 }
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1153 } else {
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1154 if (returnVoid) {
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1155 builder.statement(primaryExecuteCall);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1156 } else {
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1157 builder.startReturn();
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1158 builder.tree(createExpectType(node, castedType, primaryExecuteCall));
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1159 builder.end();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1160 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1161 }
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1162 }
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1163
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1164 private CodeTree createExpectType(NodeData node, ExecutableTypeData castedType, CodeTree value) {
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1165 if (castedType == null) {
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1166 return value;
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1167 } else if (castedType.getType().isVoid()) {
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1168 return value;
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1169 } else if (castedType.getType().isGeneric()) {
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1170 return value;
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1171 }
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1172
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1173 CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1174 String targetMethodName;
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1175 if (castedType.hasUnexpectedValue(getContext())) {
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1176 targetMethodName = TypeSystemCodeGenerator.expectTypeMethodName(castedType.getType());
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1177 } else {
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1178 targetMethodName = TypeSystemCodeGenerator.asTypeMethodName(castedType.getType());
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1179 }
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1180 startCallTypeSystemMethod(getContext(), builder, node, targetMethodName);
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1181
7750
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1182 builder.tree(value);
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1183 builder.end().end();
bdcb3cc47e16 Generated nodes can now handle the case were a non generic execute methods does not throw an UVE.
Christian Humer <christian.humer@gmail.com>
parents: 7679
diff changeset
1184 return builder.getRoot();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1185 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1186
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1187 private void buildFunctionalExecuteMethod(CodeTreeBuilder builder, SpecializationData specialization) {
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1188 if (specialization.isUninitialized()) {
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1189 builder.tree(createDeoptimize(builder));
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1190 }
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1191
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1192 builder.tree(createExecuteChildren(builder, specialization));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1193
8361
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1194 CodeTree executeNode;
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1195 if (specialization.isUninitialized()) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1196 builder.tree(createSpecializeCall(builder, specialization));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1197 }
8361
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1198 executeNode = createExecute(builder, specialization);
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1199
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1200 SpecializationData next = specialization.findNextSpecialization();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1201 CodeTree returnSpecialized = null;
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1202 if (next != null) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1203 returnSpecialized = createReturnSpecializeAndExecute(builder, next, null);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1204 }
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1205 builder.tree(createGuardAndCast(builder, null, specialization, specialization, false, executeNode, returnSpecialized));
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1206 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1207
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1208 private CodeTree createDeoptimize(CodeTreeBuilder parent) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1209 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1210 builder.startStatement();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1211 builder.startStaticCall(getContext().getTruffleTypes().getTruffleIntrinsics(), "deoptimize").end();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1212 builder.end();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1213 return builder.getRoot();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1214 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1215
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1216 private CodeTree createSpecializeCall(CodeTreeBuilder parent, SpecializationData specialization) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1217 NodeData node = specialization.getNode();
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1218
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1219 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1220 emitSpecializationListeners(builder, node);
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1221
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1222 builder.startStatement();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1223 builder.startCall("replace");
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1224 if (node.needsRewrites(getContext())) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1225 builder.startCall(factoryClassName(node), "specialize");
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1226 builder.string("this");
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1227 builder.typeLiteral(builder.findMethod().getEnclosingElement().asType());
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1228 addInternalValueParameterNames(builder, specialization, null, false, true);
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1229 builder.end(); // call replace, call specialize
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1230 } else {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1231 builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1232 }
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1233 builder.end().end();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1234 return builder.getRoot();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1235 }
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1236
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1237 private CodeTree createExecute(CodeTreeBuilder parent, SpecializationData specialization) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1238 NodeData node = specialization.getNode();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1239 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
8243
d81ff782fa1a Removed @SpecializationThrows from codegen API. Replaced it by a simplier version in @Specialization.
Christian Humer <christian.humer@gmail.com>
parents: 8242
diff changeset
1240 if (!specialization.getExceptions().isEmpty()) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1241 builder.startTryBlock();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1242 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1243
8361
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1244 if (specialization.isUninitialized()) {
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1245 String genericMethodName = generatedGenericMethodName(null);
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1246 builder.startReturn().startCall(factoryClassName(node), genericMethodName);
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1247 builder.string("this");
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1248 addInternalValueParameterNames(builder, specialization, null, true, true);
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1249 builder.end().end();
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1250 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) {
8251
cb70ed101b5f Added automatic generation of generic specialization which throws unsupported operation if reached.
Christian Humer <christian.humer@gmail.com>
parents: 8248
diff changeset
1251 emitEncounteredSynthetic(builder);
8361
676fa31bd3f0 Uninitialized cases produced wrong call to throw new UnsuportedOperationException.
Christian Humer <christian.humer@gmail.com>
parents: 8310
diff changeset
1252 } else if (specialization.isGeneric()) {
8277
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
1253 String genericMethodName;
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
1254 if (!specialization.isUseSpecializationsForGeneric()) {
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
1255 genericMethodName = generatedGenericMethodName(specialization);
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
1256 } else {
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
1257 genericMethodName = generatedGenericMethodName(null);
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
1258 }
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
1259
97ee911c4c74 Fixed behaviour of useSpecializations for Generic specializations.
Christian Humer <christian.humer@gmail.com>
parents: 8256
diff changeset
1260 builder.startReturn().startCall(factoryClassName(node), genericMethodName);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1261 builder.string("this");
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1262 addInternalValueParameterNames(builder, specialization, null, true, true);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1263 builder.end().end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1264 } else {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1265 builder.startReturn();
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1266 builder.tree(createTemplateMethodCall(builder, specialization, specialization, specialization, null));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1267 builder.end(); // return
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1268 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1269
8243
d81ff782fa1a Removed @SpecializationThrows from codegen API. Replaced it by a simplier version in @Specialization.
Christian Humer <christian.humer@gmail.com>
parents: 8242
diff changeset
1270 if (!specialization.getExceptions().isEmpty()) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1271 for (SpecializationThrowsData exception : specialization.getExceptions()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1272 builder.end().startCatchBlock(exception.getJavaClass(), "ex");
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1273 builder.tree(createReturnSpecializeAndExecute(parent, exception.getTransitionTo(), null));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1274 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1275 builder.end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1276 }
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1277 return builder.getRoot();
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1278 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1279
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1280 private CodeTree createExecuteChildren(CodeTreeBuilder parent, SpecializationData specialization) {
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1281 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1282
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1283 for (ActualParameter parameter : specialization.getParameters()) {
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1284 NodeFieldData field = specialization.getNode().findField(parameter.getSpecification().getName());
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1285 if (field == null || field.getKind() == FieldKind.FIELD) {
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1286 continue;
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1287 }
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1288
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1289 buildFieldExecute(builder, specialization, parameter, field, null);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1290 }
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1291 return builder.getRoot();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1292 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1293
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1294 private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) {
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1295 for (TemplateMethod listener : node.getSpecializationListeners()) {
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1296 builder.startStatement();
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1297 builder.tree(createTemplateMethodCall(builder, listener, listener, listener, null));
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1298 builder.end(); // statement
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1299 }
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1300 }
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1301
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1302 private void buildFieldExecute(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter param, NodeFieldData field, ActualParameter exceptionParam) {
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1303 boolean shortCircuit = startShortCircuit(builder, specialization, param, exceptionParam);
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1304 ExecutableTypeData execType = field.getNodeData().findExecutableType(param.getActualTypeData(field.getNodeData().getTypeSystem()));
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1305 boolean unexpected = execType.hasUnexpectedValue(getContext());
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1306
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1307 if (!shortCircuit && unexpected) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1308 builder.startStatement().type(param.getActualType()).string(" ").string(valueName(param)).end();
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1309 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1310
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1311 if (unexpected) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1312 builder.startTryBlock();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1313 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1314
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1315 if (!shortCircuit && !unexpected) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1316 builder.startStatement().type(param.getActualType()).string(" ").string(valueName(param)).string(" = ");
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1317 } else {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1318 builder.startStatement().string(valueName(param)).string(" = ");
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1319 }
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1320 buildExecute(builder, param, field, execType);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1321 builder.end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1322
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1323 if (unexpected) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1324 builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1325 SpecializationData generic = specialization.getNode().getGenericSpecialization();
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1326 boolean execute = false;
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1327 for (ActualParameter exParam : generic.getParameters()) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1328 NodeFieldData exField = generic.getNode().findField(exParam.getSpecification().getName());
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1329 if (exField == null || field.getKind() == FieldKind.FIELD) {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1330 continue;
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1331 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1332 if (execute) {
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1333 buildFieldExecute(builder, specialization.getNode().getGenericSpecialization(), exParam, exField, param);
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1334 } else if (exParam.getLocalName().equals(param.getLocalName())) {
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1335 execute = true;
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1336 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1337 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1338 builder.tree(createReturnSpecializeAndExecute(builder, specialization.findNextSpecialization(), param));
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1339 builder.end(); // catch block
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1340 }
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1341
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1342 endShortCircuit(builder, shortCircuit);
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1343 builder.newLine();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1344 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1345
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1346 private void buildExecute(CodeTreeBuilder builder, ActualParameter parameter, NodeFieldData field, ExecutableTypeData execType) {
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1347 if (field != null) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1348 Element accessElement = field.getAccessElement();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1349 if (accessElement.getKind() == ElementKind.METHOD) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1350 builder.startCall(accessElement.getSimpleName().toString()).end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1351 } else if (accessElement.getKind() == ElementKind.FIELD) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1352 builder.string("this.").string(accessElement.getSimpleName().toString());
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1353 } else {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1354 throw new AssertionError();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1355 }
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1356 if (parameter.getSpecification().isIndexed()) {
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1357 builder.string("[" + parameter.getIndex() + "]");
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1358 }
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1359 builder.string(".");
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1360 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1361 builder.startCall(execType.getMethodName());
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1362 if (execType.getParameters().size() == 1) {
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1363 builder.string("frameValue");
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1364 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1365 builder.end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1366 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1367
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1368 private boolean startShortCircuit(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) {
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1369 NodeFieldData forField = specialization.getNode().findField(parameter.getSpecification().getName());
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1370 if (forField == null) {
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1371 return false;
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1372 }
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1373
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1374 if (forField.getExecutionKind() != ExecutionKind.SHORT_CIRCUIT) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1375 return false;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1376 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1377
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1378 ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1379
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1380 int shortCircuitIndex = 0;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1381 for (NodeFieldData field : specialization.getNode().getFields()) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1382 if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1383 if (field == forField) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1384 break;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1385 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1386 shortCircuitIndex++;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1387 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1388 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1389
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1390 builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
8252
0905d796944a Refactored codegen error model to make error redirection a lot easier.
Christian Humer <christian.humer@gmail.com>
parents: 8251
diff changeset
1391 ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1392
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1393 builder.tree(createTemplateMethodCall(builder, shortCircuitData, shortCircuitData, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null));
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1394
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1395 builder.end(); // statement
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1396
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1397 builder.declaration(parameter.getActualType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType()));
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1398 builder.startIf().string(shortCircuitParam.getLocalName()).end();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1399 builder.startBlock();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1400
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1401 return true;
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1402 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1403
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1404 private void endShortCircuit(CodeTreeBuilder builder, boolean shortCircuit) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1405 if (shortCircuit) {
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1406 builder.end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1407 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1408 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1409
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1410 private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, SpecializationData nextSpecialization, ActualParameter exceptionParam) {
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1411 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent);
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1412 specializeCall.startCall("specializeAndExecute");
8245
703c09f8640c Implemented support for @NodeClass annotation to support builtins.
Christian Humer <christian.humer@gmail.com>
parents: 8243
diff changeset
1413 specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class");
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1414 addInternalValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, true);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1415 specializeCall.end().end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1416
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1417 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1418 builder.startReturn();
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1419 builder.tree(specializeCall.getRoot());
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1420 builder.end();
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1421 return builder.getRoot();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1422 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1423
8237
6b74ffe38183 Implemented support for executing nodes in @Children fields.
Christian Humer <christian.humer@gmail.com>
parents: 7859
diff changeset
1424 private void buildSpecializeAndExecute(CodeTypeElement clazz, SpecializationData specialization) {
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1425 NodeData node = specialization.getNode();
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1426 TypeData returnType = specialization.getReturnType().getActualTypeData(node.getTypeSystem());
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1427 ExecutableTypeData returnExecutableType = node.findExecutableType(returnType);
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1428 boolean canThrowUnexpected = returnExecutableType == null ? true : returnExecutableType.hasUnexpectedValue(getContext());
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1429
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1430 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE), returnType.getPrimitiveType(), "specializeAndExecute");
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1431 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState"));
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1432 if (canThrowUnexpected) {
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1433 method.addThrownType(getUnexpectedValueException());
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1434 }
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1435 addInternalValueParameters(method, specialization.getNode().getGenericSpecialization(), true);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1436 clazz.add(method);
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1437
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1438 CodeTreeBuilder builder = method.createBuilder();
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1439
7846
91cc98eae8ee Refactor guard creation methods are not flexible enough to handle two if guards.
Christian Humer <christian.humer@gmail.com>
parents: 7845
diff changeset
1440 builder.tree(createDeoptimize(builder));
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1441 emitSpecializationListeners(builder, specialization.getNode());
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1442
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1443 builder.startStatement();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1444 builder.startCall("replace");
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1445 builder.startCall(factoryClassName(specialization.getNode()), "specialize").string("this").string("minimumState");
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1446 addInternalValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false, true);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1447 builder.end();
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1448 builder.end(); // call replace
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1449 builder.end(); // statement
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1450
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1451 String generatedMethodName = generatedGenericMethodName(specialization.findNextSpecialization());
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1452 ExecutableElement generatedGeneric = clazz.getEnclosingClass().getMethod(generatedMethodName);
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1453
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1454 CodeTreeBuilder genericExecute = CodeTreeBuilder.createBuilder();
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1455 genericExecute.startCall(factoryClassName(specialization.getNode()), generatedMethodName);
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1456 genericExecute.string("this");
8310
89006c76f737 Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
Christian Humer <christian.humer@gmail.com>
parents: 8277
diff changeset
1457 addInternalValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true, true);
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1458 genericExecute.end(); // call generated generic
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1459
7847
06a7cd6aaf00 Casting is now done on demand using local variables for explicit guards.
Christian Humer <christian.humer@gmail.com>
parents: 7846
diff changeset
1460 CodeTree genericInvocation = createExpectType(node, returnExecutableType, genericExecute.getRoot());
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1461
7777
ca51efac4d57 Fixed rewrite in generated generic did not invoke guards.
Christian Humer <christian.humer@gmail.com>
parents: 7751
diff changeset
1462 if (generatedGeneric != null && Utils.isVoid(generatedGeneric.getReturnType())) {
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1463 builder.statement(genericInvocation);
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1464
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1465 if (!Utils.isVoid(builder.findMethod().asType())) {
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1466 builder.startReturn().defaultValue(returnType.getPrimitiveType()).end();
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1467 }
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1468 } else {
7843
4969921f57b7 Renamed generated specialize to specializeAndExecute.
Christian Humer <christian.humer@gmail.com>
parents: 7799
diff changeset
1469 builder.startReturn().tree(genericInvocation).end();
7502
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1470 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1471 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1472
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1473 }
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1474
6343a09b2ec1 Codegen operation generation is inferred from the node type hierarchy.
Christian Humer <christian.humer@gmail.com>
parents:
diff changeset
1475 }