mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-11-22 22:33:13 +03:00
Apply elm-upgrade
This commit is contained in:
parent
5c56965101
commit
48e3296fc3
@ -1,11 +1,9 @@
|
|||||||
{
|
{
|
||||||
"version": "2.0.1",
|
"type": "package",
|
||||||
|
"name": "jfmengels/elm-lint",
|
||||||
"summary": "A linter for Elm. Get your code from correct to better.",
|
"summary": "A linter for Elm. Get your code from correct to better.",
|
||||||
"repository": "https://github.com/jfmengels/elm-lint.git",
|
"license": "BSD-3-Clause",
|
||||||
"license": "BSD3",
|
"version": "2.0.1",
|
||||||
"source-directories": [
|
|
||||||
"src"
|
|
||||||
],
|
|
||||||
"exposed-modules": [
|
"exposed-modules": [
|
||||||
"Lint",
|
"Lint",
|
||||||
"Lint.Types",
|
"Lint.Types",
|
||||||
@ -25,12 +23,12 @@
|
|||||||
"Lint.Rules.SimplifyPropertyAccess",
|
"Lint.Rules.SimplifyPropertyAccess",
|
||||||
"Lint.Rules.ElmTest.NoDuplicateTestBodies"
|
"Lint.Rules.ElmTest.NoDuplicateTestBodies"
|
||||||
],
|
],
|
||||||
|
"elm-version": "0.19.0 <= v < 0.20.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Bogdanp/elm-ast": "8.0.3 <= v < 9.0.0",
|
"elm/core": "1.0.0 <= v < 2.0.0",
|
||||||
"elm-community/list-extra": "5.0.1 <= v < 6.0.0",
|
"elm/html": "1.0.0 <= v < 2.0.0",
|
||||||
"elm-community/parser-combinators": "1.1.0 <= v < 2.0.0",
|
"elm/regex": "1.0.0 <= v < 2.0.0",
|
||||||
"elm-lang/core": "5.0.0 <= v < 6.0.0",
|
"elm-community/list-extra": "8.1.0 <= v < 9.0.0"
|
||||||
"elm-lang/html": "2.0.0 <= v < 3.0.0"
|
|
||||||
},
|
},
|
||||||
"elm-version": "0.18.0 <= v < 0.19.0"
|
"test-dependencies": {}
|
||||||
}
|
}
|
@ -1,8 +1,10 @@
|
|||||||
module Lint.Rules.DefaultPatternPosition exposing (rule, Configuration, PatternPosition(..))
|
module Lint.Rules.DefaultPatternPosition exposing (rule, Configuration, PatternPosition(..))
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule, Configuration, PatternPosition
|
@docs rule, Configuration, PatternPosition
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
rules =
|
rules =
|
||||||
@ -25,6 +27,7 @@ module Lint.Rules.DefaultPatternPosition exposing (rule, Configuration, PatternP
|
|||||||
-- LintError, this pattern should appear first
|
-- LintError, this pattern should appear first
|
||||||
_ -> result
|
_ -> result
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
rules =
|
rules =
|
||||||
@ -49,11 +52,12 @@ module Lint.Rules.DefaultPatternPosition exposing (rule, Configuration, PatternP
|
|||||||
case value of
|
case value of
|
||||||
_ -> result
|
_ -> result
|
||||||
Foo -> bar
|
Foo -> bar
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Lint exposing (doNothing, lint)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, Direction(..), LintError, LintRuleImplementation)
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
import List.Extra exposing (findIndex)
|
import List.Extra exposing (findIndex)
|
||||||
import Regex
|
import Regex
|
||||||
|
|
||||||
@ -88,7 +92,7 @@ implementation configuration =
|
|||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn configuration
|
, expressionFn = expressionFn configuration
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +117,7 @@ isDefaultPattern pattern =
|
|||||||
Variable names ->
|
Variable names ->
|
||||||
if isVariable (String.join "." names) then
|
if isVariable (String.join "." names) then
|
||||||
True
|
True
|
||||||
|
|
||||||
else
|
else
|
||||||
False
|
False
|
||||||
|
|
||||||
@ -138,12 +143,14 @@ expressionFn config ctx node =
|
|||||||
First ->
|
First ->
|
||||||
if index /= 0 then
|
if index /= 0 then
|
||||||
( [ error "Expected default pattern to appear first in the list of patterns" ], ctx )
|
( [ error "Expected default pattern to appear first in the list of patterns" ], ctx )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
Last ->
|
Last ->
|
||||||
if index /= (List.length patterns) - 1 then
|
if index /= List.length patterns - 1 then
|
||||||
( [ error "Expected default pattern to appear last in the list of patterns" ], ctx )
|
( [ error "Expected default pattern to appear last in the list of patterns" ], ctx )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
|
@ -1,44 +1,52 @@
|
|||||||
module Lint.Rules.ElmTest.NoDuplicateTestBodies exposing (rule)
|
module Lint.Rules.ElmTest.NoDuplicateTestBodies exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
module Addition exposing (..)
|
|
||||||
|
|
||||||
import Test exposing (test)
|
import Test exposing (test)
|
||||||
|
|
||||||
tests =
|
tests =
|
||||||
[ test "foo" <|
|
[ test "foo" <|
|
||||||
\() -> 1 + 1
|
\() ->
|
||||||
|> Expect.equal 2
|
1
|
||||||
|
+ 1
|
||||||
|
|> Expect.equal 2
|
||||||
, test "bar" <|
|
, test "bar" <|
|
||||||
\() -> 1 + 1
|
\() ->
|
||||||
|> Expect.equal 2
|
1
|
||||||
|
+ 1
|
||||||
|
|> Expect.equal 2
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
module Addition exposing (..)
|
|
||||||
|
|
||||||
import Test exposing (test)
|
import Test exposing (test)
|
||||||
|
|
||||||
tests =
|
tests =
|
||||||
[ test "foo" <|
|
[ test "foo" <|
|
||||||
\() -> 1 + 1
|
\() ->
|
||||||
|> Expect.equal 2
|
1
|
||||||
|
+ 1
|
||||||
|
|> Expect.equal 2
|
||||||
, test "bar" <|
|
, test "bar" <|
|
||||||
\() -> 1 + 2
|
\() ->
|
||||||
|> Expect.equal 3
|
1
|
||||||
|
+ 2
|
||||||
|
|> Expect.equal 3
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Ast.Statement exposing (..)
|
import Ast.Statement exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
|
||||||
import Dict exposing (Dict)
|
import Dict exposing (Dict)
|
||||||
|
import Lint exposing (doNothing, lint)
|
||||||
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
|
|
||||||
|
|
||||||
type alias Context =
|
type alias Context =
|
||||||
@ -53,6 +61,7 @@ This may result in specifications that are thought to be implemented but are not
|
|||||||
rules =
|
rules =
|
||||||
[ ElmTest.NoDuplicateTestBodies.rule
|
[ ElmTest.NoDuplicateTestBodies.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -64,7 +73,7 @@ implementation =
|
|||||||
{ statementFn = statementFn
|
{ statementFn = statementFn
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context []
|
, initialContext = Context []
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +106,7 @@ filterTests availableTestAliases listItems =
|
|||||||
BinOp (Variable [ "<|" ]) (Application fn (String title)) testBody ->
|
BinOp (Variable [ "<|" ]) (Application fn (String title)) testBody ->
|
||||||
if isTestFunctionCall availableTestAliases fn then
|
if isTestFunctionCall availableTestAliases fn then
|
||||||
[ ( title, testBody ) ]
|
[ ( title, testBody ) ]
|
||||||
|
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
|
|
||||||
@ -124,17 +134,17 @@ expressionFn ctx node =
|
|||||||
existingTest =
|
existingTest =
|
||||||
Dict.get testBodyAsString dict
|
Dict.get testBodyAsString dict
|
||||||
in
|
in
|
||||||
case existingTest of
|
case existingTest of
|
||||||
Nothing ->
|
Nothing ->
|
||||||
{ dict = Dict.insert testBodyAsString title dict, redundant = redundant }
|
{ dict = Dict.insert testBodyAsString title dict, redundant = redundant }
|
||||||
|
|
||||||
Just existingTestTitle ->
|
Just existingTestTitle ->
|
||||||
{ dict = dict, redundant = redundant ++ [ ( title, existingTestTitle ) ] }
|
{ dict = dict, redundant = redundant ++ [ ( title, existingTestTitle ) ] }
|
||||||
)
|
)
|
||||||
{ dict = Dict.empty, redundant = [] }
|
{ dict = Dict.empty, redundant = [] }
|
||||||
tests
|
tests
|
||||||
in
|
in
|
||||||
( List.map error redundantTests.redundant, ctx )
|
( List.map error redundantTests.redundant, ctx )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
@ -152,6 +162,7 @@ extractImported exportSet =
|
|||||||
FunctionExport name ->
|
FunctionExport name ->
|
||||||
if name == "test" then
|
if name == "test" then
|
||||||
[ name ]
|
[ name ]
|
||||||
|
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
|
|
||||||
@ -172,12 +183,12 @@ statementFn ctx node =
|
|||||||
moduleFnAccess =
|
moduleFnAccess =
|
||||||
computeAlias testAlias ++ ".test"
|
computeAlias testAlias ++ ".test"
|
||||||
in
|
in
|
||||||
case exportSet of
|
case exportSet of
|
||||||
Nothing ->
|
Nothing ->
|
||||||
( [], { availableTestAliases = [ moduleFnAccess ] } )
|
( [], { availableTestAliases = [ moduleFnAccess ] } )
|
||||||
|
|
||||||
Just subExportSet ->
|
Just subExportSet ->
|
||||||
( [], { availableTestAliases = [ moduleFnAccess ] ++ extractImported subExportSet } )
|
( [], { availableTestAliases = [ moduleFnAccess ] ++ extractImported subExportSet } )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
@ -1,22 +1,44 @@
|
|||||||
module Lint.Rules.NoConstantCondition exposing (rule)
|
module Lint.Rules.NoConstantCondition exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
if True then a else b
|
if True then
|
||||||
if False then a else b
|
a
|
||||||
if foo == foo then a else b
|
|
||||||
|
else
|
||||||
|
b
|
||||||
|
|
||||||
|
if False then
|
||||||
|
a
|
||||||
|
|
||||||
|
else
|
||||||
|
b
|
||||||
|
|
||||||
|
if foo == foo then
|
||||||
|
a
|
||||||
|
|
||||||
|
else
|
||||||
|
b
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
if foo == bar then a else b
|
if foo == bar then
|
||||||
|
a
|
||||||
|
|
||||||
|
else
|
||||||
|
b
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
|
||||||
@ -29,6 +51,7 @@ type alias Context =
|
|||||||
rules =
|
rules =
|
||||||
[ NoConstantCondition.rule
|
[ NoConstantCondition.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -40,7 +63,7 @@ implementation =
|
|||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +97,7 @@ isStatic expr =
|
|||||||
Variable value ->
|
Variable value ->
|
||||||
if isStaticVariable value then
|
if isStaticVariable value then
|
||||||
True
|
True
|
||||||
|
|
||||||
else
|
else
|
||||||
False
|
False
|
||||||
|
|
||||||
@ -87,7 +111,7 @@ isStatic expr =
|
|||||||
True
|
True
|
||||||
|
|
||||||
BinOp (Variable op) left right ->
|
BinOp (Variable op) left right ->
|
||||||
(Set.member op comparisonOperators)
|
Set.member op comparisonOperators
|
||||||
&& (left == right || (isStatic left && isStatic right))
|
&& (left == right || (isStatic left && isStatic right))
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
@ -100,6 +124,7 @@ expressionFn ctx node =
|
|||||||
Enter (If cond _ _) ->
|
Enter (If cond _ _) ->
|
||||||
if isStatic cond then
|
if isStatic cond then
|
||||||
( [ error ], ctx )
|
( [ error ], ctx )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
|
@ -1,27 +1,38 @@
|
|||||||
module Lint.Rules.NoDebug exposing (rule)
|
module Lint.Rules.NoDebug exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
if Debug.log "condition" condition then a else b
|
if Debug.log "condition" condition then
|
||||||
|
a
|
||||||
|
|
||||||
|
else
|
||||||
|
b
|
||||||
|
|
||||||
if condition then
|
if condition then
|
||||||
Debug.crash "Nooo!"
|
Debug.crash "Nooo!"
|
||||||
|
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
if condition then
|
if condition then
|
||||||
a
|
a
|
||||||
|
|
||||||
else
|
else
|
||||||
b
|
b
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
|
|
||||||
|
|
||||||
type alias Context =
|
type alias Context =
|
||||||
@ -33,6 +44,7 @@ type alias Context =
|
|||||||
rules =
|
rules =
|
||||||
[ NoDebug.rule
|
[ NoDebug.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -44,7 +56,7 @@ implementation =
|
|||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +72,7 @@ expressionFn ctx node =
|
|||||||
Enter (Variable vars) ->
|
Enter (Variable vars) ->
|
||||||
if List.member "Debug" vars then
|
if List.member "Debug" vars then
|
||||||
( [ error ], ctx )
|
( [ error ], ctx )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
|
@ -1,21 +1,25 @@
|
|||||||
module Lint.Rules.NoDuplicateImports exposing (rule)
|
module Lint.Rules.NoDuplicateImports exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
import Set
|
import Set
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Statement exposing (..)
|
import Ast.Statement exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +34,7 @@ type alias Context =
|
|||||||
rules =
|
rules =
|
||||||
[ NoDuplicateImports.rule
|
[ NoDuplicateImports.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -59,10 +64,11 @@ statementFn ctx node =
|
|||||||
name =
|
name =
|
||||||
String.join "." names
|
String.join "." names
|
||||||
in
|
in
|
||||||
if Set.member name ctx.imports then
|
if Set.member name ctx.imports then
|
||||||
( [], { ctx | duplicates = Set.insert name ctx.duplicates } )
|
( [], { ctx | duplicates = Set.insert name ctx.duplicates } )
|
||||||
else
|
|
||||||
( [], { ctx | imports = Set.insert name ctx.imports } )
|
else
|
||||||
|
( [], { ctx | imports = Set.insert name ctx.imports } )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
@ -75,4 +81,4 @@ moduleEndFn ctx =
|
|||||||
Set.toList ctx.duplicates
|
Set.toList ctx.duplicates
|
||||||
|> List.map error
|
|> List.map error
|
||||||
in
|
in
|
||||||
( errors, ctx )
|
( errors, ctx )
|
||||||
|
@ -1,21 +1,25 @@
|
|||||||
module Lint.Rules.NoImportingEverything exposing (rule, Configuration)
|
module Lint.Rules.NoImportingEverything exposing (rule, Configuration)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule, Configuration
|
@docs rule, Configuration
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
import Html exposing (div, p, textarea)
|
import Html exposing (div, p, textarea)
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Set exposing (Set)
|
|
||||||
import Ast.Statement exposing (..)
|
import Ast.Statement exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
|
||||||
type alias Context =
|
type alias Context =
|
||||||
@ -32,8 +36,9 @@ type alias Configuration =
|
|||||||
functions and types are unknown to them.
|
functions and types are unknown to them.
|
||||||
|
|
||||||
rules =
|
rules =
|
||||||
[ NoImportingEverything.rule { exceptions = ["Html"]}
|
[ NoImportingEverything.rule { exceptions = [ "Html" ] }
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : Configuration -> LintRule
|
rule : Configuration -> LintRule
|
||||||
rule exceptions input =
|
rule exceptions input =
|
||||||
@ -45,7 +50,7 @@ implementation config =
|
|||||||
{ statementFn = statementFn
|
{ statementFn = statementFn
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = doNothing
|
, expressionFn = doNothing
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context (Set.fromList config.exceptions)
|
, initialContext = Context (Set.fromList config.exceptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,10 +68,11 @@ statementFn ctx node =
|
|||||||
name =
|
name =
|
||||||
String.join "." names
|
String.join "." names
|
||||||
in
|
in
|
||||||
if Set.member name ctx.exceptions then
|
if Set.member name ctx.exceptions then
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
else
|
|
||||||
( [ error name ], ctx )
|
else
|
||||||
|
( [ error name ], ctx )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
@ -1,23 +1,27 @@
|
|||||||
module Lint.Rules.NoUnannotatedFunction exposing (rule)
|
module Lint.Rules.NoUnannotatedFunction exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
a n =
|
a n =
|
||||||
n + 1
|
n + 1
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
a : Int -> Int
|
a : Int -> Int
|
||||||
a n =
|
a n =
|
||||||
n + 1
|
n + 1
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Statement exposing (..)
|
import Ast.Statement exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
|
||||||
@ -31,6 +35,7 @@ type alias Context =
|
|||||||
rules =
|
rules =
|
||||||
[ NoUnannotatedFunction.rule
|
[ NoUnannotatedFunction.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -42,7 +47,7 @@ implementation =
|
|||||||
{ statementFn = statementFn
|
{ statementFn = statementFn
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = doNothing
|
, expressionFn = doNothing
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context Set.empty
|
, initialContext = Context Set.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +66,7 @@ statementFn ctx node =
|
|||||||
Enter (FunctionDeclaration name params body) ->
|
Enter (FunctionDeclaration name params body) ->
|
||||||
if Set.member name ctx.annotatedFunctions then
|
if Set.member name ctx.annotatedFunctions then
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [ createError name ], ctx )
|
( [ createError name ], ctx )
|
||||||
|
|
||||||
|
@ -1,26 +1,32 @@
|
|||||||
module Lint.Rules.NoUnusedVariables exposing (rule)
|
module Lint.Rules.NoUnusedVariables exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
module Main exposing (a)
|
|
||||||
a n =
|
a n =
|
||||||
n + 1
|
n + 1
|
||||||
b = a 2
|
|
||||||
|
b =
|
||||||
|
a 2
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
module Main exposing (a)
|
|
||||||
a n =
|
a n =
|
||||||
n + 1
|
n + 1
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Ast.Statement exposing (..)
|
import Ast.Statement exposing (..)
|
||||||
import Lint exposing (doNothing, lint)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, Direction(..), LintError, LintRuleImplementation)
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
|
||||||
@ -46,6 +52,7 @@ emptyScope =
|
|||||||
rules =
|
rules =
|
||||||
[ NoUnusedVariables.rule
|
[ NoUnusedVariables.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -78,7 +85,7 @@ addUsedToStack scopes variables =
|
|||||||
Just scope ->
|
Just scope ->
|
||||||
{ scope | used = Set.union scope.used (Set.fromList variables) }
|
{ scope | used = Set.union scope.used (Set.fromList variables) }
|
||||||
in
|
in
|
||||||
lastScope :: (List.drop 1 scopes)
|
lastScope :: List.drop 1 scopes
|
||||||
|
|
||||||
|
|
||||||
addFoundToStack : List Scope -> List String -> List Scope
|
addFoundToStack : List Scope -> List String -> List Scope
|
||||||
@ -92,7 +99,7 @@ addFoundToStack scopes variables =
|
|||||||
Just scope ->
|
Just scope ->
|
||||||
{ scope | declared = Set.union scope.declared (Set.fromList variables) }
|
{ scope | declared = Set.union scope.declared (Set.fromList variables) }
|
||||||
in
|
in
|
||||||
lastScope :: (List.drop 1 scopes)
|
lastScope :: List.drop 1 scopes
|
||||||
|
|
||||||
|
|
||||||
makeReport : Maybe Scope -> ( List LintError, Set String )
|
makeReport : Maybe Scope -> ( List LintError, Set String )
|
||||||
@ -115,7 +122,7 @@ makeReport scope =
|
|||||||
|> List.sort
|
|> List.sort
|
||||||
|> List.map createError
|
|> List.map createError
|
||||||
in
|
in
|
||||||
( errors, variablesUsedButNotFromThisScope )
|
( errors, variablesUsedButNotFromThisScope )
|
||||||
|
|
||||||
|
|
||||||
variableName : Expression -> Maybe (List String)
|
variableName : Expression -> Maybe (List String)
|
||||||
@ -153,7 +160,7 @@ expressionFn ctx node =
|
|||||||
newScope =
|
newScope =
|
||||||
Scope variables Set.empty
|
Scope variables Set.empty
|
||||||
in
|
in
|
||||||
( [], { ctx | scopes = newScope :: ctx.scopes } )
|
( [], { ctx | scopes = newScope :: ctx.scopes } )
|
||||||
|
|
||||||
Exit (Let _ _) ->
|
Exit (Let _ _) ->
|
||||||
let
|
let
|
||||||
@ -165,7 +172,7 @@ expressionFn ctx node =
|
|||||||
newScopes =
|
newScopes =
|
||||||
List.drop 1 ctx.scopes
|
List.drop 1 ctx.scopes
|
||||||
in
|
in
|
||||||
( errors, { ctx | scopes = addUsedToStack newScopes (Set.toList variablesUsedButNotFromThisScope) } )
|
( errors, { ctx | scopes = addUsedToStack newScopes (Set.toList variablesUsedButNotFromThisScope) } )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
@ -226,7 +233,7 @@ statementFn ctx node =
|
|||||||
[]
|
[]
|
||||||
imported
|
imported
|
||||||
in
|
in
|
||||||
( [], { ctx | scopes = addFoundToStack ctx.scopes variables } )
|
( [], { ctx | scopes = addFoundToStack ctx.scopes variables } )
|
||||||
|
|
||||||
Enter (ModuleDeclaration names exportType) ->
|
Enter (ModuleDeclaration names exportType) ->
|
||||||
( [], addExposedVariables ctx exportType )
|
( [], addExposedVariables ctx exportType )
|
||||||
@ -244,9 +251,10 @@ moduleEndFn ctx =
|
|||||||
( errors, _ ) =
|
( errors, _ ) =
|
||||||
if ctx.exportsEverything then
|
if ctx.exportsEverything then
|
||||||
( [], Set.empty )
|
( [], Set.empty )
|
||||||
|
|
||||||
else
|
else
|
||||||
ctx.scopes
|
ctx.scopes
|
||||||
|> List.head
|
|> List.head
|
||||||
|> makeReport
|
|> makeReport
|
||||||
in
|
in
|
||||||
( errors, ctx )
|
( errors, ctx )
|
||||||
|
@ -1,26 +1,32 @@
|
|||||||
module Lint.Rules.NoUselessIf exposing (rule)
|
module Lint.Rules.NoUselessIf exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
if condition then
|
if condition then
|
||||||
value
|
value
|
||||||
|
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
if condition then
|
if condition then
|
||||||
value1
|
value1
|
||||||
|
|
||||||
else
|
else
|
||||||
value2
|
value2
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
|
|
||||||
|
|
||||||
type alias Context =
|
type alias Context =
|
||||||
@ -32,6 +38,7 @@ type alias Context =
|
|||||||
rules =
|
rules =
|
||||||
[ NoUselessIf.rule
|
[ NoUselessIf.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -43,7 +50,7 @@ implementation =
|
|||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +66,7 @@ expressionFn ctx node =
|
|||||||
Enter (If cond then_ else_) ->
|
Enter (If cond then_ else_) ->
|
||||||
if then_ == else_ then
|
if then_ == else_ then
|
||||||
( [ error ], ctx )
|
( [ error ], ctx )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
|
@ -1,37 +1,59 @@
|
|||||||
module Lint.Rules.NoUselessPatternMatching exposing (rule)
|
module Lint.Rules.NoUselessPatternMatching exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
-- Useless pattern matching
|
-- Useless pattern matching
|
||||||
case value of
|
case value of
|
||||||
Foo -> 1
|
Foo ->
|
||||||
Bar -> 1
|
1
|
||||||
_ -> 1
|
|
||||||
|
Bar ->
|
||||||
|
1
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
1
|
||||||
|
|
||||||
-- Useless pattern `Bar`, it's the same as the default pattern
|
-- Useless pattern `Bar`, it's the same as the default pattern
|
||||||
case value of
|
case value of
|
||||||
Foo -> 2
|
Foo ->
|
||||||
Bar -> 1
|
2
|
||||||
_ -> 1
|
|
||||||
|
Bar ->
|
||||||
|
1
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
1
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
case value of
|
case value of
|
||||||
Foo -> 1
|
Foo ->
|
||||||
Bar -> 2
|
1
|
||||||
_ -> 3
|
|
||||||
|
Bar ->
|
||||||
|
2
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
3
|
||||||
|
|
||||||
case value of
|
case value of
|
||||||
Foo n -> n
|
Foo n ->
|
||||||
Bar n -> n
|
n
|
||||||
|
|
||||||
|
Bar n ->
|
||||||
|
n
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Lint exposing (lint, visitExpression, doNothing)
|
import Lint exposing (doNothing, lint, visitExpression)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
import Regex
|
import Regex
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
@ -46,6 +68,7 @@ pattern will lead to the same value as the default pattern.
|
|||||||
rules =
|
rules =
|
||||||
[ NoUselessPatternMatching.rule
|
[ NoUselessPatternMatching.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -57,7 +80,7 @@ implementation =
|
|||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +90,7 @@ variableFinder =
|
|||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = findVariable
|
, expressionFn = findVariable
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Set.empty
|
, initialContext = Set.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +127,7 @@ subPatternMatchingVariables pattern =
|
|||||||
[ String.join "." a ]
|
[ String.join "." a ]
|
||||||
|
|
||||||
Application object variable ->
|
Application object variable ->
|
||||||
(subPatternMatchingVariables object) ++ (subPatternMatchingVariables variable)
|
subPatternMatchingVariables object ++ subPatternMatchingVariables variable
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
@ -145,7 +168,7 @@ patternsAreAllTheSame patterns =
|
|||||||
|> Set.fromList
|
|> Set.fromList
|
||||||
|> (\set -> Set.size set == 1)
|
|> (\set -> Set.size set == 1)
|
||||||
in
|
in
|
||||||
(not anyUseVariables) && bodiesAreIdentical
|
not anyUseVariables && bodiesAreIdentical
|
||||||
|
|
||||||
|
|
||||||
defaultPattern : List ( Expression, Expression, Set String, Set String ) -> Maybe ( Expression, Expression, Set String, Set String )
|
defaultPattern : List ( Expression, Expression, Set String, Set String ) -> Maybe ( Expression, Expression, Set String, Set String )
|
||||||
@ -161,6 +184,7 @@ defaultPattern patterns =
|
|||||||
Variable names ->
|
Variable names ->
|
||||||
if isVariable (String.join "." names) then
|
if isVariable (String.join "." names) then
|
||||||
Just ( pattern, body, used, declared )
|
Just ( pattern, body, used, declared )
|
||||||
|
|
||||||
else
|
else
|
||||||
Nothing
|
Nothing
|
||||||
|
|
||||||
@ -193,18 +217,17 @@ thereAreUselessPatterns patterns =
|
|||||||
justDefault =
|
justDefault =
|
||||||
Maybe.withDefault ( Integer 1, Integer 1, Set.empty, Set.empty ) default
|
Maybe.withDefault ( Integer 1, Integer 1, Set.empty, Set.empty ) default
|
||||||
in
|
in
|
||||||
hasDefault
|
hasDefault
|
||||||
&& (List.foldl
|
&& List.foldl
|
||||||
(\pattern res ->
|
(\pattern res ->
|
||||||
res
|
res
|
||||||
|| ((pattern /= justDefault)
|
|| ((pattern /= justDefault)
|
||||||
&& (patternBody pattern == patternBody justDefault)
|
&& (patternBody pattern == patternBody justDefault)
|
||||||
&& not (usesIntroducedVariable pattern)
|
&& not (usesIntroducedVariable pattern)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
False
|
False
|
||||||
patterns
|
patterns
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
expressionFn : Context -> Direction Expression -> ( List LintError, Context )
|
expressionFn : Context -> Direction Expression -> ( List LintError, Context )
|
||||||
@ -219,12 +242,14 @@ expressionFn ctx node =
|
|||||||
( pattern, body, Tuple.second <| visitExpression variableFinder body, patternMatchingVariables pattern )
|
( pattern, body, Tuple.second <| visitExpression variableFinder body, patternMatchingVariables pattern )
|
||||||
)
|
)
|
||||||
in
|
in
|
||||||
if patternsAreAllTheSame analyzedPatterns then
|
if patternsAreAllTheSame analyzedPatterns then
|
||||||
( [ uselessPatternMatchingError ], ctx )
|
( [ uselessPatternMatchingError ], ctx )
|
||||||
else if thereAreUselessPatterns analyzedPatterns then
|
|
||||||
( [ uselessPatternError ], ctx )
|
else if thereAreUselessPatterns analyzedPatterns then
|
||||||
else
|
( [ uselessPatternError ], ctx )
|
||||||
( [], ctx )
|
|
||||||
|
else
|
||||||
|
( [], ctx )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
@ -1,22 +1,30 @@
|
|||||||
module Lint.Rules.NoWarningComments exposing (rule)
|
module Lint.Rules.NoWarningComments exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
-- TODO Refactor this part of the code
|
-- TODO Refactor this part of the code
|
||||||
-- FIXME Broken because of...
|
-- FIXME Broken because of...
|
||||||
-- XXX This should not be done like this
|
-- XXX This should not be done like this
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
-- Regular comment
|
-- Regular comment
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Statement exposing (..)
|
import Ast.Statement exposing (..)
|
||||||
import Lint exposing (doNothing, lint)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, Direction(..), LintError, LintRuleImplementation)
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
|
|
||||||
|
|
||||||
type alias Context =
|
type alias Context =
|
||||||
@ -28,6 +36,7 @@ type alias Context =
|
|||||||
rules =
|
rules =
|
||||||
[ NoWarningComments.rule
|
[ NoWarningComments.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -39,7 +48,7 @@ implementation =
|
|||||||
{ statementFn = statementFn
|
{ statementFn = statementFn
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = doNothing
|
, expressionFn = doNothing
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,16 +62,22 @@ findWarning : String -> Maybe LintError
|
|||||||
findWarning text =
|
findWarning text =
|
||||||
if String.contains "TODO" text then
|
if String.contains "TODO" text then
|
||||||
Just <| error "TODO"
|
Just <| error "TODO"
|
||||||
|
|
||||||
else if String.contains "todo" text then
|
else if String.contains "todo" text then
|
||||||
Just <| error "todo"
|
Just <| error "todo"
|
||||||
|
|
||||||
else if String.contains "FIXME" text then
|
else if String.contains "FIXME" text then
|
||||||
Just <| error "FIXME"
|
Just <| error "FIXME"
|
||||||
|
|
||||||
else if String.contains "fixme" text then
|
else if String.contains "fixme" text then
|
||||||
Just <| error "fixme"
|
Just <| error "fixme"
|
||||||
|
|
||||||
else if String.contains "XXX" text then
|
else if String.contains "XXX" text then
|
||||||
Just <| error "XXX"
|
Just <| error "XXX"
|
||||||
|
|
||||||
else if String.contains "xxx" text then
|
else if String.contains "xxx" text then
|
||||||
Just <| error "xxx"
|
Just <| error "xxx"
|
||||||
|
|
||||||
else
|
else
|
||||||
Nothing
|
Nothing
|
||||||
|
|
||||||
@ -75,12 +90,12 @@ statementFn ctx node =
|
|||||||
warning =
|
warning =
|
||||||
findWarning text
|
findWarning text
|
||||||
in
|
in
|
||||||
case warning of
|
case warning of
|
||||||
Just err ->
|
Just err ->
|
||||||
( [ err ], ctx )
|
( [ err ], ctx )
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
module Lint.Rules.SimplifyPiping exposing (rule)
|
module Lint.Rules.SimplifyPiping exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
a = values
|
a =
|
||||||
|> List.map foo
|
values
|
||||||
|> List.map bar
|
|> List.map foo
|
||||||
|
|> List.map bar
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
a = values
|
a =
|
||||||
|> List.map (foo >> bar)
|
values
|
||||||
|
|> List.map (foo >> bar)
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
import Lint exposing (doNothing, lint)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +36,7 @@ type alias Context =
|
|||||||
rules =
|
rules =
|
||||||
[ SimplifyPiping.rule
|
[ SimplifyPiping.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -41,7 +48,7 @@ implementation =
|
|||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +83,7 @@ reportIfSimplifiableMethod op left right =
|
|||||||
[ Application (Access (Variable names1) fns1) _, Application (Access (Variable names2) fns2) _ ] ->
|
[ Application (Access (Variable names1) fns1) _, Application (Access (Variable names2) fns2) _ ] ->
|
||||||
if [ names1, fns1 ] == [ names2, fns2 ] && Set.member (nameOfMethod [ names1, fns1 ]) simplifiableFns then
|
if [ names1, fns1 ] == [ names2, fns2 ] && Set.member (nameOfMethod [ names1, fns1 ]) simplifiableFns then
|
||||||
[ error op <| nameOfMethod [ names1, fns1 ] ]
|
[ error op <| nameOfMethod [ names1, fns1 ] ]
|
||||||
|
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
@ -1,21 +1,27 @@
|
|||||||
module Lint.Rules.SimplifyPropertyAccess exposing (rule)
|
module Lint.Rules.SimplifyPropertyAccess exposing (rule)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs rule
|
@docs rule
|
||||||
|
|
||||||
|
|
||||||
# Fail
|
# Fail
|
||||||
|
|
||||||
a = List.map (\x -> x.foo) values
|
a =
|
||||||
|
List.map (\x -> x.foo) values
|
||||||
|
|
||||||
|
|
||||||
# Success
|
# Success
|
||||||
|
|
||||||
a = List.map .foo values
|
a =
|
||||||
|
List.map .foo values
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Statement exposing (..)
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Lint exposing (lint, doNothing)
|
import Ast.Statement exposing (..)
|
||||||
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
|
import Lint exposing (doNothing, lint)
|
||||||
|
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
|
||||||
|
|
||||||
|
|
||||||
type alias Context =
|
type alias Context =
|
||||||
@ -27,6 +33,7 @@ type alias Context =
|
|||||||
rules =
|
rules =
|
||||||
[ SimplifyPropertyAccess.rule
|
[ SimplifyPropertyAccess.rule
|
||||||
]
|
]
|
||||||
|
|
||||||
-}
|
-}
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
@ -38,7 +45,7 @@ implementation =
|
|||||||
{ statementFn = statementFn
|
{ statementFn = statementFn
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +61,7 @@ expressionFn ctx node =
|
|||||||
Enter (Lambda [ Variable paramNames ] (Access (Variable varName) properties)) ->
|
Enter (Lambda [ Variable paramNames ] (Access (Variable varName) properties)) ->
|
||||||
if List.length properties == 1 && varName == paramNames then
|
if List.length properties == 1 && varName == paramNames then
|
||||||
( [ String.join "" properties |> error ], ctx )
|
( [ String.join "" properties |> error ], ctx )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
@ -67,6 +75,7 @@ statementFn ctx node =
|
|||||||
Enter (FunctionDeclaration _ [ Variable paramNames ] (Access (Variable varName) properties)) ->
|
Enter (FunctionDeclaration _ [ Variable paramNames ] (Access (Variable varName) properties)) ->
|
||||||
if List.length properties == 1 && varName == paramNames then
|
if List.length properties == 1 && varName == paramNames then
|
||||||
( [ String.join "" properties |> error ], ctx )
|
( [ String.join "" properties |> error ], ctx )
|
||||||
|
|
||||||
else
|
else
|
||||||
( [], ctx )
|
( [], ctx )
|
||||||
|
|
||||||
|
@ -1,31 +1,32 @@
|
|||||||
module Lint.Types
|
module Lint.Types exposing
|
||||||
exposing
|
( LintError, Direction(..)
|
||||||
( Direction(..)
|
, LintRule, Severity(..), Reporter
|
||||||
, File
|
, LintRuleImplementation, LintImplementation
|
||||||
, LintError
|
, Visitor, LintResult, File
|
||||||
, LintImplementation
|
)
|
||||||
, LintResult
|
|
||||||
, LintRule
|
|
||||||
, LintRuleImplementation
|
|
||||||
, Reporter
|
|
||||||
, Severity
|
|
||||||
, Severity(..)
|
|
||||||
, Visitor
|
|
||||||
)
|
|
||||||
|
|
||||||
{-| This module contains types that are used for writing rules.
|
{-| This module contains types that are used for writing rules.
|
||||||
|
|
||||||
|
|
||||||
# Elementary types
|
# Elementary types
|
||||||
|
|
||||||
@docs LintError, Direction
|
@docs LintError, Direction
|
||||||
|
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
@docs LintRule, Severity, Reporter
|
@docs LintRule, Severity, Reporter
|
||||||
|
|
||||||
|
|
||||||
# Writing rules
|
# Writing rules
|
||||||
|
|
||||||
@docs LintRuleImplementation, LintImplementation
|
@docs LintRuleImplementation, LintImplementation
|
||||||
|
|
||||||
|
|
||||||
# Internal types
|
# Internal types
|
||||||
|
|
||||||
@docs Visitor, LintResult, File
|
@docs Visitor, LintResult, File
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
@ -38,6 +39,7 @@ a description of the error.
|
|||||||
error : LintError
|
error : LintError
|
||||||
error =
|
error =
|
||||||
LintError "NoDebug" "Forbidden use of Debug"
|
LintError "NoDebug" "Forbidden use of Debug"
|
||||||
|
|
||||||
-}
|
-}
|
||||||
type alias LintError =
|
type alias LintError =
|
||||||
{ rule : String
|
{ rule : String
|
||||||
@ -63,31 +65,35 @@ enforce.
|
|||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = \ctx -> ( [], ctx )
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
-}
|
-}
|
||||||
type alias LintImplementation nodeType context =
|
type alias LintImplementation nodeType context =
|
||||||
context -> Direction nodeType -> ( List LintError, context )
|
context -> Direction nodeType -> ( List LintError, context )
|
||||||
|
|
||||||
|
|
||||||
{-| When visiting the AST, nodes are visited twice:
|
{-| When visiting the AST, nodes are visited twice:
|
||||||
- on Enter, before the children of the node will be visited
|
|
||||||
- on Exit, after the children of the node have been visited
|
- on Enter, before the children of the node will be visited
|
||||||
|
|
||||||
|
- on Exit, after the children of the node have been visited
|
||||||
|
|
||||||
expressionFn : Context -> Direction Expression -> ( List LintError, Context )
|
expressionFn : Context -> Direction Expression -> ( List LintError, Context )
|
||||||
expressionFn ctx node =
|
expressionFn ctx node =
|
||||||
case node of
|
case node of
|
||||||
Enter (Variable names) ->
|
Enter (Variable names) ->
|
||||||
( [], markVariableAsUsed ctx names )
|
( [], markVariableAsUsed ctx names )
|
||||||
|
|
||||||
-- Find variables declared in `let .. in ..` expression
|
-- Find variables declared in `let .. in ..` expression
|
||||||
Enter (Let declarations body) ->
|
Enter (Let declarations body) ->
|
||||||
( [], registerVariables ctx declarations )
|
( [], registerVariables ctx declarations )
|
||||||
|
|
||||||
|
-- When exiting the `let .. in ..` expression, report the variables that were not used.
|
||||||
|
Exit (Let _ _) ->
|
||||||
|
( unusedVariables ctx |> List.map createError, ctx )
|
||||||
|
|
||||||
-- When exiting the `let .. in ..` expression, report the variables that were not used.
|
|
||||||
Exit (Let _ _) ->
|
|
||||||
( unusedVariables ctx |> List.map createError, ctx )
|
|
||||||
-}
|
-}
|
||||||
type Direction node
|
type Direction node
|
||||||
= Enter node
|
= Enter node
|
||||||
@ -95,25 +101,31 @@ type Direction node
|
|||||||
|
|
||||||
|
|
||||||
{-| A LintRuleImplementation is the implementation of a rule. It is a record that contains:
|
{-| A LintRuleImplementation is the implementation of a rule. It is a record that contains:
|
||||||
- initialContext: An initial context
|
|
||||||
- statementFn: A LintImplementation for Statement nodes
|
- initialContext: An initial context
|
||||||
- typeFn: A LintImplementation for Type nodes
|
|
||||||
- expressionFn: A LintImplementation for Expression nodes
|
- statementFn: A LintImplementation for Statement nodes
|
||||||
- moduleEndFn: A function that takes a context and returns a list of error. Similar to a LintImplementation, but will
|
|
||||||
be called after visiting the whole AST.
|
- typeFn: A LintImplementation for Type nodes
|
||||||
|
|
||||||
|
- expressionFn: A LintImplementation for Expression nodes
|
||||||
|
|
||||||
|
- moduleEndFn: A function that takes a context and returns a list of error. Similar to a LintImplementation, but will
|
||||||
|
be called after visiting the whole AST.
|
||||||
|
|
||||||
rule : LintRule
|
rule : LintRule
|
||||||
rule input =
|
rule input =
|
||||||
lint input implementation
|
lint input implementation
|
||||||
|
|
||||||
implementation : LintRuleImplementation Context
|
implementation : LintRuleImplementation Context
|
||||||
implementation =
|
implementation =
|
||||||
{ statementFn = doNothing
|
{ statementFn = doNothing
|
||||||
, typeFn = doNothing
|
, typeFn = doNothing
|
||||||
, expressionFn = expressionFn
|
, expressionFn = expressionFn
|
||||||
, moduleEndFn = (\ctx -> ( [], ctx ))
|
, moduleEndFn = (\\ctx -> ( [], ctx ))
|
||||||
, initialContext = Context
|
, initialContext = Context
|
||||||
}
|
}
|
||||||
|
|
||||||
-}
|
-}
|
||||||
type alias LintRuleImplementation context =
|
type alias LintRuleImplementation context =
|
||||||
{ statementFn : LintImplementation Statement context
|
{ statementFn : LintImplementation Statement context
|
||||||
@ -140,6 +152,7 @@ type alias LintRule =
|
|||||||
A Visitor represents a node and calls the appropriate function for the given node type.
|
A Visitor represents a node and calls the appropriate function for the given node type.
|
||||||
|
|
||||||
Note: this is internal API, and will be removed in a future version.
|
Note: this is internal API, and will be removed in a future version.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
type alias Visitor context =
|
type alias Visitor context =
|
||||||
LintRuleImplementation context -> context -> ( List LintError, context )
|
LintRuleImplementation context -> context -> ( List LintError, context )
|
||||||
@ -147,9 +160,10 @@ type alias Visitor context =
|
|||||||
|
|
||||||
{-| Severity associated to a rule.
|
{-| Severity associated to a rule.
|
||||||
|
|
||||||
- Critical: Transgressions reported by the rule will make the linting process fail.
|
- Critical: Transgressions reported by the rule will make the linting process fail.
|
||||||
- Warning: Transgressions reported by the rule will not make the linting process fail.
|
- Warning: Transgressions reported by the rule will not make the linting process fail.
|
||||||
- Disabled: Rule will not be enforced.
|
- Disabled: Rule will not be enforced.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
type Severity
|
type Severity
|
||||||
= Disabled
|
= Disabled
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
module Lint.Visitor exposing (transformStatementsIntoVisitors, expressionToVisitors)
|
module Lint.Visitor exposing (expressionToVisitors, transformStatementsIntoVisitors)
|
||||||
|
|
||||||
import Ast.Expression exposing (..)
|
import Ast.Expression exposing (..)
|
||||||
import Ast.Statement exposing (..)
|
import Ast.Statement exposing (..)
|
||||||
import Lint.Types exposing (LintRule, Direction(..), Visitor)
|
import Lint.Types exposing (Direction(..), LintRule, Visitor)
|
||||||
|
|
||||||
|
|
||||||
createExitAndEnterWithChildren : (Direction nodeType -> Visitor context) -> nodeType -> List (Visitor context) -> List (Visitor context)
|
createExitAndEnterWithChildren : (Direction nodeType -> Visitor context) -> nodeType -> List (Visitor context) -> List (Visitor context)
|
||||||
@ -92,7 +92,7 @@ expressionToVisitors node =
|
|||||||
childrenVisitors =
|
childrenVisitors =
|
||||||
List.concatMap expressionToVisitors children
|
List.concatMap expressionToVisitors children
|
||||||
in
|
in
|
||||||
createExitAndEnterWithChildren expressionVisitor node childrenVisitors
|
createExitAndEnterWithChildren expressionVisitor node childrenVisitors
|
||||||
|
|
||||||
|
|
||||||
typeToVisitors : Type -> List (Visitor context)
|
typeToVisitors : Type -> List (Visitor context)
|
||||||
@ -114,7 +114,7 @@ statementToVisitors node =
|
|||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
in
|
in
|
||||||
createExitAndEnterWithChildren statementVisitor node childrenVisitors
|
createExitAndEnterWithChildren statementVisitor node childrenVisitors
|
||||||
|
|
||||||
|
|
||||||
transformStatementsIntoVisitors : List Statement -> List (Visitor context)
|
transformStatementsIntoVisitors : List Statement -> List (Visitor context)
|
||||||
|
Loading…
Reference in New Issue
Block a user