Apply elm-upgrade

This commit is contained in:
Jeroen Engels 2018-11-05 14:44:22 +01:00
parent 5c56965101
commit 48e3296fc3
16 changed files with 347 additions and 188 deletions

View File

@ -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.",
"repository": "https://github.com/jfmengels/elm-lint.git",
"license": "BSD3",
"source-directories": [
"src"
],
"license": "BSD-3-Clause",
"version": "2.0.1",
"exposed-modules": [
"Lint",
"Lint.Types",
@ -25,12 +23,12 @@
"Lint.Rules.SimplifyPropertyAccess",
"Lint.Rules.ElmTest.NoDuplicateTestBodies"
],
"elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": {
"Bogdanp/elm-ast": "8.0.3 <= v < 9.0.0",
"elm-community/list-extra": "5.0.1 <= v < 6.0.0",
"elm-community/parser-combinators": "1.1.0 <= v < 2.0.0",
"elm-lang/core": "5.0.0 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0"
"elm/core": "1.0.0 <= v < 2.0.0",
"elm/html": "1.0.0 <= v < 2.0.0",
"elm/regex": "1.0.0 <= v < 2.0.0",
"elm-community/list-extra": "8.1.0 <= v < 9.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
"test-dependencies": {}
}

View File

@ -1,8 +1,10 @@
module Lint.Rules.DefaultPatternPosition exposing (rule, Configuration, PatternPosition(..))
{-|
@docs rule, Configuration, PatternPosition
# Fail
rules =
@ -25,6 +27,7 @@ module Lint.Rules.DefaultPatternPosition exposing (rule, Configuration, PatternP
-- LintError, this pattern should appear first
_ -> result
# Success
rules =
@ -49,11 +52,12 @@ module Lint.Rules.DefaultPatternPosition exposing (rule, Configuration, PatternP
case value of
_ -> result
Foo -> bar
-}
import Ast.Expression exposing (..)
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 Regex
@ -88,7 +92,7 @@ implementation configuration =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn configuration
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
@ -113,6 +117,7 @@ isDefaultPattern pattern =
Variable names ->
if isVariable (String.join "." names) then
True
else
False
@ -138,12 +143,14 @@ expressionFn config ctx node =
First ->
if index /= 0 then
( [ error "Expected default pattern to appear first in the list of patterns" ], ctx )
else
( [], ctx )
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 )
else
( [], ctx )

View File

@ -1,44 +1,52 @@
module Lint.Rules.ElmTest.NoDuplicateTestBodies exposing (rule)
{-|
@docs rule
# Fail
module Addition exposing (..)
import Test exposing (test)
tests =
[ test "foo" <|
\() -> 1 + 1
|> Expect.equal 2
\() ->
1
+ 1
|> Expect.equal 2
, test "bar" <|
\() -> 1 + 1
|> Expect.equal 2
\() ->
1
+ 1
|> Expect.equal 2
]
# Success
module Addition exposing (..)
import Test exposing (test)
tests =
[ test "foo" <|
\() -> 1 + 1
|> Expect.equal 2
\() ->
1
+ 1
|> Expect.equal 2
, test "bar" <|
\() -> 1 + 2
|> Expect.equal 3
\() ->
1
+ 2
|> Expect.equal 3
]
-}
import Ast.Expression exposing (..)
import Ast.Statement exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
import Dict exposing (Dict)
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
type alias Context =
@ -53,6 +61,7 @@ This may result in specifications that are thought to be implemented but are not
rules =
[ ElmTest.NoDuplicateTestBodies.rule
]
-}
rule : LintRule
rule input =
@ -64,7 +73,7 @@ implementation =
{ statementFn = statementFn
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context []
}
@ -97,6 +106,7 @@ filterTests availableTestAliases listItems =
BinOp (Variable [ "<|" ]) (Application fn (String title)) testBody ->
if isTestFunctionCall availableTestAliases fn then
[ ( title, testBody ) ]
else
[]
@ -124,17 +134,17 @@ expressionFn ctx node =
existingTest =
Dict.get testBodyAsString dict
in
case existingTest of
Nothing ->
{ dict = Dict.insert testBodyAsString title dict, redundant = redundant }
case existingTest of
Nothing ->
{ dict = Dict.insert testBodyAsString title dict, redundant = redundant }
Just existingTestTitle ->
{ dict = dict, redundant = redundant ++ [ ( title, existingTestTitle ) ] }
Just existingTestTitle ->
{ dict = dict, redundant = redundant ++ [ ( title, existingTestTitle ) ] }
)
{ dict = Dict.empty, redundant = [] }
tests
in
( List.map error redundantTests.redundant, ctx )
( List.map error redundantTests.redundant, ctx )
_ ->
( [], ctx )
@ -152,6 +162,7 @@ extractImported exportSet =
FunctionExport name ->
if name == "test" then
[ name ]
else
[]
@ -172,12 +183,12 @@ statementFn ctx node =
moduleFnAccess =
computeAlias testAlias ++ ".test"
in
case exportSet of
Nothing ->
( [], { availableTestAliases = [ moduleFnAccess ] } )
case exportSet of
Nothing ->
( [], { availableTestAliases = [ moduleFnAccess ] } )
Just subExportSet ->
( [], { availableTestAliases = [ moduleFnAccess ] ++ extractImported subExportSet } )
Just subExportSet ->
( [], { availableTestAliases = [ moduleFnAccess ] ++ extractImported subExportSet } )
_ ->
( [], ctx )

