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/src/Intentions/AddFunctionToSignatureFileAction.fs b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/AddFunctionToSignatureFileAction.fs index 3c505069e1..1706652c0d 100644 --- a/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/AddFunctionToSignatureFileAction.fs +++ b/ReSharper.FSharp/src/FSharp.Psi.Intentions/src/Intentions/AddFunctionToSignatureFileAction.fs @@ -116,8 +116,8 @@ type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvi use writeCookie = WriteLockCookie.Create(binding.IsPhysical()) use disableFormatter = new DisableCodeFormatter() - let factory = signatureModuleOrNamespaceDecl.CreateElementFactory() - let typeInfo = factory.CreateTypeUsageForSignature(text) + 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) = @@ -127,7 +127,9 @@ type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvi // 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. - replace t (factory.WrapParenAroundTypeUsageForSignature(t)) + let parenType = factory.CreateParenType() + replace parenType.InnerTypeUsage t + replace t parenType | _ -> () else let parameterAtIndex = tryFindParameterName true (binding.ParameterPatterns.Item(index)) @@ -139,8 +141,7 @@ type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvi | :? IFunctionTypeUsage as ft, ParameterNameFromPattern.SingleName (name, attributes) -> match ft.ArgumentTypeUsage with | :? IParameterSignatureTypeUsage as pstu -> - factory.CreateParameterSignatureTypeUsage(attributes, name, pstu.TypeUsage) - |> replace ft.ArgumentTypeUsage + pstu.SetIdentifier(name) |> ignore | _ -> () visit (index + 1) ft.ReturnTypeUsage @@ -153,8 +154,7 @@ type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvi |> Seq.iter (fun (p,t) -> match t, p with | :? IParameterSignatureTypeUsage as pstu, ParameterNameFromPattern.SingleName (name, attributes) -> - factory.CreateParameterSignatureTypeUsage(attributes, name, pstu.TypeUsage) - |> replace t + pstu.SetIdentifier(name) |> ignore | _ -> () ) | _ -> visit (index + 1) ft.ReturnTypeUsage @@ -164,7 +164,10 @@ type AddFunctionToSignatureFileAction(dataProvider: FSharpContextActionDataProvi if not binding.ParameterPatterns.IsEmpty then visit 0 typeInfo - let valSig = factory.CreateBindingSignature(refPat, typeInfo) + let valSig = + let signatureFactory = signatureModuleOrNamespaceDecl.CreateElementFactory() + signatureFactory.CreateBindingSignature(refPat, typeInfo) + let newlineNode = NewLine(signatureModuleOrNamespaceDecl.GetLineEnding()) :> ITreeNode addNodesAfter signatureModuleOrNamespaceDecl.LastChild [| newlineNode; valSig |] |> ignore 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); } }