mirror of
https://github.com/jfmengels/elm-review.git
synced 2024-11-23 06:44:41 +03:00
Add topological traversal: Create graph of files
This commit is contained in:
parent
1219faf512
commit
d8df52aa52
2
elm.json
2
elm.json
@ -16,6 +16,8 @@
|
||||
"dependencies": {
|
||||
"elm/core": "1.0.2 <= v < 2.0.0",
|
||||
"elm/project-metadata-utils": "1.0.0 <= v < 2.0.0",
|
||||
"elm-community/graph": "6.0.0 <= v < 7.0.0",
|
||||
"elm-community/intdict": "3.0.0 <= v < 4.0.0",
|
||||
"elm-explorations/test": "1.2.2 <= v < 2.0.0",
|
||||
"stil4m/elm-syntax": "7.1.0 <= v < 8.0.0"
|
||||
},
|
||||
|
@ -11,17 +11,16 @@
|
||||
"elm/core": "1.0.2",
|
||||
"elm/json": "1.1.3",
|
||||
"elm/project-metadata-utils": "1.0.0",
|
||||
"elm-community/graph": "6.0.0",
|
||||
"elm-community/intdict": "3.0.0",
|
||||
"stil4m/elm-syntax": "7.1.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/html": "1.0.0",
|
||||
"avh4/elm-fifo": "1.0.4",
|
||||
"elm/parser": "1.1.0",
|
||||
"elm/random": "1.0.0",
|
||||
"elm/time": "1.0.0",
|
||||
"elm/virtual-dom": "1.0.2",
|
||||
"elm-community/json-extra": "4.0.0",
|
||||
"elm-community/list-extra": "8.2.2",
|
||||
"elm-explorations/test": "1.2.2",
|
||||
"rtfeldman/elm-hex": "1.0.0",
|
||||
"rtfeldman/elm-iso8601-date-strings": "1.1.3",
|
||||
"stil4m/structured-writer": "1.0.2"
|
||||
@ -29,6 +28,11 @@
|
||||
},
|
||||
"test-dependencies": {
|
||||
"direct": {},
|
||||
"indirect": {}
|
||||
"indirect": {
|
||||
"elm/html": "1.0.0",
|
||||
"elm/random": "1.0.0",
|
||||
"elm/virtual-dom": "1.0.2",
|
||||
"elm-explorations/test": "1.2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +209,8 @@ import Elm.Syntax.Module as Module exposing (Module)
|
||||
import Elm.Syntax.ModuleName exposing (ModuleName)
|
||||
import Elm.Syntax.Node as Node exposing (Node)
|
||||
import Elm.Syntax.Range exposing (Range)
|
||||
import Graph exposing (Graph)
|
||||
import IntDict exposing (IntDict)
|
||||
import Review.File exposing (ParsedFile, RawFile)
|
||||
import Review.Fix exposing (Fix)
|
||||
import Review.Project exposing (Project)
|
||||
@ -555,9 +557,15 @@ type MultiSchema globalContext moduleContext
|
||||
, elmJsonVisitors : List (Maybe Elm.Project.Project -> globalContext -> globalContext)
|
||||
, dependenciesVisitors : List (Dict String Elm.Docs.Module -> globalContext -> globalContext)
|
||||
, finalEvaluationFns : List (globalContext -> List Error)
|
||||
, traversalType : TraversalType
|
||||
}
|
||||
|
||||
|
||||
type TraversalType
|
||||
= AllFilesInParallel
|
||||
| ImportedModulesFirst
|
||||
|
||||
|
||||
newMultiSchema :
|
||||
String
|
||||
->
|
||||
@ -581,6 +589,7 @@ newMultiSchema name_ { moduleVisitorSchema, initGlobalContext, initModuleContext
|
||||
, elmJsonVisitors = []
|
||||
, dependenciesVisitors = []
|
||||
, finalEvaluationFns = []
|
||||
, traversalType = AllFilesInParallel
|
||||
}
|
||||
|
||||
|
||||
@ -629,7 +638,17 @@ type alias MultiRuleCache context =
|
||||
|
||||
|
||||
runMulti : MultiSchema globalContext moduleContext -> MultiRuleCache globalContext -> Project -> List ParsedFile -> ( List Error, Rule )
|
||||
runMulti (MultiSchema schema) startCache project =
|
||||
runMulti ((MultiSchema { traversalType }) as schema) =
|
||||
case traversalType of
|
||||
AllFilesInParallel ->
|
||||
allFilesInParallelTraversal schema
|
||||
|
||||
ImportedModulesFirst ->
|
||||
importedModulesFirst schema
|
||||
|
||||
|
||||
allFilesInParallelTraversal : MultiSchema globalContext moduleContext -> MultiRuleCache globalContext -> Project -> List ParsedFile -> ( List Error, Rule )
|
||||
allFilesInParallelTraversal (MultiSchema schema) startCache project =
|
||||
let
|
||||
initialContext : globalContext
|
||||
initialContext =
|
||||
@ -718,6 +737,89 @@ runMulti (MultiSchema schema) startCache project =
|
||||
( errors, Multi schema.name (runMulti (MultiSchema schema) newCache) )
|
||||
|
||||
|
||||
importedModulesFirst : MultiSchema globalContext moduleContext -> MultiRuleCache globalContext -> Project -> List ParsedFile -> ( List Error, Rule )
|
||||
importedModulesFirst (MultiSchema schema) startCache project =
|
||||
\files ->
|
||||
let
|
||||
graph : Graph ModuleName ()
|
||||
graph =
|
||||
buildModuleGraph files
|
||||
|> Debug.log "graph"
|
||||
in
|
||||
-- TODO Implement
|
||||
( [], Multi schema.name (runMulti (MultiSchema schema) startCache) )
|
||||
|
||||
|
||||
buildModuleGraph : List ParsedFile -> Graph ModuleName ()
|
||||
buildModuleGraph files =
|
||||
-- This should be moved to `Review.Project`, to avoid having to do this for every rule
|
||||
let
|
||||
fileIds : Dict ModuleName Int
|
||||
fileIds =
|
||||
files
|
||||
|> List.indexedMap Tuple.pair
|
||||
|> List.foldl
|
||||
(\( index, file ) dict ->
|
||||
Dict.insert
|
||||
(getModuleName file)
|
||||
index
|
||||
dict
|
||||
)
|
||||
Dict.empty
|
||||
|
||||
getFileId : ModuleName -> Int
|
||||
getFileId moduleName =
|
||||
case Dict.get moduleName fileIds of
|
||||
Just fileId ->
|
||||
fileId
|
||||
|
||||
Nothing ->
|
||||
getFileId moduleName
|
||||
|
||||
( nodes, edges ) =
|
||||
files
|
||||
|> List.foldl
|
||||
(\file ( resNodes, resEdges ) ->
|
||||
let
|
||||
( moduleNode, modulesEdges ) =
|
||||
nodesAndEdges (\moduleName -> Dict.get moduleName fileIds) file (getFileId <| getModuleName file)
|
||||
in
|
||||
( moduleNode :: resNodes, List.concat [ modulesEdges, resEdges ] )
|
||||
)
|
||||
( [], [] )
|
||||
in
|
||||
Graph.fromNodesAndEdges nodes edges
|
||||
|
||||
|
||||
nodesAndEdges : (ModuleName -> Maybe Int) -> ParsedFile -> Int -> ( Graph.Node ModuleName, List (Graph.Edge ()) )
|
||||
nodesAndEdges getFileId file fileId =
|
||||
let
|
||||
moduleName =
|
||||
getModuleName file
|
||||
in
|
||||
( Graph.Node fileId moduleName
|
||||
, importedModules file
|
||||
|> List.filterMap getFileId
|
||||
|> List.map
|
||||
(\importFileId ->
|
||||
Graph.Edge fileId importFileId ()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
getModuleName : ParsedFile -> ModuleName
|
||||
getModuleName file =
|
||||
file.ast.moduleDefinition
|
||||
|> Node.value
|
||||
|> Module.moduleName
|
||||
|
||||
|
||||
importedModules : ParsedFile -> List ModuleName
|
||||
importedModules file =
|
||||
file.ast.imports
|
||||
|> List.map (Node.value >> .moduleName >> Node.value)
|
||||
|
||||
|
||||
{-| Concatenate the errors of the previous step and of the last step.
|
||||
-}
|
||||
makeFinalEvaluationForMulti : List (context -> List Error) -> context -> List Error
|
||||
|
Loading…
Reference in New Issue
Block a user