mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-12-23 17:53:35 +03:00
Add documentation for every rule inside the source
This commit is contained in:
parent
e32f51e62f
commit
a64a719cdf
@ -1,6 +1,7 @@
|
||||
# elm-lint
|
||||
|
||||
An [Elm](http://elm-lang.org/) linter written in Elm. Get your code from correct to better.
|
||||
You can learn about the API and the rules it provides on the [package documentation](http://package.elm-lang.org/packages/jfmengels/elm-ast).
|
||||
|
||||
## Try it
|
||||
|
||||
@ -28,7 +29,7 @@ You can read the slides for my [presentation](http://slides.com/jeroenengels/elm
|
||||
- [NoUnannotatedFunction](rules/NoUnannotatedFunction.md) - Ensure every top-level function declaration has a type annotation.
|
||||
- [NoUnusedVariables](rules/NoUnusedVariables.md) - Reports variables that are declared but never used.
|
||||
- [NoUselessIf](rules/NoUselessIf.md) - Reports when both paths of an If expression result will lead to the same value.
|
||||
- [NoUselessPatternMatching](rules/NoUselessPatternMatching.md) - Reports case expressions that can be simplified. Either when all patterns will lead to the same value, or when a patter will lead to the same value as the default pattern.
|
||||
- [NoUselessPatternMatching](rules/NoUselessPatternMatching.md) - Reports case expressions that can be simplified. Either when all patterns will lead to the same value, or when a pattern will lead to the same value as the default pattern.
|
||||
- [NoWarningComments](rules/NoWarningComments.md) - Detect comments containing words like `TODO`, `FIXME` and `XXX`.
|
||||
- [SimplifyPiping](rules/SimplifyPiping.md) - Simplify piped functions like `List.map f >> List.map g` to `List.map (f >> g)`
|
||||
|
||||
|
@ -1,5 +1,56 @@
|
||||
module Lint.Rules.DefaultPatternPosition exposing (rule, PatternPosition(..))
|
||||
|
||||
{-|
|
||||
@docs rule, PatternPosition
|
||||
|
||||
# Fail
|
||||
|
||||
rules =
|
||||
[ DefaultPatternPosition.rule { position = Lint.Rules.DefaultPatternPosition.Last }
|
||||
]
|
||||
|
||||
case value of
|
||||
-- Error, this pattern should appear last
|
||||
_ -> result
|
||||
Foo -> bar
|
||||
|
||||
-- --------------------
|
||||
|
||||
rules =
|
||||
[ DefaultPatternPosition.rule { position = Lint.Rules.DefaultPatternPosition.First }
|
||||
]
|
||||
|
||||
case value of
|
||||
Foo -> bar
|
||||
-- Error, this pattern should appear first
|
||||
_ -> result
|
||||
|
||||
# Success
|
||||
|
||||
rules =
|
||||
[ DefaultPatternPosition.rule { position = Lint.Rules.DefaultPatternPosition.Last }
|
||||
]
|
||||
|
||||
case value of
|
||||
Foo -> bar
|
||||
_ -> result
|
||||
|
||||
case value of
|
||||
-- No default pattern
|
||||
Foo -> bar
|
||||
Bar -> foo
|
||||
|
||||
-- --------------------
|
||||
|
||||
rules =
|
||||
[ DefaultPatternPosition.rule { position = Lint.Rules.DefaultPatternPosition.First }
|
||||
]
|
||||
|
||||
case value of
|
||||
_ -> result
|
||||
Foo -> bar
|
||||
-}
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Lint exposing (doNothing, lint)
|
||||
import Lint.Types exposing (Direction(..), Error, LintRule)
|
||||
@ -11,6 +62,8 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Configures whether the default pattern should appear first or last.
|
||||
-}
|
||||
type PatternPosition
|
||||
= First
|
||||
| Last
|
||||
@ -21,6 +74,8 @@ type alias Configuration =
|
||||
}
|
||||
|
||||
|
||||
{-| Enforce the default pattern to always appear first or last.
|
||||
-}
|
||||
rule : Configuration -> String -> List Error
|
||||
rule config input =
|
||||
lint input (implementation config)
|
||||
@ -41,8 +96,10 @@ error =
|
||||
Error "DefaultPatternPosition"
|
||||
|
||||
|
||||
{-| TODO Share this in a util file, already defined in NoUselessPatternMatching
|
||||
-}
|
||||
|
||||
{- TODO Share isVariable this in a util file, already defined in NoUselessPatternMatching -}
|
||||
|
||||
|
||||
isVariable : String -> Bool
|
||||
isVariable =
|
||||
Regex.contains (Regex.regex "^[_a-z][\\w\\d]*$")
|
||||
|
@ -1,5 +1,19 @@
|
||||
module Lint.Rules.NoConstantCondition exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
if True then a else b
|
||||
if False then a else b
|
||||
if foo == foo then a else b
|
||||
|
||||
# Success
|
||||
|
||||
if foo == bar then a else b
|
||||
-}
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -10,6 +24,12 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Forbid the use of expressions in an If condition whose value are always the same.
|
||||
|
||||
rules =
|
||||
[ NoConstantCondition.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,24 @@
|
||||
module Lint.Rules.NoDebug exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
if Debug.log "condition" condition then a else b
|
||||
if condition then
|
||||
Debug.crash "Nooo!"
|
||||
else
|
||||
value
|
||||
|
||||
# Success
|
||||
|
||||
if condition then
|
||||
a
|
||||
else
|
||||
b
|
||||
-}
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -9,6 +28,12 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Forbid the use of `Debug` before it goes into production.
|
||||
|
||||
rules =
|
||||
[ NoDebug.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,18 @@
|
||||
module Lint.Rules.NoDuplicateImports exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
import Set
|
||||
import Set exposing (Set)
|
||||
|
||||
# Success
|
||||
|
||||
import Set exposing (Set)
|
||||
-}
|
||||
|
||||
import Ast.Statement exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -12,6 +25,12 @@ type alias Context =
|
||||
}
|
||||
|
||||
|
||||
{-| Forbid importing the same module several times in a file.
|
||||
|
||||
rules =
|
||||
[ NoDuplicateImports.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,17 @@
|
||||
module Lint.Rules.NoExposingEverything exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
module Main exposing (..)
|
||||
|
||||
# Success
|
||||
|
||||
module Main exposing (a, b, C)
|
||||
-}
|
||||
|
||||
import Ast.Statement exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -9,6 +21,12 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Forbid exporting everything in your modules `module Main exposing (..)`, to make your module explicit in what it exposes.
|
||||
|
||||
rules =
|
||||
[ NoExposingEverything.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,17 @@
|
||||
module Lint.Rules.NoImportingEverything exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
import Html exposing (..)
|
||||
|
||||
# Success
|
||||
|
||||
import Html exposing (div, p, textarea)
|
||||
-}
|
||||
|
||||
import Ast.Statement exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -9,6 +21,13 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Forbid importing everything from your module. This can especially be confusing to newcomers when the exposed
|
||||
functions and types are unknown to them.
|
||||
|
||||
rules =
|
||||
[ NoImportingEverything.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,23 @@
|
||||
module Lint.Rules.NoNestedLet exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
a = let b = 1
|
||||
in let c = 2
|
||||
in b + c
|
||||
|
||||
# Success
|
||||
|
||||
a = let
|
||||
b = 1
|
||||
c = 2
|
||||
in
|
||||
b + c
|
||||
-}
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -9,6 +27,12 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Forbid nesting let expressions directly.
|
||||
|
||||
rules =
|
||||
[ NoNestedLet.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,20 @@
|
||||
module Lint.Rules.NoUnannotatedFunction exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
a n =
|
||||
n + 1
|
||||
|
||||
# Success
|
||||
|
||||
a : Int -> Int
|
||||
a n =
|
||||
n + 1
|
||||
-}
|
||||
|
||||
import Ast.Statement exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -11,6 +26,12 @@ type alias Context =
|
||||
}
|
||||
|
||||
|
||||
{-| Ensure every top-level function declaration has a type annotation.
|
||||
|
||||
rules =
|
||||
[ NoUnannotatedFunction.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,22 @@
|
||||
module Lint.Rules.NoUnusedVariables exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
module Main exposing (a)
|
||||
a n =
|
||||
n + 1
|
||||
b = a 2
|
||||
|
||||
# Success
|
||||
|
||||
module Main exposing (a)
|
||||
a n =
|
||||
n + 1
|
||||
-}
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Ast.Statement exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
@ -24,6 +41,12 @@ emptyScope =
|
||||
Scope Set.empty Set.empty
|
||||
|
||||
|
||||
{-| Reports variables that are declared but never used.
|
||||
|
||||
rules =
|
||||
[ NoUnusedVariables.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,23 @@
|
||||
module Lint.Rules.NoUselessIf exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
if condition then
|
||||
value
|
||||
else
|
||||
value
|
||||
|
||||
# Success
|
||||
|
||||
if condition then
|
||||
value1
|
||||
else
|
||||
value2
|
||||
-}
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -9,6 +27,12 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Reports when both paths of an If expression result will lead to the same value.
|
||||
|
||||
rules =
|
||||
[ NoUselessIf.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,34 @@
|
||||
module Lint.Rules.NoUselessPatternMatching exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
-- Useless pattern matching
|
||||
case value of
|
||||
Foo -> 1
|
||||
Bar -> 1
|
||||
_ -> 1
|
||||
|
||||
-- Useless pattern `Bar`, it's the same as the default pattern
|
||||
case value of
|
||||
Foo -> 2
|
||||
Bar -> 1
|
||||
_ -> 1
|
||||
|
||||
# Success
|
||||
|
||||
case value of
|
||||
Foo -> 1
|
||||
Bar -> 2
|
||||
_ -> 3
|
||||
|
||||
case value of
|
||||
Foo n -> n
|
||||
Bar n -> n
|
||||
-}
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Lint exposing (lint, visitExpression, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -11,6 +40,13 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Reports case expressions that can be simplified. Either when all patterns will lead to the same value, or when a
|
||||
pattern will lead to the same value as the default pattern.
|
||||
|
||||
rules =
|
||||
[ NoUselessPatternMatching.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,19 @@
|
||||
module Lint.Rules.NoWarningComments exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
-- TODO Refactor this part of the code
|
||||
-- FIXME Broken because of...
|
||||
-- XXX This should not be done like this
|
||||
|
||||
# Success
|
||||
|
||||
-- Regular comment
|
||||
-}
|
||||
|
||||
import Ast.Statement exposing (..)
|
||||
import Lint exposing (doNothing, lint)
|
||||
import Lint.Types exposing (Direction(..), Error, LintRule)
|
||||
@ -10,6 +24,12 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Detect comments containing words like `TODO`, `FIXME` and `XXX`.
|
||||
|
||||
rules =
|
||||
[ NoWarningComments.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
@ -1,5 +1,20 @@
|
||||
module Lint.Rules.SimplifyPiping exposing (rule)
|
||||
|
||||
{-|
|
||||
@docs rule
|
||||
|
||||
# Fail
|
||||
|
||||
a = values
|
||||
|> List.map foo
|
||||
|> List.map bar
|
||||
|
||||
# Success
|
||||
|
||||
a = values
|
||||
|> List.map (foo >> bar)
|
||||
-}
|
||||
|
||||
import Ast.Expression exposing (..)
|
||||
import Lint exposing (lint, doNothing)
|
||||
import Lint.Types exposing (LintRule, Error, Direction(..))
|
||||
@ -10,6 +25,12 @@ type alias Context =
|
||||
{}
|
||||
|
||||
|
||||
{-| Simplify piped functions like `List.map f >> List.map g` to `List.map (f >> g)`
|
||||
|
||||
rules =
|
||||
[ SimplifyPiping.rule
|
||||
]
|
||||
-}
|
||||
rule : String -> List Error
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
Loading…
Reference in New Issue
Block a user