@@ -50,82 +50,58 @@ private void _state_StateChanged(object sender, ParserStateEventArgs e)
5050 _uiDispatcher . InvokeAsync ( UpdateTab ) ;
5151 }
5252
53- public void FindAllReferences ( Declaration declaration )
53+ public void FindAllReferences ( Declaration target )
5454 {
5555 if ( _state . Status != ParserState . Ready )
5656 {
57+ _logger . Debug ( $ "ParserState is { _state . Status } . This action requires a Ready state.") ;
5758 return ;
5859 }
5960
60- var viewModel = CreateViewModel ( declaration ) ;
61- if ( ! viewModel . SearchResults . Any ( ) )
61+ var viewModel = CreateViewModel ( target ) ;
62+ if ( ! Confirm ( target . IdentifierName , viewModel . SearchResults . Count ) )
6263 {
63- _messageBox . NotifyWarn ( string . Format ( RubberduckUI . AllReferences_NoneFound , declaration . IdentifierName ) , RubberduckUI . Rubberduck ) ;
6464 return ;
6565 }
6666
67- if ( viewModel . SearchResults . Count == 1 )
68- {
69- _navigateCommand . Execute ( viewModel . SearchResults . Single ( ) . GetNavigationArgs ( ) ) ;
70- return ;
71- }
72-
73- _viewModel . AddTab ( viewModel ) ;
74- _viewModel . SelectedTab = viewModel ;
75-
76- try
77- {
78- var presenter = _presenterService . Presenter ( _viewModel ) ;
79- presenter . Show ( ) ;
80- }
81- catch ( Exception e )
82- {
83- _logger . Error ( e ) ;
84- }
67+ ShowResults ( viewModel ) ;
8568 }
8669
87- public void FindAllReferences ( Declaration declaration , ReferenceInfo reference )
70+ public void FindAllReferences ( ProjectDeclaration project , ReferenceInfo reference )
8871 {
89- if ( _state . Status != ParserState . Ready ||
90- ! ( declaration is ProjectDeclaration project ) )
72+ if ( _state . Status != ParserState . Ready )
9173 {
74+ _logger . Debug ( $ "ParserState is { _state . Status } . This action requires a Ready state.") ;
9275 return ;
9376 }
9477
95- var usages = _state . DeclarationFinder . FindAllReferenceUsesInProject ( project , reference , out var referenceProject )
96- . Select ( usage =>
97- new SearchResultItem ( usage . ParentNonScoping ,
98- new NavigateCodeEventArgs ( usage . QualifiedModuleName , usage . Selection ) ,
99- GetModuleLine ( usage . QualifiedModuleName , usage . Selection . StartLine ) ) )
100- . ToList ( ) ;
101-
102- if ( declaration is ParameterDeclaration parameter )
78+ var usages = _state . DeclarationFinder . FindAllReferenceUsesInProject ( project , reference , out var referenceProject ) . ToList ( ) ;
79+ if ( referenceProject == null )
10380 {
104- usages . AddRange ( parameter . ArgumentReferences . Select ( usage =>
105- new SearchResultItem ( usage . ParentNonScoping ,
106- new NavigateCodeEventArgs ( usage . QualifiedModuleName , usage . Selection ) ,
107- GetModuleLine ( usage . QualifiedModuleName , usage . Selection . StartLine ) ) ) ) ;
81+ return ;
10882 }
109-
110- if ( ! usages . Any ( ) )
83+ if ( ! Confirm ( referenceProject . IdentifierName , usages . Count ) )
11184 {
112- _messageBox . NotifyWarn ( string . Format ( RubberduckUI . AllReferences_NoneFoundReference , referenceProject . IdentifierName ) , RubberduckUI . Rubberduck ) ;
11385 return ;
11486 }
11587
116- if ( usages . Count > 1000 &&
117- ! _messageBox . ConfirmYesNo ( string . Format ( RubberduckUI . AllReferences_PerformanceWarning , referenceProject . IdentifierName , usages . Count ) ,
118- RubberduckUI . PerformanceWarningCaption ) )
88+ var viewModel = CreateViewModel ( project , referenceProject . IdentifierName , usages ) ;
89+ ShowResults ( viewModel ) ;
90+ }
91+
92+ private void ShowResults ( SearchResultsViewModel viewModel )
93+ {
94+ if ( viewModel . SearchResults . Count == 1 )
11995 {
96+ viewModel . NavigateCommand . Execute ( viewModel . SearchResults [ 0 ] . GetNavigationArgs ( ) ) ;
12097 return ;
12198 }
12299
123- var viewModel = CreateViewModel ( project , referenceProject , usages ) ;
124- _viewModel . AddTab ( viewModel ) ;
125- _viewModel . SelectedTab = viewModel ;
126-
127100 try
128101 {
102+ _viewModel . AddTab ( viewModel ) ;
103+ _viewModel . SelectedTab = viewModel ;
104+
129105 var presenter = _presenterService . Presenter ( _viewModel ) ;
130106 presenter . Show ( ) ;
131107 }
@@ -135,51 +111,95 @@ public void FindAllReferences(Declaration declaration, ReferenceInfo reference)
135111 }
136112 }
137113
138- private string GetModuleLine ( QualifiedModuleName module , int line )
114+ private bool Confirm ( string identifier , int referencesFound )
139115 {
140- var component = _state . ProjectsProvider . Component ( module ) ;
141- using ( var codeModule = component . CodeModule )
116+ const int threshold = 1000 ;
117+ if ( referencesFound == 0 )
142118 {
143- return codeModule . GetLines ( line , 1 ) . Trim ( ) ;
119+ _messageBox . NotifyWarn (
120+ string . Format ( RubberduckUI . AllReferences_NoneFoundReference , identifier ) ,
121+ RubberduckUI . Rubberduck ) ;
122+ return false ;
144123 }
145- }
146124
147- private SearchResultsViewModel CreateViewModel ( ProjectDeclaration project , ProjectDeclaration reference , IEnumerable < SearchResultItem > results )
148- {
149- var viewModel = new SearchResultsViewModel ( _navigateCommand ,
150- string . Format ( RubberduckUI . SearchResults_AllReferencesTabFormat , reference . IdentifierName ) , project , results ) ;
125+ if ( referencesFound > threshold )
126+ {
127+ return _messageBox . ConfirmYesNo (
128+ string . Format ( RubberduckUI . AllReferences_PerformanceWarning , identifier , referencesFound ) ,
129+ RubberduckUI . PerformanceWarningCaption ) ;
130+ }
151131
152- return viewModel ;
132+ return true ;
153133 }
154134
155- private SearchResultsViewModel CreateViewModel ( Declaration declaration )
135+
136+ private SearchResultsViewModel CreateViewModel ( Declaration declaration , string identifier = null , IEnumerable < IdentifierReference > references = null )
156137 {
157- var results = declaration . References
138+ var nameRefs = ( references ?? declaration . References )
158139 . Where ( reference => ! reference . IsArrayAccess )
159140 . Distinct ( )
160- . Select ( reference =>
161- new SearchResultItem (
162- reference . ParentNonScoping ,
163- new NavigateCodeEventArgs ( reference . QualifiedModuleName , reference . Selection ) ,
164- GetModuleLine ( reference . QualifiedModuleName , reference . Selection . StartLine ) ) )
165- . Concat ( ( declaration is ParameterDeclaration parameter )
166- ? parameter . ArgumentReferences . Select ( argument =>
167- new SearchResultItem (
168- argument . ParentNonScoping ,
169- new NavigateCodeEventArgs ( argument . QualifiedModuleName , argument . Selection ) ,
170- GetModuleLine ( argument . QualifiedModuleName , argument . Selection . StartLine ) ) )
171- : Enumerable . Empty < SearchResultItem > ( ) ) ;
141+ . GroupBy ( reference => reference . QualifiedModuleName )
142+ . ToDictionary ( group => group . Key ) ;
143+
144+ var argRefs = ( declaration is ParameterDeclaration parameter
145+ ? parameter . ArgumentReferences
146+ : Enumerable . Empty < ArgumentReference > ( ) )
147+ . Distinct ( )
148+ . GroupBy ( argRef => argRef . QualifiedModuleName )
149+ . ToDictionary ( group => group . Key ) ;
150+
151+ var results = new List < SearchResultItem > ( ) ;
152+ var modules = nameRefs . Keys . Concat ( argRefs . Keys ) . Distinct ( ) ;
153+ foreach ( var qualifiedModuleName in modules )
154+ {
155+ var component = _state . ProjectsProvider . Component ( qualifiedModuleName ) ;
156+ if ( component == null )
157+ {
158+ _logger . Warn ( $ "Could not retrieve the IVBComponent for module '{ qualifiedModuleName } '.") ;
159+ continue ;
160+ }
161+ var module = component . CodeModule ;
162+
163+ if ( nameRefs . TryGetValue ( qualifiedModuleName , out var identifierReferences ) )
164+ {
165+ foreach ( var identifierReference in identifierReferences )
166+ {
167+ var ( context , selection ) = identifierReference . HighlightSelection ( module ) ;
168+ var result = new SearchResultItem (
169+ identifierReference . ParentNonScoping ,
170+ new NavigateCodeEventArgs ( qualifiedModuleName , identifierReference . Selection ) ,
171+ context , selection ) ;
172+ results . Add ( result ) ;
173+ }
174+ }
175+
176+ if ( argRefs . TryGetValue ( qualifiedModuleName , out var argReferences ) )
177+ {
178+ foreach ( var argumentReference in argReferences )
179+ {
180+ var ( context , selection ) = argumentReference . HighlightSelection ( module ) ;
181+ var result = new SearchResultItem (
182+ argumentReference . ParentNonScoping ,
183+ new NavigateCodeEventArgs ( qualifiedModuleName , argumentReference . Selection ) ,
184+ context , selection ) ;
185+ results . Add ( result ) ;
186+ }
187+ }
188+ }
172189
173190 var accessor = declaration . DeclarationType . HasFlag ( DeclarationType . PropertyGet ) ? "(get)"
174191 : declaration . DeclarationType . HasFlag ( DeclarationType . PropertyLet ) ? "(let)"
175192 : declaration . DeclarationType . HasFlag ( DeclarationType . PropertySet ) ? "(set)"
176193 : string . Empty ;
177194
178- var tabCaption = $ "{ declaration . IdentifierName } { accessor } ". Trim ( ) ;
195+ var tabCaption = $ "{ identifier ?? declaration . IdentifierName } { accessor } ". Trim ( ) ;
179196
180197
181198 var viewModel = new SearchResultsViewModel ( _navigateCommand ,
182- string . Format ( RubberduckUI . SearchResults_AllReferencesTabFormat , tabCaption ) , declaration , results ) ;
199+ string . Format ( RubberduckUI . SearchResults_AllReferencesTabFormat , tabCaption ) , declaration ,
200+ results . OrderBy ( item => item . ParentScope . QualifiedModuleName . ToString ( ) )
201+ . ThenBy ( item => item . Selection )
202+ . ToList ( ) ) ;
183203
184204 return viewModel ;
185205 }
0 commit comments