comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java @ 18753:f6b8787dc113

Truffle-DSL: replace complex factory system with a much simpler version
author Christian Humer <christian.humer@gmail.com>
date Mon, 29 Dec 2014 23:38:21 +0100
parents 1acaa69ff61b
children 3912400fc33a
comparison
equal deleted inserted replaced
18752:1acaa69ff61b 18753:f6b8787dc113
27 27
28 import java.util.*; 28 import java.util.*;
29 29
30 import javax.lang.model.type.*; 30 import javax.lang.model.type.*;
31 31
32 import com.oracle.truffle.dsl.processor.*;
32 import com.oracle.truffle.dsl.processor.java.*; 33 import com.oracle.truffle.dsl.processor.java.*;
33 import com.oracle.truffle.dsl.processor.java.model.*; 34 import com.oracle.truffle.dsl.processor.java.model.*;
34 import com.oracle.truffle.dsl.processor.model.*; 35 import com.oracle.truffle.dsl.processor.model.*;
35 36
36 public class TypeSystemCodeGenerator extends AbstractCompilationUnitFactory<TypeSystemData> { 37 public class TypeSystemCodeGenerator extends CodeTypeElementFactory<TypeSystemData> {
37 38
38 public static String isTypeMethodName(TypeData type) { 39 public static String isTypeMethodName(TypeData type) {
39 return "is" + ElementUtils.getTypeId(type.getBoxedType()); 40 return "is" + ElementUtils.getTypeId(type.getBoxedType());
40 } 41 }
41 42
67 static String singletonName(TypeSystemData type) { 68 static String singletonName(TypeSystemData type) {
68 return createConstantName(getSimpleName(type.getTemplateType().asType())); 69 return createConstantName(getSimpleName(type.getTemplateType().asType()));
69 } 70 }
70 71
71 @Override 72 @Override
72 protected void createChildren(TypeSystemData m) { 73 public CodeTypeElement create(ProcessorContext context, TypeSystemData typeSystem) {
73 add(new TypeClassFactory(), m); 74 return new TypeClassFactory(context, typeSystem).create();
74 } 75 }
75 76
76 private static class TypeClassFactory extends AbstractClassElementFactory<TypeSystemData> { 77 private static class TypeClassFactory {
77 78
78 private static final String LOCAL_VALUE = "value"; 79 private static final String LOCAL_VALUE = "value";
79 80
80 @Override 81 private final ProcessorContext context;
81 public CodeTypeElement create(TypeSystemData typeSystem) { 82 private final TypeSystemData typeSystem;
83
84 public TypeClassFactory(ProcessorContext context, TypeSystemData typeSystem) {
85 this.context = context;
86 this.typeSystem = typeSystem;
87 }
88
89 public CodeTypeElement create() {
82 String name = typeName(typeSystem); 90 String name = typeName(typeSystem);
83 CodeTypeElement clazz = createClass(typeSystem, modifiers(PUBLIC, FINAL), name, typeSystem.getTemplateType().asType(), false); 91 CodeTypeElement clazz = GeneratorUtils.createClass(typeSystem, modifiers(PUBLIC, FINAL), name, typeSystem.getTemplateType().asType(), false);
84 92
85 clazz.add(createConstructorUsingFields(modifiers(PROTECTED), clazz)); 93 clazz.add(GeneratorUtils.createConstructorUsingFields(context, modifiers(PROTECTED), clazz));
86 CodeVariableElement singleton = createSingleton(clazz); 94 CodeVariableElement singleton = createSingleton(clazz);
87 clazz.add(singleton); 95 clazz.add(singleton);
88 96
89 for (TypeData type : typeSystem.getTypes()) { 97 for (TypeData type : typeSystem.getTypes()) {
90 if (type.isGeneric() || type.isVoid()) { 98 if (type.isGeneric() || type.isVoid()) {
118 } 126 }
119 return new ArrayList<>(sourceTypes); 127 return new ArrayList<>(sourceTypes);
120 } 128 }
121 129
122 private CodeVariableElement createSingleton(CodeTypeElement clazz) { 130 private CodeVariableElement createSingleton(CodeTypeElement clazz) {
123 CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(getModel())); 131 CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(typeSystem));
124 field.createInitBuilder().startNew(clazz.asType()).end(); 132 field.createInitBuilder().startNew(clazz.asType()).end();
125 return field; 133 return field;
126 } 134 }
127 135
128 private CodeExecutableElement createIsImplicitTypeMethod(TypeData type, boolean typed) { 136 private CodeExecutableElement createIsImplicitTypeMethod(TypeData type, boolean typed) {
129 TypeSystemData typeSystem = getModel();
130 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type); 137 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type);
131 if (casts.isEmpty()) { 138 if (casts.isEmpty()) {
132 return null; 139 return null;
133 } 140 }
134 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type)); 141 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type));
135 method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); 142 method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
136 if (typed) { 143 if (typed) {
137 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "typeHint")); 144 method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint"));
138 } 145 }
139 CodeTreeBuilder builder = method.createBuilder(); 146 CodeTreeBuilder builder = method.createBuilder();
140 147
141 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type); 148 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type);
142 149
163 builder.end(); 170 builder.end();
164 return method; 171 return method;
165 } 172 }
166 173
167 private CodeExecutableElement createAsImplicitTypeMethod(TypeData type, boolean typed) { 174 private CodeExecutableElement createAsImplicitTypeMethod(TypeData type, boolean typed) {
168 TypeSystemData typeSystem = getModel();
169 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type); 175 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type);
170 if (casts.isEmpty()) { 176 if (casts.isEmpty()) {
171 return null; 177 return null;
172 } 178 }
173 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type)); 179 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type));
174 method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); 180 method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
175 if (typed) { 181 if (typed) {
176 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "typeHint")); 182 method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint"));
177 } 183 }
178 184
179 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type); 185 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type);
180 186
181 CodeTreeBuilder builder = method.createBuilder(); 187 CodeTreeBuilder builder = method.createBuilder();
202 builder.end(); 208 builder.end();
203 builder.end(); 209 builder.end();
204 } 210 }
205 211
206 builder.startElseBlock(); 212 builder.startElseBlock();
207 builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end(); 213 builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end();
208 builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); 214 builder.startThrow().startNew(context.getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end();
209 builder.end(); 215 builder.end();
210 return method; 216 return method;
211 } 217 }
212 218
213 private CodeExecutableElement createGetTypeIndex(TypeData type) { 219 private CodeExecutableElement createGetTypeIndex(TypeData type) {
214 TypeSystemData typeSystem = getModel();
215 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type); 220 List<ImplicitCastData> casts = typeSystem.lookupByTargetType(type);
216 if (casts.isEmpty()) { 221 if (casts.isEmpty()) {
217 return null; 222 return null;
218 } 223 }
219 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type)); 224 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type));
220 method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); 225 method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
221 226
222 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type); 227 List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type);
223 CodeTreeBuilder builder = method.createBuilder(); 228 CodeTreeBuilder builder = method.createBuilder();
224 boolean elseIf = false; 229 boolean elseIf = false;
225 for (TypeData sourceType : sourceTypes) { 230 for (TypeData sourceType : sourceTypes) {
229 builder.startReturn().typeLiteral(sourceType.getPrimitiveType()).end(); 234 builder.startReturn().typeLiteral(sourceType.getPrimitiveType()).end();
230 builder.end(); 235 builder.end();
231 } 236 }
232 237
233 builder.startElseBlock(); 238 builder.startElseBlock();
234 builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end(); 239 builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end();
235 builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); 240 builder.startThrow().startNew(context.getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end();
236 builder.end(); 241 builder.end();
237 242
238 return method; 243 return method;
239 } 244 }
240 245
241 private CodeExecutableElement createIsTypeMethod(TypeData type) { 246 private CodeExecutableElement createIsTypeMethod(TypeData type) {
242 if (!type.getTypeChecks().isEmpty()) { 247 if (!type.getTypeChecks().isEmpty()) {
243 return null; 248 return null;
244 } 249 }
245 250
246 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type)); 251 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type));
247 method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); 252 method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
248 253
249 DeclaredType suppressWarnings = (DeclaredType) getContext().getType(SuppressWarnings.class); 254 DeclaredType suppressWarnings = (DeclaredType) context.getType(SuppressWarnings.class);
250 CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror(suppressWarnings); 255 CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror(suppressWarnings);
251 annotationMirror.setElementValue(annotationMirror.findExecutableElement("value"), new CodeAnnotationValue("static-method")); 256 annotationMirror.setElementValue(annotationMirror.findExecutableElement("value"), new CodeAnnotationValue("static-method"));
252 method.getAnnotationMirrors().add(annotationMirror); 257 method.getAnnotationMirrors().add(annotationMirror);
253 258
254 CodeTreeBuilder body = method.createBuilder(); 259 CodeTreeBuilder body = method.createBuilder();
261 if (!type.getTypeCasts().isEmpty()) { 266 if (!type.getTypeCasts().isEmpty()) {
262 return null; 267 return null;
263 } 268 }
264 269
265 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type)); 270 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type));
266 method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); 271 method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
267 272
268 CodeTreeBuilder body = method.createBuilder(); 273 CodeTreeBuilder body = method.createBuilder();
269 String assertMessage = typeName(getModel()) + "." + asTypeMethodName(type) + ": " + ElementUtils.getSimpleName(type.getBoxedType()) + " expected"; 274 String assertMessage = typeName(typeSystem) + "." + asTypeMethodName(type) + ": " + ElementUtils.getSimpleName(type.getBoxedType()) + " expected";
270 body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().string(" : ").doubleQuote(assertMessage).end(); 275 body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().string(" : ").doubleQuote(assertMessage).end();
271 body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end(); 276 body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end();
272 277
273 return method; 278 return method;
274 } 279 }
275 280
276 private CodeExecutableElement createExpectTypeMethod(TypeData expectedType, TypeData sourceType) { 281 private CodeExecutableElement createExpectTypeMethod(TypeData expectedType, TypeData sourceType) {
277 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType)); 282 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
278 method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE)); 283 method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE));
279 method.addThrownType(getContext().getTruffleTypes().getUnexpectedValueException()); 284 method.addThrownType(context.getTruffleTypes().getUnexpectedValueException());
280 285
281 CodeTreeBuilder body = method.createBuilder(); 286 CodeTreeBuilder body = method.createBuilder();
282 body.startIf().startCall(TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock(); 287 body.startIf().startCall(TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock();
283 body.startReturn().startCall(TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end(); 288 body.startReturn().startCall(TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end();
284 body.end(); // if-block 289 body.end(); // if-block
285 body.startThrow().startNew(getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end(); 290 body.startThrow().startNew(context.getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end();
286 291
287 return method; 292 return method;
288 } 293 }
289 294
290 } 295 }