public AbstractRecoverableSyntaxRoot(
                AbstractSyntaxTreeFactoryService service,
                string filePath,
                ParseOptions options,
                ValueSource <TextAndVersion> text,
                TRoot root)
            {
                System.Diagnostics.Debug.Assert(service != null);
                System.Diagnostics.Debug.Assert(filePath != null);
                System.Diagnostics.Debug.Assert(options != null);
                System.Diagnostics.Debug.Assert(text != null);
                System.Diagnostics.Debug.Assert(root != null);

                this.service    = service;
                this.filePath   = filePath;
                this.options    = options;
                this.textSource = text;
                this.length     = root.FullSpan.Length;

                this.syntaxTreeCache = WorkspaceServices.GetService <ISyntaxTreeCacheService>();
                System.Diagnostics.Debug.Assert(this.syntaxTreeCache != null);

                this.evictAction = new WeakAction <AbstractRecoverableSyntaxRoot <TRoot>, SyntaxNode>(this, (r, d) => r.OnEvicted(d));

                this.rootSource = new ConstantValueSource <TRoot>(root);
            }
Пример #2
0
 public static string GetTestFolder()
 {
     if (_testFolder == null)
     {
         _testFolder = WorkspaceServices.WorkspacePath("db4oj.tests/test");
     }
     return(_testFolder);
 }
Пример #3
0
 protected virtual string[] Libraries()
 {
     if (true)
     {
         return(Db4oMigrationSuiteBuilder.All);
     }
     if (true)
     {
         // run against specific libraries + the current one
         string javaPath = "db4o.archives/java1.2/db4o-5.7-java1.2.jar";
         string netPath  = "db4o.archives/net-2.0/7.4/Db4objects.Db4o.dll";
         return(new string[] { WorkspaceServices.WorkspacePath(javaPath) });
     }
     return(Db4oMigrationSuiteBuilder.Current);
 }
Пример #4
0
        private void CreateDeferredProjects(IReadOnlyDictionary <string, DeferredProjectInformation> projectInfos, CancellationToken cancellationToken)
        {
            AssertIsForeground();

            OutputToOutputWindow($"Creating projects - start");
            var start = DateTimeOffset.UtcNow;

            var targetPathsToProjectPaths = BuildTargetPathMap(projectInfos);

            var solution7 = (IVsSolution7)_vsSolution;
            var analyzerAssemblyLoader         = WorkspaceServices.GetRequiredService <IAnalyzerService>().GetLoader();
            var componentModel                 = _serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel;
            var workspaceProjectContextFactory = componentModel.GetService <IWorkspaceProjectContextFactory>();

            foreach (var(projectFilename, projectInfo) in projectInfos)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (!solution7.IsDeferredProjectLoadAllowed(projectFilename))
                {
                    OutputToOutputWindow($"\tSkipping non-deferred project: '{projectFilename}'");
                }
                else if (DesignTimeBuildFailed(projectInfo))
                {
                    OutputToOutputWindow($"\tSkipping failed design time build project: '{projectFilename}'");
                }
                else
                {
                    GetOrCreateProjectFromArgumentsAndReferences(
                        workspaceProjectContextFactory,
                        analyzerAssemblyLoader,
                        projectFilename,
                        projectInfos,
                        targetPathsToProjectPaths);
                }
            }

            OutputToOutputWindow($"Creating projects - done (took {DateTimeOffset.UtcNow - start})");
        }
Пример #5
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 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);
        }
Пример #6
0
 private string SourceFile()
 {
     return(WorkspaceServices.WorkspaceTestFilePath("db4oVersions/db4o_3.0.3"));
 }
