Mercurial > hg > graal-jvmci-8
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 } |