mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-12-26 03:04:48 +03:00
Modules reordering
This commit is contained in:
parent
1bbaf607cf
commit
c559bd94b8
@ -1,6 +1,6 @@
|
||||
module LintConfig exposing (config)
|
||||
|
||||
import Lint.Types exposing (LintRule, Severity(..))
|
||||
import Lint.Types exposing (Rule, Severity(..))
|
||||
import Lint.Rules.DefaultPatternPosition
|
||||
import Lint.Rules.NoConstantCondition
|
||||
import Lint.Rules.NoDebug
|
||||
@ -18,7 +18,7 @@ import Lint.Rules.SimplifyPropertyAccess
|
||||
import Lint.Rules.ElmTest.NoDuplicateTestBodies
|
||||
|
||||
|
||||
config : List ( Severity, LintRule )
|
||||
config : List ( Severity, Rule )
|
||||
config =
|
||||
[ ( Critical, Lint.Rules.DefaultPatternPosition.rule { position = Lint.Rules.DefaultPatternPosition.Last } )
|
||||
, ( Critical, Lint.Rules.NoConstantCondition.rule )
|
||||
|
@ -6,9 +6,9 @@ import Browser
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (class, id, style)
|
||||
import Html.Events exposing (onInput)
|
||||
import Lint exposing (lintSource)
|
||||
import Lint exposing (Rule, Severity(..), lintSource)
|
||||
import Lint.Error exposing (Error)
|
||||
import Lint.Rules.NoDebug
|
||||
import Lint.Types exposing (LintRule, Severity(..))
|
||||
import Result exposing (Result)
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ type Msg
|
||||
= Replace String
|
||||
|
||||
|
||||
config : List ( Severity, LintRule )
|
||||
config : List ( Severity, Rule )
|
||||
config =
|
||||
[ ( Critical, Lint.Rules.NoDebug.rule )
|
||||
|
||||
@ -58,7 +58,7 @@ update action model =
|
||||
m
|
||||
|
||||
|
||||
errorToString : Lint.Types.LintError -> String
|
||||
errorToString : Error -> String
|
||||
errorToString { message, range } =
|
||||
message ++ " (line " ++ String.fromInt range.start.row ++ ", column " ++ String.fromInt range.start.column ++ ")"
|
||||
|
||||
@ -66,7 +66,7 @@ errorToString { message, range } =
|
||||
lint : String -> Html Msg
|
||||
lint source =
|
||||
let
|
||||
lintResult : Result (List String) (List ( Severity, Lint.Types.LintError ))
|
||||
lintResult : Result (List String) (List ( Severity, Error ))
|
||||
lintResult =
|
||||
lintSource config source
|
||||
|
||||
|
56
src/Lint.elm
56
src/Lint.elm
@ -1,5 +1,6 @@
|
||||
module Lint exposing
|
||||
( lintSource
|
||||
( Rule, Severity(..)
|
||||
, lintSource
|
||||
, lint, visitExpression
|
||||
, parseSource
|
||||
)
|
||||
@ -29,6 +30,11 @@ To run the rules on a source code and get a list of errors:
|
||||
List.map (\err -> err.rule ++ ": " ++ err.message) errors
|
||||
|
||||
|
||||
# Configuration
|
||||
|
||||
@docs Rule, Severity
|
||||
|
||||
|
||||
# Implementation
|
||||
|
||||
@docs lintSource
|
||||
@ -50,17 +56,37 @@ import Elm.Processing exposing (addFile, init, process)
|
||||
import Elm.Syntax.Expression exposing (Expression)
|
||||
import Elm.Syntax.File exposing (File)
|
||||
import Elm.Syntax.Node exposing (Node)
|
||||
import Lint.Types exposing (Direction, LintError, LintRule, LintRuleImplementation, Severity(..), Visitor, initialContext)
|
||||
import Lint.Error exposing (Error)
|
||||
import Lint.Types exposing (Direction, LintRuleImplementation, Visitor, initialContext)
|
||||
import Lint.Visitor exposing (expressionToVisitors, transformDeclarationsIntoVisitors)
|
||||
|
||||
|
||||
{-| Shortcut to a lint rule
|
||||
-}
|
||||
type alias Rule =
|
||||
File -> List Error
|
||||
|
||||
|
||||
{-| 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.
|
||||
|
||||
-}
|
||||
type Severity
|
||||
= Disabled
|
||||
| Warning
|
||||
| Critical
|
||||
|
||||
|
||||
{-| Lints a file and gives back the errors raised by the given rules.
|
||||
|
||||
errors =
|
||||
lintSource rules source
|
||||
|
||||
-}
|
||||
lintSource : List ( Severity, LintRule ) -> String -> Result (List String) (List ( Severity, LintError ))
|
||||
lintSource : List ( Severity, Rule ) -> String -> Result (List String) (List ( Severity, Error ))
|
||||
lintSource rules source =
|
||||
source
|
||||
|> parseSource
|
||||
@ -72,7 +98,7 @@ lintSource rules source =
|
||||
)
|
||||
|
||||
|
||||
lintSourceWithRule : File -> ( Severity, LintRule ) -> List ( Severity, LintError )
|
||||
lintSourceWithRule : File -> ( Severity, Rule ) -> List ( Severity, Error )
|
||||
lintSourceWithRule file ( severity, rule ) =
|
||||
rule file
|
||||
|> List.map (\b -> ( severity, b ))
|
||||
@ -92,20 +118,20 @@ parseSource source =
|
||||
|
||||
{-| Lints source code using a given rule implementation, and gives back a list of errors that were found.
|
||||
|
||||
rule : LintRule
|
||||
rule : Rule
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
||||
implementation : LintRuleImplementation Context
|
||||
implementation =
|
||||
{ typeFn = doNothing
|
||||
, expressionFn = expressionFn
|
||||
, moduleEndFn = \ctx -> ( [], ctx )
|
||||
, visitExpression = visitExpression
|
||||
, visitEnd = \ctx -> ( [], ctx )
|
||||
, initialContext = Context
|
||||
}
|
||||
|
||||
-}
|
||||
lint : File -> LintRuleImplementation context -> List LintError
|
||||
lint : File -> LintRuleImplementation context -> List Error
|
||||
lint file rule =
|
||||
file.declarations
|
||||
|> transformDeclarationsIntoVisitors
|
||||
@ -115,8 +141,8 @@ lint file rule =
|
||||
{-| Visit an expression using a sub rule implementation. The use of this function is not encouraged, but it can make
|
||||
part of the implementation of complex rules much easier. It gives back a list of errors and a context.
|
||||
|
||||
expressionFn : Context -> Direction Expression -> ( List LintError, Context )
|
||||
expressionFn ctx node =
|
||||
visitExpression : Context -> Direction Expression -> ( List Lint.Error.Error, Context )
|
||||
visitExpression ctx node =
|
||||
case node of
|
||||
Enter (Case expr patterns) ->
|
||||
visitExpression subimplementation expr
|
||||
@ -128,25 +154,25 @@ part of the implementation of complex rules much easier. It gives back a list of
|
||||
subimplementation =
|
||||
{ statementFn = doNothing
|
||||
, typeFn = doNothing
|
||||
, expressionFn = subexpressionFn
|
||||
, moduleEndFn = \ctx -> ( [], ctx )
|
||||
, visitExpression = subvisitExpression
|
||||
, visitEnd = \ctx -> ( [], ctx )
|
||||
, initialContext = Subcontext
|
||||
}
|
||||
|
||||
-}
|
||||
visitExpression : LintRuleImplementation context -> Node Expression -> ( List LintError, context )
|
||||
visitExpression : LintRuleImplementation context -> Node Expression -> ( List Error, context )
|
||||
visitExpression rule expression =
|
||||
expressionToVisitors expression
|
||||
|> List.foldl (visitAndAccumulate rule) ( [], initialContext rule )
|
||||
|
||||
|
||||
visitAndAccumulate : LintRuleImplementation context -> Visitor context -> ( List LintError, context ) -> ( List LintError, context )
|
||||
visitAndAccumulate : LintRuleImplementation context -> Visitor context -> ( List Error, context ) -> ( List Error, context )
|
||||
visitAndAccumulate rule visitor ( errors, ctx ) =
|
||||
visitor rule ctx
|
||||
|> Tuple.mapFirst (\errors_ -> errors ++ errors_)
|
||||
|
||||
|
||||
lintWithVisitors : LintRuleImplementation context -> List (Visitor context) -> List LintError
|
||||
lintWithVisitors : LintRuleImplementation context -> List (Visitor context) -> List Error
|
||||
lintWithVisitors rule visitors =
|
||||
visitors
|
||||
|> List.foldl (visitAndAccumulate rule) ( [], initialContext rule )
|
||||
|
18
src/Lint/Error.elm
Normal file
18
src/Lint/Error.elm
Normal file
@ -0,0 +1,18 @@
|
||||
module Lint.Error exposing (Error)
|
||||
|
||||
{-| Value that describes an error found by a rule, and contains the name of the rule that raised the error, and a description of the error.
|
||||
|
||||
error : LintError
|
||||
error =
|
||||
LintError "NoDebug" "Forbidden use of Debug"
|
||||
|
||||
-}
|
||||
|
||||
import Elm.Syntax.Range exposing (Range)
|
||||
|
||||
|
||||
type alias Error =
|
||||
{ rule : String
|
||||
, message : String
|
||||
, range : Range
|
||||
}
|
@ -32,8 +32,9 @@ module Lint.Rules.NoDebug exposing (rule)
|
||||
|
||||
import Elm.Syntax.Expression exposing (Expression(..))
|
||||
import Elm.Syntax.Node exposing (Node, range, value)
|
||||
import Lint exposing (lint)
|
||||
import Lint.Types exposing (Direction(..), LintError, LintRule, LintRuleImplementation, createRule)
|
||||
import Lint exposing (Rule, lint)
|
||||
import Lint.Error exposing (Error)
|
||||
import Lint.Types exposing (Direction(..), LintRuleImplementation, createRule)
|
||||
|
||||
|
||||
type alias Context =
|
||||
@ -47,7 +48,7 @@ type alias Context =
|
||||
]
|
||||
|
||||
-}
|
||||
rule : LintRule
|
||||
rule : Rule
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
||||
@ -56,16 +57,16 @@ implementation : LintRuleImplementation Context
|
||||
implementation =
|
||||
createRule
|
||||
Context
|
||||
(\v -> { v | expressionFn = expressionFn })
|
||||
(\v -> { v | visitExpression = visitExpression })
|
||||
|
||||
|
||||
error : Node a -> LintError
|
||||
error : Node a -> Error
|
||||
error node =
|
||||
LintError "NoDebug" "Forbidden use of Debug" (range node)
|
||||
Error "NoDebug" "Forbidden use of Debug" (range node)
|
||||
|
||||
|
||||
expressionFn : Context -> Direction -> Node Expression -> ( List LintError, Context )
|
||||
expressionFn ctx direction node =
|
||||
visitExpression : Context -> Direction -> Node Expression -> ( List Error, Context )
|
||||
visitExpression ctx direction node =
|
||||
case ( direction, value node ) of
|
||||
( Enter, FunctionOrValue moduleName fnName ) ->
|
||||
if List.member "Debug" moduleName then
|
||||
|
@ -1,22 +1,16 @@
|
||||
module Lint.Types exposing
|
||||
( LintError, Direction(..)
|
||||
, LintRule, Severity(..)
|
||||
( Direction(..)
|
||||
, LintRuleImplementation, createRule
|
||||
, Visitor, LintResult
|
||||
, evaluateExpression, finalEvaluation, initialContext
|
||||
)
|
||||
|
||||
{-| This module contains types that are used for writing rules.
|
||||
{-| This module contains functions that are used for writing rules.
|
||||
|
||||
|
||||
# Elementary types
|
||||
|
||||
@docs LintError, Direction
|
||||
|
||||
|
||||
# Configuration
|
||||
|
||||
@docs LintRule, Severity
|
||||
@docs Direction
|
||||
|
||||
|
||||
# Writing rules
|
||||
@ -33,22 +27,7 @@ module Lint.Types exposing
|
||||
import Elm.Syntax.Expression exposing (Expression)
|
||||
import Elm.Syntax.File exposing (File)
|
||||
import Elm.Syntax.Node exposing (Node)
|
||||
import Elm.Syntax.Range exposing (Range)
|
||||
|
||||
|
||||
{-| Value that describes an error found by a given rule, that contains the name of the rule that raised the error, and
|
||||
a description of the error.
|
||||
|
||||
error : LintError
|
||||
error =
|
||||
LintError "NoDebug" "Forbidden use of Debug"
|
||||
|
||||
-}
|
||||
type alias LintError =
|
||||
{ rule : String
|
||||
, message : String
|
||||
, range : Range
|
||||
}
|
||||
import Lint.Error exposing (Error)
|
||||
|
||||
|
||||
{-| When visiting the AST, nodes are visited twice:
|
||||
@ -57,7 +36,7 @@ type alias LintError =
|
||||
|
||||
- on Exit, after the children of the node have been visited
|
||||
|
||||
expression : Context -> Direction Expression -> ( List LintError, Context )
|
||||
expression : Context -> Direction Expression -> ( List Lint.Error.Error, Context )
|
||||
expression ctx node =
|
||||
case node of
|
||||
Enter (Variable names) ->
|
||||
@ -83,17 +62,17 @@ type Direction
|
||||
|
||||
- expression: A LintImplementation for Expression nodes
|
||||
|
||||
- moduleEndFn: A function that takes a context and returns a list of error. Similar to a LintImplementation, but will
|
||||
- visitEnd: 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 : Rule
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
||||
implementation : LintRuleImplementation Context
|
||||
implementation =
|
||||
{ expression = expression
|
||||
, moduleEndFn = (\\ctx -> ( [], ctx ))
|
||||
, visitEnd = (\\ctx -> ( [], ctx ))
|
||||
, initialContext = Context
|
||||
}
|
||||
|
||||
@ -106,8 +85,8 @@ type LintRuleImplementation context
|
||||
|
||||
|
||||
type alias Visitors context =
|
||||
{ expressionFn : context -> Direction -> Node Expression -> ( List LintError, context )
|
||||
, moduleEndFn : context -> ( List LintError, context )
|
||||
{ visitExpression : context -> Direction -> Node Expression -> ( List Error, context )
|
||||
, visitEnd : context -> ( List Error, context )
|
||||
}
|
||||
|
||||
|
||||
@ -117,8 +96,8 @@ createRule initContext createVisitors =
|
||||
{ initContext = initContext
|
||||
, visitors =
|
||||
createVisitors
|
||||
{ expressionFn = \ctx direction node -> ( [], ctx )
|
||||
, moduleEndFn = \ctx -> ( [], ctx )
|
||||
{ visitExpression = \ctx direction node -> ( [], ctx )
|
||||
, visitEnd = \ctx -> ( [], ctx )
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,46 +107,27 @@ initialContext (LintRuleImplementation { initContext }) =
|
||||
initContext
|
||||
|
||||
|
||||
evaluateExpression : LintRuleImplementation context -> context -> Direction -> Node Expression -> ( List LintError, context )
|
||||
evaluateExpression : LintRuleImplementation context -> context -> Direction -> Node Expression -> ( List Error, context )
|
||||
evaluateExpression (LintRuleImplementation { visitors }) =
|
||||
visitors.expressionFn
|
||||
visitors.visitExpression
|
||||
|
||||
|
||||
finalEvaluation : LintRuleImplementation context -> context -> ( List LintError, context )
|
||||
finalEvaluation : LintRuleImplementation context -> context -> ( List Error, context )
|
||||
finalEvaluation (LintRuleImplementation { visitors }) =
|
||||
visitors.moduleEndFn
|
||||
visitors.visitEnd
|
||||
|
||||
|
||||
{-| Shortcut to the result of a lint rule
|
||||
-}
|
||||
type alias LintResult =
|
||||
Result (List String) (List LintError)
|
||||
Result (List String) (List Error)
|
||||
|
||||
|
||||
{-| Shortcut to a lint rule
|
||||
-}
|
||||
type alias LintRule =
|
||||
File -> List LintError
|
||||
|
||||
|
||||
{-| Shorthand for a function that takes a rule's implementation, a context and returns ( List LintError, context ).
|
||||
{-| Shorthand for a function that takes a rule's implementation, a context and returns ( List Lint.Error.Error, context ).
|
||||
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 )
|
||||
|
||||
|
||||
{-| 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.
|
||||
|
||||
-}
|
||||
type Severity
|
||||
= Disabled
|
||||
| Warning
|
||||
| Critical
|
||||
LintRuleImplementation context -> context -> ( List Error, context )
|
||||
|
@ -4,7 +4,7 @@ import Elm.Syntax.Declaration exposing (Declaration(..))
|
||||
import Elm.Syntax.Expression exposing (Expression(..), Function, FunctionImplementation, LetDeclaration(..))
|
||||
import Elm.Syntax.Infix exposing (InfixDirection(..))
|
||||
import Elm.Syntax.Node exposing (Node, value)
|
||||
import Lint.Types exposing (Direction(..), LintRule, Visitor, evaluateExpression, finalEvaluation)
|
||||
import Lint.Types exposing (Direction(..), Visitor, evaluateExpression, finalEvaluation)
|
||||
|
||||
|
||||
createExitAndEnterWithChildren : (Direction -> nodeType -> Visitor context) -> nodeType -> List (Visitor context) -> List (Visitor context)
|
||||
|
@ -1,8 +1,10 @@
|
||||
module NoDebugTest exposing (all)
|
||||
|
||||
import Elm.Syntax.Range exposing (Location, Range)
|
||||
import Lint exposing (Rule)
|
||||
import Lint.Error exposing (Error)
|
||||
import Lint.Rules.NoDebug exposing (rule)
|
||||
import Lint.Types exposing (LintError, LintResult, LintRule)
|
||||
import Lint.Types exposing (LintResult)
|
||||
import Test exposing (Test, describe, only, test)
|
||||
import TestUtil exposing (expectErrors, ruleTester)
|
||||
|
||||
@ -14,9 +16,9 @@ testRule string =
|
||||
|> ruleTester rule
|
||||
|
||||
|
||||
error : String -> Range -> LintError
|
||||
error : String -> Range -> Error
|
||||
error =
|
||||
LintError "NoDebug"
|
||||
Error "NoDebug"
|
||||
|
||||
|
||||
location : Int -> Int -> Int -> Range
|
||||
|
@ -1,17 +1,18 @@
|
||||
module TestUtil exposing (expectErrors, ruleTester)
|
||||
|
||||
import Expect
|
||||
import Lint exposing (parseSource)
|
||||
import Lint.Types exposing (LintError, LintResult, LintRule)
|
||||
import Lint exposing (Rule, parseSource)
|
||||
import Lint.Error exposing (Error)
|
||||
import Lint.Types exposing (LintResult)
|
||||
|
||||
|
||||
ruleTester : LintRule -> String -> LintResult
|
||||
ruleTester : Rule -> String -> LintResult
|
||||
ruleTester rule str =
|
||||
parseSource str
|
||||
|> Result.map rule
|
||||
|
||||
|
||||
expectErrors : List LintError -> LintResult -> Expect.Expectation
|
||||
expectErrors : List Error -> LintResult -> Expect.Expectation
|
||||
expectErrors expectedErrors result =
|
||||
case result of
|
||||
Err errors ->
|
||||
|
Loading…
Reference in New Issue
Block a user