@@ -97,6 +97,12 @@ private void ParseInternal()
9797 . SelectMany ( project => project . VBComponents . Cast < VBComponent > ( ) )
9898 . ToList ( ) ;
9999
100+ var invalidCache = _componentAttributes . Keys . Except ( components ) . ToList ( ) ;
101+ foreach ( var component in invalidCache )
102+ {
103+ _componentAttributes . Remove ( component ) ;
104+ }
105+
100106 foreach ( var vbComponent in components )
101107 {
102108 while ( ! _state . ClearDeclarations ( vbComponent ) )
@@ -147,8 +153,6 @@ public void ParseComponent(VBComponent vbComponent, TokenStreamRewriter rewriter
147153
148154 try
149155 {
150- var attributes = _attributeParser . Parse ( component ) ;
151-
152156 var qualifiedName = new QualifiedModuleName ( vbComponent ) ;
153157 var code = rewriter == null ? string . Join ( Environment . NewLine , vbComponent . CodeModule . GetSanitizedCode ( ) ) : rewriter . GetText ( ) ;
154158
@@ -180,7 +184,7 @@ public void ParseComponent(VBComponent vbComponent, TokenStreamRewriter rewriter
180184 } ;
181185
182186 var tree = GetParseTree ( vbComponent , listeners , preprocessedModuleBody , qualifiedName ) ;
183- WalkParseTree ( vbComponent , listeners , qualifiedName , tree , attributes ) ;
187+ WalkParseTree ( vbComponent , listeners , qualifiedName , tree ) ;
184188
185189 State . SetModuleState ( vbComponent , ParserState . Parsed ) ;
186190 }
@@ -222,13 +226,22 @@ private IParseTree GetParseTree(VBComponent vbComponent, IParseTreeListener[] li
222226 return tree ;
223227 }
224228
225- private void WalkParseTree ( VBComponent vbComponent , IReadOnlyList < IParseTreeListener > listeners , QualifiedModuleName qualifiedName , IParseTree tree , IDictionary < Tuple < string , DeclarationType > , Attributes > attributes )
229+ private readonly IDictionary < VBComponent , IDictionary < Tuple < string , DeclarationType > , Attributes > > _componentAttributes
230+ = new Dictionary < VBComponent , IDictionary < Tuple < string , DeclarationType > , Attributes > > ( ) ;
231+
232+ private void WalkParseTree ( VBComponent vbComponent , IReadOnlyList < IParseTreeListener > listeners , QualifiedModuleName qualifiedName , IParseTree tree )
226233 {
227234 var obsoleteCallsListener = listeners . OfType < ObsoleteCallStatementListener > ( ) . Single ( ) ;
228235 var obsoleteLetListener = listeners . OfType < ObsoleteLetStatementListener > ( ) . Single ( ) ;
229236 var emptyStringLiteralListener = listeners . OfType < EmptyStringLiteralListener > ( ) . Single ( ) ;
230237 var argListsWithOneByRefParamListener = listeners . OfType < ArgListWithOneByRefParamListener > ( ) . Single ( ) ;
231238
239+ if ( ! _componentAttributes . ContainsKey ( vbComponent ) )
240+ {
241+ _componentAttributes . Add ( vbComponent , _attributeParser . Parse ( vbComponent ) ) ;
242+ }
243+ var attributes = _componentAttributes [ vbComponent ] ;
244+
232245 // cannot locate declarations in one pass *the way it's currently implemented*,
233246 // because the context in EnterSubStmt() doesn't *yet* have child nodes when the context enters.
234247 // so we need to EnterAmbiguousIdentifier() and evaluate the parent instead - this *might* work.
0 commit comments