mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-08-17 12:00:29 +03:00
Add withDirectDependencies visitors
This commit is contained in:
parent
d82a69d0a2
commit
d746a21c9a
@ -3,7 +3,7 @@ module Review.Project exposing
|
||||
, ProjectModule, addModule, addParsedModule, removeModule, modules, modulesThatFailedToParse, precomputeModuleGraph
|
||||
, addElmJson, elmJson
|
||||
, addReadme, readme
|
||||
, addDependency, removeDependency, removeDependencies, dependencies
|
||||
, addDependency, removeDependency, removeDependencies, directDependencies, dependencies
|
||||
)
|
||||
|
||||
{-| Represents the contents of the project to be analyzed. This information will
|
||||
@ -37,11 +37,12 @@ does not look at project information (like the `elm.json`, dependencies, ...).
|
||||
|
||||
# Project dependencies
|
||||
|
||||
@docs addDependency, removeDependency, removeDependencies, dependencies
|
||||
@docs addDependency, removeDependency, removeDependencies, directDependencies, dependencies
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Elm.Package
|
||||
import Elm.Project
|
||||
import Elm.Syntax.File
|
||||
import Elm.Syntax.ModuleName exposing (ModuleName)
|
||||
@ -398,6 +399,31 @@ dependencies (Internal.Project project) =
|
||||
project.dependencies
|
||||
|
||||
|
||||
{-| Get the direct [dependencies](./Review-Project-Dependency#Dependency) of the project.
|
||||
-}
|
||||
directDependencies : Project -> Dict String Dependency
|
||||
directDependencies (Internal.Project project) =
|
||||
case Maybe.map .project project.elmJson of
|
||||
Just (Elm.Project.Application { depsDirect, testDepsDirect }) ->
|
||||
let
|
||||
allDeps : List String
|
||||
allDeps =
|
||||
List.map (\( name, _ ) -> Elm.Package.toString name) (depsDirect ++ testDepsDirect)
|
||||
in
|
||||
Dict.filter (\depName _ -> List.member depName allDeps) project.dependencies
|
||||
|
||||
Just (Elm.Project.Package { deps, testDeps }) ->
|
||||
let
|
||||
allDeps : List String
|
||||
allDeps =
|
||||
List.map (\( name, _ ) -> Elm.Package.toString name) (deps ++ testDeps)
|
||||
in
|
||||
Dict.filter (\depName _ -> List.member depName allDeps) project.dependencies
|
||||
|
||||
Nothing ->
|
||||
project.dependencies
|
||||
|
||||
|
||||
makePathOSAgnostic : String -> String
|
||||
makePathOSAgnostic path =
|
||||
String.replace "\\" "/" path
|
||||
|
@ -12,8 +12,8 @@ module Review.Rule exposing
|
||||
, withCaseBranchEnterVisitor, withCaseBranchExitVisitor
|
||||
, withLetDeclarationEnterVisitor, withLetDeclarationExitVisitor
|
||||
, withFinalModuleEvaluation
|
||||
, withElmJsonModuleVisitor, withReadmeModuleVisitor, withDependenciesModuleVisitor
|
||||
, ProjectRuleSchema, newProjectRuleSchema, fromProjectRuleSchema, withModuleVisitor, withModuleContext, withModuleContextUsingContextCreator, withElmJsonProjectVisitor, withReadmeProjectVisitor, withDependenciesProjectVisitor, withFinalProjectEvaluation, withContextFromImportedModules
|
||||
, withElmJsonModuleVisitor, withReadmeModuleVisitor, withDirectDependenciesModuleVisitor, withDependenciesModuleVisitor
|
||||
, ProjectRuleSchema, newProjectRuleSchema, fromProjectRuleSchema, withModuleVisitor, withModuleContext, withModuleContextUsingContextCreator, withElmJsonProjectVisitor, withReadmeProjectVisitor, withDirectDependenciesProjectVisitor, withDependenciesProjectVisitor, withFinalProjectEvaluation, withContextFromImportedModules
|
||||
, ContextCreator, initContextCreator, withModuleName, withModuleNameNode, withIsInSourceDirectories, withFilePath, withModuleNameLookupTable, withModuleKey, withSourceCodeExtractor, withFullAst, withModuleDocumentation
|
||||
, Metadata, withMetadata, moduleNameFromMetadata, moduleNameNodeFromMetadata, isInSourceDirectories
|
||||
, Error, error, errorWithFix, ModuleKey, errorForModule, errorForModuleWithFix, ElmJsonKey, errorForElmJson, errorForElmJsonWithFix, ReadmeKey, errorForReadme, errorForReadmeWithFix
|
||||
@ -162,7 +162,7 @@ The traversal of a module rule is the following:
|
||||
- Read project-related info (only collect data in the context in these steps)
|
||||
- The `elm.json` file, visited by [`withElmJsonModuleVisitor`](#withElmJsonModuleVisitor)
|
||||
- The `README.md` file, visited by [`withReadmeModuleVisitor`](#withReadmeModuleVisitor)
|
||||
- The definition for dependencies, visited by [`withDependenciesModuleVisitor`](#withDependenciesModuleVisitor)
|
||||
- The definition for dependencies, visited by [`withDirectDependenciesModuleVisitor`](#withDirectDependenciesModuleVisitor) and [`withDependenciesModuleVisitor`](#withDependenciesModuleVisitor)
|
||||
- Visit the Elm module (in the following order)
|
||||
- The module definition, visited by [`withSimpleModuleDefinitionVisitor`](#withSimpleModuleDefinitionVisitor) and [`withModuleDefinitionVisitor`](#withModuleDefinitionVisitor)
|
||||
- The module documentation, visited by [`withModuleDocumentationVisitor`](#withModuleDocumentationVisitor)
|
||||
@ -206,7 +206,7 @@ Evaluating/visiting a node means two things:
|
||||
|
||||
## Builder functions to analyze the project's data
|
||||
|
||||
@docs withElmJsonModuleVisitor, withReadmeModuleVisitor, withDependenciesModuleVisitor
|
||||
@docs withElmJsonModuleVisitor, withReadmeModuleVisitor, withDirectDependenciesModuleVisitor, withDependenciesModuleVisitor
|
||||
|
||||
|
||||
## Creating a project rule
|
||||
@ -222,7 +222,7 @@ Project rules can also report errors in the `elm.json` or the `README.md` files.
|
||||
If you are new to writing rules, I would recommend learning [how to build a module rule](#creating-a-module-rule)
|
||||
first, as they are in practice a simpler version of project rules.
|
||||
|
||||
@docs ProjectRuleSchema, newProjectRuleSchema, fromProjectRuleSchema, withModuleVisitor, withModuleContext, withModuleContextUsingContextCreator, withElmJsonProjectVisitor, withReadmeProjectVisitor, withDependenciesProjectVisitor, withFinalProjectEvaluation, withContextFromImportedModules
|
||||
@docs ProjectRuleSchema, newProjectRuleSchema, fromProjectRuleSchema, withModuleVisitor, withModuleContext, withModuleContextUsingContextCreator, withElmJsonProjectVisitor, withReadmeProjectVisitor, withDirectDependenciesProjectVisitor, withDependenciesProjectVisitor, withFinalProjectEvaluation, withContextFromImportedModules
|
||||
|
||||
|
||||
## Requesting more information
|
||||
@ -365,6 +365,7 @@ type alias ModuleRuleSchemaData moduleContext =
|
||||
, elmJsonVisitors : List (Maybe Elm.Project.Project -> moduleContext -> moduleContext)
|
||||
, readmeVisitors : List (Maybe String -> moduleContext -> moduleContext)
|
||||
, dependenciesVisitors : List (Dict String Review.Project.Dependency.Dependency -> moduleContext -> moduleContext)
|
||||
, directDependenciesVisitors : List (Dict String Review.Project.Dependency.Dependency -> moduleContext -> moduleContext)
|
||||
}
|
||||
|
||||
|
||||
@ -997,6 +998,7 @@ newModuleRuleSchema name initialModuleContext =
|
||||
, elmJsonVisitors = []
|
||||
, readmeVisitors = []
|
||||
, dependenciesVisitors = []
|
||||
, directDependenciesVisitors = []
|
||||
}
|
||||
|
||||
|
||||
@ -1062,6 +1064,7 @@ newModuleRuleSchemaUsingContextCreator name moduleContextCreator =
|
||||
, elmJsonVisitors = []
|
||||
, readmeVisitors = []
|
||||
, dependenciesVisitors = []
|
||||
, directDependenciesVisitors = []
|
||||
}
|
||||
|
||||
|
||||
@ -1077,6 +1080,7 @@ fromModuleRuleSchema ((ModuleRuleSchema schema) as moduleVisitor) =
|
||||
, initialProjectContext = initialModuleContext
|
||||
, elmJsonVisitors = compactProjectDataVisitors (Maybe.map .project) schema.elmJsonVisitors
|
||||
, readmeVisitors = compactProjectDataVisitors (Maybe.map .content) schema.readmeVisitors
|
||||
, directDependenciesVisitors = compactProjectDataVisitors identity schema.directDependenciesVisitors
|
||||
, dependenciesVisitors = compactProjectDataVisitors identity schema.dependenciesVisitors
|
||||
, moduleVisitors = [ removeExtensibleRecordTypeVariable (always moduleVisitor) ]
|
||||
, moduleContextCreator = Just (initContextCreator identity)
|
||||
@ -1093,6 +1097,7 @@ fromModuleRuleSchema ((ModuleRuleSchema schema) as moduleVisitor) =
|
||||
, initialProjectContext = ()
|
||||
, elmJsonVisitors = []
|
||||
, readmeVisitors = []
|
||||
, directDependenciesVisitors = []
|
||||
, dependenciesVisitors = []
|
||||
, moduleVisitors = [ removeExtensibleRecordTypeVariable (always moduleVisitor) ]
|
||||
, moduleContextCreator = Just schema.moduleContextCreator
|
||||
@ -1141,6 +1146,7 @@ type ProjectRuleSchema schemaState projectContext moduleContext
|
||||
, initialProjectContext : projectContext
|
||||
, elmJsonVisitors : List (Maybe { elmJsonKey : ElmJsonKey, project : Elm.Project.Project } -> projectContext -> ( List (Error {}), projectContext ))
|
||||
, readmeVisitors : List (Maybe { readmeKey : ReadmeKey, content : String } -> projectContext -> ( List (Error {}), projectContext ))
|
||||
, directDependenciesVisitors : List (Dict String Review.Project.Dependency.Dependency -> projectContext -> ( List (Error {}), projectContext ))
|
||||
, dependenciesVisitors : List (Dict String Review.Project.Dependency.Dependency -> projectContext -> ( List (Error {}), projectContext ))
|
||||
, moduleVisitors : List (ModuleRuleSchema {} moduleContext -> ModuleRuleSchema { hasAtLeastOneVisitor : () } moduleContext)
|
||||
, moduleContextCreator : Maybe (ContextCreator projectContext moduleContext)
|
||||
@ -1200,6 +1206,7 @@ newProjectRuleSchema name initialProjectContext =
|
||||
, initialProjectContext = initialProjectContext
|
||||
, elmJsonVisitors = []
|
||||
, readmeVisitors = []
|
||||
, directDependenciesVisitors = []
|
||||
, dependenciesVisitors = []
|
||||
, moduleVisitors = []
|
||||
, moduleContextCreator = Nothing
|
||||
@ -1246,6 +1253,7 @@ fromProjectRuleSchemaToRunnableProjectVisitor (ProjectRuleSchema schema) =
|
||||
{ initialProjectContext = schema.initialProjectContext
|
||||
, elmJsonVisitors = List.reverse schema.elmJsonVisitors
|
||||
, readmeVisitors = List.reverse schema.readmeVisitors
|
||||
, directDependenciesVisitors = List.reverse schema.directDependenciesVisitors
|
||||
, dependenciesVisitors = List.reverse schema.dependenciesVisitors
|
||||
, moduleVisitor = mergeModuleVisitors schema.initialProjectContext schema.moduleContextCreator schema.moduleVisitors
|
||||
, traversalAndFolder =
|
||||
@ -1346,6 +1354,7 @@ mergeModuleVisitorsHelp initialProjectContext moduleContextCreator visitors =
|
||||
, elmJsonVisitors = []
|
||||
, readmeVisitors = []
|
||||
, dependenciesVisitors = []
|
||||
, directDependenciesVisitors = []
|
||||
}
|
||||
in
|
||||
( List.foldl
|
||||
@ -1856,7 +1865,7 @@ withReadmeProjectVisitor visitor (ProjectRuleSchema schema) =
|
||||
ProjectRuleSchema { schema | readmeVisitors = removeErrorPhantomTypeFromVisitor visitor :: schema.readmeVisitors }
|
||||
|
||||
|
||||
{-| Add a visitor to the [`ProjectRuleSchema`](#ProjectRuleSchema) which will visit the project's
|
||||
{-| Add a visitor to the [`ProjectRuleSchema`](#ProjectRuleSchema) which will examine the project's
|
||||
[dependencies](./Review-Project-Dependency).
|
||||
|
||||
It works exactly like [`withDependenciesModuleVisitor`](#withDependenciesModuleVisitor). The visitor will be called before any
|
||||
@ -1871,6 +1880,21 @@ withDependenciesProjectVisitor visitor (ProjectRuleSchema schema) =
|
||||
ProjectRuleSchema { schema | dependenciesVisitors = removeErrorPhantomTypeFromVisitor visitor :: schema.dependenciesVisitors }
|
||||
|
||||
|
||||
{-| Add a visitor to the [`ProjectRuleSchema`](#ProjectRuleSchema) which will examine the project's
|
||||
direct [dependencies](./Review-Project-Dependency).
|
||||
|
||||
It works exactly like [`withDependenciesModuleVisitor`](#withDependenciesModuleVisitor). The visitor will be called before any
|
||||
module is evaluated.
|
||||
|
||||
-}
|
||||
withDirectDependenciesProjectVisitor :
|
||||
(Dict String Review.Project.Dependency.Dependency -> projectContext -> ( List (Error { useErrorForModule : () }), projectContext ))
|
||||
-> ProjectRuleSchema schemaState projectContext moduleContext
|
||||
-> ProjectRuleSchema { schemaState | hasAtLeastOneVisitor : () } projectContext moduleContext
|
||||
withDirectDependenciesProjectVisitor visitor (ProjectRuleSchema schema) =
|
||||
ProjectRuleSchema { schema | directDependenciesVisitors = removeErrorPhantomTypeFromVisitor visitor :: schema.directDependenciesVisitors }
|
||||
|
||||
|
||||
{-| Add a function that makes a final evaluation of the project based only on the
|
||||
data that was collected in the `projectContext`. This can be useful if you can't report something until you have visited
|
||||
all the modules in the project.
|
||||
@ -2288,7 +2312,7 @@ withReadmeModuleVisitor visitor (ModuleRuleSchema schema) =
|
||||
ModuleRuleSchema { schema | readmeVisitors = visitor :: schema.readmeVisitors }
|
||||
|
||||
|
||||
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) which will visit the project's
|
||||
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) which will examine the project's
|
||||
[dependencies](./Review-Project-Dependency).
|
||||
|
||||
You can use this look at the modules contained in dependencies, which can make the rule very precise when it targets
|
||||
@ -2303,6 +2327,21 @@ withDependenciesModuleVisitor visitor (ModuleRuleSchema schema) =
|
||||
ModuleRuleSchema { schema | dependenciesVisitors = visitor :: schema.dependenciesVisitors }
|
||||
|
||||
|
||||
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) which will examine the project's
|
||||
direct [dependencies](./Review-Project-Dependency).
|
||||
|
||||
You can use this look at the modules contained in dependencies, which can make the rule very precise when it targets
|
||||
specific functions.
|
||||
|
||||
-}
|
||||
withDirectDependenciesModuleVisitor :
|
||||
(Dict String Review.Project.Dependency.Dependency -> moduleContext -> moduleContext)
|
||||
-> ModuleRuleSchema { schemaState | canCollectProjectData : () } moduleContext
|
||||
-> ModuleRuleSchema { schemaState | canCollectProjectData : () } moduleContext
|
||||
withDirectDependenciesModuleVisitor visitor (ModuleRuleSchema schema) =
|
||||
ModuleRuleSchema { schema | directDependenciesVisitors = visitor :: schema.directDependenciesVisitors }
|
||||
|
||||
|
||||
{-| Add a visitor to the [`ModuleRuleSchema`](#ModuleRuleSchema) which will visit the module's
|
||||
[module definition](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.2.1/Elm-Syntax-Module) (`module SomeModuleName exposing (a, b)`), collect data in the `context` and/or report patterns.
|
||||
|
||||
@ -3957,6 +3996,7 @@ type alias RunnableProjectVisitor projectContext moduleContext =
|
||||
{ initialProjectContext : projectContext
|
||||
, elmJsonVisitors : List (Maybe { elmJsonKey : ElmJsonKey, project : Elm.Project.Project } -> projectContext -> ( List (Error {}), projectContext ))
|
||||
, readmeVisitors : List (Maybe { readmeKey : ReadmeKey, content : String } -> projectContext -> ( List (Error {}), projectContext ))
|
||||
, directDependenciesVisitors : List (Dict String Review.Project.Dependency.Dependency -> projectContext -> ( List (Error {}), projectContext ))
|
||||
, dependenciesVisitors : List (Dict String Review.Project.Dependency.Dependency -> projectContext -> ( List (Error {}), projectContext ))
|
||||
, moduleVisitor : Maybe ( RunnableModuleVisitor moduleContext, ContextCreator projectContext moduleContext )
|
||||
, traversalAndFolder : TraversalAndFolder projectContext moduleContext
|
||||
@ -4271,8 +4311,18 @@ computeProjectContext projectVisitor project maybePreviousCache =
|
||||
computeDependencies : () -> CacheEntryFor (Dict String Review.Project.Dependency.Dependency) projectContext
|
||||
computeDependencies () =
|
||||
let
|
||||
accumulateWithDirectDependencies : ( List (Error {}), projectContext ) -> ( List (Error {}), projectContext )
|
||||
accumulateWithDirectDependencies =
|
||||
case projectVisitor.directDependenciesVisitors of
|
||||
[] ->
|
||||
identity
|
||||
|
||||
visitors ->
|
||||
accumulateWithListOfVisitors visitors (Review.Project.directDependencies project)
|
||||
|
||||
( errorsForVisitor, contextForVisitor ) =
|
||||
( [], readmeCacheEntry.context )
|
||||
|> accumulateWithDirectDependencies
|
||||
|> accumulateWithListOfVisitors projectVisitor.dependenciesVisitors dependencies
|
||||
in
|
||||
{ value = dependencies
|
||||
@ -5505,7 +5555,7 @@ scopeRule : RunnableProjectVisitor ScopeProjectContext ScopeModuleContext
|
||||
scopeRule =
|
||||
newProjectRuleSchema "elm-review__SCOPE" scope_initialProjectContext
|
||||
|> withContextFromImportedModules
|
||||
|> withDependenciesProjectVisitor (scope_internalDependenciesVisitor |> scope_pairWithNoErrors)
|
||||
|> withDependenciesProjectVisitor (scope_dependenciesVisitor |> scope_pairWithNoErrors)
|
||||
|> withModuleVisitor scope_moduleVisitor
|
||||
|> withModuleContext
|
||||
{ fromProjectToModule = scope_fromProjectToModule
|
||||
@ -5662,8 +5712,8 @@ scope_pairWithNoErrors fn visited context =
|
||||
-- DEPENDENCIES
|
||||
|
||||
|
||||
scope_internalDependenciesVisitor : Dict String Dependency -> { context | dependenciesModules : Dict String Elm.Docs.Module } -> { context | dependenciesModules : Dict String Elm.Docs.Module }
|
||||
scope_internalDependenciesVisitor dependencies innerContext =
|
||||
scope_dependenciesVisitor : Dict String Dependency -> { context | dependenciesModules : Dict String Elm.Docs.Module } -> { context | dependenciesModules : Dict String Elm.Docs.Module }
|
||||
scope_dependenciesVisitor dependencies innerContext =
|
||||
let
|
||||
dependenciesModules : Dict String Elm.Docs.Module
|
||||
dependenciesModules =
|
||||
|
@ -25,8 +25,10 @@ all =
|
||||
|> Rule.withElmJsonModuleVisitor (\_ context -> context ++ "\n1.2 - withElmJsonModuleVisitor")
|
||||
|> Rule.withReadmeModuleVisitor (\_ context -> context ++ "\n2.1 - withReadmeModuleVisitor")
|
||||
|> Rule.withReadmeModuleVisitor (\_ context -> context ++ "\n2.2 - withReadmeModuleVisitor")
|
||||
|> Rule.withDependenciesModuleVisitor (\_ context -> context ++ "\n3.1 - withDependenciesModuleVisitor")
|
||||
|> Rule.withDependenciesModuleVisitor (\_ context -> context ++ "\n3.2 - withDependenciesModuleVisitor")
|
||||
|> Rule.withDirectDependenciesModuleVisitor (\_ context -> context ++ "\n3.1 - withDirectDependenciesModuleVisitor")
|
||||
|> Rule.withDirectDependenciesModuleVisitor (\_ context -> context ++ "\n3.2 - withDirectDependenciesModuleVisitor")
|
||||
|> Rule.withDependenciesModuleVisitor (\_ context -> context ++ "\n3.3 - withDependenciesModuleVisitor")
|
||||
|> Rule.withDependenciesModuleVisitor (\_ context -> context ++ "\n3.4 - withDependenciesModuleVisitor")
|
||||
|> Rule.withModuleDefinitionVisitor (\_ context -> ( [], context ++ "\n4.1 - withModuleDefinitionVisitor" ))
|
||||
|> Rule.withModuleDefinitionVisitor (\_ context -> ( [], context ++ "\n4.2 - withModuleDefinitionVisitor" ))
|
||||
|> Rule.withModuleDocumentationVisitor (\_ context -> ( [], context ++ "\n5.1 - withModuleDocumentationVisitor" ))
|
||||
@ -69,8 +71,10 @@ a = 1
|
||||
1.2 - withElmJsonModuleVisitor
|
||||
2.1 - withReadmeModuleVisitor
|
||||
2.2 - withReadmeModuleVisitor
|
||||
3.1 - withDependenciesModuleVisitor
|
||||
3.2 - withDependenciesModuleVisitor
|
||||
3.1 - withDirectDependenciesModuleVisitor
|
||||
3.2 - withDirectDependenciesModuleVisitor
|
||||
3.3 - withDependenciesModuleVisitor
|
||||
3.4 - withDependenciesModuleVisitor
|
||||
4.1 - withModuleDefinitionVisitor
|
||||
4.2 - withModuleDefinitionVisitor
|
||||
5.1 - withModuleDocumentationVisitor
|
||||
|
Loading…
Reference in New Issue
Block a user