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);