Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions purescript.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ common defaults
-- specific version.
aeson >=2.0.3.0 && <2.2,
aeson-better-errors >=0.9.1.3 && <0.10,
async >=2.2.4 && <2.3,
ansi-terminal >=0.11.3 && <1.1,
array >=0.5.4.0 && <0.6,
base >=4.16.2.0 && <4.19,
Expand All @@ -166,9 +167,8 @@ common defaults
cborg >=0.2.7.0 && <0.3,
cheapskate >=0.1.1.2 && <0.2,
clock >=0.8.3 && <0.9,
constraints-extras >=0.4.0 && <0.5,
containers >=0.6.5.1 && <0.7,
-- unordered-containers,
-- hashable,
cryptonite ==0.30.*,
data-ordlist >=0.4.7.0 && <0.5,
deepseq >=1.4.6.1 && <1.5,
Expand All @@ -178,6 +178,7 @@ common defaults
file-embed >=0.0.15.0 && <0.1,
filepath >=1.4.2.2 && <1.5,
Glob >=0.10.2 && <0.11,
hashable >=1.4.3 && <1.5,
haskeline ==0.8.2,
language-javascript ==0.7.0.0,
lens >=5.1.1 && <5.3,
Expand All @@ -193,11 +194,13 @@ common defaults
process >=1.6.19.0 && <1.7,
protolude >=0.3.1 && <0.4,
regex-tdfa >=1.3.1.2 && <1.4,
rock,
safe >=0.3.19 && <0.4,
scientific >=0.3.7.0 && <0.4,
semialign >=1.2.0.1 && <1.4,
semigroups ==0.20.*,
serialise >=0.2.5.0 && <0.3,
some >=1.0.4 && <1.1,
sourcemap >=0.1.7 && <0.2,
stm >=2.5.0.2 && <2.6,
stringsearch >=0.3.6.6 && <0.4,
Expand Down Expand Up @@ -340,6 +343,9 @@ library
Language.PureScript.Make.Cache
Language.PureScript.Make.ExternsDiff
Language.PureScript.Make.Monad
Language.PureScript.Make.Query
Language.PureScript.Make.Rules
Language.PureScript.Make.Traces
Language.PureScript.ModuleDependencies
Language.PureScript.Names
Language.PureScript.Options
Expand Down
355 changes: 158 additions & 197 deletions src/Language/PureScript/Make.hs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/Language/PureScript/Make/Actions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ data MakeActions m = MakeActions
-- load .js files as ES modules.
, outputPrimDocs :: m ()
-- ^ If generating docs, output the documentation for the Prim modules
, getOutputDir :: FilePath
-- ^ The output directory path (for auxiliary cache files)
}

-- | Given the output directory, determines the location for the
Expand Down Expand Up @@ -203,6 +205,7 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
writeCacheDb
writePackageJson
outputPrimDocs
outputDir
where

getInputTimestampsAndHashes
Expand Down
124 changes: 124 additions & 0 deletions src/Language/PureScript/Make/Query.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Language.PureScript.Make.Query
( Query(..)
) where

import Prelude

import Data.Constraint.Extras.TH (deriveArgDict)
import Data.GADT.Compare (GEq(..), GCompare(..), GOrdering(..))
import Data.GADT.Show (GShow(..))
import Data.Hashable (Hashable(..))
import Data.Map qualified as M
import Data.Some (Some(..))
import Data.Type.Equality ((:~:)(..))

import Language.PureScript.AST (Module)
import Language.PureScript.Environment (Environment)
import Language.PureScript.Externs (ExternsFile)
import Language.PureScript.Names (ModuleName(..))
import Language.PureScript.Sugar.Names.Env (Env)

-- | Queries for the rock-based incremental compilation pipeline.
--
-- Each constructor represents a computation that can depend on other queries
-- via @fetch@. Rock automatically tracks these dependencies for memoization
-- and incremental recomputation.
data Query a where
-- | Input query: the pre-parsed module provided by the caller.
-- In rock's verifyTraces, this would be marked as 'Input' (can change between builds).
InputModule :: ModuleName -> Query Module

