Search in sources :

Example 6 with MethodNode

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

the class SemanticAnalyzer method validateAnnotation.

protected boolean validateAnnotation(AnnotationNode annotation) {
    MethodNode[] mds = annotation.getAnnotationType().getDeclaredMethodNodes();
    Set<String> attrKeys = annotation.values.keySet();
    List<String> missingValues = new LinkedList<>();
    for (MethodNode m : mds) {
        String name = m.getName();
        if (!attrKeys.contains(name)) {
            missingValues.add(name);
        }
    }
    if (missingValues.size() > 0) {
        // TODO add offset on annotationNode
        diagnosisReporter.report(Diagnosis.Kind.ERROR, "Missing attribute for annotation:" + missingValues.toString(), OffsetRange.NONE);
        return false;
    }
    return true;
}
Also used : MethodNode(kalang.ast.MethodNode) LinkedList(java.util.LinkedList)

Example 7 with MethodNode

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

the class ClassNodeMetaBuilder method visitMethodDecl.

@Override
public Object visitMethodDecl(KalangParser.MethodDeclContext ctx) {
    String name;
    Type type;
    boolean isOverriding = ctx.OVERRIDE() != null;
    if (ctx.prefix != null && ctx.prefix.getText().equals("constructor")) {
        type = Types.VOID_TYPE;
        name = "<init>";
    } else {
        if (ctx.type() == null) {
            type = Types.VOID_TYPE;
        } else {
            type = astBuilder.parseType(ctx.returnType);
        }
        name = ctx.name.getText();
    }
    List<KalangParser.TypeContext> paramTypesCtx = ctx.paramTypes;
    int modifier = astBuilder.parseModifier(ctx.varModifier());
    Type[] paramTypes;
    String[] paramNames;
    if (paramTypesCtx != null) {
        int paramSize = paramTypesCtx.size();
        paramTypes = new Type[paramSize];
        paramNames = new String[paramSize];
        for (int i = 0; i < paramSize; i++) {
            KalangParser.TypeContext t = paramTypesCtx.get(i);
            paramTypes[i] = astBuilder.parseType(t);
            paramNames[i] = ctx.paramIds.get(i).getText();
        }
    } else {
        paramTypes = new Type[0];
        paramNames = new String[0];
    }
    // check method duplicated before generate java stub
    String mStr = MethodUtil.getDeclarationKey(name, paramTypes);
    boolean existed = Arrays.asList(thisClazz.getDeclaredMethodNodes()).stream().anyMatch((m) -> {
        return MethodUtil.getDeclarationKey(m).equals(mStr);
    });
    if (existed) {
        // TODO should remove the duplicated method
        diagnosisReporter.report(Diagnosis.Kind.ERROR, "declare method duplicately:" + mStr, ctx);
        return null;
    }
    KalangParser.BlockStmtContext blockStmt = ctx.blockStmt();
    if (blockStmt == null) {
        if (ModifierUtil.isInterface(thisClazz.modifier)) {
            modifier |= Modifier.ABSTRACT;
        } else if (!Modifier.isAbstract(modifier)) {
            diagnosisReporter.report(Diagnosis.Kind.ERROR, "method body required", ctx);
        } else if (!Modifier.isAbstract(thisClazz.modifier)) {
            diagnosisReporter.report(Diagnosis.Kind.ERROR, "declare abstract method in non-abstract class", ctx);
        }
    }
    method = thisClazz.createMethodNode(type, name, modifier);
    for (int i = 0; i < paramTypes.length; i++) {
        method.createParameter(paramTypes[i], paramNames[i]);
    }
    for (AnnotationNode a : astBuilder.getAnnotations(ctx.annotation())) method.addAnnotation(a);
    ObjectType superType = thisClazz.getSuperType();
    if (superType == null) {
        // the superType of interface may be null
        superType = Types.getRootType();
    }
    MethodDescriptor overriddenMd = ClassTypeUtil.getMethodDescriptor(superType, mStr, thisClazz, true, true);
    if (overriddenMd == null) {
        overriddenMd = ClassTypeUtil.getMethodDescriptor(thisClazz.getInterfaces(), mStr, thisClazz, true, true);
    }
    if (isOverriding && overriddenMd == null) {
        diagnosisReporter.report(Diagnosis.Kind.ERROR, "method does not override or implement a method from a supertype", ctx);
    }
    if (!isOverriding && overriddenMd != null) {
        diagnosisReporter.report(Diagnosis.Kind.ERROR, "method overrides or implements a method from a supertype", ctx);
    }
    this.methodContexts.put(method, ctx);
    KalangParser.BlockStmtContext bstm = ctx.blockStmt();
    if (bstm != null) {
        List<KalangParser.StatContext> stats = bstm.stat();
        if (stats != null)
            this.methodStatsContexts.put(method, stats.toArray(new KalangParser.StatContext[stats.size()]));
    }
    if (ctx.exceptionTypes != null) {
        for (Token et : ctx.exceptionTypes) {
            ObjectType exType = astBuilder.requireClassType(et);
            if (exType != null) {
                method.addExceptionType(exType);
            }
        }
    }
    astBuilder.mapAst(method, ctx);
    MethodNode m = method;
    method = null;
    return m;
}
Also used : Token(org.antlr.v4.runtime.Token) MethodDescriptor(kalang.core.MethodDescriptor) ObjectType(kalang.core.ObjectType) Type(kalang.core.Type) ObjectType(kalang.core.ObjectType) GenericType(kalang.core.GenericType) KalangParser(kalang.antlr.KalangParser) MethodNode(kalang.ast.MethodNode) AnnotationNode(kalang.ast.AnnotationNode)

