提交 7384b7ca 编写于 作者: A Allison Chou

Preliminary implementation, need to figure out how to add other properties

上级 cc49d584
// 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.Editor.FindUsages;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host.Mef;
namespace Microsoft.CodeAnalysis.Editor.CSharp.FindUsages
{
[ExportLanguageService(typeof(IFindUsagesLSPService), LanguageNames.CSharp), Shared]
internal class CSharpFindUsagesLSPService : AbstractFindUsagesService
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public CSharpFindUsagesLSPService(IThreadingContext threadingContext)
: base(threadingContext)
{
}
}
}
......@@ -16,7 +16,7 @@
namespace Microsoft.CodeAnalysis.Editor.FindUsages
{
internal abstract partial class AbstractFindUsagesService : IFindUsagesService
internal abstract partial class AbstractFindUsagesService : IFindUsagesService, IFindUsagesLSPService
{
private readonly IThreadingContext _threadingContext;
......@@ -60,7 +60,7 @@ protected AbstractFindUsagesService(IThreadingContext threadingContext)
}
}
public async Task FindReferencesAsync(
async Task IFindUsagesService.FindReferencesAsync(
Document document, int position, IFindUsagesContext context)
{
var definitionTrackingContext = new DefinitionTrackingContext(context);
......@@ -88,6 +88,14 @@ protected AbstractFindUsagesService(IThreadingContext threadingContext)
}
}
async Task IFindUsagesLSPService.FindReferencesAsync(
Document document, int position, IFindUsagesContext context)
{
var definitionTrackingContext = new DefinitionTrackingContext(context);
await FindLiteralOrSymbolReferencesAsync(
document, position, definitionTrackingContext).ConfigureAwait(false);
}
private async Task FindLiteralOrSymbolReferencesAsync(
Document document, int position, IFindUsagesContext context)
{
......
// 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.Threading.Tasks;
using Microsoft.CodeAnalysis.FindUsages;
using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.Editor.FindUsages
{
internal interface IFindUsagesLSPService : IFindUsagesService
{
/// <summary>
/// Finds the references for the symbol at the specific position in the document,
/// pushing the results into the context instance.
/// </summary>
new Task FindReferencesAsync(Document document, int position, IFindUsagesContext context);
/// <summary>
/// Finds the implementations for the symbol at the specific position in the document,
/// pushing the results into the context instance.
/// </summary>
new Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context);
}
}
' 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.
Imports System.Composition
Imports Microsoft.CodeAnalysis.Editor.FindUsages
Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities
Imports Microsoft.CodeAnalysis.Host.Mef
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.FindUsages
<ExportLanguageService(GetType(IFindUsagesLSPService), LanguageNames.VisualBasic), [Shared]>
Friend Class VisualBasicFindUsagesLSPService
Inherits AbstractFindUsagesService
<ImportingConstructor>
<Obsolete(MefConstruction.ImportingConstructorMessage, True)>
Public Sub New(threadingContext As IThreadingContext)
MyBase.New(threadingContext)
End Sub
End Class
End Namespace
......@@ -48,6 +48,7 @@ public Task<LSP.InitializeResult> HandleRequestAsync(Solution solution, LSP.Init
DocumentRangeFormattingProvider = true,
DocumentOnTypeFormattingProvider = new LSP.DocumentOnTypeFormattingOptions { FirstTriggerCharacter = "}", MoreTriggerCharacter = new[] { ";", "\n" } },
DocumentHighlightProvider = true,
ReferencesProvider = true,
}
});
}
......
......@@ -2,76 +2,63 @@
// 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.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Editor.FindUsages;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.FindSymbols.Finders;
using Microsoft.CodeAnalysis.FindUsages;
using Microsoft.CodeAnalysis.LanguageServer;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.VisualStudio.LanguageServer.Protocol;
using Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService;
using Microsoft.VisualStudio.LiveShare.LanguageServices;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text.Adornments;
using Newtonsoft.Json.Linq;
using LSP = Microsoft.VisualStudio.LanguageServer.Protocol;
namespace Microsoft.VisualStudio.LanguageServices.LiveShare
namespace Microsoft.CodeAnalysis.LanguageServer.Handler
{
// TODO - This should move to the ILanguageClient when we remove the UI thread dependency.
// https://github.com/dotnet/roslyn/issues/38477
// The VS LSP client supports streaming using IProgress<T> on various requests.
// However, this is not yet supported through Live Share, so deserialization fails on the IProgress<T> property.
// https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1043376 tracks Live Share support for this (committed for 16.6).
internal class FindAllReferencesHandler : ILspRequestHandler<object, object[], Solution>
[ExportLspMethod(LSP.Methods.TextDocumentReferencesName), Shared]
internal class FindAllReferencesHandler : IRequestHandler<LSP.ReferenceParams, object[]>
{
private readonly IThreadingContext _threadingContext;
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public FindAllReferencesHandler(IThreadingContext threadingContext)
{
_threadingContext = threadingContext;
}
// TODO - When FAR moves to ILanguageClient, we should switch from using ReferenceGroup (now obsolete) to ReferenceItem.
// https://github.com/dotnet/roslyn/issues/42581
[System.Obsolete]
public async Task<object[]> HandleAsync(object request, RequestContext<Solution> requestContext, CancellationToken cancellationToken)
public async Task<object[]> HandleRequestAsync(Solution solution, ReferenceParams referenceParams, ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
{
// The VS LSP client supports streaming using IProgress<T> on various requests.
// However, this is not yet supported through Live Share, so deserialization fails on the IProgress<T> property.
// https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1043376 tracks Live Share support for this (committed for 16.6).
var referenceParams = ((JObject)request).ToObject<ReferenceParams>(InProcLanguageServer.JsonSerializer);
var locations = ArrayBuilder<LSP.Location>.GetInstance();
var solution = requestContext.Context;
var document = solution.GetDocumentFromURI(referenceParams.TextDocument.Uri);
if (document == null)
{
return locations.ToArrayAndFree();
}
var findUsagesService = document.Project.LanguageServices.GetService<IFindUsagesService>();
var findUsagesService = document.Project.LanguageServices.GetService<IFindUsagesLSPService>();
var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(referenceParams.Position), cancellationToken).ConfigureAwait(false);
var context = new SimpleFindUsagesContext(cancellationToken);
// Roslyn calls into third party extensions to compute reference results and needs to be on the UI thread to compute results.
// This is not great for us and ideally we should ask for a Roslyn API where we can make this call without blocking the UI.
if (VsTaskLibraryHelper.ServiceInstance != null)
{
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
}
await findUsagesService.FindReferencesAsync(document, position, context).ConfigureAwait(false);
if (requestContext?.ClientCapabilities?.ToObject<VSClientCapabilities>()?.HasVisualStudioLspCapability() == true)
if (clientCapabilities?.HasVisualStudioLspCapability() == true)
{
return await GetReferenceGroupsAsync(referenceParams, context, cancellationToken).ConfigureAwait(false);
return await GetReferenceItemsAsync(referenceParams, context, cancellationToken).ConfigureAwait(false);
}
else
{
......@@ -79,11 +66,9 @@ public async Task<object[]> HandleAsync(object request, RequestContext<Solution>
}
}
[System.Obsolete]
private async Task<LSP.ReferenceGroup[]> GetReferenceGroupsAsync(LSP.ReferenceParams request, SimpleFindUsagesContext context, CancellationToken cancellationToken)
private async Task<LSP.VSReferenceItem[]> GetReferenceItemsAsync(LSP.ReferenceParams request, SimpleFindUsagesContext context, CancellationToken cancellationToken)
{
var definitionMap = new Dictionary<DefinitionItem, List<SourceReferenceItem>>();
foreach (var reference in context.GetReferences())
{
if (!definitionMap.ContainsKey(reference.Definition))
......@@ -94,35 +79,63 @@ private async Task<LSP.ReferenceGroup[]> GetReferenceGroupsAsync(LSP.ReferencePa
definitionMap[reference.Definition].Add(reference);
}
var referenceGroups = ArrayBuilder<LSP.ReferenceGroup>.GetInstance();
foreach (var keyValuePair in definitionMap)
{
var definition = keyValuePair.Key;
var references = keyValuePair.Value;
// Parts of FAR currently do not display correctly due to a bug in VSReferenceItem on the LSP side.
// https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1088938/
var referenceItems = ArrayBuilder<LSP.VSReferenceItem>.GetInstance();
var referenceGroup = new LSP.ReferenceGroup();
var text = definition.GetClassifiedText();
// Each reference is assigned its own unique id
var id = 0;
foreach (var definitionAndReferencesPair in definitionMap)
{
// Creating the reference item that corresponds to the definition
var definition = definitionAndReferencesPair.Key;
var definitionItem = await GenerateReferenceItem(id, definitionId: id, definition.SourceSpans.FirstOrDefault(), context, definition.DisplayableProperties,
cancellationToken, definition.GetClassifiedText()).ConfigureAwait(false);
referenceItems.Add(definitionItem);
referenceGroup.Definition = await ProtocolConversions.DocumentSpanToLocationWithTextAsync(definition.SourceSpans.First(), text, cancellationToken).ConfigureAwait(false);
referenceGroup.DefinitionIcon = new ImageElement(definition.Tags.GetFirstGlyph().GetImageId());
var definitionId = id;
id++;
var locationWithTexts = new ArrayBuilder<LSP.LocationWithText>();
// Creating a reference item for each reference
var references = definitionAndReferencesPair.Value;
foreach (var reference in references)
{
var classifiedSpansAndHighlightSpan = await ClassifiedSpansAndHighlightSpanFactory.ClassifyAsync(reference.SourceSpan, context.CancellationToken).ConfigureAwait(false);
var classifiedSpans = classifiedSpansAndHighlightSpan.ClassifiedSpans;
var referenceLocation = await ProtocolConversions.DocumentSpanToLocationAsync(reference.SourceSpan, cancellationToken).ConfigureAwait(false);
var docText = await reference.SourceSpan.Document.GetTextAsync(context.CancellationToken).ConfigureAwait(false);
var classifiedText = new ClassifiedTextElement(classifiedSpans.Select(cspan => new ClassifiedTextRun(cspan.ClassificationType, docText.ToString(cspan.TextSpan))));
var locationWithText = new LSP.LocationWithText { Range = referenceLocation.Range, Uri = referenceLocation.Uri, Text = classifiedText };
locationWithTexts.Add(locationWithText);
}
referenceGroup.References = locationWithTexts.ToArrayAndFree();
referenceGroups.Add(referenceGroup);
var referenceItem = await GenerateReferenceItem(id, definitionId, reference.SourceSpan, context, reference.AdditionalProperties, cancellationToken).ConfigureAwait(false);
referenceItems.Add(referenceItem);
id++;
};
}
return referenceGroups.ToArrayAndFree();
return referenceItems.ToArrayAndFree();
static async Task<VSReferenceItem> GenerateReferenceItem(
int id,
int? definitionId,
DocumentSpan documentSpan,
SimpleFindUsagesContext context,
ImmutableDictionary<string, string> properties,
CancellationToken cancellationToken,
ClassifiedTextElement definitionText = null)
{
var location = await ProtocolConversions.DocumentSpanToLocationAsync(documentSpan, cancellationToken).ConfigureAwait(false);
var classifiedSpansAndHighlightSpan = await ClassifiedSpansAndHighlightSpanFactory.ClassifyAsync(documentSpan, context.CancellationToken).ConfigureAwait(false);
var classifiedSpans = classifiedSpansAndHighlightSpan.ClassifiedSpans;
var docText = await documentSpan.Document.GetTextAsync(context.CancellationToken).ConfigureAwait(false);
return new LSP.VSReferenceItem
{
ContainingMember = properties.TryGetValue(AbstractReferenceFinder.ContainingMemberInfoPropertyName, out var referenceContainingMember) ? referenceContainingMember : null,
ContainingType = properties.TryGetValue(AbstractReferenceFinder.ContainingTypeInfoPropertyName, out var referenceContainingType) ? referenceContainingType : null,
DefinitionId = definitionId,
DefinitionText = definitionText, // Only definitions should have a non-null DefinitionText
DocumentName = documentSpan.Document.Name,
Id = id,
Location = new LSP.Location { Range = location.Range, Uri = location.Uri },
ProjectName = documentSpan.Document.Project.Name,
ResolutionStatus = ResolutionStatusKind.ConfirmedAsReference,
Text = new ClassifiedTextElement(classifiedSpans.Select(cspan => new ClassifiedTextRun(cspan.ClassificationType, docText.ToString(cspan.TextSpan)))),
};
}
}
private static async Task<LSP.Location[]> GetLocationsAsync(LSP.ReferenceParams request, SimpleFindUsagesContext context, CancellationToken cancellationToken)
......
......@@ -153,6 +153,19 @@ public Task<LSP.TextEdit[]> FormatDocumentRangeAsync(Solution solution, LSP.Docu
public Task<LSP.DocumentHighlight[]> GetDocumentHighlightAsync(Solution solution, LSP.TextDocumentPositionParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
=> ExecuteRequestAsync<LSP.TextDocumentPositionParams, LSP.DocumentHighlight[]>(LSP.Methods.TextDocumentDocumentHighlightName, solution, request, clientCapabilities, cancellationToken);
/// <summary>
/// TO-DO fix summary
/// Answers a document highlights request by returning the reference locations for a given document location.
/// https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight
/// </summary>
/// <param name="solution">the solution containing the request document.</param>
/// <param name="request">the document to get references from.</param>
/// <param name="clientCapabilities">the client capabilities for the request.</param>
/// <param name="cancellationToken">a cancellation token.</param>
/// <returns>the reference locations for the given document location.</returns>
public Task<object[]> GetDocumentReferencesAsync(Solution solution, LSP.ReferenceParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
=> ExecuteRequestAsync<LSP.ReferenceParams, object[]>(LSP.Methods.TextDocumentReferencesName, solution, request, clientCapabilities, cancellationToken);
/// <summary>
/// Answers a document symbols request by returning a list of symbols in the document.
/// https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol
......@@ -225,18 +238,6 @@ public Task<LSP.SymbolInformation[]> GetWorkspaceSymbolsAsync(Solution solution,
public Task<LSP.SumType<LSP.Location, LSP.Location[]>?> GoToDefinitionAsync(Solution solution, LSP.TextDocumentPositionParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
=> ExecuteRequestAsync<LSP.TextDocumentPositionParams, LSP.SumType<LSP.Location, LSP.Location[]>?>(LSP.Methods.TextDocumentDefinitionName, solution, request, clientCapabilities, cancellationToken);
/// <summary>
/// Answers a rename request by returning the workspace edit for a given symbol.
/// https://microsoft.github.io/language-server-protocol/specification#textDocument_rename
/// </summary>
/// <param name="solution">the solution containing the request.</param>
/// <param name="request">the document position of the symbol to rename.</param>
/// <param name="clientCapabilities">the client capabilities for the request.</param>
/// <param name="cancellationToken">a cancellation token.</param>
/// <returns>the workspace edits to rename the given symbol</returns>
public Task<WorkspaceEdit> RenameAsync(Solution solution, LSP.RenameParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
=> ExecuteRequestAsync<LSP.RenameParams, WorkspaceEdit>(LSP.Methods.TextDocumentRenameName, solution, request, clientCapabilities, cancellationToken);
/// <summary>
/// Answers a goto type definition request by returning the location of a given type definition.
/// https://microsoft.github.io/language-server-protocol/specification#textDocument_typeDefinition
......@@ -261,6 +262,18 @@ public Task<LSP.Location[]> GoToTypeDefinitionAsync(Solution solution, LSP.TextD
public Task<LSP.InitializeResult> InitializeAsync(Solution solution, LSP.InitializeParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
=> ExecuteRequestAsync<LSP.InitializeParams, LSP.InitializeResult>(LSP.Methods.InitializeName, solution, request, clientCapabilities, cancellationToken);
/// <summary>
/// Answers a rename request by returning the workspace edit for a given symbol.
/// https://microsoft.github.io/language-server-protocol/specification#textDocument_rename
/// </summary>
/// <param name="solution">the solution containing the request.</param>
/// <param name="request">the document position of the symbol to rename.</param>
/// <param name="clientCapabilities">the client capabilities for the request.</param>
/// <param name="cancellationToken">a cancellation token.</param>
/// <returns>the workspace edits to rename the given symbol</returns>
public Task<WorkspaceEdit> RenameAsync(Solution solution, LSP.RenameParams request, LSP.ClientCapabilities clientCapabilities, CancellationToken cancellationToken)
=> ExecuteRequestAsync<LSP.RenameParams, WorkspaceEdit>(LSP.Methods.TextDocumentRenameName, solution, request, clientCapabilities, cancellationToken);
/// <summary>
/// Answers a request to resolve a completion item.
/// https://microsoft.github.io/language-server-protocol/specification#completionItem_resolve
......
......@@ -116,10 +116,17 @@ public void Exit()
[JsonRpcMethod(Methods.TextDocumentRenameName)]
public Task<WorkspaceEdit> GetTextDocumentRenameAsync(JToken input, CancellationToken cancellationToken)
{
var renameParams = input.ToObject<RenameParams>();
var renameParams = input.ToObject<RenameParams>(JsonSerializer);
return _protocol.RenameAsync(_workspace.CurrentSolution, renameParams, _clientCapabilities, cancellationToken);
}
[JsonRpcMethod(Methods.TextDocumentReferencesName)]
public Task<object[]> GetTextDocumentReferencesAsync(JToken input, CancellationToken cancellationToken)
{
var referencesParams = input.ToObject<ReferenceParams>(JsonSerializer);
return _protocol.GetDocumentReferencesAsync(_workspace.CurrentSolution, referencesParams, _clientCapabilities, cancellationToken);
}
[JsonRpcMethod(Methods.TextDocumentCompletionName)]
public Task<SumType<CompletionItem[], CompletionList>?> GetTextDocumentCompletionAsync(JToken input, CancellationToken cancellationToken)
{
......
// 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.Composition;
using Microsoft.CodeAnalysis.Editor.FindUsages;
using Microsoft.CodeAnalysis.Host.Mef;
namespace Microsoft.VisualStudio.LanguageServices.LiveShare.Client.References
{
[ExportLanguageService(typeof(IFindUsagesService), StringConstants.CSharpLspLanguageName), Shared]
internal class CSharpLspFindUsagesService : RoslynFindUsagesService
{
[ImportingConstructor]
public CSharpLspFindUsagesService(CSharpLspClientServiceFactory csharpLspClientServiceFactory, RemoteLanguageServiceWorkspace remoteLanguageServiceWorkspace)
: base(csharpLspClientServiceFactory, remoteLanguageServiceWorkspace)
{
}
}
[ExportLanguageService(typeof(IFindUsagesService), StringConstants.VBLspLanguageName), Shared]
internal class VBLspFindUsagesService : RoslynFindUsagesService
{
[ImportingConstructor]
public VBLspFindUsagesService(VisualBasicLspClientServiceFactory vbLspClientServiceFactory, RemoteLanguageServiceWorkspace remoteLanguageServiceWorkspace)
: base(vbLspClientServiceFactory, remoteLanguageServiceWorkspace)
{
}
}
}
// 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.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.FindUsages;
using Microsoft.CodeAnalysis.FindUsages;
using Microsoft.CodeAnalysis.LanguageServer;
using Microsoft.VisualStudio.LanguageServices.LiveShare.Protocol;
using LSP = Microsoft.VisualStudio.LanguageServer.Protocol;
namespace Microsoft.VisualStudio.LanguageServices.LiveShare.Client.References
{
internal class RoslynFindUsagesService : IFindUsagesService
{
private readonly AbstractLspClientServiceFactory _roslynLspClientServiceFactory;
private readonly RemoteLanguageServiceWorkspace _remoteLanguageServiceWorkspace;
public RoslynFindUsagesService(AbstractLspClientServiceFactory roslynLspClientServiceFactory, RemoteLanguageServiceWorkspace remoteLanguageServiceWorkspace)
{
_roslynLspClientServiceFactory = roslynLspClientServiceFactory ?? throw new ArgumentNullException(nameof(roslynLspClientServiceFactory));
_remoteLanguageServiceWorkspace = remoteLanguageServiceWorkspace ?? throw new ArgumentNullException(nameof(remoteLanguageServiceWorkspace));
}
public Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context)
{
// Find implementations is now handled by the VS LSP client.
return Task.CompletedTask;
}
public async Task FindReferencesAsync(Document document, int position, IFindUsagesContext context)
{
var text = await document.GetTextAsync().ConfigureAwait(false);
var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient;
if (lspClient == null)
{
return;
}
var referenceParams = new LSP.ReferenceParams
{
Context = new LSP.ReferenceContext { IncludeDeclaration = false },
TextDocument = ProtocolConversions.DocumentToTextDocumentIdentifier(document),
Position = ProtocolConversions.LinePositionToPosition(text.Lines.GetLinePosition(position))
};
var locations = await lspClient.RequestAsync(LSP.Methods.TextDocumentReferences.ToLSRequest(), referenceParams, context.CancellationToken).ConfigureAwait(false);
if (locations == null)
{
return;
}
// TODO: Need to get real definition data from the server.
var dummyDef = DefinitionItem.CreateNonNavigableItem(ImmutableArray<string>.Empty, ImmutableArray<TaggedText>.Empty);
await context.OnDefinitionFoundAsync(dummyDef).ConfigureAwait(false);
foreach (var location in locations)
{
var documentSpan = await _remoteLanguageServiceWorkspace.GetDocumentSpanFromLocationAsync(location, context.CancellationToken).ConfigureAwait(false);
if (documentSpan == null)
{
continue;
}
await context.OnReferenceFoundAsync(new SourceReferenceItem(dummyDef, documentSpan.Value)).ConfigureAwait(false);
}
}
}
}
......@@ -96,7 +96,6 @@ public Task<ICollaborationService> CreateServiceAsync(CollaborationSession colla
// Uses Roslyn client.
CodeActionProvider = true,
ExecuteCommandProvider = new ExecuteCommandOptions(),
ReferencesProvider = true,
})));
var lifeTimeService = LspClientLifeTimeService;
......
// 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.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.VisualStudio.LanguageServer.Protocol;
using Microsoft.VisualStudio.LiveShare.LanguageServices;
namespace Microsoft.VisualStudio.LanguageServices.LiveShare
{
[ExportLspRequestHandler(LiveShareConstants.RoslynContractName, Methods.TextDocumentReferencesName)]
[Obsolete("Used for backwards compatibility with old liveshare clients.")]
internal class RoslynFindAllReferencesHandler : FindAllReferencesHandler
{
[ImportingConstructor]
public RoslynFindAllReferencesHandler(IThreadingContext threadingContext) : base(threadingContext)
{
}
}
[ExportLspRequestHandler(LiveShareConstants.CSharpContractName, Methods.TextDocumentReferencesName)]
internal class CSharpFindAllReferencesHandler : FindAllReferencesHandler
{
[ImportingConstructor]
public CSharpFindAllReferencesHandler(IThreadingContext threadingContext) : base(threadingContext)
{
}
}
[ExportLspRequestHandler(LiveShareConstants.VisualBasicContractName, Methods.TextDocumentReferencesName)]
internal class VisualBasicFindAllReferencesHandler : FindAllReferencesHandler
{
[ImportingConstructor]
public VisualBasicFindAllReferencesHandler(IThreadingContext threadingContext) : base(threadingContext)
{
}
}
[ExportLspRequestHandler(LiveShareConstants.TypeScriptContractName, Methods.TextDocumentReferencesName)]
internal class TypeScriptFindAllReferencesHandler : FindAllReferencesHandler
{
[ImportingConstructor]
public TypeScriptFindAllReferencesHandler(IThreadingContext threadingContext) : base(threadingContext)
{
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册