mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-08-16 19:40:22 +03:00
Backport rules from other projects
This commit is contained in:
parent
bb14366da9
commit
b1b96c6dcf
@ -39,7 +39,7 @@ and publishing the package. Otherwise the link for a given version could link to
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-documentation/example --rules NoUselessSubscriptions
|
elm-review --template jfmengels/elm-review-documentation/example --rules NoUselessSubscriptions
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
112
tests/NoBooleanCaseOf.elm
Normal file
112
tests/NoBooleanCaseOf.elm
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
module NoBooleanCaseOf exposing (rule)
|
||||||
|
|
||||||
|
{-|
|
||||||
|
|
||||||
|
@docs rule
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Elm.Syntax.Expression as Expression exposing (Expression)
|
||||||
|
import Elm.Syntax.Node as Node exposing (Node)
|
||||||
|
import Elm.Syntax.Pattern as Pattern exposing (Pattern)
|
||||||
|
import Review.Rule as Rule exposing (Error, Rule)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Reports when pattern matching is used for a boolean value.
|
||||||
|
|
||||||
|
The idiomatic way to check for a condition is to use an `if` expression.
|
||||||
|
Read more about it at: <https://guide.elm-lang.org/core_language.html#if-expressions>
|
||||||
|
|
||||||
|
config =
|
||||||
|
[ NoBooleanCaseOf.rule
|
||||||
|
]
|
||||||
|
|
||||||
|
This won't report pattern matching when a boolean is part of the evaluated value.
|
||||||
|
|
||||||
|
|
||||||
|
## Fail
|
||||||
|
|
||||||
|
_ =
|
||||||
|
case bool of
|
||||||
|
True ->
|
||||||
|
expression
|
||||||
|
|
||||||
|
False ->
|
||||||
|
otherExpression
|
||||||
|
|
||||||
|
|
||||||
|
## Success
|
||||||
|
|
||||||
|
_ =
|
||||||
|
if bool then
|
||||||
|
expression
|
||||||
|
|
||||||
|
else
|
||||||
|
otherExpression
|
||||||
|
|
||||||
|
_ =
|
||||||
|
case ( bool, somethingElse ) of
|
||||||
|
( True, SomeThingElse ) ->
|
||||||
|
expression
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
otherExpression
|
||||||
|
|
||||||
|
|
||||||
|
# When (not) to use this rule
|
||||||
|
|
||||||
|
You should not use this rule if you do not care about how your boolean values are
|
||||||
|
evaluated.
|
||||||
|
|
||||||
|
|
||||||
|
## Try it out
|
||||||
|
|
||||||
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
elm-review --template jfmengels/elm-review-simplification/example --rules NoBooleanCaseOf
|
||||||
|
```
|
||||||
|
|
||||||
|
-}
|
||||||
|
rule : Rule
|
||||||
|
rule =
|
||||||
|
Rule.newModuleRuleSchema "NoBooleanCaseOf" ()
|
||||||
|
|> Rule.withSimpleExpressionVisitor expressionVisitor
|
||||||
|
|> Rule.fromModuleRuleSchema
|
||||||
|
|
||||||
|
|
||||||
|
expressionVisitor : Node Expression -> List (Error {})
|
||||||
|
expressionVisitor node =
|
||||||
|
case Node.value node of
|
||||||
|
Expression.CaseExpression { expression, cases } ->
|
||||||
|
if List.any (Tuple.first >> isBoolConstructor) cases then
|
||||||
|
[ error expression ]
|
||||||
|
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
error : Node a -> Error {}
|
||||||
|
error node =
|
||||||
|
Rule.error
|
||||||
|
{ message = "Replace `case..of` by an `if` condition"
|
||||||
|
, details =
|
||||||
|
[ "The idiomatic way to check for a condition is to use an `if` expression."
|
||||||
|
, "Read more about it at: https://guide.elm-lang.org/core_language.html#if-expressions"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
(Node.range node)
|
||||||
|
|
||||||
|
|
||||||
|
isBoolConstructor : Node Pattern -> Bool
|
||||||
|
isBoolConstructor node =
|
||||||
|
case Node.value node of
|
||||||
|
Pattern.NamedPattern { moduleName, name } _ ->
|
||||||
|
(name == "True" || name == "False")
|
||||||
|
&& (moduleName == [] || moduleName == [ "Basics" ])
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
False
|
111
tests/NoBooleanCaseOfTest.elm
Normal file
111
tests/NoBooleanCaseOfTest.elm
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
module NoBooleanCaseOfTest exposing (all)
|
||||||
|
|
||||||
|
import NoBooleanCaseOf exposing (rule)
|
||||||
|
import Review.Test exposing (ReviewResult)
|
||||||
|
import Test exposing (Test, describe, test)
|
||||||
|
|
||||||
|
|
||||||
|
testRule : String -> ReviewResult
|
||||||
|
testRule string =
|
||||||
|
"module A exposing (..)\n\n"
|
||||||
|
++ string
|
||||||
|
|> Review.Test.run rule
|
||||||
|
|
||||||
|
|
||||||
|
message : String
|
||||||
|
message =
|
||||||
|
"Replace `case..of` by an `if` condition"
|
||||||
|
|
||||||
|
|
||||||
|
details : List String
|
||||||
|
details =
|
||||||
|
[ "The idiomatic way to check for a condition is to use an `if` expression."
|
||||||
|
, "Read more about it at: https://guide.elm-lang.org/core_language.html#if-expressions"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
tests : List Test
|
||||||
|
tests =
|
||||||
|
[ test "should not report pattern matches for non-boolean values" <|
|
||||||
|
\() ->
|
||||||
|
testRule """
|
||||||
|
a = case thing of
|
||||||
|
Thing -> 1"""
|
||||||
|
|> Review.Test.expectNoErrors
|
||||||
|
, test "should not report pattern matches when the evaluated expression is a tuple of with a boolean" <|
|
||||||
|
\() ->
|
||||||
|
testRule """
|
||||||
|
a = case ( bool1, bool2 ) of
|
||||||
|
( True, True ) -> 1
|
||||||
|
_ -> 2"""
|
||||||
|
|> Review.Test.expectNoErrors
|
||||||
|
, test "should report pattern matches when one of the patterns is a bool constructor" <|
|
||||||
|
\() ->
|
||||||
|
testRule """
|
||||||
|
a = case boolTrue of
|
||||||
|
True -> 1
|
||||||
|
_ -> 2
|
||||||
|
|
||||||
|
b = case boolFalse of
|
||||||
|
False -> 1
|
||||||
|
_ -> 2
|
||||||
|
|
||||||
|
c = case boolAll of
|
||||||
|
False -> 1
|
||||||
|
True -> 2"""
|
||||||
|
|> Review.Test.expectErrors
|
||||||
|
[ Review.Test.error
|
||||||
|
{ message = message
|
||||||
|
, details = details
|
||||||
|
, under = "boolTrue"
|
||||||
|
}
|
||||||
|
, Review.Test.error
|
||||||
|
{ message = message
|
||||||
|
, details = details
|
||||||
|
, under = "boolFalse"
|
||||||
|
}
|
||||||
|
, Review.Test.error
|
||||||
|
{ message = message
|
||||||
|
, details = details
|
||||||
|
, under = "boolAll"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
, test "should report pattern matches for booleans even when one of the patterns starts with `Basics.`" <|
|
||||||
|
\() ->
|
||||||
|
testRule """
|
||||||
|
a = case boolTrue of
|
||||||
|
Basics.True -> 1
|
||||||
|
_ -> 2
|
||||||
|
|
||||||
|
b = case boolFalse of
|
||||||
|
Basics.False -> 1
|
||||||
|
_ -> 2"""
|
||||||
|
|> Review.Test.expectErrors
|
||||||
|
[ Review.Test.error
|
||||||
|
{ message = message
|
||||||
|
, details = details
|
||||||
|
, under = "boolTrue"
|
||||||
|
}
|
||||||
|
, Review.Test.error
|
||||||
|
{ message = message
|
||||||
|
, details = details
|
||||||
|
, under = "boolFalse"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
, test "should report pattern matches for booleans even when the constructor seems to be for booleans but comes from an unknown module" <|
|
||||||
|
\() ->
|
||||||
|
testRule """
|
||||||
|
a = case boolTrue of
|
||||||
|
OtherModule.True -> 1
|
||||||
|
_ -> 2
|
||||||
|
|
||||||
|
b = case boolFalse of
|
||||||
|
OtherModule.False -> 1
|
||||||
|
_ -> 2"""
|
||||||
|
|> Review.Test.expectNoErrors
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
all : Test
|
||||||
|
all =
|
||||||
|
describe "NoBooleanCaseOf" tests
|
@ -57,7 +57,7 @@ do not ship to production.
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-debug/example --rules NoDebug.Log
|
elm-review --template jfmengels/elm-review-debug/example --rules NoDebug.Log
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -74,7 +74,7 @@ can configure the rule like this.
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-debug/example --rules NoDebug.TodoOrToString
|
elm-review --template jfmengels/elm-review-debug/example --rules NoDebug.TodoOrToString
|
||||||
```
|
```
|
||||||
|
|
||||||
[`Debug.log`]: https://package.elm-lang.org/packages/elm/core/latest/Debug#log
|
[`Debug.log`]: https://package.elm-lang.org/packages/elm/core/latest/Debug#log
|
||||||
@ -84,28 +84,22 @@ elm-review --template jfmengels/review-debug/example --rules NoDebug.TodoOrToStr
|
|||||||
-}
|
-}
|
||||||
rule : Rule
|
rule : Rule
|
||||||
rule =
|
rule =
|
||||||
Rule.newModuleRuleSchemaUsingContextCreator "NoDebug.TodoOrToString" contextCreator
|
Rule.newModuleRuleSchema "NoDebug.TodoOrToString" init
|
||||||
|> Rule.withImportVisitor importVisitor
|
|> Rule.withImportVisitor importVisitor
|
||||||
|> Rule.withExpressionEnterVisitor expressionVisitor
|
|> Rule.withExpressionVisitor expressionVisitor
|
||||||
|> Rule.fromModuleRuleSchema
|
|> Rule.fromModuleRuleSchema
|
||||||
|
|
||||||
|
|
||||||
contextCreator : Rule.ContextCreator () Context
|
|
||||||
contextCreator =
|
|
||||||
Rule.initContextCreator
|
|
||||||
(\metadata () ->
|
|
||||||
{ hasTodoBeenImported = False
|
|
||||||
, hasToStringBeenImported = False
|
|
||||||
, isInSourceDirectories = Rule.isInSourceDirectories metadata
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> Rule.withMetadata
|
|
||||||
|
|
||||||
|
|
||||||
type alias Context =
|
type alias Context =
|
||||||
{ hasTodoBeenImported : Bool
|
{ hasTodoBeenImported : Bool
|
||||||
, hasToStringBeenImported : Bool
|
, hasToStringBeenImported : Bool
|
||||||
, isInSourceDirectories : Bool
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init : Context
|
||||||
|
init =
|
||||||
|
{ hasTodoBeenImported = False
|
||||||
|
, hasToStringBeenImported = False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -133,13 +127,13 @@ importVisitor node context =
|
|||||||
if moduleName == [ "Debug" ] then
|
if moduleName == [ "Debug" ] then
|
||||||
case node |> Node.value |> .exposingList |> Maybe.map Node.value of
|
case node |> Node.value |> .exposingList |> Maybe.map Node.value of
|
||||||
Just (Exposing.All _) ->
|
Just (Exposing.All _) ->
|
||||||
( [], { hasTodoBeenImported = True, hasToStringBeenImported = True, isInSourceDirectories = context.isInSourceDirectories } )
|
( [], { hasTodoBeenImported = True, hasToStringBeenImported = True } )
|
||||||
|
|
||||||
Just (Exposing.Explicit importedNames) ->
|
Just (Exposing.Explicit importedNames) ->
|
||||||
( []
|
( []
|
||||||
, { hasTodoBeenImported = List.any (is "todo") importedNames
|
, { context
|
||||||
, hasToStringBeenImported = List.any (is "toString") importedNames
|
| hasTodoBeenImported = List.any (is "todo") importedNames
|
||||||
, isInSourceDirectories = context.isInSourceDirectories
|
, hasToStringBeenImported = List.any (is "toString") importedNames
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -160,32 +154,28 @@ is name node =
|
|||||||
False
|
False
|
||||||
|
|
||||||
|
|
||||||
expressionVisitor : Node Expression -> Context -> ( List (Error {}), Context )
|
expressionVisitor : Node Expression -> Rule.Direction -> Context -> ( List (Error {}), Context )
|
||||||
expressionVisitor node context =
|
expressionVisitor node direction context =
|
||||||
if not context.isInSourceDirectories then
|
case ( direction, Node.value node ) of
|
||||||
( [], context )
|
( Rule.OnEnter, Expression.FunctionOrValue [ "Debug" ] name ) ->
|
||||||
|
if name == "todo" then
|
||||||
|
( [ error node name ], context )
|
||||||
|
|
||||||
else
|
else if name == "toString" then
|
||||||
case Node.value node of
|
( [ error node name ], context )
|
||||||
Expression.FunctionOrValue [ "Debug" ] name ->
|
|
||||||
if name == "todo" then
|
|
||||||
( [ error node name ], context )
|
|
||||||
|
|
||||||
else if name == "toString" then
|
else
|
||||||
( [ error node name ], context )
|
|
||||||
|
|
||||||
else
|
|
||||||
( [], context )
|
|
||||||
|
|
||||||
Expression.FunctionOrValue [] name ->
|
|
||||||
if name == "todo" && context.hasTodoBeenImported then
|
|
||||||
( [ error node name ], context )
|
|
||||||
|
|
||||||
else if name == "toString" && context.hasToStringBeenImported then
|
|
||||||
( [ error node name ], context )
|
|
||||||
|
|
||||||
else
|
|
||||||
( [], context )
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
( [], context )
|
( [], context )
|
||||||
|
|
||||||
|
( Rule.OnEnter, Expression.FunctionOrValue [] name ) ->
|
||||||
|
if name == "todo" && context.hasTodoBeenImported then
|
||||||
|
( [ error node name ], context )
|
||||||
|
|
||||||
|
else if name == "toString" && context.hasToStringBeenImported then
|
||||||
|
( [ error node name ], context )
|
||||||
|
|
||||||
|
else
|
||||||
|
( [], context )
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
( [], context )
|
||||||
|
@ -46,7 +46,7 @@ in the following manner:
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-common/example --rules NoExposingEverything
|
elm-review --template jfmengels/elm-review-common/example --rules NoExposingEverything
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -50,7 +50,7 @@ you can configure a list of exceptions.
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-common/example --rules NoImportingEverything
|
elm-review --template jfmengels/elm-review-common/example --rules NoImportingEverything
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -58,7 +58,7 @@ This won't fail if `SomeModule` does not define a `subscriptions` function.
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm - review --template jfmengels/review-tea/example --rules NoMissingSubscriptionsCall
|
elm-review --template jfmengels/elm-review-the-elm-architecture/example --rules NoMissingSubscriptionsCall
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
@ -67,8 +67,8 @@ rule =
|
|||||||
Rule.newProjectRuleSchema "NoMissingSubscriptionsCall" initialProjectContext
|
Rule.newProjectRuleSchema "NoMissingSubscriptionsCall" initialProjectContext
|
||||||
|> Rule.withModuleVisitor moduleVisitor
|
|> Rule.withModuleVisitor moduleVisitor
|
||||||
|> Rule.withModuleContextUsingContextCreator
|
|> Rule.withModuleContextUsingContextCreator
|
||||||
{ fromProjectToModule = Rule.initContextCreator fromProjectToModule |> Rule.withModuleNameLookupTable
|
{ fromProjectToModule = fromProjectToModule
|
||||||
, fromModuleToProject = Rule.initContextCreator fromModuleToProject |> Rule.withMetadata
|
, fromModuleToProject = fromModuleToProject
|
||||||
, foldProjectContexts = foldProjectContexts
|
, foldProjectContexts = foldProjectContexts
|
||||||
}
|
}
|
||||||
|> Rule.withContextFromImportedModules
|
|> Rule.withContextFromImportedModules
|
||||||
@ -89,15 +89,12 @@ type alias ProjectContext =
|
|||||||
|
|
||||||
|
|
||||||
type alias ModuleContext =
|
type alias ModuleContext =
|
||||||
{ modulesThatExposeSubscriptionsAndUpdate : Set ModuleName
|
{ lookupTable : ModuleNameLookupTable
|
||||||
|
, modulesThatExposeSubscriptionsAndUpdate : Set ModuleName
|
||||||
--, usesUpdate : Bool
|
|
||||||
--, usesSubscription : Bool
|
|
||||||
, definesUpdate : Bool
|
, definesUpdate : Bool
|
||||||
, definesSubscriptions : Bool
|
, definesSubscriptions : Bool
|
||||||
, usesUpdateOfModule : Dict ModuleName Range
|
, usesUpdateOfModule : Dict ModuleName Range
|
||||||
, usesSubscriptionsOfModule : Set ModuleName
|
, usesSubscriptionsOfModule : Set ModuleName
|
||||||
, lookupTable : ModuleNameLookupTable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -107,26 +104,34 @@ initialProjectContext =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fromProjectToModule : ModuleNameLookupTable -> ProjectContext -> ModuleContext
|
fromProjectToModule : Rule.ContextCreator ProjectContext ModuleContext
|
||||||
fromProjectToModule lookupTable projectContext =
|
fromProjectToModule =
|
||||||
{ modulesThatExposeSubscriptionsAndUpdate = projectContext.modulesThatExposeSubscriptionsAndUpdate
|
Rule.initContextCreator
|
||||||
, definesUpdate = False
|
(\lookupTable projectContext ->
|
||||||
, definesSubscriptions = False
|
{ lookupTable = lookupTable
|
||||||
, usesUpdateOfModule = Dict.empty
|
, modulesThatExposeSubscriptionsAndUpdate = projectContext.modulesThatExposeSubscriptionsAndUpdate
|
||||||
, usesSubscriptionsOfModule = Set.empty
|
, definesUpdate = False
|
||||||
, lookupTable = lookupTable
|
, definesSubscriptions = False
|
||||||
}
|
, usesUpdateOfModule = Dict.empty
|
||||||
|
, usesSubscriptionsOfModule = Set.empty
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|> Rule.withModuleNameLookupTable
|
||||||
|
|
||||||
|
|
||||||
fromModuleToProject : Rule.Metadata -> ModuleContext -> ProjectContext
|
fromModuleToProject : Rule.ContextCreator ModuleContext ProjectContext
|
||||||
fromModuleToProject metadata moduleContext =
|
fromModuleToProject =
|
||||||
{ modulesThatExposeSubscriptionsAndUpdate =
|
Rule.initContextCreator
|
||||||
if moduleContext.definesSubscriptions && moduleContext.definesUpdate then
|
(\metadata moduleContext ->
|
||||||
Set.singleton (Rule.moduleNameFromMetadata metadata)
|
{ modulesThatExposeSubscriptionsAndUpdate =
|
||||||
|
if moduleContext.definesSubscriptions && moduleContext.definesUpdate then
|
||||||
|
Set.singleton (Rule.moduleNameFromMetadata metadata)
|
||||||
|
|
||||||
else
|
else
|
||||||
Set.empty
|
Set.empty
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|> Rule.withMetadata
|
||||||
|
|
||||||
|
|
||||||
foldProjectContexts : ProjectContext -> ProjectContext -> ProjectContext
|
foldProjectContexts : ProjectContext -> ProjectContext -> ProjectContext
|
||||||
@ -166,9 +171,9 @@ expressionVisitor node moduleContext =
|
|||||||
case Node.value node of
|
case Node.value node of
|
||||||
Expression.FunctionOrValue _ "update" ->
|
Expression.FunctionOrValue _ "update" ->
|
||||||
case ModuleNameLookupTable.moduleNameFor moduleContext.lookupTable node of
|
case ModuleNameLookupTable.moduleNameFor moduleContext.lookupTable node of
|
||||||
Just realModuleName ->
|
Just moduleName ->
|
||||||
if Set.member realModuleName moduleContext.modulesThatExposeSubscriptionsAndUpdate then
|
if Set.member moduleName moduleContext.modulesThatExposeSubscriptionsAndUpdate then
|
||||||
( [], { moduleContext | usesUpdateOfModule = Dict.insert realModuleName (Node.range node) moduleContext.usesUpdateOfModule } )
|
( [], { moduleContext | usesUpdateOfModule = Dict.insert moduleName (Node.range node) moduleContext.usesUpdateOfModule } )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], moduleContext )
|
( [], moduleContext )
|
||||||
@ -178,9 +183,9 @@ expressionVisitor node moduleContext =
|
|||||||
|
|
||||||
Expression.FunctionOrValue _ "subscriptions" ->
|
Expression.FunctionOrValue _ "subscriptions" ->
|
||||||
case ModuleNameLookupTable.moduleNameFor moduleContext.lookupTable node of
|
case ModuleNameLookupTable.moduleNameFor moduleContext.lookupTable node of
|
||||||
Just realModuleName ->
|
Just moduleName ->
|
||||||
if Set.member realModuleName moduleContext.modulesThatExposeSubscriptionsAndUpdate then
|
if Set.member moduleName moduleContext.modulesThatExposeSubscriptionsAndUpdate then
|
||||||
( [], { moduleContext | usesSubscriptionsOfModule = Set.insert realModuleName moduleContext.usesSubscriptionsOfModule } )
|
( [], { moduleContext | usesSubscriptionsOfModule = Set.insert moduleName moduleContext.usesSubscriptionsOfModule } )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], moduleContext )
|
( [], moduleContext )
|
||||||
|
@ -49,7 +49,7 @@ For that, enable [`NoMissingTypeAnnotationInLetIn`](./NoMissingTypeAnnotationInL
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-common/example --rules NoMissingTypeAnnotation
|
elm-review --template jfmengels/elm-review-common/example --rules NoMissingTypeAnnotation
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -53,7 +53,7 @@ For that, enable [`NoMissingTypeAnnotation`](./NoMissingTypeAnnotation).
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-common/example --rules NoMissingTypeAnnotationInLetIn
|
elm-review --template jfmengels/elm-review-common/example --rules NoMissingTypeAnnotationInLetIn
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -78,7 +78,7 @@ If a type is not exposed then it can be impossible to annotate functions or valu
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-common/example --rules NoMissingTypeExpose
|
elm-review --template jfmengels/elm-review-common/example --rules NoMissingTypeExpose
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -887,7 +887,7 @@ packageElmJson : String
|
|||||||
packageElmJson =
|
packageElmJson =
|
||||||
"""{
|
"""{
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"name": "jfmengels/review-common-tests",
|
"name": "jfmengels/elm-review-common-tests",
|
||||||
"summary": "A test package",
|
"summary": "A test package",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
@ -51,6 +51,15 @@ To add the rule to your configuration:
|
|||||||
[ NoRecursiveUpdate.rule
|
[ NoRecursiveUpdate.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
## Try it out
|
||||||
|
|
||||||
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
elm-review --template jfmengels/elm-review-the-elm-architecture/example --rules NoRecursiveUpdate
|
||||||
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : Rule
|
rule : Rule
|
||||||
rule =
|
rule =
|
||||||
|
@ -33,6 +33,9 @@ This rule will warn arguments that are always pattern matched using a wildcard (
|
|||||||
|
|
||||||
For package projects, custom types whose constructors are exposed as part of the package API are not reported.
|
For package projects, custom types whose constructors are exposed as part of the package API are not reported.
|
||||||
|
|
||||||
|
Note that this rule may report false positives if you compare custom types with the `==`/`/=` operators (and never destructure the custom type), like when you do `value == Just 0`.
|
||||||
|
If you have a solution in mind to better handle these cases in a manageable way, please open an issue so we can talk about it.
|
||||||
|
|
||||||
|
|
||||||
## Fail
|
## Fail
|
||||||
|
|
||||||
@ -57,6 +60,8 @@ For package projects, custom types whose constructors are exposed as part of the
|
|||||||
If you like giving names to all arguments when pattern matching, then this rule will not found many problems.
|
If you like giving names to all arguments when pattern matching, then this rule will not found many problems.
|
||||||
This rule will work well when enabled along with [`NoUnused.Patterns`](./NoUnused-Patterns).
|
This rule will work well when enabled along with [`NoUnused.Patterns`](./NoUnused-Patterns).
|
||||||
|
|
||||||
|
Also, if you like comparing custom types in the way described above, you might pass on this rule, or want to be very careful when enabling it.
|
||||||
|
|
||||||
|
|
||||||
## Try it out
|
## Try it out
|
||||||
|
|
||||||
@ -323,8 +328,7 @@ expressionVisitor node context =
|
|||||||
let
|
let
|
||||||
usedArguments : List ( ( ModuleName, String ), Set Int )
|
usedArguments : List ( ( ModuleName, String ), Set Int )
|
||||||
usedArguments =
|
usedArguments =
|
||||||
cases
|
List.concatMap (Tuple.first >> collectUsedCustomTypeArgs context.lookupTable) cases
|
||||||
|> List.concatMap (Tuple.first >> collectUsedCustomTypeArgs context.lookupTable)
|
|
||||||
in
|
in
|
||||||
( [], { context | usedArguments = registerUsedPatterns usedArguments context.usedArguments } )
|
( [], { context | usedArguments = registerUsedPatterns usedArguments context.usedArguments } )
|
||||||
|
|
||||||
|
@ -360,6 +360,30 @@ something =
|
|||||||
, under = "SomeData"
|
, under = "SomeData"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
, test "should not report args if they are used in a different module" <|
|
||||||
|
\() ->
|
||||||
|
[ """
|
||||||
|
module Main exposing (Model, main)
|
||||||
|
import Messages exposing (Msg(..))
|
||||||
|
|
||||||
|
update : Msg -> Model -> Model
|
||||||
|
update msg model =
|
||||||
|
case msg of
|
||||||
|
Content s ->
|
||||||
|
{ model | content = "content " ++ s }
|
||||||
|
|
||||||
|
Search string ->
|
||||||
|
{ model | content = "search " ++ string }
|
||||||
|
"""
|
||||||
|
, """
|
||||||
|
module Messages exposing (Msg(..))
|
||||||
|
type Msg
|
||||||
|
= Content String
|
||||||
|
| Search String
|
||||||
|
"""
|
||||||
|
]
|
||||||
|
|> Review.Test.runOnModules rule
|
||||||
|
|> Review.Test.expectNoErrors
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ I would love help with improving this :)
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm - review --template jfmengels/review-unused/example --rules NoUnused.CustomTypeConstructors
|
elm-review --template jfmengels/elm-review-unused/example --rules NoUnused.CustomTypeConstructors
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -35,7 +35,7 @@ A dependency is considered unused if none of its modules are imported in the pro
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-unused/example --rules NoUnused.Dependencies
|
elm-review --template jfmengels/elm-elm-review-unused/example --rules NoUnused.Dependencies
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -46,7 +46,7 @@ then nothing will be reported.
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm - review --template jfmengels/review-unused/example --rules NoUnused.Exports
|
elm-review --template jfmengels/elm-review-unused/example --rules NoUnused.Exports
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
@ -635,5 +635,17 @@ expressionVisitor node moduleContext =
|
|||||||
Nothing ->
|
Nothing ->
|
||||||
( [], moduleContext )
|
( [], moduleContext )
|
||||||
|
|
||||||
|
Expression.RecordUpdateExpression (Node range name) _ ->
|
||||||
|
case ModuleNameLookupTable.moduleNameAt moduleContext.lookupTable range of
|
||||||
|
Just moduleName ->
|
||||||
|
( []
|
||||||
|
, registerAsUsed
|
||||||
|
( moduleName, name )
|
||||||
|
moduleContext
|
||||||
|
)
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
( [], moduleContext )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( [], moduleContext )
|
( [], moduleContext )
|
||||||
|
@ -165,6 +165,34 @@ a = 1
|
|||||||
module B exposing (main)
|
module B exposing (main)
|
||||||
import A exposing (..)
|
import A exposing (..)
|
||||||
main = a
|
main = a
|
||||||
|
""" ]
|
||||||
|
|> Review.Test.runOnModulesWithProjectData application rule
|
||||||
|
|> Review.Test.expectNoErrors
|
||||||
|
, test "should not report an exposed value when it is used in other modules (using record update syntax, importing explicitly)" <|
|
||||||
|
\() ->
|
||||||
|
[ """
|
||||||
|
module A exposing (..)
|
||||||
|
import B exposing (person)
|
||||||
|
otherPerson =
|
||||||
|
{ person | age = 30 }
|
||||||
|
""", """
|
||||||
|
module B exposing (person)
|
||||||
|
person =
|
||||||
|
{ age = 29 }
|
||||||
|
""" ]
|
||||||
|
|> Review.Test.runOnModulesWithProjectData application rule
|
||||||
|
|> Review.Test.expectNoErrors
|
||||||
|
, test "should not report an exposed value when it is used in other modules (using record update syntax, importing all)" <|
|
||||||
|
\() ->
|
||||||
|
[ """
|
||||||
|
module A exposing (..)
|
||||||
|
import B exposing (..)
|
||||||
|
otherPerson =
|
||||||
|
{ person | age = 30 }
|
||||||
|
""", """
|
||||||
|
module B exposing (person)
|
||||||
|
person =
|
||||||
|
{ age = 29 }
|
||||||
""" ]
|
""" ]
|
||||||
|> Review.Test.runOnModulesWithProjectData application rule
|
|> Review.Test.runOnModulesWithProjectData application rule
|
||||||
|> Review.Test.expectNoErrors
|
|> Review.Test.expectNoErrors
|
||||||
|
@ -43,7 +43,7 @@ config =
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-unused/example --rules NoUnused.Modules
|
elm-review --template jfmengels/elm-review-unused/example --rules NoUnused.Modules
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -55,7 +55,7 @@ Value `something` is not used:
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-unused/example --rules NoUnused.Parameters
|
elm-review --template jfmengels/elm-review-unused/example --rules NoUnused.Parameters
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -57,7 +57,7 @@ Value `something` is not used:
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-unused/example --rules NoUnused.Patterns
|
elm-review --template jfmengels/elm-review-unused/example --rules NoUnused.Patterns
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -56,7 +56,7 @@ import Set exposing (Set)
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-unused/example --rules NoUnused.Variables
|
elm-review --template jfmengels/elm-review-unused/example --rules NoUnused.Variables
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
@ -47,7 +47,7 @@ that turn out to be unnecessary later.
|
|||||||
You can try this rule out by running the following command:
|
You can try this rule out by running the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
elm-review --template jfmengels/review-tea/example --rules NoUselessSubscriptions
|
elm-review --template jfmengels/elm-review-the-elm-architecture/example --rules NoUselessSubscriptions
|
||||||
```
|
```
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
Loading…
Reference in New Issue
Block a user