Search in sources :

Example 6 with ClassReference

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

the class AstBuilder method getImplicitInvokeExpr.

@Nullable
private ExprNode getImplicitInvokeExpr(String methodName, ExprNode[] args, ParserRuleContext ctx) {
    ExprNode expr = null;
    try {
        ObjectType clazzType = getThisType();
        InvocationExpr.MethodSelection ms = InvocationExpr.applyMethod(clazzType, methodName, args, clazzType.getMethodDescriptors(thisClazz, true, true));
        if (Modifier.isStatic(ms.selectedMethod.getModifier())) {
            expr = new StaticInvokeExpr(new ClassReference(thisClazz), ms.selectedMethod, ms.appliedArguments);
        } else {
            expr = new ObjectInvokeExpr(new ThisExpr(getThisType()), ms.selectedMethod, ms.appliedArguments);
        }
    } catch (MethodNotFoundException ex) {
        if (args.length == 1 && (methodName.equals("print") || methodName.equals("println"))) {
            try {
                StaticFieldExpr fieldExpr = StaticFieldExpr.create(new ClassReference(Types.requireClassType("java.lang.System").getClassNode()), "out", null);
                expr = getObjectInvokeExpr(fieldExpr, methodName, args, ctx);
            } catch (FieldNotFoundException fnfEx) {
                throw Exceptions.unexceptedException(fnfEx);
            }
        }
        if (expr == null) {
            this.methodNotFound(ctx.getStart(), className, methodName, args);
            expr = new UnknownInvocationExpr(null, methodName, args);
        }
    } catch (AmbiguousMethodException ex) {
        methodIsAmbiguous(ctx.start, ex);
        return null;
    }
    mapAst(expr, ctx);
    return expr;
}
Also used : FieldNotFoundException(kalang.FieldNotFoundException) ExprNode(kalang.ast.ExprNode) StaticInvokeExpr(kalang.ast.StaticInvokeExpr) ObjectType(kalang.core.ObjectType) StaticFieldExpr(kalang.ast.StaticFieldExpr) ObjectInvokeExpr(kalang.ast.ObjectInvokeExpr) ClassReference(kalang.ast.ClassReference) MethodNotFoundException(kalang.MethodNotFoundException) UnknownInvocationExpr(kalang.ast.UnknownInvocationExpr) InvocationExpr(kalang.ast.InvocationExpr) UnknownInvocationExpr(kalang.ast.UnknownInvocationExpr) ThisExpr(kalang.ast.ThisExpr) AmbiguousMethodException(kalang.AmbiguousMethodException) Nullable(javax.annotation.Nullable)

Example 7 with ClassReference

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

the class AstBuilder method createFieldExpr.

protected ExprNode createFieldExpr(GetFieldExprContext to, @Nullable ExpressionContext fromCtx, OffsetRange offsetRange) {
    // TODO support iterating syntax
    String refKey = to.refKey.getText();
    ExpressionContext exp = to.expression();
    String fname = to.Identifier().getText();
    AssignableExpr toExpr;
    Object expr = visit(exp);
    if (refKey.equals(".")) {
        ExprNode fieldExpr;
        if (expr instanceof ExprNode) {
            ExprNode exprNode = (ExprNode) expr;
            fieldExpr = getObjectFieldLikeExpr(exprNode, fname, to);
        } else if (expr instanceof ClassReference) {
            fieldExpr = getStaticFieldExpr((ClassReference) expr, fname, to);
        } else {
            throw new UnknownError("unknown node:" + expr);
        }
        if (fromCtx == null) {
            return fieldExpr;
        } else {
            if (fieldExpr instanceof AssignableExpr) {
                toExpr = (AssignableExpr) fieldExpr;
            } else {
                AstBuilder.this.handleSyntaxError("unsupported", to);
                return null;
            }
            ExprNode fromExpr = visitExpression(fromCtx);
            if (!this.semanticAnalyzer.validateAssign(toExpr, fromExpr, offsetRange)) {
                return null;
            }
            return new AssignExpr(toExpr, fromExpr);
        }
    } else if (refKey.equals("->")) {
        ExprNode[] params;
        String methodName;
        if (fromCtx == null) {
            params = new ExprNode[0];
            methodName = "get" + NameUtil.firstCharToUpperCase(fname);
        } else {
            params = new ExprNode[1];
            methodName = "set" + NameUtil.firstCharToUpperCase(fname);
        }
        if (expr instanceof ExprNode) {
            if (fromCtx != null)
                params[0] = visitExpression(fromCtx);
            return getObjectInvokeExpr((ExprNode) expr, methodName, params, to);
        } else {
            // don't support static property
            handleSyntaxError("object expression required.", to);
            return null;
        }
    } else {
        throw Exceptions.unknownValue(refKey);
    }
}
Also used : ExprNode(kalang.ast.ExprNode) ExpressionContext(kalang.antlr.KalangParser.ExpressionContext) AssignableExpr(kalang.ast.AssignableExpr) VarObject(kalang.ast.VarObject) ClassReference(kalang.ast.ClassReference) AssignExpr(kalang.ast.AssignExpr)

Example 8 with ClassReference

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

the class ClassNodeMetaBuilder method visitFieldDecl.