View File

@ -1,22 +1,44 @@
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
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
if foo == bar then
a
else
b
-}
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
import Set exposing (Set)
@ -29,6 +51,7 @@ type alias Context =
rules =
[ NoConstantCondition.rule
]
-}
rule : LintRule
rule input =
@ -40,7 +63,7 @@ implementation =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
@ -74,6 +97,7 @@ isStatic expr =
Variable value ->
if isStaticVariable value then
True
else
False
@ -87,7 +111,7 @@ isStatic expr =
True
BinOp (Variable op) left right ->
(Set.member op comparisonOperators)
Set.member op comparisonOperators
&& (left == right || (isStatic left && isStatic right))
_ ->
@ -100,6 +124,7 @@ expressionFn ctx node =
Enter (If cond _ _) ->
if isStatic cond then
( [ error ], ctx )
else
( [], ctx )

View File

@ -1,27 +1,38 @@
module Lint.Rules.NoDebug exposing (rule)
{-|
@docs rule
# Fail
if Debug.log "condition" condition then a else b
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, LintRuleImplementation, LintError, Direction(..))
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
type alias Context =
@ -33,6 +44,7 @@ type alias Context =
rules =
[ NoDebug.rule
]
-}
rule : LintRule
rule input =
@ -44,7 +56,7 @@ implementation =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
@ -60,6 +72,7 @@ expressionFn ctx node =
Enter (Variable vars) ->
if List.member "Debug" vars then
( [ error ], ctx )
else
( [], ctx )

View File

@ -1,21 +1,25 @@
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, LintRuleImplementation, LintError, Direction(..))
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
import Set exposing (Set)
@ -30,6 +34,7 @@ type alias Context =
rules =
[ NoDuplicateImports.rule
]
-}
rule : LintRule
rule input =
@ -59,10 +64,11 @@ statementFn ctx node =
name =
String.join "." names
in
if Set.member name ctx.imports then
( [], { ctx | duplicates = Set.insert name ctx.duplicates } )
else
( [], { ctx | imports = Set.insert name ctx.imports } )
if Set.member name ctx.imports then
( [], { ctx | duplicates = Set.insert name ctx.duplicates } )
else
( [], { ctx | imports = Set.insert name ctx.imports } )
_ ->
( [], ctx )
@ -75,4 +81,4 @@ moduleEndFn ctx =
Set.toList ctx.duplicates
|> List.map error
in
( errors, ctx )
( errors, ctx )

