Search in sources :

Example 16 with ObjectType

use of kalang.core.ObjectType 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 17 with ObjectType

use of kalang.core.ObjectType in project kalang by kasonyang.

the class AstBuilder method getVarObjectType.

private Type getVarObjectType(VarObject p) {
    Type type = this.overrideTypes.get(p);
    if (type == null)
        type = p.getType();
    // TODO handle other object type
    if (type instanceof ClassType) {
        Integer ns = nullState.get(p);
        NullableKind nullable;
        if (ns == null) {
            nullable = ((ObjectType) type).getNullable();
        } else if (ns == NULLSTATE_MUST_NONNULL) {
            nullable = NullableKind.NONNULL;
        } else if (ns == NULLSTATE_UNKNOWN) {
            nullable = NullableKind.UNKNOWN;
        } else if (ns == NULLSTATE_MUST_NULL || ns == NULLSTATE_NULLABLE) {
            nullable = NullableKind.NULLABLE;
        } else {
            throw Exceptions.unexceptedValue(ns);
        }
        return Types.getClassType((ClassType) type, nullable);
    } else {
        return type;
    }
}
Also used : 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) NullableKind(kalang.core.NullableKind) ClassType(kalang.core.ClassType)

Example 18 with ObjectType

use of kalang.core.ObjectType in project kalang by kasonyang.

the class AstBuilder method getObjectFieldLikeExpr.

protected ExprNode getObjectFieldLikeExpr(ExprNode expr, String fieldName, @Nullable ParserRuleContext rule) {
    ExprNode ret;
    Type type = expr.getType();
    if (!(type instanceof ObjectType)) {
        AstBuilder.this.handleSyntaxError("unsupported type", rule == null ? ParserRuleContext.EMPTY : rule);
        return null;
    }
    ObjectType exprType = (ObjectType) type;
    if ((exprType instanceof ArrayType) && fieldName.equals("length")) {
        ret = new ArrayLengthExpr(expr);
    } else {
        try {
            ret = ObjectFieldExpr.create(expr, fieldName, thisClazz);
        } catch (FieldNotFoundException ex) {
            this.diagnosisReporter.report(Diagnosis.Kind.ERROR, "field not found:" + fieldName, rule);
            ret = new UnknownFieldExpr(expr, exprType.getClassNode(), fieldName);
        }
    }
    if (rule != null)
        mapAst(ret, rule);
    return ret;
}
Also used : ExprNode(kalang.ast.ExprNode) ArrayType(kalang.core.ArrayType) 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) FieldNotFoundException(kalang.FieldNotFoundException) UnknownFieldExpr(kalang.ast.UnknownFieldExpr) ArrayLengthExpr(kalang.ast.ArrayLengthExpr)

Example 19 with ObjectType

use of kalang.core.ObjectType 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 20 with ObjectType

use of kalang.core.ObjectType in project kalang by kasonyang.

the class AstBuilder method visitForEachStat.

