@@ -66,7 +66,8 @@ private void StateOnStateChanged(object sender, EventArgs e)
66
66
if ( args . State == ParserState . Parsed )
67
67
{
68
68
Debug . WriteLine ( "(handling OnStateChanged) Starting resolver task" ) ;
69
- Task . Run ( ( ) => Resolve ( _central . Token ) ) ;
69
+ Resolve ( _central . Token ) ; // Tests expect this to be synchronous
70
+ //Task.Run(() => Resolve(_central.Token));
70
71
}
71
72
}
72
73
@@ -87,12 +88,23 @@ private void ReparseRequested(object sender, EventArgs e)
87
88
88
89
public void Parse ( )
89
90
{
90
- try
91
+ var projects = _vbe . VBProjects
92
+ . Cast < VBProject > ( )
93
+ . Where ( project => project . Protection == vbext_ProjectProtection . vbext_pp_none ) ;
94
+
95
+ var components = projects . SelectMany ( p => p . VBComponents . Cast < VBComponent > ( ) ) ;
96
+ // invalidation cleanup should go into ParseAsync?
97
+ foreach ( var invalidated in _componentAttributes . Keys . Except ( components ) )
91
98
{
92
- ParseAll ( ) ;
93
- } catch ( Exception e )
99
+ _componentAttributes . Remove ( invalidated ) ;
100
+ }
101
+
102
+ foreach ( var vbComponent in components )
94
103
{
95
- Debug . WriteLine ( e ) ;
104
+ while ( ! _state . ClearDeclarations ( vbComponent ) ) { }
105
+
106
+ // expects synchronous parse :/
107
+ ParseComponent ( vbComponent ) ;
96
108
}
97
109
}
98
110
@@ -185,6 +197,7 @@ private void ParseAsyncInternal(VBComponent component, CancellationToken token,
185
197
_state . AddParseTree ( component , e . ParseTree ) ;
186
198
_state . AddTokenStream ( component , e . Tokens ) ;
187
199
_state . SetModuleComments ( component , e . Comments ) ;
200
+
188
201
// This really needs to go last
189
202
_state . SetModuleState ( component , ParserState . Parsed ) ;
190
203
} ;
@@ -200,7 +213,9 @@ public void ParseComponent(VBComponent component, TokenStreamRewriter rewriter =
200
213
public void Resolve ( CancellationToken token )
201
214
{
202
215
var sharedTokenSource = CancellationTokenSource . CreateLinkedTokenSource ( _resolverTokenSource . Token , token ) ;
203
- Task . Run ( ( ) => ResolveInternal ( sharedTokenSource . Token ) ) ;
216
+ // tests expect this to be synchronous :/
217
+ //Task.Run(() => ResolveInternal(sharedTokenSource.Token));
218
+ ResolveInternal ( sharedTokenSource . Token ) ;
204
219
}
205
220
206
221
private void ResolveInternal ( CancellationToken token )
@@ -220,37 +235,43 @@ private void ResolveInternal(CancellationToken token)
220
235
221
236
private void ResolveDeclarations ( VBComponent component , IParseTree tree )
222
237
{
223
- // cannot locate declarations in one pass *the way it's currently implemented*,
224
- // because the context in EnterSubStmt() doesn't *yet* have child nodes when the context enters.
225
- // so we need to EnterAmbiguousIdentifier() and evaluate the parent instead - this *might* work.
226
- var declarations = new List < Declaration > ( ) ;
227
238
var qualifiedModuleName = new QualifiedModuleName ( component ) ;
228
- DeclarationSymbolsListener declarationsListener = new DeclarationSymbolsListener ( qualifiedModuleName , Accessibility . Implicit , component . Type , _state . GetModuleComments ( component ) , _state . getModuleAttributes ( component ) ) ;
229
- // TODO: should we unify the API? consider working like the other listeners instead of event-based
230
- declarationsListener . NewDeclaration += ( sender , e ) => _state . AddDeclaration ( e . Declaration ) ;
231
- declarationsListener . CreateModuleDeclarations ( ) ;
232
239
233
240
var obsoleteCallStatementListener = new ObsoleteCallStatementListener ( ) ;
234
241
var obsoleteLetStatementListener = new ObsoleteLetStatementListener ( ) ;
235
242
var emptyStringLiteralListener = new EmptyStringLiteralListener ( ) ;
236
243
var argListWithOneByRefParamListener = new ArgListWithOneByRefParamListener ( ) ;
244
+
245
+ try
246
+ {
247
+ var walker = new ParseTreeWalker ( ) ;
248
+ walker . Walk ( new CombinedParseTreeListener ( new IParseTreeListener [ ] {
249
+ obsoleteCallStatementListener ,
250
+ obsoleteLetStatementListener ,
251
+ emptyStringLiteralListener ,
252
+ argListWithOneByRefParamListener ,
253
+ } ) , tree ) ;
254
+ // FIXME this are actually (almost) isnpection results.. we should handle them as such
255
+ _state . ArgListsWithOneByRefParam = argListWithOneByRefParamListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
256
+ _state . EmptyStringLiterals = emptyStringLiteralListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
257
+ _state . ObsoleteLetContexts = obsoleteLetStatementListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
258
+ _state . ObsoleteCallContexts = obsoleteCallStatementListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
259
+
260
+ // cannot locate declarations in one pass *the way it's currently implemented*,
261
+ // because the context in EnterSubStmt() doesn't *yet* have child nodes when the context enters.
262
+ // so we need to EnterAmbiguousIdentifier() and evaluate the parent instead - this *might* work.
263
+ DeclarationSymbolsListener declarationsListener = new DeclarationSymbolsListener ( qualifiedModuleName , Accessibility . Implicit , component . Type , _state . GetModuleComments ( component ) , _state . getModuleAttributes ( component ) ) ;
264
+ // TODO: should we unify the API? consider working like the other listeners instead of event-based
265
+ declarationsListener . NewDeclaration += ( sender , e ) => _state . AddDeclaration ( e . Declaration ) ;
266
+ declarationsListener . CreateModuleDeclarations ( ) ;
267
+ // rewalk parse tree for second declaration level
268
+ walker . Walk ( declarationsListener , tree ) ;
269
+ } catch ( Exception exception )
270
+ {
271
+ Debug . Print ( "Exception thrown resolving '{0}' (thread {2}): {1}" , component . Name , exception , Thread . CurrentThread . ManagedThreadId ) ;
272
+ _state . SetModuleState ( component , ParserState . ResolverError ) ;
273
+ }
237
274
238
- // FIXME account for errors here
239
-
240
- var walker = new ParseTreeWalker ( ) ;
241
- walker . Walk ( new CombinedParseTreeListener ( new IParseTreeListener [ ] {
242
- obsoleteCallStatementListener ,
243
- obsoleteLetStatementListener ,
244
- emptyStringLiteralListener ,
245
- argListWithOneByRefParamListener ,
246
- declarationsListener ,
247
- } ) , tree ) ;
248
-
249
- // FIXME this are actually (almost) isnpection results.. we should handle them as such
250
- _state . ArgListsWithOneByRefParam = argListWithOneByRefParamListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
251
- _state . EmptyStringLiterals = emptyStringLiteralListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
252
- _state . ObsoleteLetContexts = obsoleteLetStatementListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
253
- _state . ObsoleteCallContexts = obsoleteCallStatementListener . Contexts . Select ( context => new QualifiedContext ( qualifiedModuleName , context ) ) ;
254
275
}
255
276
256
277
private void ResolveReferences ( DeclarationFinder finder , VBComponent component , IParseTree tree )
0 commit comments