Semantic classification cache for opened documents is never populated (written to the unopened-documents cache)
メンテナーはふだん 3 日以内に返信
評価
- 難易度
- 1/5
- 見積もり時間
- 1時間未満
- 初心者へのやさしさ
- 90/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- fsharp
- 領域
- tooling
調査の方向性
vsintegration/src/FSharp.Editor/Classification/ClassificationService.fs の AddSemanticClassificationsAsync から始め、262 行目付近の開いているドキュメントのキャッシュ読み取りと、301 行目付近の書き込みを比較します。開いているドキュメントの分岐が openedDocumentsSemanticClassificationCache に値を設定し、後続のリクエストで完全なチェックを繰り返す代わりにキャッシュされた分類を使用できるようになれば完了です。
索引モデルが issue の本文から書いたものです。
説明
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 withclassificationData.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 fromFSharp.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
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
dotnet/fsharp のほかの issue
-
Needs-Triage
難易度 1/5 1時間未満 初心者へのやさしさ 95/100
メンテナーはふだん 3 日以内に返信
-
`FSharpValue.PreComputeTuplePropertyInfo` reports an out-of-range index for every struct tuple対応中かも @T-Gro が今日担当しました。 オープンBug Needs-Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
メンテナーはふだん 3 日以内に返信
-
Printed quotations show a struct tuple as `NewTuple`対応中かも @T-Gro が今日担当しました。 オープンBug Needs-Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 3 日以内に返信
-
Needs-Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
dotnet/fsharp#20265 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
-
Bug Needs-Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 3 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
simkimsia/netlify-axi#19 ·
メンテナーはふだん 1 日以内に返信
-
compiler easy good first issue help wanted
難易度 1/5 1時間未満 初心者へのやさしさ 95/100
andorthehood/8f4e#1144 ·
メンテナーはふだん 1 日以内に返信
-
enhancement good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
laaielichter/Reverseport#44 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100