@@ -5,10 +5,16 @@ open FSharpLint.Framework
55open FSharpLint.Framework .Suggestion
66open FSharpLint.Framework .Ast
77open FSharpLint.Framework .Rules
8+ open FSharpLint.Rules .Utilities .LibraryHeuristics
89open Helper.Naming .Asynchronous
910open FSharp.Compiler .Syntax
1011
11- let runner ( args : AstNodeRuleParams ) =
12+ [<RequireQualifiedAccess>]
13+ type Config = {
14+ Mode: AsynchronousFunctionsMode
15+ }
16+
17+ let runner ( config : Config ) ( args : AstNodeRuleParams ) =
1218 let emitWarning range ( newFunctionName : string ) ( returnTypeName : string ) =
1319 Array.singleton
1420 {
@@ -18,53 +24,67 @@ let runner (args: AstNodeRuleParams) =
1824 TypeChecks = List.empty
1925 }
2026
21- match args.AstNode with
22- | AstNode.Binding ( SynBinding (_, _, _, _, attributes, _, _, SynPat.LongIdent( funcIdent, _, _, _, ( None | Some( SynAccess.Public _)), identRange), returnInfo, _, _, _, _))
23- when not <| Helper.Naming.isAttribute " Obsolete" attributes ->
24- let parents = args.GetParents args.NodeIndex
25- let hasEnclosingFunctionOrMethod =
26- parents
27- |> List.exists
28- ( fun node ->
29- match node with
30- | AstNode.Binding ( SynBinding (_, _, _, _, _, _, _, SynPat.LongIdent(_), _, _, _, _, _)) -> true
31- | _ -> false )
27+ let isAccessibilityLevelApplicable ( accessibility : Option < SynAccess >) =
28+ match accessibility with
29+ | None
30+ | Some( SynAccess.Public _) -> true
31+ | _ -> config.Mode = AllAPIs
32+
33+ let likelyhoodOfBeingInLibrary =
34+ match args.ProjectCheckInfo with
35+ | Some projectInfo -> howLikelyProjectIsLibrary projectInfo.ProjectContext.ProjectOptions.ProjectFileName
36+ | None -> Unlikely
37+
38+ if config.Mode = OnlyPublicAPIsInLibraries && likelyhoodOfBeingInLibrary <> Likely then
39+ Array.empty
40+ else
41+ match args.AstNode with
42+ | AstNode.Binding ( SynBinding (_, _, _, _, attributes, _, _, SynPat.LongIdent( funcIdent, _, _, _, accessibility, identRange), returnInfo, _, _, _, _))
43+ when isAccessibilityLevelApplicable accessibility && not <| Helper.Naming.isAttribute " Obsolete" attributes ->
44+ let parents = args.GetParents args.NodeIndex
45+ let hasEnclosingFunctionOrMethod =
46+ parents
47+ |> List.exists
48+ ( fun node ->
49+ match node with
50+ | AstNode.Binding ( SynBinding (_, _, _, _, _, _, _, SynPat.LongIdent(_), _, _, _, _, _)) -> true
51+ | _ -> false )
3252
33- if hasEnclosingFunctionOrMethod then
34- Array.empty
35- else
36- match returnInfo with
37- | Some ReturnsAsync ->
38- match funcIdent with
39- | HasAsyncPrefix _ ->
53+ if hasEnclosingFunctionOrMethod && config.Mode <> AllAPIs then
54+ Array.empty
55+ else
56+ match returnInfo with
57+ | Some ReturnsAsync ->
58+ match funcIdent with
59+ | HasAsyncPrefix _ ->
60+ Array.empty
61+ | HasAsyncSuffix name
62+ | HasNoAsyncPrefixOrSuffix name ->
63+ let nameWithAsync = asyncSuffixOrPrefix + name
64+ emitWarning identRange nameWithAsync " Async"
65+ | Some ReturnsTask ->
66+ match funcIdent with
67+ | HasAsyncSuffix _ ->
68+ Array.empty
69+ | HasAsyncPrefix name
70+ | HasNoAsyncPrefixOrSuffix name ->
71+ let nameWithAsync = name + asyncSuffixOrPrefix
72+ emitWarning identRange nameWithAsync " Task"
73+ | None ->
74+ // TODO: get type using typed tree in args.CheckInfo
4075 Array.empty
41- | HasAsyncSuffix name
42- | HasNoAsyncPrefixOrSuffix name ->
43- let nameWithAsync = asyncSuffixOrPrefix + name
44- emitWarning identRange nameWithAsync " Async"
45- | Some ReturnsTask ->
46- match funcIdent with
47- | HasAsyncSuffix _ ->
76+ | _ ->
4877 Array.empty
49- | HasAsyncPrefix name
50- | HasNoAsyncPrefixOrSuffix name ->
51- let nameWithAsync = name + asyncSuffixOrPrefix
52- emitWarning identRange nameWithAsync " Task"
53- | None ->
54- // TODO: get type using typed tree in args.CheckInfo
55- Array.empty
56- | _ ->
57- Array.empty
58- | _ -> Array.empty
78+ | _ -> Array.empty
5979
60- let rule =
80+ let rule config =
6181 AstNodeRule
6282 {
6383 Name = " AsynchronousFunctionNames"
6484 Identifier = Identifiers.AsynchronousFunctionNames
6585 RuleConfig =
6686 {
67- AstNodeRuleConfig.Runner = runner
87+ AstNodeRuleConfig.Runner = runner config
6888 Cleanup = ignore
6989 }
7090 }
0 commit comments