Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7ff8941

Browse files
vasily-kirichenkoKevinRansom
authored andcommitted
Fix completion for double ticked module values (dotnet#2212)
* investigation* fix* fis IsOpName* add CompletionProvider.GetChangeAsync* fix DisplayName for F# properties and methods* add FSharpDeclarationListItem.NameInCode and use it in FSharpCompletionProvider.GetChangeAsync to insert backticked names* fix layout for properties* fix provided members layout and display name* revert property layout* fix property layout
1 parent829eedd commit7ff8941

File tree

7 files changed

+91
-49
lines changed

7 files changed

+91
-49
lines changed

‎src/fsharp/NameResolution.fs‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ type Item =
202202
letminfos= minfos|> List.sortBy(fun minfo-> minfo.NumArgs|> List.sum)
203203
Item.CtorGroup(nm,minfos)
204204

205-
memberd.DisplayName=
205+
memberd.DisplayName=
206206
match dwith
207207
| Item.Value v-> v.DisplayName
208208
| Item.ActivePatternCase apref-> apref.Name
@@ -212,8 +212,11 @@ type Item =
212212
| Item.NewDef id-> id.idText
213213
| Item.ILField finfo-> finfo.FieldName
214214
| Item.Event einfo-> einfo.EventName
215-
| Item.Property(nm,_)-> nm
216-
| Item.MethodGroup(nm,_,_)-> nm
215+
| Item.Property(_, FSProp(_,_, Some v,_)::_)
216+
| Item.Property(_, FSProp(_,_,_, Some v)::_)-> v.DisplayName
217+
| Item.Property(nm,_)-> PrettyNaming.DemangleOperatorName nm
218+
| Item.MethodGroup(_,(FSMeth(_,_, v,_)::_),_)-> v.DisplayName
219+
| Item.MethodGroup(nm,_,_)-> PrettyNaming.DemangleOperatorName nm
217220
| Item.CtorGroup(nm,_)-> DemangleGenericTypeName nm
218221
| Item.FakeInterfaceCtor(AbbrevOrAppTy tcref)
219222
| Item.DelegateCtor(AbbrevOrAppTy tcref)-> DemangleGenericTypeName tcref.DisplayName
@@ -226,6 +229,7 @@ type Item =
226229
| Item.CustomOperation(customOpName,_,_)-> customOpName
227230
| Item.CustomBuilder(nm,_)-> nm
228231
|_->""
232+
229233
letvalRefHash(vref:ValRef)=
230234
match vref.TryDerefwith
231235
| None->0

‎src/fsharp/NicePrint.fs‎

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,9 @@ module private PrintTastMemberOrVals =
10881088
letmembInfo= Option.get v.MemberInfo
10891089
letstat= PrintTypes.layoutMemberFlags membInfo.MemberFlags
10901090
let_tps,argInfos,rty,_= GetTypeOfMemberInFSharpForm denv.g v
1091-
letmkNameL niceMethodTypars name=
1092-
letnameL= DemangleOperatorNameAsLayout tagMember name
1091+
1092+
letmkNameL niceMethodTypars tagFunction name=
1093+
letnameL= DemangleOperatorNameAsLayout tagFunction name
10931094
letnameL=
10941095
if denv.showMemberContainersthen
10951096
layoutTyconRef denv v.MemberApparentParent^^ SepL.dot^^ nameL
@@ -1102,7 +1103,7 @@ module private PrintTastMemberOrVals =
11021103
match membInfo.MemberFlags.MemberKindwith
11031104
| MemberKind.Member->
11041105
letniceMethodTypars,tauL= layoutMemberType denv v argInfos rty
1105-
letnameL= mkNameL niceMethodTypars v.LogicalName
1106+
letnameL= mkNameL niceMethodTyparstagMemberv.LogicalName
11061107
stat---(nameL^^ WordL.colon^^ tauL)
11071108
| MemberKind.ClassConstructor
11081109
| MemberKind.Constructor->
@@ -1111,28 +1112,30 @@ module private PrintTastMemberOrVals =
11111112
stat++ newL^^ wordL(tagPunctuation":")^^ tauL
11121113
| MemberKind.PropertyGetSet-> stat
11131114
| MemberKind.PropertyGet->
1114-
if isNil argInfosthen
1115+
if isNil argInfosthen
11151116
// use error recovery because intellisense on an incomplete file will show this
1116-
errorR(Error(FSComp.SR.tastInvalidFormForPropertyGetter(),v.Id.idRange));
1117-
stat--- wordL(tagProperty v.PropertyName)---(WordL.keywordWith^^ WordL.keywordGet)
1117+
errorR(Error(FSComp.SR.tastInvalidFormForPropertyGetter(),v.Id.idRange))
1118+
letnameL= mkNameL[] tagProperty v.CoreDisplayName
1119+
stat--- nameL---(WordL.keywordWith^^ WordL.keywordGet)
11181120
else
11191121
letargInfos=
11201122
match argInfoswith
11211123
|[[(ty,_)]]when isUnitTy denv.g ty->[]
11221124
|_-> argInfos
11231125

11241126
letniceMethodTypars,tauL= layoutMemberType denv v argInfos rty
1125-
letnameL= mkNameL niceMethodTyparsv.PropertyName
1127+
letnameL= mkNameL niceMethodTyparstagProperty v.CoreDisplayName
11261128
stat---(nameL^^ WordL.colon^^(if isNil argInfosthen tauLelse tauL---(WordL.keywordWith^^ WordL.keywordGet)))
11271129
| MemberKind.PropertySet->
11281130
if argInfos.Length<>1|| isNil argInfos.Headthen
11291131
// use error recovery because intellisense on an incomplete file will show this
1130-
errorR(Error(FSComp.SR.tastInvalidFormForPropertySetter(),v.Id.idRange));
1131-
stat--- wordL(tagProperty v.PropertyName)---(WordL.keywordWith^^ WordL.keywordSet)
1132+
errorR(Error(FSComp.SR.tastInvalidFormForPropertySetter(),v.Id.idRange))
1133+
letnameL= mkNameL[] tagProperty v.CoreDisplayName
1134+
stat--- nameL---(WordL.keywordWith^^ WordL.keywordSet)
11321135
else
11331136
letargInfos,valueInfo= List.frontAndBack argInfos.Head
11341137
letniceMethodTypars,tauL= layoutMemberType denv v(if isNil argInfosthen[]else[argInfos])(fst valueInfo)
1135-
letnameL= mkNameL niceMethodTyparsv.PropertyName
1138+
letnameL= mkNameL niceMethodTyparstagProperty v.CoreDisplayName
11361139
stat---(nameL^^ wordL(tagPunctuation":")^^(tauL---(WordL.keywordWith^^ WordL.keywordSet)))
11371140

11381141
letprivatelayoutNonMemberVal denv(tps,v:Val,tau,cxs)=
@@ -1343,6 +1346,18 @@ module InfoMemberPrinting =
13431346
layoutMethInfoCSharpStyle amap m denv minfo minfo.FormalMethodInst
13441347
#endif
13451348

1349+
letlayoutPropInfoToFreeStyle g amap m denv(pinfo:PropInfo)=
1350+
letrty= pinfo.GetPropertyType(amap,m)
1351+
letrty=if pinfo.IsIndexerthen mkRefTupledTy g(pinfo.GetParamTypes(amap, m))--> rtyelse rty
1352+
let_,rty,_= PrettyTypes.PrettifyTypes1 g rty
1353+
letnameL= DemangleOperatorNameAsLayout tagProperty pinfo.PropertyName
1354+
wordL(tagText(FSComp.SR.typeInfoProperty()))^^
1355+
layoutTyconRef denv(tcrefOfAppTy g pinfo.EnclosingType)^^
1356+
SepL.dot^^
1357+
nameL^^
1358+
RightL.colon^^
1359+
layoutTy denv rty
1360+
13461361
letformatMethInfoToBufferFreeStyle amap m denv os minfo=
13471362
layoutMethInfoToFreeStyle amap m denv minfo|> bufferL os
13481363

@@ -1902,6 +1917,9 @@ let stringOfQualifiedValOrMember denv v = PrintTastMemberOrVals.layoutValOrMembe
19021917
letformatMethInfoToBufferFreeStyle amap m denv buf d= InfoMemberPrinting.formatMethInfoToBufferFreeStyle amap m denv buf d
19031918
letlayoutMethInfoFreeStyle amap m denv d= InfoMemberPrinting.layoutMethInfoToFreeStyle amap m denv d
19041919

1920+
/// Convert a PropInfo to a string
1921+
letlayoutPropInfoToFreeStyle g amap m denv d= InfoMemberPrinting.layoutPropInfoToFreeStyle g amap m denv d
1922+
19051923
/// Convert a MethInfo to a string
19061924
letstringOfMethInfo amap m denv d= bufs(fun buf-> InfoMemberPrinting.formatMethInfoToBufferFreeStyle amap m denv buf d)
19071925

‎src/fsharp/PrettyNaming.fs‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,19 @@ module internal Microsoft.FSharp.Compiler.PrettyNaming
125125
t.Add(c)|> ignore
126126
t
127127

128-
letIsOpName(name:string)=
128+
/// Returns `true` if given string is an operator or double backticked name, e.g. ( |>> ) or ( long identifier ).
129+
/// (where ( long identifier ) is the display name for ``long identifier``).
130+
letIsOperatorOrBacktickedName(name:string)=
129131
letnameLen= name.Length
130132
let recloop i=(i< nameLen&&(opCharSet.Contains(name.[i])|| loop(i+1)))
131133
loop0
132134

135+
/// Returns `true` if given string is an operator display name, e.g. ( |>> )
136+
letIsOperatorName(name:string)=
137+
letname=if name.StartsWith"("&& name.EndsWith" )"then name.[2..name.Length-3]else name
138+
letres= name|> Seq.forall(fun c-> opCharSet.Contains c&& c<>' ')
139+
res
140+
133141
letIsMangledOpName(n:string)=
134142
n.StartsWith(opNamePrefix, System.StringComparison.Ordinal)
135143

@@ -192,7 +200,7 @@ module internal Microsoft.FSharp.Compiler.PrettyNaming
192200
match standardOpNames.TryGetValue opwith
193201
|true, x-> x
194202
|false,_->
195-
ifIsOpName opthen
203+
ifIsOperatorOrBacktickedName opthen
196204
compileCustomOpName op
197205
else op
198206

@@ -289,14 +297,14 @@ module internal Microsoft.FSharp.Compiler.PrettyNaming
289297

290298
letDemangleOperatorName nm=
291299
letnm= DecompileOpName nm
292-
ifIsOpName nmthen"("+ nm+" )"
300+
ifIsOperatorOrBacktickedName nmthen"("+ nm+" )"
293301
else nm
294302

295303
openLayoutOps
296304

297305
letDemangleOperatorNameAsLayout nonOpTagged nm=
298306
letnm= DecompileOpName nm
299-
ifIsOpName nmthen wordL(TaggedTextOps.tagPunctuation"(")^^ wordL(TaggedTextOps.tagOperator nm)^^ wordL(TaggedTextOps.tagPunctuation")")
307+
ifIsOperatorOrBacktickedName nmthen wordL(TaggedTextOps.tagPunctuation"(")^^ wordL(TaggedTextOps.tagOperator nm)^^ wordL(TaggedTextOps.tagPunctuation")")
300308
else LayoutOps.wordL(nonOpTagged nm)
301309

302310
letopNameCons= CompileOpName"::"

‎src/fsharp/vs/ServiceDeclarations.fs‎

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -862,19 +862,8 @@ module internal ItemDescriptionsImpl =
862862
FSharpStructuredToolTipElement.Single(layout, xml)
863863

864864
// F# and .NET properties
865-
| Item.Property(_,pinfos)->
866-
letpinfo= pinfos.Head
867-
letrty= pinfo.GetPropertyType(amap,m)
868-
letrty=if pinfo.IsIndexerthen mkRefTupledTy g(pinfo.GetParamTypes(amap, m))--> rtyelse rty
869-
let_,rty,_= PrettyTypes.PrettifyTypes1 g rty
870-
letlayout=
871-
wordL(tagText(FSComp.SR.typeInfoProperty()))^^
872-
NicePrint.layoutTyconRef denv(tcrefOfAppTy g pinfo.EnclosingType)^^
873-
SepL.dot^^
874-
wordL(tagProperty pinfo.PropertyName)^^
875-
RightL.colon^^
876-
NicePrint.layoutTy denv rty
877-
865+
| Item.Property(_, pinfo::_)->
866+
letlayout= NicePrint.layoutPropInfoToFreeStyle g amap m denv pinfo
878867
FSharpStructuredToolTipElement.Single(layout, xml)
879868

880869
// Custom operations in queries
@@ -1310,11 +1299,12 @@ module internal ItemDescriptionsImpl =
13101299

13111300
/// An intellisense declaration
13121301
[<Sealed>]
1313-
typeFSharpDeclarationListItem(name: string,glyphMajor: GlyphMajor,glyphMinor: GlyphMinor,info,isAttribute: bool)=
1302+
typeFSharpDeclarationListItem(name: string,nameInCode: string,glyphMajor: GlyphMajor,glyphMinor: GlyphMinor,info,isAttribute: bool)=
13141303
let mutabledescriptionTextHolder:FSharpToolTipText<_>option= None
13151304
let mutabletask=null
13161305

13171306
memberdecl.Name= name
1307+
memberdecl.NameInCode= nameInCode
13181308

13191309
memberdecl.StructuredDescriptionTextAsync=
13201310
match infowith
@@ -1380,41 +1370,39 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[]) =
13801370
// - show types with fewer generic parameters first
13811371
// - show types before over other related items - they usually have very useful XmlDocs
13821372
letitems=
1383-
items|> List.sortBy(fund->
1384-
letn=
1385-
matchdwith
1373+
items|> List.sortBy(funx->
1374+
letname=
1375+
matchxwith
13861376
| Item.Types(_,(TType_app(tcref,_)::_))->1+ tcref.TyparsNoRange.Length
13871377
// Put delegate ctors after types, sorted by #typars. RemoveDuplicateItems will remove FakeInterfaceCtor and DelegateCtor if an earlier type is also reported with this name
13881378
| Item.FakeInterfaceCtor(TType_app(tcref,_))
13891379
| Item.DelegateCtor(TType_app(tcref,_))->1000+ tcref.TyparsNoRange.Length
13901380
// Put type ctors after types, sorted by #typars. RemoveDuplicateItems will remove DefaultStructCtors if a type is also reported with this name
13911381
| Item.CtorGroup(_,(cinfo::_))->1000+10*(tcrefOfAppTy g cinfo.EnclosingType).TyparsNoRange.Length
13921382
|_->0
1393-
(d.DisplayName,n))
1383+
x.DisplayName, name)
13941384

