Skip to content

Commit

Permalink
Merge branch 'fixMerge2' into testConsistency2
Browse files Browse the repository at this point in the history
  • Loading branch information
CyrusNajmabadi committed Sep 12, 2022
2 parents c35952b + 1a57252 commit e1acd90
Show file tree
Hide file tree
Showing 42 changed files with 500 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ protected static async Task GenerateFileAndVerifyAsync(
try
{
// Using default settings here because none of the tests exercise any of the settings
var file = await service.GetGeneratedFileAsync(project, symbol, signaturesOnly: false, MetadataAsSourceOptions.GetDefault(project.Services), CancellationToken.None).ConfigureAwait(false);
var file = await service.GetGeneratedFileAsync(workspace, project, symbol, signaturesOnly: false, MetadataAsSourceOptions.GetDefault(project.Services), CancellationToken.None).ConfigureAwait(false);

if (expectNullResult)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void CleanupGeneratedFiles(Workspace? workspace)
{
}

public Task<MetadataAsSourceFile?> GetGeneratedFileAsync(Workspace workspace, Project project, ISymbol symbol, bool signaturesOnly, MetadataAsSourceOptions options, string tempPath, CancellationToken cancellationToken)
public Task<MetadataAsSourceFile?> GetGeneratedFileAsync(MetadataAsSourceWorkspace metadataWorkspace, Workspace sourceWorkspace, Project sourceProject, ISymbol symbol, bool signaturesOnly, MetadataAsSourceOptions options, string tempPath, CancellationToken cancellationToken)
{
return Task.FromResult<MetadataAsSourceFile?>(NullResult);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ await RunTestAsync(async path =>
{
NavigateToSourceLinkAndEmbeddedSources = false
};
var file = await service.GetGeneratedFileAsync(project, symbol, signaturesOnly: false, options, CancellationToken.None).ConfigureAwait(false);
var file = await service.GetGeneratedFileAsync(workspace, project, symbol, signaturesOnly: false, options, CancellationToken.None).ConfigureAwait(false);

Assert.Same(NullResultMetadataAsSourceFileProvider.NullResult, file);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System.Collections.Immutable;
using System.Composition;
using System.Linq;
Expand Down
2 changes: 1 addition & 1 deletion src/EditorFeatures/Core.Wpf/Peek/DefinitionPeekableItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void FindResults(string relationshipName, IPeekResultCollection resultCol
{
// It's a symbol from metadata, so we want to go produce it from metadata
var options = _peekableItem._globalOptions.GetMetadataAsSourceOptions(project.Services);
var declarationFile = _peekableItem._metadataAsSourceFileService.GetGeneratedFileAsync(project, symbol, signaturesOnly: false, options, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken);
var declarationFile = _peekableItem._metadataAsSourceFileService.GetGeneratedFileAsync(workspace, project, symbol, signaturesOnly: false, options, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken);
var peekDisplayInfo = new PeekResultDisplayInfo(declarationFile.DocumentTitle, declarationFile.DocumentTooltip, declarationFile.DocumentTitle, declarationFile.DocumentTooltip);
var identifierSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;
var entityOfInterestSpan = PeekHelpers.GetEntityOfInterestSpan(symbol, workspace, declarationFile.IdentifierLocation, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,18 @@ private async Task UpdateForCaretPositionAsync(SnapshotPoint pointInRoslynSnapsh
// be expensive. This doesn't cause a functional issue, since opening the window clears whatever was previously there
// so the user won't notice we weren't doing anything when it was open.
if (!await _codeDefinitionWindowService.IsWindowOpenAsync(cancellationToken).ConfigureAwait(false))
{
return;
}

var document = pointInRoslynSnapshot.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
var snapshot = pointInRoslynSnapshot.Snapshot;
var workspace = snapshot.TextBuffer.GetWorkspace();
var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (workspace is null || document is null)
return;
}

// Ensure we're off the UI thread for the rest of this since we don't want to be computing locations on the UI thread.
await TaskScheduler.Default;

var locations = await GetContextFromPointAsync(document, pointInRoslynSnapshot, cancellationToken).ConfigureAwait(true);
var locations = await GetContextFromPointAsync(workspace, document, pointInRoslynSnapshot, cancellationToken).ConfigureAwait(true);
await _codeDefinitionWindowService.SetContextAsync(locations, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
Expand All @@ -161,9 +159,8 @@ private async Task UpdateForCaretPositionAsync(SnapshotPoint pointInRoslynSnapsh
/// Internal for testing purposes.
/// </summary>
internal async Task<ImmutableArray<CodeDefinitionWindowLocation>> GetContextFromPointAsync(
Document document, int position, CancellationToken cancellationToken)
Workspace workspace, Document document, int position, CancellationToken cancellationToken)
{
var workspace = document.Project.Solution.Workspace;
var navigableItems = await GoToDefinitionHelpers.GetDefinitionsAsync(document, position, cancellationToken).ConfigureAwait(false);
if (navigableItems?.Any() == true)
{
Expand Down Expand Up @@ -211,7 +208,7 @@ internal async Task<ImmutableArray<CodeDefinitionWindowLocation>> GetContextFrom
else if (_metadataAsSourceFileService.IsNavigableMetadataSymbol(symbol))
{
var options = _globalOptions.GetMetadataAsSourceOptions(document.Project.Services);
var declarationFile = await _metadataAsSourceFileService.GetGeneratedFileAsync(document.Project, symbol, signaturesOnly: false, options, cancellationToken).ConfigureAwait(false);
var declarationFile = await _metadataAsSourceFileService.GetGeneratedFileAsync(workspace, document.Project, symbol, signaturesOnly: false, options, cancellationToken).ConfigureAwait(false);
var identifierSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;
return ImmutableArray.Create(new CodeDefinitionWindowLocation(symbol.ToDisplayString(), declarationFile.FilePath, identifierSpan.Start));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ public FindAllReferencesHandler(
Debug.Assert(context.ClientCapabilities.HasVisualStudioLspCapability());

var document = context.Document;
var workspace = context.Workspace;
Contract.ThrowIfNull(document);
Contract.ThrowIfNull(workspace);

using var progress = BufferedProgress.Create<VSInternalReferenceItem>(referenceParams.PartialResultToken);

Expand All @@ -65,7 +67,7 @@ public FindAllReferencesHandler(
ProtocolConversions.PositionToLinePosition(referenceParams.Position), cancellationToken).ConfigureAwait(false);

var findUsagesContext = new FindUsagesLSPContext(
progress, document, position, _metadataAsSourceFileService, _asyncListener, _globalOptions, cancellationToken);
progress, workspace, document, position, _metadataAsSourceFileService, _asyncListener, _globalOptions, cancellationToken);

// Finds the references for the symbol at the specific position in the document, reporting them via streaming to the LSP client.
await findUsagesService.FindReferencesAsync(findUsagesContext, document, position, cancellationToken).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace Microsoft.CodeAnalysis.LanguageServer.CustomProtocol
internal sealed class FindUsagesLSPContext : FindUsagesContext
{
private readonly IProgress<VSInternalReferenceItem[]> _progress;

private readonly Workspace _workspace;
private readonly Document _document;
private readonly int _position;
private readonly IMetadataAsSourceFileService _metadataAsSourceFileService;
Expand Down Expand Up @@ -74,6 +76,7 @@ internal sealed class FindUsagesLSPContext : FindUsagesContext

public FindUsagesLSPContext(
IProgress<VSInternalReferenceItem[]> progress,
Workspace workspace,
Document document,
int position,
IMetadataAsSourceFileService metadataAsSourceFileService,
Expand All @@ -82,6 +85,7 @@ public FindUsagesLSPContext(
CancellationToken cancellationToken)
{
_progress = progress;
_workspace = workspace;
_document = document;
_position = position;
_metadataAsSourceFileService = metadataAsSourceFileService;
Expand Down Expand Up @@ -247,7 +251,7 @@ public override async ValueTask OnReferenceFoundAsync(SourceReferenceItem refere

var options = _globalOptions.GetMetadataAsSourceOptions(_document.Project.Services);
var declarationFile = await _metadataAsSourceFileService.GetGeneratedFileAsync(
_document.Project, symbol, signaturesOnly: true, options, cancellationToken).ConfigureAwait(false);
_workspace, _document.Project, symbol, signaturesOnly: true, options, cancellationToken).ConfigureAwait(false);

var linePosSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public Task<MetadataAsSourceFile> GenerateSourceAsync(ISymbol symbol, Project? p
Contract.ThrowIfNull(symbol);

// Generate and hold onto the result so it can be disposed of with this context
return _metadataAsSourceService.GetGeneratedFileAsync(project, symbol, signaturesOnly, MetadataAsSourceOptions.GetDefault(project.Services));
return _metadataAsSourceService.GetGeneratedFileAsync(Workspace, project, symbol, signaturesOnly, MetadataAsSourceOptions.GetDefault(project.Services));
}

public async Task<MetadataAsSourceFile> GenerateSourceAsync(
Expand Down Expand Up @@ -135,7 +135,7 @@ public async Task<MetadataAsSourceFile> GenerateSourceAsync(
}

// Generate and hold onto the result so it can be disposed of with this context
var result = await _metadataAsSourceService.GetGeneratedFileAsync(project, symbol, signaturesOnly, options);
var result = await _metadataAsSourceService.GetGeneratedFileAsync(Workspace, project, symbol, signaturesOnly, options);

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Namespace Microsoft.CodeAnalysis.Editor.CodeDefinitionWindow.UnitTests

Dim definitionContextTracker = workspace.ExportProvider.GetExportedValue(Of DefinitionContextTracker)
Dim locations = Await definitionContextTracker.GetContextFromPointAsync(
workspace,
document,
hostDocument.CursorPosition.Value,
CancellationToken.None)
Expand All @@ -80,6 +81,7 @@ Namespace Microsoft.CodeAnalysis.Editor.CodeDefinitionWindow.UnitTests

Dim definitionContextTracker = workspace.ExportProvider.GetExportedValue(Of DefinitionContextTracker)
Dim locations = Await definitionContextTracker.GetContextFromPointAsync(
workspace,
triggerDocument,
triggerHostDocument.CursorPosition.Value,
CancellationToken.None)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ Namespace Microsoft.CodeAnalysis.Editor.CodeDefinitionWindow.UnitTests

Dim definitionContextTracker = workspace.ExportProvider.GetExportedValue(Of DefinitionContextTracker)
Dim locations = Await definitionContextTracker.GetContextFromPointAsync(
workspace,
document,
hostDocument.CursorPosition.Value,
CancellationToken.None)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,21 @@ public DecompilationMetadataAsSourceFileProvider(IImplementationAssemblyLookupSe
_implementationAssemblyLookupService = implementationAssemblyLookupService;
}

public async Task<MetadataAsSourceFile?> GetGeneratedFileAsync(Workspace workspace, Project project, ISymbol symbol, bool signaturesOnly, MetadataAsSourceOptions options, string tempPath, CancellationToken cancellationToken)
public async Task<MetadataAsSourceFile?> GetGeneratedFileAsync(
MetadataAsSourceWorkspace metadataWorkspace,
Workspace sourceWorkspace,
Project sourceProject,
ISymbol symbol,
bool signaturesOnly,
MetadataAsSourceOptions options,
string tempPath,
CancellationToken cancellationToken)
{
MetadataAsSourceGeneratedFileInfo fileInfo;
Location? navigateLocation = null;
var topLevelNamedType = MetadataAsSourceHelpers.GetTopLevelContainingNamedType(symbol);
var symbolId = SymbolKey.Create(symbol, cancellationToken);
var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
var compilation = await sourceProject.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);

// If we've been asked for signatures only, then we never want to use the decompiler
var useDecompiler = !signaturesOnly && options.NavigateToDecompiledSources;
Expand All @@ -68,18 +76,20 @@ public DecompilationMetadataAsSourceFileProvider(IImplementationAssemblyLookupSe
useDecompiler = !refInfo.isReferenceAssembly;
}

var infoKey = await GetUniqueDocumentKeyAsync(project, topLevelNamedType, signaturesOnly: !useDecompiler, cancellationToken).ConfigureAwait(false);
fileInfo = _keyToInformation.GetOrAdd(infoKey, _ => new MetadataAsSourceGeneratedFileInfo(tempPath, project, topLevelNamedType, signaturesOnly: !useDecompiler));
var infoKey = await GetUniqueDocumentKeyAsync(sourceProject, topLevelNamedType, signaturesOnly: !useDecompiler, cancellationToken).ConfigureAwait(false);
fileInfo = _keyToInformation.GetOrAdd(infoKey,
_ => new MetadataAsSourceGeneratedFileInfo(tempPath, sourceWorkspace, sourceProject, topLevelNamedType, signaturesOnly: !useDecompiler));

_generatedFilenameToInformation[fileInfo.TemporaryFilePath] = fileInfo;

if (!File.Exists(fileInfo.TemporaryFilePath))
{
// We need to generate this. First, we'll need a temporary project to do the generation into. We
// avoid loading the actual file from disk since it doesn't exist yet.
var temporaryProjectInfoAndDocumentId = fileInfo.GetProjectInfoAndDocumentId(workspace, loadFileFromDisk: false);
var temporaryDocument = workspace.CurrentSolution.AddProject(temporaryProjectInfoAndDocumentId.Item1)
.GetRequiredDocument(temporaryProjectInfoAndDocumentId.Item2);
var temporaryProjectInfoAndDocumentId = fileInfo.GetProjectInfoAndDocumentId(metadataWorkspace, loadFileFromDisk: false);
var temporaryDocument = metadataWorkspace.CurrentSolution
.AddProject(temporaryProjectInfoAndDocumentId.Item1)
.GetRequiredDocument(temporaryProjectInfoAndDocumentId.Item2);

if (useDecompiler)
{
Expand Down Expand Up @@ -154,7 +164,7 @@ public DecompilationMetadataAsSourceFileProvider(IImplementationAssemblyLookupSe
// If we don't have a location yet, then that means we're re-using an existing file. In this case, we'll want to relocate the symbol.
if (navigateLocation == null)
{
navigateLocation = await RelocateSymbol_NoLockAsync(workspace, fileInfo, symbolId, cancellationToken).ConfigureAwait(false);
navigateLocation = await RelocateSymbol_NoLockAsync(metadataWorkspace, fileInfo, symbolId, cancellationToken).ConfigureAwait(false);
}

var documentName = string.Format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ internal interface IMetadataAsSourceFileProvider
/// <summary>
/// Generates a file from metadata. Will be called under a lock to prevent concurrent access.
/// </summary>
Task<MetadataAsSourceFile?> GetGeneratedFileAsync(Workspace workspace, Project project, ISymbol symbol, bool signaturesOnly, MetadataAsSourceOptions options, string tempPath, CancellationToken cancellationToken);
Task<MetadataAsSourceFile?> GetGeneratedFileAsync(
MetadataAsSourceWorkspace metadataWorkspace, Workspace sourceWorkspace, Project sourceProject, ISymbol symbol, bool signaturesOnly, MetadataAsSourceOptions options, string tempPath, CancellationToken cancellationToken);

/// <summary>
/// Called when the file returned from <see cref="GetGeneratedFileAsync(Workspace, Project, ISymbol, bool, MetadataAsSourceOptions, string, CancellationToken)"/>
/// needs to be added to the workspace, to be opened. Will be called under a lock to prevent concurrent access.
/// Called when the file returned from <see cref="GetGeneratedFileAsync"/> needs to be added to the workspace,
/// to be opened. Will be called under a lock to prevent concurrent access.
/// </summary>
bool TryAddDocumentToWorkspace(Workspace workspace, string filePath, SourceTextContainer sourceTextContainer);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,18 @@ namespace Microsoft.CodeAnalysis.MetadataAsSource
internal interface IMetadataAsSourceFileService
{
/// <summary>
/// Generates a file on disk containing general information about the symbol's containing
/// assembly, and the formatted source code for the public, protected, and
/// protected-or-internal interface of which the given ISymbol is or is a part of.
/// Generates a file on disk containing general information about the symbol's containing assembly, and the
/// formatted source code for the public, protected, and protected-or-internal interface of which the given
/// ISymbol is or is a part of.
/// </summary>
/// <param name="project">The project from which the symbol to generate source for came
/// from.</param>
/// <param name="sourceWorkspace">The workspace that <paramref name="sourceProject"/> came from.</param>
/// <param name="sourceProject">The project from which the symbol to generate source for came from.</param>
/// <param name="symbol">The symbol whose interface to generate source for</param>
/// <param name="signaturesOnly"><see langword="false"/> to allow a decompiler or other technology to show a
/// representation of the original sources; otherwise <see langword="true"/> to only show member
/// signatures.</param>
/// <param name="options">Options to use when navigating. See <see cref="MetadataAsSourceOptions"/> for details.</param>
/// <param name="cancellationToken">To cancel project and document operations</param>
Task<MetadataAsSourceFile> GetGeneratedFileAsync(Project project, ISymbol symbol, bool signaturesOnly, MetadataAsSourceOptions options, CancellationToken cancellationToken = default);
Task<MetadataAsSourceFile> GetGeneratedFileAsync(Workspace sourceWorkspace, Project sourceProject, ISymbol symbol, bool signaturesOnly, MetadataAsSourceOptions options, CancellationToken cancellationToken = default);

bool TryAddDocumentToWorkspace(string filePath, SourceTextContainer buffer);

Expand Down
Loading

0 comments on commit e1acd90

Please sign in to comment.