Exemple #1
0
        private async Task PopulateWorkspaceFromDeferredProjectInfoAsync(
            CancellationToken cancellationToken)
        {
            // NOTE: We need to check cancellationToken after each await, in case the user has
            // already closed the solution.
            AssertIsForeground();

            var componentModel = _serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel;
            var workspaceProjectContextFactory = componentModel.GetService <IWorkspaceProjectContextFactory>();

            var dte            = _serviceProvider.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
            var solutionConfig = (EnvDTE80.SolutionConfiguration2)dte.Solution.SolutionBuild.ActiveConfiguration;

            OutputToOutputWindow($"Getting project information - start");
            var start = DateTimeOffset.UtcNow;

            var projectInfos = SpecializedCollections.EmptyReadOnlyDictionary <string, DeferredProjectInformation>();

            // Note that `solutionConfig` may be null. For example: if the solution doesn't actually
            // contain any projects.
            if (solutionConfig != null)
            {
                // Capture the context so that we come back on the UI thread, and do the actual project creation there.
                var deferredProjectWorkspaceService = _workspaceServices.GetService <IDeferredProjectWorkspaceService>();
                projectInfos = await deferredProjectWorkspaceService.GetDeferredProjectInfoForConfigurationAsync(
                    $"{solutionConfig.Name}|{solutionConfig.PlatformName}",
                    cancellationToken).ConfigureAwait(true);
            }

            AssertIsForeground();
            cancellationToken.ThrowIfCancellationRequested();
            OutputToOutputWindow($"Getting project information - done (took {DateTimeOffset.UtcNow - start})");

            OutputToOutputWindow($"Creating projects - start");
            start = DateTimeOffset.UtcNow;
            var targetPathsToProjectPaths = BuildTargetPathMap(projectInfos);
            var analyzerAssemblyLoader    = _workspaceServices.GetRequiredService <IAnalyzerService>().GetLoader();

            foreach (var projectFilename in projectInfos.Keys)
            {
                cancellationToken.ThrowIfCancellationRequested();
                GetOrCreateProjectFromArgumentsAndReferences(
                    workspaceProjectContextFactory,
                    analyzerAssemblyLoader,
                    projectFilename,
                    projectInfos,
                    targetPathsToProjectPaths);
            }
            OutputToOutputWindow($"Creating projects - done (took {DateTimeOffset.UtcNow - start})");

            OutputToOutputWindow($"Pushing to workspace - start");
            start = DateTimeOffset.UtcNow;
            FinishLoad();
            OutputToOutputWindow($"Pushing to workspace - done (took {DateTimeOffset.UtcNow - start})");
        }
Exemple #2
0
 private async Task <ActiveStatementsMap> GetBaseActiveStatementsAsync(CancellationToken cancellationToken)
 {
     try
     {
         return(CreateActiveStatementsMap(_baseSolution, await _activeStatementProvider.GetActiveStatementsAsync(cancellationToken).ConfigureAwait(false)));
     }
     catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e))
     {
         return(new ActiveStatementsMap(
                    SpecializedCollections.EmptyReadOnlyDictionary <DocumentId, ImmutableArray <ActiveStatement> >(),
                    SpecializedCollections.EmptyReadOnlyDictionary <ActiveInstructionId, ActiveStatement>()));
     }
 }
        private async Task PopulateWorkspaceFromDeferredProjectInfoAsync(
            CancellationToken cancellationToken)
        {
            // NOTE: We need to check cancellationToken after each await, in case the user has
            // already closed the solution.
            AssertIsForeground();

            var start          = DateTimeOffset.UtcNow;
            var dte            = _serviceProvider.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
            var solutionConfig = (EnvDTE80.SolutionConfiguration2)dte.Solution.SolutionBuild.ActiveConfiguration;

            OutputToOutputWindow($"Getting project information - start");

            var projectInfos = SpecializedCollections.EmptyReadOnlyDictionary <string, DeferredProjectInformation>();

            // Note that `solutionConfig` may be null. For example: if the solution doesn't actually
            // contain any projects.
            if (solutionConfig != null)
            {
                // Capture the context so that we come back on the UI thread, and do the actual project creation there.
                var deferredProjectWorkspaceService = _workspaceServices.GetService <IDeferredProjectWorkspaceService>();
                projectInfos = await deferredProjectWorkspaceService.GetDeferredProjectInfoForConfigurationAsync(
                    $"{solutionConfig.Name}|{solutionConfig.PlatformName}",
                    cancellationToken).ConfigureAwait(true);
            }

            AssertIsForeground();
            cancellationToken.ThrowIfCancellationRequested();
            OutputToOutputWindow($"Getting project information - done (took {DateTimeOffset.UtcNow - start})");

            ForceLoadProjectsWhoseDesignTimeBuildFailed(projectInfos);

            CreateDeferredProjects(projectInfos, cancellationToken);

            CallWithTimingLog("Pushing to workspace", FinishLoad);
        }
