TPreptimeValue inputTpv = inputs.get(i);
TInstance inputInstance = (inputTpv == null) ? null : inputTpv.type();
// allow this input if...
// ... input set takes ANY, and it isn't marked as an exact. If it's marked as an exact, we'll figure it
// out later
TInputSet inputSet = overload.inputSetAt(i);
if ((!requireExact) && inputSet.targetType() == null) {
continue;
}
// ... input can be strongly cast to input set
TClass inputTypeClass;
if (requireExact) {
inputTypeClass = (inputInstance == null) ? null : inputInstance.typeClass();
}
else if (inputInstance == null) {
// If input type is unknown (NULL literal or parameter), assume common type at this position among
// all overloads in this group.
inputTypeClass = scalarGroups.commonTypeAt(i);
if (inputTypeClass == null) { // We couldn't resolve it in this group
if (hasNext) // , but we might find a match in the subsequent ones
return false;
else
throw new OverloadException("couldn't resolve overload because of unknown input at position " + i);
}
}
else {
inputTypeClass = inputInstance.typeClass();
}
if (requireExact) {
if (inputSet.targetType() == null) {
// We're in an ANY-exact input set. The semantics are:
// - unknown types are always allowed
// - the first known type defines the type of the input set
// - subsequent known types must equal this known type
if (inputTypeClass == null) {
continue;
}
if (pickSameType == null)
pickSameType = new TClass[overload.inputSetIndexCount()];
int inputSetIndex = overload.inputSetIndexAtPos(i);
TClass definedType = pickSameType[inputSetIndex];
if (definedType == null) {
pickSameType[inputSetIndex] = inputTypeClass;
continue;
}
else if (definedType == inputTypeClass) {
continue;
}
}
else if (inputTypeClass == null && scalarGroups.hasSameTypeAt(i)) {
continue;
}
else if (inputTypeClass == inputSet.targetType()) {
continue;
}
}
else {
if (castsResolver.strongCastExists(inputTypeClass, inputSet.targetType()))
continue;
}
// This input precludes the use of the overload
return false;
}