Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Semantic classification cache for opened documents is never populated (written to the unopened-documents cache)

オープン 初心者向け
#20,445 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 3 日以内に返信

@xperiandri がすでに取り組んでいます。

2026年9月4日 から。

  • #20450 @xperiandri による — オープン

評価

難易度
1/5
見積もり時間
1時間未満
初心者へのやさしさ
90/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
fsharp
領域
tooling

調査の方向性

vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs の AddSemanticClassificationsAsync から始め、262 行目付近の開いているドキュメントのキャッシュ読み取りと、301 行目付近の書き込みを比較します。開いているドキュメントの分岐が openedDocumentsSemanticClassificationCache に値を設定し、後続のリクエストで完全なチェックを繰り返す代わりにキャッシュされた分類を使用できるようになれば完了です。

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

説明

Needs-Triage

Summary

In FSharpClassificationService.AddSemanticClassificationsAsync, the open-document branch reads from openedDocumentsSemanticClassificationCache but writes to unopenedDocumentsSemanticClassificationCache. As a result openedDocumentsSemanticClassificationCache is written nowhere, its lookup always misses, and every semantic classification request for an open document goes through a full GetFSharpParseAndCheckResultsAsync + GetSemanticClassification.

vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs:

Line Branch Operation Cache
146 — declaration unopenedDocumentsSemanticClassificationCache (TTL 5.0)
149 — declaration openedDocumentsSemanticClassificationCache (TTL 2.0)
227 not isOpenDocument read unopened…
258 not isOpenDocument write unopened… ✔
262 open document read opened…
301 open document write unopened… ✘

Suggested fix

                             if classificationData.Length > 0 then
                                 let classificationDataLookup = itemToSemanticClassificationLookup classificationData
-                                do! unopenedDocumentsSemanticClassificationCache.SetAsync(document, classificationDataLookup)
+                                do! openedDocumentsSemanticClassificationCache.SetAsync(document, classificationDataLookup)

Origin

Introduced in #15954 ("More VS cleanup", merged 2023-10-10), which split a single semantic classification cache into two. In that diff all four lines are additions: the read in the open-document branch was pointed at the new opened… cache, while the write was kept as a copy of the sibling branch and still names unopened….

git blame currently attributes line 301 to #18653 ("Move LSP development to the main branch"), but that is a red herring — that commit only wrapped the method in the shouldProduceClassification gate and re-indented the block. The version of the file at its parent commit already has the same wrong cache name.

Impact

Functionally the classification is still correct — it is a pure cache miss, so the effect is repeated full re-checking rather than wrong colors. It becomes visible when the recomputation stops fitting between requests: each new classification request cancels the previous one, and the semantic pass ends with

|> CancellableTask.ifCanceledReturn ()

which completes successfully with an empty result, so the editor drops the classification it had. Observed as semantic colors appearing for a moment and then disappearing.

How it was observed

Debugging FSharp.Editor in an experimental hive against a large F# solution (VS 18.10, ~40 F# projects):

  • breakpoint at line 299 (if classificationData.Length > 0 then) hits with classificationData.Length = 57 — the checker does produce data, and colors do appear;
  • the Debug output window for the session contained ~1600 OperationCanceledException / TaskCanceledException, a large share of them from FSharp.Editor.dll, and no other exceptions besides FCS-internal control-flow ones (UndefinedName, CannotRefute, IndeterminateType);
  • with the cache never hit, every request re-enters the full check path.

Secondary observation (not part of the fix above)

ifCanceledReturn () at line 305 makes a cancelled semantic pass indistinguishable from "there are no classifications here". Preserving previously reported classifications on cancellation would be a separate, more invasive change, and is filed here only for reference.

主要言語
F#
スター
4.3k
フォーク
881
平均マージ
4日 8時間
マージ済み PR(30日)
117

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

はじめの一歩

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

dotnet/fsharp のほかの issue

dotnet/fsharp の issue をすべて見る

似ている issue

DevTools の issue をもっと見る

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

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