diff --git a/Directory.Packages.props b/Directory.Packages.props
index efe44081a..3e6e95bce 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -8,9 +8,9 @@
-
+
-
+
diff --git a/src/FSharpLint.Core/Framework/Ast.fs b/src/FSharpLint.Core/Framework/Ast.fs
index a290b4b68..1c4de619f 100644
--- a/src/FSharpLint.Core/Framework/Ast.fs
+++ b/src/FSharpLint.Core/Framework/Ast.fs
@@ -237,7 +237,7 @@ module Ast =
| SynPat.Attrib(pattern, _, _)
| SynPat.Paren(pattern, _) -> add <| Pattern pattern
| SynPat.Named(_) -> ()
- | SynPat.Record(patternsAndIdentifier, _) -> List.revIter (fun (_, _, pattern) -> pattern |> Pattern |> add) patternsAndIdentifier
+ | SynPat.Record(patPairFieldList, _) -> patPairFieldList |> List.revIter(_.Pattern >> Pattern >> add)
| SynPat.Const(_)
| SynPat.Wild(_)
| SynPat.FromParseError(_)
@@ -256,6 +256,8 @@ module Ast =
add <| Pattern lhs
add <| Pattern rhs
+
+ // fsharplint:disable FL0025
let inline private expressionChildren (node: SynExpr) (add: AstNode -> unit) =
let addMany = List.iter add
@@ -303,13 +305,6 @@ module Ast =
| SynExpr.DotNamedIndexedPropertySet(expression, _, expression1, expression2, _)
| SynExpr.For(_, _, _, _, expression, _, expression1, expression2, _) ->
addMany [Expression expression2; Expression expression1; Expression expression]
- | SynExpr.LetOrUseBang(_, _, _, pattern, rightHandSide, andBangs, leftHandSide, _, _) ->
- addMany [Expression rightHandSide; Expression leftHandSide]
- // TODO: is the the correct way to handle the new `and!` syntax?
- List.iter (fun (SynExprAndBang(_, _, _, pattern, body, _, _)) ->
- addMany [Expression body; Pattern pattern]
- ) andBangs
- add <| Pattern pattern
| SynExpr.ForEach(_, _, _, _, pattern, expression, expression1, _) ->
addMany [Expression expression1; Expression expression; Pattern pattern]
| SynExpr.MatchLambda(_, _, matchClauses, _, _) ->
@@ -327,9 +322,22 @@ module Ast =
| SynExpr.Upcast(expression, synType, _)
| SynExpr.Downcast(expression, synType, _) ->
addMany [Type synType; Expression expression]
- | SynExpr.LetOrUse(_, _, bindings, expression, _, _) ->
+ // regular let or use
+ | SynExpr.LetOrUse(_, _, _, false, bindings, expression, _, _) ->
add <| Expression expression
List.revIter (Binding >> add) bindings
+ // let! or use!
+ | SynExpr.LetOrUse(_, _, _, true, bindings, leftHandSide, _, _) ->
+ match bindings with
+ | firstBinding :: andBangs ->
+ match firstBinding with
+ | SynBinding(headPat = pattern; expr = rightHandSide) ->
+ addMany [Expression rightHandSide; Expression leftHandSide]
+ List.iter (fun (SynBinding(headPat = pattern; expr = body)) ->
+ addMany [Expression body; Pattern pattern]
+ ) andBangs
+ add <| Pattern pattern
+ | [] -> () // error case. @@TODO@@ any other handling needed here?
| SynExpr.Ident(ident) -> add <| Identifier([ident.idText], ident.idRange)
| SynExpr.LongIdent(_, SynLongIdent(ident, _, _), _, range) ->
add <| Identifier(List.map (fun (identifier: Ident) -> identifier.idText) ident, range)
@@ -375,6 +383,8 @@ module Ast =
expr2 |> Option.iter (Expression >> add)
| _ -> ()
+ // fsharplint:enable
+
let inline private typeSimpleRepresentationChildren node add =
match node with
| SynTypeDefnSimpleRepr.Union(_, unionCases, _) -> List.revIter (UnionCase >> add) unionCases
@@ -414,7 +424,7 @@ module Ast =
| SynArgPats.Pats(patterns) ->
patterns |> List.revIter (Pattern >> add)
| SynArgPats.NamePatPairs(namePatterns, _, _) ->
- namePatterns |> List.revIter (fun (_, _, pattern) -> pattern |> Pattern |> add)
+ namePatterns |> List.revIter (_.Pattern >> Pattern >> add)
let inline private typeRepresentationChildren node add =
match node with
@@ -471,7 +481,7 @@ module Ast =
| Else(expression)
| Expression(expression) -> expressionChildren expression add
- | File(ParsedInput.ImplFile(ParsedImplFileInput(_, _, _, _, _, moduleOrNamespaces, _, _, _))) ->
+ | File(ParsedInput.ImplFile(ParsedImplFileInput(contents = moduleOrNamespaces))) ->
moduleOrNamespaces |> List.revIter (ModuleOrNamespace >> add)
| UnionCase(unionCase) -> unionCaseChildren unionCase add
diff --git a/src/FSharpLint.Core/Rules/Conventions/AsyncExceptionWithoutReturn.fs b/src/FSharpLint.Core/Rules/Conventions/AsyncExceptionWithoutReturn.fs
index 978ed38ef..ff9e7de5a 100644
--- a/src/FSharpLint.Core/Rules/Conventions/AsyncExceptionWithoutReturn.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/AsyncExceptionWithoutReturn.fs
@@ -55,7 +55,7 @@ let rec checkExpression (expression: SynExpr) (range: range) (continuation: unit
}
| SynExpr.App (_, _, funcExpr, _, range) ->
checkExpression funcExpr range returnEmptyArray
- | SynExpr.LetOrUse (_, _, _, body, range, _) ->
+ | SynExpr.LetOrUse (_, _, _, false, _, body, range, _) ->
checkExpression body range returnEmptyArray
| _ -> Array.empty)
(continuation ())
diff --git a/src/FSharpLint.Core/Rules/Conventions/AvoidTooShortNames.fs b/src/FSharpLint.Core/Rules/Conventions/AvoidTooShortNames.fs
index 5c7f04171..32ad88a2e 100644
--- a/src/FSharpLint.Core/Rules/Conventions/AvoidTooShortNames.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/AvoidTooShortNames.fs
@@ -54,8 +54,10 @@ let private getParameterWithBelowMinimumLength (pats: SynPat list): (Ident * str
let private getIdentifiers (args:AstNodeRuleParams) =
match args.AstNode with
- | AstNode.Expression(SynExpr.LetOrUseBang(_, _, _, pat, _, _, _, _, _)) ->
- getParameterWithBelowMinimumLength [pat]
+ | AstNode.Expression(SynExpr.LetOrUse(isBang = true; bindings = binding :: _)) ->
+ match binding with
+ | SynBinding(headPat = pat) ->
+ getParameterWithBelowMinimumLength [pat]
| AstNode.Expression(SynExpr.Lambda(_, _, lambdaArgs, _, _, _, _)) ->
let lambdaIdent = FunctionReimplementation.getLambdaParamIdent lambdaArgs
match lambdaIdent with
diff --git a/src/FSharpLint.Core/Rules/Conventions/Binding/BindingHelper.fs b/src/FSharpLint.Core/Rules/Conventions/Binding/BindingHelper.fs
index dd9ec7ced..a13851689 100644
--- a/src/FSharpLint.Core/Rules/Conventions/Binding/BindingHelper.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/Binding/BindingHelper.fs
@@ -8,6 +8,6 @@ let isLetBinding index (syntaxArray:AbstractSyntaxArray.Node []) =
if index > 0 then
match syntaxArray.[syntaxArray.[index].ParentIndex].Actual with
| AstNode.ModuleDeclaration(SynModuleDecl.Let(_))
- | AstNode.Expression(SynExpr.LetOrUse(_, false, _, _, _, _)) -> true
+ | AstNode.Expression(SynExpr.LetOrUse(_, false, _, false, _, _, _, _)) -> true
| _ -> false
else false
diff --git a/src/FSharpLint.Core/Rules/Conventions/Binding/FavourIgnoreOverLetWild.fs b/src/FSharpLint.Core/Rules/Conventions/Binding/FavourIgnoreOverLetWild.fs
index 4a40f86fa..7aaa963b6 100644
--- a/src/FSharpLint.Core/Rules/Conventions/Binding/FavourIgnoreOverLetWild.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/Binding/FavourIgnoreOverLetWild.fs
@@ -33,7 +33,7 @@ let private runner (args:AstNodeRuleParams) =
let bindingRange =
match args.GetParents(args.NodeIndex) with
| AstNode.ModuleDeclaration(SynModuleDecl.Let(_, _, range)) :: _
- | AstNode.Expression(SynExpr.LetOrUse(_, false, _, _, range, _)) :: _ ->
+ | AstNode.Expression(SynExpr.LetOrUse(_, false, _, false, _, _, range, _)) :: _ ->
Some(range)
| _ -> None
diff --git a/src/FSharpLint.Core/Rules/Conventions/Binding/UselessBinding.fs b/src/FSharpLint.Core/Rules/Conventions/Binding/UselessBinding.fs
index 380457eb2..7595ab4bb 100644
--- a/src/FSharpLint.Core/Rules/Conventions/Binding/UselessBinding.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/Binding/UselessBinding.fs
@@ -52,7 +52,7 @@ let private runner (args:AstNodeRuleParams) =
match args.GetParents(args.NodeIndex) with
| AstNode.ModuleDeclaration(SynModuleDecl.Let(_, _, range)) :: _ ->
Some({ FromRange = range; FromText = "let"; ToText = String.Empty })
- | AstNode.Expression(SynExpr.LetOrUse(_, false, _, _, range, _)) :: _ ->
+ | AstNode.Expression(SynExpr.LetOrUse(_, false, _, false, _, _, range, _)) :: _ ->
Some({ FromRange = range; FromText = "use"; ToText = String.Empty })
| _ -> None
match args.AstNode with
diff --git a/src/FSharpLint.Core/Rules/Conventions/FavourNonMutablePropertyInitialization.fs b/src/FSharpLint.Core/Rules/Conventions/FavourNonMutablePropertyInitialization.fs
index cf1986321..7a5dfd304 100644
--- a/src/FSharpLint.Core/Rules/Conventions/FavourNonMutablePropertyInitialization.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/FavourNonMutablePropertyInitialization.fs
@@ -64,7 +64,7 @@ let rec private processLetBinding (instanceNames: Set) (body: SynExpr) (
and [] processExpression (expression: SynExpr) (continuation: unit -> array) : array =
Array.append
(match expression with
- | SynExpr.LetOrUse(_, _, bindings, body, _, _) ->
+ | SynExpr.LetOrUse(_, _, _, false, bindings, body, _, _) ->
let instanceNames = extraFromBindings bindings List.Empty |> Set.ofList
processLetBinding instanceNames body returnEmptyArray
| SynExpr.Sequential(_, _, expr1, expr2, _, _) ->
@@ -74,7 +74,7 @@ and [] processExpression (expression: SynExpr) (continuation: unit ->
let runner args =
match args.AstNode with
- | Binding(SynBinding(_, _, _, _, _, _, _, _, _, SynExpr.LetOrUse(_, _, bindings, body, _, _), _, _, _)) ->
+ | Binding(SynBinding(_, _, _, _, _, _, _, _, _, SynExpr.LetOrUse(_, _, _, false, bindings, body, _, _), _, _, _)) ->
let instanceNames = extraFromBindings bindings List.Empty |> Set.ofList
processLetBinding instanceNames body returnEmptyArray
| Match(SynMatchClause(_, _, expr, _, _, _)) ->
diff --git a/src/FSharpLint.Core/Rules/Conventions/FavourStaticEmptyFields.fs b/src/FSharpLint.Core/Rules/Conventions/FavourStaticEmptyFields.fs
index 0ba6790fa..a4ed9e8cb 100644
--- a/src/FSharpLint.Core/Rules/Conventions/FavourStaticEmptyFields.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/FavourStaticEmptyFields.fs
@@ -49,7 +49,7 @@ let private runner (args: AstNodeRuleParams) =
| AstNode.Expression(SynExpr.Record(_, _, synExprRecordField, _)) ->
let mapping =
function
- | SynExprRecordField(_, _, expr, _) ->
+ | SynExprRecordField(_, _, expr, _, _) ->
match expr with
| Some(SynExpr.ArrayOrList(isArray, [], range)) ->
let emptyLiteralType = if isArray then EmptyArrayLiteral else EmptyListLiteral
diff --git a/src/FSharpLint.Core/Rules/Conventions/Naming/NamingHelper.fs b/src/FSharpLint.Core/Rules/Conventions/Naming/NamingHelper.fs
index 8e8fd6f4e..75956342a 100644
--- a/src/FSharpLint.Core/Rules/Conventions/Naming/NamingHelper.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/Naming/NamingHelper.fs
@@ -405,7 +405,7 @@ let rec private innerGetPatternIdents<'Item> (accessibility:AccessControlLevel)
idents
(match args with
| SynArgPats.NamePatPairs(pats, _, _) ->
- innerGetAllPatternIdents AccessControlLevel.Private getIdents (pats |> List.map (fun(_, _, synPat) -> synPat))
+ innerGetAllPatternIdents AccessControlLevel.Private getIdents (pats |> List.map _.Pattern)
| SynArgPats.Pats(pats) ->
innerGetAllPatternIdents AccessControlLevel.Private getIdents pats)
| SynPat.Named(_, _, access, _) ->
diff --git a/src/FSharpLint.Core/Rules/Conventions/RecursiveAsyncFunction.fs b/src/FSharpLint.Core/Rules/Conventions/RecursiveAsyncFunction.fs
index 834ba4ac0..10c2268a8 100644
--- a/src/FSharpLint.Core/Rules/Conventions/RecursiveAsyncFunction.fs
+++ b/src/FSharpLint.Core/Rules/Conventions/RecursiveAsyncFunction.fs
@@ -58,7 +58,7 @@ let checkRecursiveAsyncFunction (args:AstNodeRuleParams) (range:Range) (doBangEx
match crumb with
| AstNode.ModuleDeclaration (SynModuleDecl.Let (true, bindings, _)) ->
bindings
- | AstNode.Expression (SynExpr.LetOrUse (true, false, bindings, _, _, _)) ->
+ | AstNode.Expression (SynExpr.LetOrUse (true, false, _, false, bindings, _, _, _)) ->
bindings
| _ -> List.Empty)
|> List.choose getFunctionNameFromAsyncCompExprBinding
diff --git a/src/FSharpLint.Core/Rules/Typography/Indentation.fs b/src/FSharpLint.Core/Rules/Typography/Indentation.fs
index a9d9372bf..87d9aa9f1 100644
--- a/src/FSharpLint.Core/Rules/Typography/Indentation.fs
+++ b/src/FSharpLint.Core/Rules/Typography/Indentation.fs
@@ -42,7 +42,7 @@ module ContextBuilder =
| (SynExpr.Record ( _, _, fields, _)) ->
let subRecords =
fields
- |> List.choose (fun (SynExprRecordField(_, _, expr, _)) -> Option.map collectRecordFields expr)
+ |> List.choose (fun (SynExprRecordField(_, _, expr, _, _)) -> Option.map collectRecordFields expr)
|> List.concat
fields::subRecords
| _ ->
@@ -77,7 +77,7 @@ module ContextBuilder =
collectRecordFields record
|> List.collect (fun recordFields ->
recordFields
- |> List.map (fun (SynExprRecordField((fieldName, _), _, _, _)) -> fieldName.Range)
+ |> List.map (fun (SynExprRecordField((fieldName, _), _, _, _, _)) -> fieldName.Range)
|> firstRangePerLine
|> createAbsoluteAndOffsetOverridesBasedOnFirst)
| Expression (SynExpr.ArrayOrListComputed(expr=(SynExpr.ComputationExpr(expr=expr)))) ->
@@ -124,7 +124,14 @@ module ContextBuilder =
|> createAbsoluteAndOffsetOverridesBasedOnFirst
| Pattern (SynPat.Record (fieldPats=fieldPats)) ->
fieldPats
- |> List.map (fun ((_, fieldIdent), _, _) -> fieldIdent.idRange)
+ |> List.map (fun patPairField -> patPairField.Range)
+ // @@TODO@@ Do we need to look at the ranges inside FieldName here?
+ //let fieldIdent =
+ // match patPairField.FieldName.LongIdent with
+ // | [id] -> id
+ // | lid -> List.last lid
+ //
+ //fieldIdent.idRange)
|> firstRangePerLine
|> createAbsoluteAndOffsetOverridesBasedOnFirst
| _ -> List.Empty
diff --git a/tests/FSharpLint.Core.Tests/Framework/TestAbstractSyntaxArray.fs b/tests/FSharpLint.Core.Tests/Framework/TestAbstractSyntaxArray.fs
index 34ba45144..0951a1016 100644
--- a/tests/FSharpLint.Core.Tests/Framework/TestAbstractSyntaxArray.fs
+++ b/tests/FSharpLint.Core.Tests/Framework/TestAbstractSyntaxArray.fs
@@ -26,7 +26,7 @@ type TestAst() =
match ast with
| ParsedInput.ImplFile(implFile) ->
match implFile with
- | ParsedImplFileInput(_, _, _, _, _, Module(app)::_, _, _, _) ->
+ | ParsedImplFileInput(_, _, _, _, Module(app)::_, _, _, _) ->
app
| _ -> failwith "Expected at least one module or namespace."
| _ -> failwith "Expected an implementation file."