@@ -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,25 +88,72 @@ 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
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
+
110
157
private IEnumerable < IAnnotation > FindMemberAnnotations ( int firstMemberLine )
111
158
{
112
159
if ( _annotations == null )
0 commit comments