public ValueTask <ImmutableArray <Diagnostic> > GetSourceGeneratorDiagnosticsAsync(SolutionState solution, CancellationToken cancellationToken)
 {
     // We can directly return the diagnostics from the underlying tracker; this is because
     // a generated document cannot have any diagnostics that are produced by a generator:
     // a generator cannot add diagnostics to it's own file outputs, and generators don't see the
     // outputs of each other.
     return(UnderlyingTracker.GetSourceGeneratorDiagnosticsAsync(solution, cancellationToken));
 }
 public SourceGeneratedDocumentState?TryGetSourceGeneratedDocumentStateForAlreadyGeneratedId(DocumentId documentId)
 {
     if (documentId == _replacedGeneratedDocumentState.Id)
     {
         return(_replacedGeneratedDocumentState);
     }
     else
     {
         return(UnderlyingTracker.TryGetSourceGeneratedDocumentStateForAlreadyGeneratedId(documentId));
     }
 }
            public async ValueTask <TextDocumentStates <SourceGeneratedDocumentState> > GetSourceGeneratedDocumentStatesAsync(SolutionState solution, CancellationToken cancellationToken)
            {
                var underlyingGeneratedDocumentStates = await UnderlyingTracker.GetSourceGeneratedDocumentStatesAsync(solution, cancellationToken).ConfigureAwait(false);

                if (underlyingGeneratedDocumentStates.Contains(_replacedGeneratedDocumentState.Id))
                {
                    // The generated file still exists in the underlying compilation, but the contents may not match the open file if the open file
                    // is stale. Replace the syntax tree so we have a tree that matches the text.
                    return(underlyingGeneratedDocumentStates.SetState(_replacedGeneratedDocumentState.Id, _replacedGeneratedDocumentState));
                }
                else
                {
                    // The generated output no longer exists in the underlying compilation. This could happen if the user made
                    // an edit which would cause this file to no longer exist, but they're still operating on an open representation
                    // of that file. To ensure that this snapshot is still usable, we'll just add this document back in. This is not a
                    // semantically correct operation, but working on stale snapshots never has that guarantee.
                    return(underlyingGeneratedDocumentStates.AddRange(ImmutableArray.Create(_replacedGeneratedDocumentState)));
                }
            }
            public async Task <Compilation> GetCompilationAsync(SolutionState solution, CancellationToken cancellationToken)
            {
                // Fast path if we've definitely already done this before
                if (_compilationWithReplacement != null)
                {
                    return(_compilationWithReplacement);
                }

                var underlyingCompilation = await UnderlyingTracker.GetCompilationAsync(solution, cancellationToken).ConfigureAwait(false);

                var underlyingSourceGeneratedDocuments = await UnderlyingTracker.GetSourceGeneratedDocumentStatesAsync(solution, cancellationToken).ConfigureAwait(false);

                underlyingSourceGeneratedDocuments.TryGetState(_replacedGeneratedDocumentState.Id, out var existingState);

                Compilation newCompilation;

                var newSyntaxTree = await _replacedGeneratedDocumentState.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                if (existingState != null)
                {
                    // The generated file still exists in the underlying compilation, but the contents may not match the open file if the open file
                    // is stale. Replace the syntax tree so we have a tree that matches the text.
                    var existingSyntaxTree = await existingState.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                    newCompilation = underlyingCompilation.ReplaceSyntaxTree(existingSyntaxTree, newSyntaxTree);
                }
                else
                {
                    // The existing output no longer exists in the underlying compilation. This could happen if the user made
                    // an edit which would cause this file to no longer exist, but they're still operating on an open representation
                    // of that file. To ensure that this snapshot is still usable, we'll just add this document back in. This is not a
                    // semantically correct operation, but working on stale snapshots never has that guarantee.
                    newCompilation = underlyingCompilation.AddSyntaxTrees(newSyntaxTree);
                }

                Interlocked.CompareExchange(ref _compilationWithReplacement, newCompilation, null);

                return(_compilationWithReplacement);
            }
 public Task <bool> HasSuccessfullyLoadedAsync(SolutionState solution, CancellationToken cancellationToken)
 {
     return(UnderlyingTracker.HasSuccessfullyLoadedAsync(solution, cancellationToken));
 }
 private async Task <Checksum> ComputeDependentChecksumAsync(SolutionState solution, CancellationToken cancellationToken)
 => Checksum.Create(
     await UnderlyingTracker.GetDependentChecksumAsync(solution, cancellationToken).ConfigureAwait(false),
     await _replacedGeneratedDocumentState.GetChecksumAsync(cancellationToken).ConfigureAwait(false));
 public Task <VersionStamp> GetDependentSemanticVersionAsync(SolutionState solution, CancellationToken cancellationToken)
 => UnderlyingTracker.GetDependentSemanticVersionAsync(solution, cancellationToken);