Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LambdaMethodReference creates ambiguous #1431

Closed
schlosna opened this issue Jun 25, 2020 · 0 comments
Closed

LambdaMethodReference creates ambiguous #1431

schlosna opened this issue Jun 25, 2020 · 0 comments

Comments

@schlosna
Copy link
Contributor

What happened?

After upgrading gradle-baseline, the automated LambdaMethodReference refactoring triggered a compilation error on a project due to ambiguous method reference for a KeyedStream#flatMap which has two overloads -- one taking a Function<? super V, ? extends Stream<? extends R>> mapper and the other taking a BiFunction<? super K, ? super V, ? extends Stream<? extends R>> entryMapper

Before refactoring:

KeyedStream.stream(elements)
    .flatMap(o -> getValues(o))

After refactoring, fails compilation:

KeyedStream.stream(elements)
    .flatMap(this::getValues)

// where there are two overloaded
private Stream<Value> getValues(Key key);
private Stream<Value> getValues(Key key, Object o2);
ERROR: reference to flatMap is ambiguous
                .flatMap(this::getValues)
                ^
  both method <R#1>flatMap(Function<? super V,? extends Stream<? extends R#1>>) in KeyedStream and method <R#2>flatMap(BiFunction<? super K,? super V,? extends Stream<? extends R#2>>) in KeyedStream match
  where R#1,V,K,R#2 are type-variables:
    R#1 extends Object declared in method <R#1>flatMap(Function<? super V,? extends Stream<? extends R#1>>)
    V extends Object declared in interface KeyedStream
    K extends Object declared in interface KeyedStream
    R#2 extends Object declared in method <R#2>flatMap(BiFunction<? super K,? super V,? extends Stream<? extends R#2>>)

Example LambdaMethodReferenceTest test case reproducing case.

    @Test
    void testNegative_ambiguousThisOverload() {
        refactor()
                .addInputLines(
                        "Test.java",
                        "import " + BiFunction.class.getName() + ';',
                        "import " + Function.class.getName() + ';',
                        "import " + Stream.class.getName() + ';',
                        "class Test {",
                        "  private Stream<String> test() {",
                        "      return Stream.concat(",
                        "              flatMap(s -> bar(s)), flatMap((s1, s2) -> bar(s1, s2)));",
                        "  }",
                        "  private static Stream<String> flatMap(Function<String, Stream<String>> fn) {",
                        "      return fn.apply(\"a\");",
                        "  }",
                        "  private static Stream<String> flatMap(BiFunction<String, String, Stream<String>> fn) {",
                        "      return fn.apply(\"a\", \"b\");",
                        "  }",
                        "  private Stream<String> bar(String in) {",
                        "      return Stream.of(in);",
                        "  }",
                        "  private Stream<String> bar(String s1, String s2) {",
                        "      return Stream.of(s1, s2);",
                        "  }",
                        "}")
                .expectUnchanged()
                .doTest();
    }

What did you want to happen?

Skip the automated refactor as the lambda is simpler, or refactor to valid code that is not an ambiguous method reference such as the following with explicit cast (though stylistically in this case the lambda is shorter and clearer).

  .flatMap((Function<Key, Stream<? extends Value>>) this::getValues)
carterkozak added a commit that referenced this issue Jun 25, 2020
Note that this uses the expensive `SuggestedFixes.compilesWithFix`
check which can result in poor performance, particularly on large
projects.
Fortunately this case isn't very common (no occurrences in a
very large internal project).
carterkozak added a commit that referenced this issue Jun 25, 2020
Note that this uses the expensive `SuggestedFixes.compilesWithFix`
check which can result in poor performance, particularly on large
projects.
Fortunately this case isn't very common (no occurrences in a
very large internal project).
@bulldozer-bot bulldozer-bot bot closed this as completed in 5be0d9c Jul 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant