sbool preciseNuObject_debug;
static A preciseNuObject(Class c, O... args) ctex {
Constructor[] methods = getDeclaredConstructors_cached(c);
if (methods.length == 0)
fail(c + " doesn't define any constructors");
ret preciseNuObject(methods, args);
}
static A preciseNuObject(Constructor[] methods, O... args) ctex {
Constructor best = null;
int bestScore = Int.MAX_VALUE;
bool widening;
if (preciseNuObject_debug)
printVars("preciseNuObject", c := first(methods).getDeclaringClass(), methods := l(methods));
for (m : methods) {
int score = methodApplicabilityScore_withPrimitiveWidening(m, args);
if (score == 0)
ret (A) m.newInstance(args);
if (preciseNuObject_debug)
print("Method score: " + m + " " + score);
if (abs(score) < bestScore) {
best = m;
bestScore = abs(score);
widening = score < 0;
}
}
if (best != null)
if (widening)
ret (A) invokeConstructorWithWidening(best, args);
else
ret (A) best.newInstance(args);
// try varargs - TODO: make this precise too
methodSearch: for (m : methods) {
continue unless m.isVarArgs();
O[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
ret (A) m.newInstance(newArgs);
}
var c = first(methods).getDeclaringClass();
fail("No matching constructor found: " + formatFunctionCall(c, map _getClass(args)));
}