@Override
public Object visitForEachStat(KalangParser.ForEachStatContext ctx) {
    BlockStmt block = newBlock();
    ExprNode expr = this.visitExpression(ctx.expression());
    Type exprType = expr.getType();
    List<TerminalNode> idsCtx = ctx.Identifier();
    VarExpr indexVarExpr = null;
    TerminalNode varId;
    if (idsCtx.size() == 1) {
        varId = idsCtx.get(0);
    } else {
        TerminalNode indexId = idsCtx.get(0);
        LocalVarNode indexVar = this.declareLocalVar(indexId.getText(), Types.INT_TYPE, Modifier.FINAL, ctx);
        if (indexVar == null)
            return null;
        block.statements.add(new VarDeclStmt(indexVar));
        indexVarExpr = new VarExpr(indexVar);
        varId = idsCtx.get(1);
    }
    LoopStmt loopStmt;
    if (exprType instanceof ArrayType) {
        LocalVarNode localVarNode = this.declareLocalVar(varId.getText(), ((ArrayType) exprType).getComponentType(), Modifier.FINAL, ctx);
        if (localVarNode == null)
            return null;
        VarExpr localVariable = new VarExpr(localVarNode);
        block.statements.add(new VarDeclStmt(localVarNode));
        LocalVarNode lenVar = this.declareTempLocalVar(Types.INT_TYPE);
        LocalVarNode counterVar = this.declareTempLocalVar(Types.INT_TYPE);
        // var len
        block.statements.add(new VarDeclStmt(lenVar));
        // var i
        block.statements.add(new VarDeclStmt(counterVar));
        VarExpr counterVarExpr = new VarExpr(counterVar);
        VarExpr lenVarExpr = new VarExpr(lenVar);
        block.statements.add(new ExprStmt(new AssignExpr(lenVarExpr, new ArrayLengthExpr(expr))));
        // l = array.length
        block.statements.add(new ExprStmt(new AssignExpr(counterVarExpr, new ConstExpr(0))));
        // i=0
        ExprNode cnd = new CompareExpr(counterVarExpr, lenVarExpr, CompareExpr.OP_LT);
        BlockStmt loopBody = this.newBlock();
        loopBody.statements.add(new ExprStmt(new AssignExpr(localVariable, new ElementExpr(expr, counterVarExpr))));
        if (indexVarExpr != null) {
            loopBody.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, counterVarExpr)));
        }
        loopBody.statements.add(visitStat(ctx.stat()));
        popBlock();
        BlockStmt updateBs = newBlock();
        // increment counter
        updateBs.statements.add(new ExprStmt(new AssignExpr(counterVarExpr, new MathExpr(counterVarExpr, new ConstExpr(1), MathExpr.OP_ADD))));
        popBlock();
        loopStmt = new LoopStmt(cnd, null, loopBody, updateBs);
    } else {
        ObjectType iterType = Types.getIterableClassType();
        if (iterType.isAssignableFrom(exprType)) {
            ObjectInvokeExpr getIterableExpr;
            try {
                getIterableExpr = ObjectInvokeExpr.create(expr, "iterator", null);
            } catch (MethodNotFoundException | AmbiguousMethodException ex) {
                throw Exceptions.unexceptedException(ex);
            }
            LocalVarNode iterableVarNode = this.declareTempLocalVar(getIterableExpr.getType());
            block.statements.add(new VarDeclStmt(iterableVarNode));
            VarExpr iterableVarExpr = new VarExpr(iterableVarNode);
            block.statements.add(new ExprStmt(new AssignExpr(iterableVarExpr, getIterableExpr)));
            // set index = 0
            if (indexVarExpr != null) {
                block.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, new ConstExpr(0))));
            }
            ObjectInvokeExpr cnd;
            try {
                cnd = ObjectInvokeExpr.create(iterableVarExpr, "hasNext", null);
            } catch (MethodNotFoundException | AmbiguousMethodException ex) {
                throw Exceptions.unexceptedException(ex);
            }
            BlockStmt loopBody = this.newBlock();
            ObjectInvokeExpr nextInvokeExpr;
            try {
                nextInvokeExpr = ObjectInvokeExpr.create(iterableVarExpr, "next", null);
            } catch (MethodNotFoundException | AmbiguousMethodException ex) {
                throw Exceptions.unexceptedException(ex);
            }
            LocalVarNode localVarNode = this.declareLocalVar(varId.getText(), nextInvokeExpr.getType(), Modifier.FINAL, ctx);
            if (localVarNode == null)
                return null;
            VarExpr localVariable = new VarExpr(localVarNode);
            loopBody.statements.add(new VarDeclStmt(localVarNode));
            loopBody.statements.add(new ExprStmt(new AssignExpr(localVariable, new CastExpr(localVariable.getType(), nextInvokeExpr))));
            loopBody.statements.add(visitStat(ctx.stat()));
            popBlock();
            BlockStmt updateBs = newBlock();
            if (indexVarExpr != null) {
                // do index++
                updateBs.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, new MathExpr(indexVarExpr, new ConstExpr(1), BinaryExpr.OP_ADD))));
            }
            popBlock();
            loopStmt = new LoopStmt(cnd, null, loopBody, updateBs);
        } else {
            this.handleSyntaxError("require array type or iterable type", ctx.expression());
            loopStmt = null;
        }
    }
    popBlock();
    if (loopStmt != null)
        block.statements.add(loopStmt);
    return block;
}
Also used : ConstExpr(kalang.ast.ConstExpr) LoopStmt(kalang.ast.LoopStmt) BlockStmt(kalang.ast.BlockStmt) ArrayLengthExpr(kalang.ast.ArrayLengthExpr) AssignExpr(kalang.ast.AssignExpr) ExprNode(kalang.ast.ExprNode) ArrayType(kalang.core.ArrayType) 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) ExprStmt(kalang.ast.ExprStmt) CompareExpr(kalang.ast.CompareExpr) VarDeclStmt(kalang.ast.VarDeclStmt) ObjectInvokeExpr(kalang.ast.ObjectInvokeExpr) PrimitiveCastExpr(kalang.ast.PrimitiveCastExpr) CastExpr(kalang.ast.CastExpr) VarExpr(kalang.ast.VarExpr) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) LocalVarNode(kalang.ast.LocalVarNode) MethodNotFoundException(kalang.MethodNotFoundException) MathExpr(kalang.ast.MathExpr) ElementExpr(kalang.ast.ElementExpr) AmbiguousMethodException(kalang.AmbiguousMethodException)

Aggregations

ObjectType (kalang.core.ObjectType)32 GenericType (kalang.core.GenericType)15 ClassType (kalang.core.ClassType)14 Type (kalang.core.Type)14 ExprNode (kalang.ast.ExprNode)11 ArrayType (kalang.core.ArrayType)11 PrimitiveType (kalang.core.PrimitiveType)9 WildcardType (kalang.core.WildcardType)9 MethodNotFoundException (kalang.MethodNotFoundException)8 ClassNode (kalang.ast.ClassNode)7 Nullable (javax.annotation.Nullable)6 AmbiguousMethodException (kalang.AmbiguousMethodException)6 ObjectInvokeExpr (kalang.ast.ObjectInvokeExpr)6 LinkedList (java.util.LinkedList)4 FieldNotFoundException (kalang.FieldNotFoundException)4 BlockStmt (kalang.ast.BlockStmt)4 ThisExpr (kalang.ast.ThisExpr)4 ExprStmt (kalang.ast.ExprStmt)3 InvocationExpr (kalang.ast.InvocationExpr)3 MethodNode (kalang.ast.MethodNode)3