mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-11-22 22:33:13 +03:00
Expose ModuleNameLookupTable
This commit is contained in:
parent
0ff71b2c84
commit
f6f5326f3d
1
elm.json
1
elm.json
@ -6,6 +6,7 @@
|
||||
"version": "2.2.0",
|
||||
"exposed-modules": [
|
||||
"Review.Rule",
|
||||
"Review.ModuleNameLookupTable",
|
||||
"Review.Project",
|
||||
"Review.Project.Dependency",
|
||||
"Review.Fix",
|
||||
|
@ -1,8 +1,23 @@
|
||||
module Review.ModuleNameLookupTable exposing
|
||||
( ModuleNameLookupTable
|
||||
, moduleNameAt
|
||||
, moduleNameFor
|
||||
)
|
||||
module Review.ModuleNameLookupTable exposing (ModuleNameLookupTable, moduleNameFor, moduleNameAt)
|
||||
|
||||
{-| Looks up the name of the module a function or type comes from based on the position of the element in the module's AST.
|
||||
|
||||
When encountering a `Expression.FunctionOrValue ModuleName String` (among other nodes where we refer to a function or value),
|
||||
the module name available represents the module name that is in the source code. But that module name can be an alias to
|
||||
a different import, or it can be empty, meaning that it refers to a local value or one that has been imported explicitly
|
||||
or implicitly. Resolving which module name the type or function can be a bit tricky sometimes, and I recommend against
|
||||
doing it yourself.
|
||||
|
||||
`elm-review` computes this for you already. Store this value inside your module context, then use
|
||||
[`ModuleNameLookupTable.moduleNameFor`](./Review-ModuleNameLookupTable#moduleNameFor) or
|
||||
[`ModuleNameLookupTable.moduleNameAt`](./Review-ModuleNameLookupTable#moduleNameAt) to get the name of the module the
|
||||
type or value comes from.
|
||||
|
||||
@docs ModuleNameLookupTable, moduleNameFor, moduleNameAt
|
||||
|
||||
Note: If you have been using [`elm-review-scope`](https://github.com/jfmengels/elm-review-scope) before, you should use this instead.
|
||||
|
||||
-}
|
||||
|
||||
import Dict
|
||||
import Elm.Syntax.ModuleName exposing (ModuleName)
|
||||
@ -11,15 +26,80 @@ import Elm.Syntax.Range exposing (Range)
|
||||
import Review.ModuleNameLookupTable.Internal as Internal
|
||||
|
||||
|
||||
{-| Associates positions in the AST of a module to the name of the module that the contained variable or type originates
|
||||
from.
|
||||
-}
|
||||
type alias ModuleNameLookupTable =
|
||||
Internal.ModuleNameLookupTable
|
||||
|
||||
|
||||
{-| Returns the name of the module the type or value referred to by this [`Node`](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.1.0/Elm-Syntax-Node#Node).
|
||||
|
||||
The function returns `Just []` if the type or value was defined in this module. It returns `Just moduleName` if the Node is among these kinds of AST nodes (and `Nothing` for all the others):
|
||||
|
||||
- Expression.FunctionOrValue
|
||||
- `nodeForTheName` in `Expression.RecordUpdateExpression nodeForTheName modifiers`
|
||||
- `nodeForTheName` in `TypeAnnotation.Typed nodeForTheName args`
|
||||
- `nodeForTheName` in `Pattern.NamedPattern nodeForTheName subPatterns`
|
||||
|
||||
```elm
|
||||
expressionVisitor : Node Expression -> Context -> ( List (Error {}), Context )
|
||||
expressionVisitor node context =
|
||||
case Node.value node of
|
||||
Expression.FunctionOrValue _ "color" ->
|
||||
if ModuleNameLookupTable.moduleNameFor context.lookupTable node == Just [ "Css" ] then
|
||||
( [ Rule.error
|
||||
{ message = "Do not use `Css.color` directly, use the Colors module instead"
|
||||
, details = [ "We made a module which contains all the available colors of our design system. Use the functions in there instead." ]
|
||||
}
|
||||
(Node.range node)
|
||||
]
|
||||
, context
|
||||
)
|
||||
|
||||
else
|
||||
( [], context )
|
||||
|
||||
_ ->
|
||||
( [], context )
|
||||
```
|
||||
|
||||
Note: If using a `Range` is easier in your situation than using a `Node`, use [`moduleNameAt`](#moduleNameAt) instead.
|
||||
|
||||
-}
|
||||
moduleNameFor : ModuleNameLookupTable -> Node a -> Maybe ModuleName
|
||||
moduleNameFor (Internal.ModuleNameLookupTable dict) (Node range _) =
|
||||
Dict.get (Internal.toRangeLike range) dict
|
||||
|
||||
|
||||
{-| Returns the name of the module the type or value referred to by this [`Node`](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.1.0/Elm-Syntax-Node#Node).
|
||||
|
||||
The function returns `Just []` if the type or value was defined in this module. It returns `Just moduleName` if the Node is among these kinds of AST nodes (and `Nothing` for all the others):
|
||||
|
||||
- Expression.FunctionOrValue
|
||||
- `nodeForTheName` in `Expression.RecordUpdateExpression nodeForTheName modifiers`
|
||||
- `nodeForTheName` in `TypeAnnotation.Typed nodeForTheName args`
|
||||
- `nodeForTheName` in `Pattern.NamedPattern nodeForTheName subPatterns`
|
||||
|
||||
```elm
|
||||
expressionVisitor : Node Expression -> Context -> ( List (Error {}), Context )
|
||||
expressionVisitor node context =
|
||||
case Node.value node of
|
||||
Expression.RecordUpdateExpr (Node range name) _ ->
|
||||
case ModuleNameLookupTable.moduleNameAt context.lookupTable range of
|
||||
Just moduleName ->
|
||||
( [], markVariableAsUsed ( moduleName, name ) context )
|
||||
|
||||
Nothing ->
|
||||
( [], context )
|
||||
|
||||
_ ->
|
||||
( [], context )
|
||||
```
|
||||
|
||||
Note: If using a `Node` is easier in your situation than using a `Range`, use [`moduleNameFor`](#moduleNameFor) instead.
|
||||
|
||||
-}
|
||||
moduleNameAt : ModuleNameLookupTable -> Range -> Maybe ModuleName
|
||||
moduleNameAt (Internal.ModuleNameLookupTable dict) range =
|
||||
Dict.get (Internal.toRangeLike range) dict
|
||||
|
@ -4100,10 +4100,11 @@ withMetadata (ContextCreator fn (RequestedData requested)) =
|
||||
|
||||
{-| Requests the module name lookup table for the types and functions inside a module.
|
||||
|
||||
When encountering a `Expression.FunctionOrValue ModuleName String`, the module name available represents the module name
|
||||
that is in the source code. But that module name can be an alias to a different import, or it can be empty, meaning that
|
||||
it refers to a local value or one that has been imported explicitly or implicitly. Resolving which module name the type
|
||||
or function can be a bit tricky sometimes, and I recommend against doing it yourself.
|
||||
When encountering a `Expression.FunctionOrValue ModuleName String` (among other nodes where we refer to a function or value),
|
||||
the module name available represents the module name that is in the source code. But that module name can be an alias to
|
||||
a different import, or it can be empty, meaning that it refers to a local value or one that has been imported explicitly
|
||||
or implicitly. Resolving which module name the type or function can be a bit tricky sometimes, and I recommend against
|
||||
doing it yourself.
|
||||
|
||||
`elm-review` computes this for you already. Store this value inside your module context, then use
|
||||
[`ModuleNameLookupTable.moduleNameFor`](./Review-ModuleNameLookupTable#moduleNameFor) or
|
||||
@ -4148,7 +4149,7 @@ type or value comes from.
|
||||
_ ->
|
||||
( [], context )
|
||||
|
||||
Note: If you have been using [`elm-review-scope`](https://github.com/jfmengels/elm-review-scope) before, you might want to use this instead.
|
||||
Note: If you have been using [`elm-review-scope`](https://github.com/jfmengels/elm-review-scope) before, you should use this instead.
|
||||
|
||||
-}
|
||||
withModuleNameLookupTable : ContextCreator ModuleNameLookupTable (from -> to) -> ContextCreator from to
|
||||
|
Loading…
Reference in New Issue
Block a user