diff --git a/Language/Haskell/GhcMod/Cabal21.hs b/Language/Haskell/GhcMod/Cabal21.hs new file mode 100644 index 0000000..164e5d6 --- /dev/null +++ b/Language/Haskell/GhcMod/Cabal21.hs @@ -0,0 +1,73 @@ +-- Copyright : Isaac Jones 2003-2004 +{- All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Isaac Jones nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -} + +-- | ComponentLocalBuildInfo for Cabal >= 1.21 +module Language.Haskell.GhcMod.Cabal21 ( + ComponentLocalBuildInfo + , PackageIdentifier(..) + , PackageName(..) + , componentPackageDeps + , componentLibraries + ) where + +import Distribution.Package (InstalledPackageId) +import Data.Version (Version) + +data LibraryName = LibraryName String + deriving (Read, Show) + +newtype PackageName = PackageName { unPackageName :: String } + deriving (Read, Show) + +data PackageIdentifier + = PackageIdentifier { + pkgName :: PackageName, + pkgVersion :: Version + } + deriving (Read, Show) + +type PackageId = PackageIdentifier + +data ComponentLocalBuildInfo + = LibComponentLocalBuildInfo { + componentPackageDeps :: [(InstalledPackageId, PackageId)], + componentLibraries :: [LibraryName] + } + | ExeComponentLocalBuildInfo { + componentPackageDeps :: [(InstalledPackageId, PackageId)] + } + | TestComponentLocalBuildInfo { + componentPackageDeps :: [(InstalledPackageId, PackageId)] + } + | BenchComponentLocalBuildInfo { + componentPackageDeps :: [(InstalledPackageId, PackageId)] + } + deriving (Read, Show) diff --git a/Language/Haskell/GhcMod/CabalConfig.hs b/Language/Haskell/GhcMod/CabalConfig.hs index 2adcd4a..6bf44b7 100644 --- a/Language/Haskell/GhcMod/CabalConfig.hs +++ b/Language/Haskell/GhcMod/CabalConfig.hs @@ -15,6 +15,7 @@ import Language.Haskell.GhcMod.Types import qualified Language.Haskell.GhcMod.Cabal16 as C16 import qualified Language.Haskell.GhcMod.Cabal18 as C18 +import qualified Language.Haskell.GhcMod.Cabal21 as C21 #ifndef MIN_VERSION_mtl #define MIN_VERSION_mtl(x,y,z) 1 @@ -31,7 +32,8 @@ import Data.Maybe () import Data.Set () import Data.List (find,tails,isPrefixOf,isInfixOf,nub,stripPrefix) import Distribution.Package (InstalledPackageId(..) - , PackageIdentifier) + , PackageIdentifier(..) + , PackageName(..)) import Distribution.Simple.BuildPaths (defaultDistPref) import Distribution.Simple.Configure (localBuildInfoFile) import Distribution.Simple.LocalBuildInfo (ComponentName) @@ -77,7 +79,7 @@ configDependencies :: PackageIdentifier -> CabalConfig -> [Package] configDependencies thisPkg config = map fromInstalledPackageId deps where deps :: [InstalledPackageId] - deps = case deps18 `mplus` deps16 of + deps = case deps21 `mplus` deps18 `mplus` deps16 of Right ps -> ps Left msg -> error msg @@ -85,7 +87,27 @@ configDependencies thisPkg config = map fromInstalledPackageId deps -- defined in the same package). internal pkgid = pkgid == thisPkg - -- Cabal >= 1.18 + -- Cabal >= 1.21 + deps21 :: Either String [InstalledPackageId] + deps21 = + map fst + <$> filterInternal21 + <$> (readEither =<< extractField config "componentsConfigs") + + filterInternal21 + :: [(ComponentName, C21.ComponentLocalBuildInfo, [ComponentName])] + -> [(InstalledPackageId, C21.PackageIdentifier)] + + filterInternal21 ccfg = [ (ipkgid, pkgid) + | (_,clbi,_) <- ccfg + , (ipkgid, pkgid) <- C21.componentPackageDeps clbi + , not (internal . packageIdentifierFrom21 $ pkgid) ] + + packageIdentifierFrom21 :: C21.PackageIdentifier -> PackageIdentifier + packageIdentifierFrom21 (C21.PackageIdentifier (C21.PackageName myName) myVersion) = + PackageIdentifier (PackageName myName) myVersion + + -- Cabal >= 1.18 && < 1.21 deps18 :: Either String [InstalledPackageId] deps18 = map fst diff --git a/ghc-mod.cabal b/ghc-mod.cabal index b559cc0..d14ffa3 100644 --- a/ghc-mod.cabal +++ b/ghc-mod.cabal @@ -61,6 +61,7 @@ Library Language.Haskell.GhcMod.Browse Language.Haskell.GhcMod.Cabal16 Language.Haskell.GhcMod.Cabal18 + Language.Haskell.GhcMod.Cabal21 Language.Haskell.GhcMod.CabalApi Language.Haskell.GhcMod.CabalConfig Language.Haskell.GhcMod.CaseSplit