Beispiel #1
0
 private AsyncLazy <VersionStamp> CreateLazyLatestDocumentTopLevelChangeVersion(
     TextDocumentState newDocument,
     TextDocumentStates <DocumentState> newDocumentStates,
     TextDocumentStates <TextDocumentState> newAdditionalDocumentStates
     )
 {
     if (_lazyLatestDocumentTopLevelChangeVersion.TryGetValue(out var oldVersion))
     {
         return(new AsyncLazy <VersionStamp>(
                    c => ComputeTopLevelChangeTextVersionAsync(oldVersion, newDocument, c),
                    cacheResult: true
                    ));
     }
     else
     {
         return(new AsyncLazy <VersionStamp>(
                    c =>
                    ComputeLatestDocumentTopLevelChangeVersionAsync(
                        newDocumentStates,
                        newAdditionalDocumentStates,
                        c
                        ),
                    cacheResult: true
                    ));
     }
 }
Beispiel #2
0
        public ProjectState UpdateAdditionalDocument(TextDocumentState newDocument, bool textChanged, bool recalculateDependentVersions)
        {
            Contract.Requires(this.ContainsAdditionalDocument(newDocument.Id));

            var oldDocument = this.GetAdditionalDocumentState(newDocument.Id);

            if (oldDocument == newDocument)
            {
                return(this);
            }

            var newDocumentStates = this.AdditionalDocumentStates.SetItem(newDocument.Id, newDocument);

            AsyncLazy <VersionStamp> dependentDocumentVersion;
            AsyncLazy <VersionStamp> dependentSemanticVersion;

            GetLatestDependentVersions(
                this.documentStates, newDocumentStates, oldDocument, newDocument, recalculateDependentVersions, textChanged,
                out dependentDocumentVersion, out dependentSemanticVersion);

            return(this.With(
                       additionalDocumentStates: newDocumentStates,
                       latestDocumentVersion: dependentDocumentVersion,
                       latestDocumentTopLevelChangeVersion: dependentSemanticVersion));
        }
Beispiel #3
0
        internal TextDocument(Project project, TextDocumentState state)
        {
            Contract.ThrowIfNull(project);
            Contract.ThrowIfNull(state);

            this.Project = project;
            State = state;
        }
Beispiel #4
0
        internal TextDocument(Project project, TextDocumentState state)
        {
            Contract.ThrowIfNull(project);
            Contract.ThrowIfNull(state);

            this.Project = project;
            State        = state;
        }
#pragma warning restore IDE0052 // Remove unread private members

                public TouchAdditionalDocumentAction(
                    TextDocumentState oldState,
                    TextDocumentState newState
                    )
                {
                    _oldState = oldState;
                    _newState = newState;
                }
Beispiel #6
0
        public ProjectState AddAdditionalDocument(TextDocumentState document)
        {
            Debug.Assert(!this.AdditionalDocumentStates.ContainsKey(document.Id));

            return(this.With(
                       projectInfo: this.ProjectInfo.WithVersion(this.Version.GetNewerVersion()),
                       additionalDocumentIds: _additionalDocumentIds.Add(document.Id),
                       additionalDocumentStates: _additionalDocumentStates.Add(document.Id, document)));
        }
        public bool HasTextChanged(TextDocumentState oldState, bool ignoreUnchangeableDocument)
        {
            if (ignoreUnchangeableDocument && !oldState.CanApplyChange())
            {
                return(false);
            }

            return(oldState.TextAndVersionSource != TextAndVersionSource);
        }
Beispiel #8
0
        public ProjectState AddAdditionalDocument(TextDocumentState document)
        {
            Contract.Requires(!this.AdditionalDocumentStates.ContainsKey(document.Id));

            return(this.With(
                       projectInfo: this.ProjectInfo.WithVersion(this.Version.GetNewerVersion()).WithAdditionalDocuments(this.ProjectInfo.AdditionalDocuments.Concat(document.Info)),
                       additionalDocumentIds: this.AdditionalDocumentIds.ToImmutableArray().Add(document.Id),
                       additionalDocumentStates: this.AdditionalDocumentStates.Add(document.Id, document)));
        }
Beispiel #9
0
        private static async Task <VersionStamp> ComputeTopLevelChangeTextVersionAsync(
            VersionStamp oldVersion,
            TextDocumentState newDocument,
            CancellationToken cancellationToken
            )
        {
            var newVersion = await newDocument
                             .GetTopLevelChangeTextVersionAsync(cancellationToken)
                             .ConfigureAwait(false);

            return(newVersion.GetNewerVersion(oldVersion));
        }
Beispiel #10
0
        private AsyncLazy <VersionStamp> CreateLazyLatestDocumentTopLevelChangeVersion(
            TextDocumentState newDocument,
            ImmutableDictionary <DocumentId, DocumentState> newDocumentStates,
            ImmutableDictionary <DocumentId, TextDocumentState> newAdditionalDocumentStates)
        {
            VersionStamp oldVersion;

            if (this.lazyLatestDocumentTopLevelChangeVersion.TryGetValue(out oldVersion))
            {
                return(new AsyncLazy <VersionStamp>(c => ComputeTopLevelChangeTextVersionAsync(oldVersion, newDocument, c), cacheResult: true));
            }
            else
            {
                return(new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(newDocumentStates, newAdditionalDocumentStates, c), cacheResult: true));
            }
        }
Beispiel #11
0
        private void GetLatestDependentVersions(
            ImmutableDictionary <DocumentId, DocumentState> newDocumentStates,
            ImmutableDictionary <DocumentId, TextDocumentState> newAdditionalDocumentStates,
            TextDocumentState oldDocument, TextDocumentState newDocument,
            bool recalculateDependentVersions, bool textChanged,
            out AsyncLazy <VersionStamp> dependentDocumentVersion, out AsyncLazy <VersionStamp> dependentSemanticVersion)
        {
            var recalculateDocumentVersion = false;
            var recalculateSemanticVersion = false;

            if (recalculateDependentVersions)
            {
                VersionStamp oldVersion;
                if (oldDocument.TryGetTextVersion(out oldVersion))
                {
                    VersionStamp documentVersion;
                    if (!this.lazyLatestDocumentVersion.TryGetValue(out documentVersion) || documentVersion == oldVersion)
                    {
                        recalculateDocumentVersion = true;
                    }

                    VersionStamp semanticVersion;
                    if (!this.lazyLatestDocumentTopLevelChangeVersion.TryGetValue(out semanticVersion) || semanticVersion == oldVersion)
                    {
                        recalculateSemanticVersion = true;
                    }
                }
            }

            dependentDocumentVersion = recalculateDocumentVersion ?
                                       new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(newDocumentStates, newAdditionalDocumentStates, c), cacheResult: true) :
                                       textChanged ?
                                       new AsyncLazy <VersionStamp>(newDocument.GetTextVersionAsync, cacheResult: true) :
                                       this.lazyLatestDocumentVersion;

            dependentSemanticVersion = recalculateSemanticVersion ?
                                       new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(newDocumentStates, newAdditionalDocumentStates, c), cacheResult: true) :
                                       textChanged?
                                       CreateLazyLatestDocumentTopLevelChangeVersion(newDocument, newDocumentStates, newAdditionalDocumentStates) :
                                           this.lazyLatestDocumentTopLevelChangeVersion;
        }
Beispiel #12
0
        public ProjectState UpdateAdditionalDocument(TextDocumentState newDocument, bool textChanged, bool recalculateDependentVersions)
        {
            Debug.Assert(this.ContainsAdditionalDocument(newDocument.Id));

            var oldDocument = this.GetAdditionalDocumentState(newDocument.Id) !;

            if (oldDocument == newDocument)
            {
                return(this);
            }

            var newDocumentStates = _additionalDocumentStates.SetItem(newDocument.Id, newDocument);

            GetLatestDependentVersions(
                _documentStates, newDocumentStates, oldDocument, newDocument, recalculateDependentVersions, textChanged,
                out var dependentDocumentVersion, out var dependentSemanticVersion);

            return(this.With(
                       additionalDocumentStates: newDocumentStates,
                       latestDocumentVersion: dependentDocumentVersion,
                       latestDocumentTopLevelChangeVersion: dependentSemanticVersion));
        }
        public ProjectState UpdateAdditionalDocument(TextDocumentState newDocument, bool textChanged, bool recalculateDependentVersions)
        {
            Contract.Requires(this.ContainsAdditionalDocument(newDocument.Id));

            var oldDocument = this.GetAdditionalDocumentState(newDocument.Id);
            if (oldDocument == newDocument)
            {
                return this;
            }

            var newDocumentStates = this.AdditionalDocumentStates.SetItem(newDocument.Id, newDocument);

            AsyncLazy<VersionStamp> dependentDocumentVersion;
            AsyncLazy<VersionStamp> dependentSemanticVersion;
            GetLatestDependentVersions(
                _documentStates, newDocumentStates, oldDocument, newDocument, recalculateDependentVersions, textChanged,
                out dependentDocumentVersion, out dependentSemanticVersion);

            return this.With(
                additionalDocumentStates: newDocumentStates,
                latestDocumentVersion: dependentDocumentVersion,
                latestDocumentTopLevelChangeVersion: dependentSemanticVersion);
        }
Beispiel #14
0
        internal ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices)
        {
            Contract.ThrowIfNull(projectInfo);
            Contract.ThrowIfNull(languageServices);
            Contract.ThrowIfNull(solutionServices);

            this.languageServices = languageServices;
            this.solutionServices = solutionServices;

            this.projectInfo = FixProjectInfo(projectInfo);

            this.documentIds           = this.projectInfo.Documents.Select(d => d.Id).ToImmutableArray();
            this.additionalDocumentIds = this.ProjectInfo.AdditionalDocuments.Select(d => d.Id).ToImmutableArray();

            var docStates = ImmutableDictionary.CreateRange <DocumentId, DocumentState>(
                this.projectInfo.Documents.Select(d =>
                                                  new KeyValuePair <DocumentId, DocumentState>(d.Id,
                                                                                               CreateDocument(this.ProjectInfo, d, languageServices, solutionServices))));

            this.documentStates = docStates;

            var additionalDocStates = ImmutableDictionary.CreateRange <DocumentId, TextDocumentState>(
                this.projectInfo.AdditionalDocuments.Select(d =>
                                                            new KeyValuePair <DocumentId, TextDocumentState>(d.Id, TextDocumentState.Create(d, solutionServices))));

            this.additionalDocumentStates = additionalDocStates;

            this.lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true);
            this.lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true);
        }
 public bool HasInfoChanged(TextDocumentState oldState)
 => oldState.Attributes != Attributes;
 public bool HasInfoChanged(TextDocumentState oldState)
 {
     return(oldState.Attributes != Attributes);
 }
 private AsyncLazy<VersionStamp> CreateLazyLatestDocumentTopLevelChangeVersion(
     TextDocumentState newDocument,
     ImmutableDictionary<DocumentId, DocumentState> newDocumentStates,
     ImmutableDictionary<DocumentId, TextDocumentState> newAdditionalDocumentStates)
 {
     VersionStamp oldVersion;
     if (_lazyLatestDocumentTopLevelChangeVersion.TryGetValue(out oldVersion))
     {
         return new AsyncLazy<VersionStamp>(c => ComputeTopLevelChangeTextVersionAsync(oldVersion, newDocument, c), cacheResult: true);
     }
     else
     {
         return new AsyncLazy<VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(newDocumentStates, newAdditionalDocumentStates, c), cacheResult: true);
     }
 }
Beispiel #18
0
        private SolutionState WithTextDocumentState(TextDocumentState newDocument, bool textChanged = false, bool recalculateDependentVersions = false)
        {
            if (newDocument == null)
            {
                throw new ArgumentNullException(nameof(newDocument));
            }

            CheckContainsAdditionalDocument(newDocument.Id);

            if (newDocument == this.GetAdditionalDocumentState(newDocument.Id))
            {
                // old and new documents are the same instance
                return this;
            }

            var oldProject = this.GetProjectState(newDocument.Id.ProjectId);
            var newProject = oldProject.UpdateAdditionalDocument(newDocument, textChanged, recalculateDependentVersions);

            if (oldProject == newProject)
            {
                // old and new projects are the same instance
                return this;
            }

            return this.ForkProject(newProject);
        }
Beispiel #19
0
        private Solution AddAdditionalDocument(TextDocumentState state)
        {
            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }

            CheckContainsProject(state.Id.ProjectId);

            var oldProject = this.GetProjectState(state.Id.ProjectId);
            var newProject = oldProject.AddAdditionalDocument(state);

            return this.ForkProject(newProject);
        }
Beispiel #20
0
        public ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices)
        {
            Contract.ThrowIfNull(projectInfo);
            Contract.ThrowIfNull(languageServices);
            Contract.ThrowIfNull(solutionServices);

            _languageServices = languageServices;
            _solutionServices = solutionServices;

            var projectInfoFixed = FixProjectInfo(projectInfo);

            _documentIds           = projectInfoFixed.Documents.Select(d => d.Id).ToImmutableList();
            _additionalDocumentIds = projectInfoFixed.AdditionalDocuments.Select(d => d.Id).ToImmutableList();

            var parseOptions = projectInfoFixed.ParseOptions;
            var docStates    = ImmutableSortedDictionary.CreateRange(DocumentIdComparer.Instance,
                                                                     projectInfoFixed.Documents.Select(d =>
                                                                                                       new KeyValuePair <DocumentId, DocumentState>(d.Id,
                                                                                                                                                    CreateDocument(d, parseOptions, languageServices, solutionServices))));

            _documentStates = docStates;

            var additionalDocStates = ImmutableSortedDictionary.CreateRange(DocumentIdComparer.Instance,
                                                                            projectInfoFixed.AdditionalDocuments.Select(d =>
                                                                                                                        new KeyValuePair <DocumentId, TextDocumentState>(d.Id, TextDocumentState.Create(d, solutionServices))));

            _additionalDocumentStates = additionalDocStates;

            _lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true);
            _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true);

            // ownership of information on document has moved to project state. clear out documentInfo the state is
            // holding on. otherwise, these information will be held onto unnecesarily by projectInfo even after
            // the info has changed by DocumentState.
            // we hold onto the info so that we don't need to duplicate all information info already has in the state
            _projectInfo = ClearAllDocumentsFromProjectInfo(projectInfoFixed);

            _lazyChecksums = new AsyncLazy <ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true);
        }
 private static async Task<VersionStamp> ComputeTopLevelChangeTextVersionAsync(VersionStamp oldVersion, TextDocumentState newDocument, CancellationToken cancellationToken)
 {
     var newVersion = await newDocument.GetTopLevelChangeTextVersionAsync(cancellationToken).ConfigureAwait(false);
     return newVersion.GetNewerVersion(oldVersion);
 }
        public ProjectState AddAdditionalDocument(TextDocumentState document)
        {
            Contract.Requires(!this.AdditionalDocumentStates.ContainsKey(document.Id));

            return this.With(
                projectInfo: this.ProjectInfo.WithVersion(this.Version.GetNewerVersion()).WithAdditionalDocuments(this.ProjectInfo.AdditionalDocuments.Concat(document.Info)),
                additionalDocumentIds: this.AdditionalDocumentIds.ToImmutableArray().Add(document.Id),
                additionalDocumentStates: this.AdditionalDocumentStates.Add(document.Id, document));
        }
        private void GetLatestDependentVersions(
            ImmutableDictionary<DocumentId, DocumentState> newDocumentStates,
            ImmutableDictionary<DocumentId, TextDocumentState> newAdditionalDocumentStates,
            TextDocumentState oldDocument, TextDocumentState newDocument,
            bool recalculateDependentVersions, bool textChanged,
            out AsyncLazy<VersionStamp> dependentDocumentVersion, out AsyncLazy<VersionStamp> dependentSemanticVersion)
        {
            var recalculateDocumentVersion = false;
            var recalculateSemanticVersion = false;

            if (recalculateDependentVersions)
            {
                VersionStamp oldVersion;
                if (oldDocument.TryGetTextVersion(out oldVersion))
                {
                    VersionStamp documentVersion;
                    if (!_lazyLatestDocumentVersion.TryGetValue(out documentVersion) || documentVersion == oldVersion)
                    {
                        recalculateDocumentVersion = true;
                    }

                    VersionStamp semanticVersion;
                    if (!_lazyLatestDocumentTopLevelChangeVersion.TryGetValue(out semanticVersion) || semanticVersion == oldVersion)
                    {
                        recalculateSemanticVersion = true;
                    }
                }
            }

            dependentDocumentVersion = recalculateDocumentVersion ?
                new AsyncLazy<VersionStamp>(c => ComputeLatestDocumentVersionAsync(newDocumentStates, newAdditionalDocumentStates, c), cacheResult: true) :
                textChanged ?
                    new AsyncLazy<VersionStamp>(newDocument.GetTextVersionAsync, cacheResult: true) :
                    _lazyLatestDocumentVersion;

            dependentSemanticVersion = recalculateSemanticVersion ?
                new AsyncLazy<VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(newDocumentStates, newAdditionalDocumentStates, c), cacheResult: true) :
                textChanged ?
                    CreateLazyLatestDocumentTopLevelChangeVersion(newDocument, newDocumentStates, newAdditionalDocumentStates) :
                    _lazyLatestDocumentTopLevelChangeVersion;
        }
Beispiel #24
0
        public ProjectState(ProjectInfo projectInfo, HostLanguageServices languageServices, SolutionServices solutionServices)
        {
            Contract.ThrowIfNull(projectInfo);
            Contract.ThrowIfNull(languageServices);
            Contract.ThrowIfNull(solutionServices);

            _languageServices = languageServices;
            _solutionServices = solutionServices;

            _projectInfo = FixProjectInfo(projectInfo);

            _documentIds           = _projectInfo.Documents.Select(d => d.Id).ToImmutableArray();
            _additionalDocumentIds = _projectInfo.AdditionalDocuments.Select(d => d.Id).ToImmutableArray();

            var docStates = ImmutableDictionary.CreateRange <DocumentId, DocumentState>(
                _projectInfo.Documents.Select(d =>
                                              new KeyValuePair <DocumentId, DocumentState>(d.Id,
                                                                                           CreateDocument(_projectInfo, d, languageServices, solutionServices))));

            _documentStates = docStates;

            var additionalDocStates = ImmutableDictionary.CreateRange <DocumentId, TextDocumentState>(
                _projectInfo.AdditionalDocuments.Select(d =>
                                                        new KeyValuePair <DocumentId, TextDocumentState>(d.Id, TextDocumentState.Create(d, solutionServices))));

            _additionalDocumentStates = additionalDocStates;

            _lazyLatestDocumentVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentVersionAsync(docStates, additionalDocStates, c), cacheResult: true);
            _lazyLatestDocumentTopLevelChangeVersion = new AsyncLazy <VersionStamp>(c => ComputeLatestDocumentTopLevelChangeVersionAsync(docStates, additionalDocStates, c), cacheResult: true);

            // for now, let it re-calculate if anything changed.
            // TODO: optimize this so that we only re-calcuate checksums that are actually changed
            _lazyChecksums = new AsyncLazy <ProjectStateChecksums>(ComputeChecksumsAsync, cacheResult: true);
        }