2
2
using System . Collections . Generic ;
3
3
using System . Globalization ;
4
4
using System . Linq ;
5
- using Antlr4 . Runtime ;
6
- using Antlr4 . Runtime . Tree ;
7
- using Rubberduck . Common ;
8
5
using Rubberduck . Inspections . Abstract ;
9
6
using Rubberduck . Inspections . Results ;
10
- using Rubberduck . Parsing ;
11
- using Rubberduck . Parsing . Grammar ;
12
7
using Rubberduck . Parsing . Inspections . Abstract ;
13
8
using Rubberduck . Parsing . Inspections . Resources ;
14
9
using Rubberduck . Parsing . Symbols ;
@@ -28,34 +23,6 @@ private enum DeclarationSite
28
23
SameComponent = 3
29
24
}
30
25
31
- private class OptionPrivateModuleListener : VBAParserBaseListener
32
- {
33
- public List < VBAParser . ModuleContext > OptionPrivateModules { get ; } = new List < VBAParser . ModuleContext > ( ) ;
34
-
35
- public override void EnterModule ( VBAParser . ModuleContext context )
36
- {
37
- if ( context . FindChildren < VBAParser . OptionPrivateModuleStmtContext > ( ) . Any ( ) )
38
- {
39
- OptionPrivateModules . Add ( context ) ;
40
- }
41
- }
42
- }
43
-
44
- private class EnumerationRuleIndexListener : VBAParserBaseListener
45
- {
46
- public Dictionary < ParserRuleContext , int > DeclarationIndexes { get ; } = new Dictionary < ParserRuleContext , int > ( ) ;
47
-
48
- public override void EnterEnumerationStmt ( VBAParser . EnumerationStmtContext context )
49
- {
50
- DeclarationIndexes . Add ( context , context . Start . TokenIndex ) ;
51
- }
52
-
53
- public override void EnterEnumerationStmt_Constant ( VBAParser . EnumerationStmt_ConstantContext context )
54
- {
55
- DeclarationIndexes . Add ( context , context . Start . TokenIndex ) ;
56
- }
57
- }
58
-
59
26
public ShadowedDeclarationInspection ( RubberduckParserState state ) : base ( state , CodeInspectionSeverity . DoNotShow )
60
27
{
61
28
}
@@ -66,50 +33,37 @@ public ShadowedDeclarationInspection(RubberduckParserState state) : base(state,
66
33
67
34
public override IEnumerable < IInspectionResult > GetInspectionResults ( )
68
35
{
69
- var optionPrivateModuleListener = new OptionPrivateModuleListener ( ) ;
70
- var enumerationRuleIndexListener = new EnumerationRuleIndexListener ( ) ;
71
-
72
- foreach ( var module in State . DeclarationFinder . AllModules . Where ( m => m . ComponentType == ComponentType . StandardModule ) )
73
- {
74
- ParseTreeWalker . Default . Walk ( optionPrivateModuleListener , State . GetParseTree ( module ) ) ;
75
- }
76
-
77
- foreach ( var module in State . AllUserDeclarations . Where ( d => d . DeclarationType == DeclarationType . ProceduralModule || d . DeclarationType == DeclarationType . ClassModule ) )
78
- {
79
- ParseTreeWalker . Default . Walk ( enumerationRuleIndexListener , State . GetParseTree ( module . QualifiedName . QualifiedModuleName ) ) ;
80
- }
81
-
82
36
var builtInEventHandlers = State . DeclarationFinder . FindEventHandlers ( ) . ToHashSet ( ) ;
83
37
84
38
var issues = new List < IInspectionResult > ( ) ;
85
39
86
- var allUserProjects = UserDeclarations . OfType ( DeclarationType . Project ) . Cast < ProjectDeclaration > ( ) ;
40
+ var allUserProjects = State . DeclarationFinder . UserDeclarations ( DeclarationType . Project ) . Cast < ProjectDeclaration > ( ) ;
87
41
88
42
foreach ( var userProject in allUserProjects )
89
43
{
90
44
var referencedProjectIds = userProject . ProjectReferences . Select ( reference => reference . ReferencedProjectId ) . ToHashSet ( ) ;
91
45
92
- var userDeclarations = UserDeclarations . Where ( d =>
93
- d . ProjectId == userProject . ProjectId &&
46
+ var userDeclarations = UserDeclarations . Where ( declaration =>
47
+ declaration . ProjectId == userProject . ProjectId &&
94
48
// User has no control over build-in event handlers or their parameters, so we skip them
95
- ! DeclarationIsPartOfBuiltInEventHandler ( d , builtInEventHandlers ) ) ;
49
+ ! DeclarationIsPartOfBuiltInEventHandler ( declaration , builtInEventHandlers ) ) ;
96
50
97
- foreach ( var declaration in userDeclarations )
51
+ foreach ( var userDeclaration in userDeclarations )
98
52
{
99
- var shadowedDeclaration = State . AllDeclarations . FirstOrDefault ( d =>
100
- ! Equals ( d , declaration ) &&
101
- string . Equals ( d . IdentifierName , declaration . IdentifierName , StringComparison . OrdinalIgnoreCase ) &&
102
- DeclarationCanBeShadowed ( d , declaration , GetDeclarationSite ( d , declaration , referencedProjectIds ) , optionPrivateModuleListener , enumerationRuleIndexListener ) ) ;
53
+ var shadowedDeclaration = State . DeclarationFinder
54
+ . MatchName ( userDeclaration . IdentifierName ) . FirstOrDefault ( declaration =>
55
+ ! declaration . Equals ( userDeclaration ) &&
56
+ DeclarationCanBeShadowed ( declaration , userDeclaration , GetDeclarationSite ( declaration , userDeclaration , referencedProjectIds ) ) ) ;
103
57
104
58
if ( shadowedDeclaration != null )
105
59
{
106
60
issues . Add ( new DeclarationInspectionResult ( this ,
107
61
string . Format ( InspectionsUI . ShadowedDeclarationInspectionResultFormat ,
108
- RubberduckUI . ResourceManager . GetString ( "DeclarationType_" + declaration . DeclarationType , CultureInfo . CurrentUICulture ) ,
109
- declaration . IdentifierName ,
62
+ RubberduckUI . ResourceManager . GetString ( "DeclarationType_" + userDeclaration . DeclarationType , CultureInfo . CurrentUICulture ) ,
63
+ userDeclaration . IdentifierName ,
110
64
RubberduckUI . ResourceManager . GetString ( "DeclarationType_" + shadowedDeclaration . DeclarationType , CultureInfo . CurrentUICulture ) ,
111
65
shadowedDeclaration . IdentifierName ) ,
112
- declaration ) ) ;
66
+ userDeclaration ) ) ;
113
67
}
114
68
}
115
69
}
@@ -124,7 +78,7 @@ private static DeclarationSite GetDeclarationSite(Declaration originalDeclaratio
124
78
return referencedProjectIds . Contains ( originalDeclaration . ProjectId ) ? DeclarationSite . ReferencedProject : DeclarationSite . NotApplicable ;
125
79
}
126
80
127
- if ( originalDeclaration . QualifiedName . QualifiedModuleName . Name != userDeclaration . QualifiedName . QualifiedModuleName . Name )
81
+ if ( originalDeclaration . QualifiedName . QualifiedModuleName . ComponentName != userDeclaration . QualifiedName . QualifiedModuleName . ComponentName )
128
82
{
129
83
return DeclarationSite . OtherComponent ;
130
84
}
@@ -144,8 +98,7 @@ private static bool DeclarationIsPartOfBuiltInEventHandler(Declaration declarati
144
98
return parameterDeclaration != null && builtInEventHandlers . Contains ( parameterDeclaration . ParentDeclaration ) ;
145
99
}
146
100
147
- private static bool DeclarationCanBeShadowed ( Declaration originalDeclaration , Declaration userDeclaration , DeclarationSite originalDeclarationSite ,
148
- OptionPrivateModuleListener optionPrivateModuleListener , EnumerationRuleIndexListener enumerationRuleIndexListener )
101
+ private static bool DeclarationCanBeShadowed ( Declaration originalDeclaration , Declaration userDeclaration , DeclarationSite originalDeclarationSite )
149
102
{
150
103
if ( originalDeclarationSite == DeclarationSite . NotApplicable )
151
104
{
@@ -154,20 +107,20 @@ private static bool DeclarationCanBeShadowed(Declaration originalDeclaration, De
154
107
155
108
if ( originalDeclarationSite == DeclarationSite . ReferencedProject )
156
109
{
157
- return DeclarationInReferencedProjectCanBeShadowed ( originalDeclaration , userDeclaration , optionPrivateModuleListener ) ;
110
+ return DeclarationInReferencedProjectCanBeShadowed ( originalDeclaration , userDeclaration ) ;
158
111
}
159
112
160
113
if ( originalDeclarationSite == DeclarationSite . OtherComponent )
161
114
{
162
- return DeclarationInAnotherComponentCanBeShadowed ( originalDeclaration , userDeclaration , optionPrivateModuleListener ) ;
115
+ return DeclarationInAnotherComponentCanBeShadowed ( originalDeclaration , userDeclaration ) ;
163
116
}
164
117
165
- return DeclarationInTheSameComponentCanBeShadowed ( originalDeclaration , userDeclaration , enumerationRuleIndexListener ) ;
118
+ return DeclarationInTheSameComponentCanBeShadowed ( originalDeclaration , userDeclaration ) ;
166
119
}
167
120
168
- private static bool DeclarationInReferencedProjectCanBeShadowed ( Declaration originalDeclaration , Declaration userDeclaration , OptionPrivateModuleListener listener )
121
+ private static bool DeclarationInReferencedProjectCanBeShadowed ( Declaration originalDeclaration , Declaration userDeclaration )
169
122
{
170
- if ( DeclarationIsInsideOptionPrivateModule ( originalDeclaration , listener ) )
123
+ if ( DeclarationIsInsideOptionPrivateModule ( originalDeclaration ) )
171
124
{
172
125
return false ;
173
126
}
@@ -231,9 +184,9 @@ private static bool DeclarationInReferencedProjectCanBeShadowed(Declaration orig
231
184
return DeclarationAccessibilityCanBeShadowed ( originalDeclaration ) ;
232
185
}
233
186
234
- private static bool DeclarationInAnotherComponentCanBeShadowed ( Declaration originalDeclaration , Declaration userDeclaration , OptionPrivateModuleListener listener )
187
+ private static bool DeclarationInAnotherComponentCanBeShadowed ( Declaration originalDeclaration , Declaration userDeclaration )
235
188
{
236
- if ( DeclarationIsInsideOptionPrivateModule ( originalDeclaration , listener ) )
189
+ if ( DeclarationIsInsideOptionPrivateModule ( originalDeclaration ) )
237
190
{
238
191
return false ;
239
192
}
@@ -292,7 +245,7 @@ private static bool DeclarationInAnotherComponentCanBeShadowed(Declaration origi
292
245
return DeclarationAccessibilityCanBeShadowed ( originalDeclaration ) ;
293
246
}
294
247
295
- private static bool DeclarationInTheSameComponentCanBeShadowed ( Declaration originalDeclaration , Declaration userDeclaration , EnumerationRuleIndexListener listener )
248
+ private static bool DeclarationInTheSameComponentCanBeShadowed ( Declaration originalDeclaration , Declaration userDeclaration )
296
249
{
297
250
// Shadowing the component containing the declaration is not a problem, because it is possible to directly access declarations inside that component
298
251
if ( originalDeclaration . DeclarationType == DeclarationType . ProceduralModule || originalDeclaration . DeclarationType == DeclarationType . ClassModule ||
@@ -323,18 +276,20 @@ private static bool DeclarationInTheSameComponentCanBeShadowed(Declaration origi
323
276
{
324
277
return DeclarationIsLocal ( userDeclaration ) ;
325
278
}
279
+
280
+ // Shadowing between two enumerations or enumeration members is not possible inside one component.
281
+ if ( ( ( originalDeclaration . DeclarationType == DeclarationType . Enumeration
282
+ && userDeclaration . DeclarationType == DeclarationType . EnumerationMember )
283
+ || ( originalDeclaration . DeclarationType == DeclarationType . EnumerationMember
284
+ && userDeclaration . DeclarationType == DeclarationType . Enumeration ) ) )
285
+ {
286
+ var originalDeclarationIndex = originalDeclaration . Context . start . StartIndex ;
287
+ var userDeclarationIndex = userDeclaration . Context . start . StartIndex ;
326
288
327
- if ( listener . DeclarationIndexes . ContainsKey ( originalDeclaration . Context ) && listener . DeclarationIndexes . ContainsKey ( userDeclaration . Context ) )
328
- {
329
- var originalDeclarationIndex = listener . DeclarationIndexes [ originalDeclaration . Context ] ;
330
- var userDeclarationIndex = listener . DeclarationIndexes [ userDeclaration . Context ] ;
331
-
332
- // The same declaration type means that both declarations are enumerations or enumeration members, and such shadowing is not possible inside one component
333
- return originalDeclaration . DeclarationType != userDeclaration . DeclarationType &&
334
- // First declaration wins
335
- originalDeclarationIndex > userDeclarationIndex &&
336
- // Enumeration member can have the same name as enclosing enumeration
337
- ! Equals ( originalDeclaration . ParentDeclaration , userDeclaration ) ;
289
+ // First declaration wins
290
+ return originalDeclarationIndex > userDeclarationIndex
291
+ // Enumeration member can have the same name as enclosing enumeration
292
+ && ! userDeclaration . Equals ( originalDeclaration . ParentDeclaration ) ;
338
293
}
339
294
340
295
// Events don't have a body, so their parameters can't be accessed
@@ -355,20 +310,20 @@ private static bool DeclarationAccessibilityCanBeShadowed(Declaration originalDe
355
310
( originalDeclaration . DeclarationType == DeclarationType . EnumerationMember && originalDeclaration . ParentDeclaration . Accessibility == Accessibility . Public ) ;
356
311
}
357
312
358
- private static bool DeclarationIsInsideOptionPrivateModule ( Declaration declaration , OptionPrivateModuleListener listener )
313
+ private static bool DeclarationIsInsideOptionPrivateModule ( Declaration declaration )
359
314
{
360
315
if ( declaration . QualifiedName . QualifiedModuleName . ComponentType != ComponentType . StandardModule )
361
316
{
362
317
return false ;
363
318
}
364
319
365
- var moduleDeclaration = declaration as ProceduralModuleDeclaration ;
320
+ var moduleDeclaration = Declaration . GetModuleParent ( declaration ) as ProceduralModuleDeclaration ;
366
321
if ( moduleDeclaration != null )
367
322
{
368
323
return moduleDeclaration . IsPrivateModule ;
369
324
}
370
325
371
- return listener . OptionPrivateModules . Any ( moduleContext => ParserRuleContextHelper . HasParent ( declaration . Context , moduleContext ) ) ;
326
+ return false ;
372
327
}
373
328
374
329
private static bool DeclarationIsProjectOrComponent ( Declaration declaration )
0 commit comments