Skip to content

Commit e0e46d7

Browse files
committed
Add support for tuples and attributes.
1 parent ec16276 commit e0e46d7

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/AddFunctionToSignatureFileAction.fs

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ open JetBrains.ReSharper.Resources.Shell
1212
open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Tree
1313
open JetBrains.ReSharper.Psi.Tree
1414

15+
[<RequireQualifiedAccess>]
16+
type private ParameterNameFromPattern =
17+
| NoNameFound
18+
| SingleName of name: IFSharpIdentifier * attributes: string
19+
| TupleName of ParameterNameFromPattern list
20+
1521
[<ContextAction(Name = "AddFunctionToSignatureFile", Group = "F#", Description = "Add function to signature file")>]
1622
type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvider) =
1723
inherit FSharpContextActionBase(dataProvider)
@@ -23,11 +29,26 @@ type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvi
2329
|> Option.bind (fun range -> if range.FileName.EndsWith(".fs") then Some valSymbol else None)
2430
| _ -> None
2531

26-
let rec tryFindParameterName (p: IFSharpPattern) =
32+
let rec tryFindParameterName (isTopLevel: bool) (p: IFSharpPattern) : ParameterNameFromPattern =
2733
match p.IgnoreInnerParens() with
28-
| :? ITypedPat as tp -> tryFindParameterName tp.Pattern
29-
| :? ILocalReferencePat as rp -> Some rp.Identifier
30-
| _ -> None
34+
| :? ITypedPat as tp -> tryFindParameterName isTopLevel tp.Pattern
35+
| :? ILocalReferencePat as rp -> ParameterNameFromPattern.SingleName (rp.Identifier, "")
36+
| :? IAttribPat as ap ->
37+
match tryFindParameterName isTopLevel ap.Pattern with
38+
| ParameterNameFromPattern.SingleName(name, _) ->
39+
let attributes = Seq.map (fun (al:IAttributeList) -> al.GetText()) ap.AttributeListsEnumerable |> String.concat ""
40+
ParameterNameFromPattern.SingleName(name, attributes)
41+
| _ ->
42+
ParameterNameFromPattern.NoNameFound
43+
| :? ITuplePat as tp ->
44+
if not isTopLevel then
45+
ParameterNameFromPattern.NoNameFound
46+
else
47+
48+
Seq.map (tryFindParameterName false) tp.Patterns
49+
|> Seq.toList
50+
|> ParameterNameFromPattern.TupleName
51+
| _ -> ParameterNameFromPattern.NoNameFound
3152

3253
let implBindingAndDecl =
3354
let currentFSharpFile = dataProvider.PsiFile
@@ -102,22 +123,34 @@ type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvi
102123
replace t (factory.WrapParenAroundTypeUsageForSignature(t))
103124
| _ -> ()
104125
else
105-
// TODO: take tuples into account.
106-
let parameterAtIndex = tryFindParameterName (binding.ParameterPatterns.Item(index))
126+
let parameterAtIndex = tryFindParameterName true (binding.ParameterPatterns.Item(index))
107127

108128
match t, parameterAtIndex with
109-
| :? IFunctionTypeUsage as ft, Some parameterName ->
129+
| :? IFunctionTypeUsage as ft, ParameterNameFromPattern.NoNameFound ->
130+
visit (index + 1) ft.ReturnTypeUsage
131+
132+
| :? IFunctionTypeUsage as ft, ParameterNameFromPattern.SingleName (name, attributes) ->
110133
match ft.ArgumentTypeUsage with
111134
| :? IParameterSignatureTypeUsage as pstu ->
112-
// Update the parameter name if it was found in the implementation file
113-
// calling SetIdentifier on pstu does not add a ':' token.
114-
let namedTypeUsage = factory.CreateParameterSignatureTypeUsage(parameterName, pstu.TypeUsage)
115-
replace ft.ArgumentTypeUsage namedTypeUsage
135+
factory.CreateParameterSignatureTypeUsage(attributes, name, pstu.TypeUsage)
136+
|> replace ft.ArgumentTypeUsage
116137
| _ -> ()
117138

118139
visit (index + 1) ft.ReturnTypeUsage
119-
| :? IFunctionTypeUsage as ft, None ->
120-
visit (index + 1) ft.ReturnTypeUsage
140+
141+
| :? IFunctionTypeUsage as ft, ParameterNameFromPattern.TupleName multipleParameterNames ->
142+
match ft.ArgumentTypeUsage with
143+
| :? ITupleTypeUsage as tt when tt.Items.Count = multipleParameterNames.Length ->
144+
(multipleParameterNames, tt.Items)
145+
||> Seq.zip
146+
|> Seq.iter (fun (p,t) ->
147+
match t, p with
148+
| :? IParameterSignatureTypeUsage as pstu, ParameterNameFromPattern.SingleName (name, attributes) ->
149+
factory.CreateParameterSignatureTypeUsage(attributes, name, pstu.TypeUsage)
150+
|> replace t
151+
| _ -> ()
152+
)
153+
| _ -> visit (index + 1) ft.ReturnTypeUsage
121154
| _ ->
122155
()
123156

ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Intentions/AddFunctionToSignatureFileActionTest.fs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ type AddFunctionToSignatureFileActionTest() =
2222
[<Test>] member x.``Simple Binding - 02`` () = x.DoNamedTestWithSignature()
2323
[<Test>] member x.``Simple Binding - 03`` () = x.DoNamedTestWithSignature()
2424
[<Test>] member x.``Simple Binding - 04`` () = x.DoNamedTestWithSignature()
25+
[<Test>] member x.``Tuple parameter - 01`` () = x.DoNamedTestWithSignature()
26+
[<Test>] member x.``Tuple parameter - 02`` () = x.DoNamedTestWithSignature()
27+
[<Test>] member x.``Attribute in parameter - 01`` () = x.DoNamedTestWithSignature()
28+
[<Test>] member x.``Attribute in parameter - 02`` () = x.DoNamedTestWithSignature()

0 commit comments

Comments
 (0)