diff --git a/Lint.elm b/Lint.elm index 98c09550..89e4f4e1 100644 --- a/Lint.elm +++ b/Lint.elm @@ -1,7 +1,14 @@ -module Lint exposing (lint, LintRule, Error, doNothing) +module Lint + exposing + ( lint + , LintRule + , Error + , doNothing + ) import Ast.Expression exposing (..) import Ast.Statement exposing (..) +import Node exposing (..) type alias Error = @@ -9,7 +16,7 @@ type alias Error = type alias LintImplementation nodeType context = - context -> nodeType -> ( List Error, context ) + context -> Direction nodeType -> ( List Error, context ) type alias LintRule context = @@ -29,17 +36,21 @@ doNothing 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 = rule.expressionFn context node -typeVisitor : Type -> Visitor context -typeVisitor node rule context = - rule.typeFn context node - - -statementVisitor : Statement -> Visitor context +statementVisitor : Direction Statement -> Visitor context statementVisitor node rule context = rule.statementFn context node @@ -47,24 +58,24 @@ statementVisitor node rule context = expressionToVisitors : Expression -> List (Visitor context) expressionToVisitors node = let - visitAndTransformChildren children = - List.concat - [ [ expressionVisitor node ] - , List.concatMap expressionToVisitors children - ] + children = + case node of + Application expression1 expression2 -> + [ expression1, expression2 ] + + Access expression names -> + [ expression ] + + Variable _ -> + [] + + _ -> + [] + + childrenVisitors = + List.concatMap expressionToVisitors children in - case node of - Application expression1 expression2 -> - visitAndTransformChildren [ expression1, expression2 ] - - Access expression names -> - visitAndTransformChildren [ expression ] - - Variable _ -> - [ expressionVisitor node ] - - _ -> - [] + createExitAndEnterWithChildren expressionVisitor node childrenVisitors 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 node = let - visitAndTransformChildren expressions types = - List.concat - [ [ statementVisitor node ] - , List.concatMap expressionToVisitors expressions - , List.concatMap typeToVisitors types - ] + childrenVisitors = + case node of + FunctionTypeDeclaration name application -> + statementChildrenToVisitors [] [ application ] + + FunctionDeclaration name params body -> + statementChildrenToVisitors [ body ] [] + + ModuleDeclaration name exportSet -> + statementChildrenToVisitors [] [] + + _ -> + [] in - case node of - FunctionTypeDeclaration name application -> - visitAndTransformChildren [] [ application ] - - FunctionDeclaration name params body -> - visitAndTransformChildren [ body ] [] - - ModuleDeclaration name exportSet -> - visitAndTransformChildren [] [] - - _ -> - [] + createExitAndEnterWithChildren statementVisitor node childrenVisitors visitAndAccumulate : LintRule context -> Visitor context -> ( List Error, context ) -> ( List Error, context ) diff --git a/Node.elm b/Node.elm new file mode 100644 index 00000000..23158623 --- /dev/null +++ b/Node.elm @@ -0,0 +1,6 @@ +module Node exposing (..) + + +type Direction node + = Enter node + | Exit node diff --git a/rules/FindNoAnnotatedFunction.elm b/rules/FindNoAnnotatedFunction.elm index 2b950d55..b5006c97 100644 --- a/rules/FindNoAnnotatedFunction.elm +++ b/rules/FindNoAnnotatedFunction.elm @@ -1,6 +1,7 @@ module FindNoAnnotatedFunction exposing (rule) import Lint exposing (LintRule, Error, doNothing) +import Node 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 = case node of - FunctionTypeDeclaration name application -> + Enter (FunctionTypeDeclaration name application) -> ( [], { ctx | annotatedFunctions = name :: ctx.annotatedFunctions } ) - FunctionDeclaration name params body -> + Enter (FunctionDeclaration name params body) -> if List.member name ctx.annotatedFunctions then ( [], ctx ) else diff --git a/rules/NoDebug.elm b/rules/NoDebug.elm index 4b167928..e60e5e61 100644 --- a/rules/NoDebug.elm +++ b/rules/NoDebug.elm @@ -1,6 +1,7 @@ module NoDebug exposing (rule) import Lint exposing (LintRule, Error, doNothing) +import Node 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 = case node of - Variable vars -> + Enter (Variable vars) -> if List.member "Debug" vars then ( [ "Forbidden use of Debug" ], ctx ) else diff --git a/rules/NoExposingEverything.elm b/rules/NoExposingEverything.elm index e2e858bf..ef89f25c 100644 --- a/rules/NoExposingEverything.elm +++ b/rules/NoExposingEverything.elm @@ -1,6 +1,7 @@ module NoExposingEverything exposing (rule) import Lint exposing (LintRule, Error, doNothing) +import Node 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 = case node of - ModuleDeclaration names AllExport -> + Enter (ModuleDeclaration names AllExport) -> case names of [ name ] -> ( [ "Do not expose everything from module " ++ name ++ " using (..)" ], ctx )