13951385
// Remove all duplicates. We've put the types first, so this removes the DelegateCtor and DefaultStructCtor's.
13961386
letitems= items|> RemoveDuplicateItems g
13971387

13981388
if verbosethen dprintf"service.ml: mkDecls:%d found groups after filtering\n"(List.length items);
13991389

14001390
// Group by display name
1401-
letitems= items|> List.groupBy(fund->d.DisplayName)
1391+
letitems= items|> List.groupBy(funx->x.DisplayName)
14021392

14031393
// Filter out operators (and list)
14041394
letitems=
14051395
// Check whether this item looks like an operator.
1406-
letisOpItem(nm,item)=
1396+
letisOperatorItem(name,item)=
14071397
match itemwith
14081398
|[Item.Value_]
1409-
|[Item.MethodGroup(_,[_],_)]->
1410-
(IsOpName nm)&& nm.[0]='('&& nm.[nm.Length-1]=')'
1411-
|[Item.UnionCase_]-> IsOpName nm
1399+
|[Item.MethodGroup(_,[_],_)]-> IsOperatorName name
1400+
|[Item.UnionCase_]-> IsOperatorName name
14121401
|_->false
14131402

1414-
letisFSharpList nm=(nm="[]")// list shows up as a Type and a UnionCase, only such entity with a symbolic name, but want to filter out of intellisense
1415-
1416-
items|> List.filter(fun(nm,items)->not(isOpItem(nm,items))&&not(isFSharpList nm))
1403+
letisFSharpList name=(name="[]")// list shows up as a Type and a UnionCase, only such entity with a symbolic name, but want to filter out of intellisense
14171404

