Modules reordering

This commit is contained in:
Jeroen Engels 2018-11-10 23:37:18 +01:00
parent 1bbaf607cf
commit c559bd94b8
9 changed files with 105 additions and 97 deletions

View File

@ -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 )

View File

@ -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

View File

@ -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
View 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
}

View File

@ -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

View File

@ -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 )

View File

@ -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)

View File

@ -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

View File

@ -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 ->