diff --git a/ReSharper.FSharp/src/FSharp.Psi.Features/src/LanguageService/FSharpElementFactory.fs b/ReSharper.FSharp/src/FSharp.Psi.Features/src/LanguageService/FSharpElementFactory.fs index ab4f5b5293..0557a02d6b 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Features/src/LanguageService/FSharpElementFactory.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Features/src/LanguageService/FSharpElementFactory.fs @@ -94,6 +94,11 @@ type FSharpElementFactory(languageService: IFSharpLanguageService, sourceFile: I let exprStatement = getExpressionStatement source exprStatement.AttributeLists[0] + let createBindingSignature () = + let source = "module V\nval a: obj" + let moduleMember = getModuleMember source + moduleMember :?> IBindingSignature + interface IFSharpElementFactory with member x.CreateOpenStatement(ns) = // todo: mangle ns @@ -342,6 +347,12 @@ type FSharpElementFactory(languageService: IFSharpLanguageService, sourceFile: I | _ -> System.ArgumentOutOfRangeException() |> raise + member x.CreateParenType() : IParenTypeUsage = + let expr = getExpression "do () : (unit)" + let doExpr = expr :?> IDoExpr + let typedExpr = doExpr.Expression :?> ITypedExpr + typedExpr.TypeUsage :?> IParenTypeUsage + member x.CreateSetExpr(left: IFSharpExpression, right: IFSharpExpression) = let source = "() <- ()" let expr = getExpression source @@ -385,3 +396,10 @@ type FSharpElementFactory(languageService: IFSharpLanguageService, sourceFile: I moduleMember.As().TypeDeclarations[0] :?> IFSharpTypeDeclaration typeDeclaration.TypeParameterDeclarationList + + member x.CreateBindingSignature(bindingName: IFSharpPattern, returnType: ITypeUsage) = + assert sourceFile.IsFSharpSignatureFile + let signature = createBindingSignature () + signature.SetHeadPattern(bindingName) |> ignore + replace signature.ReturnTypeInfo.ReturnType returnType + signature \ No newline at end of file diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj b/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj index 64e69bee68..59df8c7b97 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj @@ -25,6 +25,7 @@ + diff --git a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/AddFunctionToSignatureFileAction.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/AddFunctionToSignatureFileAction.fs new file mode 100644 index 0000000000..1706652c0d --- /dev/null +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/AddFunctionToSignatureFileAction.fs @@ -0,0 +1,176 @@ +namespace JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions + +open FSharp.Compiler.Text +open FSharp.Compiler.Symbols +open JetBrains.ReSharper.Feature.Services.ContextActions +open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions +open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree +open JetBrains.ReSharper.Plugins.FSharp.Psi +open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl +open JetBrains.ReSharper.Psi.ExtensionsAPI +open JetBrains.ReSharper.Resources.Shell +open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl.Tree +open JetBrains.ReSharper.Psi.Tree + +[] +type private ParameterNameFromPattern = + | NoNameFound + | SingleName of name: IFSharpIdentifier * attributes: string + | TupleName of ParameterNameFromPattern list + +[] +type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvider) = + inherit FSharpContextActionBase(dataProvider) + + let (|ValFromImpl|_|) (symbol:FSharpSymbol) = + match symbol with + | :? FSharpMemberOrFunctionOrValue as valSymbol -> + let hasConstraints = + valSymbol.GenericParameters + |> Seq.exists (fun gp -> not (Seq.isEmpty gp.Constraints)) + + // Ignore constraints for now. + if hasConstraints then None else + + valSymbol.SignatureLocation + |> Option.bind (fun range -> if range.FileName.EndsWith(".fs") then Some valSymbol else None) + | _ -> None + + let rec tryFindParameterName (isTopLevel: bool) (p: IFSharpPattern) : ParameterNameFromPattern = + match p.IgnoreInnerParens() with + | :? ITypedPat as tp -> tryFindParameterName isTopLevel tp.Pattern + | :? ILocalReferencePat as rp -> ParameterNameFromPattern.SingleName (rp.Identifier, "") + | :? IAttribPat as ap -> + match tryFindParameterName isTopLevel ap.Pattern with + | ParameterNameFromPattern.SingleName(name, _) -> + let attributes = Seq.map (fun (al:IAttributeList) -> al.GetText()) ap.AttributeListsEnumerable |> String.concat "" + ParameterNameFromPattern.SingleName(name, attributes) + | _ -> + ParameterNameFromPattern.NoNameFound + | :? ITuplePat as tp -> + if not isTopLevel then + ParameterNameFromPattern.NoNameFound + else + + Seq.map (tryFindParameterName false) tp.Patterns + |> Seq.toList + |> ParameterNameFromPattern.TupleName + | _ -> ParameterNameFromPattern.NoNameFound + + let implBindingAndDecl = + let currentFSharpFile = dataProvider.PsiFile + if isNull currentFSharpFile then None else + // Don't show context action in signature file. + if currentFSharpFile.IsFSharpSigFile() then None else + + let fcsService = currentFSharpFile.FcsCheckerService + if isNull fcsService || isNull fcsService.FcsProjectProvider then None else + + let hasSignature = fcsService.FcsProjectProvider.HasPairFile dataProvider.SourceFile + if not hasSignature then None else + + let letBindings = dataProvider.GetSelectedElement() + if isNull letBindings then None else + // Currently excluding recursive bindings + if letBindings.Bindings.Count <> 1 then None else + let binding = letBindings.Bindings |> Seq.exactlyOne + let refPat = binding.HeadPattern.As() + if isNull refPat || isNull refPat.Reference then None else + + let moduleOrNamespaceDecl = QualifiableModuleLikeDeclarationNavigator.GetByMember(letBindings) + if isNull moduleOrNamespaceDecl then None else + let moduleOrNamespaceDeclaredElement = moduleOrNamespaceDecl.DeclaredElement + if isNull moduleOrNamespaceDeclaredElement then None else + + let signatureCounterPart = + moduleOrNamespaceDeclaredElement.GetDeclarations() + |> Seq.tryPick (fun d -> if d.IsFSharpSigFile() then Some d else None) + + match signatureCounterPart with + | None -> None + | Some signatureCounterPart -> + + let symbolUse = refPat.GetFcsSymbolUse() + if isNull symbolUse then None else + + match symbolUse.Symbol with + | ValFromImpl valSymbol -> + let text = + valSymbol.FormatLayout(symbolUse.DisplayContext) + |> Array.choose (fun (t : TaggedText) -> + match t.Tag with + | TextTag.UnknownEntity -> None + | _ -> Some t.Text) + |> String.concat "" + + Some (refPat, binding, text, signatureCounterPart) + | _ -> None + + override this.IsAvailable _ = Option.isSome implBindingAndDecl + + override this.ExecutePsiTransaction(_solution, _progress) = + match implBindingAndDecl with + | None -> null + | Some (refPat, binding, text, signatureModuleOrNamespaceDecl) -> + + use writeCookie = WriteLockCookie.Create(binding.IsPhysical()) + use disableFormatter = new DisableCodeFormatter() + + let factory = binding.CreateElementFactory() + let typeInfo = factory.CreateTypeUsage(text, TypeUsageContext.Return) + + // Enrich the type info with the found parameters from binding. + let rec visit (index:int) (t: ITypeUsage) = + if index = binding.ParameterPatterns.Count then + match t with + | :? IFunctionTypeUsage -> + // If the return type is a function itself, the safest thing to do is to wrap it in parentheses. + // Example: `let g _ = (*) 3` + // `val g: 'a -> int -> int` is not valid, `val g: 'a -> (int -> int)` is. + let parenType = factory.CreateParenType() + replace parenType.InnerTypeUsage t + replace t parenType + | _ -> () + else + let parameterAtIndex = tryFindParameterName true (binding.ParameterPatterns.Item(index)) + + match t, parameterAtIndex with + | :? IFunctionTypeUsage as ft, ParameterNameFromPattern.NoNameFound -> + visit (index + 1) ft.ReturnTypeUsage + + | :? IFunctionTypeUsage as ft, ParameterNameFromPattern.SingleName (name, attributes) -> + match ft.ArgumentTypeUsage with + | :? IParameterSignatureTypeUsage as pstu -> + pstu.SetIdentifier(name) |> ignore + | _ -> () + + visit (index + 1) ft.ReturnTypeUsage + + | :? IFunctionTypeUsage as ft, ParameterNameFromPattern.TupleName multipleParameterNames -> + match ft.ArgumentTypeUsage with + | :? ITupleTypeUsage as tt when tt.Items.Count = multipleParameterNames.Length -> + (multipleParameterNames, tt.Items) + ||> Seq.zip + |> Seq.iter (fun (p,t) -> + match t, p with + | :? IParameterSignatureTypeUsage as pstu, ParameterNameFromPattern.SingleName (name, attributes) -> + pstu.SetIdentifier(name) |> ignore + | _ -> () + ) + | _ -> visit (index + 1) ft.ReturnTypeUsage + | _ -> + () + + if not binding.ParameterPatterns.IsEmpty then + visit 0 typeInfo + + let valSig = + let signatureFactory = signatureModuleOrNamespaceDecl.CreateElementFactory() + signatureFactory.CreateBindingSignature(refPat, typeInfo) + + let newlineNode = NewLine(signatureModuleOrNamespaceDecl.GetLineEnding()) :> ITreeNode + addNodesAfter signatureModuleOrNamespaceDecl.LastChild [| newlineNode; valSig |] |> ignore + + null + + override this.Text = "Add function to signature file" diff --git a/ReSharper.FSharp/src/FSharp.Psi/src/IFSharpElementFactory.cs b/ReSharper.FSharp/src/FSharp.Psi/src/IFSharpElementFactory.cs index a7c14531f0..0e70dd393e 100644 --- a/ReSharper.FSharp/src/FSharp.Psi/src/IFSharpElementFactory.cs +++ b/ReSharper.FSharp/src/FSharp.Psi/src/IFSharpElementFactory.cs @@ -41,6 +41,7 @@ public interface IFSharpElementFactory ITypedPat CreateTypedPat(IFSharpPattern pattern, ITypeUsage typeUsage); ITypeUsage CreateTypeUsage(string typeUsage, TypeUsageContext context); + IParenTypeUsage CreateParenType(); IReturnTypeInfo CreateReturnTypeInfo(ITypeUsage typeSignature); @@ -62,5 +63,7 @@ public interface IFSharpElementFactory IMemberDeclaration CreatePropertyWithAccessor(string propertyName, string accessorName, FSharpList args); ITypeParameterDeclarationList CreateTypeParameterOfTypeList(FSharpList names); + + IBindingSignature CreateBindingSignature(IFSharpPattern bindingName, ITypeUsage returnType); } } diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fs new file mode 100644 index 0000000000..5a30b3caf5 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fs @@ -0,0 +1,4 @@ +module Test + +open System.Diagnostics.CodeAnalysis +let x{caret} ([] y) = y + 0 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fs.gold new file mode 100644 index 0000000000..5a30b3caf5 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fs.gold @@ -0,0 +1,4 @@ +module Test + +open System.Diagnostics.CodeAnalysis +let x{caret} ([] y) = y + 0 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fsi new file mode 100644 index 0000000000..84ca8d66f7 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fsi @@ -0,0 +1,2 @@ +module Test +open System.Diagnostics.CodeAnalysis diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fsi.gold new file mode 100644 index 0000000000..101aa6088e --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 01.fsi.gold @@ -0,0 +1,3 @@ +module Test +open System.Diagnostics.CodeAnalysis +val x: [] y: int -> int diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fs new file mode 100644 index 0000000000..e3fdd5c484 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fs @@ -0,0 +1,3 @@ +module Test + +let x{caret} ([] y : int) = y + 0 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fs.gold new file mode 100644 index 0000000000..e3fdd5c484 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fs.gold @@ -0,0 +1,3 @@ +module Test + +let x{caret} ([] y : int) = y + 0 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fsi new file mode 100644 index 0000000000..ac248bbd7a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fsi @@ -0,0 +1 @@ +module Test diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fsi.gold new file mode 100644 index 0000000000..7c2ef7b351 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 02.fsi.gold @@ -0,0 +1,2 @@ +module Test +val x: [] y: int -> int diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fs new file mode 100644 index 0000000000..5199180c5b --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fs @@ -0,0 +1,3 @@ +module Test +open System.Diagnostics.CodeAnalysis +let x{caret} ([] y : int, [] z: string) = y + 0 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fs.gold new file mode 100644 index 0000000000..5199180c5b --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fs.gold @@ -0,0 +1,3 @@ +module Test +open System.Diagnostics.CodeAnalysis +let x{caret} ([] y : int, [] z: string) = y + 0 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fsi new file mode 100644 index 0000000000..84ca8d66f7 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fsi @@ -0,0 +1,2 @@ +module Test +open System.Diagnostics.CodeAnalysis diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fsi.gold new file mode 100644 index 0000000000..a5bc0e9549 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Attribute in parameter - 03.fsi.gold @@ -0,0 +1,3 @@ +module Test +open System.Diagnostics.CodeAnalysis +val x: [] y: int * [] z: string -> int diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fs new file mode 100644 index 0000000000..e0c44abb74 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fs @@ -0,0 +1,7 @@ +module Test + +let memoizeBy{caret} (g: 'a -> 'c) (f: 'a -> 'b) = + let cache = + System.Collections.Concurrent.ConcurrentDictionary<_, _>(HashIdentity.Structural) + + fun x -> cache.GetOrAdd(Some(g x), lazy (f x)).Force() diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fs.gold new file mode 100644 index 0000000000..b6b78ddc05 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fs.gold @@ -0,0 +1 @@ +NOT AVAILABLE diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fsi new file mode 100644 index 0000000000..ac248bbd7a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Generic constraints - 01.fsi @@ -0,0 +1 @@ +module Test diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fs new file mode 100644 index 0000000000..4bdf207535 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fs @@ -0,0 +1,3 @@ +module Test + +let a{caret} b c = b + c diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fs.gold new file mode 100644 index 0000000000..4bdf207535 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fs.gold @@ -0,0 +1,3 @@ +module Test + +let a{caret} b c = b + c diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fsi new file mode 100644 index 0000000000..ac248bbd7a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fsi @@ -0,0 +1 @@ +module Test diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fsi.gold new file mode 100644 index 0000000000..4adea847f5 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 01.fsi.gold @@ -0,0 +1,2 @@ +module Test +val a: b: int -> c: int -> int diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fs new file mode 100644 index 0000000000..e5631656ef --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fs @@ -0,0 +1,3 @@ +module Test + +let a{caret} (b:string) c = c + 1 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fs.gold new file mode 100644 index 0000000000..e5631656ef --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fs.gold @@ -0,0 +1,3 @@ +module Test + +let a{caret} (b:string) c = c + 1 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fsi new file mode 100644 index 0000000000..ac248bbd7a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fsi @@ -0,0 +1 @@ +module Test diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fsi.gold new file mode 100644 index 0000000000..a9c861cbe7 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 02.fsi.gold @@ -0,0 +1,2 @@ +module Test +val a: b: string -> c: int -> int diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fs new file mode 100644 index 0000000000..75f248e77b --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fs @@ -0,0 +1,3 @@ +module Test + +let a{caret} b (c: char) d = b + d + 1 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fs.gold new file mode 100644 index 0000000000..75f248e77b --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fs.gold @@ -0,0 +1,3 @@ +module Test + +let a{caret} b (c: char) d = b + d + 1 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fsi new file mode 100644 index 0000000000..ac248bbd7a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fsi @@ -0,0 +1 @@ +module Test diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fsi.gold new file mode 100644 index 0000000000..e6b8a99f20 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 03.fsi.gold @@ -0,0 +1,2 @@ +module Test +val a: b: int -> c: char -> d: int -> int diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fs new file mode 100644 index 0000000000..efd73b1add --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fs @@ -0,0 +1,3 @@ +module Test + +let a{caret} b : int = printfn "%s" b ; 0 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fs.gold new file mode 100644 index 0000000000..efd73b1add --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fs.gold @@ -0,0 +1,3 @@ +module Test + +let a{caret} b : int = printfn "%s" b ; 0 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fsi new file mode 100644 index 0000000000..ac248bbd7a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fsi @@ -0,0 +1 @@ +module Test diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fsi.gold new file mode 100644 index 0000000000..0becddf6fd --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Simple Binding - 04.fsi.gold @@ -0,0 +1,2 @@ +module Test +val a: b: string -> int diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fs new file mode 100644 index 0000000000..e0f5baffb8 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fs @@ -0,0 +1,3 @@ +module Test + +let a{caret} (b, c) = b + c diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fs.gold new file mode 100644 index 0000000000..e0f5baffb8 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fs.gold @@ -0,0 +1,3 @@ +module Test + +let a{caret} (b, c) = b + c diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fsi new file mode 100644 index 0000000000..ac248bbd7a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fsi @@ -0,0 +1 @@ +module Test diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fsi.gold new file mode 100644 index 0000000000..3e94793c05 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 01.fsi.gold @@ -0,0 +1,2 @@ +module Test +val a: b: int * c: int -> int diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fs b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fs new file mode 100644 index 0000000000..be9be71d10 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fs @@ -0,0 +1,3 @@ +module Test + +let a{caret} (b, _, d) = printfn "%b" d ; b + 1 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fs.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fs.gold new file mode 100644 index 0000000000..be9be71d10 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fs.gold @@ -0,0 +1,3 @@ +module Test + +let a{caret} (b, _, d) = printfn "%b" d ; b + 1 diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fsi b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fsi new file mode 100644 index 0000000000..ac248bbd7a --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fsi @@ -0,0 +1 @@ +module Test diff --git a/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fsi.gold b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fsi.gold new file mode 100644 index 0000000000..bcd5472988 --- /dev/null +++ b/ReSharper.FSharp/test/data/features/intentions/addFunctionToSignature/Tuple parameter - 02.fsi.gold @@ -0,0 +1,2 @@ +module Test +val a: b: int * 'a * d: bool -> int diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/FSharp.Intentions.Tests.fsproj b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/FSharp.Intentions.Tests.fsproj index 3dbcefcdc4..80f5f9c517 100644 --- a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/FSharp.Intentions.Tests.fsproj +++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/FSharp.Intentions.Tests.fsproj @@ -47,6 +47,7 @@ + diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Intentions/AddFunctionToSignatureFileActionTest.fs b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Intentions/AddFunctionToSignatureFileActionTest.fs new file mode 100644 index 0000000000..a087896bae --- /dev/null +++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Intentions/AddFunctionToSignatureFileActionTest.fs @@ -0,0 +1,33 @@ +namespace JetBrains.ReSharper.Plugins.FSharp.Tests.Intentions.Intentions + +open JetBrains.ReSharper.Plugins.FSharp +open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Intentions +open NUnit.Framework + +type AddFunctionToSignatureFileActionTest() = + inherit FSharpContextActionExecuteTestBase() + + // TODO: is there an equivalent to CheckAllFiles for FSharpContextActionExecuteTestBase<'T>? + // override this.CheckAllFiles = true + + override this.ExtraPath = "addFunctionToSignature" + + member x.DoNamedTestWithSignature() = + let testName = x.TestMethodName + let fsExt = FSharpProjectFileType.FsExtension + let fsiExt = FSharpSignatureProjectFileType.FsiExtension + x.DoTestSolution(testName + fsiExt, testName + fsExt) + + [] member x.``Simple Binding - 01`` () = x.DoNamedTestWithSignature() + [] member x.``Simple Binding - 02`` () = x.DoNamedTestWithSignature() + [] member x.``Simple Binding - 03`` () = x.DoNamedTestWithSignature() + [] member x.``Simple Binding - 04`` () = x.DoNamedTestWithSignature() + [] member x.``Tuple parameter - 01`` () = x.DoNamedTestWithSignature() + [] member x.``Tuple parameter - 02`` () = x.DoNamedTestWithSignature() + [] member x.``Attribute in parameter - 01`` () = x.DoNamedTestWithSignature() + [] member x.``Attribute in parameter - 02`` () = x.DoNamedTestWithSignature() + [] member x.``Attribute in parameter - 03`` () = x.DoNamedTestWithSignature() + // Ignore generic constraints for now + + // This test requires `when 'c: equality` at the end of the signature. + [] member x.``Generic constraints - 01`` () = x.DoNamedTestWithSignature()