public ProcessedTokensDocument(TokensDocument previousStepSnapshot, DocumentVersion <IProcessedTokensLine> processedTokensLinesVersion, ISearchableReadOnlyList <IProcessedTokensLine> processedTokensLines) { TextSourceInfo = previousStepSnapshot.TextSourceInfo; PreviousStepSnapshot = previousStepSnapshot; CurrentVersion = processedTokensLinesVersion; Lines = processedTokensLines; }
// --- Document snapshots --- /// <summary> /// Creates a new snapshot of the document viewed as tokens BEFORE compiler directives processing. /// Thread-safe : this method can be called from any thread. /// </summary> public void RefreshTokensDocumentSnapshot() { // Make sure we don't update the document while taking a snapshot lock (lockObjectForDocumentLines) { // Create a new snapshot only if things changed since last snapshot if (TokensDocumentSnapshot == null || TokensDocumentSnapshot.CurrentVersion != currentTokensLinesVersion) { TokensDocumentSnapshot = new TokensDocument(TextSourceInfo, textLinesVersionForCurrentTokensLines, currentTokensLinesVersion, compilationDocumentLines.ToImmutable()); } } }
/// <summary> /// Creates a new snapshot of the document viewed as tokens AFTER compiler directives processing. /// (if the tokens lines changed since the last time this method was called) /// Thread-safe : this method can be called from any thread. /// </summary> public void RefreshProcessedTokensDocumentSnapshot() { // Make sure two threads don't try to update this snapshot at the same time lock (lockObjectForProcessedTokensDocumentSnapshot) { // Capture previous snapshots at one point in time TokensDocument tokensDocument = TokensDocumentSnapshot; ProcessedTokensDocument previousProcessedTokensDocument = ProcessedTokensDocumentSnapshot; // Check if an update is necessary and compute changes to apply since last version bool scanAllDocumentLines = false; IList <DocumentChange <ITokensLine> > tokensLineChanges = null; if (previousProcessedTokensDocument == null) { scanAllDocumentLines = true; } else if (tokensDocument.CurrentVersion == previousProcessedTokensDocument.PreviousStepSnapshot.CurrentVersion) { // Tokens lines did not change since last update => nothing to do return; } else { DocumentVersion <ITokensLine> previousTokensDocumentVersion = previousProcessedTokensDocument.PreviousStepSnapshot.CurrentVersion; tokensLineChanges = previousTokensDocumentVersion.GetReducedAndOrderedChangesInNewerVersion(tokensDocument.CurrentVersion); } // Start perf measurement var perfStatsForParserInvocation = PerfStatsForPreprocessor.OnStartRefreshParsingStep(); // Track all changes applied to the document while updating this snapshot DocumentChangedEvent <IProcessedTokensLine> documentChangedEvent = null; // Apply text changes to the compilation document if (scanAllDocumentLines) { if (tokensDocument != null) { // Process all lines of the document for the first time PreprocessorStep.ProcessDocument(TextSourceInfo, ((ImmutableList <CodeElementsLine>)tokensDocument.Lines), CompilerOptions, processedTokensDocumentProvider, CopyTextNamesVariations, perfStatsForParserInvocation, this.MissingCopies); // Create the first processed tokens document snapshot ProcessedTokensDocumentSnapshot = new ProcessedTokensDocument(tokensDocument, new DocumentVersion <IProcessedTokensLine>(this), ((ImmutableList <CodeElementsLine>)tokensDocument.Lines)); } } else { ImmutableList <CodeElementsLine> .Builder processedTokensDocumentLines = ((ImmutableList <CodeElementsLine>)tokensDocument.Lines).ToBuilder(); IList <DocumentChange <IProcessedTokensLine> > documentChanges = PreprocessorStep.ProcessTokensLinesChanges(TextSourceInfo, processedTokensDocumentLines, tokensLineChanges, PrepareDocumentLineForUpdate, CompilerOptions, processedTokensDocumentProvider, CopyTextNamesVariations, perfStatsForParserInvocation, this.MissingCopies); // Create a new version of the document to track these changes DocumentVersion <IProcessedTokensLine> currentProcessedTokensLineVersion = previousProcessedTokensDocument.CurrentVersion; currentProcessedTokensLineVersion.changes = documentChanges; currentProcessedTokensLineVersion.next = new DocumentVersion <IProcessedTokensLine>(currentProcessedTokensLineVersion); // Prepare an event to signal document change to all listeners documentChangedEvent = new DocumentChangedEvent <IProcessedTokensLine>(currentProcessedTokensLineVersion, currentProcessedTokensLineVersion.next); currentProcessedTokensLineVersion = currentProcessedTokensLineVersion.next; // Update the processed tokens document snapshot ProcessedTokensDocumentSnapshot = new ProcessedTokensDocument(tokensDocument, currentProcessedTokensLineVersion, processedTokensDocumentLines.ToImmutable()); } // Stop perf measurement PerfStatsForPreprocessor.OnStopRefresh(); // Send events to all listeners EventHandler <DocumentChangedEvent <IProcessedTokensLine> > processedTokensLinesChangedEventsSource = ProcessedTokensLinesChangedEventsSource; // avoid race condition if (documentChangedEvent != null && processedTokensLinesChangedEventsSource != null) { processedTokensLinesChangedEventsSource(this, documentChangedEvent); } } }