Search in sources :

Example 1 with ObjectInvokeExpr

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

the class Ast2Class method visitInvocationExpr.

@Override
public Object visitInvocationExpr(InvocationExpr node) {
    int opc;
    ExecutableDescriptor method = node.getMethod();
    // = internalName(node.getMethod().classNode);
    String ownerClass;
    if (node instanceof StaticInvokeExpr) {
        opc = INVOKESTATIC;
        ownerClass = internalName(((StaticInvokeExpr) node).getInvokeClass().getReferencedClassNode());
    } else if (node instanceof ObjectInvokeExpr) {
        ObjectInvokeExpr oie = (ObjectInvokeExpr) node;
        ObjectType targetType = (ObjectType) oie.getInvokeTarget().getType();
        ownerClass = internalName(targetType);
        ExprNode target = oie.getInvokeTarget();
        visit(target);
        if (Modifier.isPrivate(method.getModifier()) || (target instanceof SuperExpr) || method.getName().equals("<init>")) {
            opc = INVOKESPECIAL;
        } else {
            opc = ModifierUtil.isInterface(targetType.getClassNode().modifier) ? INVOKEINTERFACE : INVOKEVIRTUAL;
        }
    } else {
        throw Exceptions.unsupportedTypeException(node);
    }
    visitAll(node.getArguments());
    md.visitMethodInsn(opc, ownerClass, method.getName(), getMethodDescriptor(method.getMethodNode()));
    return null;
}
Also used : StaticInvokeExpr(kalang.ast.StaticInvokeExpr) ExprNode(kalang.ast.ExprNode) ObjectType(kalang.core.ObjectType) SuperExpr(kalang.ast.SuperExpr) ObjectInvokeExpr(kalang.ast.ObjectInvokeExpr) ExecutableDescriptor(kalang.core.ExecutableDescriptor)

Example 2 with ObjectInvokeExpr

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

the class AstBuilder method getObjectInvokeExpr.

@Nullable
private ExprNode getObjectInvokeExpr(ExprNode target, String methodName, ExprNode[] args, ParserRuleContext ctx) {
    if ("<init>".equals(methodName)) {
        throw Exceptions.unexceptedException("Don't get constructor by this method.");
    }
    Type targetType = target.getType();
    if (!(targetType instanceof ObjectType)) {
        handleSyntaxError("class type required.", ctx);
        return null;
    }
    ObjectType targetClassType = (ObjectType) targetType;
    if (targetClassType.getNullable() == NullableKind.NULLABLE) {
        handleSyntaxError("expression may be null", ctx);
        return null;
    }
    ExprNode expr;
    try {
        ObjectInvokeExpr invoke = ObjectInvokeExpr.create(target, methodName, args, thisClazz);
        if (invoke.getMethod().getMethodNode().getType() instanceof GenericType) {
            Type invokeType = invoke.getType();
            if (invokeType instanceof ObjectType) {
                expr = new CastExpr(invokeType, invoke);
            } else {
                expr = invoke;
            }
        } else {
            expr = invoke;
        }
    } catch (MethodNotFoundException ex) {
        methodNotFound(ctx.start, className, methodName, args);
        expr = new UnknownInvocationExpr(target, methodName, args);
    } catch (AmbiguousMethodException ex) {
        methodIsAmbiguous(ctx.start, ex);
        return null;
    }
    mapAst(expr, ctx);
    return expr;
}
Also used : ExprNode(kalang.ast.ExprNode) 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) GenericType(kalang.core.GenericType) ObjectInvokeExpr(kalang.ast.ObjectInvokeExpr) PrimitiveCastExpr(kalang.ast.PrimitiveCastExpr) CastExpr(kalang.ast.CastExpr) MethodNotFoundException(kalang.MethodNotFoundException) UnknownInvocationExpr(kalang.ast.UnknownInvocationExpr) AmbiguousMethodException(kalang.AmbiguousMethodException) Nullable(javax.annotation.Nullable)

Example 3 with ObjectInvokeExpr

use of kalang.ast.ObjectInvokeExpr 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 4 with ObjectInvokeExpr

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

the class AstUtil method createEmptyConstructor.

public static boolean createEmptyConstructor(ClassNode clazzNode) {
    ObjectType supType = clazzNode.getSuperType();
    if (supType == null) {
        throw new RuntimeException("super type is null:" + clazzNode.name);
    }
    ConstructorDescriptor[] constructors = supType.getConstructorDescriptors(clazzNode);
    ConstructorDescriptor m = MethodUtil.getConstructorDescriptor(constructors, null);
    if (m != null) {
        MethodNode mm = clazzNode.createMethodNode(Types.VOID_TYPE, m.getName(), m.getModifier());
        for (Type e : m.getExceptionTypes()) mm.addExceptionType(e);
        ParameterDescriptor[] pds = m.getParameterDescriptors();
        for (ParameterDescriptor pd : pds) {
            ParameterNode p = mm.createParameter(pd.getType(), pd.getName());
            // TODO update mm.createParameter
            p.modifier = pd.getModifier();
        }
        BlockStmt body = mm.getBody();
        ParameterNode[] parameters = mm.getParameters();
        ExprNode[] params = new ExprNode[parameters.length];
        for (int i = 0; i < params.length; i++) {
            params[i] = new ParameterExpr(parameters[i]);
        }
        body.statements.add(new ExprStmt(new ObjectInvokeExpr(new SuperExpr(clazzNode), m, params)));
        return true;
    } else {
        return false;
    }
}
Also used : SuperExpr(kalang.ast.SuperExpr) ParameterExpr(kalang.ast.ParameterExpr) ParameterDescriptor(kalang.core.ParameterDescriptor) BlockStmt(kalang.ast.BlockStmt) ConstructorDescriptor(kalang.core.ConstructorDescriptor) ExprNode(kalang.ast.ExprNode) ObjectType(kalang.core.ObjectType) ArrayType(kalang.core.ArrayType) Type(kalang.core.Type) ObjectType(kalang.core.ObjectType) GenericType(kalang.core.GenericType) ClassType(kalang.core.ClassType) MethodNode(kalang.ast.MethodNode) ParameterNode(kalang.ast.ParameterNode) ExprStmt(kalang.ast.ExprStmt) ObjectInvokeExpr(kalang.ast.ObjectInvokeExpr)

Example 5 with ObjectInvokeExpr

use of kalang.ast.ObjectInvokeExpr 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

ObjectInvokeExpr (kalang.ast.ObjectInvokeExpr)7 ObjectType (kalang.core.ObjectType)7 ExprNode (kalang.ast.ExprNode)6 AmbiguousMethodException (kalang.AmbiguousMethodException)5 MethodNotFoundException (kalang.MethodNotFoundException)5 ArrayType (kalang.core.ArrayType)4 ClassType (kalang.core.ClassType)4 GenericType (kalang.core.GenericType)4 Type (kalang.core.Type)4 BlockStmt (kalang.ast.BlockStmt)3 ExprStmt (kalang.ast.ExprStmt)3 SuperExpr (kalang.ast.SuperExpr)3 UnknownInvocationExpr (kalang.ast.UnknownInvocationExpr)3 Nullable (javax.annotation.Nullable)2 CastExpr (kalang.ast.CastExpr)2 InvocationExpr (kalang.ast.InvocationExpr)2 MethodNode (kalang.ast.MethodNode)2 ParameterExpr (kalang.ast.ParameterExpr)2 ParameterNode (kalang.ast.ParameterNode)2 PrimitiveCastExpr (kalang.ast.PrimitiveCastExpr)2