Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
fsharp
提交
4e2def68
F
fsharp
项目概览
dotNET Platform
/
fsharp
12 个月 前同步成功
通知
0
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
fsharp
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
4e2def68
编写于
11月 08, 2022
作者:
K
kerams
提交者:
GitHub
11月 08, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add parameter name hints for discriminated unions (#14262)
上级
f35fa1a1
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
147 addition
and
26 deletion
+147
-26
src/Compiler/Service/FSharpCheckerResults.fs
src/Compiler/Service/FSharpCheckerResults.fs
+2
-0
src/Compiler/Service/FSharpCheckerResults.fsi
src/Compiler/Service/FSharpCheckerResults.fsi
+3
-0
tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected
...s/FSharp.CompilerService.SurfaceArea.netstandard.expected
+2
-0
vsintegration/src/FSharp.Editor/Hints/HintService.fs
vsintegration/src/FSharp.Editor/Hints/HintService.fs
+8
-2
vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs
...ation/src/FSharp.Editor/Hints/InlineParameterNameHints.fs
+42
-4
vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs
vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs
+16
-13
vsintegration/tests/UnitTests/InlineParameterNameHintTests.fs
...tegration/tests/UnitTests/InlineParameterNameHintTests.fs
+61
-6
vsintegration/tests/UnitTests/OverallHintExperienceTests.fs
vsintegration/tests/UnitTests/OverallHintExperienceTests.fs
+13
-1
未找到文件。
src/Compiler/Service/FSharpCheckerResults.fs
浏览文件 @
4e2def68
...
...
@@ -242,6 +242,8 @@ type FSharpSymbolUse(denv: DisplayEnv, symbol: FSharpSymbol, inst: TyparInstanti
member
_.
IsFromDispatchSlotImplementation
=
itemOcc
=
ItemOccurence
.
Implemented
member
_.
IsFromUse
=
itemOcc
=
ItemOccurence
.
Use
member
_.
IsFromComputationExpression
=
match
symbol
.
Item
,
itemOcc
with
// 'seq' in 'seq { ... }' gets colored as keywords
...
...
src/Compiler/Service/FSharpCheckerResults.fsi
浏览文件 @
4e2def68
...
...
@@ -171,6 +171,9 @@ type public FSharpSymbolUse =
/// Indicates if the reference is in open statement
member
IsFromOpenStatement
:
bool
/// Indicates if the reference is used for example at a call site
member
IsFromUse
:
bool
/// The file name the reference occurs in
member
FileName
:
string
...
...
tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected
浏览文件 @
4e2def68
...
...
@@ -2163,6 +2163,7 @@ FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromOpenStatement
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromPattern
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromType
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsPrivateToFile
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromUse
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromAttribute()
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromComputationExpression()
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromDefinition()
...
...
@@ -2171,6 +2172,7 @@ FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromOpenStatement()
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromPattern()
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromType()
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsPrivateToFile()
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromUse()
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpDisplayContext DisplayContext
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpDisplayContext get_DisplayContext()
FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpSymbol Symbol
vsintegration/src/FSharp.Editor/Hints/HintService.fs
浏览文件 @
4e2def68
...
...
@@ -19,9 +19,15 @@ module HintService =
|
:?
FSharpMemberOrFunctionOrValue
as
symbol
when
hintKinds
|>
Set
.
contains
HintKind
.
ParameterNameHint
&&
InlineParameterNameHints
.
isValidForHint
symbol
->
&&
InlineParameterNameHints
.
is
MemberOrFunctionOrValue
ValidForHint
symbol
->
InlineParameterNameHints
.
getHints
parseResults
symbol
symbolUse
InlineParameterNameHints
.
getHintsForMemberOrFunctionOrValue
parseResults
symbol
symbolUse
|
:?
FSharpUnionCase
as
symbol
when
hintKinds
|>
Set
.
contains
HintKind
.
ParameterNameHint
&&
InlineParameterNameHints
.
isUnionCaseValidForHint
symbol
symbolUse
->
InlineParameterNameHints
.
getHintsForUnionCase
parseResults
symbol
symbolUse
// we'll be adding other stuff gradually here
|
_
->
...
...
vsintegration/src/FSharp.Editor/Hints/InlineParameterNameHints.fs
浏览文件 @
4e2def68
...
...
@@ -10,17 +10,27 @@ open Hints
module
InlineParameterNameHints
=
let
private
getHint
(
range
:
range
,
parameter
:
FSharpParameter
)
=
let
private
get
Parameter
Hint
(
range
:
range
,
parameter
:
FSharpParameter
)
=
{
Kind
=
HintKind
.
ParameterNameHint
Range
=
range
.
StartRange
Parts
=
[
TaggedText
(
TextTag
.
Text
,
$
"{parameter.DisplayName} = "
)
]
}
let
private
getFieldHint
(
range
:
range
,
field
:
FSharpField
)
=
{
Kind
=
HintKind
.
ParameterNameHint
Range
=
range
.
StartRange
Parts
=
[
TaggedText
(
TextTag
.
Text
,
$
"{field.Name} = "
)
]
}
let
private
doesParameterNameExist
(
parameter
:
FSharpParameter
)
=
parameter
.
DisplayName
<>
""
let
isValidForHint
(
symbol
:
FSharpMemberOrFunctionOrValue
)
=
let
private
doesFieldNameExist
(
field
:
FSharpField
)
=
not
field
.
IsNameGenerated
let
isMemberOrFunctionOrValueValidForHint
(
symbol
:
FSharpMemberOrFunctionOrValue
)
=
// is there a better way?
let
isNotBuiltInOperator
=
symbol
.
DeclaringEntity
...
...
@@ -29,7 +39,12 @@ module InlineParameterNameHints =
symbol
.
IsFunction
&&
isNotBuiltInOperator
// arguably, hints for those would be rather useless
let
getHints
let
isUnionCaseValidForHint
(
symbol
:
FSharpUnionCase
)
(
symbolUse
:
FSharpSymbolUse
)
=
// is the union case being used as a constructor and is it not Cons
symbolUse
.
IsFromUse
&&
symbol
.
DisplayName
<>
"(::)"
let
getHintsForMemberOrFunctionOrValue
(
parseResults
:
FSharpParseFileResults
)
(
symbol
:
FSharpMemberOrFunctionOrValue
)
(
symbolUse
:
FSharpSymbolUse
)
=
...
...
@@ -42,8 +57,31 @@ module InlineParameterNameHints =
parameters
|>
Seq
.
zip
ranges
|>
Seq
.
where
(
snd
>>
doesParameterNameExist
)
|>
Seq
.
map
getHint
|>
Seq
.
map
get
Parameter
Hint
|>
Seq
.
toList
// this is the case at least for custom operators
|
None
->
[]
let
getHintsForUnionCase
(
parseResults
:
FSharpParseFileResults
)
(
symbol
:
FSharpUnionCase
)
(
symbolUse
:
FSharpSymbolUse
)
=
let
fields
=
Seq
.
toList
symbol
.
Fields
// If a case does not use field names, don't even bother getting applied argument ranges
if
fields
|>
List
.
exists
doesFieldNameExist
|>
not
then
[]
else
let
ranges
=
parseResults
.
GetAllArgumentsForFunctionApplicationAtPosition
symbolUse
.
Range
.
Start
// When not all field values are provided (as the user is typing), don't show anything yet
match
ranges
with
|
Some
ranges
when
ranges
.
Length
=
fields
.
Length
->
fields
|>
List
.
zip
ranges
|>
List
.
where
(
snd
>>
doesFieldNameExist
)
|>
List
.
map
getFieldHint
|
_
->
[]
vsintegration/src/FSharp.Editor/Hints/RoslynAdapter.fs
浏览文件 @
4e2def68
...
...
@@ -22,19 +22,22 @@ type internal RoslynAdapter
interface
IFSharpInlineHintsService
with
member
_.
GetInlineHintsAsync
(
document
,
_,
cancellationToken
)
=
async
{
let
!
sourceText
=
document
.
GetTextAsync
cancellationToken
|>
Async
.
AwaitTask
let
hintKinds
=
OptionParser
.
getHintKinds
settings
.
Advanced
let
!
nativeHints
=
HintService
.
getHintsForDocument
document
hintKinds
userOpName
cancellationToken
let
roslynHints
=
nativeHints
|>
Seq
.
map
(
NativeToRoslynHintConverter
.
convert
sourceText
)
return
roslynHints
.
ToImmutableArray
()
if
hintKinds
.
IsEmpty
then
return
ImmutableArray
.
Empty
else
let
!
sourceText
=
document
.
GetTextAsync
cancellationToken
|>
Async
.
AwaitTask
let
!
nativeHints
=
HintService
.
getHintsForDocument
document
hintKinds
userOpName
cancellationToken
let
roslynHints
=
nativeHints
|>
Seq
.
map
(
NativeToRoslynHintConverter
.
convert
sourceText
)
return
roslynHints
.
ToImmutableArray
()
}
|>
RoslynHelpers
.
StartAsyncAsTask
cancellationToken
vsintegration/tests/UnitTests/InlineParameterNameHintTests.fs
浏览文件 @
4e2def68
...
...
@@ -159,17 +159,72 @@ let wrapped = WrappedThing 42
Assert
.
IsEmpty
(
result
)
[<
Test
>]
let
``Hints are
not (yet) shown for dicrimanted union
s``
()
=
let
``Hints are
shown for discriminated union case fields with explicit name
s``
()
=
let
code
=
"""
type Shape =
| Square of side : float
| Circle of radius : float
| Square of side: int
| Rectangle of width: int * height: int
let a = Square 1
let b = Rectangle (1, 2)
"""
let
document
=
getFsDocument
code
let
expected
=
[
{
Content
=
"side = "
;
Location
=
(
5
,
16
)
}
{
Content
=
"width = "
;
Location
=
(
6
,
20
)
}
{
Content
=
"height = "
;
Location
=
(
6
,
23
)
}
]
let
actual
=
getParameterNameHints
document
Assert
.
AreEqual
(
expected
,
actual
)
let circle = Circle 42
[<
Test
>]
let
``Hints for discriminated union case fields are not shown when names are generated``
()
=
let
code
=
"""
type Shape =
| Triangle of side1: int * int * side3: int
| Circle of int
let c = Triangle (1, 2, 3)
let d = Circle 1
"""
let
document
=
getFsDocument
code
let
result
=
getParameterNameHints
document
let
expected
=
[
{
Content
=
"side1 = "
;
Location
=
(
5
,
19
)
}
{
Content
=
"side3 = "
;
Location
=
(
5
,
25
)
}
]
Assert
.
IsEmpty
(
result
)
let
actual
=
getParameterNameHints
document
Assert
.
AreEqual
(
expected
,
actual
)
[<
Test
>]
let
``Hints for discriminated union case fields are not shown when provided arguments don't match the expected count``
()
=
let
code
=
"""
type Shape =
| Triangle of side1: int * side2: int * side3: int
| Circle of int
let c = Triangle (1, 2)
"""
let
document
=
getFsDocument
code
let
actual
=
getParameterNameHints
document
Assert
.
IsEmpty
(
actual
)
[<
Test
>]
let
``Hints for discriminated union case fields are not shown for Cons``
()
=
let
code
=
"""
type X =
member _.Test() = 42 :: [42; 42]
"""
let
document
=
getFsDocument
code
let
actual
=
getParameterNameHints
document
Assert
.
IsEmpty
(
actual
)
vsintegration/tests/UnitTests/OverallHintExperienceTests.fs
浏览文件 @
4e2def68
...
...
@@ -15,12 +15,24 @@ type Song = { Artist: string; Title: string }
let whoSings song = song.Artist
let artist = whoSings { Artist = "
Kv
ě
ty
"; Title = "
Je
podzim
" }
type Shape =
| Square of side: int
| Rectangle of width: int * height: int
let a = Square 1
let b = Rectangle (1, 2)
"""
let
document
=
getFsDocument
code
let
expected
=
[
{
Content
=
": Song"
;
Location
=
(
2
,
18
)
}
{
Content
=
": string"
;
Location
=
(
4
,
11
)
}
{
Content
=
"song = "
;
Location
=
(
4
,
23
)
}
{
Content
=
": string"
;
Location
=
(
4
,
11
)
}
{
Content
=
"side = "
;
Location
=
(
10
,
16
)
}
{
Content
=
": Shape"
;
Location
=
(
10
,
6
)
}
{
Content
=
"width = "
;
Location
=
(
11
,
20
)
}
{
Content
=
"height = "
;
Location
=
(
11
,
23
)
}
{
Content
=
": Shape"
;
Location
=
(
11
,
6
)
}
]
let
actual
=
getAllHints
document
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录