Commit 7f5c1086 authored by Edward Z. Yang's avatar Edward Z. Yang

Module reexports, fixing #8407.

The general approach is to add a new field to the package database,
reexported-modules, which considered by the module finder as possible
module declarations.  Unlike declaring stub module files, multiple
reexports of the same physical package at the same name do not
result in an ambiguous import.

Has submodule updates for Cabal and haddock.

NB: When a reexport renames a module, that renaming is *not* accessible
from inside the package.  This is not so much a deliberate design choice
as for implementation expediency (reexport resolution happens only when
a package is in the package database.)

TODO: Error handling when there are duplicate reexports/etc is not very
well tested.
Signed-off-by: default avatarEdward Z. Yang <ezyang@cs.stanford.edu>

Conflicts:
	compiler/main/HscTypes.lhs
	testsuite/.gitignore
	utils/haddock
parent dae46da7
......@@ -3588,6 +3588,7 @@ compilerInfo dflags
("RTS ways", cGhcRTSWays),
("Support dynamic-too", if isWindows then "NO" else "YES"),
("Support parallel --make", "YES"),
("Support reexported-modules", "YES"),
("Dynamic by default", if dYNAMIC_BY_DEFAULT dflags
then "YES" else "NO"),
("GHC Dynamic", if dynamicGhc
......
......@@ -196,31 +196,36 @@ findExposedPackageModule hsc_env mod_name mb_pkg
, fr_pkgs_hidden = []
, fr_mods_hidden = []
, fr_suggestions = suggest })
Right found
| null found_exposed -- Found, but with no exposed copies
Right found'
| null found_visible -- Found, but with no exposed copies
-> return (NotFound { fr_paths = [], fr_pkg = Nothing
, fr_pkgs_hidden = pkg_hiddens
, fr_mods_hidden = mod_hiddens
, fr_suggestions = [] })
| [(pkg_conf,_)] <- found_exposed -- Found uniquely
| [ModConf mod_name' pkg_conf _ _] <- found_visible -- Found uniquely
-> let pkgid = packageConfigId pkg_conf in
findPackageModule_ hsc_env (mkModule pkgid mod_name) pkg_conf
findPackageModule_ hsc_env (mkModule pkgid mod_name') pkg_conf
| otherwise -- Found in more than one place
-> return (FoundMultiple (map (packageConfigId.fst) found_exposed))
-> return (FoundMultiple (map (packageConfigId.modConfPkg)
found_visible))
where
found = eltsUFM found'
for_this_pkg = case mb_pkg of
Nothing -> found
Just p -> filter ((`matches` p) . fst) found
found_exposed = filter is_exposed for_this_pkg
is_exposed (pkg_conf,exposed_mod) = exposed pkg_conf && exposed_mod
Just p -> filter ((`matches` p).modConfPkg) found
found_visible = filter modConfVisible for_this_pkg
-- NB: _vis is guaranteed to be False; a non-exposed module
-- can never be visible.
mod_hiddens = [ packageConfigId pkg_conf
| (pkg_conf,False) <- found ]
| ModConf _ pkg_conf False _vis <- found ]
-- NB: We /re-report/ non-exposed modules of hidden packages.
pkg_hiddens = [ packageConfigId pkg_conf
| (pkg_conf,_) <- found, not (exposed pkg_conf) ]
| ModConf _ pkg_conf _ False <- found
, not (exposed pkg_conf) ]
pkg_conf `matches` pkg
= case packageName pkg_conf of
......
......@@ -1169,7 +1169,7 @@ getGRE = withSession $ \hsc_env-> return $ ic_rn_gbl_env (hsc_IC hsc_env)
-- | Return all /external/ modules available in the package database.
-- Modules from the current session (i.e., from the 'HomePackageTable') are
-- not included.
-- not included. This includes module names which are reexported by packages.
packageDbModules :: GhcMonad m =>
Bool -- ^ Only consider exposed packages.
-> m [Module]
......@@ -1177,10 +1177,12 @@ packageDbModules only_exposed = do
dflags <- getSessionDynFlags
let pkgs = eltsUFM (pkgIdMap (pkgState dflags))
return $
[ mkModule pid modname | p <- pkgs
, not only_exposed || exposed p
, let pid = packageConfigId p
, modname <- exposedModules p ]
[ mkModule pid modname
| p <- pkgs
, not only_exposed || exposed p
, let pid = packageConfigId p
, modname <- exposedModules p
++ map exportName (reexportedModules p) ]
-- -----------------------------------------------------------------------------
-- Misc exported utils
......
......@@ -1448,15 +1448,15 @@ mkPrintUnqualified dflags env = (qual_name, qual_mod)
qual_mod mod
| modulePackageKey mod == thisPackage dflags = False
| [pkgconfig] <- [pkg | (pkg,exposed_module) <- lookup,
exposed pkg && exposed_module],
| [pkgconfig] <- [modConfPkg m | m <- lookup
, modConfVisible m ],
packageConfigId pkgconfig == modulePackageKey mod
-- this says: we are given a module P:M, is there just one exposed package
-- that exposes a module M, and is it package P?
= False
| otherwise = True
where lookup = lookupModuleInAllPackages dflags (moduleName mod)
where lookup = eltsUFM $ lookupModuleInAllPackages dflags (moduleName mod)
\end{code}
......
......@@ -66,8 +66,10 @@ packageConfigId = mkPackageKey . sourcePackageId
packageConfigToInstalledPackageInfo :: PackageConfig -> InstalledPackageInfo
packageConfigToInstalledPackageInfo
(pkgconf@(InstalledPackageInfo { exposedModules = e,
reexportedModules = r,
hiddenModules = h })) =
pkgconf{ exposedModules = map convert e,
reexportedModules = map (fmap convert) r,
hiddenModules = map convert h }
where convert :: Module.ModuleName -> Distribution.ModuleName.ModuleName
convert = (expectJust "packageConfigToInstalledPackageInfo") . simpleParse . moduleNameString
......@@ -77,7 +79,9 @@ packageConfigToInstalledPackageInfo
installedPackageInfoToPackageConfig :: InstalledPackageInfo_ String -> PackageConfig
installedPackageInfoToPackageConfig
(pkgconf@(InstalledPackageInfo { exposedModules = e,
reexportedModules = r,
hiddenModules = h })) =
pkgconf{ exposedModules = map mkModuleName e,
reexportedModules = map (fmap mkModuleName) r,
hiddenModules = map mkModuleName h }
......@@ -14,6 +14,7 @@ module Packages (
-- * Reading the package config, and processing cmdline args
PackageState(..),
ModuleConf(..),
initPackages,
getPackageDetails,
lookupModuleInAllPackages, lookupModuleWithSuggestions,
......@@ -29,6 +30,7 @@ module Packages (
collectIncludeDirs, collectLibraryPaths, collectLinkOpts,
packageHsLibs,
ModuleExport(..),
-- * Utils
isDllName
......@@ -52,6 +54,7 @@ import System.Environment ( getEnv )
import Distribution.InstalledPackageInfo
import Distribution.InstalledPackageInfo.Binary
import Distribution.Package hiding (PackageId,depends)
import Distribution.ModuleExport
import FastString
import ErrUtils ( debugTraceMsg, putMsg, MsgDoc )
import Exception
......@@ -109,6 +112,34 @@ import qualified Data.Set as Set
-- When compiling A, we record in B's Module value whether it's
-- in a different DLL, by setting the DLL flag.
-- | The result of performing a lookup on moduleToPkgConfAll, this
-- is one possible provider of a module.
data ModuleConf = ModConf {
-- | The original name of the module
modConfName :: ModuleName,
-- | The original package (config) of the module
modConfPkg :: PackageConfig,
-- | Does the original package expose this module to its clients? This
-- is cached result of whether or not the module name is in
-- exposed-modules or reexported-modules in the package config. While
-- this isn't actually how we want to figure out if a module is visible,
-- this is important for error messages.
modConfExposed :: Bool,
-- | Is the module visible to our current compilation? Interestingly,
-- this is not the same as if it was exposed: if the package is hidden
-- then exposed modules are not visible. However, if another exposed
-- package reexports the module in question, it's now visible! You
-- can't tell this just by looking at the original name, so we
-- record the calculation here.
modConfVisible :: Bool
}
-- | Map from 'PackageId' (used for documentation)
type PackageIdMap = UniqFM
-- | Map from 'Module' to 'PackageId' to 'ModuleConf', see 'moduleToPkgConfAll'
type ModuleToPkgConfAll = UniqFM (PackageIdMap ModuleConf)
data PackageState = PackageState {
pkgIdMap :: PackageConfigMap, -- PackageKey -> PackageConfig
-- The exposed flags are adjusted according to -package and
......@@ -119,11 +150,14 @@ data PackageState = PackageState {
-- should be in reverse dependency order; that is, a package
-- is always mentioned before the packages it depends on.
moduleToPkgConfAll :: UniqFM [(PackageConfig,Bool)], -- ModuleEnv mapping
-- Derived from pkgIdMap.
-- Maps Module to (pkgconf,exposed), where pkgconf is the
-- PackageConfig for the package containing the module, and
-- exposed is True if the package exposes that module.
-- | ModuleEnv mapping, derived from 'pkgIdMap'.
-- Maps 'Module' to an original module which is providing the module name.
-- Since the module may be provided by multiple packages, this result
-- is further recorded in a map of the original package IDs to
-- module information. The 'modSummaryPkgConf' should agree with
-- this key. Generally, 'modSummaryName' will be the same as the
-- module key, unless there is renaming.
moduleToPkgConfAll :: ModuleToPkgConfAll,
installedPackageIdMap :: InstalledPackageIdMap
}
......@@ -811,7 +845,7 @@ mkPackageState dflags pkgs0 preload0 this_package = do
let pstate = PackageState{ preloadPackages = dep_preload,
pkgIdMap = pkg_db,
moduleToPkgConfAll = mkModuleMap pkg_db,
moduleToPkgConfAll = mkModuleMap pkg_db ipid_map,
installedPackageIdMap = ipid_map
}
......@@ -819,23 +853,43 @@ mkPackageState dflags pkgs0 preload0 this_package = do
-- -----------------------------------------------------------------------------
-- Make the mapping from module to package info
-- | Makes the mapping from module to package info for 'moduleToPkgConfAll'
mkModuleMap
:: PackageConfigMap
-> UniqFM [(PackageConfig, Bool)]
mkModuleMap pkg_db = foldr extend_modmap emptyUFM pkgids
-> InstalledPackageIdMap
-> ModuleToPkgConfAll
mkModuleMap pkg_db ipid_map = foldr extend_modmap emptyUFM pkgids
where
pkgids = map packageConfigId (eltsUFM pkg_db)
extend_modmap pkgid modmap =
addListToUFM_C (++) modmap
([(m, [(pkg, True)]) | m <- exposed_mods] ++
[(m, [(pkg, False)]) | m <- hidden_mods])
where
pkg = expectJust "mkModuleMap" (lookupPackage pkg_db pkgid)
exposed_mods = exposedModules pkg
hidden_mods = hiddenModules pkg
pkgids = map packageConfigId (eltsUFM pkg_db)
extend_modmap pkgid modmap = addListToUFM_C (plusUFM_C merge) modmap es
where -- ASSERT(m == m' && pkg == pkg' && e == e'
-- && (e || not (v || v')))
-- Some notes about the assert. Merging only ever occurs when
-- we find a reexport. The interesting condition:
-- e || not (v || v')
-- says that a non-exposed module cannot ever become visible.
-- However, an invisible (but exported) module may become
-- visible when it is reexported by a visible package,
-- which is why we merge visibility using logical OR.
merge a b = a { modConfVisible =
modConfVisible a || modConfVisible b }
es = [(m, unitUFM pkgid (ModConf m pkg True (exposed pkg)))
| m <- exposed_mods] ++
[(m, unitUFM pkgid (ModConf m pkg False False))
| m <- hidden_mods] ++
[(m, unitUFM pkgid' (ModConf m' pkg' True (exposed pkg)))
| ModuleExport{ exportName = m
, exportCachedTrueOrig = Just (ipid', m')}
<- reexported_mods
, Just pkgid' <- [Map.lookup ipid' ipid_map]
, let pkg' = pkg_lookup pkgid' ]
pkg = pkg_lookup pkgid
pkg_lookup = expectJust "mkModuleMap" . lookupPackage pkg_db
exposed_mods = exposedModules pkg
reexported_mods = reexportedModules pkg
hidden_mods = hiddenModules pkg
pprSPkg :: PackageConfig -> SDoc
pprSPkg p = text (display (sourcePackageId p))
......@@ -940,18 +994,20 @@ getPackageFrameworks dflags pkgs = do
-- -----------------------------------------------------------------------------
-- Package Utils
-- | Takes a 'Module', and if the module is in a package returns
-- @(pkgconf, exposed)@ where pkgconf is the PackageConfig for that package,
-- and exposed is @True@ if the package exposes the module.
lookupModuleInAllPackages :: DynFlags -> ModuleName -> [(PackageConfig,Bool)]
-- | Takes a 'ModuleName', and if the module is in any package returns
-- a map of package IDs to 'ModuleConf', describing where the module lives
-- and whether or not it is exposed.
lookupModuleInAllPackages :: DynFlags
-> ModuleName
-> PackageIdMap ModuleConf
lookupModuleInAllPackages dflags m
= case lookupModuleWithSuggestions dflags m of
Right pbs -> pbs
Left _ -> []
Left _ -> emptyUFM
lookupModuleWithSuggestions
:: DynFlags -> ModuleName
-> Either [Module] [(PackageConfig,Bool)]
-> Either [Module] (PackageIdMap ModuleConf)
-- Lookup module in all packages
-- Right pbs => found in pbs
-- Left ms => not found; but here are sugestions
......@@ -970,7 +1026,8 @@ lookupModuleWithSuggestions dflags m
all_mods = [ (moduleNameString mod_nm, mkModule pkg_id mod_nm)
| pkg_config <- eltsUFM (pkgIdMap pkg_state)
, let pkg_id = packageConfigId pkg_config
, mod_nm <- exposedModules pkg_config ]
, mod_nm <- exposedModules pkg_config
++ map exportName (reexportedModules pkg_config) ]
-- | Find all the 'PackageConfig' in both the preload packages from 'DynFlags' and corresponding to the list of
-- 'PackageConfig's
......
......@@ -39,7 +39,8 @@ import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, hsc_IC,
setInteractivePrintName )
import Module
import Name
import Packages ( trusted, getPackageDetails, exposed, exposedModules, pkgIdMap )
import Packages ( ModuleExport(..), trusted, getPackageDetails, exposed,
exposedModules, reexportedModules, pkgIdMap )
import PprTyThing
import RdrName ( getGRE_NameQualifier_maybes )
import SrcLoc
......@@ -2544,11 +2545,14 @@ wrapIdentCompleterWithModifier modifChars fun = completeWordWithPrev Nothing wor
where
getModifier = find (`elem` modifChars)
-- | Return a list of visible module names for autocompletion.
allExposedModules :: DynFlags -> [ModuleName]
allExposedModules dflags
= concat (map exposedModules (filter exposed (eltsUFM pkg_db)))
= concatMap extract (filter exposed (eltsUFM pkg_db))
where
pkg_db = pkgIdMap (pkgState dflags)
extract pkg = exposedModules pkg ++ map exportName (reexportedModules pkg)
-- Extract the *new* name, because that's what is user visible
completeExpression = completeQuotedWord (Just '\\') "\"" listFiles
completeIdentifier
......
Subproject commit 90811eb4f0e06ba308e8a6e93089ff041d932952
Subproject commit 96847693bf8ff48ae94f179d60c1f23411e1365e
......@@ -22,6 +22,7 @@ module Distribution.InstalledPackageInfo.Binary (
import Distribution.Version
import Distribution.Package hiding (depends)
import Distribution.License
import Distribution.ModuleExport
import Distribution.InstalledPackageInfo as IPI
import Data.Binary as Bin
import Control.Exception as Exception
......@@ -60,6 +61,7 @@ putInstalledPackageInfo ipi = do
put (category ipi)
put (exposed ipi)
put (exposedModules ipi)
put (reexportedModules ipi)
put (hiddenModules ipi)
put (trusted ipi)
put (importDirs ipi)
......@@ -94,6 +96,7 @@ getInstalledPackageInfo = do
category <- get
exposed <- get
exposedModules <- get
reexportedModules <- get
hiddenModules <- get
trusted <- get
importDirs <- get
......@@ -158,3 +161,8 @@ instance Binary Version where
deriving instance Binary PackageName
deriving instance Binary InstalledPackageId
instance Binary m => Binary (ModuleExport m) where
put (ModuleExport a b c d) = do put a; put b; put c; put d
get = do a <- get; b <- get; c <- get; d <- get;
return (ModuleExport a b c d)
......@@ -40,6 +40,9 @@ Thumbs.db
*.hp
tests/**/*.ps
*.stats
Setup
dist
tmp.d
*.dyn_o
*.dyn_hi
......@@ -102,17 +105,22 @@ mk/ghcconfig_*_inplace_bin_ghc-stage2.exe.mk
/tests/cabal/cabal04/Setup
/tests/cabal/cabal04/dist/
/tests/cabal/cabal04/err
/tests/cabal/cabal05/p-0.1.0.0/
/tests/cabal/cabal05/q-0.1.0.0/
/tests/cabal/cabal05/r-0.1.0.0/
/tests/cabal/local01.package.conf/
/tests/cabal/local03.package.conf/
/tests/cabal/local04.package.conf/
/tests/cabal/local05a.package.conf/
/tests/cabal/local05b.package.conf/
/tests/cabal/local06.package.conf/
/tests/cabal/local07.package.conf/
/tests/cabal/local1750.package.conf/
/tests/cabal/localT1750.package.conf/
/tests/cabal/localshadow1.package.conf/
/tests/cabal/localshadow2.package.conf/
/tests/cabal/package.conf.*/
/tests/cabal/recache_reexport_db/package.cache
/tests/cabal/shadow.hs
/tests/cabal/shadow1.out
/tests/cabal/shadow2.out
......
......@@ -236,3 +236,18 @@ ghcpkg02:
echo Updating $$i; \
$(GHC_PKG) describe --global $$i | $(GHC_PKG_ghcpkg02) update --global --force -; \
done
PKGCONF07=local07.package.conf
LOCAL_GHC_PKG07 = '$(GHC_PKG)' --no-user-package-db -f $(PKGCONF07)
ghcpkg07:
@rm -rf $(PKGCONF07)
$(LOCAL_GHC_PKG07) init $(PKGCONF07)
$(LOCAL_GHC_PKG07) register --force test.pkg 2>/dev/null
$(LOCAL_GHC_PKG07) register --force test7a.pkg 2>/dev/null
$(LOCAL_GHC_PKG07) field testpkg7a reexported-modules
$(LOCAL_GHC_PKG07) register --force test7b.pkg 2>/dev/null
$(LOCAL_GHC_PKG07) field testpkg7b reexported-modules
recache_reexport:
@rm -rf recache_reexport_db/package.cache
'$(GHC_PKG)' --no-user-package-db --global-package-db=recache_reexport_db recache
......@@ -47,6 +47,12 @@ test('ghcpkg06',
run_command,
['$MAKE -s --no-print-directory ghcpkg06'])
test('ghcpkg07',
extra_clean(['local07.package.conf',
'local07.package.conf.old']),
run_command,
['$MAKE -s --no-print-directory ghcpkg07'])
# Test that we *can* compile a module that also belongs to a package
# (this was disallowed in GHC 6.4 and earlier)
test('pkg01', normal, compile, [''])
......
TOP=../../..
include $(TOP)/mk/boilerplate.mk
include $(TOP)/mk/test.mk
SETUP = ../Setup -v0
# This test is for package reexports
# 1. install p
# 2. install q (reexporting p modules)
# 3. install r (reexporting p and q modules)
# 4. configure and build s, using modules from q and r
#
# Here are the permutations we test for:
# - Package qualifier? (YES/NO)
# - Where is module? (defined in SELF /
# (ORIGinally defined/REEXported) in DEPendency)
# For deps, could be BOTH, if there is NO package qualifier
# - Renamed? (YES/NO)
# - Multiple modules with same name? (YES/NO)
#
# It's illegal for the module to be defined in SELF without renaming, or
# for a package to cause a conflict with itself. A reexport which does
# not rename definitionally "conflicts" with the original package's definition.
#
# Probably the trickiest bits are when we automatically pick out which package
# when the package qualifier is missing, and handling whether or not modules
# should be exposed or hidden.
cabal05: clean
$(MAKE) clean
'$(GHC_PKG)' init tmp.d
'$(TEST_HC)' -v0 --make Setup
# build p
cd p && $(SETUP) clean
cd p && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --with-ghc='$(TEST_HC)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d --prefix='$(PWD)/$$pkgid'
cd p && $(SETUP) build
cd p && $(SETUP) copy
cd p && $(SETUP) register
# build q
cd q && $(SETUP) clean
cd q && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --with-ghc='$(TEST_HC)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d --prefix='$(PWD)/$$pkgid'
cd q && $(SETUP) build
cd q && $(SETUP) copy
cd q && $(SETUP) register
# build r
cd r && $(SETUP) clean
cd r && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --with-ghc='$(TEST_HC)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d --prefix='$(PWD)/$$pkgid'
cd r && $(SETUP) build
cd r && $(SETUP) copy
cd r && $(SETUP) register
# build s
cd s && $(SETUP) clean
cd s && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --with-ghc='$(TEST_HC)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d
cd s && $(SETUP) build
# now test that package recaching works
rm tmp.d/package.cache
'$(GHC_PKG)' --no-user-package-db --global-package-db=tmp.d recache
cd s && $(SETUP) clean
cd s && $(SETUP) configure $(CABAL_MINIMAL_BUILD) --with-ghc='$(TEST_HC)' --ghc-options='$(TEST_HC_OPTS)' --package-db=../tmp.d
cd s && $(SETUP) build
ifneq "$(CLEANUP)" ""
$(MAKE) clean
endif
clean :
'$(GHC_PKG)' unregister --force p >/dev/null 2>&1 || true
'$(GHC_PKG)' unregister --force q >/dev/null 2>&1 || true
'$(GHC_PKG)' unregister --force r >/dev/null 2>&1 || true
$(RM) -r p-* q-* r-* tmp.d *.o *.hi */*.o */*.hi */Setup$(exeext) */dist Setup$(exeext)
import Distribution.Simple
main = defaultMain
if default_testopts.cleanup != '':
cleanup = 'CLEANUP=1'
else:
cleanup = ''
test('cabal05',
ignore_output,
run_command,
['$MAKE -s --no-print-directory cabal05 ' + cleanup])
module P where
data P = P
p = True
import Distribution.Simple
main = defaultMain
name: p
version: 0.1.0.0
license-file: LICENSE
author: Edward Z. Yang
maintainer: ezyang@cs.stanford.edu
build-type: Simple
cabal-version: >=1.21
library
exposed-modules: P, P2
build-depends: base
module Q where
import P
data Q = Q
q = not p
import Distribution.Simple
main = defaultMain
name: q
version: 0.1.0.0
license-file: LICENSE
author: Edward Z. Yang
maintainer: ezyang@cs.stanford.edu
build-type: Simple
cabal-version: >=1.21
library
exposed-modules: Q
reexported-modules:
-- qualified=NO, where=DEP(ORIG), renaming=NO, conflict=NO
-- impossible
-- qualified=NO, where=DEP(ORIG), renaming=NO, conflict=YES (p,s)
P,
-- qualified=NO, where=DEP(ORIG), renaming=YES, conflict=NO
P as QP,
-- qualified=NO, where=DEP(ORIG), renaming=YES, conflict=YES (r)
P as PMerge,
P2 as PMerge2,
-- qualified=NO, where=SELF, renaming=NO, conflict=NO
-- impossible
-- qualified=NO, where=SELF, renaming=NO, conflict=YES
-- should error
-- qualified=NO, where=SELF, renaming=YES, conflict=NO
Q as QQ,
-- qualified=NO, where=SELF, renaming=YES, conflict=YES (r)
Q as QMerge
build-depends: base, p
module R where
import P -- p (exposed), q (reexport p:P)
import P2 -- q (reexport p:P)
import Q -- q (exposed)
import qualified QP -- q (reexport p:P)
import qualified QQ -- q (reexport q:Q)
import qualified PMerge -- q (reexport p:P)
import qualified PMerge2 -- q (reexport p:P2)
import qualified QMerge -- q (reexport q:Q)
data R = R
r = p && q
import Distribution.Simple
main = defaultMain
name: r
version: 0.1.0.0
license-file: LICENSE
author: Edward Z. Yang
maintainer: ezyang@cs.stanford.edu
build-type: Simple
cabal-version: >=1.21
library
exposed-modules: R
reexported-modules:
-- qualified=NO, where=DEP(BOTH), renaming=NO, conflict=YES (p,q)
P,
-- qualified=NO, where=DEP(BOTH), renaming=YES, conflict=NO
P as RP2,
-- qualified=NO, where=DEP(BOTH), renaming=YES, conflict=YES
P2 as PMerge,
-- qualified=YES, where=DEP(ORIG), renaming=YES, conflict=NO
p:P as RP,
-- qualified=YES, where=DEP(REEX), renaming=YES, conflict=NO
q:QP as RQP,
-- qualified=YES, where=DEP(REEX), renaming=YES, conflict=NO
q:P as RQP2,
-- qualified=YES, where=DEP(REEX), renaming=YES, conflict=YES
q:QQ as QMerge,
-- qualified=YES, where=SELF, renaming=YES, conflict=NO
r:R as RR,
-- qualified=YES, where=DEP, renaming=NO, conflict=YES (q)
q:Q,
-- qualified=YES, where=DEP(ORIG), renaming=YES, conflict=YES (q)
p:P2 as PMerge2
build-depends: base, p, q
module S where
-- NB: package p is hidden!
import qualified QP -- q (reexport p:P)
import qualified RP -- r (reexport p:P)
import qualified Q -- q (exposed), r (reexport q:Q)
import qualified R -- r (exposed)
import qualified RR -- r (reexport r:R)
import qualified RP -- r (reexport p:P)
import qualified RQP -- r (reexport p:P)
import qualified RQP2 -- r (reexport p:P)
import qualified PMerge -- q (reexport p:P), r (reexport p:P)
import qualified PMerge2 -- q (reexport p:P2), r (reexport p:P2)
import qualified QMerge -- q (reexport q:Q), r (reexport q:Q)
x :: QP.P
x = RP.P
s = QP.p || Q.q || R.r
import Distribution.Simple
main = defaultMain
name: s
version: 0.1.0.0
license-file: LICENSE
author: Edward Z. Yang
maintainer: ezyang@cs.stanford.edu
build-type: Simple
cabal-version: >=1.21
library
exposed-modules: S
build-depends: base, q, r
Reading package info from "test.pkg" ... done.
Reading package info from "test7a.pkg" ... done.
reexported-modules: testpkg:A (A@testpkg-1.2.3.4-XXX)
testpkg:A as A1 (A@testpkg-1.2.3.4-XXX)
E as E2 (E@testpkg7a-1.0-XXX)
Reading package info from "test7b.pkg" ... done.
reexported-modules: testpkg:A as F1 (A@testpkg-1.2.3.4-XXX)
testpkg7a:A as F2 (A@testpkg-1.2.3.4-XXX)
testpkg7a:A1 as F3 (A@testpkg-1.2.3.4-XXX)
testpkg7a:E as F4 (E@testpkg7a-1.0-XXX) E (E@testpkg7a-1.0-XXX)
E2 as E3 (E@testpkg7a-1.0-XXX)
name: testpkg7a
version: 1.0
id: testpkg7a-1.0-XXX
license: BSD3
copyright: (c) The Univsersity of Glasgow 2004
maintainer: glasgow-haskell-users@haskell.org
stability: stable
homepage: http://www.haskell.org/ghc
package-url: http://www.haskell.org/ghc
description: A Test Package
category: none
author: simonmar@microsoft.com
exposed: True
exposed-modules: E
reexported-modules: testpkg:A, testpkg:A as A1, E as E2
hs-libraries: testpkg7a-1.0
depends: testpkg-1.2.3.4-XXX
name: testpkg7a
version: 1.0
id: testpkg7a-1.0-XXX
license: BSD3
copyright: (c) The Univsersity of Glasgow 2004
maintainer: glasgow-haskell-users@haskell.org
stability: stable
homepage: http://www.haskell.org/ghc
package-url: http://www.haskell.org/ghc
description: A Test Package
category: none
author: simonmar@microsoft.com
exposed: True
exposed-modules: E
reexported-modules: testpkg:A, testpkg:A as A1, E as E2
hs-libraries: testpkg7a-1.0
depends: testpkg-1.2.3.4-XXX
name: testpkg7b
version: 1.0
id: testpkg7b-1.0-XXX
license: BSD3