Example #1
0
 /// <summary>
 /// Close the open solution, and reset the workspace to a new empty solution.
 /// </summary>
 public void CloseSolution()
 {
     using (_serializationLock.DisposableWait())
     {
         this.ClearSolution();
     }
 }
 /// <summary>
 /// Associates a project file extension with a language name.
 /// </summary>
 public void AssociateFileExtensionWithLanguage(string fileExtension, string language)
 {
     using (_dataGuard.DisposableWait())
     {
         _extensionToLanguageMap[fileExtension] = language;
     }
 }
        internal CodeModelProjectCache GetCodeModelCache()
        {
            Contract.ThrowIfNull(_vsProject);
            Contract.ThrowIfNull(_visualStudioWorkspace);

            using (_guard.DisposableWait())
            {
                if (_codeModelCache == null)
                {
                    var project = _visualStudioWorkspace.CurrentSolution.GetProject(_vsProject.Id);
                    if (project == null && !_vsProject.PushingChangesToWorkspaceHosts)
                    {
                        // if this project hasn't been pushed yet, push it now so that the user gets a useful experience here.
                        _vsProject.StartPushingToWorkspaceAndNotifyOfOpenDocuments();

                        // re-check to see whether we now has the project in the workspace
                        project = _visualStudioWorkspace.CurrentSolution.GetProject(_vsProject.Id);
                    }

                    if (project != null)
                    {
                        _codeModelCache = new CodeModelProjectCache(_vsProject, _serviceProvider, project.LanguageServices, _visualStudioWorkspace);
                    }
                }

                return(_codeModelCache);
            }
        }
Example #4
0
        private CodeModelProjectCache GetCodeModelCache()
        {
            Contract.ThrowIfNull(_projectId);
            Contract.ThrowIfNull(_visualStudioWorkspace);

            using (_guard.DisposableWait())
            {
                if (_codeModelCache == null)
                {
                    var workspaceProject = _visualStudioWorkspace.CurrentSolution.GetProject(_projectId);
                    var hostProject      = _visualStudioWorkspace.GetHostProject(_projectId);
                    if (workspaceProject == null && !hostProject.PushingChangesToWorkspace)
                    {
                        // if this project hasn't been pushed yet, push it now so that the user gets a useful experience here.
                        hostProject.StartPushingToWorkspaceAndNotifyOfOpenDocuments();

                        // re-check to see whether we now has the project in the workspace
                        workspaceProject = _visualStudioWorkspace.CurrentSolution.GetProject(_projectId);
                    }

                    if (workspaceProject != null)
                    {
                        _codeModelCache = new CodeModelProjectCache(_threadingContext, _projectId, _codeModelInstanceFactory, _serviceProvider, workspaceProject.LanguageServices, _visualStudioWorkspace);
                    }
                }

                return(_codeModelCache);
            }
        }
                public MetadataReference GetAddOrUpdate(string path, MetadataReferenceProperties properties)
                {
                    using (_gate.DisposableWait())
                    {
                        WeakReference <MetadataReference> weakref;
                        MetadataReference mref = null;

                        if (!(_references.TryGetValue(properties, out weakref) && weakref.TryGetTarget(out mref)))
                        {
                            // try to base this metadata reference off of an existing one, so we don't load the metadata bytes twice.
                            foreach (var wr in _references.Values)
                            {
                                if (wr.TryGetTarget(out mref))
                                {
                                    mref = mref.WithProperties(properties);
                                    break;
                                }
                            }

                            if (mref == null)
                            {
                                mref = _cache._createReference(path, properties);
                            }

                            _references[properties] = new WeakReference <MetadataReference>(mref);
                        }

                        return(mref);
                    }
                }
        private Task?EnsureInstanceIsSavedAsync(T instance)
        {
            if (_weakReference == null)
            {
                _weakReference = new WeakReference <T>(instance);
            }
            else
            {
                _weakReference.SetTarget(instance);
            }

            if (!_saved)
            {
                _saved = true;
                using (s_taskGuard.DisposableWait())
                {
                    // force all save tasks to be in sequence so we don't hog all the threads
                    s_latestTask = s_latestTask.SafeContinueWithFromAsync(t =>
                                                                          SaveAsync(instance, CancellationToken.None), CancellationToken.None, TaskScheduler.Default);
                    return(s_latestTask);
                }
            }

            return(null);
        }
        private async void OnEvicted(T instance)
        {
            if (!saved)
            {
                using (await this.Gate.DisposableWaitAsync(CancellationToken.None).ConfigureAwait(false))
                {
                    if (!saved)
                    {
                        Task saveTask;

                        using (taskGuard.DisposableWait())
                        {
                            // force all save tasks to be in sequence so we don't hog all the threads
                            saveTask = latestTask = latestTask.SafeContinueWith <Task>(t =>
                                                                                       this.SaveAsync(instance, CancellationToken.None), CancellationToken.None, TaskScheduler.Default).Unwrap();
                        }

                        // wait for this save to be done
                        await saveTask.ConfigureAwait(false);

                        this.saved = true;
                    }
                }
            }
        }
