Skip to content

Commit eacb60a

Browse files
MercurieVVclaude
andcommitted
refactor(mcp): dedupe annotated_source's PC-fallback onto the shared helpers
Rebasing 5439c13 ("fall back to the presentation compiler in annotated_source") onto master landed it after the already-merged #315, which had generalized the same PC-fallback into annotationsOf/ pcFallbackFields for source_ranges and source_around_position. annotated_source ended up with its own copy of that (engine, pcFallback, anns) logic instead of reusing them. Switch it over so all three tools share one implementation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DYMBTKayWeQihL2YyQRUid
1 parent 910b0ac commit eacb60a

1 file changed

Lines changed: 7 additions & 32 deletions

File tree

  • mcp/src/main/scala/com/github/mercurievv/scalasemantic/mcp

mcp/src/main/scala/com/github/mercurievv/scalasemantic/mcp/McpTools.scala

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,20 +2013,9 @@ private[mcp] object McpToolsGroupC:
20132013
val docs = argStr(a, "docs")
20142014
val lines = if docs == "strip" then az.stripComments(rawLines) else rawLines
20152015
val detail = argDetail(a, "detail")
2016-
// The compiled SemanticDB index has nothing for this file when it never compiled
2017-
// (syntax error, not yet built, excluded from the classpath) — the PC still
2018-
// best-effort-typechecks a broken/uncompiled buffer, so fall back to it instead of
2019-
// refusing to show the file at all.
2020-
val primary = az.sourceAnnotations(uri, lines, detail)
2021-
val (engine, pcFallback, annsOpt) = primary match
2022-
case Some(anns) => (az, false, Some(anns))
2023-
case None =>
2024-
az.bufferOnly(file.toUri, rawText, uri.value) match
2025-
case Some(pc) => (pc, true, pc.sourceAnnotations(uri, lines, detail))
2026-
case None => (az, false, None)
2027-
annsOpt match
2028-
case None => notFoundUri(uri.value)
2029-
case Some(anns) =>
2016+
annotationsOf(az, root, uri, rawText, lines, detail) match
2017+
case None => notFoundUri(uri.value)
2018+
case Some((engine, pcFallback, anns)) =>
20302019
val symbolsOn = argBool(a, "symbols", false)
20312020
val symbols = if symbolsOn then engine.symbolLegend(uri) else Nil
20322021
val fmt = argFormat(a, "format")
@@ -2052,8 +2041,8 @@ private[mcp] object McpToolsGroupC:
20522041
// code that is no longer there. Silence would be worse than a stale note: the
20532042
// agent would reason from it. Reported only when the index actually carries a
20542043
// digest to compare against; a missing one means "cannot tell", not "current".
2055-
// Skipped entirely under a PC fallback: there is no compiled digest at all, by
2056-
// definition of having taken that path.
2044+
// Skipped under a PC fallback: pcFallbackFields covers that case, and there is
2045+
// no compiled digest at all to compare against.
20572046
val staleFields =
20582047
if pcFallback then Nil
20592048
else
@@ -2070,24 +2059,10 @@ private[mcp] object McpToolsGroupC:
20702059
)
20712060
case Some(false) => Seq("staleIndex" -> ujson.Bool(false))
20722061
case None => Nil
2073-
val pcFallbackFields =
2074-
if pcFallback then
2075-
Seq(
2076-
"pcFallback" -> ujson.Bool(true),
2077-
"pcFallbackHint" -> ujson.Str(
2078-
s"'${uri.value}' has no compiled SemanticDB entry (it may not compile, " +
2079-
"or hasn't been built yet), so these annotations come from the " +
2080-
"presentation compiler's best-effort typecheck of this file alone, not " +
2081-
"the project's compiled index — expect gaps where the PC also can't " +
2082-
"resolve a type."
2083-
)
2084-
)
2085-
else Nil
2062+
val pcFields = if pcFallback then pcFallbackFields(uri.value) else Nil
20862063
ujson.Obj.from(
20872064
res.obj.toSeq ++
2088-
(("sha256" -> ujson.Str(
2089-
sha256Hex(rawBytes)
2090-
)) +: (staleFields ++ pcFallbackFields))
2065+
(("sha256" -> ujson.Str(sha256Hex(rawBytes))) +: (staleFields ++ pcFields))
20912066
)
20922067
}
20932068
),

0 commit comments

Comments
 (0)