use of kalang.core.ObjectType in project kalang by kasonyang.
the class AstBuilder method visitMemberInvocationExpr.
@Override
public ExprNode visitMemberInvocationExpr(MemberInvocationExprContext ctx) {
String methodName;
ExprNode target;
ObjectType clazz;
if (ctx.key != null) {
methodName = ctx.key.getText();
} else {
methodName = ctx.Identifier().getText();
}
if (methodName.equals("this")) {
methodName = "<init>";
target = new ThisExpr(this.getThisType());
clazz = this.getThisType();
} else if (methodName.equals("super")) {
methodName = "<init>";
target = new SuperExpr(thisClazz);
clazz = thisClazz.getSuperType();
} else {
target = new ThisExpr(this.getThisType());
clazz = this.getThisType();
}
List<Object> argsList = visitAll(ctx.params);
if (argsList.contains(null))
return null;
ExprNode[] args = argsList.toArray(new ExprNode[argsList.size()]);
ExprNode ie;
if (methodName.equals("<init>")) {
if (clazz == null)
throw Exceptions.unexceptedValue(clazz);
try {
InvocationExpr.MethodSelection apply = InvocationExpr.applyMethod(clazz, methodName, args, clazz.getConstructorDescriptors(thisClazz));
ie = new ObjectInvokeExpr(target, apply.selectedMethod, apply.appliedArguments);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
this.methodNotFound(ctx.start, clazz.getName(), methodName, args);
return null;
}
} else {
ie = getImplicitInvokeExpr(methodName, args, ctx);
}
return ie;
}
use of kalang.core.ObjectType in project kalang by kasonyang.
the class AstBuilder method visitNewExpr.
@Override
public AstNode visitNewExpr(NewExprContext ctx) {
ObjectType clsType = parseClassType(ctx.classType());
if (clsType == null)
return null;
ExprNode[] params = visitAll(ctx.params).toArray(new ExprNode[0]);
List<ExprNode> paramList = new LinkedList(Arrays.asList(params));
NewObjectExpr newExpr;
try {
if (this.isNonStaticInnerClass(clsType.getClassNode())) {
paramList.add(0, new ThisExpr(this.getThisType()));
}
params = paramList.toArray(new ExprNode[paramList.size()]);
newExpr = new NewObjectExpr(clsType, params);
mapAst(newExpr, ctx);
return newExpr;
} catch (MethodNotFoundException ex) {
methodNotFound(ctx.classType().rawClass, clsType.getName(), "<init>", params);
return null;
} catch (AmbiguousMethodException ex) {
methodIsAmbiguous(ctx.classType().rawClass, ex);
return null;
}
}
use of kalang.core.ObjectType in project kalang by kasonyang.
the class AstBuilder method parseWildcardType.
private Type parseWildcardType(KalangParser.WildcardTypeContext ctx) {
ObjectType classType = parseClassType(ctx.classType());
if (classType == null)
return null;
Type[] bounds = new Type[] { classType };
String boundKind = ctx.boundKind.getText();
if (boundKind.equals("super")) {
return new WildcardType(new Type[] { Types.getRootType() }, bounds);
} else {
return new WildcardType(bounds, null);
}
}
use of kalang.core.ObjectType 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.ObjectType in project kalang by kasonyang.
the class JvmClassNode method getGenericTypeMap.
private Map<TypeVariable, GenericType> getGenericTypeMap() {
if (this.genericTypeMap == null) {
Map<TypeVariable, GenericType> gTypesMap = new HashMap();
TypeVariable[] typeParameters = clazz.getTypeParameters();
if (typeParameters.length > 0) {
for (TypeVariable pt : typeParameters) {
ObjectType[] bounds = castToClassTypes(transType(pt.getBounds(), gTypesMap));
ObjectType superType;
ObjectType[] interfaces;
if (bounds != null && bounds.length > 0) {
if (ModifierUtil.isInterface(bounds[0].getModifier())) {
superType = Types.getRootType();
interfaces = bounds;
} else {
superType = bounds[0];
interfaces = new ObjectType[bounds.length - 1];
System.arraycopy(bounds, 1, interfaces, 0, interfaces.length);
}
} else {
superType = Types.getRootType();
interfaces = bounds;
}
GenericType gt = new GenericType(pt.getName(), superType, interfaces, NullableKind.NONNULL);
gTypesMap.put(pt, gt);
declareGenericType(gt);
}
}
this.genericTypeMap = gTypesMap;
}
return this.genericTypeMap;
}
Aggregations