@@ -21,7 +21,7 @@ public class DeclarationSymbolsListener : VBAParserBaseListener
21
21
private Declaration _currentScopeDeclaration ;
22
22
private Declaration _parentDeclaration ;
23
23
24
- private readonly IEnumerable < IAnnotation > _annotations ;
24
+ private readonly ICollection < IAnnotation > _annotations ;
25
25
private readonly IDictionary < ( string scopeIdentifier , DeclarationType scopeType ) , Attributes > _attributes ;
26
26
private readonly IDictionary < ( string scopeIdentifier , DeclarationType scopeType ) , ParserRuleContext > _membersAllowingAttributes ;
27
27
@@ -40,7 +40,7 @@ public DeclarationSymbolsListener(
40
40
{
41
41
_state = state ;
42
42
_qualifiedModuleName = qualifiedModuleName ;
43
- _annotations = annotations ;
43
+ _annotations = annotations . ToList ( ) ;
44
44
_attributes = attributes ;
45
45
_membersAllowingAttributes = membersAllowingAttributes ;
46
46
@@ -61,7 +61,7 @@ public DeclarationSymbolsListener(
61
61
projectDeclaration ,
62
62
_qualifiedModuleName . ComponentName ,
63
63
true ,
64
- FindAnnotations ( ) ,
64
+ FindModuleAnnotations ( ) ,
65
65
moduleAttributes ) ;
66
66
}
67
67
else
@@ -73,7 +73,7 @@ public DeclarationSymbolsListener(
73
73
projectDeclaration ,
74
74
_qualifiedModuleName . ComponentName ,
75
75
true ,
76
- FindAnnotations ( ) ,
76
+ FindModuleAnnotations ( ) ,
77
77
moduleAttributes ,
78
78
hasDefaultInstanceVariable : hasDefaultInstanceVariable ) ;
79
79
}
@@ -88,26 +88,73 @@ public DeclarationSymbolsListener(
88
88
}
89
89
}
90
90
91
- private IEnumerable < IAnnotation > FindAnnotations ( )
91
+ private IEnumerable < IAnnotation > FindModuleAnnotations ( )
92
92
{
93
93
if ( _annotations == null )
94
94
{
95
95
return null ;
96
96
}
97
97
98
- int lastDeclarationsSectionLine ;
99
- var component = _state . ProjectsProvider . Component ( _qualifiedModuleName ) ;
100
- using ( var codeModule = component . CodeModule )
98
+ var lastDeclarationsSectionLine = LastDeclarationsSectionLine ( ) ;
99
+
100
+ //There is no module body.
101
+ if ( lastDeclarationsSectionLine == null )
101
102
{
102
- lastDeclarationsSectionLine = codeModule . CountOfDeclarationLines ;
103
+ return _annotations ;
103
104
}
104
105
105
- var annotations = _annotations . Where ( annotation => annotation . QualifiedSelection . QualifiedName . Equals ( _qualifiedModuleName )
106
- && annotation . QualifiedSelection . Selection . EndLine <= lastDeclarationsSectionLine ) ;
106
+ var lastPossibleModuleAnnotationLine = lastDeclarationsSectionLine . Value ;
107
+ var annotations = _annotations . Where ( annotation => annotation . QualifiedSelection . Selection . EndLine <= lastPossibleModuleAnnotationLine ) ;
107
108
return annotations . ToList ( ) ;
108
109
}
109
110
110
- private IEnumerable < IAnnotation > FindAnnotations ( int line )
111
+ private int ? LastDeclarationsSectionLine ( )
112
+ {
113
+ var firstModuleBodyElementLine = FirstModuleBodyElementLine ( ) ;
114
+
115
+ if ( firstModuleBodyElementLine == null )
116
+ {
117
+ return null ;
118
+ }
119
+
120
+ //The VBE uses 1-based lines.
121
+ for ( var currentLine = firstModuleBodyElementLine . Value - 1 ; currentLine >= 1 ; currentLine -- )
122
+ {
123
+ if ( _annotations . Any ( annotation => annotation . QualifiedSelection . Selection . StartLine <= currentLine
124
+ && annotation . QualifiedSelection . Selection . EndLine >=
125
+ currentLine ) )
126
+ {
127
+ continue ;
128
+ }
129
+
130
+ return currentLine ;
131
+ }
132
+
133
+ //There is no declaration section.
134
+ return 0 ;
135
+ }
136
+
137
+ private int ? FirstModuleBodyElementLine ( )
138
+ {
139
+ var moduleTrees = _state . ParseTrees . Where ( kvp => kvp . Key . Equals ( _qualifiedModuleName ) ) . ToList ( ) ;
140
+ if ( ! moduleTrees . Any ( ) )
141
+ {
142
+ return null ;
143
+ }
144
+
145
+ var startContext = ( ParserRuleContext ) moduleTrees . First ( ) . Value ;
146
+ var moduleBody = startContext . GetDescendent < VBAParser . ModuleBodyContext > ( ) ;
147
+
148
+ var moduleBodyElements = moduleBody . moduleBodyElement ( ) ;
149
+ if ( ! moduleBodyElements . Any ( ) )
150
+ {
151
+ return null ;
152
+ }
153
+
154
+ return moduleBodyElements . Select ( context => context . start . Line ) . Min ( ) ;
155
+ }
156
+
157
+ private IEnumerable < IAnnotation > FindMemberAnnotations ( int firstMemberLine )
111
158
{
112
159
if ( _annotations == null )
113
160
{
@@ -117,16 +164,17 @@ private IEnumerable<IAnnotation> FindAnnotations(int line)
117
164
var annotations = new List < IAnnotation > ( ) ;
118
165
119
166
// VBE 1-based indexing
120
- for ( var i = line - 1 ; i >= 1 ; i -- )
167
+ for ( var currentLine = firstMemberLine - 1 ; currentLine >= 1 ; currentLine -- )
121
168
{
122
- var lineAnnotations = _annotations . Where ( a => a . QualifiedSelection . Selection . StartLine == i ) ;
123
-
124
- if ( ! lineAnnotations . Any ( ) )
169
+ if ( ! _annotations . Any ( annotation => annotation . QualifiedSelection . Selection . StartLine <= currentLine
170
+ && annotation . QualifiedSelection . Selection . EndLine >= currentLine ) )
125
171
{
126
172
break ;
127
173
}
128
174
129
- annotations . AddRange ( lineAnnotations ) ;
175
+ var annotationsStartingOnCurrentLine = _annotations . Where ( a => a . QualifiedSelection . Selection . StartLine == currentLine ) ;
176
+
177
+ annotations . AddRange ( annotationsStartingOnCurrentLine ) ;
130
178
}
131
179
132
180
return annotations ;
@@ -225,7 +273,7 @@ private Declaration CreateDeclaration(
225
273
_attributes . TryGetValue ( key , out var attributes ) ;
226
274
_membersAllowingAttributes . TryGetValue ( key , out var attributesPassContext ) ;
227
275
228
- var annotations = FindAnnotations ( selection . StartLine ) ;
276
+ var annotations = FindMemberAnnotations ( selection . StartLine ) ;
229
277
switch ( declarationType )
230
278
{
231
279
case DeclarationType . Procedure :
@@ -821,7 +869,7 @@ public override void EnterConstSubStmt(VBAParser.ConstSubStmtContext context)
821
869
asTypeName ,
822
870
asTypeClause ,
823
871
typeHint ,
824
- FindAnnotations ( constStmt . Start . Line ) ,
872
+ FindMemberAnnotations ( constStmt . Start . Line ) ,
825
873
accessibility ,
826
874
DeclarationType . Constant ,
827
875
value ,
0 commit comments