diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java @ 18758:3912400fc33a

Truffle-DSL: remove type system singleton
author Christian Humer <christian.humer@gmail.com>
date Mon, 29 Dec 2014 23:38:42 +0100
parents f6b8787dc113
children a665483c3881
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java	Mon Dec 29 23:38:39 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java	Mon Dec 29 23:38:42 2014 +0100
@@ -36,6 +36,105 @@
 
 public class TypeSystemCodeGenerator extends CodeTypeElementFactory<TypeSystemData> {
 
+    public static CodeTree cast(TypeData type, String content) {
+        return cast(type, CodeTreeBuilder.singleString(content));
+    }
+
+    public static CodeTree implicitType(TypeData type, String valueName) {
+        if (type.isGeneric()) {
+            return CodeTreeBuilder.singleString(valueName);
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), getImplicitClass(type)).string(valueName);
+        builder.end();
+        return builder.getRoot();
+    }
+
+    public static CodeTree invokeImplicitCast(ImplicitCastData cast, CodeTree expression) {
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = cast.getTargetType().getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), cast.getMethodName()).tree(expression);
+        builder.end();
+        return builder.getRoot();
+    }
+
+    public static CodeTree implicitCheck(TypeData type, String valueName, String typeHint) {
+        if (type.isGeneric()) {
+            return CodeTreeBuilder.singleString(valueName);
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), isImplicitTypeMethodName(type)).string(valueName);
+        if (typeHint != null) {
+            builder.string(typeHint);
+        }
+        builder.end();
+        return builder.getRoot();
+    }
+
+    public static CodeTree implicitCast(TypeData type, String valueName, String typeHint) {
+        if (type.isGeneric()) {
+            return CodeTreeBuilder.singleString(valueName);
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), asImplicitTypeMethodName(type)).string(valueName);
+        if (typeHint != null) {
+            builder.string(typeHint);
+        }
+        builder.end();
+        return builder.getRoot();
+    }
+
+    public static CodeTree cast(TypeData type, CodeTree content) {
+        if (type.isGeneric()) {
+            return content;
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+
+        if (type.isDefaultCast()) {
+            builder.cast(type.getPrimitiveType(), content);
+        } else {
+            builder.startStaticCall(typeSystem.getTemplateType().asType(), type.getTypeCasts().get(0).getMethodName()).tree(content).end();
+        }
+        return builder.getRoot();
+    }
+
+    public static CodeTree expect(TypeData type, CodeTree content) {
+        if (type.isGeneric()) {
+            return content;
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+        builder.startStaticCall(createTypeSystemGen(typeSystem), expectTypeMethodName(type)).tree(content).end();
+        return builder.getRoot();
+    }
+
+    private static CodeTypeMirror createTypeSystemGen(TypeSystemData typeSystem) {
+        return new GeneratedTypeMirror(ElementUtils.getPackageName(typeSystem.getTemplateType()), typeName(typeSystem));
+    }
+
+    public static CodeTree check(TypeData type, String content) {
+        return check(type, CodeTreeBuilder.singleString(content));
+    }
+
+    public static CodeTree check(TypeData type, CodeTree content) {
+        if (type.isGeneric()) {
+            return content;
+        }
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        TypeSystemData typeSystem = type.getTypeSystem();
+
+        if (type.isDefaultCheck()) {
+            builder.instanceOf(content, type.getBoxedType());
+        } else {
+            builder.startStaticCall(typeSystem.getTemplateType().asType(), type.getTypeChecks().get(0).getMethodName()).tree(content).end();
+        }
+        return builder.getRoot();
+    }
+
     public static String isTypeMethodName(TypeData type) {
         return "is" + ElementUtils.getTypeId(type.getBoxedType());
     }
@@ -124,12 +223,17 @@
             for (TypeCheckData cast : type.getTypeChecks()) {
                 sourceTypes.add(cast.getCheckedType());
             }
+            sourceTypes.remove(type);
             return new ArrayList<>(sourceTypes);
         }
 
         private CodeVariableElement createSingleton(CodeTypeElement clazz) {
             CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(typeSystem));
             field.createInitBuilder().startNew(clazz.asType()).end();
+
+            CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror((DeclaredType) context.getType(Deprecated.class));
+            field.getAnnotationMirrors().add(annotationMirror);
+
             return field;
         }
 
