Add new visitors for let declarations and case branches

This commit is contained in:
Jeroen Engels 2021-10-23 19:41:10 +02:00
parent 0285ed2447
commit aba58c7763
2 changed files with 326 additions and 28 deletions

File diff suppressed because one or more lines are too long

View File

@ -8,6 +8,8 @@ module Review.Rule exposing
, withImportVisitor , withImportVisitor
, Direction(..), withDeclarationEnterVisitor, withDeclarationExitVisitor, withDeclarationVisitor, withDeclarationListVisitor , Direction(..), withDeclarationEnterVisitor, withDeclarationExitVisitor, withDeclarationVisitor, withDeclarationListVisitor
, withExpressionEnterVisitor, withExpressionExitVisitor, withExpressionVisitor , withExpressionEnterVisitor, withExpressionExitVisitor, withExpressionVisitor
, withCaseBranchEnterVisitor, withCaseBranchExitVisitor
, withLetDeclarationEnterVisitor, withLetDeclarationExitVisitor
, withFinalModuleEvaluation , withFinalModuleEvaluation
, withElmJsonModuleVisitor, withReadmeModuleVisitor, withDependenciesModuleVisitor , withElmJsonModuleVisitor, withReadmeModuleVisitor, withDependenciesModuleVisitor
, ProjectRuleSchema, newProjectRuleSchema, fromProjectRuleSchema, withModuleVisitor, withModuleContext, withModuleContextUsingContextCreator, withElmJsonProjectVisitor, withReadmeProjectVisitor, withDependenciesProjectVisitor, withFinalProjectEvaluation, withContextFromImportedModules , ProjectRuleSchema, newProjectRuleSchema, fromProjectRuleSchema, withModuleVisitor, withModuleContext, withModuleContextUsingContextCreator, withElmJsonProjectVisitor, withReadmeProjectVisitor, withDependenciesProjectVisitor, withFinalProjectEvaluation, withContextFromImportedModules
@ -192,6 +194,8 @@ Evaluating/visiting a node means two things:
@docs withImportVisitor @docs withImportVisitor
@docs Direction, withDeclarationEnterVisitor, withDeclarationExitVisitor, withDeclarationVisitor, withDeclarationListVisitor @docs Direction, withDeclarationEnterVisitor, withDeclarationExitVisitor, withDeclarationVisitor, withDeclarationListVisitor
@docs withExpressionEnterVisitor, withExpressionExitVisitor, withExpressionVisitor @docs withExpressionEnterVisitor, withExpressionExitVisitor, withExpressionVisitor
@docs withCaseBranchEnterVisitor, withCaseBranchExitVisitor
@docs withLetDeclarationEnterVisitor, withLetDeclarationExitVisitor
@docs withFinalModuleEvaluation @docs withFinalModuleEvaluation
@ -334,6 +338,10 @@ type ModuleRuleSchema schemaState moduleContext
, declarationVisitorsOnExit : List (Visitor Declaration moduleContext) , declarationVisitorsOnExit : List (Visitor Declaration moduleContext)
, expressionVisitorsOnEnter : List (Visitor Expression moduleContext) , expressionVisitorsOnEnter : List (Visitor Expression moduleContext)
, expressionVisitorsOnExit : List (Visitor Expression moduleContext) , expressionVisitorsOnExit : List (Visitor Expression moduleContext)
, letDeclarationVisitorsOnEnter : List (Node Expression.LetBlock -> Node Expression.LetDeclaration -> moduleContext -> ( List (Error {}), moduleContext ))
, letDeclarationVisitorsOnExit : List (Node Expression.LetBlock -> Node Expression.LetDeclaration -> moduleContext -> ( List (Error {}), moduleContext ))
, caseBranchVisitorsOnEnter : List (Node Expression.CaseBlock -> ( Node Pattern, Node Expression ) -> moduleContext -> ( List (Error {}), moduleContext ))
, caseBranchVisitorsOnExit : List (Node Expression.CaseBlock -> ( Node Pattern, Node Expression ) -> moduleContext -> ( List (Error {}), moduleContext ))
, finalEvaluationFns : List (moduleContext -> List (Error {})) , finalEvaluationFns : List (moduleContext -> List (Error {}))
-- Project visitors -- Project visitors
@ -956,6 +964,10 @@ newModuleRuleSchema name initialModuleContext =
, declarationVisitorsOnExit = [] , declarationVisitorsOnExit = []
, expressionVisitorsOnEnter = [] , expressionVisitorsOnEnter = []
, expressionVisitorsOnExit = [] , expressionVisitorsOnExit = []
, letDeclarationVisitorsOnEnter = []
, letDeclarationVisitorsOnExit = []
, caseBranchVisitorsOnEnter = []
, caseBranchVisitorsOnExit = []
, finalEvaluationFns = [] , finalEvaluationFns = []
, elmJsonVisitors = [] , elmJsonVisitors = []
, readmeVisitors = [] , readmeVisitors = []
@ -1016,6 +1028,10 @@ newModuleRuleSchemaUsingContextCreator name moduleContextCreator =
, declarationVisitorsOnExit = [] , declarationVisitorsOnExit = []
, expressionVisitorsOnEnter = [] , expressionVisitorsOnEnter = []
, expressionVisitorsOnExit = [] , expressionVisitorsOnExit = []
, letDeclarationVisitorsOnEnter = []
, letDeclarationVisitorsOnExit = []
, caseBranchVisitorsOnEnter = []
, caseBranchVisitorsOnExit = []
, finalEvaluationFns = [] , finalEvaluationFns = []
, elmJsonVisitors = [] , elmJsonVisitors = []
, readmeVisitors = [] , readmeVisitors = []
@ -1273,6 +1289,10 @@ mergeModuleVisitors initialProjectContext maybeModuleContextCreator visitors =
, declarationVisitorsOnExit = [] , declarationVisitorsOnExit = []
, expressionVisitorsOnEnter = [] , expressionVisitorsOnEnter = []
, expressionVisitorsOnExit = [] , expressionVisitorsOnExit = []
, letDeclarationVisitorsOnEnter = []
, letDeclarationVisitorsOnExit = []
, caseBranchVisitorsOnEnter = []
, caseBranchVisitorsOnExit = []
, finalEvaluationFns = [] , finalEvaluationFns = []
, elmJsonVisitors = [] , elmJsonVisitors = []
, readmeVisitors = [] , readmeVisitors = []
@ -1301,6 +1321,10 @@ fromModuleRuleSchemaToRunnableModuleVisitor (ModuleRuleSchema schema) =
, declarationVisitorsOnExit = schema.declarationVisitorsOnExit , declarationVisitorsOnExit = schema.declarationVisitorsOnExit
, expressionVisitorsOnEnter = List.reverse schema.expressionVisitorsOnEnter , expressionVisitorsOnEnter = List.reverse schema.expressionVisitorsOnEnter
, expressionVisitorsOnExit = schema.expressionVisitorsOnExit , expressionVisitorsOnExit = schema.expressionVisitorsOnExit
, letDeclarationVisitorsOnEnter = List.reverse schema.letDeclarationVisitorsOnEnter
, letDeclarationVisitorsOnExit = schema.letDeclarationVisitorsOnExit
, caseBranchVisitorsOnEnter = List.reverse schema.caseBranchVisitorsOnEnter
, caseBranchVisitorsOnExit = schema.caseBranchVisitorsOnExit
, finalEvaluationFns = List.reverse schema.finalEvaluationFns , finalEvaluationFns = List.reverse schema.finalEvaluationFns
} }
@ -2838,6 +2862,207 @@ withExpressionExitVisitor visitor (ModuleRuleSchema schema) =
ModuleRuleSchema { schema | expressionVisitorsOnExit = visitor :: schema.expressionVisitorsOnExit } ModuleRuleSchema { schema | expressionVisitorsOnExit = visitor :: schema.expressionVisitorsOnExit }
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) which will visit the module's
case branches when entering the branch.
The visitor can be very useful if you need to change the context when inside a case branch.
The visitors would be called in the following order (ignore the expression visitor if you don't have one):
x =
case evaluated of
Pattern1 ->
expression1
Pattern2 ->
expression2
1. Expression visitor (enter) for the entire case expression.
2. Expression visitor (enter then exit) for `evaluated`
3. Case branch visitor (enter) for `( Pattern1, expression1 )`
4. Expression visitor (enter then exit) for `expression1`
5. Case branch visitor (exit) for `( Pattern1, expression1 )`
6. Case branch visitor (enter) for `( Pattern2, expression2 )`
7. Expression visitor (enter then exit) for `expression2`
8. Case branch visitor (exit) for `( Pattern2, expression2 )`
9. Expression visitor (exit) for the entire case expression.
You can use [`withCaseBranchExitVisitor`](#withCaseBranchExitVisitor) to visit the node on exit.
import Elm.Syntax.Expression as Expression exposing (Expression)
import Elm.Syntax.Node as Node exposing (Node)
import Elm.Syntax.Pattern exposing (Pattern)
import Review.Rule as Rule exposing (Rule)
rule : Rule
rule =
Rule.newModuleRuleSchema "NoUnusedCaseVariables" ( [], [] )
|> Rule.withExpressionEnterVisitor expressionVisitor
|> Rule.withCaseBranchEnterVisitor caseBranchEnterVisitor
|> Rule.withCaseBranchExitVisitor caseBranchExitVisitor
|> Rule.fromModuleRuleSchema
type alias Context =
( List String, List (List String) )
expressionVisitor : Node Expression -> Context -> ( List (Rule.Error {}), Context )
expressionVisitor node (( scope, parentScopes ) as context) =
case context of
Expression.FunctionOrValue [] name ->
( [], ( name :: used, parentScopes ) )
_ ->
( [], context )
caseBranchEnterVisitor : Node Expression.LetBlock -> ( Node Pattern, Node Expression ) -> Context -> List ( Rule.Error {}, Context )
caseBranchEnterVisitor _ _ ( scope, parentScopes ) =
-- Entering a new scope every time we enter a new branch
( [], ( [], scope :: parentScopes ) )
caseBranchExitVisitor : Node Expression.LetBlock -> ( Node Pattern, Node Expression ) -> Context -> List ( Rule.Error {}, Context )
caseBranchExitVisitor _ ( pattern, _ ) ( scope, parentScopes ) =
-- Exiting the current scope every time we enter a new branch, and reporting the patterns that weren't used
let
namesFromPattern =
findNamesFromPattern pattern
( unusedPatterns, unmatchedUsed ) =
findUnused namesFromPattern scope
newScopes =
case parentScopes of
head :: tail ->
( unmatchedUsed ++ head, tail )
[] ->
( unmatched, [] )
in
( List.map errorForUnused unusedPatterns, newScopes )
For convenience, the entire case expression is passed as the first argument.
-}
withCaseBranchEnterVisitor : (Node Expression.CaseBlock -> ( Node Pattern, Node Expression ) -> moduleContext -> ( List (Error {}), moduleContext )) -> ModuleRuleSchema schemaState moduleContext -> ModuleRuleSchema { schemaState | hasAtLeastOneVisitor : () } moduleContext
withCaseBranchEnterVisitor visitor (ModuleRuleSchema schema) =
ModuleRuleSchema { schema | caseBranchVisitorsOnEnter = visitor :: schema.caseBranchVisitorsOnEnter }
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) which will visit the module's
case branches when exiting the branch.
See the documentation for [`withCaseBranchEnterVisitor`](#withCaseBranchEnterVisitor) for explanations and an example.
-}
withCaseBranchExitVisitor : (Node Expression.CaseBlock -> ( Node Pattern, Node Expression ) -> moduleContext -> ( List (Error {}), moduleContext )) -> ModuleRuleSchema schemaState moduleContext -> ModuleRuleSchema { schemaState | hasAtLeastOneVisitor : () } moduleContext
withCaseBranchExitVisitor visitor (ModuleRuleSchema schema) =
ModuleRuleSchema { schema | caseBranchVisitorsOnExit = visitor :: schema.caseBranchVisitorsOnExit }
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) which will visit the module's
let declarations branches when entering the declaration.
The visitor can be very useful if you need to change the context when inside a let declaration.
The visitors would be called in the following order (ignore the expression visitor if you don't have one):
x =
let
declaration1 =
expression1
declaration2 =
expression2
in
letInValue
1. Expression visitor (enter) for the entire let expression.
2. Let declaration visitor (enter) for `( declaration1, expression1 )`
3. Expression visitor (enter then exit) for `expression1`
4. Let declaration visitor (exit) for `( declaration1, expression1 )`
5. Let declaration visitor (enter) for `( declaration2, expression2 )`
6. Expression visitor (enter then exit) for `expression2`
7. Let declaration visitor (exit) for `( declaration2, expression2 )`
8. Expression visitor (enter then exit) for `letInValue`
9. Expression visitor (exit) for the entire let expression.
You can use [`withLetDeclarationExitVisitor`](#withLetDeclarationExitVisitor) to visit the node on exit.
import Elm.Syntax.Expression as Expression exposing (Expression)
import Elm.Syntax.Node as Node exposing (Node)
import Review.Rule as Rule exposing (Rule)
rule : Rule
rule =
Rule.newModuleRuleSchema "NoUnusedLetFunctionParameters" ( [], [] )
|> Rule.withExpressionEnterVisitor expressionVisitor
|> Rule.withLetDeclarationEnterVisitor letDeclarationEnterVisitor
|> Rule.withLetDeclarationExitVisitor letDeclarationExitVisitor
|> Rule.fromModuleRuleSchema
type alias Context =
( List String, List (List String) )
expressionVisitor : Node Expression -> Context -> ( List (Rule.Error {}), Context )
expressionVisitor node (( scope, parentScopes ) as context) =
case context of
Expression.FunctionOrValue [] name ->
( [], ( name :: used, parentScopes ) )
_ ->
( [], context )
letDeclarationEnterVisitor : Node Expression.LetBlock -> Node Expression.LetDeclaration -> Context -> List ( Rule.Error {}, Context )
letDeclarationEnterVisitor _ letDeclaration (( scope, parentScopes ) as context) =
case Node.value letDeclaration of
Expression.LetFunction _ ->
( [], ( [], scope :: parentScopes ) )
Expression.LetDestructuring _ ->
( [], context )
letDeclarationExitVisitor : Node Expression.LetBlock -> Node Expression.LetDeclaration -> Context -> List ( Rule.Error {}, Context )
letDeclarationExitVisitor _ letDeclaration (( scope, parentScopes ) as context) =
case Node.value letDeclaration of
Expression.LetFunction _ ->
let
namesFromPattern =
findNamesFromArguments letFunction
( unusedArguments, unmatchedUsed ) =
findUnused namesFromPattern scope
newScopes =
case parentScopes of
head :: tail ->
( unmatchedUsed ++ head, tail )
[] ->
( unmatched, [] )
in
( List.map errorForUnused unusedArguments, newScopes )
Expression.LetDestructuring _ ->
( [], context )
For convenience, the entire let expression is passed as the first argument.
-}
withLetDeclarationEnterVisitor : (Node Expression.LetBlock -> Node Expression.LetDeclaration -> moduleContext -> ( List (Error {}), moduleContext )) -> ModuleRuleSchema schemaState moduleContext -> ModuleRuleSchema { schemaState | hasAtLeastOneVisitor : () } moduleContext
withLetDeclarationEnterVisitor visitor (ModuleRuleSchema schema) =
ModuleRuleSchema { schema | letDeclarationVisitorsOnEnter = visitor :: schema.letDeclarationVisitorsOnEnter }
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) which will visit the module's
let declarations branches when entering the declaration.
See the documentation for [`withLetDeclarationEnterVisitor`](#withLetDeclarationEnterVisitor) for explanations and an example.
-}
withLetDeclarationExitVisitor : (Node Expression.LetBlock -> Node Expression.LetDeclaration -> moduleContext -> ( List (Error {}), moduleContext )) -> ModuleRuleSchema schemaState moduleContext -> ModuleRuleSchema { schemaState | hasAtLeastOneVisitor : () } moduleContext
withLetDeclarationExitVisitor visitor (ModuleRuleSchema schema) =
ModuleRuleSchema { schema | letDeclarationVisitorsOnExit = visitor :: schema.letDeclarationVisitorsOnExit }
{-| Add a function that makes a final evaluation of the module based only on the {-| Add a function that makes a final evaluation of the module based only on the
data that was collected in the `moduleContext`. This can be useful if you can't or if data that was collected in the `moduleContext`. This can be useful if you can't or if
it is hard to determine something as you traverse the module. it is hard to determine something as you traverse the module.
@ -3550,6 +3775,10 @@ type alias RunnableModuleVisitor moduleContext =
, declarationVisitorsOnExit : List (Visitor Declaration moduleContext) , declarationVisitorsOnExit : List (Visitor Declaration moduleContext)
, expressionVisitorsOnEnter : List (Visitor Expression moduleContext) , expressionVisitorsOnEnter : List (Visitor Expression moduleContext)
, expressionVisitorsOnExit : List (Visitor Expression moduleContext) , expressionVisitorsOnExit : List (Visitor Expression moduleContext)
, letDeclarationVisitorsOnEnter : List (Node Expression.LetBlock -> Node Expression.LetDeclaration -> moduleContext -> ( List (Error {}), moduleContext ))
, letDeclarationVisitorsOnExit : List (Node Expression.LetBlock -> Node Expression.LetDeclaration -> moduleContext -> ( List (Error {}), moduleContext ))
, caseBranchVisitorsOnEnter : List (Node Expression.CaseBlock -> ( Node Pattern, Node Expression ) -> moduleContext -> ( List (Error {}), moduleContext ))
, caseBranchVisitorsOnExit : List (Node Expression.CaseBlock -> ( Node Pattern, Node Expression ) -> moduleContext -> ( List (Error {}), moduleContext ))
, finalEvaluationFns : List (moduleContext -> List (Error {})) , finalEvaluationFns : List (moduleContext -> List (Error {}))
} }
@ -4111,13 +4340,28 @@ visitModuleForProjectRule schema initialContext module_ =
(visitDeclaration (visitDeclaration
schema.declarationVisitorsOnEnter schema.declarationVisitorsOnEnter
schema.declarationVisitorsOnExit schema.declarationVisitorsOnExit
schema.expressionVisitorsOnEnter { expressionVisitorsOnEnter = schema.expressionVisitorsOnEnter
schema.expressionVisitorsOnExit , expressionVisitorsOnExit = schema.expressionVisitorsOnExit
, letDeclarationVisitorsOnEnter = schema.letDeclarationVisitorsOnEnter
, letDeclarationVisitorsOnExit = schema.letDeclarationVisitorsOnExit
, caseBranchVisitorsOnEnter = schema.caseBranchVisitorsOnEnter
, caseBranchVisitorsOnExit = schema.caseBranchVisitorsOnExit
}
) )
module_.ast.declarations module_.ast.declarations
|> (\( errors, moduleContext ) -> ( makeFinalEvaluation schema.finalEvaluationFns ( errors, moduleContext ), moduleContext )) |> (\( errors, moduleContext ) -> ( makeFinalEvaluation schema.finalEvaluationFns ( errors, moduleContext ), moduleContext ))
type alias ExpressionRelatedVisitors moduleContext =
{ expressionVisitorsOnEnter : List (Visitor Expression moduleContext)
, expressionVisitorsOnExit : List (Visitor Expression moduleContext)
, letDeclarationVisitorsOnEnter : List (Node Expression.LetBlock -> Node Expression.LetDeclaration -> moduleContext -> ( List (Error {}), moduleContext ))
, letDeclarationVisitorsOnExit : List (Node Expression.LetBlock -> Node Expression.LetDeclaration -> moduleContext -> ( List (Error {}), moduleContext ))
, caseBranchVisitorsOnEnter : List (Node Expression.CaseBlock -> ( Node Pattern, Node Expression ) -> moduleContext -> ( List (Error {}), moduleContext ))
, caseBranchVisitorsOnExit : List (Node Expression.CaseBlock -> ( Node Pattern, Node Expression ) -> moduleContext -> ( List (Error {}), moduleContext ))
}
extractSourceCode : List String -> Range -> String extractSourceCode : List String -> Range -> String
extractSourceCode lines range = extractSourceCode lines range =
lines lines
@ -4144,37 +4388,87 @@ visitImport :
-> moduleContext -> moduleContext
-> ( List (Error {}), moduleContext ) -> ( List (Error {}), moduleContext )
visitImport importVisitors node moduleContext = visitImport importVisitors node moduleContext =
visitNodeWithListOfVisitors importVisitors node ( [], moduleContext ) visitWithListOfVisitors importVisitors node ( [], moduleContext )
visitDeclaration : visitDeclaration :
List (Visitor Declaration moduleContext) List (Visitor Declaration moduleContext)
-> List (Visitor Declaration moduleContext) -> List (Visitor Declaration moduleContext)
-> List (Visitor Expression moduleContext) -> ExpressionRelatedVisitors moduleContext
-> List (Visitor Expression moduleContext)
-> Node Declaration -> Node Declaration
-> moduleContext -> moduleContext
-> ( List (Error {}), moduleContext ) -> ( List (Error {}), moduleContext )
visitDeclaration declarationVisitorsOnEnter declarationVisitorsOnExit expressionVisitorsOnEnter expressionVisitorsOnExit node moduleContext = visitDeclaration declarationVisitorsOnEnter declarationVisitorsOnExit expressionRelatedVisitors node moduleContext =
( [], moduleContext ) ( [], moduleContext )
|> visitNodeWithListOfVisitors declarationVisitorsOnEnter node |> visitWithListOfVisitors declarationVisitorsOnEnter node
|> accumulateList (visitExpression expressionVisitorsOnEnter expressionVisitorsOnExit) (expressionsInDeclaration node) |> accumulateList (visitExpression expressionRelatedVisitors) (expressionsInDeclaration node)
|> visitNodeWithListOfVisitors declarationVisitorsOnExit node |> visitWithListOfVisitors declarationVisitorsOnExit node
visitExpression : visitExpression :
List (Visitor Expression moduleContext) ExpressionRelatedVisitors moduleContext
-> List (Visitor Expression moduleContext)
-> Node Expression -> Node Expression
-> moduleContext -> moduleContext
-> ( List (Error {}), moduleContext ) -> ( List (Error {}), moduleContext )
visitExpression onEnter onExit node moduleContext = visitExpression expressionRelatedVisitors node moduleContext =
-- IGNORE TCO -- IGNORE TCO
-- Is there a way to make this function TCO? -- Is there a way to make this function TCO?
case Node.value node of
Expression.LetExpression letBlock ->
( [], moduleContext )
|> visitWithListOfVisitors expressionRelatedVisitors.expressionVisitorsOnEnter node
|> accumulateList (visitLetDeclaration expressionRelatedVisitors (Node (Node.range node) letBlock)) letBlock.declarations
|> accumulate (visitExpression expressionRelatedVisitors letBlock.expression)
|> visitWithListOfVisitors expressionRelatedVisitors.expressionVisitorsOnExit node
Expression.CaseExpression caseBlock ->
( [], moduleContext )
|> visitWithListOfVisitors expressionRelatedVisitors.expressionVisitorsOnEnter node
|> accumulate (visitExpression expressionRelatedVisitors caseBlock.expression)
|> accumulateList (visitCaseBranch expressionRelatedVisitors (Node (Node.range node) caseBlock)) caseBlock.cases
|> visitWithListOfVisitors expressionRelatedVisitors.expressionVisitorsOnExit node
_ ->
( [], moduleContext )
|> visitWithListOfVisitors expressionRelatedVisitors.expressionVisitorsOnEnter node
|> accumulateList (visitExpression expressionRelatedVisitors) (expressionChildren node)
|> visitWithListOfVisitors expressionRelatedVisitors.expressionVisitorsOnExit node
visitLetDeclaration :
ExpressionRelatedVisitors moduleContext
-> Node Expression.LetBlock
-> Node Expression.LetDeclaration
-> moduleContext
-> ( List (Error {}), moduleContext )
visitLetDeclaration expressionRelatedVisitors letBlockWithRange ((Node _ letDeclaration) as letDeclarationWithRange) moduleContext =
let
expressionNode : Node Expression
expressionNode =
case letDeclaration of
Expression.LetFunction function ->
functionToExpression function
Expression.LetDestructuring _ expr ->
expr
in
( [], moduleContext ) ( [], moduleContext )
|> visitNodeWithListOfVisitors onEnter node |> visitWithListOfVisitors2 expressionRelatedVisitors.letDeclarationVisitorsOnEnter letBlockWithRange letDeclarationWithRange
|> accumulateList (visitExpression onEnter onExit) (expressionChildren node) |> accumulate (visitExpression expressionRelatedVisitors expressionNode)
|> visitNodeWithListOfVisitors onExit node |> visitWithListOfVisitors2 expressionRelatedVisitors.letDeclarationVisitorsOnExit letBlockWithRange letDeclarationWithRange
visitCaseBranch :
ExpressionRelatedVisitors moduleContext
-> Node Expression.CaseBlock
-> ( Node Pattern, Node Expression )
-> moduleContext
-> ( List (Error {}), moduleContext )
visitCaseBranch expressionRelatedVisitors caseBlockWithRange (( _, caseExpression ) as caseBranch) moduleContext =
( [], moduleContext )
|> visitWithListOfVisitors2 expressionRelatedVisitors.caseBranchVisitorsOnEnter caseBlockWithRange caseBranch
|> accumulate (visitExpression expressionRelatedVisitors caseExpression)
|> visitWithListOfVisitors2 expressionRelatedVisitors.caseBranchVisitorsOnExit caseBlockWithRange caseBranch
{-| Concatenate the errors of the previous step and of the last step. {-| Concatenate the errors of the previous step and of the last step.
@ -4306,14 +4600,18 @@ expressionsInDeclaration node =
[] []
visitNodeWithListOfVisitors : visitWithListOfVisitors : List (a -> context -> ( List (Error {}), context )) -> a -> ( List (Error {}), context ) -> ( List (Error {}), context )
List (Visitor nodeType moduleContext) visitWithListOfVisitors visitors a initialErrorsAndContext =
-> Node nodeType
-> ( List (Error {}), moduleContext )
-> ( List (Error {}), moduleContext )
visitNodeWithListOfVisitors visitors node initialErrorsAndContext =
List.foldl List.foldl
(\visitor -> accumulate (visitor node)) (\visitor -> accumulate (visitor a))
initialErrorsAndContext
visitors
visitWithListOfVisitors2 : List (a -> b -> context -> ( List (Error {}), context )) -> a -> b -> ( List (Error {}), context ) -> ( List (Error {}), context )
visitWithListOfVisitors2 visitors a b initialErrorsAndContext =
List.foldl
(\visitor -> accumulate (visitor a b))
initialErrorsAndContext initialErrorsAndContext
visitors visitors
@ -4381,12 +4679,12 @@ accumulateWithListOfVisitors visitors element initialErrorsAndContext =
visitors visitors
accumulateList : (Node a -> context -> ( List (Error {}), context )) -> List (Node a) -> ( List (Error {}), context ) -> ( List (Error {}), context ) accumulateList : (a -> context -> ( List (Error {}), context )) -> List a -> ( List (Error {}), context ) -> ( List (Error {}), context )
accumulateList visitor nodes initialErrorsAndContext = accumulateList visitor elements initialErrorsAndContext =
List.foldl List.foldl
(\node -> accumulate (visitor node)) (\element -> accumulate (visitor element))
initialErrorsAndContext initialErrorsAndContext
nodes elements
{-| Concatenate the errors of the previous step and of the last step, and take the last step's context. {-| Concatenate the errors of the previous step and of the last step, and take the last step's context.
@ -5579,7 +5877,7 @@ scope_popScopeExit node context =
scope_expressionEnterVisitor : Node Expression -> ScopeModuleContext -> ScopeModuleContext scope_expressionEnterVisitor : Node Expression -> ScopeModuleContext -> ScopeModuleContext
scope_expressionEnterVisitor node context = scope_expressionEnterVisitor node context =
case Node.value node of case Node.value node of
Expression.LetExpression { declarations, expression } -> Expression.LetExpression { declarations } ->
let let
newContext : ScopeModuleContext newContext : ScopeModuleContext
newContext = newContext =