comparison truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/GeneratorUtils.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/generator/GeneratorUtils.java@b1530a6cce8c
children dc83cc1f94f2
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
1 /*
2 * Copyright (c) 2014, 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.generator;
24
25 import static com.oracle.truffle.dsl.processor.java.ElementUtils.*;
26 import static javax.lang.model.element.Modifier.*;
27
28 import java.util.*;
29
30 import javax.lang.model.element.*;
31 import javax.lang.model.type.*;
32 import javax.lang.model.util.*;
33
34 import com.oracle.truffle.api.*;
35 import com.oracle.truffle.api.dsl.*;
36 import com.oracle.truffle.api.dsl.internal.DSLOptions.TypeBoxingOptimization;
37 import com.oracle.truffle.dsl.processor.*;
38 import com.oracle.truffle.dsl.processor.java.*;
39 import com.oracle.truffle.dsl.processor.java.model.*;
40 import com.oracle.truffle.dsl.processor.model.*;
41
42 public class GeneratorUtils {
43
44 public static CodeTree createTransferToInterpreterAndInvalidate() {
45 ProcessorContext context = ProcessorContext.getInstance();
46 CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
47 builder.startStatement().startStaticCall(context.getType(CompilerDirectives.class), "transferToInterpreterAndInvalidate").end().end();
48 return builder.build();
49 }
50
51 public static CodeExecutableElement createConstructorUsingFields(Set<Modifier> modifiers, CodeTypeElement clazz) {
52 TypeElement superClass = fromTypeMirror(clazz.getSuperclass());
53 ExecutableElement constructor = findConstructor(superClass);
54 return createConstructorUsingFields(modifiers, clazz, constructor);
55 }
56
57 public static CodeExecutableElement createConstructorUsingFields(Set<Modifier> modifiers, CodeTypeElement clazz, ExecutableElement constructor) {
58 CodeExecutableElement method = new CodeExecutableElement(modifiers, null, clazz.getSimpleName().toString());
59 CodeTreeBuilder builder = method.createBuilder();
60 if (constructor != null && constructor.getParameters().size() > 0) {
61 builder.startStatement();
62 builder.startSuperCall();
63 for (VariableElement parameter : constructor.getParameters()) {
64 method.addParameter(new CodeVariableElement(parameter.asType(), parameter.getSimpleName().toString()));
65 builder.string(parameter.getSimpleName().toString());
66 }
67 builder.end(); // super
68 builder.end(); // statement
69 }
70
71 for (VariableElement field : clazz.getFields()) {
72 if (field.getModifiers().contains(STATIC)) {
73 continue;
74 }
75 String fieldName = field.getSimpleName().toString();
76 method.addParameter(new CodeVariableElement(field.asType(), fieldName));
77 builder.startStatement();
78 builder.string("this.");
79 builder.string(fieldName);
80 builder.string(" = ");
81 builder.string(fieldName);
82 builder.end(); // statement
83 }
84
85 return method;
86 }
87
88 public static boolean isTypeBoxingOptimized(TypeBoxingOptimization boxing, TypeMirror type) {
89 switch (boxing) {
90 case NONE:
91 return false;
92 case ALWAYS:
93 return !ElementUtils.isObject(type) && !ElementUtils.isVoid(type);
94 case PRIMITIVE:
95 return ElementUtils.isPrimitive(type);
96 default:
97 throw new AssertionError();
98 }
99 }
100
101 private static ExecutableElement findConstructor(TypeElement clazz) {
102 List<ExecutableElement> constructors = ElementFilter.constructorsIn(clazz.getEnclosedElements());
103 if (constructors.isEmpty()) {
104 return null;
105 } else {
106 return constructors.get(0);
107 }
108 }
109
110 public static CodeExecutableElement createSuperConstructor(ProcessorContext context, TypeElement type, ExecutableElement element) {
111 if (element.getModifiers().contains(Modifier.PRIVATE)) {
112 return null;
113 }
114 CodeExecutableElement executable = CodeExecutableElement.clone(context.getEnvironment(), element);
115 executable.setReturnType(null);
116 executable.setSimpleName(CodeNames.of(type.getSimpleName().toString()));
117 CodeTreeBuilder b = executable.createBuilder();
118 b.startStatement();
119 b.startSuperCall();
120 for (VariableElement v : element.getParameters()) {
121 b.string(v.getSimpleName().toString());
122 }
123 b.end();
124 b.end();
125
126 return executable;
127 }
128
129 public static CodeTypeElement createClass(Template sourceModel, TemplateMethod sourceMethod, Set<Modifier> modifiers, String simpleName, TypeMirror superType) {
130 TypeElement templateType = sourceModel.getTemplateType();
131
132 ProcessorContext context = ProcessorContext.getInstance();
133
134 PackageElement pack = context.getEnvironment().getElementUtils().getPackageOf(templateType);
135 CodeTypeElement clazz = new CodeTypeElement(modifiers, ElementKind.CLASS, pack, simpleName);
136 TypeMirror resolvedSuperType = superType;
137 if (resolvedSuperType == null) {
138 resolvedSuperType = context.getType(Object.class);
139 }
140 clazz.setSuperClass(resolvedSuperType);
141
142 CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) context.getType(GeneratedBy.class));
143 generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(templateType.asType()));
144 if (sourceMethod != null && sourceMethod.getMethod() != null) {
145 generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("methodName"), new CodeAnnotationValue(sourceMethod.createReferenceName()));
146 }
147
148 clazz.addAnnotationMirror(generatedByAnnotation);
149 return clazz;
150 }
151
152 public static List<ExecutableElement> findUserConstructors(TypeMirror nodeType) {
153 List<ExecutableElement> constructors = new ArrayList<>();
154 for (ExecutableElement constructor : ElementFilter.constructorsIn(ElementUtils.fromTypeMirror(nodeType).getEnclosedElements())) {
155 if (constructor.getModifiers().contains(PRIVATE)) {
156 continue;
157 }
158 if (isCopyConstructor(constructor)) {
159 continue;
160 }
161 constructors.add(constructor);
162 }
163
164 if (constructors.isEmpty()) {
165 constructors.add(new CodeExecutableElement(null, ElementUtils.getSimpleName(nodeType)));
166 }
167
168 return constructors;
169 }
170
171 public static boolean isCopyConstructor(ExecutableElement element) {
172 if (element.getParameters().size() != 1) {
173 return false;
174 }
175 VariableElement var = element.getParameters().get(0);
176 TypeElement enclosingType = ElementUtils.findNearestEnclosingType(var);
177 if (ElementUtils.typeEquals(var.asType(), enclosingType.asType())) {
178 return true;
179 }
180 List<TypeElement> types = ElementUtils.getDirectSuperTypes(enclosingType);
181 for (TypeElement type : types) {
182 if (!(type instanceof CodeTypeElement)) {
183 // no copy constructors which are not generated types
184 return false;
185 }
186
187 if (ElementUtils.typeEquals(var.asType(), type.asType())) {
188 return true;
189 }
190 }
191 return false;
192 }
193
194 }