Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
fsharp
提交
583b3d0e
F
fsharp
项目概览
dotNET Platform
/
fsharp
9 个月 前同步成功
通知
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,体验更适合开发者的 AI 搜索 >>
未验证
提交
583b3d0e
编写于
9月 05, 2023
作者:
K
kerams
提交者:
GitHub
9月 05, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Filter completions for record fields in patterns (#15903)
上级
60d2dbdc
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
215 addition
and
152 deletion
+215
-152
src/Compiler/Service/FSharpCheckerResults.fs
src/Compiler/Service/FSharpCheckerResults.fs
+133
-146
src/Compiler/Service/ServiceParsedInputOps.fs
src/Compiler/Service/ServiceParsedInputOps.fs
+22
-1
src/Compiler/Service/ServiceParsedInputOps.fsi
src/Compiler/Service/ServiceParsedInputOps.fsi
+3
-0
src/Compiler/TypedTree/TypedTree.fs
src/Compiler/TypedTree/TypedTree.fs
+2
-2
src/Compiler/TypedTree/TypedTree.fsi
src/Compiler/TypedTree/TypedTree.fsi
+2
-2
tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
...harp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
+7
-0
tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
...rp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
+7
-0
vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs
...tion/tests/FSharp.Editor.Tests/CompletionProviderTests.fs
+39
-1
未找到文件。
src/Compiler/Service/FSharpCheckerResults.fs
浏览文件 @
583b3d0e
...
...
@@ -800,6 +800,28 @@ type internal TypeCheckInfo
|
Item
.
Types
(_,
ty
::
_)
when
isInterfaceTy
g
ty
->
true
|
_
->
false
/// Is the item suitable for completion in a pattern
let
IsPatternCandidate
(
item
:
CompletionItem
)
=
match
item
.
Item
with
|
Item
.
Value
v
->
v
.
LiteralValue
.
IsSome
|
Item
.
ILField
field
->
field
.
LiteralValue
.
IsSome
|
Item
.
ActivePatternCase
_
|
Item
.
ExnCase
_
|
Item
.
ModuleOrNamespaces
_
|
Item
.
Types
_
|
Item
.
UnionCase
_
->
true
|
_
->
false
/// Is the item suitable for completion in a type application or type annotation
let
IsTypeCandidate
(
item
:
CompletionItem
)
=
match
item
.
Item
with
|
Item
.
ModuleOrNamespaces
_
|
Item
.
Types
_
|
Item
.
TypeVar
_
|
Item
.
UnqualifiedType
_
|
Item
.
ExnCase
_
->
true
|
_
->
false
/// Return only items with the specified name, modulo "Attribute" for type completions
let
FilterDeclItemsByResidue
(
getItem
:
'
a
->
Item
)
residue
(
items
:
'
a
list
)
=
let
attributedResidue
=
residue
+
"Attribute"
...
...
@@ -939,6 +961,10 @@ type internal TypeCheckInfo
Unresolved
=
None
}
let
getItem
(
x
:
ItemWithInst
)
=
x
.
Item
let
getItem2
(
x
:
CompletionItem
)
=
x
.
Item
/// Checks whether the suggested name is unused.
/// In the future we could use an increasing numeric suffix for conflict resolution
let
CreateCompletionItemForSuggestedPatternName
(
pos
:
pos
)
name
=
...
...
@@ -1044,7 +1070,7 @@ type internal TypeCheckInfo
|>
List
.
map
(
fun
(
name
,
overloads
)
->
Item
.
MethodGroup
(
name
,
overloads
,
None
)
|>
ItemWithNoInst
|>
CompletionItem
ValueNone
ValueNone
)
|>
DefaultCompletionItem
)
Some
(
overridableMethods
,
nenv
.
DisplayEnv
,
m
)
|
_
->
None
)
...
...
@@ -1063,12 +1089,77 @@ type internal TypeCheckInfo
else
Item
.
UnionCaseField
(
uci
,
index
)
|>
ItemWithNoInst
|>
CompletionItem
ValueNone
ValueNone
|>
DefaultCompletionItem
|>
Some
)
|>
Some
|
_
->
None
)
let
getItem
(
x
:
ItemWithInst
)
=
x
.
Item
let
GetCompletionsForUnionCaseField
pos
indexOrName
caseIdRange
isTheOnlyField
declaredItems
=
let
declaredItems
=
declaredItems
|>
Option
.
bind
(
FilterRelevantItemsBy
getItem2
None
IsPatternCandidate
)
// When the user types `fun (Case (x| )) ->`, we do not yet know whether the intention is to use positional or named arguments,
// so let's show options for both.
let
fields
indexOrName
isTheOnlyField
(
uci
:
UnionCaseInfo
)
=
match
indexOrName
,
isTheOnlyField
with
|
Choice1Of2
(
Some
0
),
true
->
uci
.
UnionCase
.
RecdFields
|>
List
.
mapi
(
fun
index
_
->
Item
.
UnionCaseField
(
uci
,
index
)
|>
ItemWithNoInst
|>
DefaultCompletionItem
)
|
_
->
[]
sResolutions
.
CapturedNameResolutions
|>
ResizeArray
.
tryPick
(
fun
r
->
match
r
.
Item
with
|
Item
.
UnionCase
(
uci
,
_)
when
equals
r
.
Range
caseIdRange
->
let
list
=
declaredItems
|>
Option
.
map
p13
|>
Option
.
defaultValue
[]
|>
List
.
append
(
fields
indexOrName
isTheOnlyField
uci
)
Some
(
SuggestNameForUnionCaseFieldPattern
g
caseIdRange
.
End
pos
uci
indexOrName
list
,
r
.
DisplayEnv
,
r
.
Range
)
|
_
->
None
)
|>
Option
.
orElse
declaredItems
let
GetCompletionsForRecordField
pos
referencedFields
declaredItems
=
declaredItems
|>
Option
.
map
(
fun
(
items
:
CompletionItem
list
,
denv
,
range
)
->
let
fields
=
// Try to find a name resolution for any of the referenced fields, and through it access all available fields of the record
referencedFields
|>
List
.
tryPick
(
fun
(_,
fieldRange
)
->
sResolutions
.
CapturedNameResolutions
|>
ResizeArray
.
tryPick
(
fun
cnr
->
match
cnr
.
Item
with
|
Item
.
RecdField
info
when
equals
cnr
.
Range
fieldRange
->
info
.
TyconRef
.
AllFieldAsRefList
|>
List
.
choose
(
fun
field
->
if
referencedFields
|>
List
.
exists
(
fun
(
fieldName
,
_)
->
fieldName
=
field
.
DisplayName
)
then
None
else
FreshenRecdFieldRef
ncenv
field
.
Range
field
|>
Item
.
RecdField
|>
Some
)
|>
Some
|
_
->
None
))
|>
Option
.
defaultWith
(
fun
()
->
// Fall back to showing all record field names in scope
let
(
nenv
,
_),
_
=
GetBestEnvForPos
pos
getRecordFieldsInScope
nenv
)
|>
List
.
map
(
ItemWithNoInst
>>
DefaultCompletionItem
)
let
items
=
items
|>
List
.
filter
(
fun
item
->
match
item
.
Item
with
|
Item
.
ModuleOrNamespaces
_
->
true
|
Item
.
Types
(_,
ty
::
_)
->
isRecdTy
g
ty
|
_
->
false
)
|>
List
.
append
fields
items
,
denv
,
range
)
let
GetDeclaredItems
(
...
...
@@ -1316,6 +1407,22 @@ type internal TypeCheckInfo
|
atStart
when
atStart
=
0
->
0
|
otherwise
->
otherwise
-
1
let
getDeclaredItemsNotInRangeOpWithAllSymbols
()
=
GetDeclaredItems
(
parseResultsOpt
,
lineStr
,
origLongIdentOpt
,
colAtEndOfNamesAndResidue
,
residueOpt
,
lastDotPos
,
line
,
loc
,
filterCtors
,
resolveOverloads
,
false
,
getAllSymbols
)
let
pos
=
mkPos
line
colAtEndOfNamesAndResidue
// Look for a "special" completion context
...
...
@@ -1445,21 +1552,7 @@ type internal TypeCheckInfo
|
Some
(
CompletionContext
.
ParameterList
(
endPos
,
fields
))
->
let
results
=
GetNamedParametersAndSettableFields
endPos
let
declaredItems
=
GetDeclaredItems
(
parseResultsOpt
,
lineStr
,
origLongIdentOpt
,
colAtEndOfNamesAndResidue
,
residueOpt
,
lastDotPos
,
line
,
loc
,
filterCtors
,
resolveOverloads
,
false
,
getAllSymbols
)
let
declaredItems
=
getDeclaredItemsNotInRangeOpWithAllSymbols
()
match
results
with
|
NameResResult
.
Members
(
items
,
denv
,
m
)
->
...
...
@@ -1484,20 +1577,7 @@ type internal TypeCheckInfo
|
_
->
declaredItems
|
Some
(
CompletionContext
.
AttributeApplication
)
->
GetDeclaredItems
(
parseResultsOpt
,
lineStr
,
origLongIdentOpt
,
colAtEndOfNamesAndResidue
,
residueOpt
,
lastDotPos
,
line
,
loc
,
filterCtors
,
resolveOverloads
,
false
,
getAllSymbols
)
getDeclaredItemsNotInRangeOpWithAllSymbols
()
|>
Option
.
map
(
fun
(
items
,
denv
,
m
)
->
items
|>
List
.
filter
(
fun
cItem
->
...
...
@@ -1509,20 +1589,7 @@ type internal TypeCheckInfo
m
)
|
Some
(
CompletionContext
.
OpenDeclaration
isOpenType
)
->
GetDeclaredItems
(
parseResultsOpt
,
lineStr
,
origLongIdentOpt
,
colAtEndOfNamesAndResidue
,
residueOpt
,
lastDotPos
,
line
,
loc
,
filterCtors
,
resolveOverloads
,
false
,
getAllSymbols
)
getDeclaredItemsNotInRangeOpWithAllSymbols
()
|>
Option
.
map
(
fun
(
items
,
denv
,
m
)
->
items
|>
List
.
filter
(
fun
x
->
...
...
@@ -1541,108 +1608,28 @@ type internal TypeCheckInfo
|
Some
CompletionContext
.
TypeAbbreviationOrSingleCaseUnion
// Completion at 'Field1: ...'
|
Some
(
CompletionContext
.
RecordField
(
RecordContext
.
Declaration
false
))
->
GetDeclaredItems
(
parseResultsOpt
,
lineStr
,
origLongIdentOpt
,
colAtEndOfNamesAndResidue
,
residueOpt
,
lastDotPos
,
line
,
loc
,
filterCtors
,
resolveOverloads
,
false
,
getAllSymbols
)
|>
Option
.
map
(
fun
(
items
,
denv
,
m
)
->
items
|>
List
.
filter
(
fun
cItem
->
match
cItem
.
Item
with
|
Item
.
ModuleOrNamespaces
_
|
Item
.
Types
_
|
Item
.
TypeVar
_
|
Item
.
UnqualifiedType
_
|
Item
.
ExnCase
_
->
true
|
_
->
false
),
denv
,
m
)
|
Some
(
CompletionContext
.
Pattern
(
PatternContext
.
UnionCaseFieldIdentifier
(
referencedFields
,
caseIdRange
)))
->
GetUnionCaseFields
caseIdRange
referencedFields
|>
Option
.
map
(
fun
completions
->
let
(
nenv
,
_
ad
),
m
=
GetBestEnvForPos
pos
completions
,
nenv
.
DisplayEnv
,
m
)
getDeclaredItemsNotInRangeOpWithAllSymbols
()
|>
Option
.
bind
(
FilterRelevantItemsBy
getItem2
None
IsTypeCandidate
)
|
Some
(
CompletionContext
.
Pattern
patternContext
)
->
let
declaredItems
=
GetDeclaredItems
(
parseResultsOpt
,
lineStr
,
origLongIdentOpt
,
colAtEndOfNamesAndResidue
,
residueOpt
,
lastDotPos
,
line
,
loc
,
filterCtors
,
resolveOverloads
,
false
,
getAllSymbols
)
|>
Option
.
map
(
fun
(
items
,
denv
,
range
)
->
let
filtered
=
items
|>
List
.
filter
(
fun
item
->
match
item
.
Item
with
|
Item
.
Value
v
->
v
.
LiteralValue
.
IsSome
|
Item
.
ILField
field
->
field
.
LiteralValue
.
IsSome
|
Item
.
ActivePatternCase
_
|
Item
.
ExnCase
_
|
Item
.
ModuleOrNamespaces
_
|
Item
.
NewDef
_
|
Item
.
Types
_
|
Item
.
UnionCase
_
->
true
|
_
->
false
)
filtered
,
denv
,
range
)
let
indexOrName
,
caseIdRange
=
match
patternContext
with
|
PatternContext
.
PositionalUnionCaseField
(
index
,
_,
m
)
->
Choice1Of2
index
,
m
|
PatternContext
.
NamedUnionCaseField
(
name
,
m
)
->
Choice2Of2
name
,
m
|
PatternContext
.
UnionCaseFieldIdentifier
_
|
PatternContext
.
Other
->
Choice1Of2
None
,
range0
// No special handling other than filtering out items that may not appear in a pattern
if
equals
caseIdRange
range0
then
declaredItems
else
// When the user types `fun (Case (x| )) ->`, we do not yet know whether the intention is to use positional or named arguments,
// so let's show options for both.
let
fields
patternContext
(
uci
:
UnionCaseInfo
)
=
match
patternContext
with
|
PatternContext
.
PositionalUnionCaseField
(
Some
0
,
true
,
_)
->
uci
.
UnionCase
.
RecdFields
|>
List
.
mapi
(
fun
index
_
->
Item
.
UnionCaseField
(
uci
,
index
)
|>
ItemWithNoInst
|>
CompletionItem
ValueNone
ValueNone
)
|
_
->
[]
sResolutions
.
CapturedNameResolutions
|>
ResizeArray
.
tryPick
(
fun
r
->
match
r
.
Item
with
|
Item
.
UnionCase
(
uci
,
_)
when
equals
r
.
Range
caseIdRange
->
let
list
=
declaredItems
|>
Option
.
map
p13
|>
Option
.
defaultValue
[]
|>
List
.
append
(
fields
patternContext
uci
)
Some
(
SuggestNameForUnionCaseFieldPattern
g
caseIdRange
.
End
pos
uci
indexOrName
list
,
r
.
DisplayEnv
,
r
.
Range
)
|
_
->
None
)
|>
Option
.
orElse
declaredItems
match
patternContext
with
|
PatternContext
.
UnionCaseFieldIdentifier
(
referencedFields
,
caseIdRange
)
->
GetUnionCaseFields
caseIdRange
referencedFields
|>
Option
.
map
(
fun
completions
->
let
(
nenv
,
_
ad
),
m
=
GetBestEnvForPos
pos
completions
,
nenv
.
DisplayEnv
,
m
)
|
PatternContext
.
PositionalUnionCaseField
(
fieldIndex
,
isTheOnlyField
,
caseIdRange
)
->
getDeclaredItemsNotInRangeOpWithAllSymbols
()
|>
GetCompletionsForUnionCaseField
pos
(
Choice1Of2
fieldIndex
)
caseIdRange
isTheOnlyField
|
PatternContext
.
NamedUnionCaseField
(
fieldName
,
caseIdRange
)
->
getDeclaredItemsNotInRangeOpWithAllSymbols
()
|>
GetCompletionsForUnionCaseField
pos
(
Choice2Of2
fieldName
)
caseIdRange
false
|
PatternContext
.
RecordFieldIdentifier
referencedFields
->
getDeclaredItemsNotInRangeOpWithAllSymbols
()
|>
GetCompletionsForRecordField
pos
referencedFields
|
PatternContext
.
Other
->
getDeclaredItemsNotInRangeOpWithAllSymbols
()
|>
Option
.
bind
(
FilterRelevantItemsBy
getItem2
None
IsPatternCandidate
)
|
Some
(
CompletionContext
.
MethodOverride
enclosingTypeNameRange
)
->
GetOverridableMethods
pos
enclosingTypeNameRange
...
...
src/Compiler/Service/ServiceParsedInputOps.fs
浏览文件 @
583b3d0e
...
...
@@ -64,6 +64,9 @@ type PatternContext =
/// Completing union case field identifier in a pattern (e.g. fun (Case (field1 = a; fie| )) -> )
|
UnionCaseFieldIdentifier
of
referencedFields
:
string
list
*
caseIdRange
:
range
/// Completing a record field identifier in a pattern (e.g. fun { Field1 = a; Fie| } -> )
|
RecordFieldIdentifier
of
referencedFields
:
(
string
*
range
)
list
/// Any other position in a pattern that does not need special handling
|
Other
...
...
@@ -1310,10 +1313,28 @@ module ParsedInput =
|
_
->
pats
|>
List
.
tryPick
(
fun
pat
->
TryGetCompletionContextInPattern
false
pat
None
pos
)
|
SynPat
.
Record
(
fieldPats
=
pats
)
->
pats
|>
List
.
tryPick
(
fun
((_,
fieldId
),
_,
pat
)
->
if
rangeContainsPos
fieldId
.
idRange
pos
then
let
referencedFields
=
pats
|>
List
.
map
(
fun
((_,
x
),
_,
_)
->
x
.
idText
,
x
.
idRange
)
Some
(
CompletionContext
.
Pattern
(
PatternContext
.
RecordFieldIdentifier
referencedFields
))
elif
rangeContainsPos
pat
.
Range
pos
then
TryGetCompletionContextInPattern
false
pat
None
pos
else
None
)
|>
Option
.
orElseWith
(
fun
()
->
// Last resort - check for fun { Field1 = a; F| } ->
// That is, pos is after the last field and still within braces
if
pats
|>
List
.
forall
(
fun
(_,
m
,
_)
->
rangeBeforePos
m
pos
)
then
let
referencedFields
=
pats
|>
List
.
map
(
fun
((_,
x
),
_,
_)
->
x
.
idText
,
x
.
idRange
)
Some
(
CompletionContext
.
Pattern
(
PatternContext
.
RecordFieldIdentifier
referencedFields
))
else
None
)
|
SynPat
.
Ands
(
pats
=
pats
)
|
SynPat
.
ArrayOrList
(
elementPats
=
pats
)
->
pats
|>
List
.
tryPick
(
fun
pat
->
TryGetCompletionContextInPattern
suppressIdentifierCompletions
pat
None
pos
)
|>
List
.
tryPick
(
fun
pat
->
TryGetCompletionContextInPattern
false
pat
None
pos
)
|
SynPat
.
Tuple
(
elementPats
=
pats
;
commaRanges
=
commas
;
range
=
m
)
->
pats
|>
List
.
indexed
...
...
src/Compiler/Service/ServiceParsedInputOps.fsi
浏览文件 @
583b3d0e
...
...
@@ -36,6 +36,9 @@ type public PatternContext =
/// Completing union case field identifier in a pattern (e.g. fun (Case (field1 = a; fie| )) -> )
|
UnionCaseFieldIdentifier
of
referencedFields
:
string
list
*
caseIdRange
:
range
/// Completing a record field identifier in a pattern (e.g. fun { Field1 = a; Fie| } -> )
|
RecordFieldIdentifier
of
referencedFields
:
(
string
*
range
)
list
/// Any other position in a pattern that does not need special handling
|
Other
...
...
src/Compiler/TypedTree/TypedTree.fs
浏览文件 @
583b3d0e
...
...
@@ -4142,7 +4142,7 @@ type UnionCaseRef =
type
RecdFieldRef
=
|
RecdFieldRef
of
tyconRef
:
TyconRef
*
fieldName
:
string
/// Get a reference to the type containing this
union case
/// Get a reference to the type containing this
record field
member
x
.
TyconRef
=
let
(
RecdFieldRef
(
tcref
,
_))
=
x
in
tcref
/// Get the name of the field
...
...
@@ -4151,7 +4151,7 @@ type RecdFieldRef =
/// Get the name of the field, with backticks added for non-identifier names
member
x
.
DisplayName
=
x
.
FieldName
|>
ConvertLogicalNameToDisplayName
/// Get the Entity for the type containing this
union case
/// Get the Entity for the type containing this
record field
member
x
.
Tycon
=
x
.
TyconRef
.
Deref
/// Dereference the reference
...
...
src/Compiler/TypedTree/TypedTree.fsi
浏览文件 @
583b3d0e
...
...
@@ -3001,10 +3001,10 @@ type RecdFieldRef =
/// Try to dereference the reference
member
TryRecdField
:
RecdField
voption
/// Get the Entity for the type containing this
union case
/// Get the Entity for the type containing this
record field
member
Tycon
:
Entity
/// Get a reference to the type containing this
union case
/// Get a reference to the type containing this
record field
member
TyconRef
:
TyconRef
/// Represents a type in the typed abstract syntax
...
...
tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
浏览文件 @
583b3d0e
...
...
@@ -3583,9 +3583,12 @@ FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: FSharp.C
FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: FSharp.Compiler.Text.Range get_caseIdRange()
FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] fieldIndex
FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] get_fieldIndex()
FSharp.Compiler.EditorServices.PatternContext+RecordFieldIdentifier: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,FSharp.Compiler.Text.Range]] get_referencedFields()
FSharp.Compiler.EditorServices.PatternContext+RecordFieldIdentifier: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,FSharp.Compiler.Text.Range]] referencedFields
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 NamedUnionCaseField
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Other
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 PositionalUnionCaseField
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 RecordFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 UnionCaseFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext+UnionCaseFieldIdentifier: FSharp.Compiler.Text.Range caseIdRange
FSharp.Compiler.EditorServices.PatternContext+UnionCaseFieldIdentifier: FSharp.Compiler.Text.Range get_caseIdRange()
...
...
@@ -3597,18 +3600,22 @@ FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object, Sys
FSharp.Compiler.EditorServices.PatternContext: Boolean IsNamedUnionCaseField
FSharp.Compiler.EditorServices.PatternContext: Boolean IsOther
FSharp.Compiler.EditorServices.PatternContext: Boolean IsPositionalUnionCaseField
FSharp.Compiler.EditorServices.PatternContext: Boolean IsRecordFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext: Boolean IsUnionCaseFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsNamedUnionCaseField()
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsOther()
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsPositionalUnionCaseField()
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsRecordFieldIdentifier()
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsUnionCaseFieldIdentifier()
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewNamedUnionCaseField(System.String, FSharp.Compiler.Text.Range)
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewPositionalUnionCaseField(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Boolean, FSharp.Compiler.Text.Range)
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewRecordFieldIdentifier(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,FSharp.Compiler.Text.Range]])
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewUnionCaseFieldIdentifier(Microsoft.FSharp.Collections.FSharpList`1[System.String], FSharp.Compiler.Text.Range)
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Other
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Other()
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+RecordFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+Tags
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+UnionCaseFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext: Int32 GetHashCode()
tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
浏览文件 @
583b3d0e
...
...
@@ -3583,9 +3583,12 @@ FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: FSharp.C
FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: FSharp.Compiler.Text.Range get_caseIdRange()
FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] fieldIndex
FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] get_fieldIndex()
FSharp.Compiler.EditorServices.PatternContext+RecordFieldIdentifier: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,FSharp.Compiler.Text.Range]] get_referencedFields()
FSharp.Compiler.EditorServices.PatternContext+RecordFieldIdentifier: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,FSharp.Compiler.Text.Range]] referencedFields
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 NamedUnionCaseField
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 Other
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 PositionalUnionCaseField
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 RecordFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext+Tags: Int32 UnionCaseFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext+UnionCaseFieldIdentifier: FSharp.Compiler.Text.Range caseIdRange
FSharp.Compiler.EditorServices.PatternContext+UnionCaseFieldIdentifier: FSharp.Compiler.Text.Range get_caseIdRange()
...
...
@@ -3597,18 +3600,22 @@ FSharp.Compiler.EditorServices.PatternContext: Boolean Equals(System.Object, Sys
FSharp.Compiler.EditorServices.PatternContext: Boolean IsNamedUnionCaseField
FSharp.Compiler.EditorServices.PatternContext: Boolean IsOther
FSharp.Compiler.EditorServices.PatternContext: Boolean IsPositionalUnionCaseField
FSharp.Compiler.EditorServices.PatternContext: Boolean IsRecordFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext: Boolean IsUnionCaseFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsNamedUnionCaseField()
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsOther()
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsPositionalUnionCaseField()
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsRecordFieldIdentifier()
FSharp.Compiler.EditorServices.PatternContext: Boolean get_IsUnionCaseFieldIdentifier()
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewNamedUnionCaseField(System.String, FSharp.Compiler.Text.Range)
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewPositionalUnionCaseField(Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Boolean, FSharp.Compiler.Text.Range)
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewRecordFieldIdentifier(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[System.String,FSharp.Compiler.Text.Range]])
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext NewUnionCaseFieldIdentifier(Microsoft.FSharp.Collections.FSharpList`1[System.String], FSharp.Compiler.Text.Range)
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext Other
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext get_Other()
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+NamedUnionCaseField
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+PositionalUnionCaseField
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+RecordFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+Tags
FSharp.Compiler.EditorServices.PatternContext: FSharp.Compiler.EditorServices.PatternContext+UnionCaseFieldIdentifier
FSharp.Compiler.EditorServices.PatternContext: Int32 GetHashCode()
vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs
浏览文件 @
583b3d0e
...
...
@@ -1763,7 +1763,7 @@ match U1 (1, A) with
VerifyCompletionList
(
fileContents
,
"| U1 (x, y"
,
[
"yyy"
;
"tab"
],
[
"xxx"
;
"num"
;
"fff"
])
[<
Fact
>]
let
``Completion list for union case field identifier contains available fields``
()
=
let
``Completion list for union case field identifier
in a pattern
contains available fields``
()
=
let
fileContents
=
"""
type PatternContext =
...
...
@@ -1921,3 +1921,41 @@ type C () =
VerifyNoCompletionList
(
fileContents
,
"override a"
)
VerifyNoCompletionList
(
fileContents
,
"override _"
)
VerifyNoCompletionList
(
fileContents
,
"override c"
)
[<
Fact
>]
let
``Completion list for record field identifier in a pattern contains available fields, modules, namespaces and record types``
()
=
let
fileContents
=
"""
open System
type DU =
| X
type R1 = { A: int; B: int }
type R2 = { C: int; D: int }
match [] with
| [ { A = 2; l = 2 } ]
"""
VerifyCompletionList
(
fileContents
,
"| [ { A = 2; l"
,
[
"B"
;
"R1"
;
"R2"
;
"System"
;
"LanguagePrimitives"
],
[
"A"
;
"C"
;
"D"
;
"DU"
;
"X"
;
"log"
;
"let"
;
"Lazy"
]
)
[<
Fact
>]
let
``Completion list for record field identifier in a pattern contains fields of all records in scope when the record type is not known yet``
()
=
let
fileContents
=
"""
type R1 = { A: int; B: int }
type R2 = { C: int; D: int }
match { A = 1; B = 2 } with
| { f = () }
"""
VerifyCompletionList
(
fileContents
,
"| { f = ()"
,
[
"A"
;
"B"
;
"C"
;
"D"
],
[]
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录