View File

@ -1,21 +1,25 @@
module Lint.Rules.NoImportingEverything exposing (rule, Configuration)
{-|
@docs rule, Configuration
# Fail
import Html exposing (..)
# Success
import Html exposing (div, p, textarea)
-}
import Set exposing (Set)
import Ast.Statement exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
import Set exposing (Set)
type alias Context =
@ -32,8 +36,9 @@ type alias Configuration =
functions and types are unknown to them.
rules =
[ NoImportingEverything.rule { exceptions = ["Html"]}
[ NoImportingEverything.rule { exceptions = [ "Html" ] }
]
-}
rule : Configuration -> LintRule
rule exceptions input =
@ -45,7 +50,7 @@ implementation config =
{ statementFn = statementFn
, typeFn = doNothing
, expressionFn = doNothing
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context (Set.fromList config.exceptions)
}
@ -63,10 +68,11 @@ statementFn ctx node =
name =
String.join "." names
in
if Set.member name ctx.exceptions then
( [], ctx )
else
( [ error name ], ctx )
if Set.member name ctx.exceptions then
( [], ctx )
else
( [ error name ], ctx )
_ ->
( [], ctx )

View File

@ -1,23 +1,27 @@
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, LintRuleImplementation, LintError, Direction(..))
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
import Set exposing (Set)
@ -31,6 +35,7 @@ type alias Context =
rules =
[ NoUnannotatedFunction.rule
]
-}
rule : LintRule
rule input =
@ -42,7 +47,7 @@ implementation =
{ statementFn = statementFn
, typeFn = doNothing
, expressionFn = doNothing
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context Set.empty
}
@ -61,6 +66,7 @@ statementFn ctx node =
Enter (FunctionDeclaration name params body) ->
if Set.member name ctx.annotatedFunctions then
( [], ctx )
else
( [ createError name ], ctx )

View File

@ -1,26 +1,32 @@
module Lint.Rules.NoUnusedVariables exposing (rule)
{-|
@docs rule
# Fail
module Main exposing (a)
a n =
n + 1
b = a 2
b =
a 2
# Success
module Main exposing (a)
a n =
n + 1
-}
import Ast.Expression exposing (..)
import Ast.Statement exposing (..)
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)
@ -46,6 +52,7 @@ emptyScope =
rules =
[ NoUnusedVariables.rule
]
-}
rule : LintRule
rule input =
@ -78,7 +85,7 @@ addUsedToStack scopes variables =
Just scope ->
{ scope | used = Set.union scope.used (Set.fromList variables) }
in
lastScope :: (List.drop 1 scopes)
lastScope :: List.drop 1 scopes
addFoundToStack : List Scope -> List String -> List Scope
@ -92,7 +99,7 @@ addFoundToStack scopes variables =
Just scope ->
{ scope | declared = Set.union scope.declared (Set.fromList variables) }
in
lastScope :: (List.drop 1 scopes)
lastScope :: List.drop 1 scopes
makeReport : Maybe Scope -> ( List LintError, Set String )
@ -115,7 +122,7 @@ makeReport scope =
|> List.sort
|> List.map createError
in
( errors, variablesUsedButNotFromThisScope )
( errors, variablesUsedButNotFromThisScope )
variableName : Expression -> Maybe (List String)
@ -153,7 +160,7 @@ expressionFn ctx node =
newScope =
Scope variables Set.empty
in
( [], { ctx | scopes = newScope :: ctx.scopes } )
( [], { ctx | scopes = newScope :: ctx.scopes } )
Exit (Let _ _) ->
let
@ -165,7 +172,7 @@ expressionFn ctx node =
newScopes =
List.drop 1 ctx.scopes
in
( errors, { ctx | scopes = addUsedToStack newScopes (Set.toList variablesUsedButNotFromThisScope) } )
( errors, { ctx | scopes = addUsedToStack newScopes (Set.toList variablesUsedButNotFromThisScope) } )
_ ->
( [], ctx )
@ -226,7 +233,7 @@ statementFn ctx node =
[]
imported
in
( [], { ctx | scopes = addFoundToStack ctx.scopes variables } )
( [], { ctx | scopes = addFoundToStack ctx.scopes variables } )
Enter (ModuleDeclaration names exportType) ->
( [], addExposedVariables ctx exportType )
@ -244,9 +251,10 @@ moduleEndFn ctx =
( errors, _ ) =
if ctx.exportsEverything then
( [], Set.empty )
else
ctx.scopes
|> List.head
|> makeReport
in
( errors, ctx )
( errors, ctx )