@@ -138,7 +242,7 @@
             if (casts.isEmpty()) {
                 return null;
             }
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
             if (typed) {
                 method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint"));
@@ -154,7 +258,7 @@
                 if (typed) {
                     builder.string("(typeHint == ").typeLiteral(sourceType.getPrimitiveType()).string(" && ");
                 }
-                builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
+                builder.tree(check(sourceType, LOCAL_VALUE));
                 if (typed) {
                     builder.string(")");
                 }
@@ -176,7 +280,7 @@
             if (casts.isEmpty()) {
                 return null;
             }
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
             if (typed) {
                 method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint"));
@@ -191,7 +295,7 @@
                 if (typed) {
                     builder.string("typeHint == ").typeLiteral(sourceType.getPrimitiveType());
                 } else {
-                    builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
+                    builder.tree(check(sourceType, LOCAL_VALUE));
                 }
 
                 builder.end().startBlock();
@@ -201,7 +305,7 @@
                 if (cast != null) {
                     builder.startCall(cast.getMethodName());
                 }
-                builder.startCall(asTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
+                builder.tree(cast(sourceType, LOCAL_VALUE)).end();
                 if (cast != null) {
                     builder.end();
                 }
@@ -221,7 +325,7 @@
             if (casts.isEmpty()) {
                 return null;
             }
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
 
             List<TypeData> sourceTypes = typeSystem.lookupSourceTypes(type);
@@ -229,7 +333,7 @@
             boolean elseIf = false;
             for (TypeData sourceType : sourceTypes) {
                 elseIf = builder.startIf(elseIf);
-                builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end();
+                builder.tree(check(sourceType, LOCAL_VALUE)).end();
                 builder.end().startBlock();
                 builder.startReturn().typeLiteral(sourceType.getPrimitiveType()).end();
                 builder.end();
@@ -248,16 +352,11 @@
                 return null;
             }
 
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), context.getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
 
-            DeclaredType suppressWarnings = (DeclaredType) context.getType(SuppressWarnings.class);
-            CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror(suppressWarnings);
-            annotationMirror.setElementValue(annotationMirror.findExecutableElement("value"), new CodeAnnotationValue("static-method"));
-            method.getAnnotationMirrors().add(annotationMirror);
-
             CodeTreeBuilder body = method.createBuilder();
-            body.startReturn().instanceOf(LOCAL_VALUE, type.getBoxedType()).end();
+            body.startReturn().tree(check(type, LOCAL_VALUE)).end();
 
             return method;
         }
@@ -267,25 +366,25 @@
                 return null;
             }
 
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type));
             method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE));
 
             CodeTreeBuilder body = method.createBuilder();
             String assertMessage = typeName(typeSystem) + "." + asTypeMethodName(type) + ": " + ElementUtils.getSimpleName(type.getBoxedType()) + " expected";
-            body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().string(" : ").doubleQuote(assertMessage).end();
-            body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end();
+            body.startAssert().tree(check(type, LOCAL_VALUE)).string(" : ").doubleQuote(assertMessage).end();
+            body.startReturn().tree(cast(type, LOCAL_VALUE)).end();
 
             return method;
         }
 
         private CodeExecutableElement createExpectTypeMethod(TypeData expectedType, TypeData sourceType) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
             method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE));
             method.addThrownType(context.getTruffleTypes().getUnexpectedValueException());
 
             CodeTreeBuilder body = method.createBuilder();
-            body.startIf().startCall(TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock();
-            body.startReturn().startCall(TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end();
+            body.startIf().tree(check(expectedType, LOCAL_VALUE)).end().startBlock();
+            body.startReturn().tree(cast(expectedType, LOCAL_VALUE)).end().end();
             body.end(); // if-block
             body.startThrow().startNew(context.getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end();
 
@@ -293,4 +392,5 @@
         }
 
     }
+
 }