module Language.PureScript.ModuleDependencies (
sortModules
) where
import Data.Data
import Data.Graph
import Data.Generics
import Data.List (nub, intersect)
import Control.Applicative ((<$>))
import Language.PureScript.Declarations
import Language.PureScript.Names
import Language.PureScript.Values
import Language.PureScript.Types
sortModules :: [Module] -> Either String [Module]
sortModules ms = do
let verts = map (\m -> (m, getModuleName m, usedModules m)) ms
mapM toModule $ stronglyConnComp verts
usedModules :: (Data d) => d -> [ProperName]
usedModules = nub . everything (++) (mkQ [] qualifiedIdents `extQ` qualifiedProperNames `extQ` imports)
where
qualifiedIdents :: Qualified Ident -> [ProperName]
qualifiedIdents (Qualified (Just (ModuleName pn)) _) = [pn]
qualifiedIdents _ = []
qualifiedProperNames :: Qualified ProperName -> [ProperName]
qualifiedProperNames (Qualified (Just (ModuleName pn)) _) = [pn]
qualifiedProperNames _ = []
imports :: Declaration -> [ProperName]
imports (ImportDeclaration (ModuleName pn) _) = [pn]
imports _ = []
getModuleName :: Module -> ProperName
getModuleName (Module pn _) = pn
toModule :: SCC Module -> Either String Module
toModule (AcyclicSCC m) = return m
toModule (CyclicSCC [m]) = return m
toModule (CyclicSCC _) = Left "Cycle in module dependencies"