Add NoNestedLet rule

This commit is contained in:
Jeroen Engels 2017-01-24 23:33:16 +01:00
parent 1e6129cdd1
commit da3f260ece
5 changed files with 91 additions and 0 deletions

View File

@ -23,6 +23,8 @@ You can read the slides for my [presentation](http://slides.com/jeroenengels/elm
- [NoDebug](rules/NoDebug.md) - Forbid the use of `Debug` before it goes into production.
- [NoDuplicateImports](rules/NoDuplicateImports.md) - Forbid importing the same module several times in a file.
- [NoExposingEverything](rules/NoExposingEverything.md) - Forbid exporting everything in your modules `module Main exposing (..)`, to make your module explicit in what it exposes.
- [NoImportingEverything](rules/NoImportingEverything.md) - Forbid importing everything from your module. This can especially be confusing to newcomers when the exposed functions and types are unknown to them.
- [NoNestedLet](rules/NoNestedLet.md) - Forbid nesting let expressions directly.
- [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.

View File

@ -20,6 +20,7 @@ import NoDebug
import NoDuplicateImports
import NoExposingEverything
import NoImportingEverything
import NoNestedLet
import NoUnannotatedFunction
import NoUnusedVariables
import NoUselessIf
@ -40,6 +41,7 @@ rules =
, NoDuplicateImports.rule
, NoExposingEverything.rule
, NoImportingEverything.rule
, NoNestedLet.rule
, NoUnannotatedFunction.rule
, NoUnusedVariables.rule
, NoUselessIf.rule

39
rules/NoNestedLet.elm Normal file
View File

@ -0,0 +1,39 @@
module NoNestedLet exposing (rule)
import Lint exposing (lint, doNothing)
import Types exposing (LintRule, Error, Direction(..))
import Ast.Expression exposing (..)
type alias Context =
{}
rule : String -> List Error
rule input =
lint input implementation
implementation : LintRule Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, initialContext = Context
}
error : Error
error =
Error "NoNestedLet" "Do not nest Let expressions directly"
expressionFn : Context -> Direction Expression -> ( List Error, Context )
expressionFn ctx node =
case node of
Enter (Let declarations (Let _ _)) ->
( [ error ], ctx )
_ ->
( [], ctx )

View File

@ -8,6 +8,7 @@ import NoConstantConditionTest
import NoDebugTest
import NoDuplicateImportsTest
import NoImportingEverythingTest
import NoNestedLetTest
import NoUnannotatedFunctionTest
import NoUnusedVariablesTest
import NoUselessIfTest
@ -32,6 +33,7 @@ all =
, NoDebugTest.all
, NoDuplicateImportsTest.all
, NoImportingEverythingTest.all
, NoNestedLetTest.all
, NoUnannotatedFunctionTest.all
, NoUnusedVariablesTest.all
, NoUselessIfTest.all

46
tests/NoNestedLetTest.elm Normal file
View File

@ -0,0 +1,46 @@
port module NoNestedLetTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import NoNestedLet exposing (rule)
import Types exposing (Error)
error : Error
error =
Error "NoNestedLet" "Do not nest Let expressions directly"
tests : List Test
tests =
[ test "should not report single let expression" <|
\() ->
"""a = let b = 1
in b
"""
|> rule
|> Expect.equal []
, test "should report let expression inside the body of an other let expression" <|
\() ->
"""a = let b = 1
in let c = 2
in c
"""
|> rule
|> Expect.equal [ error ]
, test "should not report let expression indirectly inside another " <|
\() ->
"""a = let b = 1
in if foo then
let c = 2 in c
else
3
"""
|> rule
|> Expect.equal []
]
all : Test
all =
describe "NoNestedLet" tests