[java-psi] Multi-resolve of functional interface type improvements

- Support constructors
- Support diamond types
- Infer lambda parameter type even if functions differ
Also: PsiCall.multiResolve method; used where possible
Improves IDEA-364426 Missing variable type inference of lambda in a method call while typing a first parameter if all parameters haven't been provided yet (until overload is chosen, even though the first parameter can be inferred already)
Fixes IDEA-318792 Stray "Cannot resolve constructor" error

GitOrigin-RevId: 3227c2da22ef417457ad07a524403b405aeebbcd
This commit is contained in:
Tagir Valeev
2025-03-19 12:03:57 +01:00
committed by intellij-monorepo-bot
parent b6806f1e7b
commit ef4334ea4b
42 changed files with 297 additions and 167 deletions

View File

@@ -1,6 +1,9 @@
public interface IDEA99969 {
default IntStream distinct(Stream s) {
return s.map<error descr="Ambiguous method call: both 'Stream.map(Function)' and 'Stream.map(IntFunction)' match">(i -> <error descr="Inconvertible types; cannot cast '<lambda parameter>' to 'int'">(int) i</error>)</error>;
return s.map<error descr="Ambiguous method call: both 'Stream.map(Function)' and 'Stream.map(IntFunction)' match">(i -> (int) i)</error>;
}
default IntStream distinct2(Stream<String> s) {
return s.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super String, ?>)' and 'Stream.map(IntFunction<? super String>)' match">(i -> <error descr="Inconvertible types; cannot cast 'java.lang.String' to 'int'">(int) i</error>)</error>;
}
}
interface Stream<T> {

View File

@@ -8,8 +8,8 @@ class Test {
IntStream mi = sp.map(Inner::foo);
Stream<Integer> mI = sp.map(Inner::fooBoxed);
IntStream li = sp.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super Inner, ?>)' and 'Stream.map(IntFunction<? super Inner>)' match">(inner->inner.<error descr="Cannot resolve method 'foo()'">foo</error>())</error>;
Stream<Integer> lI = sp.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super Inner, ?>)' and 'Stream.map(IntFunction<? super Inner>)' match">(inner -> inner.<error descr="Cannot resolve method 'fooBoxed()'">fooBoxed</error>())</error>;
IntStream li = sp.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super Inner, ?>)' and 'Stream.map(IntFunction<? super Inner>)' match">(inner->inner.foo())</error>;
Stream<Integer> lI = sp.map<error descr="Ambiguous method call: both 'Stream.map(Function<? super Inner, ?>)' and 'Stream.map(IntFunction<? super Inner>)' match">(inner -> inner.fooBoxed())</error>;
}
interface Stream<T> {

View File

@@ -0,0 +1,45 @@
import java.io.InputStream;
import java.util.function.Function;
class ConstructorNotFound {
public static void main(String[] args) {
new SuggesterSpec2<><error descr="Cannot resolve constructor 'SuggesterSpec2(String, <method reference>)'">("test", SuggestionBuilder::new)</error>;
new SuggesterSpec2<><error descr="Cannot resolve constructor 'SuggesterSpec2(String, <lambda expression>)'">("test", is -> new SuggestionBuilder(is))</error>;
new SuggesterSpec<><error descr="Cannot resolve constructor 'SuggesterSpec(String, <lambda expression>)'">("test", is -> new SuggestionBuilder(is))</error>;
new SuggesterSpec<><error descr="Cannot resolve constructor 'SuggesterSpec(String, <method reference>)'">("test", SuggestionBuilder::new)</error>;
}
}
class SuggesterSpec<T> {
public SuggesterSpec(String name, Function<InputStream, T> builderReader, int count) {
}
public SuggesterSpec(String count, Function<InputStream, T> builderReader, String name) {
}
}
class SuggesterSpec2<T> {
public SuggesterSpec2(String name, Function<InputStream, T> builderReader, int count) {
}
public SuggesterSpec2(int count, Function<InputStream, T> builderReader, String name) {
}
}
class SuggestionBuilder {
public SuggestionBuilder() {
}
public SuggestionBuilder(InputStream is) {
}
}