Previously individual top-level file declarations relied on their corresponding file-class to declare their `File` instance, but this can be scuppered by a Java extractor replacing that file-class and identifying a different file location.
This fixes two mistakes: return-type extraction not imposing a wildcard where a Java prototype explicitly uses one, and nested wildcard detection quietly failing due to not looking through a `JavaWildcardType` correctly.
I add a variant of the `kotlin_java_lowering_wildcards` test where Java prototypes are only seen from Kotlin, to be sure extraction is working as expected.
This avoids extracting the default value expression in more than one place, which causes inconsistencies for e.g. anonymous classes, which expect to have a single `new` expression associated.
In this circumstance the compiler seems to generate a specialised version of the implementing function with its argument type replaced by the interface-implementing child class' type parameter. However it stores a back-pointer to the real declared function, which we should use as the call target.
This arises when a generic class extends one of its parameters; for example, `class G<T> { val T.v; get() = 1 }`, where specialisation `G<List>` should generate a method specialisation `getV(List)`.
For example, Java code might use `HasOutVariance<? extends String>`, or `HasInVariance<? super Object>`, both of which are needless wildcards and which the Kotlin extractor would previously have refused to reintroduce due to their not specifying a larger type than their bound. However this led to inconsistency with Java extraction, which
extracts the type as it appears in source.
This seems to particularly happen with generated code, e.g. the output of the Kotlin protobuf compiler.
Due to a probable compiler bug (?) the redeclaration looks like a fake symbol, leading to Java dispatching against a declaration that Kotlin doesn't believe exists.
Previously we accidentally named these something like <init>$main, which is a name-mangling the Kotlin compiler applies to internal methods but not to constructors, which look to Java just like regular public constructors.
Dataflow requires accounting for the fact that the varargs parameter isn't necessarily last in the parameter list in a couple more places. Default handling just requires that if the only null parameter is the varargs argument, and it has no default value, then no $default method is required-- the caller is expected to simply pass nothing (at QL
/ source level) or an empty array (at JVM level).