feat(decompiler): link override keyword to base member definition#3741
feat(decompiler): link override keyword to base member definition#3741leno23 wants to merge 1 commit into
Conversation
Make the override modifier a navigation hyperlink to the nearest overridden member, matching Visual Studio go-to-definition behavior. Also fix a duplicate "to" typo in ilspycmd --generate-diagrammer help. Fixes icsharpcode#2035
siegfriedpammer
left a comment
There was a problem hiding this comment.
Note
This review was generated by Claude (claude-fable-5 via Claude Code) and is posted on its behalf after reading it.
Thanks for the contribution! The feature idea is right and the placement (TextTokenWriter.WriteKeyword, next to the existing this/base constructor-initializer references) is exactly where this belongs. Unfortunately the execution has a build-breaking issue and some looseness we would have to fix anyway, so we are not going to take this PR — it has been superseded by #3769, which implements the same feature with the fixes below and regression tests. Review details for reference:
Blocking: the change does not compile
IMember? GetOverrideMemberFromNodeStack() uses a nullable reference annotation, but TextTokenWriter.cs has no #nullable enable and ICSharpCode.Decompiler.csproj does not enable nullable project-wide (this repo enables it per-file). That is CS8632, and the repo builds with TreatWarningsAsErrors=true, so the Decompiler build fails. The PR description notes the change was never built locally; CI never ran on the branch.
The match is looser than it needs to be
- No role check. The existing
this/basebranch keys on the role; this one only checkskeyword == "override". Modifiers arrive inWriteKeywordwithEntityDeclaration.ModifierRole(VisitCSharpTokenNodepassescSharpTokenNode.Rolethrough), so the guard should require that role as well. - Walking the whole
nodeStackis unnecessary. Modifier tokens are written without aStartNodepush (see the comment inVisitCSharpTokenNode), so when the modifier is being written,nodeStack.Peek()is theEntityDeclarationthat owns it. A peek — exactly like thethis/basebranch above — is sufficient, and avoids a stray "override" written deeper in an override member's subtree getting linked to the enclosing member's base.
Other notes
- No regression test; a test that decompiles a derived type and asserts the
overridetoken carries a reference to the base member is needed to keep this from silently regressing (added in #3769). - The typo fixes (
next to to,assmbly) are correct but unrelated to #2035; theassmblyones were already fixed on master in the meantime.
|
We do NOT do AI-by-proxy, closing because "my AI found a better solution than your AI", which is how I would have implemented the feature manually. Sorry. |
Summary
Fixes #2035
When decompiling C# with syntax highlighting enabled, the
overridemodifier is now emitted as a hyperlink to the nearest overridden member (viaInheritanceHelper.GetBaseMember), similar to Visual Studio go-to-definition onoverride.Implementation is in
TextTokenWriter.WriteKeyword, alongside the existingthis/baseconstructor-initializer references.Also fixes a duplicate word typo (
next to to→next to the) inilspycmd --generate-diagrammerhelp text.Test plan
overrideand confirm navigation to the base memberI do not have a local .NET SDK in this environment; changes were not built locally.