Search in sources :

Example 1 with MethodDescriptor

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

the class AstUtil method getUnimplementedMethod.

@Nonnull
public static List<MethodDescriptor> getUnimplementedMethod(ClassNode theClass, ObjectType theInterface) {
    ClassType theType = Types.getClassType(theClass);
    MethodDescriptor[] implementedMethods = theType.getMethodDescriptors(theClass, true, false);
    List<MethodDescriptor> list = new LinkedList();
    for (MethodDescriptor m : theInterface.getMethodDescriptors(theClass, false, true)) {
        if (ModifierUtil.isDefault(m.getModifier()))
            continue;
        String name = m.getName();
        Type[] types = m.getParameterTypes();
        MethodDescriptor overridingMd = MethodUtil.getMethodDescriptor(implementedMethods, name, types);
        if (overridingMd == null || // TODO move check to where method declare
        !OverrideUtil.overridingCompatible(overridingMd.getModifier(), m.getModifier()) || !OverrideUtil.returnTypeCompatible(overridingMd.getReturnType(), m.getReturnType()) || !OverrideUtil.exceptionTypeCompatible(overridingMd.getExceptionTypes(), m.getExceptionTypes())) {
            list.add(m);
        }
    }
    return list;
}
Also used : ArrayType(kalang.core.ArrayType) Type(kalang.core.Type) ObjectType(kalang.core.ObjectType) GenericType(kalang.core.GenericType) ClassType(kalang.core.ClassType) ClassType(kalang.core.ClassType) MethodDescriptor(kalang.core.MethodDescriptor) LinkedList(java.util.LinkedList) Nonnull(javax.annotation.Nonnull)

Example 2 with MethodDescriptor

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

the class AstUtil method hasSetter.

public static boolean hasSetter(ClassNode clazz, FieldNode field) {
    ClassType type = Types.getClassType(clazz);
    MethodDescriptor md = MethodUtil.getMethodDescriptor(type.getMethodDescriptors(clazz, true, true), "set" + NameUtil.firstCharToUpperCase(field.getName()), new Type[] { field.getType() });
    return md != null;
}
Also used : ClassType(kalang.core.ClassType) MethodDescriptor(kalang.core.MethodDescriptor)

Example 3 with MethodDescriptor

use of kalang.core.MethodDescriptor 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 4 with MethodDescriptor

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

the class StaticInvokeExpr method create.

public static StaticInvokeExpr create(ClassReference clazz, String methodName, ExprNode[] args, @Nullable ClassNode caller) throws MethodNotFoundException, AmbiguousMethodException {
    ObjectType clazzType = Types.getClassType(clazz.getReferencedClassNode());
    // TODO static only
    // TODO what about generic static method?
    MethodDescriptor[] candidates = clazzType.getMethodDescriptors(caller, true, true);
    MethodSelection ms = applyMethod(Types.getClassType(clazz.getReferencedClassNode()), methodName, args, candidates);
    ExecutableDescriptor md = ms.selectedMethod;
    if (!AstUtil.isStatic(md.getModifier())) {
        throw new MethodNotFoundException(methodName + " is not static");
    }
    return new StaticInvokeExpr(clazz, md, ms.appliedArguments);
}
Also used : ObjectType(kalang.core.ObjectType) MethodDescriptor(kalang.core.MethodDescriptor) MethodNotFoundException(kalang.MethodNotFoundException) ExecutableDescriptor(kalang.core.ExecutableDescriptor)

Example 5 with MethodDescriptor

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

the class AstUtil method hasGetter.

public static boolean hasGetter(ClassNode clazz, FieldNode field) {
    ClassType type = Types.getClassType(clazz);
    MethodDescriptor md = MethodUtil.getMethodDescriptor(type.getMethodDescriptors(clazz, true, true), "get" + NameUtil.firstCharToUpperCase(field.getName()), null);
    return md != null;
}
Also used : ClassType(kalang.core.ClassType) MethodDescriptor(kalang.core.MethodDescriptor)

Aggregations

MethodDescriptor (kalang.core.MethodDescriptor)6 ClassType (kalang.core.ClassType)4 ObjectType (kalang.core.ObjectType)4 GenericType (kalang.core.GenericType)3 Type (kalang.core.Type)3 MethodNotFoundException (kalang.MethodNotFoundException)2 MethodNode (kalang.ast.MethodNode)2 ArrayType (kalang.core.ArrayType)2 LinkedList (java.util.LinkedList)1 Nonnull (javax.annotation.Nonnull)1 AmbiguousMethodException (kalang.AmbiguousMethodException)1 KalangParser (kalang.antlr.KalangParser)1 AnnotationNode (kalang.ast.AnnotationNode)1 BlockStmt (kalang.ast.BlockStmt)1 ExprStmt (kalang.ast.ExprStmt)1 NewObjectExpr (kalang.ast.NewObjectExpr)1 ObjectInvokeExpr (kalang.ast.ObjectInvokeExpr)1 ParameterExpr (kalang.ast.ParameterExpr)1 ParameterNode (kalang.ast.ParameterNode)1 ExecutableDescriptor (kalang.core.ExecutableDescriptor)1