Пример #7
0
        private AbstractProject GetOrCreateProjectFromArgumentsAndReferences(
            IWorkspaceProjectContextFactory workspaceProjectContextFactory,
            IAnalyzerAssemblyLoader analyzerAssemblyLoader,
            string projectFilename,
            IReadOnlyDictionary <string, DeferredProjectInformation> allProjectInfos,
            IReadOnlyDictionary <string, string> targetPathsToProjectPaths)
        {
            var languageName = GetLanguageOfProject(projectFilename);

            if (languageName == null)
            {
                return(null);
            }

            if (!allProjectInfos.TryGetValue(projectFilename, out var projectInfo))
            {
                // This could happen if we were called recursively about a dangling P2P reference
                // that isn't actually in the solution.
                return(null);
            }

            // TODO: Should come from .sln file?
            var projectName = PathUtilities.GetFileName(projectFilename, includeExtension: false);

            // `AbstractProject` only sets the filename if it actually exists.  Since we want
            // our ids to match, mimic that behavior here.
            var projectId = File.Exists(projectFilename)
                ? GetOrCreateProjectIdForPath(projectFilename, projectName)
                : GetOrCreateProjectIdForPath(projectName, projectName);

            // See if something has already created this project - it's not deferred, the AnyCode design time build
            // failed so we force loaded it, or we already created a deferred project and we're in a recursive call
            // to find a ProjectReference
            if (_projectMap.TryGetValue(projectId, out var project))
            {
                return(project);
            }

            // If the project system has opted this project out of deferred loading, or AnyCode
            // was unable to get command line info for it, we can't create a project for it.
            // NOTE: We need to check this even though it happened in CreateDeferredProjects
            // because we could be in a recursive call from a project reference below.
            var solution7 = (IVsSolution7)_vsSolution;

            if (DesignTimeBuildFailed(projectInfo) ||
                !solution7.IsDeferredProjectLoadAllowed(projectFilename))
            {
                return(null);
            }

            var commandLineParser    = WorkspaceServices.GetLanguageServices(languageName).GetService <ICommandLineParserService>();
            var projectDirectory     = PathUtilities.GetDirectoryName(projectFilename);
            var commandLineArguments = commandLineParser.Parse(
                projectInfo.CommandLineArguments,
                projectDirectory,
                isInteractive: false,
                sdkDirectory: RuntimeEnvironment.GetRuntimeDirectory());

            OutputToOutputWindow($"\tCreating '{projectName}':\t{commandLineArguments.SourceFiles.Length} source files,\t{commandLineArguments.MetadataReferences.Length} references.");

            var projectGuid    = GetProjectGuid(projectFilename);
            var projectContext = workspaceProjectContextFactory.CreateProjectContext(
                languageName,
                projectName,
                projectFilename,
                projectGuid: projectGuid,
                hierarchy: null,
                binOutputPath: projectInfo.TargetPath);

            project = (AbstractProject)projectContext;
            projectContext.SetOptions(projectInfo.CommandLineArguments.Join(" "));

            var addedSourceFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (var sourceFile in commandLineArguments.SourceFiles)
            {
                if (addedSourceFilePaths.Add(sourceFile.Path))
                {
                    projectContext.AddSourceFile(sourceFile.Path);
                }
            }

            var addedAdditionalFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (var additionalFile in commandLineArguments.AdditionalFiles)
            {
                if (addedAdditionalFilePaths.Add(additionalFile.Path))
                {
                    projectContext.AddAdditionalFile(additionalFile.Path);
                }
            }

            var metadataReferences     = commandLineArguments.ResolveMetadataReferences(project.CurrentCompilationOptions.MetadataReferenceResolver).AsImmutable();
            var addedProjectReferences = new HashSet <string>();

            foreach (var projectReferencePath in projectInfo.ReferencedProjectFilePaths)
            {
                var referencedProject = TryFindExistingProjectForProjectReference(projectReferencePath, metadataReferences);
                if (referencedProject == null)
                {
                    referencedProject = GetOrCreateProjectFromArgumentsAndReferences(
                        workspaceProjectContextFactory,
                        analyzerAssemblyLoader,
                        projectReferencePath,
                        allProjectInfos,
                        targetPathsToProjectPaths);
                }

                var referencedProjectContext = referencedProject as IWorkspaceProjectContext;
                if (referencedProjectContext != null)
                {
                    // TODO: Can we get the properties from corresponding metadata reference in
                    // commandLineArguments?
                    addedProjectReferences.Add(projectReferencePath);
                    projectContext.AddProjectReference(
                        referencedProjectContext,
                        new MetadataReferenceProperties());
                }
                else if (referencedProject != null)
                {
                    // This project was already created by the regular project system. See if we
                    // can find the matching project somehow.
                    var existingReferenceOutputPath = referencedProject?.BinOutputPath;
                    if (existingReferenceOutputPath != null)
                    {
                        addedProjectReferences.Add(projectReferencePath);
                        projectContext.AddMetadataReference(
                            existingReferenceOutputPath,
                            new MetadataReferenceProperties());
                    }
                }
                else
                {
                    // We don't know how to create this project.  Another language or something?
                    OutputToOutputWindow($"\t\tFailed to create a project for '{projectReferencePath}'.");
                }
            }

            var addedReferencePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (var reference in metadataReferences)
            {
                var path = GetReferencePath(reference);
                if (targetPathsToProjectPaths.TryGetValue(path, out var possibleProjectReference) &&
                    addedProjectReferences.Contains(possibleProjectReference))
                {
                    // We already added a P2P reference for this, we don't need to add the file reference too.
                    continue;
                }

                if (addedReferencePaths.Add(path))
                {
                    projectContext.AddMetadataReference(path, reference.Properties);
                }
            }

            var addedAnalyzerPaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (var reference in commandLineArguments.ResolveAnalyzerReferences(analyzerAssemblyLoader))
            {
                var path = reference.FullPath;
                if (!PathUtilities.IsAbsolute(path))
                {
                    path = PathUtilities.CombineAbsoluteAndRelativePaths(
                        projectDirectory,
                        path);
                }

                if (addedAnalyzerPaths.Add(path))
                {
                    projectContext.AddAnalyzerReference(path);
                }
            }

            return((AbstractProject)projectContext);
        }