@Override
public Void visitFieldDecl(KalangParser.FieldDeclContext ctx) {
    int fieldModifier = astBuilder.parseModifier(ctx.varModifier());
    for (KalangParser.VarDeclContext vd : ctx.varDecl()) {
        ExprNode initExpr;
        if (vd.expression() != null) {
            initExpr = astBuilder.visitExpression(vd.expression());
        } else {
            initExpr = null;
        }
        AstBuilder.VarInfo varInfo = astBuilder.varDecl(vd, initExpr == null ? Types.getRootType() : initExpr.getType());
        varInfo.modifier |= fieldModifier;
        FieldNode fieldNode = thisClazz.createField(varInfo.type, varInfo.name, varInfo.modifier);
        // TODO simplify it
        if (initExpr != null) {
            if (AstUtil.isStatic(fieldNode.modifier)) {
                thisClazz.staticInitStmts.add(new ExprStmt(new AssignExpr(new StaticFieldExpr(new ClassReference(thisClazz), fieldNode), initExpr)));
            } else {
                thisClazz.initStmts.add(new ExprStmt(new AssignExpr(new ObjectFieldExpr(new ThisExpr(Types.getClassType(thisClazz)), fieldNode), initExpr)));
            }
        }
    }
    return null;
}
Also used : FieldNode(kalang.ast.FieldNode) AssignExpr(kalang.ast.AssignExpr) ExprNode(kalang.ast.ExprNode) StaticFieldExpr(kalang.ast.StaticFieldExpr) ObjectFieldExpr(kalang.ast.ObjectFieldExpr) KalangParser(kalang.antlr.KalangParser) ExprStmt(kalang.ast.ExprStmt) ClassReference(kalang.ast.ClassReference) ThisExpr(kalang.ast.ThisExpr)

Example 9 with ClassReference

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

the class AstUtil method createSetter.

public static void createSetter(ClassNode clazz, FieldDescriptor field, int accessModifier) {
    String fn = field.getName();
    String setterName = "set" + NameUtil.firstCharToUpperCase(fn);
    boolean isStatic = isStatic(field.getModifier());
    if (isStatic) {
        accessModifier |= Modifier.STATIC;
    }
    MethodNode setter = clazz.createMethodNode(Types.VOID_TYPE, setterName, accessModifier);
    // setter.offset = field.offset;
    ParameterNode param = setter.createParameter(field.getType(), field.getName());
    BlockStmt body = setter.getBody();
    FieldExpr fe;
    ExprNode paramVal = new ParameterExpr(param);
    ClassReference cr = new ClassReference(clazz);
    if (isStatic) {
        fe = new StaticFieldExpr(cr, field);
    } else {
        fe = new ObjectFieldExpr(new ThisExpr(Types.getClassType(clazz)), field);
    }
    body.statements.add(new ExprStmt(new AssignExpr(fe, paramVal)));
}
Also used : ParameterExpr(kalang.ast.ParameterExpr) BlockStmt(kalang.ast.BlockStmt) AssignExpr(kalang.ast.AssignExpr) ExprNode(kalang.ast.ExprNode) StaticFieldExpr(kalang.ast.StaticFieldExpr) ObjectFieldExpr(kalang.ast.ObjectFieldExpr) MethodNode(kalang.ast.MethodNode) ParameterNode(kalang.ast.ParameterNode) ExprStmt(kalang.ast.ExprStmt) ClassReference(kalang.ast.ClassReference) StaticFieldExpr(kalang.ast.StaticFieldExpr) FieldExpr(kalang.ast.FieldExpr) ObjectFieldExpr(kalang.ast.ObjectFieldExpr) ThisExpr(kalang.ast.ThisExpr)

Example 10 with ClassReference

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

the class BoxUtil method castPrimitive2Object.

private static ExprNode castPrimitive2Object(ExprNode expr, PrimitiveType fromType) {
    ObjectType classType = Types.getClassType(fromType);
    if (classType == null) {
        throw new UnknownError("unknown primitive type:" + fromType);
    }
    InvocationExpr inv;
    try {
        inv = StaticInvokeExpr.create(new ClassReference(classType.getClassNode()), "valueOf", new ExprNode[] { expr });
    } catch (MethodNotFoundException | AmbiguousMethodException ex) {
        throw new RuntimeException(ex);
    }
    return inv;
}
Also used : ExprNode(kalang.ast.ExprNode) ObjectType(kalang.core.ObjectType) ClassReference(kalang.ast.ClassReference) MethodNotFoundException(kalang.MethodNotFoundException) InvocationExpr(kalang.ast.InvocationExpr) AmbiguousMethodException(kalang.AmbiguousMethodException)

Aggregations

ClassReference (kalang.ast.ClassReference)11 ExprNode (kalang.ast.ExprNode)9 ThisExpr (kalang.ast.ThisExpr)6 AssignExpr (kalang.ast.AssignExpr)5 StaticFieldExpr (kalang.ast.StaticFieldExpr)5 ExprStmt (kalang.ast.ExprStmt)4 ObjectFieldExpr (kalang.ast.ObjectFieldExpr)4 BlockStmt (kalang.ast.BlockStmt)3 VarObject (kalang.ast.VarObject)3 ObjectType (kalang.core.ObjectType)3 Nullable (javax.annotation.Nullable)2 AmbiguousMethodException (kalang.AmbiguousMethodException)2 MethodNotFoundException (kalang.MethodNotFoundException)2 ConstExpr (kalang.ast.ConstExpr)2 FieldExpr (kalang.ast.FieldExpr)2 FieldNode (kalang.ast.FieldNode)2 InvocationExpr (kalang.ast.InvocationExpr)2 LocalVarNode (kalang.ast.LocalVarNode)2 MethodNode (kalang.ast.MethodNode)2 ParameterExpr (kalang.ast.ParameterExpr)2