1405+
items|> List.filter(fun(name,items)->not(isOperatorItem(name, items))&&not(isFSharpList name))
14181406

14191407
letdecls=
14201408
// Filter out duplicate names
@@ -1423,11 +1411,19 @@ type FSharpDeclarationListInfo(declarations: FSharpDeclarationListItem[]) =
14231411
|[]-> failwith"Unexpected empty bag"
14241412
| items->
14251413
letglyphMajor,glyphMinor= GlyphOfItem(denv,items.Head)
1426-
new FSharpDeclarationListItem(nm, glyphMajor, glyphMinor, Choice1Of2(items, infoReader, m, denv, reactor, checkAlive), IsAttribute infoReader items.Head))
1414+
letname,nameInCode=
1415+
if nm.StartsWith"("&& nm.EndsWith" )"then
1416+
letcleanName= nm.[2..nm.Length-3]
1417+
cleanName,
1418+
if IsOperatorName nmthen cleanNameelse"``"+ cleanName+"``"
1419+
else nm, nm
1420+
1421+
new FSharpDeclarationListItem(name, nameInCode, glyphMajor, glyphMinor, Choice1Of2(items, infoReader, m, denv, reactor, checkAlive), IsAttribute infoReader items.Head))
14271422

14281423
new FSharpDeclarationListInfo(Array.ofList decls)
14291424