Пример #8
0
        /// <summary>
        /// Starts pushing events from the given projects to the workspace hosts and notifies about open documents.
        /// </summary>
        /// <remarks>This method must be called on the foreground thread.</remarks>
        internal void StartPushingToWorkspaceAndNotifyOfOpenDocuments(IEnumerable <AbstractProject> projects)
        {
            AssertIsForeground();

            // If the solution is closing we shouldn't do anything, because all of our state is
            // in the process of going away. This can happen if we receive notification that a document has
            // opened in the middle of the solution close operation.
            if (_solutionIsClosing)
            {
                return;
            }

            // We need to push these projects and any project dependencies we already know about. Therefore, compute the
            // transitive closure of the projects that haven't already been pushed, keeping them in appropriate order.
            var visited       = new HashSet <AbstractProject>();
            var inOrderToPush = new List <AbstractProject>();

            void addToInOrderToPush(AbstractProject project)
            {
                Contract.ThrowIfFalse(ContainsProject(project));

                // Bail out if any of the following is true:
                //  1. We have already started pushing changes for this project OR
                //  2. We have already visited this project in a prior recursive call
                if (_pushedProjects.Contains(project) || !visited.Add(project))
                {
                    return;
                }

                foreach (var projectReference in project.GetCurrentProjectReferences())
                {
                    addToInOrderToPush(GetProject(projectReference.ProjectId));
                }

                inOrderToPush.Add(project);
            }

            foreach (var project in projects)
            {
                addToInOrderToPush(project);
            }

            var projectInfos = inOrderToPush.Select(p => p.CreateProjectInfoForCurrentState()).ToImmutableArray();

            // We need to enable projects to start pushing changes to the workspace even before we add the solution/project to the host.
            // This is required because between the point we capture the project info for current state and the point where we start pushing to the workspace,
            // project system may send new events on the AbstractProject on a background thread, and these won't get pushed over to the workspace hosts as we didn't set the _pushingChangesToWorkspaceHost flag on the AbstractProject.
            // By invoking StartPushingToWorkspaceHosts upfront, any project state changes on the background thread will enqueue notifications to workspace hosts on foreground scheduled tasks.
            foreach (var project in inOrderToPush)
            {
                project.PushingChangesToWorkspace = true;

                Logger.Log(FunctionId.AbstractProject_PushedToWorkspace,
                           KeyValueLogMessage.Create(LogType.Trace, m =>
                {
                    m[AbstractProject.ProjectGuidPropertyName] = project.Guid;
                }));
            }

            using (WorkspaceServices.GetService <IGlobalOperationNotificationService>()?.Start("Add Project to Workspace"))
            {
                if (!_solutionAdded)
                {
                    string       solutionFilePath = null;
                    VersionStamp?version          = default;
                    // Figure out the solution version
                    if (ErrorHandler.Succeeded(_vsSolution.GetSolutionInfo(out var solutionDirectory, out var solutionFileName, out var userOptsFile)) && solutionFileName != null)
                    {
                        solutionFilePath = Path.Combine(solutionDirectory, solutionFileName);
                        if (File.Exists(solutionFilePath))
                        {
                            version = VersionStamp.Create(File.GetLastWriteTimeUtc(solutionFilePath));
                        }
                    }

                    if (version == null)
                    {
                        version = VersionStamp.Create();
                    }

                    var id = SolutionId.CreateNewId(string.IsNullOrWhiteSpace(solutionFileName) ? null : solutionFileName);

                    var solutionInfo = SolutionInfo.Create(id, version.Value, solutionFilePath, projects: projectInfos);

                    NotifyWorkspace(workspace => workspace.OnSolutionAdded(solutionInfo));

                    _solutionAdded = true;

                    var persistenceService = WorkspaceServices.GetRequiredService <IPersistentStorageLocationService>() as VisualStudioPersistentStorageLocationService;
                    persistenceService?.UpdateForVisualStudioWorkspace(_workspace);
                }
                else
                {
                    // The solution is already added, so we'll just do project added notifications from here
                    foreach (var projectInfo in projectInfos)
                    {
                        NotifyWorkspace(workspace => workspace.OnProjectAdded(projectInfo));
                    }
                }

                foreach (var project in inOrderToPush)
                {
                    _pushedProjects.Add(project);

                    foreach (var document in project.GetCurrentDocuments())
                    {
                        if (document.IsOpen)
                        {
                            NotifyWorkspace(workspace =>
                            {
                                workspace.OnDocumentOpened(
                                    document.Id,
                                    document.GetOpenTextBuffer().AsTextContainer(),
                                    isCurrentContext: LinkedFileUtilities.IsCurrentContextHierarchy(document, _runningDocumentTable));
                                (workspace as VisualStudioWorkspaceImpl)?.ConnectToSharedHierarchyEvents(document);
                            });
                        }
                    }
                }
            }
        }
Пример #9
0
 private static string DbFilePath()
 {
     return(WorkspaceServices.WorkspaceTestFilePath("db4oVersions/db4o_5.5.2.db4o"));
 }
Пример #10
0
 private static string OriginalFilePath()
 {
     return(WorkspaceServices.WorkspaceTestFilePath("db4oVersions/db4o_5.5.2"));
 }
Пример #11
0
        //override protected string[] Libraries()
        //{
        //    return new string[] { AssemblyPathFor("7.9") };
        //}

        private string AssemblyPathFor(string version)
        {
            return(WorkspaceServices.WorkspacePath("db4o.archives/net-2.0/" + version + "/Db4objects.Db4o.dll"));
        }
Пример #12
0
 public static string LibraryPath()
 {
     return(WorkspaceServices.WorkspacePath("db4o.archives/net-2.0"));
 }