diff --git a/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/IUnitTestingStackTraceServiceAccessor.cs b/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/IUnitTestingStackTraceServiceAccessor.cs new file mode 100644 index 0000000000000..daed2fdca3eba --- /dev/null +++ b/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/IUnitTestingStackTraceServiceAccessor.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Host; + +namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api +{ + internal interface IUnitTestingStackTraceServiceAccessor : IWorkspaceService + { + Task> TryParseAsync(string input, Workspace workspace, CancellationToken cancellationToken); + Task TryFindMethodDefinitionAsync(Workspace workspace, UnitTestingParsedFrameWrapper parsedFrame, CancellationToken cancellationToken); + (Document? document, int lineNumber) GetDocumentAndLine(Workspace workspace, UnitTestingParsedFrameWrapper parsedFrame); + Task TryNavigateToAsync(Workspace workspace, UnitTestingDefinitionItemWrapper definitionItem, bool showInPreviewTab, bool activateTab, CancellationToken cancellationToken); + } +} diff --git a/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingDefinitionItemWrapper.cs b/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingDefinitionItemWrapper.cs new file mode 100644 index 0000000000000..5a066d48da9d5 --- /dev/null +++ b/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingDefinitionItemWrapper.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api +{ + internal readonly struct UnitTestingDefinitionItemWrapper + { + internal FindUsages.DefinitionItem UnderlyingObject { get; } + + public UnitTestingDefinitionItemWrapper(FindUsages.DefinitionItem definition) + { + UnderlyingObject = definition; + } + } +} diff --git a/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingParsedFrameWrapper.cs b/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingParsedFrameWrapper.cs new file mode 100644 index 0000000000000..5159b778f2448 --- /dev/null +++ b/src/Features/Core/Portable/ExternalAccess/UnitTesting/API/UnitTestingParsedFrameWrapper.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.StackTraceExplorer; + +namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api +{ + internal readonly struct UnitTestingParsedFrameWrapper + { + internal ParsedFrame UnderlyingObject { get; } + + public UnitTestingParsedFrameWrapper(ParsedFrame parsedFrame) + { + UnderlyingObject = parsedFrame; + } + } +} diff --git a/src/Features/Core/Portable/ExternalAccess/UnitTesting/UnitTestingStackTraceServiceAccessor.cs b/src/Features/Core/Portable/ExternalAccess/UnitTesting/UnitTestingStackTraceServiceAccessor.cs new file mode 100644 index 0000000000000..cc74dbe801c29 --- /dev/null +++ b/src/Features/Core/Portable/ExternalAccess/UnitTesting/UnitTestingStackTraceServiceAccessor.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.StackTraceExplorer; + +namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting +{ + internal class UnitTestingStackTraceServiceAccessor : IUnitTestingStackTraceServiceAccessor + { + private readonly IStackTraceExplorerService _stackTraceExplorerService; + + [Obsolete(MefConstruction.FactoryMethodMessage, error: true)] + public UnitTestingStackTraceServiceAccessor( + IStackTraceExplorerService stackTraceExplorerService) + { + _stackTraceExplorerService = stackTraceExplorerService; + } + + public (Document? document, int lineNumber) GetDocumentAndLine(Workspace workspace, UnitTestingParsedFrameWrapper parsedFrame) + => _stackTraceExplorerService.GetDocumentAndLine(workspace.CurrentSolution, parsedFrame.UnderlyingObject); + + public async Task TryFindMethodDefinitionAsync(Workspace workspace, UnitTestingParsedFrameWrapper parsedFrame, CancellationToken cancellationToken) + { + var definition = await _stackTraceExplorerService.TryFindDefinitionAsync(workspace.CurrentSolution, parsedFrame.UnderlyingObject, StackFrameSymbolPart.Method, cancellationToken).ConfigureAwait(false); + return definition is null + ? null + : new UnitTestingDefinitionItemWrapper(definition); + } + + public async Task> TryParseAsync(string input, Workspace workspace, CancellationToken cancellationToken) + { + var result = await StackTraceAnalyzer.AnalyzeAsync(input, cancellationToken).ConfigureAwait(false); + return result.ParsedFrames.SelectAsArray(p => new UnitTestingParsedFrameWrapper(p)); + } + + public Task TryNavigateToAsync(Workspace workspace, UnitTestingDefinitionItemWrapper definitionItem, bool showInPreviewTab, bool activateTab, CancellationToken cancellationToken) + => definitionItem.UnderlyingObject.TryNavigateToAsync(workspace, showInPreviewTab, activateTab, cancellationToken); + } +} diff --git a/src/Features/Core/Portable/ExternalAccess/UnitTesting/UnitTestingStackTraceServiceAccessorFactory.cs b/src/Features/Core/Portable/ExternalAccess/UnitTesting/UnitTestingStackTraceServiceAccessorFactory.cs new file mode 100644 index 0000000000000..6f439c85d209f --- /dev/null +++ b/src/Features/Core/Portable/ExternalAccess/UnitTesting/UnitTestingStackTraceServiceAccessorFactory.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.StackTraceExplorer; + +namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting +{ + [ExportWorkspaceServiceFactory(typeof(IUnitTestingStackTraceServiceAccessor))] + [Shared] + + internal class UnitTestingStackTraceServiceAccessorFactory : IWorkspaceServiceFactory + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public UnitTestingStackTraceServiceAccessorFactory() + { + } + + [Obsolete(MefConstruction.FactoryMethodMessage, error: true)] + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) + { + var stackTraceExplorerService = workspaceServices.GetRequiredService(); + return new UnitTestingStackTraceServiceAccessor(stackTraceExplorerService); + } + } +}