Separate visitors into Enter and Exit types

This commit is contained in:
Jeroen Engels 2017-01-08 15:31:17 +01:00
parent 9ebb4ac7d4
commit 5e25a994cb
5 changed files with 75 additions and 51 deletions

103
Lint.elm
View File

@ -1,7 +1,14 @@
module Lint exposing (lint, LintRule, Error, doNothing) module Lint
exposing
( lint
, LintRule
, Error
, doNothing
)
import Ast.Expression exposing (..) import Ast.Expression exposing (..)
import Ast.Statement exposing (..) import Ast.Statement exposing (..)
import Node exposing (..)
type alias Error = type alias Error =
@ -9,7 +16,7 @@ type alias Error =
type alias LintImplementation nodeType context = type alias LintImplementation nodeType context =
context -> nodeType -> ( List Error, context ) context -> Direction nodeType -> ( List Error, context )
type alias LintRule context = type alias LintRule context =
@ -29,17 +36,21 @@ doNothing ctx _ =
( [], ctx ) ( [], ctx )
expressionVisitor : Expression -> Visitor context createExitAndEnterWithChildren : (Direction nodeType -> Visitor context) -> nodeType -> List (Visitor context) -> List (Visitor context)
createExitAndEnterWithChildren toVisitor node children =
List.concat
[ [ toVisitor (Enter node) ]
, children
, [ toVisitor (Exit node) ]
]
expressionVisitor : Direction Expression -> Visitor context
expressionVisitor node rule context = expressionVisitor node rule context =
rule.expressionFn context node rule.expressionFn context node
typeVisitor : Type -> Visitor context statementVisitor : Direction Statement -> Visitor context
typeVisitor node rule context =
rule.typeFn context node
statementVisitor : Statement -> Visitor context
statementVisitor node rule context = statementVisitor node rule context =
rule.statementFn context node rule.statementFn context node
@ -47,24 +58,24 @@ statementVisitor node rule context =
expressionToVisitors : Expression -> List (Visitor context) expressionToVisitors : Expression -> List (Visitor context)
expressionToVisitors node = expressionToVisitors node =
let let
visitAndTransformChildren children = children =
List.concat case node of
[ [ expressionVisitor node ] Application expression1 expression2 ->
, List.concatMap expressionToVisitors children [ expression1, expression2 ]
]
Access expression names ->
[ expression ]
Variable _ ->
[]
_ ->
[]
childrenVisitors =
List.concatMap expressionToVisitors children
in in
case node of createExitAndEnterWithChildren expressionVisitor node childrenVisitors
Application expression1 expression2 ->
visitAndTransformChildren [ expression1, expression2 ]
Access expression names ->
visitAndTransformChildren [ expression ]
Variable _ ->
[ expressionVisitor node ]
_ ->
[]
typeToVisitors : Type -> List (Visitor context) typeToVisitors : Type -> List (Visitor context)
@ -72,28 +83,32 @@ typeToVisitors node =
[] []
statementChildrenToVisitors : List Expression -> List Type -> List (Visitor context)
statementChildrenToVisitors expressions types =
List.concat
[ List.concatMap expressionToVisitors expressions
, List.concatMap typeToVisitors types
]
statementToVisitors : Statement -> List (Visitor context) statementToVisitors : Statement -> List (Visitor context)
statementToVisitors node = statementToVisitors node =
let let
visitAndTransformChildren expressions types = childrenVisitors =
List.concat case node of
[ [ statementVisitor node ] FunctionTypeDeclaration name application ->
, List.concatMap expressionToVisitors expressions statementChildrenToVisitors [] [ application ]
, List.concatMap typeToVisitors types
] FunctionDeclaration name params body ->
statementChildrenToVisitors [ body ] []
ModuleDeclaration name exportSet ->
statementChildrenToVisitors [] []
_ ->
[]
in in
case node of createExitAndEnterWithChildren statementVisitor node childrenVisitors
FunctionTypeDeclaration name application ->
visitAndTransformChildren [] [ application ]
FunctionDeclaration name params body ->
visitAndTransformChildren [ body ] []
ModuleDeclaration name exportSet ->
visitAndTransformChildren [] []
_ ->
[]
visitAndAccumulate : LintRule context -> Visitor context -> ( List Error, context ) -> ( List Error, context ) visitAndAccumulate : LintRule context -> Visitor context -> ( List Error, context ) -> ( List Error, context )

6
Node.elm Normal file
View File

@ -0,0 +1,6 @@
module Node exposing (..)
type Direction node
= Enter node
| Exit node

View File

@ -1,6 +1,7 @@
module FindNoAnnotatedFunction exposing (rule) module FindNoAnnotatedFunction exposing (rule)
import Lint exposing (LintRule, Error, doNothing) import Lint exposing (LintRule, Error, doNothing)
import Node exposing (..)
import Ast.Statement exposing (..) import Ast.Statement exposing (..)
@ -18,13 +19,13 @@ rule =
} }
statementFn : Context -> Statement -> ( List Error, Context ) statementFn : Context -> Direction Statement -> ( List Error, Context )
statementFn ctx node = statementFn ctx node =
case node of case node of
FunctionTypeDeclaration name application -> Enter (FunctionTypeDeclaration name application) ->
( [], { ctx | annotatedFunctions = name :: ctx.annotatedFunctions } ) ( [], { ctx | annotatedFunctions = name :: ctx.annotatedFunctions } )
FunctionDeclaration name params body -> Enter (FunctionDeclaration name params body) ->
if List.member name ctx.annotatedFunctions then if List.member name ctx.annotatedFunctions then
( [], ctx ) ( [], ctx )
else else

View File

@ -1,6 +1,7 @@
module NoDebug exposing (rule) module NoDebug exposing (rule)
import Lint exposing (LintRule, Error, doNothing) import Lint exposing (LintRule, Error, doNothing)
import Node exposing (..)
import Ast.Expression exposing (..) import Ast.Expression exposing (..)
@ -17,10 +18,10 @@ rule =
} }
expressionFn : Context -> Expression -> ( List Error, Context ) expressionFn : Context -> Direction Expression -> ( List Error, Context )
expressionFn ctx node = expressionFn ctx node =
case node of case node of
Variable vars -> Enter (Variable vars) ->
if List.member "Debug" vars then if List.member "Debug" vars then
( [ "Forbidden use of Debug" ], ctx ) ( [ "Forbidden use of Debug" ], ctx )
else else

View File

@ -1,6 +1,7 @@
module NoExposingEverything exposing (rule) module NoExposingEverything exposing (rule)
import Lint exposing (LintRule, Error, doNothing) import Lint exposing (LintRule, Error, doNothing)
import Node exposing (..)
import Ast.Statement exposing (..) import Ast.Statement exposing (..)
@ -17,10 +18,10 @@ rule =
} }
statementFn : Context -> Statement -> ( List Error, Context ) statementFn : Context -> Direction Statement -> ( List Error, Context )
statementFn ctx node = statementFn ctx node =
case node of case node of
ModuleDeclaration names AllExport -> Enter (ModuleDeclaration names AllExport) ->
case names of case names of
[ name ] -> [ name ] ->
( [ "Do not expose everything from module " ++ name ++ " using (..)" ], ctx ) ( [ "Do not expose everything from module " ++ name ++ " using (..)" ], ctx )