14301425
static memberError msg=
14311426
new FSharpDeclarationListInfo(
1432-
[|new FSharpDeclarationListItem("<Note>", GlyphMajor.Error, GlyphMinor.Normal, Choice2Of2(FSharpToolTipText[FSharpStructuredToolTipElement.CompositionError msg]),false)|])
1427+
[|new FSharpDeclarationListItem("<Note>","<Note>", GlyphMajor.Error, GlyphMinor.Normal,
1428+
Choice2Of2(FSharpToolTipText[FSharpStructuredToolTipElement.CompositionError msg]),false)|])
14331429
static memberEmpty=new FSharpDeclarationListInfo([||])

‎src/fsharp/vs/ServiceDeclarations.fsi‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ module internal Tooltips =
7474
typeinternalFSharpDeclarationListItem=
7575
/// Get the display name for the declaration.
7676
memberName:string
77+
/// Get the name for the declaration as it's presented in source code.
78+
memberNameInCode:string
7779
/// Get the description text for the declaration. Commputing this property may require using compiler
7880
/// resources and may trigger execution of a type provider method to retrieve documentation.
7981
///

‎src/fsharp/vs/service.fs‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,9 +1173,8 @@ type TypeCheckInfo
11731173
letisOpItem(nm,item)=
11741174
match itemwith
11751175
|[Item.Value_]
1176-
|[Item.MethodGroup(_,[_],_)]->
1177-
(IsOpName nm)&& nm.[0]='('&& nm.[nm.Length-1]=')'
1178-
|[Item.UnionCase_]-> IsOpName nm
1176+
|[Item.MethodGroup(_,[_],_)]-> IsOperatorName nm
1177+
|[Item.UnionCase_]-> IsOperatorName nm
11791178
|_->false
11801179

