private void ProcessComponentParseResults(QualifiedModuleName module, Task <ComponentParseTask.ParseCompletionArgs> finishedParseTask, CancellationToken token) { if (finishedParseTask.IsFaulted) { //In contrast to the situation in the success scenario, the overall parser state is reevaluated immediately. //This sets the state directly on the state because it is the sole instance where we have to pass the potential SyntaxErorException. _state.SetModuleState(module, ParserState.Error, token, finishedParseTask.Exception?.InnerException as SyntaxErrorException); } else { var result = finishedParseTask.Result; lock (_state) { token.ThrowIfCancellationRequested(); //This has to come first because it creates the module state if not present. _state.SetModuleAttributes(module, result.Attributes); _state.AddTokenStream(module, result.Tokens); _state.AddParseTree(module, result.ParseTree); _state.AddParseTree(module, result.AttributesTree, ParsePass.AttributesPass); _state.SetModuleComments(module, result.Comments); _state.SetModuleAnnotations(module, result.Annotations); _state.AddAttributesRewriter(module, result.AttributesRewriter); // This really needs to go last //It does not reevaluate the overall parer state to avoid concurrent evaluation of all module states and for performance reasons. //The evaluation has to be triggered manually in the calling procedure. StateManager.SetModuleState(module, ParserState.Parsed, token, false); //Note that this is ok because locks allow re-entrancy. } } }