Search in sources :

Example 11 with ClassNode

use of kalang.ast.ClassNode in project kalang by kasonyang.

the class ClassType method isAssignableFrom.

@Override
public boolean isAssignableFrom(Type type) {
    if (super.isAssignableFrom(type))
        return true;
    if (type instanceof ClassType) {
        ClassType other = (ClassType) type;
        if (!nullable.isAssignableFrom(other.getNullable()))
            return false;
        ClassNode otherClazz = other.getClassNode();
        if (!clazz.equals(otherClazz))
            return false;
        GenericType[] gts = clazz.getGenericTypes();
        if (gts.length == 0)
            return true;
        // handle parameterizedType
        Type[] typeArgs = getTypeArguments();
        Type[] otherTypeArgs = other.getTypeArguments();
        if (typeArgs.length == 0 || otherTypeArgs.length == 0)
            return true;
        if (typeArgs.length != otherTypeArgs.length)
            return false;
        for (int i = 0; i < typeArgs.length; i++) {
            Type a = typeArgs[i];
            Type oa = otherTypeArgs[i];
            if (a.equals(oa))
                continue;
            if (a instanceof WildcardType) {
                WildcardType wt = (WildcardType) a;
                if (!wt.containsType((ObjectType) oa))
                    return false;
            }
        }
        return true;
    }
    return false;
}
Also used : ClassNode(kalang.ast.ClassNode)

Example 12 with ClassNode

use of kalang.ast.ClassNode in project kalang by kasonyang.

the class Ast2Class method visitClassNode.

