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;
}
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;
}
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;
}
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);
}
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;
}
Aggregations