comparison truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeData.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeData.java@8e5f9310f3aa
children dc83cc1f94f2
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
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
34 public class NodeData extends Template implements Comparable<NodeData> {
35
36 private final String nodeId;
37 private final String shortName;
38 private final List<NodeData> enclosingNodes = new ArrayList<>();
39 private NodeData declaringNode;
40
41 private final TypeSystemData typeSystem;
42 private final List<NodeChildData> children;
43 private final List<NodeExecutionData> childExecutions;
44 private final List<NodeFieldData> fields;
45
46 private ParameterSpec instanceParameterSpec;
47
48 private final List<SpecializationData> specializations = new ArrayList<>();
49 private final List<ShortCircuitData> shortCircuits = new ArrayList<>();
50 private final List<CreateCastData> casts = new ArrayList<>();
51 private final List<ExecutableTypeData> executableTypes = new ArrayList<>();
52
53 private final NodeExecutionData thisExecution;
54 private final boolean generateFactory;
55
56 private TypeMirror frameType;
57
58 public NodeData(ProcessorContext context, TypeElement type, String shortName, TypeSystemData typeSystem, boolean generateFactory) {
59 super(context, type, null);
60 this.nodeId = ElementUtils.getSimpleName(type);
61 this.shortName = shortName;
62 this.typeSystem = typeSystem;
63 this.fields = new ArrayList<>();
64 this.children = new ArrayList<>();
65 this.childExecutions = new ArrayList<>();
66 this.thisExecution = new NodeExecutionData(new NodeChildData(null, null, "this", getNodeType(), getNodeType(), null, Cardinality.ONE), -1, -1, false);
67 this.thisExecution.getChild().setNode(this);
68 this.generateFactory = generateFactory;
69 }
70
71 public NodeData(ProcessorContext context, TypeElement type) {
72 this(context, type, null, null, false);
73 }
74
75 public boolean isGenerateFactory() {
76 return generateFactory;
77 }
78
79 public NodeExecutionData getThisExecution() {
80 return thisExecution;
81 }
82
83 public boolean isFallbackReachable() {
84 SpecializationData generic = getGenericSpecialization();
85 if (generic != null) {
86 return generic.isReachable();
87 }
88 return false;
89 }
90
91 public void setFrameType(TypeMirror frameType) {
92 this.frameType = frameType;
93 }
94
95 public TypeMirror getFrameType() {
96 return frameType;
97 }
98
99 public void addEnclosedNode(NodeData node) {
100 this.enclosingNodes.add(node);
101 node.declaringNode = this;
102 }
103
104 public List<NodeExecutionData> getChildExecutions() {
105 return childExecutions;
106 }
107
108 public Set<TypeMirror> findSpecializedTypes(NodeExecutionData execution) {
109 Set<TypeMirror> types = new HashSet<>();
110 for (SpecializationData specialization : getSpecializations()) {
111 if (!specialization.isSpecialized()) {
112 continue;
113 }
114 List<Parameter> parameters = specialization.findByExecutionData(execution);
115 for (Parameter parameter : parameters) {
116 TypeMirror type = parameter.getType();
117 if (type == null) {
118 throw new AssertionError();
119 }
120 types.add(type);
121 }
122 }
123 return types;
124 }
125
126 public Collection<TypeMirror> findSpecializedReturnTypes() {
127 Set<TypeMirror> types = new HashSet<>();
128 for (SpecializationData specialization : getSpecializations()) {
129 if (!specialization.isSpecialized()) {
130 continue;
131 }
132 types.add(specialization.getReturnType().getType());
133 }
134 return types;
135 }
136
137 public int getExecutionCount() {
138 return getChildExecutions().size();
139 }
140
141 public int getSignatureSize() {
142 int count = 0;
143 for (NodeExecutionData execution : getChildExecutions()) {
144 if (execution.isShortCircuit()) {
145 count++;
146 }
147 count++;
148 }
149 return count;
150 }
151
152 public boolean isFrameUsedByAnyGuard() {
153 for (SpecializationData specialization : specializations) {
154 if (!specialization.isReachable()) {
155 continue;
156 }
157 Parameter frame = specialization.getFrame();
158 if (frame != null) {
159 for (GuardExpression guard : specialization.getGuards()) {
160 if (guard.getExpression().findBoundVariableElements().contains(frame.getVariableElement())) {
161 return true;
162 }
163 }
164 for (CacheExpression cache : specialization.getCaches()) {
165 if (cache.getExpression().findBoundVariableElements().contains(frame.getVariableElement())) {
166 return true;
167 }
168 }
169 }
170 }
171 return false;
172 }
173
174 public List<CreateCastData> getCasts() {
175 return casts;
176 }
177
178 public String getShortName() {
179 return shortName;
180 }
181
182 public List<NodeFieldData> getFields() {
183 return fields;
184 }
185
186 @Override
187 protected List<MessageContainer> findChildContainers() {
188 List<MessageContainer> containerChildren = new ArrayList<>();
189 if (enclosingNodes != null) {
190 containerChildren.addAll(enclosingNodes);
191 }
192 if (typeSystem != null) {
193 containerChildren.add(typeSystem);
194 }
195 if (specializations != null) {
196 for (MessageContainer specialization : specializations) {
197 if (specialization.getMessageElement() != null) {
198 containerChildren.add(specialization);
199 }
200 }
201 }
202 if (executableTypes != null) {
203 containerChildren.addAll(getExecutableTypes());
204 }
205 if (shortCircuits != null) {
206 containerChildren.addAll(shortCircuits);
207 }
208 if (children != null) {
209 containerChildren.addAll(children);
210 }
211 if (fields != null) {
212 containerChildren.addAll(fields);
213 }
214 if (casts != null) {
215 containerChildren.addAll(casts);
216 }
217 return containerChildren;
218 }
219
220 public ParameterSpec getInstanceParameterSpec() {
221 return instanceParameterSpec;
222 }
223
224 public void setInstanceParameterSpec(ParameterSpec instanceParameter) {
225 this.instanceParameterSpec = instanceParameter;
226 }
227
228 public String getNodeId() {
229 return nodeId;
230 }
231
232 public TypeMirror getNodeType() {
233 return getTemplateType().asType();
234 }
235
236 public boolean needsFactory() {
237 if (specializations == null) {
238 return false;
239 }
240 if (getTemplateType().getModifiers().contains(Modifier.PRIVATE)) {
241 return false;
242 }
243
244 boolean noSpecialization = true;
245 for (SpecializationData specialization : specializations) {
246 noSpecialization = noSpecialization && !specialization.isSpecialized();
247 }
248 return !noSpecialization;
249 }
250
251 public boolean supportsFrame() {
252 if (executableTypes != null) {
253 for (ExecutableTypeData execType : getExecutableTypes(-1)) {
254 if (execType.getFrameParameter() == null) {
255 return false;
256 }
257 }
258 }
259 return true;
260 }
261
262 public NodeExecutionData findExecutionByExpression(String childNameExpression) {
263 String childName = childNameExpression;
264 int index = -1;
265
266 int start = childName.indexOf('[');
267 int end = childName.lastIndexOf(']');
268 if (start != -1 && end != -1 && start < end) {
269 try {
270 index = Integer.parseInt(childName.substring(start + 1, end));
271 childName = childName.substring(0, start);
272 childName = NodeExecutionData.createName(childName, index);
273 } catch (NumberFormatException e) {
274 // ignore
275 }
276 }
277
278 for (NodeExecutionData execution : childExecutions) {
279 if (execution.getName().equals(childName) && (execution.getChildIndex() == -1 || execution.getChildIndex() == index)) {
280 return execution;
281 }
282 }
283 return null;
284 }
285
286 public List<NodeData> getNodesWithFactories() {
287 List<NodeData> nodeChildren = new ArrayList<>();
288 for (NodeData child : getEnclosingNodes()) {
289 if (child.needsFactory() && child.isGenerateFactory()) {
290 nodeChildren.add(child);
291 }
292 nodeChildren.addAll(child.getNodesWithFactories());
293 }
294 return nodeChildren;
295 }
296
297 public NodeData getDeclaringNode() {
298 return declaringNode;
299 }
300
301 public List<NodeData> getEnclosingNodes() {
302 return enclosingNodes;
303 }
304
305 public List<ExecutableElement> getAllTemplateMethods() {
306 List<ExecutableElement> methods = new ArrayList<>();
307
308 for (SpecializationData specialization : getSpecializations()) {
309 methods.add(specialization.getMethod());
310 }
311
312 for (ExecutableTypeData execType : getExecutableTypes()) {
313 if (execType.getMethod() != null) {
314 methods.add(execType.getMethod());
315 }
316 }
317 for (ShortCircuitData shortcircuit : getShortCircuits()) {
318 methods.add(shortcircuit.getMethod());
319 }
320
321 if (getCasts() != null) {
322 for (CreateCastData castData : getCasts()) {
323 methods.add(castData.getMethod());
324 }
325 }
326
327 return methods;
328 }
329
330 public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context, int evaluatedCount) {
331 List<ExecutableTypeData> types = findGenericExecutableTypes(context, evaluatedCount);
332 for (ExecutableTypeData type : types) {
333 if (context.isType(type.getReturnType(), Object.class)) {
334 return type;
335 }
336 }
337
338 for (ExecutableTypeData type : types) {
339 if (!context.isType(type.getReturnType(), void.class)) {
340 return type;
341 }
342 }
343
344 for (ExecutableTypeData type : types) {
345 return type;
346 }
347 return null;
348 }
349
350 public List<ExecutableTypeData> getExecutableTypes(int evaluatedCount) {
351 if (evaluatedCount == -1) {
352 return executableTypes;
353 } else {
354 List<ExecutableTypeData> filteredTypes = new ArrayList<>();
355 for (ExecutableTypeData type : executableTypes) {
356 if (type.getEvaluatedCount() == evaluatedCount) {
357 filteredTypes.add(type);
358 }
359 }
360 return filteredTypes;
361 }
362 }
363
364 public List<ExecutableTypeData> findGenericExecutableTypes(ProcessorContext context, int evaluatedCount) {
365 List<ExecutableTypeData> types = new ArrayList<>();
366 for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) {
367 if (!type.hasUnexpectedValue(context)) {
368 types.add(type);
369 }
370 }
371 return types;
372 }
373
374 public ExecutableTypeData findExecutableType(TypeMirror primitiveType, int evaluatedCount) {
375 for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) {
376 if (ElementUtils.typeEquals(type.getReturnType(), primitiveType)) {
377 return type;
378 }
379 }
380 return null;
381 }
382
383 public boolean needsRewrites(ProcessorContext context) {
384 boolean needsRewrites = false;
385
386 for (SpecializationData specialization : getSpecializations()) {
387 if (specialization.hasRewrite(context)) {
388 needsRewrites = true;
389 break;
390 }
391 }
392 return needsRewrites || getSpecializations().size() > 1;
393 }
394
395 public SpecializationData getPolymorphicSpecialization() {
396 for (SpecializationData specialization : specializations) {
397 if (specialization.isPolymorphic()) {
398 return specialization;
399 }
400 }
401 return null;
402 }
403
404 public SpecializationData getGenericSpecialization() {
405 for (SpecializationData specialization : specializations) {
406 if (specialization.isFallback()) {
407 return specialization;
408 }
409 }
410 return null;
411 }
412
413 public SpecializationData getUninitializedSpecialization() {
414 for (SpecializationData specialization : specializations) {
415 if (specialization.isUninitialized()) {
416 return specialization;
417 }
418 }
419 return null;
420 }
421
422 @Override
423 public TypeSystemData getTypeSystem() {
424 return typeSystem;
425 }
426
427 @Override
428 public String dump() {
429 return dump(0);
430 }
431
432 private String dump(int level) {
433 String indent = "";
434 for (int i = 0; i < level; i++) {
435 indent += " ";
436 }
437 StringBuilder builder = new StringBuilder();
438
439 builder.append(String.format("%s%s {", indent, toString()));
440
441 dumpProperty(builder, indent, "templateClass", ElementUtils.getQualifiedName(getTemplateType()));
442 dumpProperty(builder, indent, "typeSystem", getTypeSystem());
443 dumpProperty(builder, indent, "fields", getChildren());
444 dumpProperty(builder, indent, "executableTypes", getExecutableTypes());
445 dumpProperty(builder, indent, "specializations", getSpecializations());
446 dumpProperty(builder, indent, "casts", getCasts());
447 dumpProperty(builder, indent, "messages", collectMessages());
448 if (getEnclosingNodes().size() > 0) {
449 builder.append(String.format("\n%s children = [", indent));
450 for (NodeData node : getEnclosingNodes()) {
451 builder.append("\n");
452 builder.append(node.dump(level + 1));
453 }
454 builder.append(String.format("\n%s ]", indent));
455 }
456 builder.append(String.format("%s}", indent));
457 return builder.toString();
458 }
459
460 private static void dumpProperty(StringBuilder b, String indent, String propertyName, Object value) {
461 if (value instanceof List) {
462 List<?> list = (List<?>) value;
463 if (!list.isEmpty()) {
464 b.append(String.format("\n%s %s = %s", indent, propertyName, dumpList(indent, (List<?>) value)));
465 }
466 } else {
467 if (value != null) {
468 b.append(String.format("\n%s %s = %s", indent, propertyName, value));
469 }
470 }
471 }
472
473 private static String dumpList(String indent, List<?> array) {
474 if (array == null) {
475 return "null";
476 }
477
478 if (array.isEmpty()) {
479 return "[]";
480 } else if (array.size() == 1) {
481 return "[" + array.get(0).toString() + "]";
482 }
483
484 StringBuilder b = new StringBuilder();
485 b.append("[");
486 for (Object object : array) {
487 b.append("\n ");
488 b.append(indent);
489 b.append(object);
490 b.append(", ");
491 }
492 b.append("\n ").append(indent).append("]");
493 return b.toString();
494 }
495
496 public NodeChildData findChild(String name) {
497 for (NodeChildData field : getChildren()) {
498 if (field.getName().equals(name)) {
499 return field;
500 }
501 }
502 return null;
503 }
504
505 public List<NodeChildData> getChildren() {
506 return children;
507 }
508
509 public List<SpecializationData> getSpecializations() {
510 return specializations;
511 }
512
513 public ExecutableTypeData getGenericExecutableType(ExecutableTypeData typeHint) {
514 ExecutableTypeData polymorphicDelegate = null;
515 if (typeHint != null) {
516 polymorphicDelegate = typeHint;
517 while (polymorphicDelegate.getDelegatedTo() != null && polymorphicDelegate.getEvaluatedCount() != getSignatureSize()) {
518 polymorphicDelegate = polymorphicDelegate.getDelegatedTo();
519 }
520 }
521 if (polymorphicDelegate == null) {
522 for (ExecutableTypeData type : getExecutableTypes()) {
523 if (type.getDelegatedTo() == null && type.getEvaluatedCount() == getSignatureSize()) {
524 polymorphicDelegate = type;
525 break;
526 }
527 }
528 }
529 return polymorphicDelegate;
530 }
531
532 public List<ExecutableTypeData> getExecutableTypes() {
533 return getExecutableTypes(-1);
534 }
535
536 public List<ShortCircuitData> getShortCircuits() {
537 return shortCircuits;
538 }
539
540 public int getMinimalEvaluatedParameters() {
541 int minimalEvaluatedParameters = Integer.MAX_VALUE;
542 for (ExecutableTypeData type : getExecutableTypes()) {
543 minimalEvaluatedParameters = Math.min(minimalEvaluatedParameters, type.getEvaluatedCount());
544 }
545 return minimalEvaluatedParameters;
546 }
547
548 @Override
549 public String toString() {
550 return getClass().getSimpleName() + "[" + getNodeId() + "]";
551 }
552
553 public CreateCastData findCast(String name) {
554 if (getCasts() != null) {
555 for (CreateCastData cast : getCasts()) {
556 if (cast.getChildNames().contains(name)) {
557 return cast;
558 }
559 }
560 }
561 return null;
562 }
563
564 public int compareTo(NodeData o) {
565 return getNodeId().compareTo(o.getNodeId());
566 }
567
568 public TypeMirror getGenericType(NodeExecutionData execution) {
569 return ElementUtils.getCommonSuperType(getContext(), getGenericTypes(execution));
570 }
571
572 public List<TypeMirror> getGenericTypes(NodeExecutionData execution) {
573 List<TypeMirror> types = new ArrayList<>();
574
575 // add types possible through return types and evaluated parameters in execute methods
576 if (execution.getChild() != null) {
577 for (ExecutableTypeData executable : execution.getChild().getNodeData().getExecutableTypes()) {
578 if (executable.hasUnexpectedValue(getContext())) {
579 continue;
580 }
581 types.add(executable.getReturnType());
582 }
583 }
584
585 int executionIndex = execution.getIndex();
586 if (executionIndex >= 0) {
587 for (ExecutableTypeData typeData : getExecutableTypes()) {
588 List<TypeMirror> signatureParameters = typeData.getSignatureParameters();
589 if (executionIndex < signatureParameters.size()) {
590 TypeMirror genericType = signatureParameters.get(executionIndex);
591 types.add(genericType);
592 }
593 }
594 }
595
596 return ElementUtils.uniqueSortedTypes(types, false);
597 }
598
599 }