11811180
letisFSharpList nm=(nm="[]")// list shows up as a Type and a UnionCase, only such entity with a symbolic name, but want to filter out of intellisense

‎vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type internal FSharpCompletionProvider
4646

4747
static letcompletionTriggers=[|'.'|]
4848
static letdeclarationItemsCache= ConditionalWeakTable<string, FSharpDeclarationListItem>()
49+
static let [<Literal>]NameInCodePropName="NameInCode"
4950

5051
letxmlMemberIndexService= serviceProvider.GetService(typeof<IVsXMLMemberIndexService>):?> IVsXMLMemberIndexService
5152
letdocumentationBuilder= XmlDocumentation.CreateDocumentationBuilder(xmlMemberIndexService, serviceProvider.DTE)
@@ -113,12 +114,18 @@ type internal FSharpCompletionProvider
113114

114115
for declarationItemin declarations.Itemsdo
115116
letglyph= CommonRoslynHelpers.FSharpGlyphToRoslynGlyph declarationItem.GlyphMajor
116-
letname=
117+
letname=
117118
match entityKindwith
118119
| Some EntityKind.Attributewhen declarationItem.IsAttribute&& declarationItem.Name.EndsWith"Attribute"->
119120
declarationItem.Name.[0..declarationItem.Name.Length- attributeSuffixLength-1]
120121
|_-> declarationItem.Name
121122
letcompletionItem= CommonCompletionItem.Create(name, glyph= Nullable glyph)
123+
124+
letcompletionItem=
125+
if declarationItem.Name<> declarationItem.NameInCodethen
126+
completionItem.AddProperty(NameInCodePropName, declarationItem.NameInCode)
127+
else completionItem
128+
122129
declarationItemsCache.Remove(completionItem.DisplayText)|> ignore// clear out stale entries if they exist
123130
declarationItemsCache.Add(completionItem.DisplayText, declarationItem)
124131
results.Add(completionItem)
@@ -159,6 +166,14 @@ type internal FSharpCompletionProvider
159166
return CompletionDescription.Empty
160167
}|> CommonRoslynHelpers.StartAsyncAsTask cancellationToken
161168

169+
overridethis.GetChangeAsync(_,item,_,_):Task<CompletionChange>=
170+
letnameInCode=
171+
match item.Properties.TryGetValue NameInCodePropNamewith
172+
|true, x-> x
173+
|_-> item.DisplayText
174+
175+
Task.FromResult(CompletionChange.Create(new TextChange(item.Span, nameInCode)))
176+
162177
typeinternalFSharpCompletionService
163178
(
164179
workspace: Workspace,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp