Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
3d614b9e
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
3d614b9e
编写于
4月 15, 2020
作者:
D
David Barbet
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add hover support for razor lsp
上级
9e48ecfa
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
109 addition
and
13 deletion
+109
-13
src/Features/LanguageServer/Protocol/Handler/Hover/HoverHandler.cs
...res/LanguageServer/Protocol/Handler/Hover/HoverHandler.cs
+4
-7
src/Features/LanguageServer/ProtocolUnitTests/Hover/HoverTests.cs
...ures/LanguageServer/ProtocolUnitTests/Hover/HoverTests.cs
+78
-1
src/VisualStudio/Core/Def/Implementation/LanguageClient/AbstractLanguageServerClient.cs
...ementation/LanguageClient/AbstractLanguageServerClient.cs
+8
-1
src/VisualStudio/Core/Def/Implementation/LanguageClient/InProcLanguageServer.cs
...Def/Implementation/LanguageClient/InProcLanguageServer.cs
+16
-3
src/VisualStudio/Core/Def/Implementation/LanguageClient/RazorLanguageClient.cs
.../Def/Implementation/LanguageClient/RazorLanguageClient.cs
+2
-0
src/VisualStudio/Core/Test.Next/Services/LspDiagnosticsTests.cs
...sualStudio/Core/Test.Next/Services/LspDiagnosticsTests.cs
+1
-1
未找到文件。
src/Features/LanguageServer/Protocol/Handler/Hover/HoverHandler.cs
浏览文件 @
3d614b9e
...
...
@@ -55,19 +55,16 @@ public HoverHandler()
// local functions
// TODO - This should return correctly formatted markdown from quick info.
// https://github.com/dotnet/roslyn/
projects/45#card-20033878
// https://github.com/dotnet/roslyn/
issues/43387
static
string
GetMarkdownString
(
QuickInfoItem
info
)
{
var
stringBuilder
=
new
StringBuilder
();
var
description
=
info
.
Sections
.
FirstOrDefault
(
s
=>
QuickInfoSectionKinds
.
Description
.
Equals
(
s
.
Kind
))?.
Text
??
string
.
Empty
;
var
documentation
=
info
.
Sections
.
FirstOrDefault
(
s
=>
QuickInfoSectionKinds
.
DocumentationComments
.
Equals
(
s
.
Kind
))?.
Text
??
string
.
Empty
;
if
(!
string
.
IsNullOrEmpty
(
description
)
)
foreach
(
var
section
in
info
.
Sections
)
{
stringBuilder
.
Append
(
description
);
if
(!
string
.
IsNullOrEmpty
(
documentation
))
if
(!
string
.
IsNullOrEmpty
(
section
.
Text
))
{
stringBuilder
.
Append
(
"\r\n> "
).
Append
(
documentation
);
stringBuilder
.
Append
(
section
.
Text
).
Append
(
"\r\n"
);
}
}
...
...
src/Features/LanguageServer/ProtocolUnitTests/Hover/HoverTests.cs
浏览文件 @
3d614b9e
...
...
@@ -30,7 +30,84 @@ public async Task TestGetHoverAsync()
}"
;
using
var
workspace
=
CreateTestWorkspace
(
markup
,
out
var
locations
);
var
expectedLocation
=
locations
[
"caret"
].
Single
();
var
expected
=
CreateHover
(
expectedLocation
,
"string A.Method(int i)\r\n> A great method"
);
var
expected
=
CreateHover
(
expectedLocation
,
"string A.Method(int i)\r\n A great method\r\n\r\nReturns:\r\n a string\r\n"
);
var
results
=
await
RunGetHoverAsync
(
workspace
.
CurrentSolution
,
expectedLocation
).
ConfigureAwait
(
false
);
AssertJsonEquals
(
expected
,
results
);
}
[
Fact
]
public
async
Task
TestGetHoverAsync_WithExceptions
()
{
var
markup
=
@"class A
{
/// <summary>
/// A great method
/// </summary>
/// <exception cref='System.NullReferenceException'>
/// Oh no!
/// </exception>
private string {|caret:Method|}(int i)
{
}
}"
;
using
var
workspace
=
CreateTestWorkspace
(
markup
,
out
var
locations
);
var
expectedLocation
=
locations
[
"caret"
].
Single
();
var
expected
=
CreateHover
(
expectedLocation
,
"string A.Method(int i)\r\n A great method\r\n\r\nExceptions:\r\n System.NullReferenceException\r\n"
);
var
results
=
await
RunGetHoverAsync
(
workspace
.
CurrentSolution
,
expectedLocation
).
ConfigureAwait
(
false
);
AssertJsonEquals
(
expected
,
results
);
}
[
Fact
]
public
async
Task
TestGetHoverAsync_WithRemarks
()
{
var
markup
=
@"class A
{
/// <summary>
/// A great method
/// </summary>
/// <remarks>
/// Remarks are cool too.
/// </remarks>
private string {|caret:Method|}(int i)
{
}
}"
;
using
var
workspace
=
CreateTestWorkspace
(
markup
,
out
var
locations
);
var
expectedLocation
=
locations
[
"caret"
].
Single
();
var
expected
=
CreateHover
(
expectedLocation
,
"string A.Method(int i)\r\n A great method\r\n\r\nRemarks are cool too.\r\n"
);
var
results
=
await
RunGetHoverAsync
(
workspace
.
CurrentSolution
,
expectedLocation
).
ConfigureAwait
(
false
);
AssertJsonEquals
(
expected
,
results
);
}
[
Fact
]
public
async
Task
TestGetHoverAsync_WithList
()
{
var
markup
=
@"class A
{
/// <summary>
/// A great method
/// <list type='bullet'>
/// <item>
/// <description>Item 1.</description>
/// </item>
/// <item>
/// <description>Item 2.</description>
/// </item>
/// </list>
/// </summary>
private string {|caret:Method|}(int i)
{
}
}"
;
using
var
workspace
=
CreateTestWorkspace
(
markup
,
out
var
locations
);
var
expectedLocation
=
locations
[
"caret"
].
Single
();
var
expected
=
CreateHover
(
expectedLocation
,
"string A.Method(int i)\r\n A great method\r\n\r\n• Item 1.\r\n• Item 2.\r\n"
);
var
results
=
await
RunGetHoverAsync
(
workspace
.
CurrentSolution
,
expectedLocation
).
ConfigureAwait
(
false
);
AssertJsonEquals
(
expected
,
results
);
...
...
src/VisualStudio/Core/Def/Implementation/LanguageClient/AbstractLanguageServerClient.cs
浏览文件 @
3d614b9e
...
...
@@ -26,6 +26,13 @@ internal abstract class AbstractLanguageServerClient : ILanguageClient
private
readonly
Workspace
_workspace
;
private
InProcLanguageServer
?
_languageServer
;
/// <summary>
/// Allows the implementation to specify if hover should be supported from this language client.
/// Can be removed as soon as LSP supports classifications in hover.
/// Tracking - https://devdiv.visualstudio.com/DevDiv/_workitems/edit/918138/
/// </summary>
protected
virtual
bool
SupportsHover
=>
false
;
/// <summary>
/// Gets the name of the language client (displayed to the user).
/// </summary>
...
...
@@ -71,7 +78,7 @@ public Task<Connection> ActivateAsync(CancellationToken token)
Contract
.
ThrowIfFalse
(
_languageServer
==
null
,
"This language server has already been initialized"
);
var
(
clientStream
,
serverStream
)
=
FullDuplexStream
.
CreatePair
();
_languageServer
=
new
InProcLanguageServer
(
serverStream
,
serverStream
,
_languageServerProtocol
,
_workspace
,
_diagnosticService
,
clientName
:
_diagnosticsClientName
);
_languageServer
=
new
InProcLanguageServer
(
serverStream
,
serverStream
,
_languageServerProtocol
,
_workspace
,
_diagnosticService
,
clientName
:
_diagnosticsClientName
,
SupportsHover
);
return
Task
.
FromResult
(
new
Connection
(
clientStream
,
clientStream
));
}
...
...
src/VisualStudio/Core/Def/Implementation/LanguageClient/InProcLanguageServer.cs
浏览文件 @
3d614b9e
...
...
@@ -39,15 +39,17 @@ internal class InProcLanguageServer
private
readonly
string
?
_clientName
;
private
readonly
JsonRpc
_jsonRpc
;
private
readonly
LanguageServerProtocol
_protocol
;
private
readonly
bool
_supportsHover
;
private
readonly
Workspace
_workspace
;
private
VSClientCapabilities
?
_clientCapabilities
;
public
InProcLanguageServer
(
Stream
inputStream
,
Stream
outputStream
,
LanguageServerProtocol
protocol
,
Workspace
workspace
,
IDiagnosticService
diagnosticService
,
string
?
clientName
)
Workspace
workspace
,
IDiagnosticService
diagnosticService
,
string
?
clientName
,
bool
supportsHover
)
{
_protocol
=
protocol
;
_workspace
=
workspace
;
_supportsHover
=
supportsHover
;
_jsonRpc
=
new
JsonRpc
(
outputStream
,
inputStream
,
this
);
_jsonRpc
.
StartListening
();
...
...
@@ -63,7 +65,7 @@ internal class InProcLanguageServer
/// The specification assures that the initialize request is sent only once.
/// </summary>
[
JsonRpcMethod
(
Methods
.
InitializeName
)]
public
Task
<
InitializeResult
>
InitializeAsync
(
JToken
input
,
CancellationToken
cancellationToken
)
public
async
Task
<
InitializeResult
>
InitializeAsync
(
JToken
input
,
CancellationToken
cancellationToken
)
{
// The VS LSP protocol package changed the type of 'tagSupport' from bool to an object.
// Our version of the LSP protocol package is older and assumes that the type is bool, so deserialization fails.
...
...
@@ -85,7 +87,11 @@ public Task<InitializeResult> InitializeAsync(JToken input, CancellationToken ca
// sends additional VS specific capabilities, so directly deserialize them into the VSClientCapabilities
// to avoid losing them.
_clientCapabilities
=
input
[
"capabilities"
].
ToObject
<
VSClientCapabilities
>(
serializer
);
return
_protocol
.
InitializeAsync
(
_workspace
.
CurrentSolution
,
input
.
ToObject
<
InitializeParams
>(
serializer
),
_clientCapabilities
,
cancellationToken
);
var
serverCapabilities
=
await
_protocol
.
InitializeAsync
(
_workspace
.
CurrentSolution
,
input
.
ToObject
<
InitializeParams
>(
serializer
),
_clientCapabilities
,
cancellationToken
).
ConfigureAwait
(
false
);
// As soon as LSP supports classifications in hover, we can remove this and always advertise hover support.
// Tracking - https://devdiv.visualstudio.com/DevDiv/_workitems/edit/918138/
serverCapabilities
.
Capabilities
.
HoverProvider
=
_supportsHover
;
return
serverCapabilities
;
}
[
JsonRpcMethod
(
Methods
.
InitializedName
)]
...
...
@@ -147,6 +153,13 @@ public Task<DocumentHighlight[]> GetTextDocumentDocumentHighlightsAsync(JToken i
return
_protocol
.
GetDocumentHighlightAsync
(
_workspace
.
CurrentSolution
,
textDocumentPositionParams
,
_clientCapabilities
,
cancellationToken
);
}
[
JsonRpcMethod
(
Methods
.
TextDocumentHoverName
)]
public
Task
<
Hover
>
GetTextDocumentDocumentHoverAsync
(
JToken
input
,
CancellationToken
cancellationToken
)
{
var
textDocumentPositionParams
=
input
.
ToObject
<
TextDocumentPositionParams
>();
return
_protocol
.
GetHoverAsync
(
_workspace
.
CurrentSolution
,
textDocumentPositionParams
,
_clientCapabilities
,
cancellationToken
);
}
[
JsonRpcMethod
(
Methods
.
TextDocumentDocumentSymbolName
)]
public
Task
<
object
[
]>
GetTextDocumentDocumentSymbolsAsync
(
JToken
input
,
CancellationToken
cancellationToken
)
{
...
...
src/VisualStudio/Core/Def/Implementation/LanguageClient/RazorLanguageClient.cs
浏览文件 @
3d614b9e
...
...
@@ -32,6 +32,8 @@ internal class RazorLanguageClient : AbstractLanguageServerClient
{
public
const
string
ClientName
=
"RazorCSharp"
;
protected
override
bool
SupportsHover
=>
true
;
/// <summary>
/// Gets the name of the language client (displayed to the user).
/// </summary>
...
...
src/VisualStudio/Core/Test.Next/Services/LspDiagnosticsTests.cs
浏览文件 @
3d614b9e
...
...
@@ -378,7 +378,7 @@ static InProcLanguageServer CreateLanguageServer(Stream inputStream, Stream outp
{
var
protocol
=
((
TestWorkspace
)
workspace
).
ExportProvider
.
GetExportedValue
<
LanguageServerProtocol
>();
var
languageServer
=
new
InProcLanguageServer
(
inputStream
,
outputStream
,
protocol
,
workspace
,
mockDiagnosticService
,
clientName
:
"RazorCSharp"
);
var
languageServer
=
new
InProcLanguageServer
(
inputStream
,
outputStream
,
protocol
,
workspace
,
mockDiagnosticService
,
clientName
:
"RazorCSharp"
,
supportsHover
:
false
);
return
languageServer
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录