comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeData.java @ 16759:23415229349b

Truffle-DSL: new package structure.
author Christian Humer <christian.humer@gmail.com>
date Mon, 11 Aug 2014 15:57:14 +0200
parents graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java@bd28da642eea
children 2db61eddcb97
comparison
equal deleted inserted replaced
16758:c5f8eeb3cbc8 16759:23415229349b
1 /*
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.truffle.dsl.processor.model;
24
25 import java.util.*;
26
27 import javax.lang.model.element.*;
28 import javax.lang.model.type.*;
29
30 import com.oracle.truffle.dsl.processor.*;
31 import com.oracle.truffle.dsl.processor.java.*;
32 import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality;
33 import com.oracle.truffle.dsl.processor.parser.*;
34
35 public class NodeData extends Template implements Comparable<NodeData> {
36
37 private final String nodeId;
38 private final String shortName;
39 private final List<NodeData> enclosingNodes = new ArrayList<>();
40 private NodeData declaringNode;
41
42 private final TypeSystemData typeSystem;
43 private final List<NodeChildData> children;
44 private final List<NodeExecutionData> childExecutions;
45 private final List<NodeFieldData> fields;
46 private final List<String> assumptions;
47
48 private ParameterSpec instanceParameterSpec;
49
50 private final List<SpecializationData> specializations = new ArrayList<>();
51 private final List<ShortCircuitData> shortCircuits = new ArrayList<>();
52 private final List<CreateCastData> casts = new ArrayList<>();
53 private Map<Integer, List<ExecutableTypeData>> executableTypes;
54
55 private final NodeExecutionData thisExecution;
56
57 public NodeData(ProcessorContext context, TypeElement type, String shortName, TypeSystemData typeSystem, List<NodeChildData> children, List<NodeExecutionData> executions,
58 List<NodeFieldData> fields, List<String> assumptions) {
59 super(context, type, null, null);
60 this.nodeId = type.getSimpleName().toString();
61 this.shortName = shortName;
62 this.typeSystem = typeSystem;
63 this.fields = fields;
64 this.children = children;
65 this.childExecutions = executions;
66 this.assumptions = assumptions;
67 this.thisExecution = new NodeExecutionData(new NodeChildData(null, null, "this", getNodeType(), getNodeType(), null, Cardinality.ONE), -1, false);
68 this.thisExecution.getChild().setNode(this);
69 }
70
71 public NodeData(ProcessorContext context, TypeElement type) {
72 this(context, type, null, null, null, null, null, null);
73 }
74
75 public NodeExecutionData getThisExecution() {
76 return thisExecution;
77 }
78
79 public boolean isFallbackReachable() {
80 SpecializationData generic = getGenericSpecialization();
81 if (generic != null) {
82 return generic.isReachable();
83 }
84 return false;
85 }
86
87 public void addEnclosedNode(NodeData node) {
88 this.enclosingNodes.add(node);
89 node.declaringNode = this;
90 }
91
92 public List<NodeExecutionData> getChildExecutions() {
93 return childExecutions;
94 }
95
96 public int getSignatureSize() {
97 if (getSpecializations() != null && !getSpecializations().isEmpty()) {
98 return getSpecializations().get(0).getSignatureSize();
99 }
100 return 0;
101 }
102
103 public boolean needsFrame(ProcessorContext context) {
104 for (SpecializationData specialization : specializations) {
105 if (!specialization.isReachable()) {
106 continue;
107 }
108 if (specialization.hasFrame(context)) {
109 return true;
110 }
111 }
112 return false;
113 }
114
115 public boolean isPolymorphic(ProcessorContext context) {
116 return needsRewrites(context);
117 }
118
119 public List<CreateCastData> getCasts() {
120 return casts;
121 }
122
123 public String getShortName() {
124 return shortName;
125 }
126
127 public List<NodeFieldData> getFields() {
128 return fields;
129 }
130
131 @Override
132 protected List<MessageContainer> findChildContainers() {
133 List<MessageContainer> containerChildren = new ArrayList<>();
134 if (enclosingNodes != null) {
135 containerChildren.addAll(enclosingNodes);
136 }
137 if (typeSystem != null) {
138 containerChildren.add(typeSystem);
139 }
140 if (specializations != null) {
141 for (MessageContainer specialization : specializations) {
142 if (specialization.getMessageElement() != null) {
143 containerChildren.add(specialization);
144 }
145 }
146 }
147 if (executableTypes != null) {
148 containerChildren.addAll(getExecutableTypes());
149 }
150 if (shortCircuits != null) {
151 containerChildren.addAll(shortCircuits);
152 }
153 if (children != null) {
154 containerChildren.addAll(children);
155 }
156 if (fields != null) {
157 containerChildren.addAll(fields);
158 }
159 if (casts != null) {
160 containerChildren.addAll(casts);
161 }
162 return containerChildren;
163 }
164
165 public ParameterSpec getInstanceParameterSpec() {
166 return instanceParameterSpec;
167 }
168
169 public void setInstanceParameterSpec(ParameterSpec instanceParameter) {
170 this.instanceParameterSpec = instanceParameter;
171 }
172
173 public String getNodeId() {
174 return nodeId;
175 }
176
177 public TypeMirror getNodeType() {
178 return getTemplateType().asType();
179 }
180
181 public List<String> getAssumptions() {
182 return assumptions;
183 }
184
185 public boolean needsFactory() {
186 if (specializations == null) {
187 return false;
188 }
189 if (getTemplateType().getModifiers().contains(Modifier.PRIVATE)) {
190 return false;
191 }
192
193 boolean noSpecialization = true;
194 for (SpecializationData specialization : specializations) {
195 noSpecialization = noSpecialization && !specialization.isSpecialized();
196 }
197 return !noSpecialization;
198 }
199
200 public boolean supportsFrame() {
201 if (executableTypes != null) {
202 for (ExecutableTypeData execType : getExecutableTypes(-1)) {
203 if (execType.findParameter("frameValue") == null) {
204 return false;
205 }
206 }
207 }
208 return true;
209 }
210
211 public List<NodeData> getNodeDeclaringChildren() {
212 List<NodeData> nodeChildren = new ArrayList<>();
213 for (NodeData child : getEnclosingNodes()) {
214 if (child.needsFactory()) {
215 nodeChildren.add(child);
216 }
217 nodeChildren.addAll(child.getNodeDeclaringChildren());
218 }
219 return nodeChildren;
220 }
221
222 public NodeData getDeclaringNode() {
223 return declaringNode;
224 }
225
226 public List<NodeData> getEnclosingNodes() {
227 return enclosingNodes;
228 }
229
230 public List<TemplateMethod> getAllTemplateMethods() {
231 List<TemplateMethod> methods = new ArrayList<>();
232
233 for (SpecializationData specialization : getSpecializations()) {
234 methods.add(specialization);
235 }
236
237 methods.addAll(getExecutableTypes());
238 methods.addAll(getShortCircuits());
239 if (getCasts() != null) {
240 methods.addAll(getCasts());
241 }
242
243 return methods;
244 }
245
246 public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context, int evaluatedCount) {
247 List<ExecutableTypeData> types = findGenericExecutableTypes(context, evaluatedCount);
248 for (ExecutableTypeData type : types) {
249 if (type.getType().isGeneric()) {
250 return type;
251 }
252 }
253
254 for (ExecutableTypeData type : types) {
255 if (!type.getType().isVoid()) {
256 return type;
257 }
258 }
259
260 for (ExecutableTypeData type : types) {
261 return type;
262 }
263 return null;
264 }
265
266 public List<ExecutableTypeData> getExecutableTypes(int evaluatedCount) {
267 if (executableTypes == null) {
268 return Collections.emptyList();
269 }
270 if (evaluatedCount == -1) {
271 List<ExecutableTypeData> typeData = new ArrayList<>();
272 for (int currentEvaluationCount : executableTypes.keySet()) {
273 typeData.addAll(executableTypes.get(currentEvaluationCount));
274 }
275 return typeData;
276 } else {
277 List<ExecutableTypeData> types = executableTypes.get(evaluatedCount);
278 if (types == null) {
279 return Collections.emptyList();
280 }
281 return types;
282 }
283 }
284
285 public List<ExecutableTypeData> findGenericExecutableTypes(ProcessorContext context, int evaluatedCount) {
286 List<ExecutableTypeData> types = new ArrayList<>();
287 for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) {
288 if (!type.hasUnexpectedValue(context)) {
289 types.add(type);
290 }
291 }
292 return types;
293 }
294
295 public ExecutableTypeData findExecutableType(TypeData prmitiveType, int evaluatedCount) {
296 for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) {
297 if (ElementUtils.typeEquals(type.getType().getPrimitiveType(), prmitiveType.getPrimitiveType())) {
298 return type;
299 }
300 }
301 return null;
302 }
303
304 public boolean needsRewrites(ProcessorContext context) {
305 boolean needsRewrites = false;
306
307 for (SpecializationData specialization : getSpecializations()) {
308 if (specialization.hasRewrite(context)) {
309 needsRewrites = true;
310 break;
311 }
312 }
313 return needsRewrites || getSpecializations().size() > 1;
314 }
315
316 public SpecializationData getPolymorphicSpecialization() {
317 for (SpecializationData specialization : specializations) {
318 if (specialization.isPolymorphic()) {
319 return specialization;
320 }
321 }
322 return null;
323 }
324
325 public SpecializationData getGenericSpecialization() {
326 for (SpecializationData specialization : specializations) {
327 if (specialization.isGeneric()) {
328 return specialization;
329 }
330 }
331 return null;
332 }
333
334 public SpecializationData getUninitializedSpecialization() {
335 for (SpecializationData specialization : specializations) {
336 if (specialization.isUninitialized()) {
337 return specialization;
338 }
339 }
340 return null;
341 }
342
343 @Override
344 public TypeSystemData getTypeSystem() {
345 return typeSystem;
346 }
347
348 public String dump() {
349 return dump(0);
350 }
351
352 private String dump(int level) {
353 String indent = "";
354 for (int i = 0; i < level; i++) {
355 indent += " ";
356 }
357 StringBuilder builder = new StringBuilder();
358
359 builder.append(String.format("%s%s {", indent, toString()));
360
361 dumpProperty(builder, indent, "templateClass", ElementUtils.getQualifiedName(getTemplateType()));
362 dumpProperty(builder, indent, "typeSystem", getTypeSystem());
363 dumpProperty(builder, indent, "fields", getChildren());
364 dumpProperty(builder, indent, "executableTypes", getExecutableTypes());
365 dumpProperty(builder, indent, "specializations", getSpecializations());
366 dumpProperty(builder, indent, "assumptions", getAssumptions());
367 dumpProperty(builder, indent, "casts", getCasts());
368 dumpProperty(builder, indent, "messages", collectMessages());
369 if (getEnclosingNodes().size() > 0) {
370 builder.append(String.format("\n%s children = [", indent));
371 for (NodeData node : getEnclosingNodes()) {
372 builder.append("\n");
373 builder.append(node.dump(level + 1));
374 }
375 builder.append(String.format("\n%s ]", indent));
376 }
377 builder.append(String.format("%s}", indent));
378 return builder.toString();
379 }
380
381 private static void dumpProperty(StringBuilder b, String indent, String propertyName, Object value) {
382 if (value instanceof List) {
383 List<?> list = (List<?>) value;
384 if (!list.isEmpty()) {
385 b.append(String.format("\n%s %s = %s", indent, propertyName, dumpList(indent, (List<?>) value)));
386 }
387 } else {
388 if (value != null) {
389 b.append(String.format("\n%s %s = %s", indent, propertyName, value));
390 }
391 }
392 }
393
394 private static String dumpList(String indent, List<?> array) {
395 if (array == null) {
396 return "null";
397 }
398
399 if (array.isEmpty()) {
400 return "[]";
401 } else if (array.size() == 1) {
402 return "[" + array.get(0).toString() + "]";
403 }
404
405 StringBuilder b = new StringBuilder();
406 b.append("[");
407 for (Object object : array) {
408 b.append("\n ");
409 b.append(indent);
410 b.append(object);
411 b.append(", ");
412 }
413 b.append("\n ").append(indent).append("]");
414 return b.toString();
415 }
416
417 public NodeChildData findChild(String name) {
418 for (NodeChildData field : getChildren()) {
419 if (field.getName().equals(name)) {
420 return field;
421 }
422 }
423 return null;
424 }
425
426 public List<NodeChildData> getChildren() {
427 return children;
428 }
429
430 public List<SpecializationData> getSpecializations() {
431 return specializations;
432 }
433
434 public List<ExecutableTypeData> getExecutableTypes() {
435 return getExecutableTypes(-1);
436 }
437
438 public List<ShortCircuitData> getShortCircuits() {
439 return shortCircuits;
440 }
441
442 public void setExecutableTypes(Map<Integer, List<ExecutableTypeData>> executableTypes) {
443 this.executableTypes = executableTypes;
444 }
445
446 @Override
447 public String toString() {
448 return getClass().getSimpleName() + "[" + getNodeId() + "]";
449 }
450
451 public CreateCastData findCast(String name) {
452 if (getCasts() != null) {
453 for (CreateCastData cast : getCasts()) {
454 if (cast.getChildNames().contains(name)) {
455 return cast;
456 }
457 }
458 }
459 return null;
460 }
461
462 public int compareTo(NodeData o) {
463 return getNodeId().compareTo(o.getNodeId());
464 }
465
466 }