use of kalang.core.Type in project kalang by kasonyang.
the class AstBuilder method createBinaryExpr.
private ExprNode createBinaryExpr(String op, ExpressionContext exprCtx1, ExpressionContext exprCtx2, Token opStart, Token opEnd, ParserRuleContext ctx) {
ExprNode expr1 = visitExpression(exprCtx1);
ExprNode expr2 = visitExpression(exprCtx2);
Type type1 = expr1.getType();
Type type2 = expr2.getType();
boolean isPrimitive1 = (type1 instanceof PrimitiveType);
boolean isPrimitive2 = (type2 instanceof PrimitiveType);
ExprNode expr;
if (isPrimitive1 && isPrimitive2) {
expr = createBinaryExpr(expr1, expr2, op);
} else if (Types.isNumber(type1) && Types.isNumber(type2)) {
PrimitiveType t = SemanticAnalyzer.getMathType(type1, type2, op);
expr1 = BoxUtil.assign(expr1, type1, t);
expr2 = BoxUtil.assign(expr2, type2, t);
if (expr1 == null)
throw Exceptions.unexceptedValue(expr1);
if (expr2 == null)
throw Exceptions.unexceptedValue(expr2);
expr = createBinaryExpr(expr1, expr2, op);
} else if (op.equals("==") || op.equals("!=")) {
expr = createBinaryExpr(expr1, expr2, op);
} else if (op.equals("+")) {
expr = this.concatExpressionsToStringExpr(new ExprNode[] { expr1, expr2 }, new Token[] { exprCtx1.getStart(), exprCtx2.getStart() });
} else {
handleSyntaxError("unsupported operation", ParserRuleContext.EMPTY, opStart, opEnd);
return null;
}
if (expr != null)
mapAst(expr, ctx);
return expr;
}
use of kalang.core.Type 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.Type in project kalang by kasonyang.
the class AstBuilder method visitCastExpr.
@Override
public AstNode visitCastExpr(CastExprContext ctx) {
ExprNode castExpr;
ExprNode expr = visitExpression(ctx.expression());
Type toType = parseType(ctx.type());
Type fromType = expr.getType();
if (fromType instanceof PrimitiveType) {
if (toType instanceof PrimitiveType) {
castExpr = new PrimitiveCastExpr((PrimitiveType) fromType, (PrimitiveType) toType, expr);
} else {
this.handleSyntaxError("unable to cast primitive type to class type", ctx);
return null;
}
} else {
if (toType instanceof PrimitiveType) {
this.handleSyntaxError("unable to cast class type to primitive type", ctx);
return null;
} else {
castExpr = new CastExpr(toType, expr);
}
}
mapAst(castExpr, ctx);
return castExpr;
}
use of kalang.core.Type 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.Type in project kalang by kasonyang.
the class ObjectFieldExpr method create.
@Nonnull
public static FieldExpr create(@Nonnull ExprNode target, String fieldName, @Nullable ClassNode caller) throws FieldNotFoundException {
Type type = target.getType();
if (!(type instanceof ObjectType)) {
throw new UnsupportedOperationException("unsupported type:" + type);
}
ObjectType classType = (ObjectType) type;
FieldDescriptor field = getField(classType, fieldName, caller);
if (AstUtil.isStatic(field.getModifier())) {
throw new FieldNotFoundException(fieldName + " is static");
}
return new ObjectFieldExpr(target, field);
}
Aggregations