Repository navigation
[VS] Rename (Ctrl+R, Ctrl+R) for X# symbols - #2154
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tive scope Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…of interface implementations Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…undo, safe rollback, one search at a time Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…les stay unsaved Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hout INHERIT Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The project reads a renamed file from disk, but an open file keeps the
rename unsaved, so the code model still had the old class name under
the new path ("'Dog' already exists" when renaming back). The editor
also kept the XFile of the old path, so a second rename did not offer
to rename the file. XFile.Rename moves that object to the new path, and
the editor text is parsed afterwards.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new checkbox in the rename dialog (members only, unchecked at the start of every rename) also changes the late-bound group that Find All References lists: o:Name sends and #Name symbols; for a symbol only the name behind the hash is replaced. Unresolved, ambiguous and inactive places are still only reported. The dialog now says that the places that are not changed are listed in the Find All References window after Apply. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
|
Nice, although I would have preferred a XAML dialog window. That is also supported by VS2019 |
Contributor
Author
|
I will provide an PR with this |
RobertvanderHulst
pushed a commit
that referenced
this pull request
Nov 8, 2026
…2156 (#2161) The squash merge of #2156 mixed the SelectTarget method from #2154 (Rename) with the old inline lookup, so FindReferencesCommand.cs did not compile. SelectTarget now resolves the symbol through TargetUnderCursor.Resolve and fills TargetSelection from it; messages are unchanged. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
RobertvanderHulst
pushed a commit
that referenced
this pull request
Nov 8, 2026
…roject tree (#2163) - The rename dialog is defined in XAML (RenameDialog.xaml) instead of being built in code; both LanguageService projects include it. It now uses the VS theme like the other X# windows. - XSharpProjectTreePropertiesProvider: while a file is renamed the tree can still ask for the old path; return early when the file does not exist instead of throwing (and catching) a FileNotFoundException in FindClassDeclaration. Follow-up to #2154 (review comments). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
RobertvanderHulst
pushed a commit
that referenced
this pull request
Nov 9, 2026
* [VS] Fix the build: SelectTarget after the Go To Implementation merge The squash merge of #2156 on top of #2154 mixed the old body of FindReferencesCommand.SelectTarget with the Go To Implementation version (await in a non-async method, duplicate locals, undefined doc/name), so the language service did not compile. SelectTarget now uses TargetUnderCursor.Resolve, as Find References did in #2156, and keeps the TargetSelection result that Rename (#2154) needs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: thread-safe lookup state and walker suspend XSharpLookup.nestedSearches is per thread now: lookups run in the background (inlay hints, Find References) next to QuickInfo on the UI thread and shared the recursion guard. ModelWalker.Suspend/Resume use Interlocked, they are called from several threads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: candidates HintCandidates finds calls with arguments (Name(...), Type{...}) and implied declarations (VAR, LOCAL IMPLIED, FOREACH VAR, FOR VAR, USING VAR) on lexer tokens. Declarations (FUNCTION Foo(...)) and OUT VAR are skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: rules HintRules decides which hints show: parameter names only for arguments that say nothing (literals, NIL, NULL_*, signed numbers, Type{...}), only when exactly one overload fits the call, none beyond the last parameter or after the first PARAMS argument; extension methods called on an instance skip their first parameter. Type hints are hidden when the initializer names the type. Type names are shown without namespaces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: type rewrite The double-click on a type hint writes the type: VAR x := e and LOCAL IMPLIED x := e become LOCAL x := e AS T (X# puts the type after the initializer), FOREACH VAR x IN c becomes FOREACH x AS T IN c. No edit for FOR, USING, STATIC and statements with several variables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: computer and queue InlayHintComputer resolves the candidates of a document snapshot on a private copy of its tokens (the classifier refills the live document), inside one ModelWalker.Suspend/Resume, and logs the time per file. A type hint is silent when the initializer ends in an ambiguous call or the type is unknown. InlayHintQueue runs one computation at a time for the IDE; a newer request for the same document replaces a queued one and cancels a running one; RequestDebounced waits for a quiet second. The classifier raises ParseCompleted after each parse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: tagger, options, triggers InlayHintTagger (IViewTaggerProvider, IntraTextAdornmentTag) shows the hints of the last computed snapshot, translated to the current one; a hint whose text was edited disappears until the next result. Hover shows the parameter (with its XML doc and the member prototype) or the type; a double-click on a type hint writes the type (one undo step). Colours in Fonts and Colors (X# Inlay Hint). Options: Show parameter name hints, Show inferred type hints (both on). Open documents are recomputed after a quiet second when the code model walker is done (new ModelWalker.WalkCompleted) or another file of the project was saved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Overload filter: untyped parameters make an implicit CLIPPER method VO METHOD Open(cName, lShared) accepts any number of arguments, but the code model only marks CLIPPER when the keyword is written. Inlay hints were missing for calls with fewer or more arguments (Find References kept them only by the no-match fallback). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: draw an opaque stored background translucent Fonts and Colors stores colours without alpha: the hint background came back as opaque #808080, the same grey as the text, and the hints showed as empty grey boxes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: no type hint when the lookup leaves the initializer text The parser stores the initializer text as the type name of a VAR; when the lookup cannot resolve it, that text stays. FOREACH VAR d IN <DbFile>{o} showed ' AS <DbFile>{o}' and double-click wrote it out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Lookup: FOREACH VAR over a typed array literal and over a VAR local FOREACH VAR d IN <DbFile>{o} now types d as DbFile. VAR list := s:Load() kept List<T> instead of the declared List<STRING>, so FOREACH VAR item IN list could not type item; implied assignments now keep the type arguments of the declaration, as FOREACH variables already did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: review fixes - Type hint stays silent when the overloads of the final call return different types: the lookup takes the first overload, not the one the arguments pick (Math.Max(1, 2) said BYTE). - Type hint stays silent when a type argument does not resolve (List<TSource> from ToList(), List<T> from a generic class). - The double-click edit writes the namespace unless a USING or the enclosing namespace brings it in, so the edit compiles. - The lookup's array type cache is a ConcurrentDictionary: the lookup now also runs in the background. - The hint computation no longer suspends the code model walker; a suspend made the walker drop and restart its current project after every parse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: hover tooltip as QuickInfo shows it The tooltip of a hint was a plain WPF ToolTip with plain text: white in every theme and without syntax colours. It now uses the editor's IToolTipService with the same content elements as the X# QuickInfo (icon + classified text), so it follows the theme and the classification colours like the C# hints do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: show all hints while Alt+F1 is held down As in C#: a third option "Show all hints while pressing Alt+F1" (on by default) shows the switched off kinds while Alt+F1 is held down in an X# editor. Releasing F1 or Alt, or moving the focus away, hides them again at once. A key processor tracks the hold; the tagger computes the missing kinds without the debounce and filters by the current setting. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Code model: no file lookup per member when a source type is built XProject.GetType rebuilds a source type from the database on every lookup. For each member, XDbResult.UpdateLocation looked the file up through XSolution.FindFile, which creates a new XFile and reads it from the database; GetType then replaced that file with its own cached one. For a VO class with many members this was most of the time of a lookup. UpdateLocation now takes the file from the caller: GetType passes the file it resolves per file id, the extension method path looks its single file up once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: compute the visible lines first A large file was resolved as a whole before any hint appeared. The tagger now computes the visible lines and one screen above and below, and when the view scrolls to lines that are not covered it computes those after a short pause and merges them with the hints of the same snapshot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: find the call arguments by position HintCandidates.Calls looked each call name up in the token list to find its arguments. In the editor the token index does not match the position in that list, so every call searched the whole list: a 775 KB file spent about a second on this before any call was resolved. OverloadFilter.Arguments now also takes the position, and the scan passes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: the colours of the C# inline hints The hints were grey on a translucent grey background in every theme. They now take the colours of the C# "inline hints" item in Fonts and Colors: the Visual Studio themes colour it, so the hints follow light and dark like the C# hints, and a colour the user picks for C# applies to both. Without that item (no Roslyn) the X# item is used, now with the C# defaults. It is no longer shown in Fonts and Colors, where it would change nothing while the C# item exists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: generic type arguments in VAR declarations VAR d := Dictionary<STRING, INT>{} was split at the comma between the type arguments into two declarators. The double-click edit then wrote the type after STRING, in the middle of the type arguments, and the code no longer compiled. The commas of Name<A, B>{...}, Name<A, B>(...) and <T>{...} now stay in the initializer; a comparison such as VAR a := x < y, b := 2 still splits. A generic constructor (VAR l := List<STRING>{}) now counts as a visible type, like Customer{}, so it no longer gets a redundant type hint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Lookup: FOREACH VAR over <T>{} only takes T when it resolves The element type name of a typed array literal was stored as the type of the loop variable before the lookup searched it, so an unknown T showed as an inlay hint (and in QuickInfo). The name is now only taken when the type resolves; otherwise the variable stays unresolved and gets no hint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: a request cancels a pending debounce of the same document A pending debounced computation was asked for an older state; after a direct request for the same document it ran once more for nothing. Request now cancels it. The CancellationTokenSources of the debounce are disposed when their delay ends. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Find References, inlay hints: generic type arguments in call arguments OverloadFilter.Arguments split Foo(Dictionary<STRING, INT>{}, 1) at the comma between the type arguments and counted three arguments. Find References then dropped the matching overload, and the inlay hints found no parameter for the call or shifted the names of a CLIPPER method. The commas of Name<A, B>{...}, Name<A, B>(...) and <T>{...} now stay in their argument; a comparison such as Foo(a < b, c > d, e) still counts three. The type argument check moved from HintCandidates to OverloadFilter, where both use it; it now skips tokens off the default channel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Find References, inlay hints: calls with type arguments after the name List<STRING>{10} and o:Foo<INT>(1, 2) had no argument list: the argument reader and the inlay hint candidates expected ( or { right after the name, and a generic creation was not narrowed to the constructors. So these calls got no parameter hints, and Find References did not filter their overloads. OverloadFilter.ListAfterName finds the ( or { after the name, also after type arguments; Arguments, SymbolResolver.ForCreation and HintCandidates.Calls use it. Foo < 3 and Foo < b, c > d stay no call. Go To Definition on Foo in Foo<T>{1} now reaches the constructor, as it already did for Foo{1}. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Find References: generic source classes and their constructors CLASS Box<T> is stored as Box`1. Find References searched the files for "Box`1", which no source contains, and did not recognise the declaration, so a generic class had no references at all. The search name and the declaration check now drop the arity. The constructor candidates only took Box{...}; Box<INT>{...} is now one too (OverloadFilter.ListAfterName), so Find References on the CONSTRUCTOR of a generic class finds its creations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Go To Definition: a keyword is no target F12 on a keyword (the caret on CLASS) showed "Cannot navigate to the symbol under the cursor"; when nothing is found F12 stays silent, a keyword is now treated the same. Seen after F12 on Foo{1} through DTE.ExecuteCommand: the shell sent the command twice, the first call opened the class with the caret at the start of its line, the second one hit the CLASS keyword. The deduplication moved into XSharpGotoDefinition.Targets, which also drops the keywords. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: off by default, all hints while Alt+F1 is held down As C# (Roslyn: EnabledForParameters and EnabledForTypes false, DisplayAllHintsWhilePressingAltF1 true): parameter and type hints are off until switched on in Tools - Options; holding Alt+F1 shows both. The defaults are constants in InlayHintSettings, used by the options page and as the start values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: an argument of only names and dots is no constructor 5df8da4 dropped the end check in HintRules.IsConstructor: for an argument or initializer made only of IDs and dots (Foo(Color.Red), VAR e := Encoding.UTF8) it read past the end of the token list. The exception left the computation, so the whole range showed no hints. Found in review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: a recompute drops the hints it no longer finds Merging with the older hints of the same snapshot kept every old hint the fresh result had no hint for at the same place, also inside the range just recomputed. After the walker finished or another file was saved, a call that had become ambiguous kept its stale parameter name until the next edit. Inside the freshly covered range only the fresh hints count now. Found in review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Inlay hints: generic VAR calls get the overload check; no fixed time limit in the linear-time test FinalCallName took the token before the argument list as the call name, so for VAR x := o:Foo<INT>(1) it found '>' and skipped the check that the call is unambiguous; the type hint could come from the wrong overload. It now steps back over the type arguments to the name (checked with OverloadFilter.ListAfterName). ALargeFileIsScannedInLinearTime had a 1000 ms wall-clock limit that can fail on the E-cores. It now compares 5000 with 20000 calls (fastest of three runs each): linear is about 4x, the test allows less than 8x; the quadratic scan it guards against measured 23x. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [VS] Correction to the message of f80b56f (no code change) f80b56f says: "Go To Definition on Foo in Foo<T>{1} now reaches the constructor, as it already did for Foo{1}." That is wrong. Correct is: Find References on Foo in Foo<T>{1} now resolves to the constructors, as it already did for Foo{1}; Go To Definition still goes to the class, for Foo{1} as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rename (Ctrl+R, Ctrl+R) for X# symbols in Visual Studio, built on the Find All References engine (#2148).
What it does
#ifdefcode, files that could not be read) are never changed. After Apply they are listed in the Find All References window.System.Objectmembers of classes without INHERIT), symbols not declared in the X# source.@@), warns about existing symbols with the new name, and stops before any change when a closed file is read-only or a file changed since the search.Changes outside the new Rename folder
FindReferencesCommandtoReferencesWindowso that Rename can list its places there; it includes the keep fix of [VS] Find References: Keep Results no longer clears the kept window, search does not block the UI #2152.XFile.Rename(newPath)in the code model: after a file rename the open editor keeps itsXFile; Rename moves it to the new path and parses the editor text. (A plain rename of an open, changed file in Solution Explorer still leaves the old class name in the code model until the file is saved; not changed here.)Tests
LanguageService.Tests: 106 tests (name check, guard, conflicts, planner, text and uncertainty of the engine).Known limitations
#Nameliterals of classes and functions are reported, not changed.🤖 Generated with Claude Code