mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-11-29 01:24:35 +03:00
Add docs+example for withExtraFilesModuleVisitor
This commit is contained in:
parent
d842a6a48d
commit
e2a8067855
@ -1903,6 +1903,8 @@ doesn't analyze by default.
|
|||||||
|
|
||||||
The visitor function will be called with all the files matching the file patterns.
|
The visitor function will be called with all the files matching the file patterns.
|
||||||
|
|
||||||
|
REPLACEME
|
||||||
|
|
||||||
The following example rule reads a project's `.css` files to extract all the mentioned CSS classes,
|
The following example rule reads a project's `.css` files to extract all the mentioned CSS classes,
|
||||||
then finds calls to `Html.Attributes.class` in the Elm code (such as `Html.Attributes.class "big-red-button"`)
|
then finds calls to `Html.Attributes.class` in the Elm code (such as `Html.Attributes.class "big-red-button"`)
|
||||||
and reports errors when the classes given as argument are unknown.
|
and reports errors when the classes given as argument are unknown.
|
||||||
@ -2497,7 +2499,96 @@ withElmJsonModuleVisitor visitor (ModuleRuleSchema schema) =
|
|||||||
ModuleRuleSchema { schema | elmJsonVisitor = Just (combineContextOnlyVisitor visitor schema.elmJsonVisitor) }
|
ModuleRuleSchema { schema | elmJsonVisitor = Just (combineContextOnlyVisitor visitor schema.elmJsonVisitor) }
|
||||||
|
|
||||||
|
|
||||||
{-| REPLACEME
|
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) to visit files that `elm-review`
|
||||||
|
doesn't analyze by default.
|
||||||
|
|
||||||
|
The visitor function will be called with all the files matching the file patterns.
|
||||||
|
|
||||||
|
The following example rule reads a project's `.css` files to extract all the mentioned CSS classes,
|
||||||
|
then finds calls to `Html.Attributes.class` in the Elm code (such as `Html.Attributes.class "big-red-button"`)
|
||||||
|
and reports errors when the classes given as argument are unknown.
|
||||||
|
|
||||||
|
import Dict exposing (Dict)
|
||||||
|
import Elm.Syntax.Expression as Expression exposing (Expression)
|
||||||
|
import Elm.Syntax.Node as Node exposing (Node)
|
||||||
|
import Elm.Syntax.Range exposing (Range)
|
||||||
|
import Regex exposing (Regex)
|
||||||
|
import Review.FilePattern as FilePattern
|
||||||
|
import Review.Rule as Rule exposing (Rule)
|
||||||
|
import Set exposing (Set)
|
||||||
|
|
||||||
|
rule : Rule
|
||||||
|
rule =
|
||||||
|
Rule.newModuleRuleSchema "Css.NoUnknownCssClasses" initialContext
|
||||||
|
|> Rule.withExtraFilesModuleVisitor cssFilesVisitor
|
||||||
|
[ FilePattern.include "**/*.css" ]
|
||||||
|
|> Rule.withExpressionEnterVisitor expressionVisitor
|
||||||
|
|> Rule.fromModuleRuleSchema
|
||||||
|
|
||||||
|
type alias Context =
|
||||||
|
{ knownCssClasses : Set String
|
||||||
|
}
|
||||||
|
|
||||||
|
initialContext : Context
|
||||||
|
initialContext =
|
||||||
|
{ knownCssClasses = Set.empty
|
||||||
|
}
|
||||||
|
|
||||||
|
cssClassRegex : Regex
|
||||||
|
cssClassRegex =
|
||||||
|
Regex.fromString "\\.([\\w-_]+)"
|
||||||
|
|> Maybe.withDefault Regex.never
|
||||||
|
|
||||||
|
cssFilesVisitor : Dict String String -> Context -> Context
|
||||||
|
cssFilesVisitor files context =
|
||||||
|
{ knownCssClasses =
|
||||||
|
files
|
||||||
|
|> Dict.values
|
||||||
|
|> List.concatMap (\cssSource -> Regex.find cssClassRegex cssSource)
|
||||||
|
|> List.map (\m -> String.dropLeft 1 m.match)
|
||||||
|
|> Set.fromList
|
||||||
|
}
|
||||||
|
|
||||||
|
expressionVisitor : Node Expression -> Context -> ( List (Rule.Error {}), Context )
|
||||||
|
expressionVisitor node context =
|
||||||
|
case Node.value node of
|
||||||
|
Expression.Application [ function, firstArg ] ->
|
||||||
|
case Node.value function of
|
||||||
|
Expression.FunctionOrValue [ "Html", "Attributes" ] "class" ->
|
||||||
|
case Node.value firstArg of
|
||||||
|
Expression.Literal stringLiteral ->
|
||||||
|
( stringLiteral
|
||||||
|
|> String.split " "
|
||||||
|
|> List.filterMap (checkForUnknownCssClass context.knownCssClasses (Node.range firstArg))
|
||||||
|
, context
|
||||||
|
)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
( [], context )
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
( [], context )
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
( [], context )
|
||||||
|
|
||||||
|
checkForUnknownCssClass : Set String -> Range -> String -> Maybe (Rule.Error {})
|
||||||
|
checkForUnknownCssClass knownCssClasses range class =
|
||||||
|
if Set.member class knownCssClasses then
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
else
|
||||||
|
Just
|
||||||
|
(Rule.error
|
||||||
|
{ message = "Unknown CSS class " ++ class
|
||||||
|
, details =
|
||||||
|
[ "This CSS class does not appear in the project's `.css` files."
|
||||||
|
, "Could it be that you misspelled the name of the class, or that the class recently got removed?"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
range
|
||||||
|
)
|
||||||
|
|
||||||
-}
|
-}
|
||||||
withExtraFilesModuleVisitor :
|
withExtraFilesModuleVisitor :
|
||||||
(Dict String String -> moduleContext -> moduleContext)
|
(Dict String String -> moduleContext -> moduleContext)
|
||||||
|
Loading…
Reference in New Issue
Block a user