2020-04-08 01:14:03 +03:00
|
|
|
module NoImportingEverything exposing (rule)
|
2019-06-03 01:30:24 +03:00
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
{-|
|
2019-06-03 01:30:24 +03:00
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
@docs rule
|
2019-07-03 15:19:29 +03:00
|
|
|
|
2019-06-03 01:30:24 +03:00
|
|
|
-}
|
|
|
|
|
|
|
|
import Elm.Syntax.Exposing as Exposing
|
|
|
|
import Elm.Syntax.Import exposing (Import)
|
|
|
|
import Elm.Syntax.Node as Node exposing (Node)
|
2019-09-29 00:47:02 +03:00
|
|
|
import Review.Rule as Rule exposing (Error, Rule)
|
2020-06-20 16:13:37 +03:00
|
|
|
import Review.Rule3 as Rule3
|
2020-04-08 01:14:03 +03:00
|
|
|
import Set exposing (Set)
|
2019-06-03 01:30:24 +03:00
|
|
|
|
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
{-| Forbids importing everything from a module.
|
2019-06-03 01:30:24 +03:00
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
When you import everything from a module, it becomes harder to know where a function
|
|
|
|
or a type comes from. The official guide even
|
|
|
|
[recommends against importing everything](https://guide.elm-lang.org/webapps/modules.html#using-modules).
|
2019-06-03 01:30:24 +03:00
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
config =
|
|
|
|
[ NoImportingEverything.rule []
|
|
|
|
]
|
2019-06-03 01:30:24 +03:00
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
Teams often have an agreement on the list of imports from which it is okay to expose everything, so
|
|
|
|
you can configure a list of exceptions.
|
2019-07-23 00:38:39 +03:00
|
|
|
|
2019-07-23 00:50:24 +03:00
|
|
|
config =
|
2020-04-08 01:14:03 +03:00
|
|
|
[ NoImportingEverything.rule [ "Html", "Some.Module" ]
|
2019-07-23 00:50:24 +03:00
|
|
|
]
|
|
|
|
|
2019-07-23 00:38:39 +03:00
|
|
|
|
|
|
|
## Fail
|
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
import A exposing (..)
|
|
|
|
import A as B exposing (..)
|
2019-07-23 00:38:39 +03:00
|
|
|
|
|
|
|
|
|
|
|
## Success
|
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
import A as B exposing (B(..), C, d)
|
2019-07-23 00:38:39 +03:00
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
-- If configured with `[ "Html" ]`
|
2019-07-23 00:38:39 +03:00
|
|
|
import Html exposing (..)
|
|
|
|
|
2019-06-03 01:30:24 +03:00
|
|
|
-}
|
2020-04-08 01:14:03 +03:00
|
|
|
rule : List String -> Rule
|
|
|
|
rule exceptions =
|
2020-06-20 16:13:37 +03:00
|
|
|
Rule3.newModuleRuleSchema_New "NoImportingEverything" ()
|
|
|
|
|> Rule3.withSimpleImportVisitor_New (importVisitor <| exceptionsToSet exceptions)
|
|
|
|
|> Rule3.fromModuleRuleSchema_New
|
2019-06-03 01:30:24 +03:00
|
|
|
|
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
exceptionsToSet : List String -> Set (List String)
|
|
|
|
exceptionsToSet exceptions =
|
|
|
|
exceptions
|
|
|
|
|> List.map (String.split ".")
|
|
|
|
|> Set.fromList
|
2019-06-03 01:30:24 +03:00
|
|
|
|
|
|
|
|
2020-04-08 01:14:03 +03:00
|
|
|
importVisitor : Set (List String) -> Node Import -> List (Error {})
|
|
|
|
importVisitor exceptions node =
|
|
|
|
if Set.member (moduleName node) exceptions then
|
2019-06-16 22:12:37 +03:00
|
|
|
[]
|
2019-06-03 01:30:24 +03:00
|
|
|
|
|
|
|
else
|
2020-04-08 01:14:03 +03:00
|
|
|
case
|
|
|
|
Node.value node
|
|
|
|
|> .exposingList
|
|
|
|
|> Maybe.map Node.value
|
|
|
|
of
|
2019-06-03 01:30:24 +03:00
|
|
|
Just (Exposing.All range) ->
|
2020-04-08 01:14:03 +03:00
|
|
|
[ Rule.error
|
|
|
|
{ message = "Prefer listing what you wish to import and/or using qualified imports"
|
|
|
|
, details = [ "When you import everything from a module, it becomes harder to know where a function or a type comes from" ]
|
|
|
|
}
|
|
|
|
{ start = { row = range.start.row, column = range.start.column - 1 }
|
|
|
|
, end = { row = range.end.row, column = range.end.column + 1 }
|
|
|
|
}
|
|
|
|
]
|
2019-06-03 01:30:24 +03:00
|
|
|
|
|
|
|
_ ->
|
2019-06-16 22:12:37 +03:00
|
|
|
[]
|
2020-04-08 01:14:03 +03:00
|
|
|
|
|
|
|
|
|
|
|
moduleName : Node Import -> List String
|
|
|
|
moduleName node =
|
|
|
|
node
|
|
|
|
|> Node.value
|
|
|
|
|> .moduleName
|
|
|
|
|> Node.value
|