[{"name":"Review","comment":" A review inspects modules, `elm.json`, dependencies and extra files like `README.md` from your project\nand uses the combined knowledge to report problems.\n\n@docs ignoreErrorsForPathsWhere\n\nEverything below is intended for writing a new review\n\n@docs create\n\n\n# inspecting\n\nCollect knowledge from parts of the project.\n\n@docs inspectElmJson, inspectDirectDependencies, inspectExtraFile, inspectModule\n\n\n# reporting\n\n@docs Error, elmJsonPath\n@docs SourceEdit, insertAt, removeRange, replaceRange\n\nIf you want to insert\nbigger pieces of dynamic elm code,\nI recommend either using [`the-sett/elm-syntax-dsl`](https://dark.elm.dmy.fr/packages/the-sett/elm-syntax-dsl/latest/)\nor [`mdgriffith/elm-codegen`](https://dark.elm.dmy.fr/packages/mdgriffith/elm-codegen/latest/)\n\n\n# convenience helpers\n\nVarious helpers for [`elm-syntax`](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/)\nand other project data that is often useful when writing a review.\n\nFor example,\nby only listing all immediate sub-parts of a piece of syntax you can choose to traverse it however you need to.\nE.g. to find all `as` pattern ranges\n\n    findAllAsPatternRanges :\n        Elm.Syntax.Node.Node ELm.Syntax.Pattern.Pattern\n        -> List ELm.Syntax.Range.Range\n    findAllAsPatternRanges =\n        \\patternNode ->\n            (case patternNode of\n                Elm.Syntax.Node.Node asRange (Elm.Syntax.Pattern.AsPattern _ _) ->\n                    [ asRange ]\n\n                _ ->\n                    []\n            )\n                ++ (patternNode |> Review.patternSubs |> List.concatMap findAllAsPatternRanges)\n\nThis fine control allows you to e.g. skip visiting certain parts that you already accounted for.\n\n@docs expressionSubs, expressionSubsWithBindings, patternBindings, patternSubs, typeSubs\n\n@docs moduleHeaderDocumentation\n@docs determineModuleOrigin, importsToExplicit\n@docs moduleExposes, topLevelExposeListToExposes, moduleInterfaceExposes\n@docs sourceExtractInRange, sourceRangesOf\n@docs packageElmJsonExposedModules\n\nSuggestions to add, remove or change helpers welcome!\n\n\n# running\n\nMake `elm-review-mini` run in a new environment\n\n@docs Inspect, Review, run, sourceApplyEdits, SourceEditError, Run\n\n","unions":[{"name":"Inspect","comment":" How to collect knowledge from scanning a single part of the project\n","args":["knowledge"],"cases":[["InspectDirectDependencies",["List.List { elmJson : Elm.Project.Project, modules : List.List Elm.Docs.Module } -> knowledge"]],["InspectElmJson",["{ source : String.String, project : Elm.Project.Project } -> knowledge"]],["InspectExtraFile",["{ path : String.String, source : String.String } -> knowledge"]],["InspectModule",["{ syntax : Elm.Syntax.File.File, source : String.String, path : String.String } -> knowledge"]]]},{"name":"Run","comment":" A function that inspects, folds knowledge and reports errors in one go, and provides\na recursively-defined future run function that already has the calculated knowledges cached.\n\nDoes it need to be so complicated?\n\nDifferent reviews can have different knowledge types,\nso how can we put all of them in a single list?\nNo problem, hide this parameter by only storing the combined run function from project files to errors.\n\nBut how do we implement caching this way\n(only re-run inspections for files that changed, otherwise take the already computed knowledge parts)?\nI know about roughly three options:\n\n  - require users to provide encode/decode pairs to some generic structure.\n    The simplest and fastest seems to be [miniBill/elm-codec](https://dark.elm.dmy.fr/packages/miniBill/elm-codec/latest/)\n      - the ability to use the encoded cache at any time enables write to disk\n        (not a goal of `elm-review-mini` but having the option is nice)\n      - the ability to show the encoded cache in the elm debugger\n        (undeniably cool, though that only works in the browser. `Debug.log` is likely a nice enough alternative)\n      - the ability to export the produced json for external use\n        (not a goal of `elm-review-mini` but undeniably cool, similar to `elm-review` insights/extract although less explicit)\n      - quite a burden users should preferably not bear\n\n  - use js shenanigans to effectively \"cast specific context type to any\" and \"cast any to specific context type\"\n    similar to [linsyking/elm-anytype](https://dark.elm.dmy.fr/packages/linsyking/elm-anytype/latest/)\n      - faster than any possible alternative\n      - simpler elm internals than any possible alternative\n      - the highest possible degree of danger, as incorrect casting is always possible\n        (+ no way to control that `Review.run` users wire them correctly)\n      - custom embeds of running reviews (e.g. if you wanted to create a browser playground)\n        always need additional js hacking which to me is deal breaking\n\n  - provide a future function as a result which knows about the\n    previously calculated knowledges.\n    I was surprised to find that it's almost trivial to implement and even cuts down\n    internal complexity compared to something like the codec one.\n    If you're intrigued and have a week,\n    some smart folks have written [an entertaining dialog-blog-ish series about these \"Jeremy's interfaces\"](https://discourse.elm-lang.org/t/demystifying-jeremys-interfaces/8834)\n      - still very fast (much faster than the codec one)\n      - concise internals\n      - possibly less flexible for implementing stuff like shared knowledge\n        (I much prefer defunctionalization wherever possible)\n      - slightly less obvious than the codec one\n\nI didn't expect to ever need to resort to such a complex feature but here we are.\nThough I'm always excited to try and experiment with other options (except the codec one which I already tried), issues welcome!\n\n","args":[],"cases":[["Run",["{ elmJson : { source : String.String, project : Elm.Project.Project }, directDependencies : List.List { elmJson : Elm.Project.Project, docsJson : List.List Elm.Docs.Module }, addedOrChangedExtraFiles : List.List { path : String.String, source : String.String }, addedOrChangedModules : List.List { path : String.String, source : String.String, syntax : Elm.Syntax.File.File }, removedExtraFilePaths : List.List String.String, removedModulePaths : List.List String.String } -> { errorsByPath : FastDict.Dict String.String (List.List { range : Elm.Syntax.Range.Range, message : String.String, details : List.List String.String, fixEditsByPath : FastDict.Dict String.String (List.List Review.SourceEdit) }), nextRun : Review.Run }"]]]},{"name":"SourceEdit","comment":" A single edit to be applied to a file's source\nin order to fix a [review error](#Error)\n","args":[],"cases":[["SourceRangeReplacement",["{ range : Elm.Syntax.Range.Range, replacement : String.String }"]]]},{"name":"SourceEditError","comment":" An undesired situation when trying to apply [`SourceEdit`](#SourceEdit)s\n","args":[],"cases":[["AfterFixIsUnchanged",[]],["FixHasCollisionsInRanges",[]]]}],"aliases":[{"name":"Error","comment":" A problem to report in a given file and range, possibly suggesting a fix with [`SourceEdit`](#SourceEdit)s\n\nTake the elm compiler errors as inspiration in terms of helpfulness:\n\n  - error `message`: half-sentence on what _is_ undesired here. A user\n    that has encountered this error multiple times should know exactly what to do.\n    Example: \"\\`\\` is never used\" → a user who\n    knows the rule knows that a function can be removed and which one\n  - error `details`: additional information such as the rationale and suggestions\n    for a solution or alternative\n  - error report `range`: The region marked as problematic. Make this section as small as\n    possible. For instance, in a rule that would forbid\n    `Debug.log`, you would want the error to appear at `Debug.log`, not on the whole\n    function call\n\n","args":[],"type":"{ path : String.String, range : Elm.Syntax.Range.Range, message : String.String, details : List.List String.String, fix : List.List { path : String.String, edits : List.List Review.SourceEdit } }"},{"name":"Review","comment":" A construct that can inspect your project files and report errors, see [`Review.create`](Review#create)\n","args":[],"type":"{ ignoreErrorsForPathsWhere : String.String -> Basics.Bool, run : Review.Run }"}],"values":[{"name":"create","comment":" First, read [\"when to write or enable a review\"](https://dark.elm.dmy.fr/packages/lue-bird/elm-review-mini#when-to-write-or-enable-a-review).\nTo write a new [`Review`](#Review) you need to\n\n  - `inspect`: the parts you want to scan to collect knowledge from. See [section inspecting](#inspecting)\n  - `knowledgeMerge`: assemble knowledge from multiple you've collected into one\n  - `report`: the final evaluation, turning your combined knowledge into a list of [errors](#Error)\n\nWrite tests with [`Review.Test`](Review-Test) alongside your implementation\nand document your review,\nexplaining when (not) to enable the review\nand adding examples of patterns that will (not) be reported\n\n","type":"{ inspect : List.List (Review.Inspect knowledge), knowledgeMerge : knowledge -> knowledge -> knowledge, report : knowledge -> List.List Review.Error } -> Review.Review"},{"name":"determineModuleOrigin","comment":" Either the full qualification of a given variant/value/function/type identifier\nor `Nothing` if defined locally.\n\nRequires a list of local explicit imports, see [`importsToExplicit`](#importsToExplicit)\n\n","type":"FastDict.Dict Elm.Syntax.ModuleName.ModuleName { alias : Maybe.Maybe String.String, exposes : Set.Set String.String } -> ( Elm.Syntax.ModuleName.ModuleName, String.String ) -> Maybe.Maybe Elm.Syntax.ModuleName.ModuleName"},{"name":"elmJsonPath","comment":" Relative path to the project elm.json to be used in an [`Error`](#Error) or [expected test error](Review-Test#run).\nYou could also just use `\"elm.json\"` which feels a bit brittle.\n","type":"String.String"},{"name":"expressionSubs","comment":" All surface-level child [expression](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/Elm-Syntax-Expression)s.\n\nIf you also want to record the newly available variables by child expression,\nuse [`expressionSubsWithBindings`](#expressionSubsWithBindings)\n\n","type":"Elm.Syntax.Node.Node Elm.Syntax.Expression.Expression -> List.List (Elm.Syntax.Node.Node Elm.Syntax.Expression.Expression)"},{"name":"expressionSubsWithBindings","comment":" Like [`expressionSubs`](#expressionSubs)\nwith additional info about newly available variables from patterns and let declared value/function names\nwhich can be used to for example disambiguate variables you plan to introduce yourself through a fix\n","type":"Elm.Syntax.Node.Node Elm.Syntax.Expression.Expression -> List.List { expressionNode : Elm.Syntax.Node.Node Elm.Syntax.Expression.Expression, bindings : List.List String.String }"},{"name":"ignoreErrorsForPathsWhere","comment":" Specify where you don't want errors to be reported in:\n\n  - an external library you copied over and don't want to modify more than necessary\n  - generated source code which isn't supposed to be read and or over which you have little control\n  - you wrote a review that is very specific and should only be applied for a portion of your codebase\n\n`tests/` is never inspected\n\n","type":"(String.String -> Basics.Bool) -> Review.Review -> Review.Review"},{"name":"importsToExplicit","comment":" Regular elm imports don't tell the whole truth of what names can be used in the module declarations.\nElm for example [uses some imports implicitly](https://dark.elm.dmy.fr/packages/elm/core/latest#Default-Imports),\nallows `exposing (..)` and `ChoiceTypeWithVariants(..)`\nand merges imports in a specific manner.\n\n[`importsToExplicit`](#importsToExplicit) now takes the module exposes\nof each module (see [`moduleExposes`](#moduleExposes))\nand a list of imports `exposing (..)` and imports exposing explicit (see [`topLevelExposeListToExposes`](#topLevelExposeListToExposes))\nfrom the current module to give you a\n[`FastDict`](https://dark.elm.dmy.fr/packages/miniBill/elm-fast-dict/latest/) with all imports and actual exposes and aliases listed.\n\nCan be used to [`determineModuleOrigin`](#determineModuleOrigin).\n\nEdge case note: The [elm compiler has a bug where the List module does not expose the type `List`](https://github.com/elm/core/issues/1037).\nTo make it easier to differentiate between local and imported `List` type\nwe still say that the `List` type originates from `List`.\nIt's then the responsibility of review authors to cope with this edge case\nwhen trying to edit the qualification or adding an import.\n\n","type":"{ moduleExposes : FastDict.Dict Elm.Syntax.ModuleName.ModuleName { typesWithVariantNames : FastDict.Dict String.String (Set.Set String.String), simpleNames : Set.Set String.String }, importsExposingAll : List.List { moduleName : Elm.Syntax.ModuleName.ModuleName, alias : Maybe.Maybe String.String }, importsExposingExplicit : List.List { moduleName : Elm.Syntax.ModuleName.ModuleName, alias : Maybe.Maybe String.String, typesExposingVariants : Set.Set String.String, simpleNames : Set.Set String.String } } -> FastDict.Dict Elm.Syntax.ModuleName.ModuleName { alias : Maybe.Maybe String.String, exposes : Set.Set String.String }"},{"name":"insertAt","comment":" Insert something at the given position\n","type":"Elm.Syntax.Range.Location -> String.String -> Review.SourceEdit"},{"name":"inspectDirectDependencies","comment":" Collect knowledge from all [project configs](https://dark.elm.dmy.fr/packages/elm/project-metadata-utils/latest/Elm-Project#Project)\nand [module docs](https://dark.elm.dmy.fr/packages/elm/project-metadata-utils/latest/Elm-Docs#Module)\nthe project directly depends on\n","type":"(List.List { elmJson : Elm.Project.Project, modules : List.List Elm.Docs.Module } -> knowledge) -> Review.Inspect knowledge"},{"name":"inspectElmJson","comment":" Collect knowledge from the [elm.json project config](https://dark.elm.dmy.fr/packages/elm/project-metadata-utils/latest/Elm-Project#Project).\nYou can use the raw source to [search for a section](#sourceRangesOf) you want to highlight in an [`Error`](#Error)\n","type":"({ source : String.String, project : Elm.Project.Project } -> knowledge) -> Review.Inspect knowledge"},{"name":"inspectExtraFile","comment":" Collect knowledge from an available files like README.md or CHANGELOG.md that aren't source modules or the elm.json.\nThe provided path is relative to the project's `elm.json`\nand can be used as an [`Error`](#Error) target file path\n","type":"({ path : String.String, source : String.String } -> knowledge) -> Review.Inspect knowledge"},{"name":"inspectModule","comment":" Collect knowledge from a module file.\n\nThe path is relative to the project's `elm.json`\nand can be used as an [`Error`](#Error) target file path.\n\nThe raw elm file source can be used\nto preserve existing formatting in a range\nin case you want to move and copy things around,\nsee [`sourceExtractInRange`](#sourceExtractInRange).\n\nThe `syntax` field contains a tree-like structure which represents your source code:\n[`elm-syntax` `File`](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/File).\nI recommend having the documentation for that package open while writing a review.\n\n\n### syntax.moduleDefinition\n\nThe [module header](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/7.2.1/Elm-Syntax-Module) (`module SomeModuleName exposing (a, b)`).\n\n\n### syntax.declarations\n\nThe module's\n[declaration statements](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/Elm-Syntax-Declaration)\n(`someVar = add 1 2`, `type Bool = True | False`, `port output : Json.Encode.Value -> Cmd msg`).\n\n\n### syntax.comments\n\n  - Module documentation (`{-| -}`)\n  - Port documentation comments (`{-| -}`)\n  - comments (`{- -}` and `--`)\n\nprovided in source order.\nDocumentation comments (`{-| -}`) of value/function/choice type/type alias declarations\ncan be found directly in their syntax data.\n\nIf you only need the module documentation, use\n[`moduleHeaderDocumentation`](#moduleHeaderDocumentation).\n\n\n### syntax.imports\n\nThe module's\n[import statements](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/7.2.1/Elm-Syntax-Import)\n(`import Html as H exposing (div)`) in order of their definition.\nA nice helper to get the exposes: [`topLevelExposeListToExposes`](#topLevelExposeListToExposes)\n\nAn example review that forbids importing both `Element` (`elm-ui`) and\n`Html.Styled` (`elm-css`) in the same module:\n\n    import Elm.Syntax.Import\n    import Elm.Syntax.Node\n    import Elm.Syntax.Range\n    import Review\n    import FastDict\n\n    review : Review.Review\n    review =\n        Review.create\n            { inspect =\n                [ Review.inspectModule\n                    (\\moduleData ->\n                        let\n                            importedModuleNames : Dict Elm.Syntax.ModuleName.ModuleName Elm.Syntax.Range.Range\n                            importedModuleNames =\n                                moduleData.syntax.imports\n                                    |> List.map\n                                        (\\(Elm.Syntax.Node.Node _ import_) ->\n                                            ( import.moduleName |> Elm.Syntax.Node.value, import.moduleName |> Elm.Syntax.Node.range )\n                                        )\n                                    |> FastDict.fromList\n                        in\n                        case\n                            ( importedModuleNames |> Dict.get [ \"Element\" ]\n                            , importedModuleNames |> Dict.get [ \"Html\", \"Styled\" ]\n                            )\n                        of\n                            ( Just elementImportRange, Just _ ) ->\n                                FastDict.singleton moduleData.path elementImportRange\n\n                        else\n                            FastDict.empty\n                    )\n                ]\n            , knowledgeMerge = \\a b -> FastDict.union a b\n            , report =\n                \\invalidImportsByPath ->\n                    invalidImportsByPath\n                        |> FastDict.toList\n                        |> List.map\n                            (\\( path, elementImportRange ) ->\n                                { path = moduleData.path\n                                , message = \"both `elm-ui` and `elm-css` used\"\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                                , range = elementImportRange\n                                , fix = []\n                                }\n                            )\n            }\n\nI strongly recommend [`FastDict`](https://dark.elm.dmy.fr/packages/miniBill/elm-fast-dict/latest/)\nfor your writing your review instead of `Dict`\nbecause `Dict.union` and friends have performance footguns you shouldn't need to worry about\n\n","type":"({ syntax : Elm.Syntax.File.File, source : String.String, path : String.String } -> knowledge) -> Review.Inspect knowledge"},{"name":"moduleExposes","comment":" Collect all exposed members from the file\n\n  - `simpleNames`: values, functions, type alias, opaque types (those without `(..)`), infix operators (parenthesized)\n\n  - `typesWithVariantNames`: names of types that expose their variants with `(..)`\n    paired with what variant names are actually meant by `..`.\n    It's provided as a [`FastDict`](https://dark.elm.dmy.fr/packages/miniBill/elm-fast-dict/latest/).\n    I strongly recommend using it too for your writing your review instead of `Dict`\n    because `Dict.union` and friends have performance footguns you shouldn't need to worry about\n\n","type":"Elm.Syntax.File.File -> { simpleNames : Set.Set String.String, typesWithVariantNames : FastDict.Dict String.String (Set.Set String.String) }"},{"name":"moduleHeaderDocumentation","comment":" The module's documentation comment at the top of the file, which can be `Nothing`.\n`elm-syntax` has a weird way of giving you the comments of a file, this helper should make it easier\n","type":"Elm.Syntax.File.File -> Maybe.Maybe (Elm.Syntax.Node.Node String.String)"},{"name":"moduleInterfaceExposes","comment":" Same as [`moduleExposes`](#moduleExposes) but for [docs module](https://dark.elm.dmy.fr/packages/elm/project-metadata-utils/latest/Elm-Docs#Module)s\nfrom [`Review.inspectDirectDependencies`](#inspectDirectDependencies)\n","type":"Elm.Docs.Module -> { simpleNames : Set.Set String.String, typesWithVariantNames : FastDict.Dict String.String (Set.Set String.String) }"},{"name":"packageElmJsonExposedModules","comment":" The set of modules in [`Elm-Project.Exposed`](https://dark.elm.dmy.fr/packages/elm/project-metadata-utils/latest/Elm-Project#Exposed)\n(the `exposed-modules` field in a package elm.json)\n","type":"Elm.Project.Exposed -> Set.Set Elm.Syntax.ModuleName.ModuleName"},{"name":"patternBindings","comment":" Recursively find all introduced variables\nin the [pattern](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/Elm-Syntax-Pattern)\n(like `a` and `b` in `( Just a, { b } )`)\n","type":"Elm.Syntax.Node.Node Elm.Syntax.Pattern.Pattern -> List.List String.String"},{"name":"patternSubs","comment":" All surface-level child [pattern](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/Elm-Syntax-Pattern)s\n","type":"Elm.Syntax.Node.Node Elm.Syntax.Pattern.Pattern -> List.List (Elm.Syntax.Node.Node Elm.Syntax.Pattern.Pattern)"},{"name":"removeRange","comment":" Remove the section in between a given range\n","type":"Elm.Syntax.Range.Range -> Review.SourceEdit"},{"name":"replaceRange","comment":" Replace the section in between a given range by something\n","type":"Elm.Syntax.Range.Range -> String.String -> Review.SourceEdit"},{"name":"run","comment":" Review a given project and return the errors reported by the given [`Review`](#Review)\nas a [`FastDict`](https://dark.elm.dmy.fr/packages/miniBill/elm-fast-dict/latest/)\nalong with a next [`Run`](#Run) that uses cached knowledge wherever it can.\n\n    import Review\n    import SomeConvention\n\n    doReview =\n        let\n            project =\n                { addedOrChangedModules =\n                    [ { path = \"src/A.elm\", source = \"module A exposing (a)\\na = 1\", syntax = ... }\n                    , { path = \"src/B.elm\", source = \"module B exposing (b)\\nb = 1\", syntax = ... }\n                    ]\n                , ...\n                }\n\n            runResult =\n                Review.run SomeConvention.review project\n        in\n        doSomethingWith runResult.errorsByPath\n\n(elm/core is automatically part of every project)\n\nThe resulting next [`Run`](#Run) internally keeps a cache to make it faster to re-run the review when only some files have changed.\nYou can store this resulting `nextRun` in your application state type, e.g.\n\n    Review.run\n        { run = yourApplicationState.nextRunProvidedByTheLastReviewRun\n        , ignoreErrorsForPathsWhere = SomeConvention.review.ignoreErrorsForPathsWhere\n        }\n        { addedOrChangedModules =\n            [ { path = \"src/C.elm\", source = \"module C exposing (c)\\nc = 1\", syntax = ... }\n            ]\n        , removedModulePaths = [ \"src/B.elm\" ]\n        , ...\n        }\n\n","type":"Review.Review -> { elmJson : { source : String.String, project : Elm.Project.Project }, directDependencies : List.List { elmJson : Elm.Project.Project, docsJson : List.List Elm.Docs.Module }, addedOrChangedExtraFiles : List.List { path : String.String, source : String.String }, addedOrChangedModules : List.List { path : String.String, source : String.String, syntax : Elm.Syntax.File.File }, removedExtraFilePaths : List.List String.String, removedModulePaths : List.List String.String } -> { errorsByPath : FastDict.Dict String.String (List.List { range : Elm.Syntax.Range.Range, message : String.String, details : List.List String.String, fixEditsByPath : FastDict.Dict String.String (List.List Review.SourceEdit) }), nextRun : Review.Run }"},{"name":"sourceApplyEdits","comment":" Try to apply a set of [`SourceEdit`](#SourceEdit)es to the relevant file source,\npotentially failing with a [`SourceEditError`](#SourceEditError)\n","type":"List.List Review.SourceEdit -> String.String -> Result.Result Review.SourceEditError String.String"},{"name":"sourceExtractInRange","comment":" In case you need the read the source in a range as formatted by the user.\nThis can be nice to keep the user's formatting if you just move code around\n","type":"Elm.Syntax.Range.Range -> String.String -> String.String"},{"name":"sourceRangesOf","comment":" Find all occurrences of a given section in the source in the case you\ncan't access or easily calculate the [range](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/Elm-Syntax-Range)\n","type":"String.String -> String.String -> List.List Elm.Syntax.Range.Range"},{"name":"topLevelExposeListToExposes","comment":" Collect all exposed members from an explicit exposing list of [visible expose](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/Elm-Syntax-Exposing#TopLevelExpose)s\n\n  - `simpleNames`: values, functions, type alias, opaque types (those without `(..)`), infix operators (parenthesized)\n  - `typesWithVariantNames`: names of types that expose their variants with `(..)`\n\n","type":"List.List (Elm.Syntax.Node.Node Elm.Syntax.Exposing.TopLevelExpose) -> { simpleNames : Set.Set String.String, typesExposingVariants : Set.Set String.String }"},{"name":"typeSubs","comment":" All surface-level child [type](https://dark.elm.dmy.fr/packages/stil4m/elm-syntax/latest/Elm-Syntax-TypeAnnotation)s\n","type":"Elm.Syntax.Node.Node Elm.Syntax.TypeAnnotation.TypeAnnotation -> List.List (Elm.Syntax.Node.Node Elm.Syntax.TypeAnnotation.TypeAnnotation)"}],"binops":[]},{"name":"Review.Cli","comment":"\n\n@docs program, Program\n\nIf you experience a high memory footprint in a large project,\nplease open an issue called \"only ask for file sources to generate local error displays\".\n\nThat's all you need to know.\nBelow are the internal types if you're interested:\n\n@docs ProgramEvent, ProgramState\n\n","unions":[{"name":"ProgramEvent","comment":" elm msg of a [`Review.Cli.program`](#program)\n","args":[],"cases":[["InitialFilesReceived",["{ elmJson : { source : String.String, project : Elm.Project.Project }, directDependencies : List.List { elmJson : Elm.Project.Project, docsJson : List.List Elm.Docs.Module }, extraFiles : List.List { path : String.String, source : String.String }, modules : List.List { path : String.String, source : String.String } }"]],["ModuleAddedOrChanged",["{ path : String.String, source : String.String }"]],["ModuleRemoved",["{ path : String.String }"]],["ExtraFileAddedOrChanged",["{ path : String.String, source : String.String }"]],["ExtraFileRemoved",["{ path : String.String }"]],["ErrorFixRejected",[]],["JsEventJsonFailedToDecode",["Json.Decode.Error"]]]},{"name":"ProgramState","comment":" elm model of a [`Review.program`](#program)\n","args":[],"cases":[["WaitingForInitialFiles",[]],["HavingRunReviewsPreviously",["{ nextRuns : List.List Review.Run, availableErrorsOnReject : FastDict.Dict String.String (List.List { range : Elm.Syntax.Range.Range, message : String.String, details : List.List String.String, fixEditsByPath : FastDict.Dict String.String (List.List Review.SourceEdit) }), elmJson : { source : String.String, project : Elm.Project.Project }, filesByPath : FastDict.Dict String.String String.String }"]]]}],"aliases":[{"name":"Program","comment":" An elm worker produced by [`Review.Cli.Program`](Review-Cli#Program)\n","args":[],"type":"Platform.Program () Review.Cli.ProgramState Review.Cli.ProgramEvent"}],"values":[{"name":"program","comment":" Run reviews, re-running on file changes.\nTo be used from a node.js CLI program\nas showcased in [elm-review-mini-cli-starter](https://github.com/lue-bird/elm-review-mini-cli-starter)\n","type":"{ configuration : { reviews : List.List Review.Review, extraPaths : List.List String.String }, toJs : Json.Encode.Value -> Platform.Cmd.Cmd Basics.Never, fromJs : (Json.Encode.Value -> Review.Cli.ProgramEvent) -> Platform.Sub.Sub Review.Cli.ProgramEvent } -> Review.Cli.Program"}],"binops":[]},{"name":"Review.Test","comment":" Test your review using [`elm-explorations/test`](https://dark.elm.dmy.fr/packages/elm-explorations/test/latest/).\n\nImplementing a review works really well in a Test-Driven loop:\n\n  - write a failing test before writing any code. Run it to make sure that it is failing.\n    Also write tests to ensure cases _similar_ to what you want to report are not reported.\n    For instance, if you wish to report uses of variables named `foo`, write a test\n    that ensures that the use of variables named differently does not get reported\n  - write simple (almost stupid) review code to make the test pass,\n    using `Debug.todo` etc to cut corner cases\n  - run the tests again and make sure that both new and previous tests are passing\n\nThen repeat for every case that needs to be handled.\nIdeally, by only reading through the test titles, someone else should be able to\nrecreate the rule you are testing.\n\nTests are cheap and it is better to have too many tests rather than too few,\nsince the behavior of a review rarely changes drastically.\n\nIf you like putting `Debug.log`s in your code as much as I do,\nrun your tests with [`elm-test-rs`](https://github.com/mpizenberg/elm-test-rs).\n\n@docs run, applicationConfigurationMinimal, ExpectedErrorRange\n\n","unions":[{"name":"ExpectedErrorRange","comment":" An expectation for the reported error range.\nIf the section to mark is unique in the source, use `Under \"your section source\"`.\nIf the section occurs multiple times in the source, use `UnderExactly { section = \"your section source\", startingAt = { row = ..., column = ... } }`\n","args":[],"cases":[["Under",["String.String"]],["UnderExactly",["{ section : String.String, startingAt : Elm.Syntax.Range.Location }"]]]}],"aliases":[],"values":[{"name":"applicationConfigurationMinimal","comment":" The default project after `elm init` minus the `elm/html` and `elm/browser` dependencies.\nEquivalent to (copy and adapt if necessary)\n\n    { elmJson = \"\"\"\n        {\n            \"type\": \"application\",\n            \"source-directories\": [\n                \"src\"\n            ],\n            \"elm-version\": \"0.19.1\",\n            \"dependencies\": {\n                \"direct\": {\n                    \"elm/core\": \"1.0.5\"\n                },\n                \"indirect\": {\n                    \"elm/json\": \"1.1.3\"\n                }\n            },\n            \"test-dependencies\": {\n                \"direct\": {},\n                \"indirect\": {}\n            }\n        }\n        \"\"\"\n    , directDependencies = []\n    }\n\n(elm/core is automatically part of every tested project)\n\n","type":"{ elmJson : String.String, directDependencies : List.List { elmJson : String.String, docsJson : String.String } }"},{"name":"run","comment":" Run a `Review` on a project, matching all reported module errors, `elm.json` errors and extra file errors\nwith your provided expected errors.\n\n    import Review.Test\n    import Test exposing (Test)\n    import DebugForbid\n\n    tests : Test\n    tests =\n        Test.describe \"DebugForbid\"\n            [ Test.test \"report Debug.log use\"\n                (\\() ->\n                    { files =\n                        [ { path = \"src/A.elm\"\n                          , source = \"\"\"\n                                module A exposing (a)\n                                import Html\n                                a =\n                                    Debug.log \"some\" \"message\"\n                                \"\"\"\n                          }\n                        ]\n                    , projectConfiguration =\n                    , review = DebugForbid.review\n                    , expectedErrors =\n                        [ { path = \"src/A.elm\"\n                          , message = \"Remove the use of `Debug` before shipping to production\"\n                          , details = [ \"Compiling elm code in optimized mode does not allow these helpers.\" ]\n                          , range = Review.Test.Under \"Debug.log\"\n                          , fixedFiles =\n                              [ { path = \"src/A.elm\"\n                                , source = \"\"\"\n                                    module A exposing (a)\n                                    a =\n                                        \"message\"\n                                    \"\"\"\n                                }\n                              ]\n                          }\n                        ]\n                    }\n                        |> Review.Test.run\n                )\n            ]\n\nThe extra indentation specified by the first line will be stripped of all the provided source strings.\n\nYou can also specify a custom project config in case you need to test a package\nor want to add dependencies (elm/core is automatically part of every tested project)\nby supplying the raw sources for the `elm.json` and the direct dependency `docs.json`\nand `elm.json` you can find in your elm root folder.\n\n","type":"{ files : List.List { path : String.String, source : String.String }, projectConfiguration : { elmJson : String.String, directDependencies : List.List { elmJson : String.String, docsJson : String.String } }, review : Review.Review, expectedErrors : List.List { path : String.String, message : String.String, details : List.List String.String, range : Review.Test.ExpectedErrorRange, fixedFiles : List.List { path : String.String, source : String.String } } } -> Expect.Expectation"}],"binops":[]}]