diff options
Diffstat (limited to 'source/Checking/Dependencies.hs')
| -rw-r--r-- | source/Checking/Dependencies.hs | 189 |
1 files changed, 0 insertions, 189 deletions
diff --git a/source/Checking/Dependencies.hs b/source/Checking/Dependencies.hs deleted file mode 100644 index 392bb04..0000000 --- a/source/Checking/Dependencies.hs +++ /dev/null @@ -1,189 +0,0 @@ -{-# LANGUAGE NoImplicitPrelude #-} - -module Checking.Dependencies - ( DependencyRegistry - , DependencyRegistrationError(..) - , fromRootSymbols - , registerDependencies - , lookupDependencies - , dependencyClosure - , dependencyPath - , DependencyRegistryDelta - , dependencyRegistryExtension - , applyDependencyRegistryDelta - ) where - -import Base -import Syntax.Internal - -import Data.List.NonEmpty qualified as NonEmpty -import Data.Map.Strict qualified as Map -import Data.Set qualified as Set -import Data.Text qualified as Text - - -newtype DependencyRegistry = DependencyRegistry - { dependencyRows :: Map Symbol (Set Symbol) - } - deriving (Show, Eq) - -data DependencyRegistrationError - = DependencyOwnerAlreadyRegistered !Symbol - | SelfDependency !Symbol - | UnknownDependency !Symbol - deriving (Show, Eq) - -fromRootSymbols :: Set Symbol -> DependencyRegistry -fromRootSymbols roots = - DependencyRegistry - (Map.fromSet (const mempty) roots) - -registerDependencies - :: Symbol - -> Set Symbol - -> DependencyRegistry - -> Either DependencyRegistrationError DependencyRegistry -registerDependencies owner dependencies registry - | Map.member owner rows = - Left (DependencyOwnerAlreadyRegistered owner) - | owner `Set.member` dependencies = - Left (SelfDependency owner) - | Just unknown <- Set.lookupMin (dependencies `Set.difference` Map.keysSet rows) = - Left (UnknownDependency unknown) - | otherwise = - Right - (DependencyRegistry - (Map.insert owner dependencies rows)) - where - rows = dependencyRows registry - -lookupDependencies - :: Symbol - -> DependencyRegistry - -> Maybe (Set Symbol) -lookupDependencies symbol = - Map.lookup symbol . dependencyRows - -dependencyClosure - :: DependencyRegistry - -> Set Symbol - -> Either Symbol (Set Symbol) -dependencyClosure registry = - go mempty . Set.toList - where - go seen [] = - Right seen - go seen (symbol:rest) - | symbol `Set.member` seen = - go seen rest - | otherwise = - case lookupDependencies symbol registry of - Nothing -> - Left symbol - Just direct -> - go - (Set.insert symbol seen) - (Set.toList direct <> rest) - -dependencyPath - :: DependencyRegistry - -> Set Symbol - -> Symbol - -> Either Symbol (Maybe (NonEmpty Symbol)) -dependencyPath registry seeds target = - firstPath (Set.toList seeds) - where - firstPath [] = - Right Nothing - firstPath (seed:rest) = do - path <- go mempty seed - case path of - Just _ -> - pure path - Nothing -> - firstPath rest - - go seen symbol - | symbol == target = - Right (Just (NonEmpty.singleton symbol)) - | symbol `Set.member` seen = - Right Nothing - | otherwise = - case lookupDependencies symbol registry of - Nothing -> - Left symbol - Just direct -> - prependFirst - symbol - (Set.toList direct) - (Set.insert symbol seen) - - prependFirst _prefix [] _seen = - Right Nothing - prependFirst prefix (dependency:rest) seen = do - path <- go seen dependency - case path of - Just found -> - Right (Just (NonEmpty.cons prefix found)) - Nothing -> - prependFirst prefix rest seen - - -newtype DependencyRegistryDelta = DependencyRegistryDelta - (Map Symbol (Set Symbol)) - deriving (Show, Eq) - -dependencyRegistryExtension - :: DependencyRegistry - -> DependencyRegistry - -> Either Text DependencyRegistryDelta -dependencyRegistryExtension previous current - | not - (all - (\(symbol, dependencies) -> - Map.lookup symbol currentRows - == Just dependencies) - (Map.toList previousRows)) = - Left "dependency registry changed an imported row" - | otherwise = - Right - (DependencyRegistryDelta - (Map.difference currentRows previousRows)) - where - previousRows = - dependencyRows previous - currentRows = - dependencyRows current - -applyDependencyRegistryDelta - :: DependencyRegistryDelta - -> DependencyRegistry - -> Either Text DependencyRegistry -applyDependencyRegistryDelta - (DependencyRegistryDelta additions) - registry - | not (Set.null duplicateOwners) = - Left "dependency registry imports define the same owner" - | Just owner <- - find - (\(candidate, dependencies) -> - candidate `Set.member` dependencies) - (Map.toList additions) = - Left - ("dependency registry import is self-referential: " - <> Text.pack (show (fst owner))) - | not (Set.null unknownDependencies) = - Left "dependency registry import has an unknown dependency" - | otherwise = - Right - (DependencyRegistry - (Map.union rows additions)) - where - rows = - dependencyRows registry - duplicateOwners = - Map.keysSet rows `Set.intersection` Map.keysSet additions - available = - Map.keysSet rows <> Map.keysSet additions - unknownDependencies = - Set.unions (Map.elems additions) `Set.difference` available |