Exemple #4
0
        /// <summary>
        /// Calculate the set of changes up to top-level types. The result
        /// will be used as a filter when traversing the module.
        ///
        /// Note that these changes only include user-defined source symbols, not synthesized symbols since those will be
        /// generated during lowering of the changed user-defined symbols.
        /// </summary>
        private static void CalculateChanges(IEnumerable <SemanticEdit> edits, out IReadOnlyDictionary <ISymbol, SymbolChange> changes, out ISet <ISymbol> replaceSymbols, out IReadOnlyDictionary <ISymbol, ISet <ISymbol> > deletedMembers)
        {
            var changesBuilder = new Dictionary <ISymbol, SymbolChange>();
            HashSet <ISymbol>?lazyReplaceSymbolsBuilder = null;
            Dictionary <ISymbol, ISet <ISymbol> >?lazyDeletedMembersBuilder = null;

            foreach (var edit in edits)
            {
                SymbolChange change;

                switch (edit.Kind)
                {
                case SemanticEditKind.Update:
                    change = SymbolChange.Updated;
                    break;

                case SemanticEditKind.Insert:
                    change = SymbolChange.Added;
                    break;

                case SemanticEditKind.Replace:
                    Debug.Assert(edit.NewSymbol != null);
                    (lazyReplaceSymbolsBuilder ??= new HashSet <ISymbol>()).Add(edit.NewSymbol);
                    change = SymbolChange.Added;
                    break;

                case SemanticEditKind.Delete:
                    // We allow method deletions only at the moment.
                    // For deletions NewSymbol is actually containing symbol
                    if (edit.OldSymbol is IMethodSymbol && edit.NewSymbol is { } newContainingSymbol)
                    {
                        Debug.Assert(edit.OldSymbol != null);
                        lazyDeletedMembersBuilder ??= new();
                        if (!lazyDeletedMembersBuilder.TryGetValue(newContainingSymbol, out var set))
                        {
                            set = new HashSet <ISymbol>();
                            lazyDeletedMembersBuilder.Add(newContainingSymbol, set);
                        }
                        set.Add(edit.OldSymbol);
                        // We need to make sure we track the containing type of the member being
                        // deleted, from the new compilation, in case the deletion is the only change.
                        if (!changesBuilder.ContainsKey(newContainingSymbol))
                        {
                            changesBuilder.Add(newContainingSymbol, SymbolChange.ContainsChanges);
                            AddContainingTypesAndNamespaces(changesBuilder, newContainingSymbol);
                        }
                    }
                    continue;

                default:
                    throw ExceptionUtilities.UnexpectedValue(edit.Kind);
                }

                var member = edit.NewSymbol;
                RoslynDebug.AssertNotNull(member);

                // Partial methods are supplied as implementations but recorded
                // internally as definitions since definitions are used in emit.
                if (member.Kind == SymbolKind.Method)
                {
                    var method = (IMethodSymbol)member;

                    // Partial methods should be implementations, not definitions.
                    Debug.Assert(method.PartialImplementationPart == null);
                    Debug.Assert((edit.OldSymbol == null) || (((IMethodSymbol)edit.OldSymbol).PartialImplementationPart == null));

                    var definitionPart = method.PartialDefinitionPart;
                    if (definitionPart != null)
                    {
                        member = definitionPart;
                    }
                }

                AddContainingTypesAndNamespaces(changesBuilder, member);
                changesBuilder.Add(member, change);
            }

            changes        = changesBuilder;
            replaceSymbols = lazyReplaceSymbolsBuilder ?? SpecializedCollections.EmptySet <ISymbol>();
            deletedMembers = lazyDeletedMembersBuilder ?? SpecializedCollections.EmptyReadOnlyDictionary <ISymbol, ISet <ISymbol> >();
        }