CheckModules.lhs

module CheckModules(ModSysErr(..),chkModule) where
 
  import Relations
  import NamesEntities
  import ModSysAST
  --import Modules
  import List (partition,nub)
  import Maybe(isNothing)
  import Sets






  data ModSysErr 
    = UndefinedModuleAlias ModName
    | UndefinedExport QName
    | UndefinedSubExport QName Name
    | AmbiguousExport Name [Entity] 
    | MissingModule ModName
    | UndefinedImport ModName Name 
    | UndefinedSubImport ModName Name Name 
    deriving Show             










































  chkModule :: 
    (ModName -> Maybe (Rel Name Entity)) ->
    Rel QName Entity ->
    Module ->
      [ModSysErr]
 
  chkModule expsOf inscp mod
    = chkAmbigExps mod_exports
      ++ if null missingModules
         then chkExpSpec inscp mod
               ++ [err | (imp,Just exps) <- impSources,
                         err <- chkImport exps imp]
         else map MissingModule missingModules
    where
    Just mod_exports = expsOf (modName mod)
 
    missingModules =
      nub [impSource imp|(imp,Nothing)<-impSources]
    impSources =
      [(imp,expsOf (impSource imp))|imp<-modImports mod]


















  chkAmbigExps :: Rel Name Entity -> [ModSysErr]
  chkAmbigExps exps = concatMap isAmbig 
                               (setToList (dom exps))
    where
    isAmbig n = 
      let (values,types) = partition isValue (applyRel exps n) 
      in ambig n values ++ ambig n types
 
    ambig n ents@(_:_:_)    = [AmbiguousExport n ents]
    ambig n _               = []





















  chkEntSpec :: (Ord j, ToSimple j) =>
    Bool ->                             -- is it a hiding import?
    (j -> ModSysErr) ->                 -- report error
    (j -> Name -> ModSysErr) ->         -- report error
    EntSpec j ->                        -- the specification
    Rel j Entity  ->                    -- the relation to check
    (j->[Entity]) ->                    -- the relation to check
      [ModSysErr]                       -- detected errors
 
  chkEntSpec isHiding errUndef errUndefSub 
             (Ent x subspec) rel relfun =
    case xents of
      []   -> [errUndef x]
      ents -> concatMap chk ents
    where
    xents = filter consider (relfun x)
 
    chk ent = 
      case subspec of
        Just (Subs subs) -> 
          map (errUndefSub x)
              (filter (not . (`elementOf` subsInScope)) subs)
          where
          subsInScope = 
            mapSet toSimple 
              $ dom 
              $ restrictRng (`elementOf` owns ent) rel
        _ -> []
 
    consider
      | isHiding && isNothing subspec = const True
      | otherwise                     = not . isCon





















  chkExpSpec :: Rel QName Entity -> Module -> [ModSysErr]
  chkExpSpec inscp mod =
      case modExpList mod of
        Nothing   -> []
        Just exps -> concatMap chk exps
    where
    aliases = modName mod : impAs `map` modImports mod
 
    chk (ModuleExp x)
      | x `elem` aliases = []
      | otherwise        = [UndefinedModuleAlias x]
    chk (EntExp spec) = chkEntSpec False 
                 UndefinedExport UndefinedSubExport 
                 spec inscp (applyRel inscp)







  chkImport :: Rel Name Entity -> Import -> [ModSysErr]
  chkImport exps imp = concatMap chk (impList imp)
    where
    src      = impSource imp
    chk spec = 
      chkEntSpec (impHiding imp)
        (UndefinedImport src) (UndefinedSubImport src)
        spec exps (applyRel exps)




Plain-text version of CheckModules.lhs | Valid HTML?