-- | This module contains a compiler pass that add an import declaration -- for the @Prelude@ module to the imports of a module if it does not -- import the @Prelude@ explicitly. -- -- = Example -- -- If a module does not have an explicit import of the @Prelude@ module -- -- > module Queue where -- > -- > import Test.QuickCheck -- > -- > type Queue a = ([a], [a]) -- > -- > {- ... -} -- -- an import for the @Prelude@ module is added to the import list -- -- > module Queue where -- > -- > import Prelude -- > import Test.QuickCheck -- > -- > type Queue a = ([a], [a]) -- > -- > {- ... -} -- -- = Specification -- -- == Preconditions -- -- There are no special requirements. -- -- == Translation -- -- If the module does not contain an import of the form @import Prelude@ -- it is added to the top of the import list. -- -- == Postconditions -- -- There is an explicit import for the @Prelude@ module. module FreeC.Pass.ImplicitPreludePass ( implicitPreludePass ) where import qualified FreeC.IR.Base.Prelude as IR.Prelude import FreeC.IR.SrcSpan import qualified FreeC.IR.Syntax as IR import FreeC.Pass -- | A compiler pass that adds an import declaration for the @Prelude@ module -- if there is no such import. implicitPreludePass :: Pass IR.Module IR.Module implicitPreludePass ast = return ast { IR.modImports = addImplicitPreludeImport (IR.modImports ast) } -- | Adds an import for the @Prelude@ module to the given list of imports if -- there is no explicit import for the @Prelude@ already. addImplicitPreludeImport :: [IR.ImportDecl] -> [IR.ImportDecl] addImplicitPreludeImport imports | importsPrelude = imports | otherwise = preludeImport : imports where -- | Whether there is an explicit import for the @Prelude@ module. importsPrelude :: Bool importsPrelude = IR.Prelude.modName `elem` map IR.importName imports -- | An explicit import for the @Prelude@ module. preludeImport :: IR.ImportDecl preludeImport = IR.ImportDecl NoSrcSpan IR.Prelude.modName