Example #8
0
        private CodeModelProjectCache GetCodeModelCache()
        {
            Contract.ThrowIfNull(_projectId);
            Contract.ThrowIfNull(_visualStudioWorkspace);

            using (_guard.DisposableWait())
            {
                if (_codeModelCache == null)
                {
                    var workspaceProject = _visualStudioWorkspace.CurrentSolution.GetProject(
                        _projectId
                        );

                    if (workspaceProject != null)
                    {
                        _codeModelCache = new CodeModelProjectCache(
                            _threadingContext,
                            _projectId,
                            _codeModelInstanceFactory,
                            _projectCodeModelFactory,
                            _serviceProvider,
                            workspaceProject.LanguageServices,
                            _visualStudioWorkspace
                            );
                    }
                }

                return(_codeModelCache);
            }
        }
Example #9
0
            public MetadataReference GetMetadataReference(Compilation compilation, ImmutableArray <string> aliases, bool embedInteropTypes)
            {
                var key = new MetadataReferenceProperties(MetadataImageKind.Assembly, aliases, embedInteropTypes);

                using (gate.DisposableWait())
                {
                    WeakReference <MetadataReference> weakMetadata;
                    MetadataReference metadataReference;
                    if (!metadataReferences.TryGetValue(key, out weakMetadata) || !weakMetadata.TryGetTarget(out metadataReference))
                    {
                        // here we give out strong reference to compilation. so there is possibility that we end up making 2 compilations for same project alive.
                        // one for final compilation and one for declaration only compilation. but the final compilation will be eventually kicked out from compilation cache
                        // if there is no activity on the project. or the declaration compilation will go away if the project that depends on the reference doesn't have any
                        // activity when it is kicked out from compilation cache. if there is an activity, then both will updated as activity happens.
                        // so simply put, things will go away when compilations are kicked out from the cache or due to user activity.
                        //
                        // there is one case where we could have 2 compilations for same project alive. if a user opens a file that requires a skeleton assembly when the skeleton
                        // assembly project didn't reach the final stage yet and then the user opens another document that is part of the skeleton assembly project
                        // and then never change it. declaration compilation will be alive by skeleton assembly and final compilation will be alive by background compiler.
                        metadataReference            = this.image.CreateReference(aliases, embedInteropTypes, new DeferredDocumentationProvider(compilation));
                        weakMetadata                 = new WeakReference <MetadataReference>(metadataReference);
                        this.metadataReferences[key] = weakMetadata;
                    }

                    return(metadataReference);
                }
            }
Example #10
0
        private Task EnsureInstanceIsSaved(T instance)
        {
            if (this.weakInstance == NoReference)
            {
                this.weakInstance = new WeakReference <T>(instance);
            }
            else
            {
                this.weakInstance.SetTarget(instance);
            }

            if (!saved)
            {
                this.saved = true;
                using (taskGuard.DisposableWait())
                {
                    // force all save tasks to be in sequence so we don't hog all the threads
                    latestTask = latestTask.SafeContinueWithFromAsync(t =>
                                                                      this.SaveAsync(instance, CancellationToken.None), CancellationToken.None, TaskScheduler.Default);
                    return(latestTask);
                }
            }
            else
            {
                return(null);
            }
        }
Example #11
0
        /// <summary>
        /// Associates a project file extension with a language name.
        /// </summary>
        public void AssociateFileExtensionWithLanguage(string projectFileExtension, string language)
        {
            if (language == null)
            {
                throw new ArgumentNullException(nameof(language));
            }

            if (projectFileExtension == null)
            {
                throw new ArgumentNullException(nameof(projectFileExtension));
            }

            using (_dataGuard.DisposableWait())
            {
                _extensionToLanguageMap[projectFileExtension] = language;
            }
        }
Example #12
0
 protected static Task SaveTreeAsync(SyntaxNode root, ITemporaryStorage storage)
 {
     using (taskGuard.DisposableWait())
     {
         // force all save tasks to be in sequence
         latestTask = latestTask.SafeContinueWith(t => SaveTreeWorkerAsync(root, storage, CancellationToken.None), CancellationToken.None, TaskScheduler.Default).Unwrap();
         return(latestTask);
     }
 }
Example #13
0
        public IAsyncToken BeginAsyncOperation(string name, object tag = null, [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0)
        {
            using (_gate.DisposableWait(CancellationToken.None))
            {
                IAsyncToken asyncToken;
                if (_trackActiveTokens)
                {
                    var token = new DiagnosticAsyncToken(this, name, tag, filePath, lineNumber);
                    _diagnosticTokenList.Add(token);
                    asyncToken = token;
                }
                else
                {
                    asyncToken = new AsyncToken(this);
                }

                return(asyncToken);
            }
        }
Example #14
0
        public void AddProject(ProjectId projectId, string projectName, string language = LanguageNames.CSharp)
        {
            using (_serializationLock.DisposableWait())
            {
                var oldSolution = this.CurrentSolution;
                var newSolution = this.SetCurrentSolution(oldSolution.AddProject(projectId, projectName, projectName, language));

                this.RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.ProjectAdded, oldSolution, newSolution, projectId);
            }
        }