View File

@ -1,26 +1,32 @@
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, LintRuleImplementation, LintError, Direction(..))
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
type alias Context =
@ -32,6 +38,7 @@ type alias Context =
rules =
[ NoUselessIf.rule
]
-}
rule : LintRule
rule input =
@ -43,7 +50,7 @@ implementation =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
@ -59,6 +66,7 @@ expressionFn ctx node =
Enter (If cond then_ else_) ->
if then_ == else_ then
( [ error ], ctx )
else
( [], ctx )

View File

@ -1,37 +1,59 @@
module Lint.Rules.NoUselessPatternMatching exposing (rule)
{-|
@docs rule
# Fail
-- Useless pattern matching
case value of
Foo -> 1
Bar -> 1
_ -> 1
Foo ->
1
Bar ->
1
_ ->
1
-- Useless pattern `Bar`, it's the same as the default pattern
case value of
Foo -> 2
Bar -> 1
_ -> 1
Foo ->
2
Bar ->
1
_ ->
1
# Success
case value of
Foo -> 1
Bar -> 2
_ -> 3
Foo ->
1
Bar ->
2
_ ->
3
case value of
Foo n -> n
Bar n -> n
Foo n ->
n
Bar n ->
n
-}
import Ast.Expression exposing (..)
import Lint exposing (lint, visitExpression, doNothing)
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
import Lint exposing (doNothing, lint, visitExpression)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
import Regex
import Set exposing (Set)
@ -46,6 +68,7 @@ pattern will lead to the same value as the default pattern.
rules =
[ NoUselessPatternMatching.rule
]
-}
rule : LintRule
rule input =
@ -57,7 +80,7 @@ implementation =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
@ -67,7 +90,7 @@ variableFinder =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = findVariable
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Set.empty
}
@ -104,7 +127,7 @@ subPatternMatchingVariables pattern =
[ String.join "." a ]
Application object variable ->
(subPatternMatchingVariables object) ++ (subPatternMatchingVariables variable)
subPatternMatchingVariables object ++ subPatternMatchingVariables variable
_ ->
[]
@ -145,7 +168,7 @@ patternsAreAllTheSame patterns =
|> Set.fromList
|> (\set -> Set.size set == 1)
in
(not anyUseVariables) && bodiesAreIdentical
not anyUseVariables && bodiesAreIdentical
defaultPattern : List ( Expression, Expression, Set String, Set String ) -> Maybe ( Expression, Expression, Set String, Set String )
@ -161,6 +184,7 @@ defaultPattern patterns =
Variable names ->
if isVariable (String.join "." names) then
Just ( pattern, body, used, declared )
else
Nothing
@ -193,18 +217,17 @@ thereAreUselessPatterns patterns =
justDefault =
Maybe.withDefault ( Integer 1, Integer 1, Set.empty, Set.empty ) default
in
hasDefault
&& (List.foldl
(\pattern res ->
res
|| ((pattern /= justDefault)
&& (patternBody pattern == patternBody justDefault)
&& not (usesIntroducedVariable pattern)
)
)
False
patterns
)
hasDefault
&& List.foldl
(\pattern res ->
res
|| ((pattern /= justDefault)
&& (patternBody pattern == patternBody justDefault)
&& not (usesIntroducedVariable pattern)
)
)
False
patterns
expressionFn : Context -> Direction Expression -> ( List LintError, Context )
@ -219,12 +242,14 @@ expressionFn ctx node =
( pattern, body, Tuple.second <| visitExpression variableFinder body, patternMatchingVariables pattern )
)
in
if patternsAreAllTheSame analyzedPatterns then
( [ uselessPatternMatchingError ], ctx )
else if thereAreUselessPatterns analyzedPatterns then
( [ uselessPatternError ], ctx )
else
( [], ctx )
if patternsAreAllTheSame analyzedPatterns then
( [ uselessPatternMatchingError ], ctx )
else if thereAreUselessPatterns analyzedPatterns then
( [ uselessPatternError ], ctx )
else
( [], ctx )
_ ->
( [], ctx )

