mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-12-26 03:04:48 +03:00
Remove previous Rule implementation
This commit is contained in:
parent
9923ec0368
commit
f0b1733e8b
77
src/Lint.elm
77
src/Lint.elm
@ -1,8 +1,6 @@
|
||||
module Lint exposing
|
||||
( Rule, Severity(..)
|
||||
, lintSource
|
||||
, lint, expressionVisitor
|
||||
, createRule
|
||||
)
|
||||
|
||||
{-| A linter for Elm.
|
||||
@ -35,15 +33,10 @@ To run the rules on a source code and get a list of errors:
|
||||
@docs Rule, Severity
|
||||
|
||||
|
||||
# Implementation
|
||||
# Linting
|
||||
|
||||
@docs lintSource
|
||||
|
||||
|
||||
# Rule creation functions
|
||||
|
||||
@docs lint, expressionVisitor
|
||||
|
||||
-}
|
||||
|
||||
import Elm.Parser as Parser
|
||||
@ -53,8 +46,6 @@ import Elm.Syntax.File exposing (File)
|
||||
import Elm.Syntax.Node exposing (Node)
|
||||
import Lint.Direction exposing (Direction)
|
||||
import Lint.Error as Error exposing (Error)
|
||||
import Lint.NodeToVisitor exposing (createVisitorsForFile, expressionToVisitors)
|
||||
import Lint.Rule as Rule exposing (Implementation, Visitor)
|
||||
import Lint.RuleError as RuleError exposing (RuleError)
|
||||
|
||||
|
||||
@ -120,69 +111,3 @@ parseSource source =
|
||||
|> Result.mapError (\error -> [ "Parsing error" ])
|
||||
-- TODO Add all files to have more context https://package.elm-lang.org/packages/stil4m/elm-syntax/7.0.2/Elm-Processing
|
||||
|> Result.map (process init)
|
||||
|
||||
|
||||
{-| Lints source code using a given rule implementation, and gives back a list of errors that were found.
|
||||
|
||||
rule : Rule
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
||||
implementation : Implementation Context
|
||||
implementation =
|
||||
{ typeFn = doNothing
|
||||
, expressionVisitor = expressionVisitor
|
||||
, visitEnd = \ctx -> ( [], ctx )
|
||||
, initialContext = Context
|
||||
}
|
||||
|
||||
-}
|
||||
lint : Implementation context -> File -> List Error
|
||||
lint rule file =
|
||||
createVisitorsForFile file
|
||||
|> lintWithVisitors 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.
|
||||
|
||||
expressionVisitor : Context -> Direction Expression -> ( List Lint.Error.Error, Context )
|
||||
expressionVisitor ctx node =
|
||||
case node of
|
||||
Enter (Case expr patterns) ->
|
||||
expressionVisitor subimplementation expr
|
||||
|
||||
_ ->
|
||||
( [], ctx )
|
||||
|
||||
subimplementation : Implementation Subcontext
|
||||
subimplementation =
|
||||
{ statementFn = doNothing
|
||||
, typeFn = doNothing
|
||||
, expressionVisitor = subvisitExpression
|
||||
, visitEnd = \ctx -> ( [], ctx )
|
||||
, initialContext = Subcontext
|
||||
}
|
||||
|
||||
-}
|
||||
expressionVisitor : Implementation context -> Node Expression -> ( List Error, context )
|
||||
expressionVisitor rule expression =
|
||||
expressionToVisitors expression
|
||||
|> List.foldl (visitAndAccumulate rule) ( [], Rule.initialContext rule )
|
||||
|
||||
|
||||
visitAndAccumulate : Implementation context -> Visitor context -> ( List Error, context ) -> ( List Error, context )
|
||||
visitAndAccumulate rule visitor ( errors, ctx ) =
|
||||
let
|
||||
( newErrors, newContext ) =
|
||||
visitor rule ctx
|
||||
in
|
||||
( List.reverse newErrors ++ errors, newContext )
|
||||
|
||||
|
||||
lintWithVisitors : Implementation context -> List (Visitor context) -> List Error
|
||||
lintWithVisitors rule visitors =
|
||||
visitors
|
||||
|> List.foldl (visitAndAccumulate rule) ( [], Rule.initialContext rule )
|
||||
|> Tuple.first
|
||||
|> List.reverse
|
||||
|
@ -1,207 +0,0 @@
|
||||
module Lint.NodeToVisitor exposing (createVisitorsForFile, expressionToVisitors)
|
||||
|
||||
import Elm.Syntax.Declaration exposing (Declaration(..))
|
||||
import Elm.Syntax.Expression exposing (Expression(..), Function, FunctionImplementation, LetDeclaration(..))
|
||||
import Elm.Syntax.File exposing (File)
|
||||
import Elm.Syntax.Import exposing (Import)
|
||||
import Elm.Syntax.Infix exposing (InfixDirection(..))
|
||||
import Elm.Syntax.Module exposing (Module)
|
||||
import Elm.Syntax.Node exposing (Node, value)
|
||||
import Elm.Syntax.TypeAnnotation exposing (TypeAnnotation(..))
|
||||
import Lint.Direction as Direction exposing (Direction)
|
||||
import Lint.Rule exposing (Visitor, evaluateDeclaration, evaluateExpression, evaluateImport, evaluateModuleDefinition, finalEvaluation)
|
||||
|
||||
|
||||
createExitAndEnterWithChildren : (Direction -> nodeType -> Visitor context) -> nodeType -> List (Visitor context) -> List (Visitor context)
|
||||
createExitAndEnterWithChildren toVisitor node children =
|
||||
List.concat
|
||||
[ [ toVisitor Direction.Enter node ]
|
||||
, children
|
||||
, [ toVisitor Direction.Exit node ]
|
||||
]
|
||||
|
||||
|
||||
moduleVisitor : Visitor context
|
||||
moduleVisitor rule context =
|
||||
( finalEvaluation rule context, context )
|
||||
|
||||
|
||||
moduleDefinitionVisitor : Node Module -> Visitor context
|
||||
moduleDefinitionVisitor node rule context =
|
||||
evaluateModuleDefinition rule context node
|
||||
|
||||
|
||||
importVisitor : Node Import -> Visitor context
|
||||
importVisitor node rule context =
|
||||
evaluateImport rule context node
|
||||
|
||||
|
||||
expressionVisitor : Direction -> Node Expression -> Visitor context
|
||||
expressionVisitor direction node rule context =
|
||||
evaluateExpression rule context direction node
|
||||
|
||||
|
||||
declarationVisitor : Direction -> Node Declaration -> Visitor context
|
||||
declarationVisitor direction node rule context =
|
||||
evaluateDeclaration rule context direction node
|
||||
|
||||
|
||||
functionToExpression : Function -> Node Expression
|
||||
functionToExpression { documentation, signature, declaration } =
|
||||
let
|
||||
{ name, arguments, expression } =
|
||||
value declaration
|
||||
in
|
||||
expression
|
||||
|
||||
|
||||
expressionToVisitors : Node Expression -> List (Visitor context)
|
||||
expressionToVisitors node =
|
||||
let
|
||||
children : List (Node Expression)
|
||||
children =
|
||||
case value node of
|
||||
Application expressions ->
|
||||
expressions
|
||||
|
||||
Literal _ ->
|
||||
[]
|
||||
|
||||
Integer _ ->
|
||||
[]
|
||||
|
||||
Floatable _ ->
|
||||
[]
|
||||
|
||||
UnitExpr ->
|
||||
[]
|
||||
|
||||
ListExpr elements ->
|
||||
elements
|
||||
|
||||
FunctionOrValue _ _ ->
|
||||
[]
|
||||
|
||||
RecordExpr fields ->
|
||||
List.map (value >> (\( name, expr ) -> expr)) fields
|
||||
|
||||
RecordUpdateExpression name setters ->
|
||||
List.map (value >> (\( field, expr ) -> expr)) setters
|
||||
|
||||
ParenthesizedExpression expr ->
|
||||
[ expr ]
|
||||
|
||||
Operator name ->
|
||||
[]
|
||||
|
||||
OperatorApplication operator direction left right ->
|
||||
case direction of
|
||||
Left ->
|
||||
[ left, right ]
|
||||
|
||||
Right ->
|
||||
[ right, left ]
|
||||
|
||||
Non ->
|
||||
[ left, right ]
|
||||
|
||||
IfBlock cond then_ else_ ->
|
||||
[ cond, then_, else_ ]
|
||||
|
||||
LetExpression { expression, declarations } ->
|
||||
List.map
|
||||
(\declaration ->
|
||||
case value declaration of
|
||||
LetFunction function ->
|
||||
functionToExpression function
|
||||
|
||||
LetDestructuring pattern expr ->
|
||||
expr
|
||||
)
|
||||
declarations
|
||||
++ [ expression ]
|
||||
|
||||
CaseExpression { expression, cases } ->
|
||||
[ expression ]
|
||||
++ List.map (\( pattern, caseExpression ) -> caseExpression) cases
|
||||
|
||||
LambdaExpression { args, expression } ->
|
||||
[ expression ]
|
||||
|
||||
TupledExpression expressions ->
|
||||
expressions
|
||||
|
||||
PrefixOperator name ->
|
||||
[]
|
||||
|
||||
Hex _ ->
|
||||
[]
|
||||
|
||||
Negation expr ->
|
||||
[ expr ]
|
||||
|
||||
CharLiteral _ ->
|
||||
[]
|
||||
|
||||
RecordAccess expr property ->
|
||||
[ expr ]
|
||||
|
||||
RecordAccessFunction name ->
|
||||
[]
|
||||
|
||||
GLSLExpression expr ->
|
||||
[]
|
||||
|
||||
childrenVisitors =
|
||||
List.concatMap expressionToVisitors children
|
||||
in
|
||||
createExitAndEnterWithChildren expressionVisitor node childrenVisitors
|
||||
|
||||
|
||||
declarationToVisitors : Node Declaration -> List (Visitor context)
|
||||
declarationToVisitors node =
|
||||
let
|
||||
childrenVisitors =
|
||||
case value node of
|
||||
FunctionDeclaration function ->
|
||||
functionToExpression function |> expressionToVisitors
|
||||
|
||||
CustomTypeDeclaration _ ->
|
||||
[]
|
||||
|
||||
AliasDeclaration { typeAnnotation } ->
|
||||
[]
|
||||
|
||||
Destructuring pattern expr ->
|
||||
expressionToVisitors expr
|
||||
|
||||
PortDeclaration _ ->
|
||||
[]
|
||||
|
||||
InfixDeclaration _ ->
|
||||
[]
|
||||
in
|
||||
createExitAndEnterWithChildren declarationVisitor node childrenVisitors
|
||||
|
||||
|
||||
declarationsIntoVisitors : List (Node Declaration) -> List (Visitor context)
|
||||
declarationsIntoVisitors declarations =
|
||||
List.concatMap declarationToVisitors declarations
|
||||
|
||||
|
||||
importsIntoVisitors : List (Node Import) -> List (Visitor context)
|
||||
importsIntoVisitors imports =
|
||||
List.map importVisitor imports
|
||||
|
||||
|
||||
moduleDefinitionIntoVisitor : Node Module -> Visitor context
|
||||
moduleDefinitionIntoVisitor moduleNode =
|
||||
moduleDefinitionVisitor moduleNode
|
||||
|
||||
|
||||
createVisitorsForFile : File -> List (Visitor context)
|
||||
createVisitorsForFile file =
|
||||
[ moduleDefinitionIntoVisitor file.moduleDefinition ]
|
||||
++ importsIntoVisitors file.imports
|
||||
++ declarationsIntoVisitors file.declarations
|
||||
++ [ moduleVisitor ]
|
@ -1,213 +0,0 @@
|
||||
module Lint.Rule exposing
|
||||
( Implementation
|
||||
, create, createSimple
|
||||
, withModuleDefinitionVisitor, withImportVisitor, withExpressionVisitor, withDeclarationVisitor, withFinalEvaluation
|
||||
, withSimpleModuleDefinitionVisitor, withSimpleImportVisitor, withSimpleExpressionVisitor, withSimpleDeclarationVisitor
|
||||
, evaluateDeclaration, evaluateExpression, evaluateImport, evaluateModuleDefinition, finalEvaluation, initialContext
|
||||
, Visitor
|
||||
)
|
||||
|
||||
{-| This module contains functions that are used for writing rules.
|
||||
|
||||
|
||||
# Definition
|
||||
|
||||
@docs Implementation
|
||||
|
||||
|
||||
# Writing rules
|
||||
|
||||
@docs create, createSimple
|
||||
@docs withModuleDefinitionVisitor, withImportVisitor, withExpressionVisitor, withDeclarationVisitor, withFinalEvaluation
|
||||
@docs withSimpleModuleDefinitionVisitor, withSimpleImportVisitor, withSimpleExpressionVisitor, withSimpleDeclarationVisitor
|
||||
|
||||
|
||||
# ACCESS
|
||||
|
||||
@docs evaluateDeclaration, evaluateExpression, evaluateImport, evaluateModuleDefinition, finalEvaluation, initialContext
|
||||
|
||||
|
||||
# Internal types
|
||||
|
||||
@docs Visitor
|
||||
|
||||
-}
|
||||
|
||||
import Elm.Syntax.Declaration exposing (Declaration)
|
||||
import Elm.Syntax.Expression exposing (Expression)
|
||||
import Elm.Syntax.File exposing (File)
|
||||
import Elm.Syntax.Import exposing (Import)
|
||||
import Elm.Syntax.Module exposing (Module)
|
||||
import Elm.Syntax.Node exposing (Node)
|
||||
import Elm.Syntax.TypeAnnotation exposing (TypeAnnotation)
|
||||
import Lint.Direction as Direction exposing (Direction)
|
||||
import Lint.Error exposing (Error)
|
||||
|
||||
|
||||
{-| A Implementation is the implementation of a rule. It is a record that contains:
|
||||
|
||||
- initialContext: An initial context
|
||||
|
||||
- expression: A LintImplementation for Expression nodes
|
||||
|
||||
- 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.
|
||||
|
||||
import Lint exposing (Rule)
|
||||
import Lint.Rule as Rule
|
||||
|
||||
type alias Context =
|
||||
{ numberOfImports : Int
|
||||
}
|
||||
|
||||
rule : Rule
|
||||
rule input =
|
||||
lint input implementation
|
||||
|
||||
implementation : Rule.Implementation Context
|
||||
implementation =
|
||||
Rule.create { numberOfImports = 0 }
|
||||
|> Rule.withImportVisitor importVisitor
|
||||
|
||||
-}
|
||||
type Implementation context
|
||||
= Implementation
|
||||
{ initialContext : context
|
||||
, moduleDefinitionVisitor : context -> Node Module -> ( List Error, context )
|
||||
, importVisitor : context -> Node Import -> ( List Error, context )
|
||||
, expressionVisitor : context -> Direction -> Node Expression -> ( List Error, context )
|
||||
, declarationVisitor : context -> Direction -> Node Declaration -> ( List Error, context )
|
||||
, finalEvaluationFn : context -> List Error
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- RULE CONSTRUCTOR AND BUILDERS
|
||||
-- RULES WITH ANALYSES
|
||||
|
||||
|
||||
create : context -> Implementation context
|
||||
create initialContext_ =
|
||||
Implementation
|
||||
{ initialContext = initialContext_
|
||||
, moduleDefinitionVisitor = \context node -> ( [], context )
|
||||
, importVisitor = \context node -> ( [], context )
|
||||
, expressionVisitor = \context direction node -> ( [], context )
|
||||
, declarationVisitor = \context direction node -> ( [], context )
|
||||
, finalEvaluationFn = \context -> []
|
||||
}
|
||||
|
||||
|
||||
withModuleDefinitionVisitor : (context -> Node Module -> ( List Error, context )) -> Implementation context -> Implementation context
|
||||
withModuleDefinitionVisitor visitor (Implementation impl) =
|
||||
Implementation { impl | moduleDefinitionVisitor = visitor }
|
||||
|
||||
|
||||
withImportVisitor : (context -> Node Import -> ( List Error, context )) -> Implementation context -> Implementation context
|
||||
withImportVisitor visitor (Implementation impl) =
|
||||
Implementation { impl | importVisitor = visitor }
|
||||
|
||||
|
||||
withExpressionVisitor : (context -> Direction -> Node Expression -> ( List Error, context )) -> Implementation context -> Implementation context
|
||||
withExpressionVisitor visitor (Implementation impl) =
|
||||
Implementation { impl | expressionVisitor = visitor }
|
||||
|
||||
|
||||
withDeclarationVisitor : (context -> Direction -> Node Declaration -> ( List Error, context )) -> Implementation context -> Implementation context
|
||||
withDeclarationVisitor visitor (Implementation impl) =
|
||||
Implementation { impl | declarationVisitor = visitor }
|
||||
|
||||
|
||||
withFinalEvaluation : (context -> List Error) -> Implementation context -> Implementation context
|
||||
withFinalEvaluation visitor (Implementation impl) =
|
||||
Implementation { impl | finalEvaluationFn = visitor }
|
||||
|
||||
|
||||
|
||||
-- RULES WITHOUT ANALYSIS
|
||||
|
||||
|
||||
createSimple : Implementation ()
|
||||
createSimple =
|
||||
create ()
|
||||
|
||||
|
||||
withSimpleModuleDefinitionVisitor : (Node Module -> List Error) -> Implementation context -> Implementation context
|
||||
withSimpleModuleDefinitionVisitor visitor (Implementation impl) =
|
||||
Implementation { impl | moduleDefinitionVisitor = \context node -> ( visitor node, context ) }
|
||||
|
||||
|
||||
withSimpleImportVisitor : (Node Import -> List Error) -> Implementation context -> Implementation context
|
||||
withSimpleImportVisitor visitor (Implementation impl) =
|
||||
Implementation { impl | importVisitor = \context node -> ( visitor node, context ) }
|
||||
|
||||
|
||||
withSimpleExpressionVisitor : (Node Expression -> List Error) -> Implementation context -> Implementation context
|
||||
withSimpleExpressionVisitor visitor (Implementation impl) =
|
||||
Implementation
|
||||
{ impl
|
||||
| expressionVisitor =
|
||||
\context direction node ->
|
||||
case direction of
|
||||
Direction.Enter ->
|
||||
( visitor node, context )
|
||||
|
||||
Direction.Exit ->
|
||||
( [], context )
|
||||
}
|
||||
|
||||
|
||||
withSimpleDeclarationVisitor : (Node Declaration -> List Error) -> Implementation context -> Implementation context
|
||||
withSimpleDeclarationVisitor visitor (Implementation impl) =
|
||||
Implementation
|
||||
{ impl
|
||||
| declarationVisitor =
|
||||
\context direction node ->
|
||||
case direction of
|
||||
Direction.Enter ->
|
||||
( visitor node, context )
|
||||
|
||||
Direction.Exit ->
|
||||
( [], context )
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ACCESS
|
||||
|
||||
|
||||
initialContext : Implementation context -> context
|
||||
initialContext (Implementation impl) =
|
||||
impl.initialContext
|
||||
|
||||
|
||||
evaluateModuleDefinition : Implementation context -> context -> Node Module -> ( List Error, context )
|
||||
evaluateModuleDefinition (Implementation impl) =
|
||||
impl.moduleDefinitionVisitor
|
||||
|
||||
|
||||
evaluateImport : Implementation context -> context -> Node Import -> ( List Error, context )
|
||||
evaluateImport (Implementation impl) =
|
||||
impl.importVisitor
|
||||
|
||||
|
||||
evaluateExpression : Implementation context -> context -> Direction -> Node Expression -> ( List Error, context )
|
||||
evaluateExpression (Implementation impl) =
|
||||
impl.expressionVisitor
|
||||
|
||||
|
||||
evaluateDeclaration : Implementation context -> context -> Direction -> Node Declaration -> ( List Error, context )
|
||||
evaluateDeclaration (Implementation impl) =
|
||||
impl.declarationVisitor
|
||||
|
||||
|
||||
finalEvaluation : Implementation context -> context -> List Error
|
||||
finalEvaluation (Implementation impl) =
|
||||
impl.finalEvaluationFn
|
||||
|
||||
|
||||
{-| 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.
|
||||
-}
|
||||
type alias Visitor context =
|
||||
Implementation context -> context -> ( List Error, context )
|
Loading…
Reference in New Issue
Block a user