Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply fixes found in the result cache #150

Merged
merged 16 commits into from
Feb 2, 2023
32 changes: 20 additions & 12 deletions src/Review/ModuleNameLookupTable/Compute.elm
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import NonEmpty exposing (NonEmpty)
import Review.ModuleNameLookupTable.Internal as ModuleNameLookupTableInternal exposing (ModuleNameLookupTable)
import Review.Project.Dependency
import Review.Project.ProjectCache as ProjectCache exposing (ProjectCache)
import Review.Project.ProjectModule exposing (ProjectModule)
import Review.Project.ProjectModule as ProjectModule exposing (OpaqueProjectModule)
import Review.Project.Valid as ValidProject exposing (ValidProject)
import Set exposing (Set)
import Vendor.ListExtra as ListExtra
Expand Down Expand Up @@ -73,7 +73,7 @@ emptyScope =
}


compute : ModuleName -> ProjectModule -> ValidProject -> ( ModuleNameLookupTable, ValidProject )
compute : ModuleName -> OpaqueProjectModule -> ValidProject -> ( ModuleNameLookupTable, ValidProject )
compute moduleName module_ project =
let
projectCache : ProjectCache
Expand All @@ -99,28 +99,32 @@ compute moduleName module_ project =
Nothing ->
computeDependencies project

modulesByModuleName : Dict ModuleName ProjectModule
modulesByModuleName : Dict ModuleName OpaqueProjectModule
modulesByModuleName =
ValidProject.modulesByModuleName project

moduleAst : Elm.Syntax.File.File
moduleAst =
ProjectModule.ast module_

( imported, projectCacheWithComputedImports ) =
List.foldl
(computeImportedModulesDocs modulesByModuleName deps)
( Dict.empty, projectCache )
(elmCorePrelude ++ module_.ast.imports)
(elmCorePrelude ++ moduleAst.imports)

cacheKey : ProjectCache.ModuleCacheKey
cacheKey =
{ imported = imported, source = module_.source }
{ imported = imported, source = ProjectModule.source module_ }