Example 8 with MethodNode

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

the class ClassNodeMetaBuilder method visitScriptDef.

@Override
public Object visitScriptDef(KalangParser.ScriptDefContext ctx) {
    // FIXME fix filename
    // thisClazz.fileName = this.compilationUnit.getSource().getFileName();
    thisClazz.setSuperType(this.getScriptType());
    List<MethodDeclContext> mds = ctx.methodDecl();
    if (mds != null) {
        for (MethodDeclContext m : mds) {
            visit(m);
        }
    }
    MethodNode mm = thisClazz.createMethodNode(Types.VOID_TYPE, "execute", Modifier.PUBLIC);
    mm.addExceptionType(Types.getExceptionClassType());
    method = mm;
    List<KalangParser.StatContext> stats = ctx.stat();
    if (stats != null) {
        this.methodStatsContexts.put(mm, stats.toArray(new KalangParser.StatContext[stats.size()]));
    }
    AstUtil.createEmptyConstructor(thisClazz);
    AstUtil.createScriptMainMethodIfNotExists(thisClazz);
    return null;
}
Also used : MethodNode(kalang.ast.MethodNode) MethodDeclContext(kalang.antlr.KalangParser.MethodDeclContext)

Example 9 with MethodNode

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

the class AstUtil method createGetter.

public static void createGetter(ClassNode clazz, FieldDescriptor field, int accessModifier) {
    String fn = field.getName();
    String getterName = "get" + NameUtil.firstCharToUpperCase(fn);
    boolean isStatic = isStatic(field.getModifier());
    if (isStatic) {
        accessModifier |= Modifier.STATIC;
    }
    MethodNode getter = clazz.createMethodNode(field.getType(), getterName, accessModifier);
    // getter.offset = field.offset;
    BlockStmt body = getter.getBody();
    FieldExpr fe;
    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 ReturnStmt(fe));
}
Also used : StaticFieldExpr(kalang.ast.StaticFieldExpr) ObjectFieldExpr(kalang.ast.ObjectFieldExpr) MethodNode(kalang.ast.MethodNode) BlockStmt(kalang.ast.BlockStmt) ClassReference(kalang.ast.ClassReference) StaticFieldExpr(kalang.ast.StaticFieldExpr) FieldExpr(kalang.ast.FieldExpr) ObjectFieldExpr(kalang.ast.ObjectFieldExpr) ReturnStmt(kalang.ast.ReturnStmt) ThisExpr(kalang.ast.ThisExpr)

Example 10 with MethodNode

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

the class AstUtil method createScriptMainMethodIfNotExists.

public static void createScriptMainMethodIfNotExists(ClassNode clazz) {
    ClassType clazzType = Types.getClassType(clazz);
    MethodDescriptor[] methods = clazzType.getMethodDescriptors(null, false, false);
    Type[] argTypes = new Type[] { Types.getArrayType(Types.getStringClassType()) };
    MethodDescriptor mainMethod = MethodUtil.getMethodDescriptor(methods, "main", argTypes);
    if (mainMethod == null) {
        MethodNode m = clazz.createMethodNode(Types.VOID_TYPE, "main", Modifier.PUBLIC + Modifier.STATIC);
        ParameterNode p = m.createParameter(argTypes[0], "arg");
        BlockStmt body = m.getBody();
        try {
            NewObjectExpr newScriptExpr = new NewObjectExpr(clazzType);
            ObjectInvokeExpr invokeExpr = ObjectInvokeExpr.create(newScriptExpr, "run", new ExprNode[] { new ParameterExpr(p) });
            body.statements.add(new ExprStmt(invokeExpr));
        } catch (MethodNotFoundException | AmbiguousMethodException ex) {
            throw Exceptions.unexceptedException(ex);
        }
    }
}
Also used : ParameterExpr(kalang.ast.ParameterExpr) BlockStmt(kalang.ast.BlockStmt) NewObjectExpr(kalang.ast.NewObjectExpr) ClassType(kalang.core.ClassType) MethodDescriptor(kalang.core.MethodDescriptor) 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) MethodNotFoundException(kalang.MethodNotFoundException) AmbiguousMethodException(kalang.AmbiguousMethodException)

Aggregations

MethodNode (kalang.ast.MethodNode)10 BlockStmt (kalang.ast.BlockStmt)6 GenericType (kalang.core.GenericType)5 ObjectType (kalang.core.ObjectType)5 ExprStmt (kalang.ast.ExprStmt)4 ParameterExpr (kalang.ast.ParameterExpr)4 ParameterNode (kalang.ast.ParameterNode)4 Type (kalang.core.Type)4 ExprNode (kalang.ast.ExprNode)3 ThisExpr (kalang.ast.ThisExpr)3 ClassType (kalang.core.ClassType)3 LinkedList (java.util.LinkedList)2 AmbiguousMethodException (kalang.AmbiguousMethodException)2 MethodNotFoundException (kalang.MethodNotFoundException)2 KalangParser (kalang.antlr.KalangParser)2 AssignExpr (kalang.ast.AssignExpr)2 ClassNode (kalang.ast.ClassNode)2 ClassReference (kalang.ast.ClassReference)2 FieldExpr (kalang.ast.FieldExpr)2 ObjectFieldExpr (kalang.ast.ObjectFieldExpr)2