use of kalang.ast.ClassReference in project kalang by kasonyang.
the class AstBuilder method getImplicitInvokeExpr.
@Nullable
private ExprNode getImplicitInvokeExpr(String methodName, ExprNode[] args, ParserRuleContext ctx) {
ExprNode expr = null;
try {
ObjectType clazzType = getThisType();
InvocationExpr.MethodSelection ms = InvocationExpr.applyMethod(clazzType, methodName, args, clazzType.getMethodDescriptors(thisClazz, true, true));
if (Modifier.isStatic(ms.selectedMethod.getModifier())) {
expr = new StaticInvokeExpr(new ClassReference(thisClazz), ms.selectedMethod, ms.appliedArguments);
} else {
expr = new ObjectInvokeExpr(new ThisExpr(getThisType()), ms.selectedMethod, ms.appliedArguments);
}
} catch (MethodNotFoundException ex) {
if (args.length == 1 && (methodName.equals("print") || methodName.equals("println"))) {
try {
StaticFieldExpr fieldExpr = StaticFieldExpr.create(new ClassReference(Types.requireClassType("java.lang.System").getClassNode()), "out", null);
expr = getObjectInvokeExpr(fieldExpr, methodName, args, ctx);
} catch (FieldNotFoundException fnfEx) {
throw Exceptions.unexceptedException(fnfEx);
}
}
if (expr == null) {
this.methodNotFound(ctx.getStart(), className, methodName, args);
expr = new UnknownInvocationExpr(null, methodName, args);
}
} catch (AmbiguousMethodException ex) {
methodIsAmbiguous(ctx.start, ex);
return null;
}
mapAst(expr, ctx);
return expr;
}
use of kalang.ast.ClassReference in project kalang by kasonyang.
the class AstBuilder method createFieldExpr.
protected ExprNode createFieldExpr(GetFieldExprContext to, @Nullable ExpressionContext fromCtx, OffsetRange offsetRange) {
// TODO support iterating syntax
String refKey = to.refKey.getText();
ExpressionContext exp = to.expression();
String fname = to.Identifier().getText();
AssignableExpr toExpr;
Object expr = visit(exp);
if (refKey.equals(".")) {
ExprNode fieldExpr;
if (expr instanceof ExprNode) {
ExprNode exprNode = (ExprNode) expr;
fieldExpr = getObjectFieldLikeExpr(exprNode, fname, to);
} else if (expr instanceof ClassReference) {
fieldExpr = getStaticFieldExpr((ClassReference) expr, fname, to);
} else {
throw new UnknownError("unknown node:" + expr);
}
if (fromCtx == null) {
return fieldExpr;
} else {
if (fieldExpr instanceof AssignableExpr) {
toExpr = (AssignableExpr) fieldExpr;
} else {
AstBuilder.this.handleSyntaxError("unsupported", to);
return null;
}
ExprNode fromExpr = visitExpression(fromCtx);
if (!this.semanticAnalyzer.validateAssign(toExpr, fromExpr, offsetRange)) {
return null;
}
return new AssignExpr(toExpr, fromExpr);
}
} else if (refKey.equals("->")) {
ExprNode[] params;
String methodName;
if (fromCtx == null) {
params = new ExprNode[0];
methodName = "get" + NameUtil.firstCharToUpperCase(fname);
} else {
params = new ExprNode[1];
methodName = "set" + NameUtil.firstCharToUpperCase(fname);
}
if (expr instanceof ExprNode) {
if (fromCtx != null)
params[0] = visitExpression(fromCtx);
return getObjectInvokeExpr((ExprNode) expr, methodName, params, to);
} else {
// don't support static property
handleSyntaxError("object expression required.", to);
return null;
}
} else {
throw Exceptions.unknownValue(refKey);
}
}
use of kalang.ast.ClassReference in project kalang by kasonyang.
the class ClassNodeMetaBuilder method visitFieldDecl.
@Override
public Void visitFieldDecl(KalangParser.FieldDeclContext ctx) {
int fieldModifier = astBuilder.parseModifier(ctx.varModifier());
for (KalangParser.VarDeclContext vd : ctx.varDecl()) {
ExprNode initExpr;
if (vd.expression() != null) {
initExpr = astBuilder.visitExpression(vd.expression());
} else {
initExpr = null;
}
AstBuilder.VarInfo varInfo = astBuilder.varDecl(vd, initExpr == null ? Types.getRootType() : initExpr.getType());
varInfo.modifier |= fieldModifier;
FieldNode fieldNode = thisClazz.createField(varInfo.type, varInfo.name, varInfo.modifier);
// TODO simplify it
if (initExpr != null) {
if (AstUtil.isStatic(fieldNode.modifier)) {
thisClazz.staticInitStmts.add(new ExprStmt(new AssignExpr(new StaticFieldExpr(new ClassReference(thisClazz), fieldNode), initExpr)));
} else {
thisClazz.initStmts.add(new ExprStmt(new AssignExpr(new ObjectFieldExpr(new ThisExpr(Types.getClassType(thisClazz)), fieldNode), initExpr)));
}
}
}
return null;
}
use of kalang.ast.ClassReference in project kalang by kasonyang.
the class AstUtil method createSetter.
public static void createSetter(ClassNode clazz, FieldDescriptor field, int accessModifier) {
String fn = field.getName();
String setterName = "set" + NameUtil.firstCharToUpperCase(fn);
boolean isStatic = isStatic(field.getModifier());
if (isStatic) {
accessModifier |= Modifier.STATIC;
}
MethodNode setter = clazz.createMethodNode(Types.VOID_TYPE, setterName, accessModifier);
// setter.offset = field.offset;
ParameterNode param = setter.createParameter(field.getType(), field.getName());
BlockStmt body = setter.getBody();
FieldExpr fe;
ExprNode paramVal = new ParameterExpr(param);
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 ExprStmt(new AssignExpr(fe, paramVal)));
}
use of kalang.ast.ClassReference in project kalang by kasonyang.
the class BoxUtil method castPrimitive2Object.
private static ExprNode castPrimitive2Object(ExprNode expr, PrimitiveType fromType) {
ObjectType classType = Types.getClassType(fromType);
if (classType == null) {
throw new UnknownError("unknown primitive type:" + fromType);
}
InvocationExpr inv;
try {
inv = StaticInvokeExpr.create(new ClassReference(classType.getClassNode()), "valueOf", new ExprNode[] { expr });
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw new RuntimeException(ex);
}
return inv;
}
Aggregations