use of kalang.AmbiguousMethodException in project kalang by kasonyang.
the class AstBuilder method visitMapExpr.
@Override
public MultiStmtExpr visitMapExpr(KalangParser.MapExprContext ctx) {
Type keyType = ctx.keyType != null ? requireClassType(ctx.keyType) : Types.getRootType();
Type valueType = ctx.valueType != null ? requireClassType(ctx.valueType) : Types.getRootType();
if (keyType == null || valueType == null)
return null;
LocalVarNode vo = declareTempLocalVar(Types.getClassType(Types.getMapImplClassType().getClassNode(), new Type[] { keyType, valueType }));
VarDeclStmt vds = new VarDeclStmt(vo);
NewObjectExpr newExpr;
try {
newExpr = new NewObjectExpr(Types.getMapImplClassType());
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
List<Statement> stmts = new LinkedList<>();
stmts.add(vds);
stmts.add(new ExprStmt(new AssignExpr(new VarExpr(vo), newExpr)));
VarExpr ve = new VarExpr(vo);
List<TerminalNode> ids = ctx.Identifier();
for (int i = 0; i < ids.size(); i++) {
ExpressionContext e = ctx.expression(i);
ExprNode v = (ExprNode) visit(e);
ConstExpr k = new ConstExpr(ctx.Identifier(i).getText());
ExprNode[] args = new ExprNode[] { k, v };
InvocationExpr iv;
try {
iv = ObjectInvokeExpr.create(ve, "put", args);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
ExprStmt es = new ExprStmt(iv);
stmts.add(es);
}
MultiStmtExpr mse = new MultiStmtExpr(stmts, ve);
mapAst(mse, ctx);
return mse;
}
use of kalang.AmbiguousMethodException in project kalang by kasonyang.
the class AstBuilder method getObjectInvokeExpr.
@Nullable
private ExprNode getObjectInvokeExpr(ExprNode target, String methodName, ExprNode[] args, ParserRuleContext ctx) {
if ("<init>".equals(methodName)) {
throw Exceptions.unexceptedException("Don't get constructor by this method.");
}
Type targetType = target.getType();
if (!(targetType instanceof ObjectType)) {
handleSyntaxError("class type required.", ctx);
return null;
}
ObjectType targetClassType = (ObjectType) targetType;
if (targetClassType.getNullable() == NullableKind.NULLABLE) {
handleSyntaxError("expression may be null", ctx);
return null;
}
ExprNode expr;
try {
ObjectInvokeExpr invoke = ObjectInvokeExpr.create(target, methodName, args, thisClazz);
if (invoke.getMethod().getMethodNode().getType() instanceof GenericType) {
Type invokeType = invoke.getType();
if (invokeType instanceof ObjectType) {
expr = new CastExpr(invokeType, invoke);
} else {
expr = invoke;
}
} else {
expr = invoke;
}
} catch (MethodNotFoundException ex) {
methodNotFound(ctx.start, className, methodName, args);
expr = new UnknownInvocationExpr(target, methodName, args);
} catch (AmbiguousMethodException ex) {
methodIsAmbiguous(ctx.start, ex);
return null;
}
mapAst(expr, ctx);
return expr;
}
use of kalang.AmbiguousMethodException 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.AmbiguousMethodException in project kalang by kasonyang.
the class AstBuilder method visitMethods.
private void visitMethods(ClassNode clazz) {
thisClazz = clazz;
for (MethodNode m : thisClazz.getDeclaredMethodNodes()) {
BlockStmt mbody = m.getBody();
StatContext[] stats = classNodeMetaBuilder.getStatContexts(m);
if (stats != null) {
method = m;
returned = false;
visitBlockStmt(stats, mbody);
boolean needReturn = (m.getType() != null && !m.getType().equals(Types.VOID_TYPE));
if (m.getBody() != null && needReturn && !returned) {
this.diagnosisReporter.report(Diagnosis.Kind.ERROR, "Missing return statement in method:" + MethodUtil.toString(method), classNodeMetaBuilder.getMethodDeclContext(m));
}
new InitializationAnalyzer(compilationUnit, astLoader).check(clazz, m);
}
if (AstUtil.isConstructor(m)) {
@SuppressWarnings("null") List<Statement> bodyStmts = mbody.statements;
if (!AstUtil.hasConstructorCallStatement(bodyStmts)) {
try {
bodyStmts.add(0, AstUtil.createDefaultSuperConstructorCall(thisClazz));
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
diagnosisReporter.report(Diagnosis.Kind.ERROR, "default constructor not found", classNodeMetaBuilder.getMethodDeclContext(m));
}
}
// check super()
int stmtsSize = mbody.statements.size();
assert stmtsSize > 0;
Statement firstStmt = mbody.statements.get(0);
if (!AstUtil.isConstructorCallStatement(firstStmt)) {
// TODO handle error
throw new RuntimeException("missing constructor call");
}
mbody.statements.addAll(1, this.thisClazz.initStmts);
}
}
for (ClassNode c : clazz.classes) {
this.visitMethods(c);
}
}
use of kalang.AmbiguousMethodException in project kalang by kasonyang.
the class InvocationExpr method applyMethod.
/**
* select the method for invocation expression,and apply ast transform if needed
* @param clazz
* @param methodName
* @param args
* @param candidates
* @return the selected method,or null
* @throws MethodNotFoundException
* @throws AmbiguousMethodException
*/
public static MethodSelection applyMethod(ObjectType clazz, String methodName, @Nullable ExprNode[] args, ExecutableDescriptor[] candidates) throws MethodNotFoundException, AmbiguousMethodException {
if (args == null)
args = new ExprNode[0];
Type[] types = AstUtil.getExprTypes(args);
if (types == null)
types = new Type[0];
List<ExecutableDescriptor> selectedList = methodSelector.select(candidates, methodName, types);
if (selectedList.isEmpty()) {
throw new MethodNotFoundException(clazz, methodName);
} else if (selectedList.size() > 1) {
throw new AmbiguousMethodException(selectedList);
}
ExecutableDescriptor md = selectedList.get(0);
ExprNode[] matchedParam = AstUtil.matchTypes(args, types, md.getParameterTypes());
Objects.requireNonNull(matchedParam);
return new MethodSelection(md, matchedParam);
}
Aggregations