View File

@ -1,22 +1,30 @@
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 (LintRule, Direction(..), LintError, LintRuleImplementation)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
type alias Context =
@ -28,6 +36,7 @@ type alias Context =
rules =
[ NoWarningComments.rule
]
-}
rule : LintRule
rule input =
@ -39,7 +48,7 @@ implementation =
{ statementFn = statementFn
, typeFn = doNothing
, expressionFn = doNothing
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
@ -53,16 +62,22 @@ findWarning : String -> Maybe LintError
findWarning text =
if String.contains "TODO" text then
Just <| error "TODO"
else if String.contains "todo" text then
Just <| error "todo"
else if String.contains "FIXME" text then
Just <| error "FIXME"
else if String.contains "fixme" text then
Just <| error "fixme"
else if String.contains "XXX" text then
Just <| error "XXX"
else if String.contains "xxx" text then
Just <| error "xxx"
else
Nothing
@ -75,12 +90,12 @@ statementFn ctx node =
warning =
findWarning text
in
case warning of
Just err ->
( [ err ], ctx )
case warning of
Just err ->
( [ err ], ctx )
Nothing ->
( [], ctx )
Nothing ->
( [], ctx )
_ ->
( [], ctx )

View File

@ -1,23 +1,29 @@
module Lint.Rules.SimplifyPiping exposing (rule)
{-|
@docs rule
# Fail
a = values
|> List.map foo
|> List.map bar
a =
values
|> List.map foo
|> List.map bar
# Success
a = values
|> List.map (foo >> bar)
a =
values
|> List.map (foo >> bar)
-}
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
import Set exposing (Set)
@ -30,6 +36,7 @@ type alias Context =
rules =
[ SimplifyPiping.rule
]
-}
rule : LintRule
rule input =
@ -41,7 +48,7 @@ implementation =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
@ -76,6 +83,7 @@ reportIfSimplifiableMethod op left right =
[ Application (Access (Variable names1) fns1) _, Application (Access (Variable names2) fns2) _ ] ->
if [ names1, fns1 ] == [ names2, fns2 ] && Set.member (nameOfMethod [ names1, fns1 ]) simplifiableFns then
[ error op <| nameOfMethod [ names1, fns1 ] ]
else
[]

View File