computeLookupTableForModule : () -> ( ModuleNameLookupTable, Dict ModuleName Elm.Docs.Module )
computeLookupTableForModule () =
let
moduleContext : Context
moduleContext =
fromProjectToModule moduleName imported
|> collectModuleDocs module_.ast
|> collectLookupTable module_.ast.declarations
|> collectModuleDocs moduleAst
|> collectLookupTable moduleAst.declarations
in
( moduleContext.lookupTable
, Dict.insert moduleName
Expand Down Expand Up @@ -158,23 +162,27 @@ compute moduleName module_ project =

computeOnlyModuleDocs :
ModuleName
-> ProjectModule
-> Dict ModuleName ProjectModule
-> OpaqueProjectModule
-> Dict ModuleName OpaqueProjectModule
-> Dict ModuleName Elm.Docs.Module
-> ProjectCache
-> ( Elm.Docs.Module, ProjectCache )
computeOnlyModuleDocs moduleName module_ modulesByModuleName deps projectCache =
let
moduleAst : Elm.Syntax.File.File
moduleAst =
ProjectModule.ast module_

( imported, projectCacheWithComputedImports ) =
List.foldl
(computeImportedModulesDocs modulesByModuleName deps)
( Dict.empty, projectCache )
(elmCorePrelude ++ module_.ast.imports)
(elmCorePrelude ++ moduleAst.imports)

moduleContext : Context
moduleContext =
fromProjectToModule moduleName imported
|> collectModuleDocs module_.ast
|> collectModuleDocs moduleAst

moduleDocs : Elm.Docs.Module
moduleDocs =
Expand All @@ -194,7 +202,7 @@ computeOnlyModuleDocs moduleName module_ modulesByModuleName deps projectCache =


computeImportedModulesDocs :
Dict ModuleName ProjectModule
Dict ModuleName OpaqueProjectModule
-> Dict ModuleName Elm.Docs.Module
-> Node Import
-> ( Dict ModuleName Elm.Docs.Module, ProjectCache )
Expand Down
41 changes: 23 additions & 18 deletions src/Review/Project.elm
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,13 @@ addModule { path, source } project =
in
project
|> addModuleToProject
{ path = path
, source = source
, ast = ast
, contentHash = ContentHash.hash source
, isInSourceDirectories = List.any (\dir -> String.startsWith (Path.makeOSAgnostic dir) osAgnosticPath) (Internal.sourceDirectories project)
}
(ProjectModule.create
{ path = path
, source = source
, ast = ast
, isInSourceDirectories = List.any (\dir -> String.startsWith (Path.makeOSAgnostic dir) osAgnosticPath) (Internal.sourceDirectories project)
}
)
|> removeFileFromFilesThatFailedToParse path
|> forceModuleGraphRecomputation

Expand All @@ -147,18 +148,19 @@ addParsedModule { path, source, ast } project =
project
|> removeFileFromFilesThatFailedToParse path
|> addModuleToProject
{ path = path
, source = source
, ast = ast
, contentHash = ContentHash.hash source
, isInSourceDirectories = List.any (\dir -> String.startsWith (Path.makeOSAgnostic dir) osAgnosticPath) (Internal.sourceDirectories project)
}
(ProjectModule.create
{ path = path
, source = source
, ast = ast
, isInSourceDirectories = List.any (\dir -> String.startsWith (Path.makeOSAgnostic dir) osAgnosticPath) (Internal.sourceDirectories project)
}
)
|> forceModuleGraphRecomputation


addModuleToProject : ProjectModule -> Project -> Project
addModuleToProject : ProjectModule.OpaqueProjectModule -> Project -> Project
addModuleToProject module_ (Internal.Project project) =
Internal.Project { project | modules = Dict.insert module_.path { module_ | ast = Internal.sanitizeModule module_.ast } project.modules }
Internal.Project { project | modules = Dict.insert (ProjectModule.path module_) module_ project.modules }


addFileThatFailedToParse : { path : String, source : String } -> Project -> Project
Expand Down Expand Up @@ -197,6 +199,7 @@ removeFileFromFilesThatFailedToParse path (Internal.Project project) =
modules : Project -> List ProjectModule
modules (Internal.Project project) =
Dict.values project.modules
|> List.map ProjectModule.toRecord


{-| Get the list of file paths that failed to parse, because they were syntactically invalid Elm code.
Expand Down Expand Up @@ -236,20 +239,22 @@ addElmJson elmJson_ (Internal.Project project) =
sourceDirectories =
Internal.sourceDirectoriesForProject elmJson_.project

modules_ : Dict String ProjectModule.ProjectModule
modules_ : Dict String ProjectModule.OpaqueProjectModule
modules_ =
if project.sourceDirectories == sourceDirectories then
project.modules

else
Dict.map
(\_ value ->
(\path module_ ->
let
osAgnosticPath : String
osAgnosticPath =
Path.makeOSAgnostic value.path
Path.makeOSAgnostic path
in
{ value | isInSourceDirectories = List.any (\dir -> String.startsWith dir osAgnosticPath) sourceDirectories }
ProjectModule.setIsInSourceDirectories
(List.any (\dir -> String.startsWith dir osAgnosticPath) sourceDirectories)
module_
)
project.modules
in
Expand Down
20 changes: 2 additions & 18 deletions src/Review/Project/Internal.elm
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module Review.Project.Internal exposing
( Project(..)
, sanitizeModule
, sourceDirectories
, sourceDirectoriesForProject
)
Expand All @@ -11,20 +10,18 @@ the `elm.json` file, the project modules and the project dependencies.

import Dict exposing (Dict)
import Elm.Project
import Elm.Syntax.File
import Elm.Syntax.Node exposing (Node(..))
import Path
import Review.Cache.ContentHash exposing (ContentHash)
import Review.FilePath exposing (FilePath)
import Review.Project.Dependency exposing (Dependency)
import Review.Project.ProjectCache exposing (ProjectCache)
import Review.Project.ProjectModule exposing (ProjectModule)
import Review.Project.ProjectModule exposing (OpaqueProjectModule)
import Vendor.Graph exposing (Graph)


type Project
= Project
{ modules : Dict String ProjectModule
{ modules : Dict String OpaqueProjectModule
, modulesThatFailedToParse : List { path : String, source : String }
, elmJson : Maybe ( { path : String, raw : String, project : Elm.Project.Project }, ContentHash )
, readme : Maybe ( { path : String, content : String }, ContentHash )
Expand All @@ -40,19 +37,6 @@ sourceDirectories (Project project) =
project.sourceDirectories


sanitizeModule : Elm.Syntax.File.File -> Elm.Syntax.File.File
sanitizeModule ast =
{ ast | comments = List.sortBy (\(Node range _) -> positionAsInt range.start) ast.comments }


positionAsInt : { row : Int, column : Int } -> Int
positionAsInt { row, column } =
-- This is a quick and simple heuristic to be able to sort ranges.
-- It is entirely based on the assumption that no line is longer than
-- 1.000.000 characters long, which the compiler does not support for Elm 0.19.1.
row * 1000000 + column


sourceDirectoriesForProject : Elm.Project.Project -> List String
sourceDirectoriesForProject elmJson_ =
case elmJson_ of
Expand Down
93 changes: 91 additions & 2 deletions src/Review/Project/ProjectModule.elm
Original file line number Diff line number Diff line change
@@ -1,10 +1,94 @@
module Review.Project.ProjectModule exposing (ProjectModule)
module Review.Project.ProjectModule exposing
( OpaqueProjectModule, create
, path, source, ast, contentHash, isInSourceDirectories
, setIsInSourceDirectories
, ProjectModule, toRecord
)

{-| Represents a parsed file.

@docs OpaqueProjectModule, create

@docs path, source, ast, contentHash, isInSourceDirectories
@docs setIsInSourceDirectories

@docs ProjectModule, toRecord

-}

import Elm.Syntax.File
import Review.Cache.ContentHash exposing (ContentHash)
import Elm.Syntax.Node exposing (Node(..))
import Review.Cache.ContentHash as ContentHash exposing (ContentHash)


type OpaqueProjectModule
= OpaqueProjectModule
{ path : String
, source : String
, ast : Elm.Syntax.File.File
, contentHash : ContentHash
, isInSourceDirectories : Bool
}


create :
{ path : String
, source : String
, ast : Elm.Syntax.File.File
, isInSourceDirectories : Bool
}
-> OpaqueProjectModule
create params =
OpaqueProjectModule
{ path = params.path
, source = params.source
, ast = sanitizeModule params.ast
, contentHash = ContentHash.hash params.source
, isInSourceDirectories = params.isInSourceDirectories
}


sanitizeModule : Elm.Syntax.File.File -> Elm.Syntax.File.File
sanitizeModule ast_ =
{ ast_ | comments = List.sortBy (\(Node range _) -> positionAsInt range.start) ast_.comments }


positionAsInt : { row : Int, column : Int } -> Int
positionAsInt { row, column } =
-- This is a quick and simple heuristic to be able to sort ranges.
-- It is entirely based on the assumption that no line is longer than
-- 1.000.000 characters long, which the compiler does not support for Elm 0.19.1.
row * 1000000 + column


path : OpaqueProjectModule -> String
path (OpaqueProjectModule module_) =
module_.path


source : OpaqueProjectModule -> String
source (OpaqueProjectModule module_) =
module_.source


ast : OpaqueProjectModule -> Elm.Syntax.File.File
ast (OpaqueProjectModule module_) =
module_.ast


contentHash : OpaqueProjectModule -> ContentHash
contentHash (OpaqueProjectModule module_) =
module_.contentHash


isInSourceDirectories : OpaqueProjectModule -> Bool
isInSourceDirectories (OpaqueProjectModule module_) =
module_.isInSourceDirectories


setIsInSourceDirectories : Bool -> OpaqueProjectModule -> OpaqueProjectModule
setIsInSourceDirectories isInSourceDirectories_ (OpaqueProjectModule module_) =
OpaqueProjectModule { module_ | isInSourceDirectories = isInSourceDirectories_ }


type alias ProjectModule =
Expand All @@ -14,3 +98,8 @@ type alias ProjectModule =
, contentHash : ContentHash
, isInSourceDirectories : Bool
}


toRecord : OpaqueProjectModule -> ProjectModule
toRecord (OpaqueProjectModule module_) =
module_
Loading