Example #15
0
        /// <summary>
        /// Gets the list of projects (topologically sorted) that directly depend on this project.
        /// </summary>
        public IImmutableSet <ProjectId> GetProjectsThatDirectlyDependOnThisProject(ProjectId projectId)
        {
            if (projectId == null)
            {
                throw new ArgumentNullException(nameof(projectId));
            }

            if (_lazyReverseReferencesMap == null)
            {
                using (_dataLock.DisposableWait())
                {
                    return(this.GetProjectsThatDirectlyDependOnThisProject_NoLock(projectId));
                }
            }
            else
            {
                // okay, because its only ever going to be computed and assigned once
                return(this.GetProjectsThatDirectlyDependOnThisProject_NoLock(projectId));
            }
        }
Example #16
0
                private static void ClearQueueWorker <TKey, TValue>(NonReentrantLock gate, Dictionary <TKey, TValue> map, Func <TValue, IDisposable> disposerSelector)
                {
                    using (gate.DisposableWait(CancellationToken.None))
                    {
                        foreach (var(_, data) in map)
                        {
                            disposerSelector?.Invoke(data)?.Dispose();
                        }

                        map.Clear();
                    }
                }
Example #17
0
                private static TValue DequeueWorker <TKey, TValue>(NonReentrantLock gate, Dictionary <TKey, TValue> map, CancellationToken cancellationToken)
                {
                    using (gate.DisposableWait(cancellationToken))
                    {
                        var first = default(KeyValuePair <TKey, TValue>);
                        foreach (var kv in map)
                        {
                            first = kv;
                            break;
                        }

                        // this is only one that removes data from the queue. so, it should always succeed
                        var result = map.Remove(first.Key);
                        Debug.Assert(result);

                        return(first.Value);
                    }
                }
Example #18
0
        /// <summary>
        /// Loads the <see cref="SolutionInfo"/> for the specified solution file, including all projects referenced by the solution file and
        /// all the projects referenced by the project files.
        /// </summary>
        /// <param name="solutionFilePath">The path to the solution file to be loaded. This may be an absolute path or a path relative to the
        /// current working directory.</param>
        /// <param name="progress">An optional <see cref="IProgress{T}"/> that will receive updates as the solution is loaded.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> to allow cancellation of this operation.</param>
        public async Task <SolutionInfo> LoadSolutionInfoAsync(
            string solutionFilePath,
            IProgress <ProjectLoadProgress> progress = null,
            CancellationToken cancellationToken      = default)
        {
            if (solutionFilePath == null)
            {
                throw new ArgumentNullException(nameof(solutionFilePath));
            }

            if (!_pathResolver.TryGetAbsoluteSolutionPath(solutionFilePath, baseDirectory: Directory.GetCurrentDirectory(), DiagnosticReportingMode.Throw, out var absoluteSolutionPath))
            {
                // TryGetAbsoluteSolutionPath should throw before we get here.
                return(null);
            }

            using (_dataGuard.DisposableWait(cancellationToken))
            {
                this.SetSolutionProperties(absoluteSolutionPath);
            }

            var solutionFile = MSB.Construction.SolutionFile.Parse(absoluteSolutionPath);

            var reportingMode = GetReportingModeForUnrecognizedProjects();

            var reportingOptions = new DiagnosticReportingOptions(
                onPathFailure: reportingMode,
                onLoaderFailure: reportingMode);

            var projectPaths = ImmutableArray.CreateBuilder <string>();

            // load all the projects
            foreach (var project in solutionFile.ProjectsInOrder)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (project.ProjectType != MSB.Construction.SolutionProjectType.SolutionFolder)
                {
                    projectPaths.Add(project.RelativePath);
                }
            }

            var buildManager = new ProjectBuildManager(_properties);

            var worker = new Worker(
                _workspaceServices,
                _diagnosticReporter,
                _pathResolver,
                _projectFileLoaderRegistry,
                buildManager,
                projectPaths.ToImmutable(),
                baseDirectory: Path.GetDirectoryName(absoluteSolutionPath),
                _properties,
                projectMap: null,
                progress,
                requestedProjectOptions: reportingOptions,
                discoveredProjectOptions: reportingOptions,
                preferMetadataForReferencesOfDiscoveredProjects: false);

            var projects = await worker.LoadAsync(cancellationToken).ConfigureAwait(false);

            // construct workspace from loaded project infos
            return(SolutionInfo.Create(
                       SolutionId.CreateNewId(debugName: absoluteSolutionPath),
                       version: default,