@ -1,21 +1,27 @@
module Lint.Rules.SimplifyPropertyAccess exposing (rule)
{-|
@docs rule
# Fail
a = List.map (\x -> x.foo) values
a =
List.map (\x -> x.foo) values
# Success
a = List.map .foo values
a =
List.map .foo values
-}
import Ast.Statement exposing (..)
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, LintRuleImplementation, LintError, Direction(..))
import Ast.Statement exposing (..)
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation)
type alias Context =
@ -27,6 +33,7 @@ type alias Context =
rules =
[ SimplifyPropertyAccess.rule
]
-}
rule : LintRule
rule input =
@ -38,7 +45,7 @@ implementation =
{ statementFn = statementFn
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
@ -54,6 +61,7 @@ expressionFn ctx node =
Enter (Lambda [ Variable paramNames ] (Access (Variable varName) properties)) ->
if List.length properties == 1 && varName == paramNames then
( [ String.join "" properties |> error ], ctx )
else
( [], ctx )
@ -67,6 +75,7 @@ statementFn ctx node =
Enter (FunctionDeclaration _ [ Variable paramNames ] (Access (Variable varName) properties)) ->
if List.length properties == 1 && varName == paramNames then
( [ String.join "" properties |> error ], ctx )
else
( [], ctx )

View File

@ -1,31 +1,32 @@
module Lint.Types
exposing
( Direction(..)
, File
, LintError
, LintImplementation
, LintResult
, LintRule
, LintRuleImplementation
, Reporter
, Severity
, Severity(..)
, Visitor
)
module Lint.Types exposing
( LintError, Direction(..)
, LintRule, Severity(..), Reporter
, LintRuleImplementation, LintImplementation
, Visitor, LintResult, File
)
{-| This module contains types that are used for writing rules.
# Elementary types
@docs LintError, Direction
# Configuration
@docs LintRule, Severity, Reporter
# Writing rules
@docs LintRuleImplementation, LintImplementation
# Internal types
@docs Visitor, LintResult, File
-}
import Ast.Expression exposing (..)
@ -38,6 +39,7 @@ a description of the error.
error : LintError
error =
LintError "NoDebug" "Forbidden use of Debug"
-}
type alias LintError =
{ rule : String
@ -63,31 +65,35 @@ enforce.
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, moduleEndFn = \ctx -> ( [], ctx )
, initialContext = Context
}
-}
type alias LintImplementation nodeType context =
context -> Direction nodeType -> ( List LintError, context )
{-| 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 ctx node =
case node of
Enter (Variable names) ->
( [], markVariableAsUsed ctx names )
case node of
Enter (Variable names) ->
( [], markVariableAsUsed ctx names )
-- Find variables declared in `let .. in ..` expression
Enter (Let declarations body) ->
( [], registerVariables ctx declarations )
-- Find variables declared in `let .. in ..` expression
Enter (Let declarations body) ->
( [], 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
= Enter node
@ -95,25 +101,31 @@ type Direction node
{-| A LintRuleImplementation is the implementation of a rule. It is a record that contains:
- initialContext: An initial context
- statementFn: A LintImplementation for Statement nodes
- 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.
- initialContext: An initial context
- statementFn: A LintImplementation for Statement nodes
- 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 input =
lint input implementation
lint input implementation
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\ctx -> ( [], ctx ))
, initialContext = Context
}
{ statementFn = doNothing
, typeFn = doNothing
, expressionFn = expressionFn
, moduleEndFn = (\\ctx -> ( [], ctx ))
, initialContext = Context
}
-}
type alias LintRuleImplementation 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.
Note: this is internal API, and will be removed in a future version.
-}
type alias Visitor context =
LintRuleImplementation context -> context -> ( List LintError, context )
@ -147,9 +160,10 @@ type alias Visitor context =
{-| Severity associated to a rule.
- 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.
- Disabled: Rule will not be enforced.
- 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.
- Disabled: Rule will not be enforced.
-}
type Severity
= Disabled

View File

@ -1,8 +1,8 @@
module Lint.Visitor exposing (transformStatementsIntoVisitors, expressionToVisitors)
module Lint.Visitor exposing (expressionToVisitors, transformStatementsIntoVisitors)
import Ast.Expression 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)
@ -92,7 +92,7 @@ expressionToVisitors node =
childrenVisitors =
List.concatMap expressionToVisitors children
in
createExitAndEnterWithChildren expressionVisitor node childrenVisitors
createExitAndEnterWithChildren expressionVisitor node childrenVisitors
typeToVisitors : Type -> List (Visitor context)
@ -114,7 +114,7 @@ statementToVisitors node =
_ ->
[]
in
createExitAndEnterWithChildren statementVisitor node childrenVisitors
createExitAndEnterWithChildren statementVisitor node childrenVisitors
transformStatementsIntoVisitors : List Statement -> List (Visitor context)