@@ -179,8 +179,7 @@ private void ParseAll()
179
179
State . SetStatusAndFireStateChanged ( _state . Status ) ;
180
180
return ;
181
181
}
182
-
183
-
182
+
184
183
lock ( _state ) // note, method is invoked from UI thread... really need the lock here?
185
184
{
186
185
foreach ( var component in toParse )
@@ -192,9 +191,6 @@ private void ParseAll()
192
191
// note: seting to 'Parsed' would include them in the resolver walk. 'Ready' excludes them.
193
192
_state . SetModuleState ( component , ParserState . Ready ) ;
194
193
}
195
-
196
- //Debug.Assert(unchanged.All(component => _state.GetModuleState(component) == ParserState.Ready));
197
- //Debug.Assert(toParse.All(component => _state.GetModuleState(component) == ParserState.Pending));
198
194
}
199
195
200
196
// invalidation cleanup should go into ParseAsync?
@@ -206,18 +202,65 @@ private void ParseAll()
206
202
}
207
203
}
208
204
209
- var parseTasks = new Task [ components . Count ] ;
210
- for ( var i = 0 ; i < components . Count ; i ++ )
205
+ _projectDeclarations . Clear ( ) ;
206
+ _state . ClearBuiltInReferences ( ) ;
207
+
208
+ var parseTasks = new Task [ toParse . Count ] ;
209
+ for ( var i = 0 ; i < toParse . Count ; i ++ )
211
210
{
212
- parseTasks [ i ] = ParseAsync ( components [ i ] , CancellationToken . None ) ;
211
+ var index = i ;
212
+ parseTasks [ i ] = new Task ( ( ) =>
213
+ {
214
+ ParseAsync ( toParse [ index ] , CancellationToken . None ) . Wait ( ) ;
215
+
216
+ if ( _resolverTokenSource . IsCancellationRequested || _central . IsCancellationRequested )
217
+ {
218
+ return ;
219
+ }
220
+
221
+ if ( _state . Status == ParserState . Error ) { return ; }
222
+
223
+ var qualifiedName = new QualifiedModuleName ( toParse [ index ] ) ;
224
+ Logger . Debug ( "Module '{0}' {1}" , qualifiedName . ComponentName ,
225
+ _state . IsNewOrModified ( qualifiedName ) ? "was modified" : "was NOT modified" ) ;
226
+
227
+ _state . SetModuleState ( toParse [ index ] , ParserState . Resolving ) ;
228
+ ResolveDeclarations ( qualifiedName . Component ,
229
+ _state . ParseTrees . Find ( s => s . Key == qualifiedName ) . Value ) ;
230
+ } ) ;
231
+
232
+ parseTasks [ i ] . Start ( ) ;
213
233
}
214
234
215
235
Task . WaitAll ( parseTasks ) ;
236
+ _state . SetStatusAndFireStateChanged ( ParserState . ResolvedDeclarations ) ;
216
237
217
- if ( _state . Status != ParserState . Error )
238
+ if ( _state . Status < ParserState . Error )
218
239
{
219
- Logger . Trace ( "Starting resolver task" ) ;
220
- Resolve ( _central . Token ) ;
240
+ ResolveReferencesAsync ( ) ;
241
+ }
242
+ }
243
+
244
+ private void ResolveReferencesAsync ( )
245
+ {
246
+ var finder = new DeclarationFinder ( _state . AllDeclarations , _state . AllComments , _state . AllAnnotations ) ;
247
+ var passes = new List < ICompilationPass >
248
+ {
249
+ // This pass has to come first because the type binding resolution depends on it.
250
+ new ProjectReferencePass ( finder ) ,
251
+ new TypeHierarchyPass ( finder , new VBAExpressionParser ( ) ) ,
252
+ new TypeAnnotationPass ( finder , new VBAExpressionParser ( ) )
253
+ } ;
254
+ passes . ForEach ( p => p . Execute ( ) ) ;
255
+
256
+ foreach ( var kvp in _state . ParseTrees )
257
+ {
258
+ if ( _resolverTokenSource . IsCancellationRequested || _central . IsCancellationRequested )
259
+ {
260
+ return ;
261
+ }
262
+
263
+ Task . Run ( ( ) => ResolveReferences ( finder , kvp . Key . Component , kvp . Value ) ) ;
221
264
}
222
265
}
223
266
@@ -584,7 +627,7 @@ private Declaration CreateProjectDeclaration(QualifiedModuleName projectQualifie
584
627
private void ResolveReferences ( DeclarationFinder finder , VBComponent component , IParseTree tree )
585
628
{
586
629
var state = _state . GetModuleState ( component ) ;
587
- if ( _state . Status == ParserState . ResolverError || ( state != ParserState . Parsed ) )
630
+ if ( state != ParserState . Resolving )
588
631
{
589
632
return ;
590
633
}
0 commit comments