[{"name":"Review","comment":" Module to configure your review configuration and run it on a source file.\n\n\n# Reviewing\n\n@docs review\n\n\n# Errors\n\n@docs Error, errorModuleName, errorRuleName, errorMessage, errorDetails, errorRange, errorFixes\n\n","unions":[{"name":"Error","comment":" Represents an error in a file found by a rule.\n\nNote: This should not be confused with `Error` from the `Review.Rule` module.\n`Review.Error` is created from `Review.Rule.Error` but contains additional information\nlike the name of the rule that emitted it and the file name.\n\n","args":[],"cases":[]}],"aliases":[],"values":[{"name":"errorDetails","comment":" Get the details of an error.\n","type":"Review.Error -> List.List String.String"},{"name":"errorFixes","comment":" Get the fixes for an error.\n","type":"Review.Error -> Maybe.Maybe (List.List Review.Fix.Fix)"},{"name":"errorMessage","comment":" Get the message of an error.\n","type":"Review.Error -> String.String"},{"name":"errorModuleName","comment":" Get the name of the module for which the error occurred.\n","type":"Review.Error -> Maybe.Maybe String.String"},{"name":"errorRange","comment":" Get the range of an error.\n","type":"Review.Error -> Elm.Syntax.Range.Range"},{"name":"errorRuleName","comment":" Get the name of the rule of an error.\n","type":"Review.Error -> String.String"},{"name":"review","comment":" Review a file and gives back the errors raised by the given rules.\n\n    config : List Rule\n    config =\n        [ Some.Rule.rule\n        , Some.Other.Rule.rule\n        ]\n\n    project : Project\n    project =\n        Project.new\n\n    errors : List Error\n    errors =\n        review config project sourceCode\n\n","type":"List.List Review.Rule.Rule -> Review.Project.Project -> { path : String.String, source : String.String } -> List.List Review.Error"}],"binops":[]},{"name":"Review.Fix","comment":" Tools to write automatic error fixes.\n\nWhen creating a [`Review.Rule.Error`](./Review-Rule#Error), you can provide an automatic\nfix for the error using [`Review.Rule.withFixes`](./Review-Rule#withFixes) so that the\nuser doesn't need to fix the problem themselves.\n\nIn the [CLI](https://github.com/jfmengels/node-elm-review), the user can ask to\nfix the errors automatically, and in doing so, they will be presented by a fix\nwhich they can accept or refuse. If the fix gets refused, then the next fixable\nerror will be presented. Otherwise, if the fix gets accepted, the file will be\napplied and the fixed file content get analyzed again by the different rules in\nthe user's configuration, and then another fix will be presented. When there are\nno more fixable errors, the remaining errors will be reported, just like when\nthe user doesn't request errors to be automatically fixed.\n\nIn summary, errors will be presented one by one and the user will validate them.\n\n\n# Guidelines\n\nAn automatic fix, when applied, should resolve the reported error completely.\nThis means that when the automatic fix is applied, the user should not have to\nthink about the error anymore or have to do additional work. Imagine if the user\napplies a lot of automatic fixes all at once, we don't want them to have to\nremember having to do something, otherwise we may have just offloaded a lot of\nwork that they may forget to do. In that case, it is better not to provide a fix\nat all, so that they keep a reminder and the details of how to fix the problem.\n\nAn automatic fix should resolve only the reported error, not try to fix other\npotential errors. By only fixing one error at a time, the fix will be easier for\nthe user to digest and understand. The file will be re-reviewed when the fix is\napplied, and then another error can fix that one.\n\n\n# When (not) to provide an automatic fix?\n\nFor users, having an automatic fix always feels like a nice-to-have and they may\nrequest you to provide some, but they are not mandatory, and in some cases, it\nis better not to have any.\n\n\n## Reasons not to provide an automatic fix\n\n\n### A complete automatic fix is not possible\n\nSometimes, just by going through the whole file, you are missing some of the\ninformation needed to generate the right fix. Instead of providing a partial or\npotentially incorrect fix, it would be better to provide more details, hints or\nsuggestions.\n\n\n### The fix would result in a compiler error\n\nAn automatic fix should not cause changes that would break the file or the\nproject. In some cases, we can detect that the [fix will break things](#Problem),\nlike if the result of the fix is invalid Elm code (as in resulting in a parsing\nerror), but ultimately we can't detect that the project will still compile after\nthe fix is applied.\n\nUsers are notified that an automatic fix is available. For performance reasons,\nwe only check that a fix is valid before presenting it to the user and ignore it\nif it turns out to be invalid. This means that the user will be disappointed or\nconfused when the error ends up not being enforced. The only way we have to\nprevent this is to write tests, as fixes are applied in tests.\n\n\n### The user should learn about problem and how to solve it\n\nSometimes problems are learning opportunities, and it is worth having the user\nspend some time reading through the details of the error and trying several\nalternatives in order to understand the problem and the tradeoffs of the\nsolutions. Do try to guide them by having great error details though!\n\n\n## Reasons to provide an automatic fix\n\nThe reasons to provide an automatic fix are basically the opposite of the\nreasons not to provide an automatic fix:\n\n  - We know how to fix the problem completely and accurately\n  - The task is menial and the user will not learn anything by fixing the error\n    themselves\n\n\n# Strategies for writing automatic fixes effectively\n\n\n### Write a lot of tests\n\nAutomatic fixes are more error-prone than rules, especially since we may work\nwith re-writing ports of the code, for which the AST does not provide the\ncurrent formatting of a file (there is no information about spacing,\nline-breaks, ...). I suggest writing a lot of tests, and especially write tests\nwhere the formatting of the original file is a bit odd, as you may for instance\nunknowingly attempt to delete characters next to the thing you wanted to remove.\n\n\n### Store ranges in the context if necessary\n\nFixes work with ranges or position. If the context of a different element is not\navailable in the scope of where you create the error, then you should store it\nin the context of your rule.\n\n\n# Definition\n\n@docs Fix\n\n\n# Constructors\n\n@docs removeRange, replaceRangeBy, insertAt\n\n\n# Applying fixes\n\n@docs FixResult, Problem, fix\n\n","unions":[{"name":"Fix","comment":" Represents (part of a) fix that will be applied to a file's source code in order to\nautomatically fix a review error.\n","args":[],"cases":[]},{"name":"FixResult","comment":" Represents the result of having applied a list of fixes to a source code.\n","args":[],"cases":[["Successful",["String.String"]],["Errored",["Review.Fix.Problem"]]]},{"name":"Problem","comment":" Represents a problem that may have occurred when attempting to apply a list\nof fixes.\n","args":[],"cases":[["Unchanged",[]],["SourceCodeIsNotValid",["String.String"]],["HasCollisionsInFixRanges",[]]]}],"aliases":[],"values":[{"name":"fix","comment":" Apply the changes on the source code.\n","type":"List.List Review.Fix.Fix -> String.String -> Review.Fix.FixResult"},{"name":"insertAt","comment":" Insert some code at the given position.\n","type":"{ row : Basics.Int, column : Basics.Int } -> String.String -> Review.Fix.Fix"},{"name":"removeRange","comment":" Remove the code in between a range.\n","type":"Elm.Syntax.Range.Range -> Review.Fix.Fix"},{"name":"replaceRangeBy","comment":" Replace the code in between a range by some other code.\n","type":"Elm.Syntax.Range.Range -> String.String -> Review.Fix.Fix"}],"binops":[]},{"name":"Review.Project","comment":" Represents project-related data, that a rule can access to get more information.\n\nThese will be accessible in rules with functions like [`Review.Rule.withElmJsonVisitor`](./Review-Rule#withElmJsonVisitor).\nThis module is made to build all of the project-related data that we want\nrules to have access to, to later pass it to the [`Review.review`](./Review#review) function.\n\n\n# Definition\n\n@docs Project, ElmJson\n\n\n# Access\n\n@docs elmJson\n\n\n# Build\n\n@docs new, withElmJson\n\n","unions":[{"name":"Project","comment":" Represents all kinds of details about the project, such as the contents of\nthe `elm.json` file.\n","args":[],"cases":[]}],"aliases":[{"name":"ElmJson","comment":" Contents of the `elm.json` file. Alias to\n[`elm/project-metadata-utils`'s Project data structure](https://package.elm-lang.org/packages/elm/project-metadata-utils/latest/Elm-Project).\n","args":[],"type":"Elm.Project.Project"}],"values":[{"name":"elmJson","comment":" Get the contents of the `elm.json` file, if available.\n\nThis will give you a `Project` type from the\n[`elm/project-metadata-utils`](https://package.elm-lang.org/packages/elm/project-metadata-utils/1.0.0/Elm-Project)\npackage, so you will need to install and use it to gain access to the\ninformation inside the `elm.json` file.\n\n","type":"Review.Project.Project -> Maybe.Maybe Review.Project.ElmJson"},{"name":"new","comment":" Create a new Project.\n","type":"Review.Project.Project"},{"name":"withElmJson","comment":" Add the contents of the `elm.json` file to the project details.\n","type":"Review.Project.ElmJson -> Review.Project.Project -> Review.Project.Project"}],"binops":[]},{"name":"Review.Rule","comment":" This module contains functions that are used for writing rules.\n\n\n# How does it work?\n\n`elm-review` turns the code of the analyzed file into an [Abstract Syntax Tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree)\n(a tree-like structure which represents your source code) using the\n[`elm-syntax` package](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/).\nThen, for each file and rule, it will give the details of your project (like the `elm.json` file) and the\ncontents of the file to analyze to the rule. The order in which things get passed to the rule is the following:\n\n  - Read project-related info (only collect data in these steps)\n      - The `elm.json` file, visited by [`withElmJsonVisitor`](#withElmJsonVisitor)\n  - Visit the file (in the following order)\n      - The module definition, visited by [`withSimpleModuleDefinitionVisitor`](#withSimpleModuleDefinitionVisitor) and [`withModuleDefinitionVisitor`](#withModuleDefinitionVisitor)\n      - Each import, visited by [`withSimpleImportVisitor`](#withSimpleImportVisitor) and [`withImportVisitor`](#withImportVisitor)\n      - The list of declarations, visited by [`withDeclarationListVisitor`](#withDeclarationListVisitor).\n      - Each declaration, visited by [`withSimpleDeclarationVisitor`](#withSimpleDeclarationVisitor) and [`withDeclarationVisitor`](#withDeclarationVisitor).\n        Before evaluating the next declaration, the expression contained in the declaration\n        will be visited recursively using by [`withSimpleExpressionVisitor`](#withSimpleExpressionVisitor) and [`withExpressionVisitor`](#withExpressionVisitor)\n      - A final evaluation is made when the whole AST has been traversed, using [`withFinalEvaluation`](#withFinalEvaluation)\n\nEvaluating a node means two things:\n\n  - Detecting patterns and reporting errors\n  - Collecting data in a `context` to have more information available in a later\n    node evaluation. This is only available using \"non-simple with\\*\" visitors.\n    I recommend using the \"simple with\\*\" visitors if you don't need to collect\n    data, as they are simpler to use\n\n`elm-review` relies on the [`elm-syntax`package](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/),\nand all the node types you'll see will be coming from there. You are likely to\nneed to have the documentation for that package open when writing a rule.\n\nThere are plenty of examples in the documentation for each visitor function,\nand you can also look at the source code for existing rules to better grasp how\nrules work.\n\n\n# What makes a good rule\n\nApart from the rationale on [whether a rule should be written](./#when-to-write-or-enable-a-rule),\nhere are a few tips on what makes a rule helpful.\n\nA review rule is an automated communication tool which sends messages to\ndevelopers who have written patterns your rule wishes to prevent. As all\ncommunication, the message is important.\n\n\n## A good rule name\n\nThe name of the rule (`NoUnusedVariables`, `NoDebug`, ...) should try to convey\nreally quickly what kind of pattern we're dealing with. Ideally, a user who\nencounters this pattern for the first time could guess the problem just from the\nname. And a user who encountered it several times should know how to fix the\nproblem just from the name too.\n\nI recommend having the name of the file containing the rule be the same as the\nrule name. This will make it easier to find the module in the project or on\nthe packages website when trying to get more information.\n\n\n## A helpful error message and details\n\nThe error message should give more information about the problem. It is split\ninto two parts:\n\n  - The `message`: A short sentence that describes the forbidden pattern. A user\n    that has encountered this error multiple times should know exactly what to do.\n    Example: \"Function `foo` is never used\". With this information, a user who\n    knows the rule probably knows that a function needs to be removed from the\n    source code, and also knows which one.\n  - The `details`: All the additional information that can be useful to the\n    user, such as the rationale behind forbidding the pattern, and suggestions\n    for a solution or alternative.\n\nWhen writing the error message that the user will see, try to make them be as\nhelpful as the messages the compiler gives you when it encounters a problem.\n\n\n## The smallest section of code that makes sense\n\nWhen creating an error, you need to specify under which section of the code this\nmessage appears. This is where you would see squiggly lines in your editor when\nyou have review or compiler errors.\n\nTo make the error easier to spot, it is best to make this section as small as\npossible, as long as that makes sense. For instance, in a rule that would forbid\n`Debug.log`, you would the error to appear under `Debug.log`, not on the whole\nfunction which contains this piece of code.\n\n\n## Good rule documentation\n\nThe rule documentation should give the same information as what you would see in\nthe error message.\n\nIf published in a package, the rule documentation should explain when not to\nenable the rule in the user's review configuration. For instance, for a rule that\nmakes sure that a package is publishable by ensuring that all docs are valid,\nthe rule might say something along the lines of \"If you are writing an\napplication, then you should not use this rule.\".\n\nAdditionally, it could give a few examples of patterns that will be reported and\nof patterns that will not be reported, so that users can have a better grasp of\nwhat to expect.\n\n\n# Strategies for writing rules effectively\n\n\n## Use Test-Driven Development\n\nThis package comes with [`Review.Test`](./Review-Test), which works with [`elm-test`](https://github.com/elm-explorations/test).\nI recommend reading through [`the strategies for effective testing`](./Review-Test#strategies-for-effective-testing) before\nstarting writing a rule.\n\n\n## Look at the documentation for [`elm-syntax`](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/)\n\n`elm-review` is heavily dependent on the types that [`elm-syntax`](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/)\nprovides. If you don't understand the AST it provides, you will have a hard time\nimplementing the rule you wish to create.\n\n\n# Writing a Rule\n\n**NOTE**: There are a lot of rule examples in the documentation of the functions\nbelow. They are only here to showcase how to write rules and how a function can\nbe used. The rule examples are not necessarily good rules to enforce. See the\n[section on whether to write a rule](./#when-to-write-or-enable-a-rule) for more on that. Even if you think\nthey are good ideas to enforce, they are often not complete, as there are other\npatterns you would want to forbid, but that are not handled by the example.\n\n\n## Definition\n\n@docs Rule, Schema\n\n\n## Creating a Rule\n\n@docs newSchema, fromSchema\n\n\n## Builder functions without context\n\n@docs withSimpleModuleDefinitionVisitor, withSimpleImportVisitor, withSimpleDeclarationVisitor, withSimpleExpressionVisitor\n\n\n## Builder functions with context\n\n@docs withInitialContext, withModuleDefinitionVisitor, withImportVisitor, Direction, withDeclarationVisitor, withDeclarationListVisitor, withExpressionVisitor, withFinalEvaluation\n\n\n## Builder functions to analyze the project's data\n\n@docs withElmJsonVisitor\n\n\n## Automatic fixing\n\nFor more information on automatic fixing, read the documentation for [`Review.Fix`](./Review-Fix).\n\n@docs withFixes\n\n\n## Errors\n\n@docs Error, error, errorMessage, errorDetails, errorRange, errorFixes\n\n\n# ACCESS\n\n@docs name, analyzer\n\n","unions":[{"name":"Direction","comment":" Represents whether a Node is being traversed before having seen its children (`OnEnter`ing the Node), or after (`OnExit`ing the Node).\n\nWhen visiting the AST, nodes are visited twice: once on `OnEnter`, before the\nchildren of the node will be visited, and once on `OnExit`, after the children of\nthe node have been visited.\n\nIn most cases, you'll only want to handle the `OnEnter` case, but in some cases,\nyou'll want to visit a `Node` after having seen its children. For instance, if\nyou're trying to detect the unused variables defined inside of a `let in` expression,\nyou'll want to collect the declaration of variables, note which ones are used,\nand at the end of the block, report the ones that weren't used.\n\n    expressionVisitor : Context -> Direction -> Node Expression -> ( List Error, Context )\n    expressionVisitor context direction node =\n        case ( direction, node ) of\n            ( Rule.OnEnter, Expression.FunctionOrValue moduleName name ) ->\n                ( [], markVariableAsUsed context name )\n\n            -- Find variables declared in `let in` expression\n            ( Rule.OnEnter, LetExpression letBlock ) ->\n                ( [], registerVariables context letBlock )\n\n            -- When exiting the `let in expression, report the variables that were not used.\n            ( Rule.OnExit, LetExpression _ ) ->\n                ( unusedVariables context |> List.map createError, context )\n\n","args":[],"cases":[["OnEnter",[]],["OnExit",[]]]},{"name":"Error","comment":" Represents an error found by a [`Rule`](#Rule).\n\nNote: This should not be confused with [`Review.Error`](./Review#Error) from the\n[`Review`](./Review) module. [`Review.Error`](./Review#Error) is created from\nthis module's [`Error`](#Error) but contains additional information like the\nname of the rule that emitted it and the file name.\n\n","args":[],"cases":[]},{"name":"Rule","comment":" Represents a construct able to analyze a `File` and report unwanted patterns.\nSee [`newSchema`](#newSchema), and [`fromSchema`](#fromSchema) for how to create one.\n","args":[],"cases":[]},{"name":"Schema","comment":" Represents a Schema for a [`Rule`](#Rule). Create one using [`newSchema`](#newSchema).\n\n    import Review.Rule as Rule exposing (Rule)\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoDebug\"\n            |> Rule.withSimpleExpressionVisitor expressionVisitor\n            |> Rule.fromSchema\n\n","args":["configurationState","context"],"cases":[]}],"aliases":[],"values":[{"name":"analyzer","comment":" Get the analyzer function of a [`Rule`](#Rule).\n","type":"Review.Rule.Rule -> Review.Project.Project -> Elm.Syntax.File.File -> List.List Review.Rule.Error"},{"name":"error","comment":" Creates an [`Error`](#Error). Use it when you find a pattern that the rule should forbid.\nIt takes the [message you want to display to the user](#a-helpful-error-message-and-details), and a [`Range`](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.1.0/Elm-Syntax-Range),\nwhich is the location where the error should be shown (under which to put the squiggly lines in an editor).\nIn most cases, you can get it using [`Node.range`](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.1.0/Elm-Syntax-Node#range).\n\nThe `details` is a list of strings, and each item will be visually separated\nwhen shown to the user. The details may not be empty, and this will be enforced\nby the tests automatically.\n\n    error : Node a -> Error\n    error node =\n        Rule.error\n            { message = \"Remove the use of `Debug` before shipping to production\"\n            , details = [ \"The `Debug` module is useful when developing, but is not meant to be shipped to production or published in a package. I suggest removing its use before committing and attempting to push to production.\" ]\n            }\n            (Node.range node)\n\n","type":"{ message : String.String, details : List.List String.String } -> Elm.Syntax.Range.Range -> Review.Rule.Error"},{"name":"errorDetails","comment":" Get the error details of an [`Error`](#Error).\n","type":"Review.Rule.Error -> List.List String.String"},{"name":"errorFixes","comment":" Get the [`Range`](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.1.0/Elm-Syntax-Range)\nof an [`Error`](#Error).\n","type":"Review.Rule.Error -> Maybe.Maybe (List.List Review.Fix.Fix)"},{"name":"errorMessage","comment":" Get the error message of an [`Error`](#Error).\n","type":"Review.Rule.Error -> String.String"},{"name":"errorRange","comment":" Get the [`Range`](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.1.0/Elm-Syntax-Range)\nof an [`Error`](#Error).\n","type":"Review.Rule.Error -> Elm.Syntax.Range.Range"},{"name":"fromSchema","comment":" Create a [`Rule`](#Rule) from a configured [`Schema`](#Schema).\n","type":"Review.Rule.Schema { hasAtLeastOneVisitor : () } context -> Review.Rule.Rule"},{"name":"name","comment":" Get the name of a [`Rule`](#Rule).\n","type":"Review.Rule.Rule -> String.String"},{"name":"newSchema","comment":" Creates a new schema for a rule. Will require calling [`fromSchema`](#fromSchema)\nto create a usable [`Rule`](#Rule). Use \"with\\*\" functions from this module, like\n[`withSimpleExpressionVisitor`](#withSimpleExpressionVisitor) or [`withSimpleImportVisitor`](#withSimpleImportVisitor)\nto make it report something.\n\n    import Review.Rule as Rule exposing (Rule)\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoDebug\"\n            |> Rule.withSimpleExpressionVisitor expressionVisitor\n            |> Rule.withSimpleImportVisitor importVisitor\n            |> Rule.fromSchema\n\nIf you wish to build a [`Rule`](#Rule) that collects data as the file gets traversed,\ntake a look at [`withInitialContext`](#withInitialContext) and \"with\\*\" functions without\n\"Simple\" in their name, like [`withExpressionVisitor`](#withExpressionVisitor),\n[`withImportVisitor`](#withImportVisitor) or [`withFinalEvaluation`](#withFinalEvaluation).\n\n    import Review.Rule as Rule exposing (Rule)\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoUnusedVariables\"\n            |> Rule.withInitialContext { declaredVariables = [], usedVariables = [] }\n            |> Rule.withExpressionVisitor expressionVisitor\n            |> Rule.withImportVisitor importVisitor\n            |> Rule.fromSchema\n\n","type":"String.String -> Review.Rule.Schema { hasNoVisitor : () } ()"},{"name":"withDeclarationListVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s\n[declaration statements](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Declaration)\n(`someVar = add 1 2`, `type Bool = True | False`, `port output : Json.Encode.Value -> Cmd msg`),\ncollect data and/or report patterns.\n\nIt is similar to [withDeclarationVisitor](#withDeclarationVisitor), but the\nvisitor used with this function is called before the visitor added with\n[withDeclarationVisitor](#withDeclarationVisitor). You can use this visitor in\norder to look ahead and add the file's types and variables into your context,\nbefore visiting the contents of the file using [withDeclarationVisitor](#withDeclarationVisitor)\nand [withExpressionVisitor](#withExpressionVisitor). Otherwise, using\n[withDeclarationVisitor](#withDeclarationVisitor) is probably a simpler choice.\n\n","type":"(List.List (Elm.Syntax.Node.Node Elm.Syntax.Declaration.Declaration) -> context -> ( List.List Review.Rule.Error, context )) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withDeclarationVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s\n[declaration statements](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Declaration)\n(`someVar = add 1 2`, `type Bool = True | False`, `port output : Json.Encode.Value -> Cmd msg`),\ncollect data and/or report patterns. The declarations will be visited in the order of their definition.\n\nThe following example forbids exposing a function or a value without it having a\ntype annotation.\n\n    import Elm.Syntax.Declaration exposing (Declaration(..))\n    import Elm.Syntax.Exposing as Exposing\n    import Elm.Syntax.Module as Module exposing (Module)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Direction, Error, Rule)\n\n    type ExposedFunctions\n        = All\n        | OnlySome (List String)\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoMissingDocumentationForExposedFunctions\"\n            |> Rule.withInitialContext (OnlySome [])\n            |> Rule.withModuleDefinitionVisitor moduleDefinitionVisitor\n            |> Rule.withDeclarationVisitor declarationVisitor\n            |> Rule.fromSchema\n\n    moduleDefinitionVisitor : Node Module -> ExposedFunctions -> ( List Error, ExposedFunctions )\n    moduleDefinitionVisitor node context =\n        case Node.value node |> Module.exposingList of\n            Exposing.All _ ->\n                ( [], All )\n\n            Exposing.Explicit exposedValues ->\n                ( [], OnlySome (List.filterMap exposedFunctionName exposedValues) )\n\n    exposedFunctionName : Node Exposing.TopLevelExpose -> Maybe String\n    exposedFunctionName value =\n        case Node.value value of\n            Exposing.FunctionExpose functionName ->\n                Just functionName\n\n            _ ->\n                Nothing\n\n    declarationVisitor : Node Declaration -> Direction -> ExposedFunctions -> ( List Error, ExposedFunctions )\n    declarationVisitor node direction context =\n        case ( direction, Node.value node ) of\n            ( Rule.OnEnter, FunctionDeclaration { documentation, declaration } ) ->\n                let\n                    functionName : String\n                    functionName =\n                        Node.value declaration |> .name |> Node.value\n                in\n                if documentation == Nothing && isExposed context functionName then\n                    ( [ Rule.error\n                            { message = \"Exposed function \" ++ functionName ++ \" is missing a type annotation\"\n                            , details =\n                                [ \"Type annotations are very helpful for people who use the module. It can give a lot of information without having to read the contents of the function.\"\n                                , \"To add a type annotation, add a line like `\" functionName ++ \" : ()`, and replace the `()` by the type of the function. If you don't replace `()`, the compiler should give you a suggestion of what the type should be.\"\n                                ]\n                            }\n                            (Node.range node)\n                      ]\n                    , context\n                    )\n\n                else\n                    ( [], context )\n\n            _ ->\n                ( [], context )\n\n    isExposed : ExposedFunctions -> String -> Bool\n    isExposed exposedFunctions name =\n        case exposedFunctions of\n            All ->\n                True\n\n            OnlySome exposedList ->\n                List.member name exposedList\n\nTip: If you do not need to collect or use the `context` in this visitor, you may wish to use the\nsimpler [`withSimpleDeclarationVisitor`](#withSimpleDeclarationVisitor) function.\n\n","type":"(Elm.Syntax.Node.Node Elm.Syntax.Declaration.Declaration -> Review.Rule.Direction -> context -> ( List.List Review.Rule.Error, context )) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withElmJsonVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the project's\n[`elm.json`](https://package.elm-lang.org/packages/elm/project-metadata-utils/latest/Elm-Project) file.\ninformation, such as the contents of the `elm.json` file, to collect data (`module SomeModuleName exposing (a, b)`), collect data in the `context` and/or report patterns.\n\nThe following example forbids exposing a file in an \"Internal\" directory in your `elm.json` file.\n\n    import Elm.Module\n    import Elm.Project\n    import Elm.Syntax.Module as Module exposing (Module)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Error, Rule)\n\n    type alias Context =\n        Maybe Elm.Project.Project\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"DoNoExposeInternalModules\"\n            |> Rule.withInitialContext Nothing\n            |> Rule.withElmJsonVisitor elmJsonVisitor\n            |> Rule.withModuleDefinitionVisitor moduleDefinitionVisitor\n            |> Rule.fromSchema\n\n    elmJsonVisitor : Maybe Elm.Project.Project -> Context -> Context\n    elmJsonVisitor elmJson context =\n        elmJson\n\n    moduleDefinitionVisitor : Node Module -> Context -> ( List Error, Context )\n    moduleDefinitionVisitor node context =\n        let\n            moduleName : List String\n            moduleName =\n                Node.value node |> Module.moduleName\n        in\n        if List.member \"Internal\" moduleName then\n            case context of\n                Just (Elm.Project.Package { exposed }) ->\n                    let\n                        exposedModules : List String\n                        exposedModules =\n                            case exposed of\n                                Elm.Project.ExposedList names ->\n                                    names\n                                        |> List.map Elm.Module.toString\n\n                                Elm.Project.ExposedDict fakeDict ->\n                                    fakeDict\n                                        |> List.concatMap Tuple.second\n                                        |> List.map Elm.Module.toString\n                    in\n                    if List.member (String.join \".\" moduleName) exposedModules then\n                        ( [ Rule.error \"Do not expose modules in `Internal` as part of the public API\" (Node.range node) ], context )\n\n                    else\n                        ( [], context )\n\n                _ ->\n                    ( [], context )\n\n        else\n            ( [], context )\n\n","type":"(Maybe.Maybe Elm.Project.Project -> context -> context) -> Review.Rule.Schema anything context -> Review.Rule.Schema anything context"},{"name":"withExpressionVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s\n[expressions](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Expression)\n(`1`, `True`, `add 1 2`, `1 + 2`), collect data in the `context` and/or report patterns.\nThe expressions are visited in pre-order depth-first search, meaning that an\nexpression will be visited, then its first child, the first child's children\n(and so on), then the second child (and so on).\n\nThe following example forbids the use of `Debug.log` even when it is imported like\n`import Debug exposing (log)`.\n\n    import Elm.Syntax.Exposing as Exposing exposing (TopLevelExpose(..))\n    import Elm.Syntax.Expression exposing (Expression(..))\n    import Elm.Syntax.Import exposing (Import)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Direction, Error, Rule)\n\n    type Context\n        = DebugLogWasNotImported\n        | DebugLogWasImported\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoDebugEvenIfImported\"\n            |> Rule.withInitialContext DebugLogWasNotImported\n            |> Rule.withImportVisitor importVisitor\n            |> Rule.withExpressionVisitor expressionVisitor\n            |> Rule.fromSchema\n\n    importVisitor : Node Import -> Context -> ( List Error, Context )\n    importVisitor node context =\n        case ( Node.value node |> .moduleName |> Node.value, (Node.value node).exposingList |> Maybe.map Node.value ) of\n            ( [ \"Debug\" ], Just (Exposing.All _) ) ->\n                ( [], DebugLogWasImported )\n\n            ( [ \"Debug\" ], Just (Exposing.Explicit exposedFunctions) ) ->\n                let\n                    isLogFunction : Node Exposing.TopLevelExpose -> Bool\n                    isLogFunction exposeNode =\n                        case Node.value exposeNode of\n                            FunctionExpose \"log\" ->\n                                True\n\n                            _ ->\n                                False\n                in\n                if List.any isLogFunction exposedFunctions then\n                    ( [], DebugLogWasImported )\n\n                else\n                    ( [], DebugLogWasNotImported )\n\n            _ ->\n                ( [], DebugLogWasNotImported )\n\n    expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )\n    expressionVisitor node direction context =\n        case context of\n            DebugLogWasNotImported ->\n                ( [], context )\n\n            DebugLogWasImported ->\n                case ( direction, Node.value node ) of\n                    ( Rule.OnEnter, FunctionOrValue [] \"log\" ) ->\n                        ( [ Rule.error\n                                { message = \"Remove the use of `Debug` before shipping to production\"\n                                , details = [ \"The `Debug` module is useful when developing, but is not meant to be shipped to production or published in a package. I suggest removing its use before committing and attempting to push to production.\" ]\n                                }\n                                (Node.range node)\n                          ]\n                        , context\n                        )\n\n                    _ ->\n                        ( [], context )\n\nTip: If you do not need to collect or use the `context` in this visitor, you may wish to use the\nsimpler [`withSimpleExpressionVisitor`](#withSimpleExpressionVisitor) function.\n\n","type":"(Elm.Syntax.Node.Node Elm.Syntax.Expression.Expression -> Review.Rule.Direction -> context -> ( List.List Review.Rule.Error, context )) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withFinalEvaluation","comment":" Add a function that makes a final evaluation based only on the data that was\ncollected in the `context`. This can be useful if you can't or if it is hard to\ndetermine something as you traverse the file.\n\nThe following example forbids importing both `Element` (`elm-ui`) and\n`Html.Styled` (`elm-css`). Note that this is the same one written in the example\nfor [`withImportVisitor`](#withImportVisitor), but using [`withFinalEvaluation`](#withFinalEvaluation).\n\n    import Dict as Dict exposing (Dict)\n    import Elm.Syntax.Import exposing (Import)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Elm.Syntax.Range exposing (Range)\n    import Review.Rule as Rule exposing (Error, Rule)\n\n    type alias Context =\n        Dict (List String) Range\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoUsingBothHtmlAndHtmlStyled\"\n            |> Rule.withInitialContext Dict.empty\n            |> Rule.withImportVisitor importVisitor\n            |> Rule.withFinalEvaluation finalEvaluation\n            |> Rule.fromSchema\n\n    importVisitor : Node Import -> Context -> ( List Error, Context )\n    importVisitor node context =\n        ( [], Dict.insert (Node.value node |> .moduleName |> Node.value) (Node.range node) context )\n\n    finalEvaluation : Context -> List Error\n    finalEvaluation context =\n        case ( Dict.get [ \"Element\" ] context, Dict.get [ \"Html\", \"Styled\" ] context ) of\n            ( Just elmUiRange, Just _ ) ->\n                [ Rule.error\n                    { message = \"Do not use both `elm-ui` and `elm-css`\"\n                    , details = [ \"At fruits.com, we use `elm-ui` in the dashboard application, and `elm-css` in the rest of the code. We want to use `elm-ui` in our new projects, but in projects using `elm-css`, we don't want to use both libraries to keep things simple.\" ]\n                    }\n                    elmUiRange\n                ]\n\n            _ ->\n                []\n\n","type":"(context -> List.List Review.Rule.Error) -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withFixes","comment":" Give a list of fixes to automatically fix the error.\n\n    import Review.Fix as Fix\n\n    error : Node a -> Error\n    error node =\n        Rule.error\n            { message = \"Remove the use of `Debug` before shipping to production\"\n            , details = [ \"The `Debug` module is useful when developing, but is not meant to be shipped to production or published in a package. I suggest removing its use before committing and attempting to push to production.\" ]\n            }\n            (Node.range node)\n            |> withFixes [ Fix.removeRange (Node.range node) ]\n\nTake a look at [`Review.Fix`](./Review-Fix) to know more on how to makes fixes.\n\nIf you pass `withFixes` an empty list, the error will be considered as having no\nautomatic fix available. Calling `withFixes` several times on an error will\noverwrite the previous fixes.\n\n**Note**: Each fix applies on a location in the code, defined by a range. To avoid an\nunpredictable result, those ranges may not overlap. The order of the fixes does\nnot matter.\n\n","type":"List.List Review.Fix.Fix -> Review.Rule.Error -> Review.Rule.Error"},{"name":"withImportVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s\n[import statements](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Import)\n(`import Html as H exposing (div)`) in order of their definition, collect data\nin the `context` and/or report patterns.\n\nThe following example forbids importing both `Element` (`elm-ui`) and\n`Html.Styled` (`elm-css`).\n\n    import Elm.Syntax.Import exposing (Import)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Error, Rule)\n\n    type alias Context =\n        { elmUiWasImported : Bool\n        , elmCssWasImported : Bool\n        }\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoUsingBothHtmlAndHtmlStyled\"\n            |> Rule.withInitialContext { elmUiWasImported = False, elmCssWasImported = False }\n            |> Rule.withImportVisitor importVisitor\n            |> Rule.fromSchema\n\n    error : Node Import -> Error\n    error node =\n        Rule.error\n            { message = \"Do not use both `elm-ui` and `elm-css`\"\n            , details = [ \"At fruits.com, we use `elm-ui` in the dashboard application, and `elm-css` in the rest of the code. We want to use `elm-ui` in our new projects, but in projects using `elm-css`, we don't want to use both libraries to keep things simple.\" ]\n            }\n            (Node.range node)\n\n    importVisitor : Node Import -> Context -> ( List Error, Context )\n    importVisitor node context =\n        case Node.value node |> .moduleName |> Node.value of\n            [ \"Element\" ] ->\n                if context.elmCssWasImported then\n                    ( [ error node ]\n                    , { context | elmUiWasImported = True }\n                    )\n\n                else\n                    ( [ error node ]\n                    , { context | elmUiWasImported = True }\n                    )\n\n            [ \"Html\", \"Styled\" ] ->\n                if context.elmUiWasImported then\n                    ( [ error node ]\n                    , { context | elmCssWasImported = True }\n                    )\n\n                else\n                    ( [ error node ]\n                    , { context | elmCssWasImported = True }\n                    )\n\n            _ ->\n                ( [], context )\n\nThis example was written in a different way in the example for [`withFinalEvaluation`](#withFinalEvaluation).\n\nTip: If you do not need to collect or use the `context` in this visitor, you may wish to use the\nsimpler [`withSimpleImportVisitor`](#withSimpleImportVisitor) function.\n\n","type":"(Elm.Syntax.Node.Node Elm.Syntax.Import.Import -> context -> ( List.List Review.Rule.Error, context )) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withInitialContext","comment":" Adds an initial `context` to start collecting data during your traversal.\n\nIn some cases, you can't just report a pattern when you see it, but you want to\nnot report or report differently depending on information located in a different\npart of the file. In that case, you collect data as the nodes in the file get\ntraversed and store it in what we'll call a `context`. This `context` will be\navailable and updated by non-\"simple\" \"with\\*\" functions, like\n[`withExpressionVisitor`](#withExpressionVisitor) or [`withImportVisitor`](#withImportVisitor).\n\nOnce the file has been traversed and you have collected all the data available\nfrom the file, you can report some final errors using [`withFinalEvaluation`](#withFinalEvaluation).\n\nA few use examples:\n\n  - You want to report the use of `Debug.log`: and if you see a call using a `log`\n    function, you need to check whether `log` was defined in the file, or imported\n    using `import Debug exposing (log)` or `import Debug exposing (..)`.\n  - You wish to report unused variables, so you need to register the declared and\n    imported variables, and note when they get used.\n  - You noticed plenty of bad or inconsistent uses of the `Html.button` function,\n    so you built a nice `Button` module. You now want to forbid all uses of\n    `Html.button`, except in the `Button` module ([`See simplified example`](#withModuleDefinitionVisitor)).\n\nThe `context` you choose needs to be of the same type for all visitors. In practice,\nit is similar to a `Model` for a rule.\n\nThe following example forbids calling `Rule.newSchema` with a name that is not\nthe same as the module's name (forbidding `Rule.newSchema \"NoSomething\"` when the\nmodule name is `Review.Rule.NoSomethingElse`).\n\n    import Elm.Syntax.Expression exposing (Expression(..))\n    import Elm.Syntax.Module as Module exposing (Module)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Direction, Error, Rule)\n\n    type alias Context =\n        -- Contains the module name's last part\n        Maybe String\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoDifferentNameForRuleAndModuleName\"\n            |> Rule.withInitialContext Nothing\n            |> Rule.withModuleDefinitionVisitor moduleDefinitionVisitor\n            |> Rule.withExpressionVisitor expressionVisitor\n            |> Rule.fromSchema\n\n    moduleDefinitionVisitor : Node Module -> Context -> ( List Error, Context )\n    moduleDefinitionVisitor node context =\n        let\n            moduleLastName : Maybe String\n            moduleLastName =\n                node\n                    |> Node.value\n                    |> Module.moduleName\n                    |> List.reverse\n                    |> List.head\n        in\n        ( [], moduleLastName )\n\n    expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )\n    expressionVisitor node direction context =\n        case ( direction, Node.value node ) of\n            ( Rule.OnEnter, Application (function :: ruleNameNode :: _) ) ->\n                case ( Node.value function, Node.value ruleNameNode ) of\n                    ( FunctionOrValue [ \"Rule\" ] \"newSchema\", Literal ruleName ) ->\n                        if Just ruleName /= context then\n                            let\n                                suggestedName : String\n                                suggestedName =\n                                    case context of\n                                        Just name ->\n                                            \" (`\" ++ name ++ \"`)\"\n\n                                        Nothing ->\n                                            \"\"\n                            in\n                            ( [ Rule.error\n                                    { message = \"Rule name should be the same as the module name\" ++ suggestedName\n                                    , details = [ \"This makes it easier to find the documentation for a rule or to find the rule in the configuration.\" ]\n                                    }\n                                    (Node.range ruleNameNode)\n                              ]\n                            , context\n                            )\n\n                        else\n                            ( [], context )\n\n                    _ ->\n                        ( [], context )\n\n            _ ->\n                ( [], context )\n\nNote that due to implementation details, `withInitialContext` needs to be chained\nright after [`newSchema`](#newSchema) just like in the example above, as previous\n\"with\\*\" functions will be ignored.\n\n","type":"context -> Review.Rule.Schema { hasNoVisitor : () } () -> Review.Rule.Schema { hasNoVisitor : () } context"},{"name":"withModuleDefinitionVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s\n[module definition](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Module) (`module SomeModuleName exposing (a, b)`), collect data in the `context` and/or report patterns.\n\nThe following example forbids the use of `Html.button` except in the \"Button\" file.\nThe example is simplified to only forbid the use of the `Html.button` expression.\n\n    import Elm.Syntax.Expression exposing (Expression(..))\n    import Elm.Syntax.Module as Module exposing (Module)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Direction, Error, Rule)\n\n    type Context\n        = HtmlButtonIsAllowed\n        | HtmlButtonIsForbidden\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoHtmlButton\"\n            |> Rule.withInitialContext HtmlButtonIsForbidden\n            |> Rule.withModuleDefinitionVisitor moduleDefinitionVisitor\n            |> Rule.withExpressionVisitor expressionVisitor\n            |> Rule.fromSchema\n\n    moduleDefinitionVisitor : Node Module -> Context -> ( List Error, Context )\n    moduleDefinitionVisitor node context =\n        if (Node.value node |> Module.moduleName) == [ \"Button\" ] then\n            ( [], HtmlButtonIsAllowed )\n\n        else\n            ( [], HtmlButtonIsForbidden )\n\n    expressionVisitor : Node Expression -> Direction -> Context -> ( List Error, Context )\n    expressionVisitor node direction context =\n        case ( direction, context ) of\n            ( Rule.OnEnter, HtmlButtonIsAllowed ) ->\n                ( [], context )\n\n            ( Rule.OnEnter, HtmlButtonIsForbidden ) ->\n                case Node.value node of\n                    FunctionOrValue [ \"Html\" ] \"button\" ->\n                        ( [ Rule.error\n                                { message = \"Do not use `Html.button` directly\"\n                                , details = [ \"At fruits.com, we've built a nice `Button` module that suits our needs better. Using this module instead of `Html.button` ensures we have a consistent button experience across the website.\" ]\n                                }\n                                (Node.range node)\n                          ]\n                        , context\n                        )\n\n                    _ ->\n                        ( [], context )\n\n            ( _, _ ) ->\n                ( [], context )\n\nTip: If you do not need to collect data in this visitor, you may wish to use the\nsimpler [`withSimpleModuleDefinitionVisitor`](#withSimpleModuleDefinitionVisitor) function).\n\n","type":"(Elm.Syntax.Node.Node Elm.Syntax.Module.Module -> context -> ( List.List Review.Rule.Error, context )) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withSimpleDeclarationVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s\n[declaration statements](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Declaration)\n(`someVar = add 1 2`, `type Bool = True | False`, `port output : Json.Encode.Value -> Cmd msg`)\nand report patterns. The declarations will be visited in the order of their definition.\n\nThe following example forbids declaring a function or a value without a type\nannotation.\n\n    import Elm.Syntax.Declaration exposing (Declaration(..))\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Error, Rule)\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoMissingTypeAnnotation\"\n            |> Rule.withSimpleDeclarationVisitor declarationVisitor\n            |> Rule.fromSchema\n\n    declarationVisitor : Node Declaration -> List Error\n    declarationVisitor node =\n        case Node.value node of\n            FunctionDeclaration { signature, declaration } ->\n                case signature of\n                    Just _ ->\n                        []\n\n                    Nothing ->\n                        let\n                            functionName : String\n                            functionName =\n                                declaration |> Node.value |> .name |> Node.value\n                        in\n                        [ Rule.error\n                            { message = \"Missing type annotation for `\" ++ functionName ++ \"`\"\n                            , details =\n                                [ \"Type annotations are very helpful for people who read your code. It can give a lot of information without having to read the contents of the function. When encountering problems, the compiler will also give much more precise and helpful information to help you solve the problem.\"\n                                , \"To add a type annotation, add a line like `\" functionName ++ \" : ()`, and replace the `()` by the type of the function. If you don't replace `()`, the compiler should give you a suggestion of what the type should be.\"\n                                ]\n                            }\n                            (Node.range node)\n                        ]\n\n            _ ->\n                []\n\nNote: `withSimpleDeclarationVisitor` is a simplified version of [`withDeclarationVisitor`](#withDeclarationVisitor),\nwhich 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.\n\n","type":"(Elm.Syntax.Node.Node Elm.Syntax.Declaration.Declaration -> List.List Review.Rule.Error) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withSimpleExpressionVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s\n[expressions](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Expression)\n(`1`, `True`, `add 1 2`, `1 + 2`). The expressions are visited in pre-order\ndepth-first search, meaning that an expression will be visited, then its first\nchild, the first child's children (and so on), then the second child (and so on).\n\nThe following example forbids using the Debug module.\n\n    import Elm.Syntax.Expression exposing (Expression(..))\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Error, Rule)\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoDebug\"\n            |> Rule.withSimpleExpressionVisitor expressionVisitor\n            |> Rule.fromSchema\n\n    expressionVisitor : Node Expression -> List Error\n    expressionVisitor node =\n        case Node.value node of\n            FunctionOrValue moduleName fnName ->\n                if List.member \"Debug\" moduleName then\n                    [ Rule.error\n                        { message = \"Remove the use of `Debug` before shipping to production\"\n                        , details = [ \"The `Debug` module is useful when developing, but is not meant to be shipped to production or published in a package. I suggest removing its use before committing and attempting to push to production.\" ]\n                        }\n                        (Node.range node)\n                    ]\n\n                else\n                    []\n\n            _ ->\n                []\n\nNote: `withSimpleExpressionVisitor` is a simplified version of [`withExpressionVisitor`](#withExpressionVisitor),\nwhich 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.\n\n","type":"(Elm.Syntax.Node.Node Elm.Syntax.Expression.Expression -> List.List Review.Rule.Error) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withSimpleImportVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s [import statements](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Import) (`import Html as H exposing (div)`) in order of their definition and report patterns.\n\nThe following example forbids using the core Html package and suggests using\n`elm-css` instead.\n\n    import Elm.Syntax.Import exposing (Import)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Error, Rule)\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoCoreHtml\"\n            |> Rule.withSimpleImportVisitor importVisitor\n            |> Rule.fromSchema\n\n    importVisitor : Node Import -> List Error\n    importVisitor node =\n        let\n            moduleName : List String\n            moduleName =\n                node\n                    |> Node.value\n                    |> .moduleName\n                    |> Node.value\n        in\n        case moduleName of\n            [ \"Html\" ] ->\n                [ Rule.error\n                    { message = \"Use `elm-css` instead of the core HTML package.\"\n                    , details =\n                        [ \"At fruits.com, we chose to use the `elm-css` package (https://package.elm-lang.org/packages/rtfeldman/elm-css/latest/Css) to build our HTML and CSS rather than the core Html package. To keep things simple, we think it is best to not mix these different libraries.\"\n                        , \"The API is very similar, but instead of using the `Html` module, use the `Html.Styled`. CSS is then defined using the Html.Styled.Attributes.css function (https://package.elm-lang.org/packages/rtfeldman/elm-css/latest/Html-Styled-Attributes#css).\"\n                        ]\n                    }\n                    (Node.range node)\n                ]\n\n            _ ->\n                []\n\nNote: `withSimpleImportVisitor` is a simplified version of [`withImportVisitor`](#withImportVisitor),\nwhich isn't passed a `context` and doesn't return one. You can use `withSimpleImportVisitor` even if you use \"non-simple with\\*\" functions.\n\n","type":"(Elm.Syntax.Node.Node Elm.Syntax.Import.Import -> List.List Review.Rule.Error) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"},{"name":"withSimpleModuleDefinitionVisitor","comment":" Add a visitor to the [`Schema`](#Schema) which will visit the `File`'s [module definition](https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Syntax-Module) (`module SomeModuleName exposing (a, b)`) and report patterns.\n\nThe following example forbids having `_` in any part of a module name.\n\n    import Elm.Syntax.Module as Module exposing (Module)\n    import Elm.Syntax.Node as Node exposing (Node)\n    import Review.Rule as Rule exposing (Error, Rule)\n\n    rule : Rule\n    rule =\n        Rule.newSchema \"NoUnderscoreInModuleName\"\n            |> Rule.withSimpleModuleDefinitionVisitor moduleDefinitionVisitor\n            |> Rule.fromSchema\n\n    moduleDefinitionVisitor : Node Module -> List Error\n    moduleDefinitionVisitor node =\n        if List.any (String.contains \"\") (Node.value node |> Module.moduleName) then\n            [ Rule.error\n                { message = \"Do not use `_` in a module name\"\n                , details = [ \"By convention, Elm modules names use Pascal case (like `MyModuleName`). Please rename your module using this format.\" ]\n                }\n                (Node.range node)\n            ]\n\n        else\n            []\n\nNote: `withSimpleModuleDefinitionVisitor` is a simplified version of [`withModuleDefinitionVisitor`](#withModuleDefinitionVisitor),\nwhich isn't passed a `context` and doesn't return one. You can use `withSimpleModuleDefinitionVisitor` even if you use \"non-simple with\\*\" functions.\n\n","type":"(Elm.Syntax.Node.Node Elm.Syntax.Module.Module -> List.List Review.Rule.Error) -> Review.Rule.Schema anything context -> Review.Rule.Schema { hasAtLeastOneVisitor : () } context"}],"binops":[]},{"name":"Review.Test","comment":" Module that helps you test your rules, using [`elm-test`](https://package.elm-lang.org/packages/elm-explorations/test/latest/).\n\n    import Review.Test exposing (ReviewResult)\n    import Test exposing (Test, describe, test)\n    import The.Rule.You.Want.To.Test exposing (rule)\n\n    testRule : String -> ReviewResult\n    testRule string =\n        Review.Test.run rule string\n\n    -- In this example, the rule we're testing is `NoDebug`\n    tests : Test\n    tests =\n        describe \"NoDebug\"\n            [ test \"should not report calls to normal functions\" <|\n                \\() ->\n                    testRule \"\"\"module A exposing (..)\n    a = foo n\"\"\"\n                        |> Review.Test.expectNoErrors\n            , test \"should report Debug.log use\" <|\n                \\() ->\n                    testRule \"\"\"module A exposing (..)\n    a = Debug.log \"some\" \"message\\\"\"\"\"\n                        |> Review.Test.expectErrors\n                            [ Review.Test.error\n                                { message = \"Remove the use of `Debug` before shipping to production\"\n                                , under = \"Debug.log\"\n                                }\n                            ]\n            ]\n\n\n# Strategies for effective testing\n\n\n## Use Test-Driven Development\n\nWriting a rule is a process that works really well with the Test-Driven\nDevelopment process loop, which is:\n\n  - Before writing any code, write a failing test.\n  - Run the test and make sure that it is failing, otherwise you can't be\n    sure that the test is well-written.\n  - Write the simplest (almost stupid) code to make the test pass\n  - Run the tests again and make sure that the test is passing, and that you\n    didn't break any previous tests\n  - Optionally, refactor your code but be sure not to change the behavior of the\n    implementation. You should not add support for new patterns, as you will\n    want to write tests for that first.\n  - (Then start over from step 1 until you've handled all the cases you wished\n    to handle)\n\n\n## Have a good title\n\nA good test title explains\n\n  - what is tested - Probably the rule, but making it explicit\n    in a [`describe`](https://package.elm-lang.org/packages/elm-explorations/test/latest/Test#describe)\n    might improve your test report. Or maybe you are testing a sub-part of the rule,\n    and you can name it explictly.\n  - what should happen: (not) reporting an error, fix <something> by <doing something>, ...\n  - when: what is the situation that this test sets up?\n\nIdeally, by only reading through the test titles, someone else should be able to\nrewrite the rule you are testing.\n\n\n## What should you test?\n\nYou should test the scenarios where you expect the rule to report something. At\nthe same time, you should also test when it shouldn't. I encourage writing tests\nto make sure that things that are similar to what you want to report are not\nreported.\n\nFor instance, if you wish to report uses of variables named `foo`, write a test\nthat ensures that the use of variables named differently does not get reported.\n\nTests are pretty cheap, and in the case of rules, it is probably better to have\ntoo many tests rather than too few, since the behavior of a rule rarely changes\ndrastically.\n\n\n# Design goals\n\nIf you are interested, you can read\n[the design goals](https://github.com/jfmengels/elm-review/blob/master/documentation/design/test-module.md)\nfor this module.\n\n\n# Running tests\n\n@docs ReviewResult, run, runWithProjectData\n\n\n# Making assertions\n\n@docs ExpectedError, expectErrors, expectNoErrors, error, atExactly, whenFixed\n\n","unions":[{"name":"ExpectedError","comment":" An expectation for an error. Use [`error`](#error) to create one.\n","args":[],"cases":[]},{"name":"ReviewResult","comment":" The result of running a rule on a `String` containing source code.\n","args":[],"cases":[]}],"aliases":[],"values":[{"name":"atExactly","comment":" Precise the exact position where the error should be shown to the user. This\nis only necessary when the `under` field is ambiguous.\n\n`atExactly` takes a record with start and end positions.\n\n    tests : Test\n    tests =\n        describe \"NoDebug\"\n            [ test \"should report multiple Debug.log calls\" <|\n                \\() ->\n                    testRule \"\"\"module A exposing (..)\n    a = Debug.log \"foo\" z\n    b = Debug.log \"foo\" z\n    \"\"\"\n                        |> Review.Test.expectErrors\n                            [ Review.Test.error\n                                { message = \"Remove the use of `Debug` before shipping to production\"\n                                , under = \"Debug.log\"\n                                }\n                                |> Review.Test.atExactly { start = { row = 4, column = 5 }, end = { row = 4, column = 14 } }\n                            , Review.Test.error\n                                { message = \"Remove the use of `Debug` before shipping to production\"\n                                , under = \"Debug.log\"\n                                }\n                                |> Review.Test.atExactly { start = { row = 5, column = 5 }, end = { row = 5, column = 14 } }\n                            ]\n            ]\n\nTip: By default, do not use this function. If the test fails because there is some\nambiguity, the test error will give you a recommendation of what to use as a parameter\nof `atExactly`, so you do not have to bother writing this hard-to-write argument yourself.\n\n","type":"{ start : { row : Basics.Int, column : Basics.Int }, end : { row : Basics.Int, column : Basics.Int } } -> Review.Test.ExpectedError -> Review.Test.ExpectedError"},{"name":"error","comment":" Create an expectation for an error.\n\n`message` should be the message you're expecting to be shown to the user.\n\n`under` is the part of the code where you are expecting the error to be shown to\nthe user. If it helps, imagine `under` to be the text under which the squiggly\nlines will appear if the error appeared in an editor.\n\n    tests : Test\n    tests =\n        describe \"NoDebug\"\n            [ test \"should report Debug.log use\" <|\n                \\() ->\n                    testRule \"\"\"module A exposing (..)\n    a = Debug.log \"some\" \"message\\\"\"\"\"\n                        |> Review.Test.expectErrors\n                            [ Review.Test.error\n                                { message = \"Remove the use of `Debug` before shipping to production\"\n                                , under = \"Debug.log\"\n                                }\n                            ]\n            ]\n\nIf there are multiple locations where the value of `under` appears, the test will\nfail unless you use [`atExactly`](#atExactly) to remove any ambiguity of where the\nerror should be used.\n\n","type":"{ message : String.String, details : List.List String.String, under : String.String } -> Review.Test.ExpectedError"},{"name":"expectErrors","comment":" Assert that the rule reported some errors, by specifying which one.\n\nAssert which errors are reported using [`error`](#error). The test will fail if\na different number of errors than expected are reported, or if the message or the\nlocation is incorrect.\n\nThe errors should be in the order of where they appear in the source code. An error\nat the start of the source code should appear earlier in the list than\nan error at the end of the source code.\n\n    import Review.Test exposing (ReviewResult)\n    import Test exposing (Test, describe, test)\n    import The.Rule.You.Want.To.Test exposing (rule)\n\n    testRule : String -> ReviewResult\n    testRule string =\n        Review.Test.run rule string\n\n    -- In this example, the rule we're testing is `NoDebug`\n    tests : Test\n    tests =\n        describe \"NoDebug\"\n            [ test \"should report Debug.log use\" <|\n                \\() ->\n                    testRule \"\"\"module A exposing (..)\n    a = Debug.log \"some\" \"message\\\"\"\"\"\n                        |> Review.Test.expectErrors\n                            [ Review.Test.error\n                                { message = \"Remove the use of `Debug` before shipping to production\"\n                                , under = \"Debug.log\"\n                                }\n                            ]\n            ]\n\n","type":"List.List Review.Test.ExpectedError -> Review.Test.ReviewResult -> Expect.Expectation"},{"name":"expectNoErrors","comment":" Assert that the rule reported no errors. Note, this is equivalent to using [`expectErrors`](#expectErrors)\nlike `expectErrors []`.\n\n    import Review.Test exposing (ReviewResult)\n    import Test exposing (Test, describe, test)\n    import The.Rule.You.Want.To.Test exposing (rule)\n\n    testRule : String -> ReviewResult\n    testRule string =\n        Review.Test.run rule string\n\n    -- In this example, the rule we're testing is `NoDebug`\n    tests : Test\n    tests =\n        describe \"NoDebug\"\n            [ test \"should not report calls to normal functions\" <|\n                \\() ->\n                    testRule \"\"\"module A exposing (..)\n    a = foo n\"\"\"\n                        |> Review.Test.expectNoErrors\n            ]\n\n","type":"Review.Test.ReviewResult -> Expect.Expectation"},{"name":"run","comment":" Run a `Rule` on a `String` containing source code. You can then use\n[`expectNoErrors`](#expectNoErrors) or [`expectErrors`](#expectErrors) to assert\nthe errors reported by the rule.\n\n    import My.Rule exposing (rule)\n    import Review.Test exposing (ReviewResult)\n    import Test exposing (Test)\n\n    all : Test\n    all =\n        test \"test title\" <|\n            \\() ->\n                Review.Test.run rule \"\"\"module SomeModule exposing (a)\n    a = 1\"\"\"\n                    |> Review.Test.expectNoErrors\n\nThe source code needs to be syntactically valid Elm code. If the code\ncan't be parsed, the test will fail regardless of the expectations you set on it.\n\nNote that to be syntactically valid, you need at least a module declaration at the\ntop of the file (like `module A exposing (..)`) and one declaration (like `a = 1`).\nYou can't just have an expression like `1 + 2`.\n\nNote: This is a simpler version of [`runWithProjectData`](#runWithProjectData).\nIf your rule is interested in project related details, then you should use\n[`runWithProjectData`](#runWithProjectData) instead.\n\n","type":"Review.Rule.Rule -> String.String -> Review.Test.ReviewResult"},{"name":"runWithProjectData","comment":" Run a `Rule` on a `String` containing source code, with data about the\nproject loaded, such as the contents of `elm.json` file.\n\n    import My.Rule exposing (rule)\n    import Review.Project as Project exposing (Project)\n    import Review.Test exposing (ReviewResult)\n    import Test exposing (Test)\n\n    all : Test\n    all =\n        test \"test title\" <|\n            \\() ->\n                let\n                    project : Project\n                    project =\n                        Project.new\n                            |> Project.withElmJson elmJsonToConstructManually\n                in\n                Review.Test.runWithProjectData project rule \"\"\"module SomeModule exposing (a)\n    a = 1\"\"\"\n                    |> Review.Test.expectNoErrors\n\nThe source code needs to be syntactically valid Elm code. If the code\ncan't be parsed, the test will fail regardless of the expectations you set on it.\n\nNote that to be syntactically valid, you need at least a module declaration at the\ntop of the file (like `module A exposing (..)`) and one declaration (like `a = 1`).\nYou can't just have an expression like `1 + 2`.\n\nNote: This is a more complex version of [`run`](#run). If your rule is not\ninterested in project related details, then you should use [`run`](#run) instead.\n\n","type":"Review.Project.Project -> Review.Rule.Rule -> String.String -> Review.Test.ReviewResult"},{"name":"whenFixed","comment":" Create an expectation that the error provides fixes, meaning that it used\nthe [`withFixes`](#withFixes) function) and an expectation of what the source\ncode should be after the error's fixes have been applied.\n\nIn the absence of `whenFixed`, the test will fail if the error provides fixes.\nIn other words: If the error provides fixes, you need to use `withFixes`, and if\nit doesn't, you should not use `withFixes`.\n\n    tests : Test\n    tests =\n        describe \"NoDebug\"\n            [ test \"should report multiple Debug.log calls\" <|\n                \\() ->\n                    testRule \"\"\"module A exposing (..)\n    a = 1\n    b = Debug.log \"foo\" 2\n    \"\"\"\n                        |> Review.Test.expectErrors\n                            [ Review.Test.error\n                                { message = \"Remove the use of `Debug` before shipping to production\"\n                                , under = \"Debug.log\"\n                                }\n                                |> Review.Test.whenFixed \"\"\"module SomeModule exposing (b)\n    a = 1\n    b = 2\n    \"\"\"\n                            ]\n            ]\n\n","type":"String.String -> Review.Test.ExpectedError -> Review.Test.ExpectedError"}],"binops":[]}]