From e8701e132d676d3242346d8c8b31a481b3bceaa5 Mon Sep 17 00:00:00 2001 From: webwarrior-ws Date: Wed, 6 Aug 2025 14:32:22 +0200 Subject: [PATCH 1/2] Tests(SuggestUseAutoProperty): add test for struct Added test for type with `[]` annotation. Such types cannot have auto-properties, so the rule should not apply. --- .../Rules/Conventions/SuggestUseAutoProperty.fs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/FSharpLint.Core.Tests/Rules/Conventions/SuggestUseAutoProperty.fs b/tests/FSharpLint.Core.Tests/Rules/Conventions/SuggestUseAutoProperty.fs index 01a8606a5..7852bfff6 100644 --- a/tests/FSharpLint.Core.Tests/Rules/Conventions/SuggestUseAutoProperty.fs +++ b/tests/FSharpLint.Core.Tests/Rules/Conventions/SuggestUseAutoProperty.fs @@ -106,3 +106,13 @@ type Foo(content: int) = this.Parse source Assert.AreEqual(expected, this.ApplyQuickFix source) + + [] + member this.``Should not suggest using auto-property for types with [] attribute`` () = + this.Parse """ +[] +type Foo(content: int) = + member self.Content = content +""" + + Assert.IsTrue this.NoErrorsExist From 1d71bab5ec7a77527d8fa82791182ae210d5f4bc Mon Sep 17 00:00:00 2001 From: webwarrior-ws Date: Wed, 6 Aug 2025 14:57:06 +0200 Subject: [PATCH 2/2] SuggestUseAutoProperty: don't apply to structs Don't apply rule to types with `[]` annotation, because such types cannot have auto-properties. Fixes https://github.com/fsprojects/FSharpLint/issues/755 --- .../Conventions/SuggestUseAutoProperty.fs | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/FSharpLint.Core/Rules/Conventions/SuggestUseAutoProperty.fs b/src/FSharpLint.Core/Rules/Conventions/SuggestUseAutoProperty.fs index 69f8716dd..e1efccf39 100644 --- a/src/FSharpLint.Core/Rules/Conventions/SuggestUseAutoProperty.fs +++ b/src/FSharpLint.Core/Rules/Conventions/SuggestUseAutoProperty.fs @@ -44,6 +44,18 @@ and isImmutableSequentialExpression args expression = || isImmutableValueExpression args expr2) | _ -> false +let private hasStructAttribute node = + match node with + | AstNode.TypeDefinition(SynTypeDefn(SynComponentInfo(attributes, _, _, _, _, _, _, _), _, _, _, _, _)) -> + attributes + |> extractAttributes + |> List.exists + (fun attribute -> + match List.tryLast attribute.TypeName.LongIdent with + | Some(ident) -> ident.idText = "Struct" || ident.idText = "StructAttribute" + | None -> false) + | _ -> false + let private runner (args: AstNodeRuleParams) = match args.AstNode with | MemberDefinition @@ -73,21 +85,25 @@ let private runner (args: AstNodeRuleParams) = | _, SynArgPats.Pats pats when pats.Length > 0 -> // non-property member Array.empty | expression, _ when isImmutableValueExpression args expression -> - let suggestedFix = - lazy - (match memberIdentifier.LongIdent with - | [ _; memberName ] -> - Some - { FromText = args.FileContent - FromRange = memberIdentifier.Range - ToText = $"val {memberName.idText}" } - | _ -> None) - - { Range = memberRange - Message = Resources.GetString "RulesSuggestUseAutoProperty" - SuggestedFix = Some suggestedFix - TypeChecks = List.Empty } - |> Array.singleton + match args.GetParents args.NodeIndex with + | parentNode :: _ when hasStructAttribute parentNode -> + Array.empty + | _ -> + let suggestedFix = + lazy + (match memberIdentifier.LongIdent with + | [ _; memberName ] -> + Some + { FromText = args.FileContent + FromRange = memberIdentifier.Range + ToText = $"val {memberName.idText}" } + | _ -> None) + + { Range = memberRange + Message = Resources.GetString "RulesSuggestUseAutoProperty" + SuggestedFix = Some suggestedFix + TypeChecks = List.Empty } + |> Array.singleton | _ -> Array.empty | _ -> Array.empty