-- | Dependency graph: maps each module to its (transitively) sorted dependencies.
ModuleGraph :: Query (M.Map ModuleName [ModuleName])

-- | Sorted module names in topological order (leaves first).
SortedModules :: Query [ModuleName]

-- | Build the sugar names Env for a module from its dependencies' externs.
ModuleSugarEnv :: ModuleName -> Query Env

-- | Build the typechecker Environment from dependency externs.
ModuleTypeEnv :: ModuleName -> Query Environment

-- | Full per-module compilation: desugar, typecheck, corefn, codegen.
-- Returns the module's ExternsFile.
CompileModule :: ModuleName -> Query ExternsFile

deriving instance Show (Query a)

instance Eq (Query a) where
InputModule a == InputModule b = a == b
ModuleGraph == ModuleGraph = True
SortedModules == SortedModules = True
ModuleSugarEnv a == ModuleSugarEnv b = a == b
ModuleTypeEnv a == ModuleTypeEnv b = a == b
CompileModule a == CompileModule b = a == b

instance GShow Query where
gshowsPrec = showsPrec

-- | GEq instance: structural equality on the query key, returning type-level
-- proof (Refl) when two queries are identical.
instance GEq Query where
geq (InputModule a) (InputModule b)
| a == b = Just Refl
geq ModuleGraph ModuleGraph = Just Refl
geq SortedModules SortedModules = Just Refl
geq (ModuleSugarEnv a) (ModuleSugarEnv b)
| a == b = Just Refl
geq (ModuleTypeEnv a) (ModuleTypeEnv b)
| a == b = Just Refl
geq (CompileModule a) (CompileModule b)
| a == b = Just Refl
geq _ _ = Nothing

-- | GCompare instance required by some rock operations.
instance GCompare Query where
gcompare (InputModule a) (InputModule b) = case compare a b of
EQ -> GEQ; LT -> GLT; GT -> GGT
gcompare (InputModule _) _ = GLT
gcompare _ (InputModule _) = GGT

gcompare ModuleGraph ModuleGraph = GEQ
gcompare ModuleGraph _ = GLT
gcompare _ ModuleGraph = GGT

gcompare SortedModules SortedModules = GEQ
gcompare SortedModules _ = GLT
gcompare _ SortedModules = GGT

gcompare (ModuleSugarEnv a) (ModuleSugarEnv b) = case compare a b of
EQ -> GEQ; LT -> GLT; GT -> GGT
gcompare (ModuleSugarEnv _) _ = GLT
gcompare _ (ModuleSugarEnv _) = GGT

gcompare (ModuleTypeEnv a) (ModuleTypeEnv b) = case compare a b of
EQ -> GEQ; LT -> GLT; GT -> GGT
gcompare (ModuleTypeEnv _) _ = GLT
gcompare _ (ModuleTypeEnv _) = GGT

gcompare (CompileModule a) (CompileModule b) = case compare a b of
EQ -> GEQ; LT -> GLT; GT -> GGT

-- | Hashable instance for individual queries.
instance Hashable (Query a) where
hashWithSalt salt = \case
InputModule mn -> hashWithSalt salt (0 :: Int, mn)
ModuleGraph -> hashWithSalt salt (1 :: Int)
SortedModules -> hashWithSalt salt (2 :: Int)
ModuleSugarEnv mn -> hashWithSalt salt (3 :: Int, mn)
ModuleTypeEnv mn -> hashWithSalt salt (4 :: Int, mn)
CompileModule mn -> hashWithSalt salt (5 :: Int, mn)

-- | Hashable for existentially-wrapped queries (required by rock's memoise).
instance Hashable (Some Query) where
hashWithSalt salt (Some q) = hashWithSalt salt q

-- | ArgDict derivation for constraints-extras (needed for verifyTraces).
deriveArgDict ''Query
Loading
Loading