@@ -32,8 +32,11 @@ public class DeclarationFinder
32
32
private IDictionary < Declaration , List < ParameterDeclaration > > _parametersByParent ;
33
33
private IDictionary < DeclarationType , List < Declaration > > _userDeclarationsByType ;
34
34
private IDictionary < QualifiedSelection , List < Declaration > > _declarationsBySelection ;
35
+
36
+ private IReadOnlyList < IdentifierReference > _identifierReferences ;
35
37
private IDictionary < QualifiedSelection , List < IdentifierReference > > _referencesBySelection ;
36
38
private IReadOnlyDictionary < QualifiedModuleName , IReadOnlyList < IdentifierReference > > _referencesByModule ;
39
+ private IReadOnlyDictionary < string , IReadOnlyList < IdentifierReference > > _referencesByProjectId ;
37
40
private IDictionary < QualifiedMemberName , List < IdentifierReference > > _referencesByMember ;
38
41
39
42
private Lazy < IDictionary < DeclarationType , List < Declaration > > > _builtInDeclarationsByType ;
@@ -107,12 +110,7 @@ private List<Action> CollectionConstructionActions(IReadOnlyList<Declaration> de
107
110
. Where ( declaration => declaration . IsUserDefined )
108
111
. GroupBy ( GetGroupingKey )
109
112
. ToDictionary ( ) ,
110
- ( ) =>
111
- _referencesBySelection = declarations
112
- . SelectMany ( declaration => declaration . References )
113
- . GroupBy (
114
- reference => new QualifiedSelection ( reference . QualifiedModuleName , reference . Selection ) )
115
- . ToDictionary ( ) ,
113
+
116
114
( ) =>
117
115
_parametersByParent = declarations
118
116
. Where ( declaration => declaration . DeclarationType == DeclarationType . Parameter )
@@ -124,22 +122,34 @@ private List<Action> CollectionConstructionActions(IReadOnlyList<Declaration> de
124
122
. Where ( declaration => declaration . IsUserDefined )
125
123
. GroupBy ( declaration => declaration . DeclarationType )
126
124
. ToDictionary ( ) ,
127
- ( ) =>
128
- _referencesByModule = declarations
129
- . SelectMany ( declaration => declaration . References )
130
- . GroupBy ( reference =>
131
- Declaration . GetModuleParent ( reference . ParentScoping ) . QualifiedName . QualifiedModuleName )
132
- . ToReadonlyDictionary ( ) ,
133
- ( ) =>
134
- _referencesByMember = declarations
135
- . SelectMany ( declaration => declaration . References )
136
- . GroupBy ( reference => reference . ParentScoping . QualifiedName )
137
- . ToDictionary ( )
125
+
126
+ ( ) => InitializeIdentifierDictionaries ( declarations )
138
127
} ;
139
128
140
129
return actions ;
141
130
}
142
131
132
+ private void InitializeIdentifierDictionaries ( IReadOnlyList < Declaration > declarations )
133
+ {
134
+ _identifierReferences = declarations . SelectMany ( declaration => declaration . References ) . ToList ( ) ;
135
+
136
+ _referencesBySelection = _identifierReferences
137
+ . GroupBy ( reference => new QualifiedSelection ( reference . QualifiedModuleName , reference . Selection ) )
138
+ . ToDictionary ( ) ;
139
+
140
+ _referencesByModule = _identifierReferences
141
+ . GroupBy ( reference => Declaration . GetModuleParent ( reference . ParentScoping ) . QualifiedName . QualifiedModuleName )
142
+ . ToReadonlyDictionary ( ) ;
143
+
144
+ _referencesByMember = _identifierReferences
145
+ . GroupBy ( reference => reference . ParentScoping . QualifiedName )
146
+ . ToDictionary ( ) ;
147
+
148
+ _referencesByProjectId = _identifierReferences
149
+ . GroupBy ( reference => reference . Declaration . ProjectId )
150
+ . ToReadonlyDictionary ( ) ;
151
+ }
152
+
143
153
private void InitializeLazyCollections ( )
144
154
{
145
155
_builtInDeclarationsByType = new Lazy < IDictionary < DeclarationType , List < Declaration > > > ( ( ) =>
@@ -1160,12 +1170,7 @@ public bool IsReferenceUsedInProject(ProjectDeclaration project, ReferenceInfo r
1160
1170
return false ;
1161
1171
}
1162
1172
1163
- var referenceProject = reference . Guid . Equals ( Guid . Empty )
1164
- ? UserDeclarations ( DeclarationType . Project ) . OfType < ProjectDeclaration > ( ) . FirstOrDefault ( proj =>
1165
- proj . QualifiedModuleName . ProjectPath . Equals ( reference . FullPath , StringComparison . OrdinalIgnoreCase ) )
1166
- : BuiltInDeclarations ( DeclarationType . Project ) . OfType < ProjectDeclaration > ( ) . FirstOrDefault ( proj =>
1167
- proj . Guid . Equals ( reference . Guid ) && proj . MajorVersion == reference . Major &&
1168
- proj . MinorVersion == reference . Minor ) ;
1173
+ var referenceProject = GetProjectDeclarationForReference ( reference ) ;
1169
1174
1170
1175
if ( referenceProject == null || // Can't locate the project for the reference - assume it is used to avoid false negatives.
1171
1176
IdentifierReferences ( ) . Any ( item =>
@@ -1186,6 +1191,44 @@ public bool IsReferenceUsedInProject(ProjectDeclaration project, ReferenceInfo r
1186
1191
declaration . AsTypeDeclaration . QualifiedModuleName . ProjectId . Equals ( referenceProject . ProjectId ) ) ;
1187
1192
}
1188
1193
1194
+ public List < IdentifierReference > FindAllReferenceUsesInProject ( ProjectDeclaration project , ReferenceInfo reference ,
1195
+ out ProjectDeclaration referenceProject )
1196
+ {
1197
+ var output = new List < IdentifierReference > ( ) ;
1198
+ if ( project == null || string . IsNullOrEmpty ( reference . FullPath ) )
1199
+ {
1200
+ referenceProject = null ;
1201
+ return output ;
1202
+ }
1203
+
1204
+ referenceProject = GetProjectDeclarationForReference ( reference ) ;
1205
+
1206
+ if ( ! _referencesByProjectId . TryGetValue ( referenceProject . ProjectId , out var directReferences ) )
1207
+ {
1208
+ return output ;
1209
+ }
1210
+
1211
+ output . AddRange ( directReferences ) ;
1212
+
1213
+ var projectId = referenceProject . ProjectId ;
1214
+
1215
+ output . AddRange ( _identifierReferences . Where ( identifier =>
1216
+ identifier ? . Declaration ? . AsTypeDeclaration != null &&
1217
+ identifier . Declaration . AsTypeDeclaration . QualifiedModuleName . ProjectId . Equals ( projectId ) ) ) ;
1218
+
1219
+ return output ;
1220
+ }
1221
+
1222
+ private ProjectDeclaration GetProjectDeclarationForReference ( ReferenceInfo reference )
1223
+ {
1224
+ return reference . Guid . Equals ( Guid . Empty )
1225
+ ? UserDeclarations ( DeclarationType . Project ) . OfType < ProjectDeclaration > ( ) . FirstOrDefault ( proj =>
1226
+ proj . QualifiedModuleName . ProjectPath . Equals ( reference . FullPath , StringComparison . OrdinalIgnoreCase ) )
1227
+ : BuiltInDeclarations ( DeclarationType . Project ) . OfType < ProjectDeclaration > ( ) . FirstOrDefault ( proj =>
1228
+ proj . Guid . Equals ( reference . Guid ) && proj . MajorVersion == reference . Major &&
1229
+ proj . MinorVersion == reference . Minor ) ;
1230
+ }
1231
+
1189
1232
private bool UsesScopeResolution ( RuleContext ruleContext )
1190
1233
{
1191
1234
return ( ruleContext is VBAParser . WithMemberAccessExprContext )
0 commit comments