comparison truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/ExecutableTypeData.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/ExecutableTypeData.java@b1530a6cce8c
children dc83cc1f94f2
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
1 /*
2 * Copyright (c) 2012, 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 static com.oracle.truffle.dsl.processor.java.ElementUtils.*;
26
27 import java.util.*;
28
29 import javax.lang.model.element.*;
30 import javax.lang.model.type.*;
31
32 import com.oracle.truffle.api.nodes.*;
33 import com.oracle.truffle.dsl.processor.*;
34 import com.oracle.truffle.dsl.processor.java.*;
35
36 public class ExecutableTypeData extends MessageContainer implements Comparable<ExecutableTypeData> {
37
38 private final NodeData node;
39 private final ExecutableElement method;
40 private final TypeMirror returnType;
41 private final TypeMirror frameParameter;
42 private final List<TypeMirror> evaluatedParameters;
43 private ExecutableTypeData delegatedTo;
44 private final List<ExecutableTypeData> delegatedFrom = new ArrayList<>();
45
46 private String uniqueName;
47
48 public ExecutableTypeData(NodeData node, TypeMirror returnType, String uniqueName, TypeMirror frameParameter, List<TypeMirror> evaluatedParameters) {
49 this.node = node;
50 this.returnType = returnType;
51 this.frameParameter = frameParameter;
52 this.evaluatedParameters = evaluatedParameters;
53 this.uniqueName = uniqueName;
54 this.method = null;
55 }
56
57 public ExecutableTypeData(NodeData node, ExecutableElement method, int signatureSize, List<TypeMirror> frameTypes) {
58 this.node = node;
59 this.method = method;
60 this.returnType = method.getReturnType();
61 TypeMirror foundFrameParameter = null;
62 List<? extends VariableElement> parameters = method.getParameters();
63
64 int parameterIndex = 0;
65 evaluatedParameters = new ArrayList<>();
66 if (!parameters.isEmpty()) {
67 TypeMirror firstParameter = parameters.get(0).asType();
68 for (TypeMirror frameType : frameTypes) {
69 if (ElementUtils.typeEquals(firstParameter, frameType)) {
70 foundFrameParameter = firstParameter;
71 parameterIndex++;
72 break;
73 }
74 }
75 }
76
77 int numberParameters = Math.max(parameters.size() - parameterIndex, signatureSize);
78 for (int i = 0; i < numberParameters; i++) {
79 TypeMirror parameter;
80 if (method.isVarArgs() && parameterIndex >= parameters.size() - 1) {
81 ArrayType varArgsArray = (ArrayType) parameters.get(parameters.size() - 1).asType();
82 parameter = varArgsArray.getComponentType();
83 } else if (parameterIndex < parameters.size()) {
84 parameter = parameters.get(parameterIndex).asType();
85 } else {
86 break;
87 }
88 parameterIndex++;
89 evaluatedParameters.add(parameter);
90 }
91 this.frameParameter = foundFrameParameter;
92 this.uniqueName = createName(this);
93 }
94
95 public static String createName(ExecutableTypeData type) {
96 return "execute" + (ElementUtils.isObject(type.getReturnType()) ? "" : ElementUtils.getTypeId(type.getReturnType()));
97 }
98
99 public void addDelegatedFrom(ExecutableTypeData child) {
100 this.delegatedFrom.add(child);
101 child.delegatedTo = this;
102 }
103
104 public List<ExecutableTypeData> getDelegatedFrom() {
105 return delegatedFrom;
106 }
107
108 public ExecutableTypeData getDelegatedTo() {
109 return delegatedTo;
110 }
111
112 public ExecutableElement getMethod() {
113 return method;
114 }
115
116 public String getUniqueName() {
117 return uniqueName;
118 }
119
120 public void setUniqueName(String name) {
121 this.uniqueName = name;
122 }
123
124 @Override
125 public Element getMessageElement() {
126 return method;
127 }
128
129 public List<TypeMirror> getEvaluatedParameters() {
130 return evaluatedParameters;
131 }
132
133 public List<TypeMirror> getSignatureParameters() {
134 List<TypeMirror> signaturetypes = new ArrayList<>();
135 int index = 0;
136 for (NodeExecutionData execution : node.getChildExecutions()) {
137 if (execution.isShortCircuit()) {
138 index++;
139 }
140 if (index < getEvaluatedCount()) {
141 signaturetypes.add(getEvaluatedParameters().get(index));
142 }
143 index++;
144 }
145 return signaturetypes;
146 }
147
148 public int getVarArgsIndex(int parameterIndex) {
149 if (method.isVarArgs()) {
150 int index = parameterIndex - (method.getParameters().size() - 1);
151 return index;
152 }
153 return -1;
154 }
155
156 public int getParameterIndex(int signatureIndex) {
157 return frameParameter != null ? signatureIndex + 1 : signatureIndex;
158 }
159
160 public TypeMirror getFrameParameter() {
161 return frameParameter;
162 }
163
164 public TypeMirror getReturnType() {
165 return returnType;
166 }
167
168 public boolean hasUnexpectedValue(ProcessorContext context) {
169 return method == null ? false : ElementUtils.canThrowType(method.getThrownTypes(), context.getType(UnexpectedResultException.class));
170 }
171
172 public boolean isFinal() {
173 return method == null ? false : method.getModifiers().contains(Modifier.FINAL);
174 }
175
176 public boolean isAbstract() {
177 return method == null ? false : method.getModifiers().contains(Modifier.ABSTRACT);
178 }
179
180 public int getEvaluatedCount() {
181 return evaluatedParameters.size();
182 }
183
184 public boolean canDelegateTo(ExecutableTypeData to) {
185 ExecutableTypeData from = this;
186 if (to.getEvaluatedCount() < from.getEvaluatedCount()) {
187 return false;
188 }
189
190 ProcessorContext context = node.getContext();
191
192 // we cannot delegate from generic to unexpected
193 if (!from.hasUnexpectedValue(context) && to.hasUnexpectedValue(context)) {
194 return false;
195 }
196
197 // we can skip the return type check for void. everything is assignable to void.
198 if (!isVoid(from.getReturnType())) {
199 if (!isSubtypeBoxed(context, from.getReturnType(), to.getReturnType()) && !isSubtypeBoxed(context, to.getReturnType(), from.getReturnType())) {
200 return false;
201 }
202 }
203 if (from.getFrameParameter() != to.getFrameParameter() && from.getFrameParameter() != null && to.getFrameParameter() != null &&
204 !isSubtypeBoxed(context, from.getFrameParameter(), to.getFrameParameter())) {
205 return false;
206 }
207
208 for (int i = 0; i < from.getEvaluatedCount(); i++) {
209 if (!isSubtypeBoxed(context, from.getEvaluatedParameters().get(i), to.getEvaluatedParameters().get(i))) {
210 return false;
211 }
212 }
213
214 List<TypeMirror> fromSignatureParameters = from.getSignatureParameters();
215 List<TypeMirror> toSignatureParameters = to.getSignatureParameters();
216 for (int i = fromSignatureParameters.size(); i < toSignatureParameters.size(); i++) {
217 TypeMirror delegateToParameter = toSignatureParameters.get(i);
218 if (i < node.getChildExecutions().size()) {
219 TypeMirror genericType = node.getGenericType(node.getChildExecutions().get(i));
220 if (!isSubtypeBoxed(context, genericType, delegateToParameter)) {
221 return false;
222 }
223 }
224 }
225
226 return true;
227 }
228
229 public int compareTo(ExecutableTypeData o2) {
230 ExecutableTypeData o1 = this;
231 ProcessorContext context = ProcessorContext.getInstance();
232
233 if (canDelegateTo(o2)) {
234 if (!o2.canDelegateTo(this)) {
235 return 1;
236 }
237 } else if (o2.canDelegateTo(this)) {
238 return -1;
239 }
240
241 int result = Integer.compare(o2.getEvaluatedCount(), o1.getEvaluatedCount());
242 if (result != 0) {
243 return result;
244 }
245
246 result = Boolean.compare(o1.hasUnexpectedValue(context), o2.hasUnexpectedValue(context));
247 if (result != 0) {
248 return result;
249 }
250
251 result = compareType(context, o1.getReturnType(), o2.getReturnType());
252 if (result != 0) {
253 return result;
254 }
255 result = compareType(context, o1.getFrameParameter(), o2.getFrameParameter());
256 if (result != 0) {
257 return result;
258 }
259
260 for (int i = 0; i < o1.getEvaluatedCount(); i++) {
261 result = compareType(context, o1.getEvaluatedParameters().get(i), o2.getEvaluatedParameters().get(i));
262 if (result != 0) {
263 return result;
264 }
265 }
266
267 result = o1.getUniqueName().compareTo(o2.getUniqueName());
268 if (result != 0) {
269 return result;
270 }
271
272 if (o1.getMethod() != null && o2.getMethod() != null) {
273 result = ElementUtils.compareMethod(o1.getMethod(), o2.getMethod());
274 if (result != 0) {
275 return result;
276 }
277 }
278 return 0;
279 }
280
281 public static int compareType(ProcessorContext context, TypeMirror signature1, TypeMirror signature2) {
282 if (signature1 == null) {
283 if (signature2 == null) {
284 return 0;
285 }
286 return -1;
287 } else if (signature2 == null) {
288 return 1;
289 }
290 if (ElementUtils.typeEquals(signature1, signature2)) {
291 return 0;
292 }
293 if (isVoid(signature1)) {
294 if (isVoid(signature2)) {
295 return 0;
296 }
297 return 1;
298 } else if (isVoid(signature2)) {
299 return -1;
300 }
301
302 TypeMirror boxedType1 = ElementUtils.boxType(context, signature1);
303 TypeMirror boxedType2 = ElementUtils.boxType(context, signature2);
304
305 if (ElementUtils.isSubtype(boxedType1, boxedType2)) {
306 if (ElementUtils.isSubtype(boxedType2, boxedType1)) {
307 return 0;
308 }
309 return 1;
310 } else if (ElementUtils.isSubtype(boxedType2, boxedType1)) {
311 return -1;
312 } else {
313 return ElementUtils.getSimpleName(signature1).compareTo(ElementUtils.getSimpleName(signature2));
314 }
315 }
316
317 public String getName() {
318 if (method != null) {
319 return method.getSimpleName().toString();
320 } else {
321 return getUniqueName();
322 }
323
324 }
325
326 private static String formatType(TypeMirror type) {
327 return type == null ? "null" : ElementUtils.getSimpleName(type);
328 }
329
330 @Override
331 public String toString() {
332 return String.format("%s %s(%s,%s)", formatType(getReturnType()), getName(), formatType(getFrameParameter()), getEvaluatedParameters());
333 }
334
335 public boolean sameParameters(ExecutableTypeData other) {
336 if (!typeEquals(other.getFrameParameter(), getFrameParameter())) {
337 return false;
338 }
339
340 if (getEvaluatedCount() != other.getEvaluatedCount()) {
341 return false;
342 }
343
344 for (int i = 0; i < getEvaluatedCount(); i++) {
345 if (!typeEquals(getEvaluatedParameters().get(i), other.getEvaluatedParameters().get(i))) {
346 return false;
347 }
348 }
349 return true;
350 }
351
352 public boolean sameSignature(ExecutableTypeData other) {
353 if (!typeEquals(other.getReturnType(), getReturnType())) {
354 return false;
355 }
356
357 if (other.getFrameParameter() != null) {
358 if (!typeEquals(getFrameParameter(), other.getFrameParameter())) {
359 return false;
360 }
361 }
362
363 if (getEvaluatedCount() != other.getEvaluatedCount()) {
364 return false;
365 }
366
367 for (int i = 0; i < getEvaluatedCount(); i++) {
368 if (!typeEquals(getEvaluatedParameters().get(i), other.getEvaluatedParameters().get(i))) {
369 return false;
370 }
371 }
372
373 return true;
374 }
375 }