diff --git a/Directory.Packages.props b/Directory.Packages.props index 04c1d832b..b58b86286 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 21f6ef154..43e4e6d2b 100644 --- a/src/FSharpLint.Core/Framework/Ast.fs +++ b/src/FSharpLint.Core/Framework/Ast.fs @@ -135,7 +135,7 @@ module Ast = | SynModuleDecl.NestedModule(componentInfo, _, moduleDeclarations, _, _, _) -> List.revIter (ModuleDeclaration >> add) moduleDeclarations add <| ComponentInfo componentInfo - | SynModuleDecl.Let(_, bindings, _) -> List.revIter (Binding >> add) bindings + | SynModuleDecl.Let(_, bindings, _, _) -> List.revIter (Binding >> add) bindings | SynModuleDecl.Expr(expression, _) -> add <| Expression expression | SynModuleDecl.Types(typeDefinitions, _) -> List.revIter (TypeDefinition >> add) typeDefinitions | SynModuleDecl.Exception(SynExceptionDefn.SynExceptionDefn(repr, _, members, _), _) -> @@ -204,7 +204,7 @@ module Ast = | SynMemberDefn.ImplicitInherit(synType, expression, _, _, _) -> add <| Expression expression add <| Type synType - | SynMemberDefn.LetBindings(bindings, _, _, _) -> List.revIter (Binding >> add) bindings + | SynMemberDefn.LetBindings(bindings, _, _, _, _) -> List.revIter (Binding >> add) bindings | SynMemberDefn.Interface(synType, _, Some(members), _) -> List.revIter (MemberDefinition >> add) members add <| Type synType @@ -240,7 +240,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(_) @@ -278,6 +278,8 @@ module Ast = | SynExpr.Lazy(expression, _) | SynExpr.TraitCall(_, _, expression, _) | SynExpr.YieldOrReturn(_, expression, _, _) + | SynExpr.AnonRecd(_, Some (expression, _), _, _, _) + | SynExpr.IndexFromEnd(expression, _) | SynExpr.YieldOrReturnFrom(_, expression, _, _) -> add <| Expression expression | SynExpr.SequentialOrImplicitYield(_, expression1, expression2, ifNotExpression, _) -> addMany [Expression expression1; Expression expression2; Expression ifNotExpression] @@ -296,23 +298,12 @@ module Ast = | SynExpr.Tuple(_, expressions, _, _) | SynExpr.ArrayOrList(_, expressions, _) -> List.revIter (Expression >> add) expressions | SynExpr.Record(_, Some(expr, _), _, _) -> add <| Expression expr - | SynExpr.Record(_, None, _, _) -> () - | SynExpr.AnonRecd(_, Some (expr,_), _, _, _) -> - add <| Expression expr - | SynExpr.AnonRecd(_, None, _, _, _) -> () | SynExpr.ObjExpr(synType, _, _, bindings, _, _, _, _) -> List.revIter (Binding >> add) bindings add <| Type synType | 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, _, _) -> @@ -330,9 +321,22 @@ module Ast = | SynExpr.Upcast(expression, synType, _) | SynExpr.Downcast(expression, synType, _) -> addMany [Type synType; Expression expression] - | SynExpr.LetOrUse(_, _, bindings, expression, _, _) -> - add <| Expression expression + // regular let or use + | ExpressionUtilities.LetOrUse({Bindings = bindings; Body = body}, false, _) -> + add <| Expression body List.revIter (Binding >> add) bindings + // let! or use! + | ExpressionUtilities.LetOrUse({Bindings = bindings; Body = body}, true, _) -> + match bindings with + | firstBinding :: andBangs -> + match firstBinding with + | SynBinding(headPat = pattern; expr = rightHandSide) -> + addMany [Expression rightHandSide; Expression body] + 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) @@ -362,17 +366,17 @@ module Ast = | SynExpr.DotLambda(_) | SynExpr.App(_) | SynExpr.Fixed(_) -> () - *) + | SynExpr.Record(_, None, _, _) -> () + | SynExpr.AnonRecd(_, None, _, _, _) -> () | SynExpr.Typar(_) -> () - | SynExpr.WhileBang(_, expression, expression1, _) -> + *) + | SynExpr.WhileBang(_, expression1, expression2, _) -> add <| Expression expression1 - add <| Expression expression + add <| Expression expression2 | SynExpr.DebugPoint(_debugPoint, _, innerExpr) -> add <| Expression innerExpr | SynExpr.Dynamic(funcExpr, _, argExpr, _) -> addMany [Expression funcExpr; Expression argExpr] - | SynExpr.IndexFromEnd(expr, _) -> - add <| Expression expr | SynExpr.IndexRange(expr1, _, expr2, _, _, _) -> expr1 |> Option.iter (Expression >> add) expr2 |> Option.iter (Expression >> add) @@ -417,7 +421,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 @@ -474,7 +478,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/Framework/Utilities.fs b/src/FSharpLint.Core/Framework/Utilities.fs index 8973b8ac1..1ccd396ad 100644 --- a/src/FSharpLint.Core/Framework/Utilities.fs +++ b/src/FSharpLint.Core/Framework/Utilities.fs @@ -145,6 +145,15 @@ module ExpressionUtilities = (range.StartLine, range.StartColumn) >= (containingRange.StartLine, containingRange.StartColumn) && (range.EndLine, range.EndColumn) <= (containingRange.EndLine, containingRange.EndColumn) + /// Active pattern to match any SynExpr.LetOrUse + /// Returns a tuple of (isBang, isUse, record) allowing matching on both booleans and accessing the full record + /// Borrowed from https://github.com/nojaf/fsharp/blob/b3d90dc6ab9a9cedad4b8702fd8625f8f8175ae1/src/Compiler/SyntaxTree/SyntaxTreeOps.fs#L138 + [] + let (|LetOrUse|_|) (expr: SynExpr) = + match expr with + | SynExpr.LetOrUse(letOrUse) -> ValueSome(letOrUse, letOrUse.IsBang, letOrUse.IsUse) + | _ -> ValueNone + module String = open System.IO diff --git a/src/FSharpLint.Core/Rules/Conventions/Binding/BindingHelper.fs b/src/FSharpLint.Core/Rules/Conventions/Binding/BindingHelper.fs index dd9ec7ced..8aa65d21e 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(ExpressionUtilities.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 60aed9942..e0bf2b012 100644 --- a/src/FSharpLint.Core/Rules/Conventions/Binding/FavourIgnoreOverLetWild.fs +++ b/src/FSharpLint.Core/Rules/Conventions/Binding/FavourIgnoreOverLetWild.fs @@ -32,8 +32,8 @@ let private runner (args:AstNodeRuleParams) = | AstNode.Binding(SynBinding(_, _, _, _, _, _, _, pattern, _, expr, range, _, _)) -> let bindingRange = match args.GetParents(args.NodeIndex) with - | AstNode.ModuleDeclaration(SynModuleDecl.Let(_, _, range)) :: _ - | AstNode.Expression(SynExpr.LetOrUse(_, false, _, _, range, _)) :: _ -> + | AstNode.ModuleDeclaration(SynModuleDecl.Let(_, _, range, _)) :: _ + | AstNode.Expression(ExpressionUtilities.LetOrUse({Range = range}, false, false)) :: _ -> Some(range) | _ -> None diff --git a/src/FSharpLint.Core/Rules/Conventions/Binding/UselessBinding.fs b/src/FSharpLint.Core/Rules/Conventions/Binding/UselessBinding.fs index b878850f8..8e306e481 100644 --- a/src/FSharpLint.Core/Rules/Conventions/Binding/UselessBinding.fs +++ b/src/FSharpLint.Core/Rules/Conventions/Binding/UselessBinding.fs @@ -51,9 +51,9 @@ let private runner (args:AstNodeRuleParams) = let maybeSuggestedFix = match args.GetParents(args.NodeIndex) with - | AstNode.ModuleDeclaration(SynModuleDecl.Let(_, _, range)) :: _ -> + | AstNode.ModuleDeclaration(SynModuleDecl.Let(_, _, range, _)) :: _ -> Some({ FromRange = range; FromText = "let"; ToText = String.Empty }) - | AstNode.Expression(SynExpr.LetOrUse(_, false, _, _, range, _)) :: _ -> + | AstNode.Expression(ExpressionUtilities.LetOrUse({Range = range}, false, false)) :: _ -> Some({ FromRange = range; FromText = "use"; ToText = String.Empty }) | _ -> None match args.AstNode with diff --git a/src/FSharpLint.Core/Rules/Conventions/DisallowShadowing.fs b/src/FSharpLint.Core/Rules/Conventions/DisallowShadowing.fs index c9e86e9e7..130c38efc 100644 --- a/src/FSharpLint.Core/Rules/Conventions/DisallowShadowing.fs +++ b/src/FSharpLint.Core/Rules/Conventions/DisallowShadowing.fs @@ -27,7 +27,7 @@ let rec private processExpressions (processArgs: SynSimplePats -> bool) (expressions: list) = match expressions with - | SynExpr.LetOrUse(_, _, bindings, _, _, _) :: rest -> + | ExpressionUtilities.LetOrUse({Bindings = bindings}, false, _) :: rest -> bindings |> List.exists processBinding || processExpressions processBinding processArgs rest | SynExpr.Sequential(_, _, expr1, expr2, _, _) :: rest -> @@ -60,7 +60,7 @@ let rec private processPatterns (definitionsAndPatterns: list processPatterns ((definitions, pat) :: rest) | (definitions, SynPat.Record(fieldPats, _)) :: rest -> - processPatterns ((fieldPats |> List.map (fun (_, _, pat) -> (definitions, pat))) @ rest) + processPatterns ((fieldPats |> List.map (fun patPairField -> (definitions, patPairField.Pattern))) @ rest) | (definitions, SynPat.Tuple(_, pats, _, _)) :: rest -> processPatterns ((pats |> List.map (fun pat -> (definitions, pat))) @ rest) | (definitions, SynPat.Typed(pat, _, _)) :: rest -> @@ -114,7 +114,7 @@ let runner (args: AstNodeRuleParams) = let processModuleDeclaration (moduleDecl: SynModuleDecl) = match moduleDecl with - | SynModuleDecl.Let(_, bindings, _) -> bindings |> List.exists processBinding + | SynModuleDecl.Let(_, bindings, _, _) -> bindings |> List.exists processBinding | _ -> false let processExpression (expr: SynExpr) = processExpressions processBinding processArgs (List.singleton expr) diff --git a/src/FSharpLint.Core/Rules/Conventions/DiscourageStringInterpolationWithStringFormat.fs b/src/FSharpLint.Core/Rules/Conventions/DiscourageStringInterpolationWithStringFormat.fs index 2344e8cb4..0ea15a83a 100644 --- a/src/FSharpLint.Core/Rules/Conventions/DiscourageStringInterpolationWithStringFormat.fs +++ b/src/FSharpLint.Core/Rules/Conventions/DiscourageStringInterpolationWithStringFormat.fs @@ -37,7 +37,7 @@ let runner args = |> List.exists (fun decl -> match decl with - | SynModuleDecl.Let(_, bindings, _) -> + | SynModuleDecl.Let(_, bindings, _, _) -> bindings |> List.exists isBindingOfIdentifierToTemplate | _ -> false) | _ -> false diff --git a/src/FSharpLint.Core/Rules/Conventions/EnsureTailCallDiagnosticsInRecursiveFunctions.fs b/src/FSharpLint.Core/Rules/Conventions/EnsureTailCallDiagnosticsInRecursiveFunctions.fs index 3991aa7da..b8da369ca 100644 --- a/src/FSharpLint.Core/Rules/Conventions/EnsureTailCallDiagnosticsInRecursiveFunctions.fs +++ b/src/FSharpLint.Core/Rules/Conventions/EnsureTailCallDiagnosticsInRecursiveFunctions.fs @@ -47,7 +47,7 @@ let runner (args: AstNodeRuleParams) = funcs |> List.choose (processFunction false checkInfo funcs) |> List.toArray - | AstNode.Expression(SynExpr.LetOrUse(true, _, bindings, _, _, _)), Some checkInfo -> + | AstNode.Expression(ExpressionUtilities.LetOrUse({IsRecursive = true; Bindings = bindings}, false, _)), Some checkInfo -> match UnneededRecKeyword.getRecursiveFunctionsFromBindings bindings with | [] -> Array.empty | funcs -> diff --git a/src/FSharpLint.Core/Rules/Conventions/FavourNestedFunctions.fs b/src/FSharpLint.Core/Rules/Conventions/FavourNestedFunctions.fs index ebfed999f..abe167be8 100644 --- a/src/FSharpLint.Core/Rules/Conventions/FavourNestedFunctions.fs +++ b/src/FSharpLint.Core/Rules/Conventions/FavourNestedFunctions.fs @@ -35,7 +35,7 @@ let rec private collectMemberBindings (acc: list) (memberDefns: collectMemberBindings (collectBindings (List.singleton binding) @ acc) rest | SynMemberDefn.GetSetMember(getMember, setMember, _, _) :: rest -> collectMemberBindings (collectBindings ((Option.toList getMember) @ (Option.toList setMember)) @ acc) rest - | SynMemberDefn.LetBindings(bindings, _, _, _) :: rest -> + | SynMemberDefn.LetBindings(bindings, _, _, _, _) :: rest -> collectMemberBindings (collectBindings bindings @ acc) rest | SynMemberDefn.Interface(_, _, Some(members), _) :: rest -> collectMemberBindings acc (members @ rest) @@ -45,7 +45,7 @@ let rec private collectMemberBindings (acc: list) (memberDefns: let runner (args: AstNodeRuleParams) = let collectTopLevelFunctionBindings (declaration: SynModuleDecl): list = match declaration with - | SynModuleDecl.Let(_, bindings, _) -> collectBindings bindings + | SynModuleDecl.Let(_, bindings, _, _) -> collectBindings bindings | _ -> List.empty match args.AstNode with @@ -75,7 +75,7 @@ let runner (args: AstNodeRuleParams) = collectBindings (List.singleton binding) | SynMemberDefn.GetSetMember(getMember, setMember, _, _) -> collectBindings ((Option.toList getMember) @ (Option.toList setMember)) - | SynMemberDefn.LetBindings(bindings, _, _, _) -> + | SynMemberDefn.LetBindings(bindings, _, _, _, _) -> collectBindings bindings | SynMemberDefn.Interface(_, _, Some(members), _) -> collectMemberBindings List.empty members diff --git a/src/FSharpLint.Core/Rules/Conventions/FavourNonMutablePropertyInitialization.fs b/src/FSharpLint.Core/Rules/Conventions/FavourNonMutablePropertyInitialization.fs index 47a601cf8..78ddde55f 100644 --- a/src/FSharpLint.Core/Rules/Conventions/FavourNonMutablePropertyInitialization.fs +++ b/src/FSharpLint.Core/Rules/Conventions/FavourNonMutablePropertyInitialization.fs @@ -64,9 +64,9 @@ 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, _, _) -> - let instanceNames = extraFromBindings bindings List.Empty |> Set.ofList - processLetBinding instanceNames body returnEmptyArray + | SynExpr.LetOrUse letOrUse when not letOrUse.IsBang -> + let instanceNames = extraFromBindings letOrUse.Bindings List.Empty |> Set.ofList + processLetBinding instanceNames letOrUse.Body returnEmptyArray | SynExpr.Sequential(_, _, expr1, expr2, _, _) -> processExpression expr1 (fun () -> processExpression expr2 returnEmptyArray) | _ -> Array.empty) @@ -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(_, _, _, _, _, _, _, _, _, ExpressionUtilities.LetOrUse({Bindings = bindings; Body = body}, false, _), _, _, _)) -> 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 0bab96baf..fe119778d 100644 --- a/src/FSharpLint.Core/Rules/Conventions/FavourStaticEmptyFields.fs +++ b/src/FSharpLint.Core/Rules/Conventions/FavourStaticEmptyFields.fs @@ -75,7 +75,7 @@ let rec private processExpressions (errorsSoFar: array) (args: A | SynExpr.Record(_, _, synExprRecordFields, _) :: tail -> let mapping = function - | SynExprRecordField(_, _, expr, _) -> expr + | SynExprRecordField(_, _, expr, _, _) -> expr let fieldExpressions = synExprRecordFields |> List.choose mapping diff --git a/src/FSharpLint.Core/Rules/Conventions/Naming/AvoidTooShortNames.fs b/src/FSharpLint.Core/Rules/Conventions/Naming/AvoidTooShortNames.fs index 11f8574f2..8c904a448 100644 --- a/src/FSharpLint.Core/Rules/Conventions/Naming/AvoidTooShortNames.fs +++ b/src/FSharpLint.Core/Rules/Conventions/Naming/AvoidTooShortNames.fs @@ -58,8 +58,10 @@ let runner (args:AstNodeRuleParams) = let identifiers = match args.AstNode with - | AstNode.Expression(SynExpr.LetOrUseBang(_, _, _, pat, _, _, _, _, _)) -> - getParameterWithBelowMinimumLength [pat] + | AstNode.Expression(ExpressionUtilities.LetOrUse({Bindings = binding :: _}, true, _)) -> + 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/Naming/SimpleAsyncComplementaryHelpers.fs b/src/FSharpLint.Core/Rules/Conventions/Naming/SimpleAsyncComplementaryHelpers.fs index ee590aaa7..842bf17f7 100644 --- a/src/FSharpLint.Core/Rules/Conventions/Naming/SimpleAsyncComplementaryHelpers.fs +++ b/src/FSharpLint.Core/Rules/Conventions/Naming/SimpleAsyncComplementaryHelpers.fs @@ -32,7 +32,7 @@ type private Func = [] let rec private getBindings (acc: list) (declarations: list) = match declarations with - | SynModuleDecl.Let(_, bindings, _) :: rest -> getBindings (bindings @ acc) rest + | SynModuleDecl.Let(_, bindings, _, _) :: rest -> getBindings (bindings @ acc) rest | SynModuleDecl.NestedModule(_, _, innerDecls, _, _, _) :: rest -> getBindings acc (innerDecls @ rest) | [] -> acc | _ :: rest -> getBindings acc rest @@ -145,7 +145,7 @@ let runner (config: Config) (args: AstNodeRuleParams) = | SynArgPats.NamePatPairs(pairs, _, _) -> let argsList = pairs - |> List.map (fun (ident, _, _) -> ident.idRange) + |> List.map _.Range |> List.choose (fun range -> ExpressionUtilities.tryFindTextOfRange range args.FileContent) " " + String.Join(" ", argsList) | SynArgPats.Pats([ SynPat.Paren(SynPat.Const(SynConst.Unit, _), _) ]) -> diff --git a/src/FSharpLint.Core/Rules/Conventions/RecursiveAsyncFunction.fs b/src/FSharpLint.Core/Rules/Conventions/RecursiveAsyncFunction.fs index 834ba4ac0..958f445e8 100644 --- a/src/FSharpLint.Core/Rules/Conventions/RecursiveAsyncFunction.fs +++ b/src/FSharpLint.Core/Rules/Conventions/RecursiveAsyncFunction.fs @@ -56,9 +56,9 @@ let checkRecursiveAsyncFunction (args:AstNodeRuleParams) (range:Range) (doBangEx breadcrumbs |> List.collect (fun crumb -> match crumb with - | AstNode.ModuleDeclaration (SynModuleDecl.Let (true, bindings, _)) -> + | AstNode.ModuleDeclaration (SynModuleDecl.Let (true, bindings, _, _)) -> bindings - | AstNode.Expression (SynExpr.LetOrUse (true, false, bindings, _, _, _)) -> + | AstNode.Expression (ExpressionUtilities.LetOrUse ({IsRecursive = true; Bindings = bindings}, false, false)) -> bindings | _ -> List.Empty) |> List.choose getFunctionNameFromAsyncCompExprBinding diff --git a/src/FSharpLint.Core/Rules/Conventions/RedundantNewKeyword.fs b/src/FSharpLint.Core/Rules/Conventions/RedundantNewKeyword.fs index 880c1891e..d7724da1b 100644 --- a/src/FSharpLint.Core/Rules/Conventions/RedundantNewKeyword.fs +++ b/src/FSharpLint.Core/Rules/Conventions/RedundantNewKeyword.fs @@ -50,8 +50,7 @@ let runner args = args.GetParents args.NodeIndex |> List.tryFind (function - | AstNode.Expression(SynExpr.LetOrUse(_, true, _, _, _, _)) -> true - | AstNode.Expression(SynExpr.LetOrUseBang(_, true, _, _, _, _, _, _, _)) -> true + | AstNode.Expression(ExpressionUtilities.LetOrUse(_, _, true)) -> true | _ -> false) match maybeUseBinding with | Some _binding -> diff --git a/src/FSharpLint.Core/Rules/Conventions/SuggestUseAutoProperty.fs b/src/FSharpLint.Core/Rules/Conventions/SuggestUseAutoProperty.fs index e57dab5ec..7ef04e511 100644 --- a/src/FSharpLint.Core/Rules/Conventions/SuggestUseAutoProperty.fs +++ b/src/FSharpLint.Core/Rules/Conventions/SuggestUseAutoProperty.fs @@ -16,7 +16,7 @@ let rec private isImmutableValueExpression (args: AstNodeRuleParams) (expression let isMutableVariable = let exists memberDef = match memberDef with - | SynMemberDefn.LetBindings (bindings, _, _, _) -> + | SynMemberDefn.LetBindings (bindings, _, _, _, _) -> List.exists (fun (SynBinding (_, _, _, isMutable, _, _, _, headPat, _, _, _, _, _)) -> match headPat with | SynPat.Named (SynIdent(bindingIdent, _), _, _, _) when isMutable -> diff --git a/src/FSharpLint.Core/Rules/Conventions/UnneededRecKeyword.fs b/src/FSharpLint.Core/Rules/Conventions/UnneededRecKeyword.fs index 882947ab3..75c65c5c4 100644 --- a/src/FSharpLint.Core/Rules/Conventions/UnneededRecKeyword.fs +++ b/src/FSharpLint.Core/Rules/Conventions/UnneededRecKeyword.fs @@ -28,7 +28,7 @@ let internal getRecursiveFunctionsFromBindings (bindings: List) = let internal (|RecursiveFunctions|_|) (astNode: AstNode) = match astNode with - | AstNode.ModuleDeclaration (SynModuleDecl.Let (true, bindings, _)) -> + | AstNode.ModuleDeclaration (SynModuleDecl.Let (true, bindings, _, _)) -> match getRecursiveFunctionsFromBindings bindings with | [] -> None | recursiveBindings -> Some recursiveBindings diff --git a/src/FSharpLint.Core/Rules/Formatting/Typography/Indentation.fs b/src/FSharpLint.Core/Rules/Formatting/Typography/Indentation.fs index c98b50eb5..e110a4492 100644 --- a/src/FSharpLint.Core/Rules/Formatting/Typography/Indentation.fs +++ b/src/FSharpLint.Core/Rules/Formatting/Typography/Indentation.fs @@ -45,7 +45,7 @@ module ContextBuilder = | (SynExpr.Record (_, _, fields, _)) -> let newAcc = fields :: acc fields - |> List.fold (fun currentAcc (SynExprRecordField(_, _, exprOpt, _)) -> + |> List.fold (fun currentAcc (SynExprRecordField(_, _, exprOpt, _, _)) -> match exprOpt with | Some expr -> collectRecordFieldsInner currentAcc expr | None -> currentAcc @@ -84,7 +84,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)))) -> @@ -131,7 +131,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/src/FSharpLint.Core/Rules/NamingHelper.fs b/src/FSharpLint.Core/Rules/NamingHelper.fs index baf8f215d..a6c02fdf4 100644 --- a/src/FSharpLint.Core/Rules/NamingHelper.fs +++ b/src/FSharpLint.Core/Rules/NamingHelper.fs @@ -404,7 +404,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/Smells/AsyncExceptionWithoutReturn.fs b/src/FSharpLint.Core/Rules/Smells/AsyncExceptionWithoutReturn.fs index 688083df3..9986fc1c8 100644 --- a/src/FSharpLint.Core/Rules/Smells/AsyncExceptionWithoutReturn.fs +++ b/src/FSharpLint.Core/Rules/Smells/AsyncExceptionWithoutReturn.fs @@ -55,7 +55,7 @@ let rec checkExpression (expression: SynExpr) (range: range) (continuation: unit } | SynExpr.App (_, _, funcExpr, _, innerRange) -> checkExpression funcExpr innerRange returnEmptyArray - | SynExpr.LetOrUse (_, _, _, body, innerRange, _) -> + | ExpressionUtilities.LetOrUse({Body = body; Range = innerRange}, false, _) -> checkExpression body innerRange returnEmptyArray | _ -> Array.empty) (continuation ()) diff --git a/tests/FSharpLint.Core.Tests/Framework/TestAbstractSyntaxArray.fs b/tests/FSharpLint.Core.Tests/Framework/TestAbstractSyntaxArray.fs index 4772314f3..09a67417a 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."