diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Stages/PatternTypeHintsStage.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Stages/PatternTypeHintsStage.fs
index a318be54ef..e41b415e0a 100644
--- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Stages/PatternTypeHintsStage.fs
+++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Daemon/src/Stages/PatternTypeHintsStage.fs
@@ -11,6 +11,7 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi.Daemon.Highlightings.FSharpTypeHints
open JetBrains.ReSharper.Plugins.FSharp.Psi.Daemon.Utils.VisibleRangeContainer
open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings
open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Stages
+open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util.FcsTypeUtil
open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl
open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree
open JetBrains.ReSharper.Plugins.FSharp.Psi.Util
@@ -201,11 +202,9 @@ type private PatternsHighlightingProcess(fsFile, settingsStore: IContextBoundSet
if isNull symbol then ValueNone else
let fcsType = symbol.FullType
+ let pattern, fcsType = tryGetOuterOptionalParameterAndItsType refPat fcsType
let range = pattern.GetNavigationRange().EndOffsetRange()
- let isOptional = isNotNull (OptionalValPatNavigator.GetByPattern(refPat))
- let fcsType = if isOptional && isOption fcsType then fcsType.GenericArguments[0] else fcsType
-
createTypeHintHighlighting fcsType defaultDisplayContext range pushToHintMode actionsProvider false
|> ValueSome
diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj
index bcce22fda4..ce524fa30f 100644
--- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj
+++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/FSharp.Psi.Intentions.fsproj
@@ -36,7 +36,7 @@
-
+
diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/FunctionAnnotationAction.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/AnnotationActions.fs
similarity index 78%
rename from ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/FunctionAnnotationAction.fs
rename to ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/AnnotationActions.fs
index 50f63521a5..797ee4908f 100644
--- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/FunctionAnnotationAction.fs
+++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/Intentions/AnnotationActions.fs
@@ -50,7 +50,12 @@ module SpecifyTypes =
parenPat.SetPattern(pattern) |> ignore
parenPat :> IFSharpPattern
- let specifyParameterType displayContext (fcsType: FSharpType) (pattern: IFSharpPattern) =
+ let specifyPatternType displayContext (fcsType: FSharpType) (pattern: IFSharpPattern) =
+ let pattern, fcsType =
+ match pattern with
+ | :? IReferencePat as pattern -> FcsTypeUtil.tryGetOuterOptionalParameterAndItsType pattern fcsType
+ | _ -> pattern, fcsType
+
let pattern = pattern.IgnoreParentParens()
let factory = pattern.CreateElementFactory()
@@ -61,13 +66,11 @@ module SpecifyTypes =
let typedPat =
let typeUsage = factory.CreateTypeUsage(fcsType.Format(displayContext), TypeUsageContext.TopLevel)
- let typedPat = factory.CreateTypedPat(newPattern, typeUsage)
- if isNull (TuplePatNavigator.GetByPattern(pattern)) then
- addParens factory typedPat
- else
- typedPat :> _
+ factory.CreateTypedPat(newPattern, typeUsage)
- ModificationUtil.ReplaceChild(pattern, typedPat) |> ignore
+ ModificationUtil.ReplaceChild(pattern, typedPat)
+ |> ParenPatUtil.addParensIfNeeded
+ |> ignore
let specifyPropertyType displayContext (fcsType: FSharpType) (decl: IMemberDeclaration) =
Assertion.Assert(isNull decl.ReturnTypeInfo, "isNull decl.ReturnTypeInfo")
@@ -104,7 +107,7 @@ type FunctionAnnotationAction(dataProvider: FSharpContextActionDataProvider) =
| TupleLikePattern pat when isTopLevel ->
specifyParameterTypes fcsType.GenericArguments pat.Patterns false
| pattern ->
- SpecifyTypes.specifyParameterType displayContext fcsType pattern
+ SpecifyTypes.specifyPatternType displayContext fcsType pattern
specifyParameterTypes types parameters true
@@ -153,3 +156,34 @@ type FunctionAnnotationAction(dataProvider: FSharpContextActionDataProvider) =
if isNull binding.ReturnTypeInfo then
SpecifyTypes.specifyBindingReturnType displayContext mfv binding
+
+
+[,
+ Description = "Annotate named parameter/pattern with it is type")>]
+type PatternAnnotationAction(dataProvider: FSharpContextActionDataProvider) =
+ inherit FSharpContextActionBase(dataProvider)
+ override x.Text = "Add type annotation"
+
+ override x.IsAvailable _ =
+ let pattern = dataProvider.GetSelectedElement().IgnoreParentParens()
+ let pattern =
+ match OptionalValPatNavigator.GetByPattern(pattern) with
+ | null -> pattern
+ | x -> x
+
+ isNotNull pattern &&
+ isNull (TypedPatNavigator.GetByPattern(pattern)) &&
+ isNull (BindingNavigator.GetByHeadPattern(pattern))
+
+ override x.ExecutePsiTransaction _ =
+ let pattern = dataProvider.GetSelectedElement()
+
+ use writeCookie = WriteLockCookie.Create(pattern.IsPhysical())
+ use disableFormatter = new DisableCodeFormatter()
+
+ let symbolUse = pattern.GetFcsSymbolUse()
+
+ let mfv = symbolUse.Symbol :?> FSharpMemberOrFunctionOrValue
+ let displayContext = symbolUse.DisplayContext
+
+ SpecifyTypes.specifyPatternType displayContext mfv.FullType pattern
diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterBaseTypeFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterBaseTypeFix.fs
index 31f0780780..01e4d08b7b 100644
--- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterBaseTypeFix.fs
+++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterBaseTypeFix.fs
@@ -122,7 +122,7 @@ type SpecifyParameterBaseTypeFix(refExpr: IReferenceExpr, typeUsage: ITypeUsage)
use writeCookie = WriteLockCookie.Create(pat.IsPhysical())
let baseType, displayContext = baseType.Value
- SpecifyTypes.specifyParameterType displayContext baseType pat
+ SpecifyTypes.specifyPatternType displayContext baseType pat
override this.Execute(solution, textControl) =
let fcsEntity, displayContext = getFcsEntity typeUsage |> Option.get
diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterTypeFix.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterTypeFix.fs
index 498ba35449..9af139d3f7 100644
--- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterTypeFix.fs
+++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Intentions/src/QuickFixes/SpecifyParameterTypeFix.fs
@@ -81,7 +81,7 @@ type SpecifyParameterTypeFix(qualifiedExpr: IQualifiedExpr) =
override this.SpecifyType(decl, mfv, d) =
let decl = decl :?> ILocalReferencePat
- SpecifyTypes.specifyParameterType d mfv.FullType decl
+ SpecifyTypes.specifyPatternType d mfv.FullType decl
type SpecifyPropertyTypeFix(qualifiedExpr: IQualifiedExpr) =
diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs
index 618c270bf4..a34bc69e2f 100644
--- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs
+++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/FcsTypeUtil.fs
@@ -1,6 +1,8 @@
module JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util.FcsTypeUtil
open FSharp.Compiler.Symbols
+open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree
+open JetBrains.ReSharper.Plugins.FSharp.Util
let getFunctionTypeArgs includeReturnType fcsType =
let rec loop (fcsType: FSharpType) acc =
@@ -19,3 +21,8 @@ let getFunctionTypeArgs includeReturnType fcsType =
acc
loop fcsType [] |> List.rev
+
+let tryGetOuterOptionalParameterAndItsType (pattern: IReferencePat) fcsType =
+ let optionalValPat = OptionalValPatNavigator.GetByPattern(pattern)
+ if isNotNull optionalValPat && isOption fcsType then (optionalValPat : IFSharpPattern), fcsType.GenericArguments[0]
+ else pattern, fcsType
diff --git a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/ParenPatUtil.fs b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/ParenPatUtil.fs
index 4fe8d4f311..f9b706d05e 100644
--- a/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/ParenPatUtil.fs
+++ b/ReSharper.FSharp/src/FSharp/FSharp.Psi.Services/src/Util/ParenPatUtil.fs
@@ -221,22 +221,27 @@ let addParensIfNeeded (pattern: IFSharpPattern) =
let nextSibling = nameNode.NextSibling
if isInlineSpace nextSibling && nextSibling.NextSibling == pattern && nextSibling.GetTextLength() = 1 then
- let settingsStore = pattern.GetSettingsStoreWithEditorConfig()
- let spaceBeforeUppercase =
- settingsStore.GetValue(fun (key: FSharpFormatSettingsKey) -> key.SpaceBeforeUppercaseInvocation)
+ ModificationUtil.DeleteChild(nextSibling)
- if not spaceBeforeUppercase then
- ModificationUtil.DeleteChild(nextSibling)
+ let settingsStore = parenPattern.GetSettingsStoreWithEditorConfig()
let parametersOwnerPat = ParametersOwnerPatNavigator.GetByParameter(parenPattern)
- if isNotNull parametersOwnerPat then
+ if isNotNull parametersOwnerPat &&
+ not (settingsStore.GetValue(fun (key: FSharpFormatSettingsKey) -> key.SpaceBeforeUppercaseInvocation)) then
removeSpace parametersOwnerPat.ReferenceName parenPattern
let patternDeclaration = ParametersPatternDeclarationNavigator.GetByPattern(parenPattern)
let memberDeclaration = MemberDeclarationNavigator.GetByParametersDeclaration(patternDeclaration)
- if isNotNull memberDeclaration then
+ if isNotNull memberDeclaration &&
+ not (settingsStore.GetValue(fun (key: FSharpFormatSettingsKey) -> key.SpaceBeforeUppercaseInvocation)) then
removeSpace memberDeclaration.Identifier patternDeclaration
+ let ctorDeclaration = PrimaryConstructorDeclarationNavigator.GetByParametersDeclaration(patternDeclaration)
+ let typeDeclaration = FSharpTypeDeclarationNavigator.GetByPrimaryConstructorDeclaration(ctorDeclaration)
+ if isNotNull typeDeclaration &&
+ not (settingsStore.GetValue(fun (key: FSharpFormatSettingsKey) -> key.SpaceBeforeClassConstructor)) then
+ removeSpace typeDeclaration.Identifier ctorDeclaration
+
pattern
else
pattern
diff --git a/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 08 - As.fs b/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 08 - As.fs
new file mode 100644
index 0000000000..1258536098
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 08 - As.fs
@@ -0,0 +1,3 @@
+module Module
+
+let a as (b: int) = 1
diff --git a/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 08 - As.fs.gold b/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 08 - As.fs.gold
new file mode 100644
index 0000000000..3b47ca1852
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 08 - As.fs.gold
@@ -0,0 +1,5 @@
+module Module
+
+let a as (b: int) = 1
+
+---------------------------------------------------------
diff --git a/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 09 - Named field.fs b/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 09 - Named field.fs
new file mode 100644
index 0000000000..ea086cb3d9
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 09 - Named field.fs
@@ -0,0 +1,4 @@
+module Module
+
+type R = { A: int }
+let { A = (a: int) } = failwith ""
diff --git a/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 09 - Named field.fs.gold b/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 09 - Named field.fs.gold
new file mode 100644
index 0000000000..5e6fbc4f40
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/daemon/redundantParens/pat/Typed 09 - Named field.fs.gold
@@ -0,0 +1,6 @@
+module Module
+
+type R = { A: int }
+let { A = (a: int) } = failwith ""
+
+---------------------------------------------------------
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/availability/Patterns 01.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/availability/Patterns 01.fs
new file mode 100644
index 0000000000..cdc91ac33e
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/availability/Patterns 01.fs
@@ -0,0 +1,9 @@
+module Module
+
+let x{off} = 1
+let a, b{on} = 1, 1
+
+let f{off} x{on} (So{off}me(y{on})) (z{off}: int) = ()
+
+type A() =
+ member _.M(?x{on}, ?y{off}: int) = x + y
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Ands pat 01.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Ands pat 01.fs
new file mode 100644
index 0000000000..8a2e45e871
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Ands pat 01.fs
@@ -0,0 +1,5 @@
+module Module
+
+let (|Bool|) (x: int) = true
+
+let f (x{caret} & Bool(_)) = ()
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Ands pat 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Ands pat 01.fs.gold
new file mode 100644
index 0000000000..ad7e18de3e
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Ands pat 01.fs.gold
@@ -0,0 +1,5 @@
+module Module
+
+let (|Bool|) (x: int) = true
+
+let f (x: int{caret} & Bool(_)) = ()
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/As pat 01.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/As pat 01.fs
new file mode 100644
index 0000000000..24131b5f3d
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/As pat 01.fs
@@ -0,0 +1,3 @@
+module Module
+
+let f (x, y as z{caret}) = ()
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/As pat 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/As pat 01.fs.gold
new file mode 100644
index 0000000000..9ce13b98c7
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/As pat 01.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+let f (x, y as (z: 'a * 'b){caret}) = ()
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Lambda 01.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Lambda 01.fs
new file mode 100644
index 0000000000..187e45d4d5
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Lambda 01.fs
@@ -0,0 +1,3 @@
+module Module
+
+fun x{caret} -> x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Lambda 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Lambda 01.fs.gold
new file mode 100644
index 0000000000..7f2bf28940
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Lambda 01.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+fun (x: int){caret} -> x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 01.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 01.fs
new file mode 100644
index 0000000000..e2c940f577
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 01.fs
@@ -0,0 +1,3 @@
+module Module
+
+let f x{caret} = x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 01.fs.gold
new file mode 100644
index 0000000000..98e05f2a9b
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 01.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+let f (x: int){caret} = x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 02 - Optional.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 02 - Optional.fs
new file mode 100644
index 0000000000..09ca243f2c
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 02 - Optional.fs
@@ -0,0 +1,4 @@
+module Module
+
+type A =
+ member _.M1(?x{caret}) = x.Value + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 02 - Optional.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 02 - Optional.fs.gold
new file mode 100644
index 0000000000..3b82122a9a
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Parameter 02 - Optional.fs.gold
@@ -0,0 +1,4 @@
+module Module
+
+type A =
+ member _.M1(?x: int{caret}) = x.Value + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Record field 01.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Record field 01.fs
new file mode 100644
index 0000000000..64f04dd2a0
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Record field 01.fs
@@ -0,0 +1,5 @@
+module Module
+
+type R = { A: int }
+
+let f { A = a{caret} } = ()
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Record field 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Record field 01.fs.gold
new file mode 100644
index 0000000000..99ff82b8ab
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Record field 01.fs.gold
@@ -0,0 +1,5 @@
+module Module
+
+type R = { A: int }
+
+let f { A = (a: int){caret} } = ()
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 01.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 01.fs
new file mode 100644
index 0000000000..6223b12fd1
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 01.fs
@@ -0,0 +1,3 @@
+module Module
+
+let f (a{caret}, b) = a + b
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 01.fs.gold
new file mode 100644
index 0000000000..adb7122d69
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 01.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+let f (a: int{caret}, b) = a + b
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 02 - Top level.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 02 - Top level.fs
new file mode 100644
index 0000000000..7270641ad2
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 02 - Top level.fs
@@ -0,0 +1,3 @@
+module Module
+
+let a, b{caret} = 1, 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 02 - Top level.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 02 - Top level.fs.gold
new file mode 100644
index 0000000000..865721db24
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 02 - Top level.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+let a, (b: int){caret} = 1, 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 03 - As.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 03 - As.fs
new file mode 100644
index 0000000000..bec6d0e280
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 03 - As.fs
@@ -0,0 +1,3 @@
+module Module
+
+let f (x{caret}, y as z) = ()
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 03 - As.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 03 - As.fs.gold
new file mode 100644
index 0000000000..d32dbe9277
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Tuple 03 - As.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+let f (x: 'a{caret}, y as z) = ()
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 01.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 01.fs
new file mode 100644
index 0000000000..c1898bf92a
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 01.fs
@@ -0,0 +1,3 @@
+module Module
+
+let f (Some(x{caret})) = x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 01.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 01.fs.gold
new file mode 100644
index 0000000000..bb0f7ced84
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 01.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+let f (Some(x: int{caret})) = x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 02 - Named.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 02 - Named.fs
new file mode 100644
index 0000000000..562a2d56f9
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 02 - Named.fs
@@ -0,0 +1,3 @@
+module Module
+
+let f (Some(Value = x{caret})) = x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 02 - Named.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 02 - Named.fs.gold
new file mode 100644
index 0000000000..b208f4576a
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 02 - Named.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+let f (Some(Value = (x: int){caret})) = x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 03 - Parens.fs b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 03 - Parens.fs
new file mode 100644
index 0000000000..3a7ddf08d6
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 03 - Parens.fs
@@ -0,0 +1,3 @@
+module Module
+
+let f (Some x{caret}) = x + 1
diff --git a/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 03 - Parens.fs.gold b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 03 - Parens.fs.gold
new file mode 100644
index 0000000000..2bb53247ad
--- /dev/null
+++ b/ReSharper.FSharp/test/data/features/intentions/specifyTypes/patterns/Union case 03 - Parens.fs.gold
@@ -0,0 +1,3 @@
+module Module
+
+let f (Some(x: int){caret}) = x + 1
diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Daemon/RedundantParenPatTest.fs b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Daemon/RedundantParenPatTest.fs
index b83c6c2f2f..06e77d5ae0 100644
--- a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Daemon/RedundantParenPatTest.fs
+++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Daemon/RedundantParenPatTest.fs
@@ -56,6 +56,10 @@ type RedundantParenPatTest() =
[] member x.``Typed 05 - Members param decl``() = x.DoNamedTest()
[] member x.``Typed 06 - Tuple``() = x.DoNamedTest()
[] member x.``Typed 07 - Match clause``() = x.DoNamedTest()
+ //TODO: remove parens
+ [] member x.``Typed 08 - As``() = x.DoNamedTest()
+ //TODO: remove parens
+ [] member x.``Typed 09 - Named field``() = x.DoNamedTest()
[] member x.``Wild - Function param 01``() = x.DoNamedTest()
[] member x.``Wild - Pattern param 01``() = x.DoNamedTest()
diff --git a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Intentions/SpecifyTypesTest.fs b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Intentions/SpecifyTypesTest.fs
index f8f092ef10..cfc2401f6e 100644
--- a/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Intentions/SpecifyTypesTest.fs
+++ b/ReSharper.FSharp/test/src/FSharp.Intentions.Tests/src/Intentions/SpecifyTypesTest.fs
@@ -5,7 +5,7 @@ open JetBrains.ReSharper.Plugins.FSharp.Services.Formatter
open JetBrains.ReSharper.TestFramework
open NUnit.Framework
-type SpecifyTypesActionTest() =
+type SpecifyFunctionTypesActionTest() =
inherit FSharpContextActionExecuteTestBase()
override x.ExtraPath = "specifyTypes"
@@ -58,6 +58,33 @@ type SpecifyTypesActionTest() =
[] member x.``Function - Recursive - Function 04`` () = x.DoNamedTest()
+type SpecifyPatternTypeActionTest() =
+ inherit FSharpContextActionExecuteTestBase()
+
+ override x.ExtraPath = "specifyTypes/patterns"
+
+ [] member x.``Parameter 01``() = x.DoNamedTest()
+ [] member x.``Parameter 02 - Optional``() = x.DoNamedTest()
+
+ [] member x.``Lambda 01``() = x.DoNamedTest()
+
+ [] member x.``Tuple 01``() = x.DoNamedTest()
+ [] member x.``Tuple 02 - Top level``() = x.DoNamedTest()
+ [] member x.``Tuple 03 - As``() = x.DoNamedTest()
+
+ //TODO: remove parens
+ [] member x.``Record field 01``() = x.DoNamedTest()
+
+ [] member x.``Union case 01``() = x.DoNamedTest()
+ //TODO: remove parens
+ [] member x.``Union case 02 - Named``() = x.DoNamedTest()
+ [] member x.``Union case 03 - Parens``() = x.DoNamedTest()
+
+ [] member x.``As pat 01``() = x.DoNamedTest()
+
+ [] member x.``Ands pat 01``() = x.DoNamedTest()
+
+
type SpecifyTypesActionAvailabilityTest() =
inherit FSharpContextActionAvailabilityTestBase()
@@ -71,3 +98,11 @@ type SpecifyTypesActionAvailabilityTest() =
[] member x.``LetBang - 01`` () = x.DoNamedTest()
[] member x.``UseBang - 01`` () = x.DoNamedTest()
[] member x.``AndBang - 01`` () = x.DoNamedTest()
+
+
+type SpecifyPatternTypeActionAvailabilityTest() =
+ inherit FSharpContextActionAvailabilityTestBase()
+
+ override x.ExtraPath = "specifyTypes"
+
+ [] member x.``Patterns 01``() = x.DoNamedTest()