redhat-developer / redhat-developer/vscode-java

Java type inference fails with this program

オープン
#3,688 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

compile upstream
主要言語
TypeScript
スター
2.3k
フォーク
546
平均マージ
20時間 1分
マージ済み PR(30日)
11

説明

Environment
  • Operating System: macOS Sonoma
  • JDK version: 21
  • Visual Studio Code version: 1.90.2
  • Java extension version: 1.31.0
Steps To Reproduce

Create a file Main.java, paste the following content into it and then open it with VS Code and the Java extension:

import java.util.*;
import java.util.stream.Collectors;

public class Main {

    record Foo(String id, List<Bar> bars) {}

    record Bar(String id) {}

    public static void main(String[] args) {
        var barsByFooIdAndBarId = Collections.<Foo>emptyList()
            .stream()
            .collect(
                Collectors.toMap(
                    Foo::id,
                    foo ->
                        Collections.<String, Bar>emptyMap()
                            .entrySet()
                            .stream()
                            .collect(
                                Collectors.toMap(
                                    Map.Entry::getKey,
                                    entry ->
                                        foo
                                            .bars()
                                            .get(0)
                                )
                            )
                )
            );

        Bar bar = barsByFooIdAndBarId
            .computeIfAbsent("fooId", id -> Collections.emptyMap())
            .get("barId");

        System.out.println(bar);
    }
}
Current Result

The program doesn't compile. barsByFooIdAndBarId's type is inferred as Map<String, Map<String, Object>> instead of Map<String, Map<String, Bar>>. As a result, the assignment to Bar bar is invalid because Object is not assignable to Bar. However, if you replace var with Map<String, Map<String, Bar>> directly, then the program will be just fine. You can even run it and it will print null.

I know that this doesn't happen with javac nor IntelliJ because I noticed this at work and my colleagues using IntelliJ don't have the issue and manual compilation with Maven is also fine.

I suspect that the issue comes from the Eclipse Java language server which the Java extension is based on. But I cannot confirm this for now as I'm still trying to build and run the language server locally. And this is harder than I thought.

Expected Result

The program compiles and runs with VS Code and the Java extension. I understand that this may not be easy to solve. I would already appreciate some insights on the issue. If you think that I should open an issue on Eclipse's side, please let me know!

Additional Informations

Last but not least, thank you for your amazing work! 💪 I'm so happy to be able to write Java in VS Code thanks to the extension. I was able to move away from IntelliJ which I genuinely dislike. So thank you so much for the dedication in making this possible! ❤️

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

VS Code 1.90.2 で、Java extension 1.31.0 と JDK 21 を使用して、提供された Main.java プログラムで推論の失敗を再現します。まず Eclipse Java language server を調査し、次に barsByFooIdAndBarId が Map<String, Map<String, Bar>> として推論され、プログラムが期待どおりにコンパイルおよび実行されることを確認します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
java
領域
devtools
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
32/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。