Skip to content

Commit

Permalink
support type abbreviations
Browse files Browse the repository at this point in the history
  • Loading branch information
dawedawe committed Mar 25, 2023
1 parent 25e92c5 commit fde67bd
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 5 deletions.
29 changes: 25 additions & 4 deletions src/FsAutoComplete/CodeFixes/AddPrivateAccessModifier.fs
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,25 @@ let private getRangesAndPlacement input pos =
|> Option.isSome

let tryGetDeclContainingRange (path: SyntaxVisitorPath) pos =
let skip =
match path with
| SyntaxNode.SynTypeDefn(SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel _)) :: _ -> 0 // keep containing range of ctor decl to class range
| _ -> 1

path
|> Seq.skip 1
|> Seq.skip skip
|> Seq.tryPick (fun p ->
match p with
| SyntaxNode.SynTypeDefn m when rangeContainsPos m.Range pos -> Some m.Range
| SyntaxNode.SynModule m when rangeContainsPos m.Range pos -> Some m.Range
| SyntaxNode.SynModule(SynModuleDecl.NestedModule(range = r)) when rangeContainsPos r pos -> Some r
| SyntaxNode.SynModuleOrNamespace m when rangeContainsPos m.Range pos -> Some m.Range
| _ -> None)

let rec findNested path decls =
decls
|> List.tryPick (fun d ->
match d with
// Nested Module
| SynModuleDecl.NestedModule(
moduleInfo = SynComponentInfo(attributes = attributes; longId = longId; accessibility = None)
trivia = { ModuleKeyword = Some r }) as m when longIdentContainsPos longId pos ->
Expand All @@ -103,6 +109,7 @@ let private getRangesAndPlacement input pos =
typeDefns
|> List.tryPick (fun td ->
match td with
// Class Type
| SynTypeDefn(
typeInfo = SynComponentInfo(longId = longId; accessibility = None; range = r)
typeRepr = SynTypeDefnRepr.ObjectModel _) as t when longIdentContainsPos longId pos ->
Expand All @@ -112,8 +119,9 @@ let private getRangesAndPlacement input pos =
match tryGetDeclContainingRange path pos with
| Some r -> Some(editRange, r, Before)
| _ -> None
| SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(_, members, _)) as d ->
let path = SyntaxNode.SynTypeDefn d :: path
// AutoProperty
| SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(_, members, _)) as t ->
let path = SyntaxNode.SynTypeDefn t :: path

members
|> List.tryPick (fun m ->
Expand All @@ -130,13 +138,26 @@ let private getRangesAndPlacement input pos =
| Some r -> Some(editRange, r, After)
| _ -> None
| _ -> None)
// Type Abbreviation
| SynTypeDefn(
typeInfo = SynComponentInfo(accessibility = None; range = r)
typeRepr = SynTypeDefnRepr.Simple(simpleRepr = SynTypeDefnSimpleRepr.TypeAbbrev _)) as t when
rangeContainsPos r pos
->
let editRange = r.WithEnd r.Start
let path = SyntaxNode.SynTypeDefn t :: path

match tryGetDeclContainingRange path pos with
| Some r -> Some(editRange, r, Before)
| _ -> None
| _ -> None)
| _ -> None)

let visitor =
{ new SyntaxVisitorBase<_>() with
member _.VisitBinding(path, _, synBinding) =
match synBinding with
// explicit Ctor
| SynBinding(valData = SynValData(memberFlags = Some({ MemberKind = SynMemberKind.Constructor }))) -> None
| SynBinding(headPat = headPat; kind = SynBindingKind.Normal) as s when
rangeContainsPos s.RangeOfHeadPattern pos
Expand Down
26 changes: 25 additions & 1 deletion test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ let private addPrivateAccessModifierTests state =
with
member private _.Foo x = x
"""

testCaseAsync "add private is not offered for Record type definition" // ref finding might not show us type inferred usages
<| CodeFix.checkNotApplicable
server
Expand Down Expand Up @@ -1055,6 +1055,30 @@ let private addPrivateAccessModifierTests state =
"""
Diagnostics.acceptAll
selectCodeFix

testCaseAsync "add private works for type abbreviation"
<| CodeFix.check
server
"""
type My$0Int = int
"""
Diagnostics.acceptAll
selectCodeFix
"""
type private MyInt = int
"""

testCaseAsync "add private is not offered for type abbreviation with reference outside its declaring module"
<| CodeFix.checkNotApplicable
server
"""
module M =
type My$0Int = int
let x: M.MyInt = 23
"""
Diagnostics.acceptAll
selectCodeFix
])

let private convertTripleSlashCommentToXmlTaggedDocTests state =
Expand Down

0 comments on commit fde67bd

Please sign in to comment.