private void SignupForTextChanges(DocumentId documentId, SourceTextContainer textContainer, bool isCurrentContext, Action<Workspace, DocumentId, SourceText, PreservationMode> onChangedHandler) { var tracker = new TextTracker(this, documentId, textContainer, onChangedHandler); _textTrackers.Add(documentId, tracker); this.UpdateCurrentContextMapping_NoLock(textContainer, documentId, isCurrentContext); tracker.Connect(); }
protected internal void OnDocumentOpened(DocumentId documentId, SourceTextContainer textContainer, bool isCurrentContext = true) { CheckDocumentIsInCurrentSolution(documentId); CheckDocumentIsClosed(documentId); using (this.serializationLock.DisposableWait()) { var oldSolution = this.CurrentSolution; var oldDocument = oldSolution.GetDocument(documentId); var oldText = oldDocument.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None); using (this.stateLock.DisposableWrite()) { var openDocuments = GetProjectOpenDocuments_NoLock(documentId.ProjectId); if (openDocuments != null) { openDocuments.Add(documentId); } else { this.projectToOpenDocumentsMap.Add(documentId.ProjectId, new HashSet <DocumentId> { documentId }); } } // keep open document text alive by using PreserveIdentity var newText = textContainer.CurrentText; var currentSolution = oldSolution; if (oldText != newText) { if (oldText.ContentEquals(newText)) { // if the supplied text is the same as the previous text, then add with same version var version = oldDocument.GetTextVersionAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None); var newTextAndVersion = TextAndVersion.Create(newText, version, oldDocument.FilePath); currentSolution = oldSolution.WithDocumentText(documentId, newTextAndVersion, PreservationMode.PreserveIdentity); } else { currentSolution = oldSolution.WithDocumentText(documentId, newText, PreservationMode.PreserveIdentity); } } var newSolution = this.SetCurrentSolution(currentSolution); var tracker = new TextTracker(this, documentId, textContainer); this.textTrackers.Add(documentId, tracker); this.AddTextToDocumentIdMapping_NoLock(textContainer, documentId, isCurrentContext); tracker.Connect(); var newDoc = newSolution.GetDocument(documentId); this.OnDocumentTextChanged(newDoc); this.RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.DocumentChanged, oldSolution, newSolution, documentId: documentId); var tsk = this.RaiseDocumentOpenedEventAsync(newDoc); // don't await this } // register outside of lock since it may call user code. this.RegisterText(textContainer); }