Esempio n. 1
0
        private void ExecuteCommonParseActivities(IReadOnlyCollection <QualifiedModuleName> toParse, IReadOnlyCollection <QualifiedModuleName> toReresolveReferencesInput, IReadOnlyCollection <string> newProjectIds, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            var toReresolveReferences = new HashSet <QualifiedModuleName>();

            toReresolveReferences.UnionWith(toReresolveReferencesInput);
            token.ThrowIfCancellationRequested();

            _parserStateManager.SetModuleStates(toParse, ParserState.Started, token);
            token.ThrowIfCancellationRequested();

            _parsingCacheService.ClearProjectWhoseCompilationArgumentsChanged();
            token.ThrowIfCancellationRequested();

            _parserStateManager.SetStatusAndFireStateChanged(this, ParserState.LoadingReference, token);
            token.ThrowIfCancellationRequested();

            _parsingStageService.SyncComReferences(token);
            if (_parsingStageService.LastSyncOfCOMReferencesLoadedReferences || _parsingStageService.COMReferencesUnloadedInLastSync.Any())
            {
                var unloadedReferences = _parsingStageService.COMReferencesUnloadedInLastSync.ToHashSet();
                var unloadedModules    =
                    _parsingCacheService.DeclarationFinder.AllModules
                    .Where(qmn => unloadedReferences.Contains(qmn.ProjectId))
                    .ToHashSet();
                var additionalModulesToBeReresolved = OtherModulesReferencingAnyNotToBeParsed(unloadedModules.AsReadOnly(), toParse);
                toReresolveReferences.UnionWith(additionalModulesToBeReresolved);
                _parserStateManager.SetModuleStates(additionalModulesToBeReresolved, ParserState.ResolvingReferences, token);
                ClearModuleToModuleReferences(unloadedModules);
                RefreshDeclarationFinder();
            }

            if (_parsingStageService.COMReferencesAffectedByPriorityChangesInLastSync.Any())
            {
                //We only use the referencedProjectId because that simplifies the reference management immensely.
                var affectedReferences = _parsingStageService.COMReferencesAffectedByPriorityChangesInLastSync
                                         .Select(tpl => tpl.referencedProjectId)
                                         .ToHashSet();
                var referenceModules =
                    _parsingCacheService.DeclarationFinder.AllModules
                    .Where(qmn => affectedReferences.Contains(qmn.ProjectId))
                    .ToHashSet();
                var additionalModulesToBeReresolved = OtherModulesReferencingAnyNotToBeParsed(referenceModules.AsReadOnly(), toParse);
                toReresolveReferences.UnionWith(additionalModulesToBeReresolved);
                _parserStateManager.SetModuleStates(additionalModulesToBeReresolved, ParserState.ResolvingReferences, token);
            }
            token.ThrowIfCancellationRequested();

            _parsingStageService.LoadBuitInDeclarations();
            if (newProjectIds.Any())
            {
                _parsingStageService.CreateProjectDeclarations(newProjectIds);
                RefreshDeclarationFinder();
            }
            if (_parsingStageService.LastLoadOfBuiltInDeclarationsLoadedDeclarations || newProjectIds.Any())
            {
                RefreshDeclarationFinder();
            }
            token.ThrowIfCancellationRequested();

            _parsingStageService.RefreshProjectReferences();
            token.ThrowIfCancellationRequested();

            IReadOnlyCollection <QualifiedModuleName> toResolveReferences;

            if (!toParse.Any())
            {
                toResolveReferences = toReresolveReferences.AsReadOnly();
            }
            else
            {
                toResolveReferences = ModulesForWhichToResolveReferences(toParse, toReresolveReferences);
                token.ThrowIfCancellationRequested();

                PerformPreParseCleanup(toResolveReferences, token);
                token.ThrowIfCancellationRequested();

                _parserStateManager.SetModuleStates(toParse, ParserState.Parsing, token);
                token.ThrowIfCancellationRequested();

                _parsingStageService.ParseModules(toParse, token);

                if (token.IsCancellationRequested || State.Status >= ParserState.Error)
                {
                    throw new OperationCanceledException(token);
                }

                _parserStateManager.EvaluateOverallParserState(token);

                if (token.IsCancellationRequested || State.Status >= ParserState.Error)
                {
                    throw new OperationCanceledException(token);
                }

                _parserStateManager.SetModuleStates(toParse, ParserState.ResolvingDeclarations, token);
                token.ThrowIfCancellationRequested();

                _parsingStageService.ResolveDeclarations(toParse, token);
            }

            if (token.IsCancellationRequested || State.Status >= ParserState.Error)
            {
                throw new OperationCanceledException(token);
            }

            //We need to refresh the DeclarationFinder before the handlers for ResolvedDeclarations run no matter
            //whether we parsed or resolved something because modules not referenced by any remeining module might
            //have been removed. E.g. the CodeExplorer needs this update.
            RefreshDeclarationFinder();
            token.ThrowIfCancellationRequested();

            //Explicitly setting the overall state here guarantees that the handlers attached
            //to the state change to ResolvedDeclarations always run, provided there is no error.
            _parserStateManager.SetStatusAndFireStateChanged(this, ParserState.ResolvedDeclarations, token);

            if (token.IsCancellationRequested || State.Status >= ParserState.Error)
            {
                throw new OperationCanceledException(token);
            }

            _parserStateManager.SetModuleStates(toResolveReferences, ParserState.ResolvingReferences, token);
            token.ThrowIfCancellationRequested();

            _parsingStageService.ResolveReferences(toResolveReferences, token);

            if (token.IsCancellationRequested || State.Status >= ParserState.Error)
            {
                throw new OperationCanceledException(token);
            }

            RefreshDeclarationFinder();
            token.ThrowIfCancellationRequested();

            //At this point all modules should either be in the Ready state or in an error state.
            //This is the point where the change of the overall state to Ready is triggered on the success path.
            _parserStateManager.EvaluateOverallParserState(token);
            token.ThrowIfCancellationRequested();
        }
        private void ExecuteCommonParseActivities(IReadOnlyCollection <QualifiedModuleName> toParse, IReadOnlyCollection <QualifiedModuleName> toReresolveReferencesInput, IReadOnlyCollection <string> newProjectIds, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            var toReresolveReferences = new HashSet <QualifiedModuleName>();

            toReresolveReferences.UnionWith(toReresolveReferencesInput);
            token.ThrowIfCancellationRequested();

            _parserStateManager.SetModuleStates(toParse, ParserState.Started, token);
            token.ThrowIfCancellationRequested();

            _parsingCacheService.ClearProjectWhoseCompilationArgumentsChanged();
            token.ThrowIfCancellationRequested();

            _parserStateManager.SetStatusAndFireStateChanged(this, ParserState.LoadingReference, token);
            token.ThrowIfCancellationRequested();

            ProcessUserComProjects(ref token, ref toParse, ref toReresolveReferences, ref newProjectIds);

            SyncComReferences(toParse, token, toReresolveReferences);
            token.ThrowIfCancellationRequested();

            _parsingStageService.LoadBuitInDeclarations();
            if (newProjectIds.Any())
            {
                _parsingStageService.CreateProjectDeclarations(newProjectIds);
                RefreshDeclarationFinder();
            }
            if (_parsingStageService.LastLoadOfBuiltInDeclarationsLoadedDeclarations || newProjectIds.Any())
            {
                RefreshDeclarationFinder();
            }
            token.ThrowIfCancellationRequested();

            _parsingStageService.RefreshProjectReferences();
            token.ThrowIfCancellationRequested();

            IReadOnlyCollection <QualifiedModuleName> toResolveReferences;

            if (!toParse.Any())
            {
                toResolveReferences = toReresolveReferences.AsReadOnly();
            }
            else
            {
                toResolveReferences = ModulesForWhichToResolveReferences(toParse, toReresolveReferences);
                token.ThrowIfCancellationRequested();

                PerformPreParseCleanup(toResolveReferences, token);
                token.ThrowIfCancellationRequested();

                _parserStateManager.SetModuleStates(toParse, ParserState.Parsing, token);
                token.ThrowIfCancellationRequested();

                _parsingStageService.ParseModules(toParse, token);

                if (token.IsCancellationRequested || State.Status >= ParserState.Error)
                {
                    throw new OperationCanceledException(token);
                }

                _parserStateManager.EvaluateOverallParserState(token);

                if (token.IsCancellationRequested || State.Status >= ParserState.Error)
                {
                    throw new OperationCanceledException(token);
                }

                _parserStateManager.SetModuleStates(toParse, ParserState.ResolvingDeclarations, token);
                token.ThrowIfCancellationRequested();

                _parsingStageService.ResolveDeclarations(toParse, token);
            }

            if (token.IsCancellationRequested || State.Status >= ParserState.Error)
            {
                throw new OperationCanceledException(token);
            }

            //We need to refresh the DeclarationFinder before the handlers for ResolvedDeclarations run no matter
            //whether we parsed or resolved something because modules not referenced by any remaining module might
            //have been removed. E.g. the CodeExplorer needs this update.
            RefreshDeclarationFinder();
            token.ThrowIfCancellationRequested();

            //Explicitly setting the overall state here guarantees that the handlers attached
            //to the state change to ResolvedDeclarations always run, provided there is no error.
            _parserStateManager.SetStatusAndFireStateChanged(this, ParserState.ResolvedDeclarations, token);

            if (token.IsCancellationRequested || State.Status >= ParserState.Error)
            {
                throw new OperationCanceledException(token);
            }

            _parserStateManager.SetModuleStates(toResolveReferences, ParserState.ResolvingReferences, token);
            token.ThrowIfCancellationRequested();

            _parsingStageService.ResolveReferences(toResolveReferences, token);

            if (token.IsCancellationRequested || State.Status >= ParserState.Error)
            {
                throw new OperationCanceledException(token);
            }

            RefreshDeclarationFinder();
            token.ThrowIfCancellationRequested();

            //At this point all modules should either be in the Ready state or in an error state.
            //This is the point where the change of the overall state to Ready is triggered on the success path.
            _parserStateManager.EvaluateOverallParserState(token);
            token.ThrowIfCancellationRequested();
        }