mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-11-27 12:08:51 +03:00
Move Direction to Lint.Rule
This commit is contained in:
parent
3e580eabc3
commit
b324066736
@ -1,43 +0,0 @@
|
|||||||
module Lint.Direction exposing (Direction(..))
|
|
||||||
|
|
||||||
{-| Represents whether a Node is being traversed before having seen it's children (`Enter`ing the Node), or after (`Exit`ing the Node).
|
|
||||||
|
|
||||||
|
|
||||||
# Definition
|
|
||||||
|
|
||||||
@docs Direction
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Represents whether a Node is being traversed before having seen it's children
|
|
||||||
(`Enter`ing the Node), or after (`Exit`ing the Node).
|
|
||||||
|
|
||||||
When visiting the AST, nodes are visited twice: once on `Enter`, before the
|
|
||||||
children of the node will be visited, and once on `Exit`, after the children of
|
|
||||||
the node have been visited.
|
|
||||||
|
|
||||||
In most cases, you'll only want to handle the `Enter` case, but in some cases,
|
|
||||||
you'll want to visit a `Node` after having seen it's children. For instance, if
|
|
||||||
you're trying to detect the unused variables defined inside of a `let in` expression,
|
|
||||||
you'll want to collect the declaration of variables, note which ones are used,
|
|
||||||
and at the end of the block, report the ones that weren't used.
|
|
||||||
|
|
||||||
expressionVisitor : Context -> Direction -> Node Expression -> ( List Error, Context )
|
|
||||||
expressionVisitor context direction node =
|
|
||||||
case ( direction, node ) of
|
|
||||||
( Direction.Enter, Expression.FunctionOrValue moduleName name ) ->
|
|
||||||
( [], markVariableAsUsed context name )
|
|
||||||
|
|
||||||
-- Find variables declared in `let in` expression
|
|
||||||
( Direction.Enter, LetExpression letBlock ) ->
|
|
||||||
( [], registerVariables context letBlock )
|
|
||||||
|
|
||||||
-- When exiting the `let in expression, report the variables that were not used.
|
|
||||||
( Direction.Exit, LetExpression _ ) ->
|
|
||||||
( unusedVariables context |> List.map createError, context )
|
|
||||||
|
|
||||||
-}
|
|
||||||
type Direction
|
|
||||||
= Enter
|
|
||||||
| Exit
|
|
@ -1,7 +1,6 @@
|
|||||||
module Lint.Internal.Accumulate exposing (accumulate, accumulateList)
|
module Lint.Internal.Accumulate exposing (accumulate, accumulateList)
|
||||||
|
|
||||||
import Elm.Syntax.Node exposing (Node)
|
import Elm.Syntax.Node exposing (Node)
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error exposing (Error)
|
import Lint.Error exposing (Error)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
module Lint.Internal.DeclarationVisitor exposing (visit)
|
|
||||||
|
|
||||||
import Elm.Syntax.Declaration exposing (Declaration(..))
|
|
||||||
import Elm.Syntax.Expression exposing (Expression)
|
|
||||||
import Elm.Syntax.Node as Node exposing (Node)
|
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error exposing (Error)
|
|
||||||
import Lint.Internal.Accumulate exposing (accumulate, accumulateList)
|
|
||||||
import Lint.Internal.ExpressionVisitor as ExpressionVisitor
|
|
||||||
|
|
||||||
|
|
||||||
visit :
|
|
||||||
(Node Declaration -> Direction -> context -> ( List Error, context ))
|
|
||||||
-> (Node Expression -> Direction -> context -> ( List Error, context ))
|
|
||||||
-> Node Declaration
|
|
||||||
-> context
|
|
||||||
-> ( List Error, context )
|
|
||||||
visit declarationVisitor expressionVisitor node context =
|
|
||||||
context
|
|
||||||
|> declarationVisitor node Direction.Enter
|
|
||||||
|> accumulateList (ExpressionVisitor.visit expressionVisitor) (expressionChildren node)
|
|
||||||
|> accumulate (declarationVisitor node Direction.Exit)
|
|
||||||
|
|
||||||
|
|
||||||
expressionChildren : Node Declaration -> List (Node Expression)
|
|
||||||
expressionChildren node =
|
|
||||||
case Node.value node of
|
|
||||||
FunctionDeclaration function ->
|
|
||||||
[ ExpressionVisitor.functionToExpression function ]
|
|
||||||
|
|
||||||
CustomTypeDeclaration _ ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
AliasDeclaration { typeAnnotation } ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
Destructuring pattern expr ->
|
|
||||||
[ expr ]
|
|
||||||
|
|
||||||
PortDeclaration _ ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
InfixDeclaration _ ->
|
|
||||||
[]
|
|
@ -1,117 +0,0 @@
|
|||||||
module Lint.Internal.ExpressionVisitor exposing (functionToExpression, visit)
|
|
||||||
|
|
||||||
import Elm.Syntax.Expression exposing (Expression(..), Function, LetDeclaration(..))
|
|
||||||
import Elm.Syntax.Infix exposing (InfixDirection(..))
|
|
||||||
import Elm.Syntax.Node as Node exposing (Node)
|
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error exposing (Error)
|
|
||||||
import Lint.Internal.Accumulate exposing (accumulate, accumulateList)
|
|
||||||
|
|
||||||
|
|
||||||
visit : (Node Expression -> Direction -> context -> ( List Error, context )) -> Node Expression -> context -> ( List Error, context )
|
|
||||||
visit visitor node context =
|
|
||||||
context
|
|
||||||
|> visitor node Direction.Enter
|
|
||||||
|> accumulateList (visit visitor) (children node)
|
|
||||||
|> accumulate (visitor node Direction.Exit)
|
|
||||||
|
|
||||||
|
|
||||||
children : Node Expression -> List (Node Expression)
|
|
||||||
children node =
|
|
||||||
case Node.value node of
|
|
||||||
Application expressions ->
|
|
||||||
expressions
|
|
||||||
|
|
||||||
Literal _ ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
Integer _ ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
Floatable _ ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
UnitExpr ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
ListExpr elements ->
|
|
||||||
elements
|
|
||||||
|
|
||||||
FunctionOrValue _ _ ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
RecordExpr fields ->
|
|
||||||
List.map (Node.value >> (\( name, expr ) -> expr)) fields
|
|
||||||
|
|
||||||
RecordUpdateExpression name setters ->
|
|
||||||
List.map (Node.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 Node.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 ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
|
|
||||||
functionToExpression : Function -> Node Expression
|
|
||||||
functionToExpression function =
|
|
||||||
Node.value function.declaration
|
|
||||||
|> .expression
|
|
@ -2,7 +2,7 @@ module Lint.Rule exposing
|
|||||||
( Rule, Schema
|
( Rule, Schema
|
||||||
, newSchema, fromSchema
|
, newSchema, fromSchema
|
||||||
, withSimpleModuleDefinitionVisitor, withSimpleImportVisitor, withSimpleDeclarationVisitor, withSimpleExpressionVisitor
|
, withSimpleModuleDefinitionVisitor, withSimpleImportVisitor, withSimpleDeclarationVisitor, withSimpleExpressionVisitor
|
||||||
, withInitialContext, withModuleDefinitionVisitor, withImportVisitor, withDeclarationVisitor, withExpressionVisitor, withFinalEvaluation
|
, withInitialContext, withModuleDefinitionVisitor, withImportVisitor, Direction(..), withDeclarationVisitor, withExpressionVisitor, withFinalEvaluation
|
||||||
, name, analyzer
|
, name, analyzer
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ TODO Explain that and why people need to look at the documentation for elm-synta
|
|||||||
|
|
||||||
@docs newSchema, fromSchema
|
@docs newSchema, fromSchema
|
||||||
@docs withSimpleModuleDefinitionVisitor, withSimpleImportVisitor, withSimpleDeclarationVisitor, withSimpleExpressionVisitor
|
@docs withSimpleModuleDefinitionVisitor, withSimpleImportVisitor, withSimpleDeclarationVisitor, withSimpleExpressionVisitor
|
||||||
@docs withInitialContext, withModuleDefinitionVisitor, withImportVisitor, withDeclarationVisitor, withExpressionVisitor, withFinalEvaluation
|
@docs withInitialContext, withModuleDefinitionVisitor, withImportVisitor, Direction, withDeclarationVisitor, withExpressionVisitor, withFinalEvaluation
|
||||||
|
|
||||||
|
|
||||||
# ACCESS
|
# ACCESS
|
||||||
@ -31,16 +31,15 @@ TODO Explain that and why people need to look at the documentation for elm-synta
|
|||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Elm.Syntax.Declaration exposing (Declaration)
|
import Elm.Syntax.Declaration exposing (Declaration(..))
|
||||||
import Elm.Syntax.Expression exposing (Expression)
|
import Elm.Syntax.Expression exposing (Expression(..), Function, LetDeclaration(..))
|
||||||
import Elm.Syntax.File exposing (File)
|
import Elm.Syntax.File exposing (File)
|
||||||
import Elm.Syntax.Import exposing (Import)
|
import Elm.Syntax.Import exposing (Import)
|
||||||
|
import Elm.Syntax.Infix exposing (InfixDirection(..))
|
||||||
import Elm.Syntax.Module exposing (Module)
|
import Elm.Syntax.Module exposing (Module)
|
||||||
import Elm.Syntax.Node exposing (Node)
|
import Elm.Syntax.Node as Node exposing (Node)
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error exposing (Error)
|
import Lint.Error exposing (Error)
|
||||||
import Lint.Internal.Accumulate exposing (accumulateList)
|
import Lint.Internal.Accumulate exposing (accumulate, accumulateList)
|
||||||
import Lint.Internal.DeclarationVisitor as DeclarationVisitor
|
|
||||||
|
|
||||||
|
|
||||||
{-| Represents a construct able to analyze a `File` and report unwanted patterns.
|
{-| Represents a construct able to analyze a `File` and report unwanted patterns.
|
||||||
@ -76,6 +75,38 @@ type Schema context
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| Represents whether a Node is being traversed before having seen it's children (`OnEnter`ing the Node), or after (`OnExit`ing the Node).
|
||||||
|
|
||||||
|
When visiting the AST, nodes are visited twice: once on `OnEnter`, before the
|
||||||
|
children of the node will be visited, and once on `OnExit`, after the children of
|
||||||
|
the node have been visited.
|
||||||
|
|
||||||
|
In most cases, you'll only want to handle the `OnEnter` case, but in some cases,
|
||||||
|
you'll want to visit a `Node` after having seen it's children. For instance, if
|
||||||
|
you're trying to detect the unused variables defined inside of a `let in` expression,
|
||||||
|
you'll want to collect the declaration of variables, note which ones are used,
|
||||||
|
and at the end of the block, report the ones that weren't used.
|
||||||
|
|
||||||
|
expressionVisitor : Context -> Direction -> Node Expression -> ( List Error, Context )
|
||||||
|
expressionVisitor context direction node =
|
||||||
|
case ( direction, node ) of
|
||||||
|
( Rule.OnEnter, Expression.FunctionOrValue moduleName name ) ->
|
||||||
|
( [], markVariableAsUsed context name )
|
||||||
|
|
||||||
|
-- Find variables declared in `let in` expression
|
||||||
|
( Rule.OnEnter, LetExpression letBlock ) ->
|
||||||
|
( [], registerVariables context letBlock )
|
||||||
|
|
||||||
|
-- When exiting the `let in expression, report the variables that were not used.
|
||||||
|
( Rule.OnExit, LetExpression _ ) ->
|
||||||
|
( unusedVariables context |> List.map createError, context )
|
||||||
|
|
||||||
|
-}
|
||||||
|
type Direction
|
||||||
|
= OnEnter
|
||||||
|
| OnExit
|
||||||
|
|
||||||
|
|
||||||
{-| Creates a new schema for a rule. Will require calling [`fromSchema`](#fromSchema)
|
{-| Creates a new schema for a rule. Will require calling [`fromSchema`](#fromSchema)
|
||||||
to create a usable [`Rule`](#Rule). Use "with\*" functions from this module, like
|
to create a usable [`Rule`](#Rule). Use "with\*" functions from this module, like
|
||||||
[`withSimpleExpressionVisitor`](#withSimpleExpressionVisitor) or [`withSimpleImportVisitor`](#withSimpleImportVisitor)
|
[`withSimpleExpressionVisitor`](#withSimpleExpressionVisitor) or [`withSimpleImportVisitor`](#withSimpleImportVisitor)
|
||||||
@ -130,7 +161,7 @@ fromSchema (Schema schema) =
|
|||||||
schema.initialContext
|
schema.initialContext
|
||||||
|> schema.moduleDefinitionVisitor file.moduleDefinition
|
|> schema.moduleDefinitionVisitor file.moduleDefinition
|
||||||
|> accumulateList schema.importVisitor file.imports
|
|> accumulateList schema.importVisitor file.imports
|
||||||
|> accumulateList (DeclarationVisitor.visit schema.declarationVisitor schema.expressionVisitor) file.declarations
|
|> accumulateList (visitDeclaration schema.declarationVisitor schema.expressionVisitor) file.declarations
|
||||||
|> makeFinalEvaluation schema.finalEvaluationFn
|
|> makeFinalEvaluation schema.finalEvaluationFn
|
||||||
|> List.reverse
|
|> List.reverse
|
||||||
}
|
}
|
||||||
@ -257,7 +288,7 @@ annotation.
|
|||||||
[]
|
[]
|
||||||
|
|
||||||
Note: `withSimpleDeclarationVisitor` is a simplified version of [`withDeclarationVisitor`](#withDeclarationVisitor),
|
Note: `withSimpleDeclarationVisitor` is a simplified version of [`withDeclarationVisitor`](#withDeclarationVisitor),
|
||||||
which isn't passed a `Direction` (it will only be called on `Direction.Enter`) and a `context` and doesn't return a context. You can use `withSimpleDeclarationVisitor` even if you use "non-simple with\*" functions.
|
which isn't passed a [`Direction`](#Direction) (it will only be called `OnEnter`ing the node) and a `context` and doesn't return a context. You can use `withSimpleDeclarationVisitor` even if you use "non-simple with\*" functions.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
withSimpleDeclarationVisitor : (Node Declaration -> List Error) -> Schema context -> Schema context
|
withSimpleDeclarationVisitor : (Node Declaration -> List Error) -> Schema context -> Schema context
|
||||||
@ -267,10 +298,10 @@ withSimpleDeclarationVisitor visitor (Schema schema) =
|
|||||||
| declarationVisitor =
|
| declarationVisitor =
|
||||||
\node direction context ->
|
\node direction context ->
|
||||||
case direction of
|
case direction of
|
||||||
Direction.Enter ->
|
OnEnter ->
|
||||||
( visitor node, context )
|
( visitor node, context )
|
||||||
|
|
||||||
Direction.Exit ->
|
OnExit ->
|
||||||
( [], context )
|
( [], context )
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +339,7 @@ The following example forbids using the Debug module.
|
|||||||
[]
|
[]
|
||||||
|
|
||||||
Note: `withSimpleExpressionVisitor` is a simplified version of [`withExpressionVisitor`](#withExpressionVisitor),
|
Note: `withSimpleExpressionVisitor` is a simplified version of [`withExpressionVisitor`](#withExpressionVisitor),
|
||||||
which isn't passed a `Direction` (it will only be called on `Direction.Enter`) and a `context` and doesn't return a context. You can use `withSimpleExpressionVisitor` even if you use "non-simple with\*" functions.
|
which isn't passed a [`Direction`](#Direction) (it will only be called `OnEnter`ing the node) and a `context` and doesn't return a context. You can use `withSimpleExpressionVisitor` even if you use "non-simple with\*" functions.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
withSimpleExpressionVisitor : (Node Expression -> List Error) -> Schema context -> Schema context
|
withSimpleExpressionVisitor : (Node Expression -> List Error) -> Schema context -> Schema context
|
||||||
@ -318,10 +349,10 @@ withSimpleExpressionVisitor visitor (Schema schema) =
|
|||||||
| expressionVisitor =
|
| expressionVisitor =
|
||||||
\node direction context ->
|
\node direction context ->
|
||||||
case direction of
|
case direction of
|
||||||
Direction.Enter ->
|
OnEnter ->
|
||||||
( visitor node, context )
|
( visitor node, context )
|
||||||
|
|
||||||
Direction.Exit ->
|
OnExit ->
|
||||||
( [], context )
|
( [], context )
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,9 +393,8 @@ module name is `Lint.Rule.NoSomethingElse`).
|
|||||||
import Elm.Syntax.Expression exposing (Expression(..))
|
import Elm.Syntax.Expression exposing (Expression(..))
|
||||||
import Elm.Syntax.Module as Module exposing (Module)
|
import Elm.Syntax.Module as Module exposing (Module)
|
||||||
import Elm.Syntax.Node as Node exposing (Node)
|
import Elm.Syntax.Node as Node exposing (Node)
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error as Error exposing (Error)
|
import Lint.Error as Error exposing (Error)
|
||||||
import Lint.Rule as Rule exposing (Rule)
|
import Lint.Rule as Rule exposing (Direction, Rule)
|
||||||
import List.Extra
|
import List.Extra
|
||||||
|
|
||||||
type alias Context =
|
type alias Context =
|
||||||
@ -394,7 +424,7 @@ module name is `Lint.Rule.NoSomethingElse`).
|
|||||||
expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )
|
expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )
|
||||||
expressionVisitor node direction context =
|
expressionVisitor node direction context =
|
||||||
case ( direction, Node.value node ) of
|
case ( direction, Node.value node ) of
|
||||||
( Direction.Enter, Application (function :: ruleNameNode :: _) ) ->
|
( Rule.OnEnter, Application (function :: ruleNameNode :: _) ) ->
|
||||||
case ( Node.value function, Node.value ruleNameNode ) of
|
case ( Node.value function, Node.value ruleNameNode ) of
|
||||||
( FunctionOrValue [ "Rule" ] "newSchema", Literal ruleName ) ->
|
( FunctionOrValue [ "Rule" ] "newSchema", Literal ruleName ) ->
|
||||||
if Just ruleName /= context then
|
if Just ruleName /= context then
|
||||||
@ -451,9 +481,8 @@ by a configuration which could look like `( Critical, NoDebugExceptInSomeModules
|
|||||||
import Elm.Syntax.Expression exposing (Expression(..))
|
import Elm.Syntax.Expression exposing (Expression(..))
|
||||||
import Elm.Syntax.Module as Module exposing (Module)
|
import Elm.Syntax.Module as Module exposing (Module)
|
||||||
import Elm.Syntax.Node as Node exposing (Node)
|
import Elm.Syntax.Node as Node exposing (Node)
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error as Error exposing (Error)
|
import Lint.Error as Error exposing (Error)
|
||||||
import Lint.Rule as Rule exposing (Rule)
|
import Lint.Rule as Rule exposing (Direction, Rule)
|
||||||
|
|
||||||
type Context
|
type Context
|
||||||
= DebugIsAllowed
|
= DebugIsAllowed
|
||||||
@ -479,10 +508,10 @@ by a configuration which could look like `( Critical, NoDebugExceptInSomeModules
|
|||||||
expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )
|
expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )
|
||||||
expressionVisitor node direction context =
|
expressionVisitor node direction context =
|
||||||
case ( direction, context ) of
|
case ( direction, context ) of
|
||||||
( Direction.Enter, DebugIsAllowed ) ->
|
( Rule.OnEnter, DebugIsAllowed ) ->
|
||||||
( [], context )
|
( [], context )
|
||||||
|
|
||||||
( Direction.Enter, DebugIsForbidden ) ->
|
( Rule.OnEnter, DebugIsForbidden ) ->
|
||||||
case Node.value node of
|
case Node.value node of
|
||||||
FunctionOrValue moduleName fnName ->
|
FunctionOrValue moduleName fnName ->
|
||||||
if List.member "Debug" moduleName then
|
if List.member "Debug" moduleName then
|
||||||
@ -582,9 +611,8 @@ annotation.
|
|||||||
import Elm.Syntax.Exposing as Exposing
|
import Elm.Syntax.Exposing as Exposing
|
||||||
import Elm.Syntax.Module as Module exposing (Module)
|
import Elm.Syntax.Module as Module exposing (Module)
|
||||||
import Elm.Syntax.Node as Node exposing (Node)
|
import Elm.Syntax.Node as Node exposing (Node)
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error as Error exposing (Error)
|
import Lint.Error as Error exposing (Error)
|
||||||
import Lint.Rule as Rule exposing (Rule)
|
import Lint.Rule as Rule exposing (Direction, Rule)
|
||||||
|
|
||||||
type ExposedFunctions
|
type ExposedFunctions
|
||||||
= All
|
= All
|
||||||
@ -619,7 +647,7 @@ annotation.
|
|||||||
declarationVisitor : Node Declaration -> Direction -> ExposedFunctions -> ( List Error, ExposedFunctions )
|
declarationVisitor : Node Declaration -> Direction -> ExposedFunctions -> ( List Error, ExposedFunctions )
|
||||||
declarationVisitor node direction context =
|
declarationVisitor node direction context =
|
||||||
case ( direction, Node.value node ) of
|
case ( direction, Node.value node ) of
|
||||||
( Direction.Enter, FunctionDeclaration { documentation, declaration } ) ->
|
( Rule.OnEnter, FunctionDeclaration { documentation, declaration } ) ->
|
||||||
let
|
let
|
||||||
functionName : String
|
functionName : String
|
||||||
functionName =
|
functionName =
|
||||||
@ -667,9 +695,8 @@ module Main exposing (Context(..), expressionVisitor, importVisitor, rule)
|
|||||||
import Elm.Syntax.Expression exposing (Expression(..))
|
import Elm.Syntax.Expression exposing (Expression(..))
|
||||||
import Elm.Syntax.Import exposing (Import)
|
import Elm.Syntax.Import exposing (Import)
|
||||||
import Elm.Syntax.Node as Node exposing (Node)
|
import Elm.Syntax.Node as Node exposing (Node)
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error as Error exposing (Error)
|
import Lint.Error as Error exposing (Error)
|
||||||
import Lint.Rule as Rule exposing (Rule)
|
import Lint.Rule as Rule exposing (Direction, Rule)
|
||||||
|
|
||||||
type Context
|
type Context
|
||||||
= DebugLogWasNotImported
|
= DebugLogWasNotImported
|
||||||
@ -717,7 +744,7 @@ module Main exposing (Context(..), expressionVisitor, importVisitor, rule)
|
|||||||
|
|
||||||
DebugLogWasImported ->
|
DebugLogWasImported ->
|
||||||
case ( direction, Node.value node ) of
|
case ( direction, Node.value node ) of
|
||||||
( Direction.Enter, FunctionOrValue [] "log" ) ->
|
( Rule.OnEnter, FunctionOrValue [] "log" ) ->
|
||||||
( [ Error.create "Forbidden use of Debug.log" (Node.range node) ], context )
|
( [ Error.create "Forbidden use of Debug.log" (Node.range node) ], context )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
@ -795,3 +822,151 @@ name (Rule rule) =
|
|||||||
analyzer : Rule -> (File -> List Error)
|
analyzer : Rule -> (File -> List Error)
|
||||||
analyzer (Rule rule) =
|
analyzer (Rule rule) =
|
||||||
rule.analyzer
|
rule.analyzer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- TREE TRAVERSAL
|
||||||
|
|
||||||
|
|
||||||
|
visitDeclaration :
|
||||||
|
(Node Declaration -> Direction -> context -> ( List Error, context ))
|
||||||
|
-> (Node Expression -> Direction -> context -> ( List Error, context ))
|
||||||
|
-> Node Declaration
|
||||||
|
-> context
|
||||||
|
-> ( List Error, context )
|
||||||
|
visitDeclaration declarationVisitor expressionVisitor node context =
|
||||||
|
context
|
||||||
|
|> declarationVisitor node OnEnter
|
||||||
|
|> accumulateList (visitExpression expressionVisitor) (expressionsInDeclaration node)
|
||||||
|
|> accumulate (declarationVisitor node OnExit)
|
||||||
|
|
||||||
|
|
||||||
|
expressionsInDeclaration : Node Declaration -> List (Node Expression)
|
||||||
|
expressionsInDeclaration node =
|
||||||
|
case Node.value node of
|
||||||
|
FunctionDeclaration function ->
|
||||||
|
[ functionToExpression function ]
|
||||||
|
|
||||||
|
CustomTypeDeclaration _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
AliasDeclaration { typeAnnotation } ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
Destructuring pattern expr ->
|
||||||
|
[ expr ]
|
||||||
|
|
||||||
|
PortDeclaration _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
InfixDeclaration _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
visitExpression : (Node Expression -> Direction -> context -> ( List Error, context )) -> Node Expression -> context -> ( List Error, context )
|
||||||
|
visitExpression visitor node context =
|
||||||
|
context
|
||||||
|
|> visitor node OnEnter
|
||||||
|
|> accumulateList (visitExpression visitor) (expressionChildren node)
|
||||||
|
|> accumulate (visitor node OnExit)
|
||||||
|
|
||||||
|
|
||||||
|
expressionChildren : Node Expression -> List (Node Expression)
|
||||||
|
expressionChildren node =
|
||||||
|
case Node.value node of
|
||||||
|
Application expressions ->
|
||||||
|
expressions
|
||||||
|
|
||||||
|
Literal _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
Integer _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
Floatable _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
UnitExpr ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
ListExpr elements ->
|
||||||
|
elements
|
||||||
|
|
||||||
|
FunctionOrValue _ _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
RecordExpr fields ->
|
||||||
|
List.map (Node.value >> (\( _, expr ) -> expr)) fields
|
||||||
|
|
||||||
|
RecordUpdateExpression _ setters ->
|
||||||
|
List.map (Node.value >> (\( field, expr ) -> expr)) setters
|
||||||
|
|
||||||
|
ParenthesizedExpression expr ->
|
||||||
|
[ expr ]
|
||||||
|
|
||||||
|
Operator _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
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 Node.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 _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
Hex _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
Negation expr ->
|
||||||
|
[ expr ]
|
||||||
|
|
||||||
|
CharLiteral _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
RecordAccess expr property ->
|
||||||
|
[ expr ]
|
||||||
|
|
||||||
|
RecordAccessFunction _ ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
GLSLExpression expr ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
||||||
|
functionToExpression : Function -> Node Expression
|
||||||
|
functionToExpression function =
|
||||||
|
Node.value function.declaration
|
||||||
|
|> .expression
|
||||||
|
@ -30,9 +30,8 @@ import Elm.Syntax.Module as Module exposing (Module(..))
|
|||||||
import Elm.Syntax.Node as Node exposing (Node)
|
import Elm.Syntax.Node as Node exposing (Node)
|
||||||
import Elm.Syntax.Range exposing (Range)
|
import Elm.Syntax.Range exposing (Range)
|
||||||
import Elm.Syntax.TypeAnnotation exposing (TypeAnnotation(..))
|
import Elm.Syntax.TypeAnnotation exposing (TypeAnnotation(..))
|
||||||
import Lint.Direction as Direction exposing (Direction)
|
|
||||||
import Lint.Error as Error exposing (Error)
|
import Lint.Error as Error exposing (Error)
|
||||||
import Lint.Rule as Rule exposing (Rule)
|
import Lint.Rule as Rule exposing (Direction, Rule)
|
||||||
import List.Nonempty as Nonempty exposing (Nonempty)
|
import List.Nonempty as Nonempty exposing (Nonempty)
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
|
|
||||||
@ -223,19 +222,19 @@ importVisitor node context =
|
|||||||
expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )
|
expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )
|
||||||
expressionVisitor node direction context =
|
expressionVisitor node direction context =
|
||||||
case ( direction, Node.value node ) of
|
case ( direction, Node.value node ) of
|
||||||
( Direction.Enter, FunctionOrValue [] name ) ->
|
( Rule.OnEnter, FunctionOrValue [] name ) ->
|
||||||
( [], markAsUsed name context )
|
( [], markAsUsed name context )
|
||||||
|
|
||||||
( Direction.Enter, FunctionOrValue moduleName name ) ->
|
( Rule.OnEnter, FunctionOrValue moduleName name ) ->
|
||||||
( [], markAsUsed (getModuleName moduleName) context )
|
( [], markAsUsed (getModuleName moduleName) context )
|
||||||
|
|
||||||
( Direction.Enter, OperatorApplication name _ _ _ ) ->
|
( Rule.OnEnter, OperatorApplication name _ _ _ ) ->
|
||||||
( [], markAsUsed name context )
|
( [], markAsUsed name context )
|
||||||
|
|
||||||
( Direction.Enter, PrefixOperator name ) ->
|
( Rule.OnEnter, PrefixOperator name ) ->
|
||||||
( [], markAsUsed name context )
|
( [], markAsUsed name context )
|
||||||
|
|
||||||
( Direction.Enter, LetExpression { declarations } ) ->
|
( Rule.OnEnter, LetExpression { declarations } ) ->
|
||||||
let
|
let
|
||||||
newContext =
|
newContext =
|
||||||
List.foldl
|
List.foldl
|
||||||
@ -252,7 +251,7 @@ expressionVisitor node direction context =
|
|||||||
in
|
in
|
||||||
( [], newContext )
|
( [], newContext )
|
||||||
|
|
||||||
( Direction.Exit, LetExpression _ ) ->
|
( Rule.OnExit, LetExpression _ ) ->
|
||||||
let
|
let
|
||||||
( errors, remainingUsed ) =
|
( errors, remainingUsed ) =
|
||||||
makeReport (Nonempty.head context.scopes)
|
makeReport (Nonempty.head context.scopes)
|
||||||
@ -271,7 +270,7 @@ expressionVisitor node direction context =
|
|||||||
declarationVisitor : Node Declaration -> Direction -> Context -> ( List Error, Context )
|
declarationVisitor : Node Declaration -> Direction -> Context -> ( List Error, Context )
|
||||||
declarationVisitor node direction context =
|
declarationVisitor node direction context =
|
||||||
case ( direction, Node.value node ) of
|
case ( direction, Node.value node ) of
|
||||||
( Direction.Enter, FunctionDeclaration function ) ->
|
( Rule.OnEnter, FunctionDeclaration function ) ->
|
||||||
let
|
let
|
||||||
declaration =
|
declaration =
|
||||||
Node.value function.declaration
|
Node.value function.declaration
|
||||||
@ -288,26 +287,26 @@ declarationVisitor node direction context =
|
|||||||
in
|
in
|
||||||
( [], newContext )
|
( [], newContext )
|
||||||
|
|
||||||
( Direction.Enter, CustomTypeDeclaration { name } ) ->
|
( Rule.OnEnter, CustomTypeDeclaration { name } ) ->
|
||||||
( [], register Type (Node.range name) (Node.value name) context )
|
( [], register Type (Node.range name) (Node.value name) context )
|
||||||
|
|
||||||
( Direction.Enter, AliasDeclaration { name } ) ->
|
( Rule.OnEnter, AliasDeclaration { name } ) ->
|
||||||
( [], register Type (Node.range name) (Node.value name) context )
|
( [], register Type (Node.range name) (Node.value name) context )
|
||||||
|
|
||||||
( Direction.Enter, PortDeclaration { name, typeAnnotation } ) ->
|
( Rule.OnEnter, PortDeclaration { name, typeAnnotation } ) ->
|
||||||
( []
|
( []
|
||||||
, context
|
, context
|
||||||
|> markAllAsUsed (collectNamesFromTypeAnnotation typeAnnotation)
|
|> markAllAsUsed (collectNamesFromTypeAnnotation typeAnnotation)
|
||||||
|> register Port (Node.range name) (Node.value name)
|
|> register Port (Node.range name) (Node.value name)
|
||||||
)
|
)
|
||||||
|
|
||||||
( Direction.Enter, InfixDeclaration _ ) ->
|
( Rule.OnEnter, InfixDeclaration _ ) ->
|
||||||
( [], context )
|
( [], context )
|
||||||
|
|
||||||
( Direction.Enter, Destructuring _ _ ) ->
|
( Rule.OnEnter, Destructuring _ _ ) ->
|
||||||
( [], context )
|
( [], context )
|
||||||
|
|
||||||
( Direction.Exit, _ ) ->
|
( Rule.OnExit, _ ) ->
|
||||||
( [], context )
|
( [], context )
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user