@Override
public Object visitClassNode(ClassNode node) {
    ClassNode oldClass = this.clazz;
    this.clazz = node;
    String oldClassInternalName = this.classInternalName;
    this.classInternalName = internalName(clazz);
    ClassWriter oldClassWriter = this.classWriter;
    this.classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    annotation(classWriter, clazz.getAnnotations());
    String parentName = "java.lang.Object";
    ObjectType superType = node.getSuperType();
    if (superType != null) {
        parentName = superType.getName();
    }
    String[] interfaces = null;
    if (node.getInterfaces().length > 0) {
        interfaces = internalName(node.getInterfaces());
    }
    int access = node.modifier;
    classWriter.visit(V1_6, access, internalName(node.name), classSignature(node), internalName(parentName), interfaces);
    String fileName = node.fileName;
    if (fileName != null && !fileName.isEmpty()) {
        classWriter.visitSource(fileName, null);
    }
    visitChildren(node);
    // clinit
    if (!node.staticInitStmts.isEmpty()) {
        md = classWriter.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
        visitAll(node.staticInitStmts);
        md.visitInsn(RETURN);
        md.visitMaxs(1, 1);
    }
    if (node.enclosingClass != null) {
        this.classWriter.visitInnerClass(this.internalName(node), this.internalName(node.enclosingClass), NameUtil.getSimpleClassName(node.name), node.modifier);
    }
    for (ClassNode ic : node.classes) {
        classWriter.visitInnerClass(internalName(ic), internalName(node), NameUtil.getSimpleClassName(ic.name), ic.modifier);
    }
    classWriter.visitEnd();
    if (outputManager != null) {
        try {
            try (OutputStream os = outputManager.createOutputStream(node.name)) {
                os.write(this.classWriter.toByteArray());
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    } else {
        LOG.log(Level.WARNING, "outputManager is null");
    }
    this.clazz = oldClass;
    this.classInternalName = oldClassInternalName;
    this.classWriter = oldClassWriter;
    return null;
}
Also used : ClassNode(kalang.ast.ClassNode) ObjectType(kalang.core.ObjectType) ClassWriter(org.objectweb.asm.ClassWriter)

Example 13 with ClassNode

use of kalang.ast.ClassNode in project kalang by kasonyang.

the class AstBuilder method parseClassType.

@Nullable
protected ObjectType parseClassType(KalangParser.ClassTypeContext ctx) {
    NullableKind nullable = ctx.nullable == null ? NullableKind.NONNULL : NullableKind.NULLABLE;
    Token rawTypeToken = ctx.rawClass;
    List<String> classNameParts = new LinkedList();
    for (Token p : ctx.paths) {
        classNameParts.add(p.getText());
    }
    if (ctx.innerClass != null) {
        classNameParts.add(rawTypeToken.getText() + "$" + ctx.innerClass.getText());
    } else {
        classNameParts.add(rawTypeToken.getText());
    }
    String rawType = String.join(".", classNameParts);
    for (GenericType gt : thisClazz.getGenericTypes()) {
        if (rawType.equals(gt.getName()))
            return gt;
    }
    ObjectType clazzType = requireClassType(rawType, rawTypeToken);
    if (clazzType == null)
        return null;
    ClassNode clazzNode = clazzType.getClassNode();
    GenericType[] clzDeclaredGenericTypes = clazzNode.getGenericTypes();
    List<KalangParser.ParameterizedElementTypeContext> parameterTypes = ctx.parameterTypes;
    if (parameterTypes != null && !parameterTypes.isEmpty()) {
        Type[] typeArguments = new Type[parameterTypes.size()];
        if (parameterTypes != null && parameterTypes.size() > 0) {
            if (clzDeclaredGenericTypes.length != parameterTypes.size()) {
                diagnosisReporter.report(Diagnosis.Kind.ERROR, "wrong number of type arguments", ctx);
                return null;
            }
            for (int i = 0; i < typeArguments.length; i++) {
                typeArguments[i] = parseParameterizedElementType(parameterTypes.get(i));
                // TODO should return null?
                if (typeArguments[i] == null)
                    return null;
            }
        }
        return Types.getClassType(clazzType.getClassNode(), typeArguments, nullable);
    } else {
        return Types.getClassType(clazzType.getClassNode(), nullable);
    }
}
Also used : ClassNode(kalang.ast.ClassNode) GenericType(kalang.core.GenericType) NullableKind(kalang.core.NullableKind) Token(org.antlr.v4.runtime.Token) LinkedList(java.util.LinkedList) ObjectType(kalang.core.ObjectType) WildcardType(kalang.core.WildcardType) ArrayType(kalang.core.ArrayType) ClassType(kalang.core.ClassType) PrimitiveType(kalang.core.PrimitiveType) Type(kalang.core.Type) GenericType(kalang.core.GenericType) ObjectType(kalang.core.ObjectType) Nullable(javax.annotation.Nullable)

Example 14 with ClassNode

use of kalang.ast.ClassNode in project kalang by kasonyang.

the class AstBuilder method visitAnnotation.

@Override
@Nullable
public AnnotationNode visitAnnotation(KalangParser.AnnotationContext ctx) {
    ClassNode anType = requireAst(ctx.annotationType);
    if (anType == null)
        return null;
    List<Token> vk = ctx.annotationValueKey;
    LiteralContext dv = ctx.annotationDefaultValue;
    AnnotationNode anNode = new AnnotationNode(anType);
    if (vk != null && vk.size() > 0) {
        List<LiteralContext> anValues = ctx.annotationValue;
        int ksize = vk.size();
        for (int i = 0; i < ksize; i++) {
            String kname = vk.get(i).getText();
            ConstExpr value = visitLiteral(anValues.get(i));
            anNode.values.put(kname, value);
        }
    } else if (dv != null) {
        ConstExpr defaultValue = visitLiteral(dv);
        anNode.values.put("value", defaultValue);
    }
    if (!semanticAnalyzer.validateAnnotation(anNode))
        return null;
    // TODO validate annotation's values
    return anNode;
}
Also used : LiteralContext(kalang.antlr.KalangParser.LiteralContext) ClassNode(kalang.ast.ClassNode) ConstExpr(kalang.ast.ConstExpr) AnnotationNode(kalang.ast.AnnotationNode) Token(org.antlr.v4.runtime.Token) Nullable(javax.annotation.Nullable)

Example 15 with ClassNode

use of kalang.ast.ClassNode in project kalang by kasonyang.

the class AstLoader method loadAst.

@Nonnull
public ClassNode loadAst(@Nonnull String className) throws AstNotFoundException {
    ClassNode ast = cachedAsts.get(className);
    if (ast != null)
        return ast;
    if (parent != null) {
        try {
            return parent.loadAst(className);
        } catch (AstNotFoundException ex) {
        }
    }
    if (className.endsWith("[]")) {
        String name = className;
        name = name.substring(0, name.length() - 2);
        ast = AstUtil.createArrayAst(loadAst(name).name);
    } else {
        ast = findAst(className);
        if (ast == null)
            throw new AstNotFoundException(className);
    }
    cachedAsts.put(className, ast);
    return ast;
}
Also used : ClassNode(kalang.ast.ClassNode) AstNotFoundException(kalang.AstNotFoundException) Nonnull(javax.annotation.Nonnull)

Aggregations

ClassNode (kalang.ast.ClassNode)21 ObjectType (kalang.core.ObjectType)8 Nullable (javax.annotation.Nullable)4 ClassType (kalang.core.ClassType)4 Token (org.antlr.v4.runtime.Token)4 BlockStmt (kalang.ast.BlockStmt)3 ArrayType (kalang.core.ArrayType)3 GenericType (kalang.core.GenericType)3 Type (kalang.core.Type)3 LinkedList (java.util.LinkedList)2 Nonnull (javax.annotation.Nonnull)2 AssignExpr (kalang.ast.AssignExpr)2 ConstExpr (kalang.ast.ConstExpr)2 ExprNode (kalang.ast.ExprNode)2 ExprStmt (kalang.ast.ExprStmt)2 MethodNode (kalang.ast.MethodNode)2 Statement (kalang.ast.Statement)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 AmbiguousMethodException (kalang.AmbiguousMethodException)1