зеркало из https://github.com/dotnet/razor.git
Cohost Go To Implementation (#10824)
Needs https://github.com/dotnet/roslyn/pull/74978 Fixes https://github.com/dotnet/razor/issues/10695 Part of https://github.com/dotnet/razor/issues/9519 Pretty straightforward. A tiny bit of code moved to be shared with Go To Def, but that's it.
This commit is contained in:
Коммит
49e727b90e
|
@ -11,82 +11,82 @@
|
|||
<Sha>6bcf90f99d13da86c5e9753a6f34b6484673d0a0</Sha>
|
||||
<SourceBuild RepoName="source-build-reference-packages" ManagedOnly="true" />
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CommonLanguageServerProtocol.Framework" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CommonLanguageServerProtocol.Framework" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.ExternalAccess.Razor" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.ExternalAccess.Razor" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Common" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Common" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp.EditorFeatures" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp.EditorFeatures" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp.Features" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp.Features" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.EditorFeatures" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.EditorFeatures" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.EditorFeatures.Common" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.EditorFeatures.Common" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.EditorFeatures.Text" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.EditorFeatures.Text" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.EditorFeatures.Wpf" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.EditorFeatures.Wpf" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Remote.ServiceHub" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Remote.ServiceHub" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.VisualBasic.Workspaces" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.VisualBasic.Workspaces" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.VisualStudio.LanguageServices" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.VisualStudio.LanguageServices" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Test.Utilities" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Test.Utilities" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
</Dependency>
|
||||
<!-- Intermediate is necessary for source build. -->
|
||||
<Dependency Name="Microsoft.SourceBuild.Intermediate.roslyn" Version="4.12.0-2.24419.3">
|
||||
<Dependency Name="Microsoft.SourceBuild.Intermediate.roslyn" Version="4.12.0-3.24454.5">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>0ec44d9775c80a6861b811d8af637ee36e3315e1</Sha>
|
||||
<Sha>9f86520c46f67d2a8a59af189f8fd87e35c574bb</Sha>
|
||||
<SourceBuild RepoName="roslyn" ManagedOnly="true" />
|
||||
</Dependency>
|
||||
</ProductDependencies>
|
||||
|
|
|
@ -53,25 +53,25 @@
|
|||
<MicrosoftSourceBuildIntermediatearcadePackageVersion>9.0.0-beta.24453.1</MicrosoftSourceBuildIntermediatearcadePackageVersion>
|
||||
<MicrosoftDotNetXliffTasksPackageVersion>1.0.0-beta.23475.1</MicrosoftDotNetXliffTasksPackageVersion>
|
||||
<MicrosoftSourceBuildIntermediatexlifftasksPackageVersion>1.0.0-beta.23475.1</MicrosoftSourceBuildIntermediatexlifftasksPackageVersion>
|
||||
<MicrosoftNetCompilersToolsetPackageVersion>4.12.0-2.24419.3</MicrosoftNetCompilersToolsetPackageVersion>
|
||||
<MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion>4.12.0-2.24419.3</MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion>
|
||||
<MicrosoftCodeAnalysisExternalAccessRazorPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisExternalAccessRazorPackageVersion>
|
||||
<MicrosoftCodeAnalysisCommonPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisCommonPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpEditorFeaturesPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisCSharpEditorFeaturesPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
|
||||
<MicrosoftCodeAnalysisEditorFeaturesPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisEditorFeaturesPackageVersion>
|
||||
<MicrosoftCodeAnalysisEditorFeaturesCommonPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisEditorFeaturesCommonPackageVersion>
|
||||
<MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>
|
||||
<MicrosoftCodeAnalysisEditorFeaturesWpfPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisEditorFeaturesWpfPackageVersion>
|
||||
<MicrosoftCodeAnalysisRemoteServiceHubPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisRemoteServiceHubPackageVersion>
|
||||
<MicrosoftCodeAnalysisTestUtilitiesPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisTestUtilitiesPackageVersion>
|
||||
<MicrosoftCodeAnalysisVisualBasicWorkspacesPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisVisualBasicWorkspacesPackageVersion>
|
||||
<MicrosoftCodeAnalysisWorkspacesCommonPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisWorkspacesCommonPackageVersion>
|
||||
<MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion>4.12.0-2.24419.3</MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion>
|
||||
<MicrosoftSourceBuildIntermediateroslynPackageVersion>4.12.0-2.24419.3</MicrosoftSourceBuildIntermediateroslynPackageVersion>
|
||||
<MicrosoftVisualStudioLanguageServicesPackageVersion>4.12.0-2.24419.3</MicrosoftVisualStudioLanguageServicesPackageVersion>
|
||||
<MicrosoftNetCompilersToolsetPackageVersion>4.12.0-3.24454.5</MicrosoftNetCompilersToolsetPackageVersion>
|
||||
<MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion>4.12.0-3.24454.5</MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion>
|
||||
<MicrosoftCodeAnalysisExternalAccessRazorPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisExternalAccessRazorPackageVersion>
|
||||
<MicrosoftCodeAnalysisCommonPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisCommonPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpEditorFeaturesPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisCSharpEditorFeaturesPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisCSharpFeaturesPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
|
||||
<MicrosoftCodeAnalysisEditorFeaturesPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisEditorFeaturesPackageVersion>
|
||||
<MicrosoftCodeAnalysisEditorFeaturesCommonPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisEditorFeaturesCommonPackageVersion>
|
||||
<MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisEditorFeaturesTextPackageVersion>
|
||||
<MicrosoftCodeAnalysisEditorFeaturesWpfPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisEditorFeaturesWpfPackageVersion>
|
||||
<MicrosoftCodeAnalysisRemoteServiceHubPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisRemoteServiceHubPackageVersion>
|
||||
<MicrosoftCodeAnalysisTestUtilitiesPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisTestUtilitiesPackageVersion>
|
||||
<MicrosoftCodeAnalysisVisualBasicWorkspacesPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisVisualBasicWorkspacesPackageVersion>
|
||||
<MicrosoftCodeAnalysisWorkspacesCommonPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisWorkspacesCommonPackageVersion>
|
||||
<MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion>4.12.0-3.24454.5</MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion>
|
||||
<MicrosoftSourceBuildIntermediateroslynPackageVersion>4.12.0-3.24454.5</MicrosoftSourceBuildIntermediateroslynPackageVersion>
|
||||
<MicrosoftVisualStudioLanguageServicesPackageVersion>4.12.0-3.24454.5</MicrosoftVisualStudioLanguageServicesPackageVersion>
|
||||
<!--
|
||||
Exception - Microsoft.Extensions.ObjectPool and System.Collections.Immutable packages are not updated by automation,
|
||||
but are present in Version.Details.xml for source-build PVP flow. See the comment in Version.Details.xml for more information.
|
||||
|
|
|
@ -30,5 +30,6 @@
|
|||
<ServiceHubService Include="Microsoft.VisualStudio.Razor.Rename" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteRenameService+Factory" />
|
||||
<ServiceHubService Include="Microsoft.VisualStudio.Razor.AutoInsert" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteAutoInsertService+Factory" />
|
||||
<ServiceHubService Include="Microsoft.VisualStudio.Razor.Formatting" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteFormattingService+Factory" />
|
||||
<ServiceHubService Include="Microsoft.VisualStudio.Razor.GoToImplementation" ClassName="Microsoft.CodeAnalysis.Remote.Razor.RemoteGoToImplementationService+Factory" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -184,10 +184,10 @@ internal partial class RazorLanguageServer : SystemTextJsonLanguageServer<RazorR
|
|||
// Transient because it should only be used once and I'm hoping it doesn't stick around.
|
||||
services.AddTransient<IOnInitialized>(sp => sp.GetRequiredService<RazorConfigurationEndpoint>());
|
||||
|
||||
services.AddHandlerWithCapabilities<ImplementationEndpoint>();
|
||||
|
||||
if (!featureOptions.UseRazorCohostServer)
|
||||
{
|
||||
services.AddHandlerWithCapabilities<ImplementationEndpoint>();
|
||||
|
||||
services.AddSingleton<IRazorComponentDefinitionService, RazorComponentDefinitionService>();
|
||||
services.AddHandlerWithCapabilities<DefinitionEndpoint>();
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
|
||||
using RoslynLocation = Roslyn.LanguageServer.Protocol.Location;
|
||||
using RoslynPosition = Roslyn.LanguageServer.Protocol.Position;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Razor.Remote;
|
||||
|
||||
internal interface IRemoteGoToImplementationService : IRemoteJsonService
|
||||
{
|
||||
ValueTask<RemoteResponse<RoslynLocation[]?>> GetImplementationAsync(
|
||||
JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo,
|
||||
JsonSerializableDocumentId razorDocumentId,
|
||||
RoslynPosition position,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
|
@ -33,6 +33,7 @@ internal static class RazorServices
|
|||
(typeof(IRemoteInlayHintService), null),
|
||||
(typeof(IRemoteDocumentSymbolService), null),
|
||||
(typeof(IRemoteRenameService), null),
|
||||
(typeof(IRemoteGoToImplementationService), null),
|
||||
];
|
||||
|
||||
private const string ComponentName = "Razor";
|
||||
|
|
|
@ -19,7 +19,6 @@ using static Microsoft.CodeAnalysis.Razor.Remote.RemoteResponse<Roslyn.LanguageS
|
|||
using ExternalHandlers = Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost.Handlers;
|
||||
using RoslynLocation = Roslyn.LanguageServer.Protocol.Location;
|
||||
using RoslynPosition = Roslyn.LanguageServer.Protocol.Position;
|
||||
using VsPosition = Microsoft.VisualStudio.LanguageServer.Protocol.Position;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Remote.Razor;
|
||||
|
||||
|
@ -58,20 +57,7 @@ internal sealed class RemoteGoToDefinitionService(in ServiceArgs args) : RazorDo
|
|||
return NoFurtherHandling;
|
||||
}
|
||||
|
||||
var positionInfo = GetPositionInfo(codeDocument, hostDocumentIndex);
|
||||
|
||||
if (positionInfo.LanguageKind == RazorLanguageKind.Html)
|
||||
{
|
||||
// Sometimes Html can actually be mapped to C#, like for example component attributes, which map to
|
||||
// C# properties, even though they appear entirely in a Html context. Since remapping is pretty cheap
|
||||
// it's easier to just try mapping, and see what happens, rather than checking for specific syntax nodes.
|
||||
if (DocumentMappingService.TryMapToGeneratedDocumentPosition(codeDocument.GetCSharpDocument(), positionInfo.HostDocumentIndex, out VsPosition? csharpPosition, out _))
|
||||
{
|
||||
// We're just gonna pretend this mapped perfectly normally onto C#. Moving this logic to the actual position info
|
||||
// calculating code is possible, but could have untold effects, so opt-in is better (for now?)
|
||||
positionInfo = positionInfo with { LanguageKind = RazorLanguageKind.CSharp, Position = csharpPosition };
|
||||
}
|
||||
}
|
||||
var positionInfo = GetPositionInfo(codeDocument, hostDocumentIndex, preferCSharpOverHtml: true);
|
||||
|
||||
if (positionInfo.LanguageKind is RazorLanguageKind.Html or RazorLanguageKind.Razor)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
|
||||
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
|
||||
using Microsoft.CodeAnalysis.Razor.Protocol;
|
||||
using Microsoft.CodeAnalysis.Razor.Remote;
|
||||
using Microsoft.CodeAnalysis.Remote.Razor.DocumentMapping;
|
||||
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Microsoft.VisualStudio.LanguageServer.Protocol;
|
||||
using Roslyn.LanguageServer.Protocol;
|
||||
using static Microsoft.CodeAnalysis.Razor.Remote.RemoteResponse<Roslyn.LanguageServer.Protocol.Location[]?>;
|
||||
using ExternalHandlers = Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost.Handlers;
|
||||
using RoslynLocation = Roslyn.LanguageServer.Protocol.Location;
|
||||
using RoslynPosition = Roslyn.LanguageServer.Protocol.Position;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Remote.Razor;
|
||||
|
||||
internal sealed class RemoteGoToImplementationService(in ServiceArgs args) : RazorDocumentServiceBase(in args), IRemoteGoToImplementationService
|
||||
{
|
||||
internal sealed class Factory : FactoryBase<IRemoteGoToImplementationService>
|
||||
{
|
||||
protected override IRemoteGoToImplementationService CreateService(in ServiceArgs args)
|
||||
=> new RemoteGoToImplementationService(in args);
|
||||
}
|
||||
|
||||
protected override IDocumentPositionInfoStrategy DocumentPositionInfoStrategy => PreferAttributeNameDocumentPositionInfoStrategy.Instance;
|
||||
|
||||
public ValueTask<RemoteResponse<RoslynLocation[]?>> GetImplementationAsync(
|
||||
JsonSerializableRazorPinnedSolutionInfoWrapper solutionInfo,
|
||||
JsonSerializableDocumentId documentId,
|
||||
RoslynPosition position,
|
||||
CancellationToken cancellationToken)
|
||||
=> RunServiceAsync(
|
||||
solutionInfo,
|
||||
documentId,
|
||||
context => GetImplementationAsync(context, position, cancellationToken),
|
||||
cancellationToken);
|
||||
|
||||
private async ValueTask<RemoteResponse<RoslynLocation[]?>> GetImplementationAsync(
|
||||
RemoteDocumentContext context,
|
||||
RoslynPosition position,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var codeDocument = await context.GetCodeDocumentAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!codeDocument.Source.Text.TryGetAbsoluteIndex(position, out var hostDocumentIndex))
|
||||
{
|
||||
return NoFurtherHandling;
|
||||
}
|
||||
|
||||
var positionInfo = GetPositionInfo(codeDocument, hostDocumentIndex, preferCSharpOverHtml: true);
|
||||
|
||||
if (positionInfo.LanguageKind is RazorLanguageKind.Razor)
|
||||
{
|
||||
return NoFurtherHandling;
|
||||
}
|
||||
|
||||
if (positionInfo.LanguageKind is RazorLanguageKind.Html)
|
||||
{
|
||||
return CallHtml;
|
||||
}
|
||||
|
||||
if (!DocumentMappingService.TryMapToGeneratedDocumentPosition(codeDocument.GetCSharpDocument(), positionInfo.HostDocumentIndex, out var mappedPosition, out _))
|
||||
{
|
||||
// If we can't map to the generated C# file, we're done.
|
||||
return NoFurtherHandling;
|
||||
}
|
||||
|
||||
// Finally, call into C#.
|
||||
var generatedDocument = await context.Snapshot.GetGeneratedDocumentAsync().ConfigureAwait(false);
|
||||
|
||||
var locations = await ExternalHandlers.GoToImplementation
|
||||
.FindImplementationsAsync(
|
||||
generatedDocument,
|
||||
mappedPosition,
|
||||
supportsVisualStudioExtensions: true,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (locations is null and not [])
|
||||
{
|
||||
// C# didn't return anything, so we're done.
|
||||
return NoFurtherHandling;
|
||||
}
|
||||
|
||||
// Map the C# locations back to the Razor file.
|
||||
using var mappedLocations = new PooledArrayBuilder<RoslynLocation>(locations.Length);
|
||||
|
||||
foreach (var location in locations)
|
||||
{
|
||||
var (uri, range) = location;
|
||||
|
||||
var (mappedDocumentUri, mappedRange) = await DocumentMappingService
|
||||
.MapToHostDocumentUriAndRangeAsync(context.Snapshot, uri, range.ToLinePositionSpan(), cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var mappedLocation = RoslynLspFactory.CreateLocation(mappedDocumentUri, mappedRange);
|
||||
|
||||
mappedLocations.Add(mappedLocation);
|
||||
}
|
||||
|
||||
return Results(mappedLocations.ToArray());
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
|
||||
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
|
||||
using Microsoft.CodeAnalysis.Razor.Protocol;
|
||||
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Microsoft.VisualStudio.LanguageServer.Protocol;
|
||||
|
@ -24,11 +25,34 @@ internal abstract class RazorDocumentServiceBase(in ServiceArgs args) : RazorBro
|
|||
protected virtual IDocumentPositionInfoStrategy DocumentPositionInfoStrategy { get; } = DefaultDocumentPositionInfoStrategy.Instance;
|
||||
|
||||
protected DocumentPositionInfo GetPositionInfo(RazorCodeDocument codeDocument, int hostDocumentIndex)
|
||||
=> GetPositionInfo(codeDocument, hostDocumentIndex, preferCSharpOverHtml: false);
|
||||
|
||||
protected DocumentPositionInfo GetPositionInfo(RazorCodeDocument codeDocument, int hostDocumentIndex, bool preferCSharpOverHtml)
|
||||
{
|
||||
return DocumentPositionInfoStrategy.GetPositionInfo(DocumentMappingService, codeDocument, hostDocumentIndex);
|
||||
var positionInfo = DocumentPositionInfoStrategy.GetPositionInfo(DocumentMappingService, codeDocument, hostDocumentIndex);
|
||||
|
||||
if (preferCSharpOverHtml && positionInfo.LanguageKind == RazorLanguageKind.Html)
|
||||
{
|
||||
// Sometimes Html can actually be mapped to C#, like for example component attributes, which map to
|
||||
// C# properties, even though they appear entirely in a Html context. Since remapping is pretty cheap
|
||||
// it's easier to just try mapping, and see what happens, rather than checking for specific syntax nodes.
|
||||
if (DocumentMappingService.TryMapToGeneratedDocumentPosition(codeDocument.GetCSharpDocument(), positionInfo.HostDocumentIndex, out VsPosition? csharpPosition, out _))
|
||||
{
|
||||
// We're just gonna pretend this mapped perfectly normally onto C#. Moving this logic to the actual position info
|
||||
// calculating code is possible, but could have untold effects, so opt-in is better (for now?)
|
||||
|
||||
// TODO: Not using a with operator here because it doesn't work in OOP for some reason.
|
||||
positionInfo = new DocumentPositionInfo(RazorLanguageKind.CSharp, csharpPosition, positionInfo.HostDocumentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return positionInfo;
|
||||
}
|
||||
|
||||
protected bool TryGetDocumentPositionInfo(RazorCodeDocument codeDocument, RoslynPosition position, out DocumentPositionInfo positionInfo)
|
||||
=> TryGetDocumentPositionInfo(codeDocument, position, preferCSharpOverHtml: false, out positionInfo);
|
||||
|
||||
protected bool TryGetDocumentPositionInfo(RazorCodeDocument codeDocument, RoslynPosition position, bool preferCSharpOverHtml, out DocumentPositionInfo positionInfo)
|
||||
{
|
||||
if (!codeDocument.Source.Text.TryGetAbsoluteIndex(position, out var hostDocumentIndex))
|
||||
{
|
||||
|
@ -36,11 +60,14 @@ internal abstract class RazorDocumentServiceBase(in ServiceArgs args) : RazorBro
|
|||
return false;
|
||||
}
|
||||
|
||||
positionInfo = GetPositionInfo(codeDocument, hostDocumentIndex);
|
||||
positionInfo = GetPositionInfo(codeDocument, hostDocumentIndex, preferCSharpOverHtml);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool TryGetDocumentPositionInfo(RazorCodeDocument codeDocument, VsPosition position, out DocumentPositionInfo positionInfo)
|
||||
=> TryGetDocumentPositionInfo(codeDocument, position, preferCSharpOverHtml: false, out positionInfo);
|
||||
|
||||
protected bool TryGetDocumentPositionInfo(RazorCodeDocument codeDocument, VsPosition position, bool preferCSharpOverHtml, out DocumentPositionInfo positionInfo)
|
||||
{
|
||||
if (!codeDocument.Source.Text.TryGetAbsoluteIndex(position, out var hostDocumentIndex))
|
||||
{
|
||||
|
@ -48,7 +75,7 @@ internal abstract class RazorDocumentServiceBase(in ServiceArgs args) : RazorBro
|
|||
return false;
|
||||
}
|
||||
|
||||
positionInfo = GetPositionInfo(codeDocument, hostDocumentIndex);
|
||||
positionInfo = GetPositionInfo(codeDocument, hostDocumentIndex, preferCSharpOverHtml);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System.Composition;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.ExternalAccess.Razor.Cohost;
|
||||
using Microsoft.CodeAnalysis.Razor.Remote;
|
||||
using Microsoft.CodeAnalysis.Razor.Workspaces;
|
||||
using Microsoft.VisualStudio.LanguageServer.ContainedLanguage;
|
||||
using Microsoft.VisualStudio.LanguageServer.Protocol;
|
||||
using RoslynLspFactory = Roslyn.LanguageServer.Protocol.RoslynLspFactory;
|
||||
using RoslynLspLocation = Roslyn.LanguageServer.Protocol.Location;
|
||||
using VsLspLocation = Microsoft.VisualStudio.LanguageServer.Protocol.Location;
|
||||
|
||||
namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;
|
||||
|
||||
#pragma warning disable RS0030 // Do not use banned APIs
|
||||
[Shared]
|
||||
[CohostEndpoint(Methods.TextDocumentImplementationName)]
|
||||
[Export(typeof(IDynamicRegistrationProvider))]
|
||||
[ExportCohostStatelessLspService(typeof(CohostGoToImplementationEndpoint))]
|
||||
[method: ImportingConstructor]
|
||||
#pragma warning restore RS0030 // Do not use banned APIs
|
||||
internal sealed class CohostGoToImplementationEndpoint(
|
||||
IRemoteServiceInvoker remoteServiceInvoker,
|
||||
IHtmlDocumentSynchronizer htmlDocumentSynchronizer,
|
||||
LSPRequestInvoker requestInvoker,
|
||||
IFilePathService filePathService)
|
||||
: AbstractRazorCohostDocumentRequestHandler<TextDocumentPositionParams, SumType<RoslynLspLocation[], VsLspLocation[], VSInternalReferenceItem[]>?>, IDynamicRegistrationProvider
|
||||
{
|
||||
private readonly IRemoteServiceInvoker _remoteServiceInvoker = remoteServiceInvoker;
|
||||
private readonly IHtmlDocumentSynchronizer _htmlDocumentSynchronizer = htmlDocumentSynchronizer;
|
||||
private readonly LSPRequestInvoker _requestInvoker = requestInvoker;
|
||||
private readonly IFilePathService _filePathService = filePathService;
|
||||
|
||||
protected override bool MutatesSolutionState => false;
|
||||
|
||||
protected override bool RequiresLSPSolution => true;
|
||||
|
||||
public Registration? GetRegistration(VSInternalClientCapabilities clientCapabilities, DocumentFilter[] filter, RazorCohostRequestContext requestContext)
|
||||
{
|
||||
if (clientCapabilities.TextDocument?.Implementation?.DynamicRegistration == true)
|
||||
{
|
||||
return new Registration
|
||||
{
|
||||
Method = Methods.TextDocumentImplementationName,
|
||||
RegisterOptions = new ImplementationOptions()
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override RazorTextDocumentIdentifier? GetRazorTextDocumentIdentifier(TextDocumentPositionParams request)
|
||||
=> request.TextDocument.ToRazorTextDocumentIdentifier();
|
||||
|
||||
protected override Task<SumType<RoslynLspLocation[], VsLspLocation[], VSInternalReferenceItem[]>?> HandleRequestAsync(TextDocumentPositionParams request, RazorCohostRequestContext context, CancellationToken cancellationToken)
|
||||
=> HandleRequestAsync(
|
||||
request,
|
||||
context.TextDocument.AssumeNotNull(),
|
||||
cancellationToken);
|
||||
|
||||
private async Task<SumType<RoslynLspLocation[], VsLspLocation[], VSInternalReferenceItem[]>?> HandleRequestAsync(TextDocumentPositionParams request, TextDocument razorDocument, CancellationToken cancellationToken)
|
||||
{
|
||||
var position = RoslynLspFactory.CreatePosition(request.Position.ToLinePosition());
|
||||
|
||||
var response = await _remoteServiceInvoker
|
||||
.TryInvokeAsync<IRemoteGoToImplementationService, RemoteResponse<RoslynLspLocation[]?>>(
|
||||
razorDocument.Project.Solution,
|
||||
(service, solutionInfo, cancellationToken) =>
|
||||
service.GetImplementationAsync(solutionInfo, razorDocument.Id, position, cancellationToken),
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (response.Result is RoslynLspLocation[] locations)
|
||||
{
|
||||
return locations;
|
||||
}
|
||||
|
||||
if (response.StopHandling)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await GetHtmlImplementationsAsync(request, razorDocument, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<SumType<RoslynLspLocation[], VsLspLocation[], VSInternalReferenceItem[]>?> GetHtmlImplementationsAsync(TextDocumentPositionParams request, TextDocument razorDocument, CancellationToken cancellationToken)
|
||||
{
|
||||
var htmlDocument = await _htmlDocumentSynchronizer.TryGetSynchronizedHtmlDocumentAsync(razorDocument, cancellationToken).ConfigureAwait(false);
|
||||
if (htmlDocument is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
request.TextDocument = request.TextDocument.WithUri(htmlDocument.Uri);
|
||||
|
||||
var result = await _requestInvoker
|
||||
.ReinvokeRequestOnServerAsync<TextDocumentPositionParams, SumType<VsLspLocation[], VSInternalReferenceItem[]>?>(
|
||||
htmlDocument.Buffer,
|
||||
Methods.TextDocumentImplementationName,
|
||||
RazorLSPConstants.HtmlLanguageServerName,
|
||||
request,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (result is not { Response: { } response })
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (response.TryGetFirst(out var locations))
|
||||
{
|
||||
foreach (var location in locations)
|
||||
{
|
||||
RemapVirtualHtmlUri(location);
|
||||
}
|
||||
|
||||
return locations;
|
||||
}
|
||||
else if (response.TryGetSecond(out var referenceItems))
|
||||
{
|
||||
foreach (var referenceItem in referenceItems)
|
||||
{
|
||||
RemapVirtualHtmlUri(referenceItem.Location);
|
||||
}
|
||||
|
||||
return referenceItems;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void RemapVirtualHtmlUri(VsLspLocation location)
|
||||
{
|
||||
if (_filePathService.IsVirtualHtmlFile(location.Uri))
|
||||
{
|
||||
location.Uri = _filePathService.GetRazorDocumentUri(location.Uri);
|
||||
}
|
||||
}
|
||||
|
||||
internal TestAccessor GetTestAccessor() => new(this);
|
||||
|
||||
internal readonly struct TestAccessor(CohostGoToImplementationEndpoint instance)
|
||||
{
|
||||
public Task<SumType<RoslynLspLocation[], VsLspLocation[], VSInternalReferenceItem[]>?> HandleRequestAsync(
|
||||
TextDocumentPositionParams request, TextDocument razorDocument, CancellationToken cancellationToken)
|
||||
=> instance.HandleRequestAsync(request, razorDocument, cancellationToken);
|
||||
}
|
||||
}
|
|
@ -216,17 +216,18 @@ public abstract partial class SingleServerDelegatingEndpointTestBase
|
|||
private Task<VSInternalReferenceItem[]> HandleReferencesAsync<TParams>(TParams @params)
|
||||
{
|
||||
var delegatedParams = Assert.IsType<DelegatedPositionParams>(@params);
|
||||
var delegatedRequest = new TextDocumentPositionParams()
|
||||
var delegatedRequest = new ReferenceParams()
|
||||
{
|
||||
TextDocument = new VSTextDocumentIdentifier()
|
||||
{
|
||||
Uri = _csharpDocumentUri,
|
||||
ProjectContext = delegatedParams.Identifier.TextDocumentIdentifier.GetProjectContext(),
|
||||
},
|
||||
Position = delegatedParams.ProjectedPosition
|
||||
Position = delegatedParams.ProjectedPosition,
|
||||
Context = new ReferenceContext()
|
||||
};
|
||||
|
||||
return _csharpServer.ExecuteRequestAsync<TextDocumentPositionParams, VSInternalReferenceItem[]>(
|
||||
return _csharpServer.ExecuteRequestAsync<ReferenceParams, VSInternalReferenceItem[]>(
|
||||
Methods.TextDocumentReferencesName,
|
||||
delegatedRequest,
|
||||
_cancellationToken);
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Test.Common;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.ExternalAccess.Razor;
|
||||
using Microsoft.CodeAnalysis.Remote.Razor;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Microsoft.VisualStudio.LanguageServer.Protocol;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using LspLocation = Microsoft.VisualStudio.LanguageServer.Protocol.Location;
|
||||
using RoslynLspExtensions = Roslyn.LanguageServer.Protocol.RoslynLspExtensions;
|
||||
|
||||
namespace Microsoft.VisualStudio.Razor.LanguageClient.Cohost;
|
||||
|
||||
public class CohostGoToImplementationEndpointTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper)
|
||||
{
|
||||
[Fact]
|
||||
public async Task CSharp_Method()
|
||||
{
|
||||
var input = """
|
||||
<div></div>
|
||||
|
||||
@{
|
||||
var x = Ge$$tX();
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
void [|GetX|]()
|
||||
{
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
await VerifyCSharpGoToImplementationAsync(input);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CSharp_Field()
|
||||
{
|
||||
var input = """
|
||||
<div></div>
|
||||
|
||||
@{
|
||||
var x = GetX();
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
private string [|_name|];
|
||||
|
||||
string GetX()
|
||||
{
|
||||
return _na$$me;
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
await VerifyCSharpGoToImplementationAsync(input);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CSharp_Multiple()
|
||||
{
|
||||
var input = """
|
||||
<div></div>
|
||||
|
||||
@code
|
||||
{
|
||||
class [|Base|] { }
|
||||
class [|Derived1|] : Base { }
|
||||
class [|Derived2|] : Base { }
|
||||
|
||||
void M(Ba$$se b)
|
||||
{
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
await VerifyCSharpGoToImplementationAsync(input);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Html()
|
||||
{
|
||||
// This really just validates Uri remapping, the actual response is largely arbitrary
|
||||
|
||||
TestCode input = """
|
||||
<div></div>
|
||||
|
||||
<script>
|
||||
function [|foo|]() {
|
||||
f$$oo();
|
||||
}
|
||||
</script>
|
||||
""";
|
||||
|
||||
var document = CreateProjectAndRazorDocument(input.Text);
|
||||
var inputText = await document.GetTextAsync(DisposalToken);
|
||||
|
||||
var htmlResponse = new SumType<LspLocation[], VSInternalReferenceItem[]>?(new LspLocation[]
|
||||
{
|
||||
new LspLocation
|
||||
{
|
||||
Uri = new Uri(document.CreateUri(), document.Name + FeatureOptions.HtmlVirtualDocumentSuffix),
|
||||
Range = inputText.GetRange(input.Span),
|
||||
},
|
||||
});
|
||||
|
||||
var requestInvoker = new TestLSPRequestInvoker([(Methods.TextDocumentImplementationName, htmlResponse)]);
|
||||
|
||||
await VerifyGoToImplementationResultAsync(input, document, requestInvoker);
|
||||
}
|
||||
|
||||
private async Task VerifyCSharpGoToImplementationAsync(TestCode input)
|
||||
{
|
||||
var document = CreateProjectAndRazorDocument(input.Text);
|
||||
|
||||
var requestInvoker = new TestLSPRequestInvoker();
|
||||
|
||||
await VerifyGoToImplementationResultAsync(input, document, requestInvoker);
|
||||
}
|
||||
|
||||
private async Task VerifyGoToImplementationResultAsync(TestCode input, TextDocument document, TestLSPRequestInvoker requestInvoker)
|
||||
{
|
||||
var inputText = await document.GetTextAsync(DisposalToken);
|
||||
|
||||
var filePathService = new RemoteFilePathService(FeatureOptions);
|
||||
var endpoint = new CohostGoToImplementationEndpoint(RemoteServiceInvoker, TestHtmlDocumentSynchronizer.Instance, requestInvoker, filePathService);
|
||||
|
||||
var position = inputText.GetPosition(input.Position);
|
||||
var textDocumentPositionParams = new TextDocumentPositionParams
|
||||
{
|
||||
Position = position,
|
||||
TextDocument = new TextDocumentIdentifier { Uri = document.CreateUri() },
|
||||
};
|
||||
|
||||
var result = await endpoint.GetTestAccessor().HandleRequestAsync(textDocumentPositionParams, document, DisposalToken);
|
||||
|
||||
if (result.Value.TryGetFirst(out var roslynLocations))
|
||||
{
|
||||
var expected = input.Spans.Select(s => inputText.GetRange(s).ToLinePositionSpan()).OrderBy(r => r.Start.Line).ToArray();
|
||||
var actual = roslynLocations.Select(l => RoslynLspExtensions.ToLinePositionSpan(l.Range)).OrderBy(r => r.Start.Line).ToArray();
|
||||
Assert.Equal(expected, actual);
|
||||
|
||||
Assert.All(roslynLocations, l => l.Uri.Equals(document.CreateUri()));
|
||||
}
|
||||
else if (result.Value.TryGetSecond(out var vsLocations))
|
||||
{
|
||||
var expected = input.Spans.Select(s => inputText.GetRange(s).ToLinePositionSpan()).OrderBy(r => r.Start.Line).ToArray();
|
||||
var actual = vsLocations.Select(l => l.Range.ToLinePositionSpan()).OrderBy(r => r.Start.Line).ToArray();
|
||||
Assert.Equal(expected, actual);
|
||||
|
||||
Assert.All(vsLocations, l => l.Uri.Equals(document.CreateUri()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Fail($"Unsupported result type: {result.Value.GetType()}");
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче