{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
module Distribution.Simple.BuildTarget (
readTargetInfos,
readBuildTargets,
BuildTarget(..),
showBuildTarget,
QualLevel(..),
buildTargetComponentName,
UserBuildTarget,
readUserBuildTargets,
showUserBuildTarget,
UserBuildTargetProblem(..),
reportUserBuildTargetProblems,
resolveBuildTargets,
BuildTargetProblem(..),
reportBuildTargetProblems,
) where
import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Types.TargetInfo
import Distribution.Types.LocalBuildInfo
import Distribution.Types.ComponentRequestedSpec
import Distribution.Types.ForeignLib
import Distribution.Types.UnqualComponentName
import Distribution.Package
import Distribution.PackageDescription
import Distribution.ModuleName
import Distribution.Simple.LocalBuildInfo
import Distribution.Pretty
import Distribution.Parsec
import Distribution.Simple.Utils
import Distribution.Verbosity
import qualified Distribution.Compat.CharParsing as P
import Control.Monad ( msum )
import Data.List ( stripPrefix, groupBy )
import qualified Data.List.NonEmpty as NE
import System.FilePath as FilePath
( dropExtension, normalise, splitDirectories, joinPath, splitPath
, hasTrailingPathSeparator )
import System.Directory ( doesFileExist, doesDirectoryExist )
import qualified Data.Map as Map
readTargetInfos :: Verbosity -> PackageDescription -> LocalBuildInfo -> [String] -> IO [TargetInfo]
readTargetInfos :: Verbosity
-> PackageDescription
-> LocalBuildInfo
-> [String]
-> IO [TargetInfo]
readTargetInfos Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi [String]
args = do
[BuildTarget]
build_targets <- Verbosity -> PackageDescription -> [String] -> IO [BuildTarget]
readBuildTargets Verbosity
verbosity PackageDescription
pkg_descr [String]
args
Verbosity
-> PackageDescription
-> LocalBuildInfo
-> [BuildTarget]
-> IO [TargetInfo]
checkBuildTargets Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi [BuildTarget]
build_targets
data UserBuildTarget =
UserBuildTargetSingle String
| UserBuildTargetDouble String String
| UserBuildTargetTriple String String String
deriving (Int -> UserBuildTarget -> ShowS
[UserBuildTarget] -> ShowS
UserBuildTarget -> String
(Int -> UserBuildTarget -> ShowS)
-> (UserBuildTarget -> String)
-> ([UserBuildTarget] -> ShowS)
-> Show UserBuildTarget
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UserBuildTarget] -> ShowS
$cshowList :: [UserBuildTarget] -> ShowS
show :: UserBuildTarget -> String
$cshow :: UserBuildTarget -> String
showsPrec :: Int -> UserBuildTarget -> ShowS
$cshowsPrec :: Int -> UserBuildTarget -> ShowS
Show, UserBuildTarget -> UserBuildTarget -> Bool
(UserBuildTarget -> UserBuildTarget -> Bool)
-> (UserBuildTarget -> UserBuildTarget -> Bool)
-> Eq UserBuildTarget
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UserBuildTarget -> UserBuildTarget -> Bool
$c/= :: UserBuildTarget -> UserBuildTarget -> Bool
== :: UserBuildTarget -> UserBuildTarget -> Bool
$c== :: UserBuildTarget -> UserBuildTarget -> Bool
Eq, Eq UserBuildTarget
Eq UserBuildTarget
-> (UserBuildTarget -> UserBuildTarget -> Ordering)
-> (UserBuildTarget -> UserBuildTarget -> Bool)
-> (UserBuildTarget -> UserBuildTarget -> Bool)
-> (UserBuildTarget -> UserBuildTarget -> Bool)
-> (UserBuildTarget -> UserBuildTarget -> Bool)
-> (UserBuildTarget -> UserBuildTarget -> UserBuildTarget)
-> (UserBuildTarget -> UserBuildTarget -> UserBuildTarget)
-> Ord UserBuildTarget
UserBuildTarget -> UserBuildTarget -> Bool
UserBuildTarget -> UserBuildTarget -> Ordering
UserBuildTarget -> UserBuildTarget -> UserBuildTarget
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: UserBuildTarget -> UserBuildTarget -> UserBuildTarget
$cmin :: UserBuildTarget -> UserBuildTarget -> UserBuildTarget
max :: UserBuildTarget -> UserBuildTarget -> UserBuildTarget
$cmax :: UserBuildTarget -> UserBuildTarget -> UserBuildTarget
>= :: UserBuildTarget -> UserBuildTarget -> Bool
$c>= :: UserBuildTarget -> UserBuildTarget -> Bool
> :: UserBuildTarget -> UserBuildTarget -> Bool
$c> :: UserBuildTarget -> UserBuildTarget -> Bool
<= :: UserBuildTarget -> UserBuildTarget -> Bool
$c<= :: UserBuildTarget -> UserBuildTarget -> Bool
< :: UserBuildTarget -> UserBuildTarget -> Bool
$c< :: UserBuildTarget -> UserBuildTarget -> Bool
compare :: UserBuildTarget -> UserBuildTarget -> Ordering
$ccompare :: UserBuildTarget -> UserBuildTarget -> Ordering
$cp1Ord :: Eq UserBuildTarget
Ord)
data BuildTarget =
BuildTargetComponent ComponentName
| BuildTargetModule ComponentName ModuleName
| BuildTargetFile ComponentName FilePath
deriving (BuildTarget -> BuildTarget -> Bool
(BuildTarget -> BuildTarget -> Bool)
-> (BuildTarget -> BuildTarget -> Bool) -> Eq BuildTarget
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BuildTarget -> BuildTarget -> Bool
$c/= :: BuildTarget -> BuildTarget -> Bool
== :: BuildTarget -> BuildTarget -> Bool
$c== :: BuildTarget -> BuildTarget -> Bool
Eq, Int -> BuildTarget -> ShowS
[BuildTarget] -> ShowS
BuildTarget -> String
(Int -> BuildTarget -> ShowS)
-> (BuildTarget -> String)
-> ([BuildTarget] -> ShowS)
-> Show BuildTarget
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BuildTarget] -> ShowS
$cshowList :: [BuildTarget] -> ShowS
show :: BuildTarget -> String
$cshow :: BuildTarget -> String
showsPrec :: Int -> BuildTarget -> ShowS
$cshowsPrec :: Int -> BuildTarget -> ShowS
Show, (forall x. BuildTarget -> Rep BuildTarget x)
-> (forall x. Rep BuildTarget x -> BuildTarget)
-> Generic BuildTarget
forall x. Rep BuildTarget x -> BuildTarget
forall x. BuildTarget -> Rep BuildTarget x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BuildTarget x -> BuildTarget
$cfrom :: forall x. BuildTarget -> Rep BuildTarget x
Generic)
instance Binary BuildTarget
buildTargetComponentName :: BuildTarget -> ComponentName
buildTargetComponentName :: BuildTarget -> ComponentName
buildTargetComponentName (BuildTargetComponent ComponentName
cn) = ComponentName
cn
buildTargetComponentName (BuildTargetModule ComponentName
cn ModuleName
_) = ComponentName
cn
buildTargetComponentName (BuildTargetFile ComponentName
cn String
_) = ComponentName
cn
readBuildTargets :: Verbosity -> PackageDescription -> [String] -> IO [BuildTarget]
readBuildTargets :: Verbosity -> PackageDescription -> [String] -> IO [BuildTarget]
readBuildTargets Verbosity
verbosity PackageDescription
pkg [String]
targetStrs = do
let ([UserBuildTargetProblem]
uproblems, [UserBuildTarget]
utargets) = [String] -> ([UserBuildTargetProblem], [UserBuildTarget])
readUserBuildTargets [String]
targetStrs
Verbosity -> [UserBuildTargetProblem] -> IO ()
reportUserBuildTargetProblems Verbosity
verbosity [UserBuildTargetProblem]
uproblems
[(UserBuildTarget, Bool)]
utargets' <- (UserBuildTarget -> IO (UserBuildTarget, Bool))
-> [UserBuildTarget] -> IO [(UserBuildTarget, Bool)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse UserBuildTarget -> IO (UserBuildTarget, Bool)
checkTargetExistsAsFile [UserBuildTarget]
utargets
let ([BuildTargetProblem]
bproblems, [BuildTarget]
btargets) = PackageDescription
-> [(UserBuildTarget, Bool)]
-> ([BuildTargetProblem], [BuildTarget])
resolveBuildTargets PackageDescription
pkg [(UserBuildTarget, Bool)]
utargets'
Verbosity -> [BuildTargetProblem] -> IO ()
reportBuildTargetProblems Verbosity
verbosity [BuildTargetProblem]
bproblems
[BuildTarget] -> IO [BuildTarget]
forall (m :: * -> *) a. Monad m => a -> m a
return [BuildTarget]
btargets
checkTargetExistsAsFile :: UserBuildTarget -> IO (UserBuildTarget, Bool)
checkTargetExistsAsFile :: UserBuildTarget -> IO (UserBuildTarget, Bool)
checkTargetExistsAsFile UserBuildTarget
t = do
Bool
fexists <- String -> IO Bool
existsAsFile (UserBuildTarget -> String
fileComponentOfTarget UserBuildTarget
t)
(UserBuildTarget, Bool) -> IO (UserBuildTarget, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (UserBuildTarget
t, Bool
fexists)
where
existsAsFile :: String -> IO Bool
existsAsFile String
f = do
Bool
exists <- String -> IO Bool
doesFileExist String
f
case String -> [String]
splitPath String
f of
(String
d:[String]
_) | String -> Bool
hasTrailingPathSeparator String
d -> String -> IO Bool
doesDirectoryExist String
d
(String
d:String
_:[String]
_) | Bool -> Bool
not Bool
exists -> String -> IO Bool
doesDirectoryExist String
d
[String]
_ -> Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
exists
fileComponentOfTarget :: UserBuildTarget -> String
fileComponentOfTarget (UserBuildTargetSingle String
s1) = String
s1
fileComponentOfTarget (UserBuildTargetDouble String
_ String
s2) = String
s2
fileComponentOfTarget (UserBuildTargetTriple String
_ String
_ String
s3) = String
s3
readUserBuildTargets :: [String] -> ([UserBuildTargetProblem]
,[UserBuildTarget])
readUserBuildTargets :: [String] -> ([UserBuildTargetProblem], [UserBuildTarget])
readUserBuildTargets = [Either UserBuildTargetProblem UserBuildTarget]
-> ([UserBuildTargetProblem], [UserBuildTarget])
forall a b. [Either a b] -> ([a], [b])
partitionEithers ([Either UserBuildTargetProblem UserBuildTarget]
-> ([UserBuildTargetProblem], [UserBuildTarget]))
-> ([String] -> [Either UserBuildTargetProblem UserBuildTarget])
-> [String]
-> ([UserBuildTargetProblem], [UserBuildTarget])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Either UserBuildTargetProblem UserBuildTarget)
-> [String] -> [Either UserBuildTargetProblem UserBuildTarget]
forall a b. (a -> b) -> [a] -> [b]
map String -> Either UserBuildTargetProblem UserBuildTarget
readUserBuildTarget
readUserBuildTarget :: String -> Either UserBuildTargetProblem
UserBuildTarget
readUserBuildTarget :: String -> Either UserBuildTargetProblem UserBuildTarget
readUserBuildTarget String
targetstr =
case ParsecParser UserBuildTarget
-> String -> Either String UserBuildTarget
forall a. ParsecParser a -> String -> Either String a
explicitEitherParsec ParsecParser UserBuildTarget
forall (m :: * -> *). CabalParsing m => m UserBuildTarget
parseTargetApprox String
targetstr of
Left String
_ -> UserBuildTargetProblem
-> Either UserBuildTargetProblem UserBuildTarget
forall a b. a -> Either a b
Left (String -> UserBuildTargetProblem
UserBuildTargetUnrecognised String
targetstr)
Right UserBuildTarget
tgt -> UserBuildTarget -> Either UserBuildTargetProblem UserBuildTarget
forall a b. b -> Either a b
Right UserBuildTarget
tgt
where
parseTargetApprox :: CabalParsing m => m UserBuildTarget
parseTargetApprox :: m UserBuildTarget
parseTargetApprox = do
(String, Maybe (String, Maybe String))
ts <- m (String, Maybe (String, Maybe String))
forall (m :: * -> *).
CabalParsing m =>
m (String, Maybe (String, Maybe String))
tokens
UserBuildTarget -> m UserBuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (UserBuildTarget -> m UserBuildTarget)
-> UserBuildTarget -> m UserBuildTarget
forall a b. (a -> b) -> a -> b
$ case (String, Maybe (String, Maybe String))
ts of
(String
a, Maybe (String, Maybe String)
Nothing) -> String -> UserBuildTarget
UserBuildTargetSingle String
a
(String
a, Just (String
b, Maybe String
Nothing)) -> String -> String -> UserBuildTarget
UserBuildTargetDouble String
a String
b
(String
a, Just (String
b, Just String
c)) -> String -> String -> String -> UserBuildTarget
UserBuildTargetTriple String
a String
b String
c
tokens :: CabalParsing m => m (String, Maybe (String, Maybe String))
tokens :: m (String, Maybe (String, Maybe String))
tokens = (\String
s -> (String
s, Maybe (String, Maybe String)
forall a. Maybe a
Nothing)) (String -> (String, Maybe (String, Maybe String)))
-> m String -> m (String, Maybe (String, Maybe String))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m String
forall (m :: * -> *). CabalParsing m => m String
parsecHaskellString
m (String, Maybe (String, Maybe String))
-> m (String, Maybe (String, Maybe String))
-> m (String, Maybe (String, Maybe String))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (,) (String
-> Maybe (String, Maybe String)
-> (String, Maybe (String, Maybe String)))
-> m String
-> m (Maybe (String, Maybe String)
-> (String, Maybe (String, Maybe String)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m String
forall (m :: * -> *). CabalParsing m => m String
token m (Maybe (String, Maybe String)
-> (String, Maybe (String, Maybe String)))
-> m (Maybe (String, Maybe String))
-> m (String, Maybe (String, Maybe String))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m (String, Maybe String) -> m (Maybe (String, Maybe String))
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
P.optional (Char -> m Char
forall (m :: * -> *). CharParsing m => Char -> m Char
P.char Char
':' m Char -> m (String, Maybe String) -> m (String, Maybe String)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> m (String, Maybe String)
forall (m :: * -> *). CabalParsing m => m (String, Maybe String)
tokens2)
tokens2 :: CabalParsing m => m (String, Maybe String)
tokens2 :: m (String, Maybe String)
tokens2 = (\String
s -> (String
s, Maybe String
forall a. Maybe a
Nothing)) (String -> (String, Maybe String))
-> m String -> m (String, Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m String
forall (m :: * -> *). CabalParsing m => m String
parsecHaskellString
m (String, Maybe String)
-> m (String, Maybe String) -> m (String, Maybe String)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (,) (String -> Maybe String -> (String, Maybe String))
-> m String -> m (Maybe String -> (String, Maybe String))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m String
forall (m :: * -> *). CabalParsing m => m String
token m (Maybe String -> (String, Maybe String))
-> m (Maybe String) -> m (String, Maybe String)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m String -> m (Maybe String)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
P.optional (Char -> m Char
forall (m :: * -> *). CharParsing m => Char -> m Char
P.char Char
':' m Char -> m String -> m String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (m String
forall (m :: * -> *). CabalParsing m => m String
parsecHaskellString m String -> m String -> m String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> m String
forall (m :: * -> *). CabalParsing m => m String
token))
token :: CabalParsing m => m String
token :: m String
token = (Char -> Bool) -> m String
forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m String
P.munch1 (\Char
x -> Bool -> Bool
not (Char -> Bool
isSpace Char
x) Bool -> Bool -> Bool
&& Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
':')
data UserBuildTargetProblem
= UserBuildTargetUnrecognised String
deriving Int -> UserBuildTargetProblem -> ShowS
[UserBuildTargetProblem] -> ShowS
UserBuildTargetProblem -> String
(Int -> UserBuildTargetProblem -> ShowS)
-> (UserBuildTargetProblem -> String)
-> ([UserBuildTargetProblem] -> ShowS)
-> Show UserBuildTargetProblem
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UserBuildTargetProblem] -> ShowS
$cshowList :: [UserBuildTargetProblem] -> ShowS
show :: UserBuildTargetProblem -> String
$cshow :: UserBuildTargetProblem -> String
showsPrec :: Int -> UserBuildTargetProblem -> ShowS
$cshowsPrec :: Int -> UserBuildTargetProblem -> ShowS
Show
reportUserBuildTargetProblems :: Verbosity -> [UserBuildTargetProblem] -> IO ()
reportUserBuildTargetProblems :: Verbosity -> [UserBuildTargetProblem] -> IO ()
reportUserBuildTargetProblems Verbosity
verbosity [UserBuildTargetProblem]
problems = do
case [ String
target | UserBuildTargetUnrecognised String
target <- [UserBuildTargetProblem]
problems ] of
[] -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
[String]
target ->
Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ String
"Unrecognised build target '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
name String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"'."
| String
name <- [String]
target ]
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Examples:\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" - build foo -- component name "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"(library, executable, test-suite or benchmark)\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" - build Data.Foo -- module name\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" - build Data/Foo.hsc -- file name\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" - build lib:foo exe:foo -- component qualified by kind\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" - build foo:Data.Foo -- module qualified by component\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" - build foo:Data/Foo.hsc -- file qualified by component"
showUserBuildTarget :: UserBuildTarget -> String
showUserBuildTarget :: UserBuildTarget -> String
showUserBuildTarget = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
":" ([String] -> String)
-> (UserBuildTarget -> [String]) -> UserBuildTarget -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserBuildTarget -> [String]
getComponents
where
getComponents :: UserBuildTarget -> [String]
getComponents (UserBuildTargetSingle String
s1) = [String
s1]
getComponents (UserBuildTargetDouble String
s1 String
s2) = [String
s1,String
s2]
getComponents (UserBuildTargetTriple String
s1 String
s2 String
s3) = [String
s1,String
s2,String
s3]
showBuildTarget' :: QualLevel -> PackageId -> BuildTarget -> String
showBuildTarget' :: QualLevel -> PackageId -> BuildTarget -> String
showBuildTarget' QualLevel
ql PackageId
pkgid BuildTarget
bt =
UserBuildTarget -> String
showUserBuildTarget (QualLevel -> BuildTarget -> PackageId -> UserBuildTarget
renderBuildTarget QualLevel
ql BuildTarget
bt PackageId
pkgid)
showBuildTarget :: PackageId -> BuildTarget -> String
showBuildTarget :: PackageId -> BuildTarget -> String
showBuildTarget PackageId
pkgid BuildTarget
t =
QualLevel -> PackageId -> BuildTarget -> String
showBuildTarget' (BuildTarget -> QualLevel
qlBuildTarget BuildTarget
t) PackageId
pkgid BuildTarget
t
where
qlBuildTarget :: BuildTarget -> QualLevel
qlBuildTarget BuildTargetComponent{} = QualLevel
QL2
qlBuildTarget BuildTarget
_ = QualLevel
QL3
resolveBuildTargets :: PackageDescription
-> [(UserBuildTarget, Bool)]
-> ([BuildTargetProblem], [BuildTarget])
resolveBuildTargets :: PackageDescription
-> [(UserBuildTarget, Bool)]
-> ([BuildTargetProblem], [BuildTarget])
resolveBuildTargets PackageDescription
pkg = [Either BuildTargetProblem BuildTarget]
-> ([BuildTargetProblem], [BuildTarget])
forall a b. [Either a b] -> ([a], [b])
partitionEithers
([Either BuildTargetProblem BuildTarget]
-> ([BuildTargetProblem], [BuildTarget]))
-> ([(UserBuildTarget, Bool)]
-> [Either BuildTargetProblem BuildTarget])
-> [(UserBuildTarget, Bool)]
-> ([BuildTargetProblem], [BuildTarget])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((UserBuildTarget, Bool) -> Either BuildTargetProblem BuildTarget)
-> [(UserBuildTarget, Bool)]
-> [Either BuildTargetProblem BuildTarget]
forall a b. (a -> b) -> [a] -> [b]
map ((UserBuildTarget -> Bool -> Either BuildTargetProblem BuildTarget)
-> (UserBuildTarget, Bool) -> Either BuildTargetProblem BuildTarget
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (PackageDescription
-> UserBuildTarget -> Bool -> Either BuildTargetProblem BuildTarget
resolveBuildTarget PackageDescription
pkg))
resolveBuildTarget :: PackageDescription -> UserBuildTarget -> Bool
-> Either BuildTargetProblem BuildTarget
resolveBuildTarget :: PackageDescription
-> UserBuildTarget -> Bool -> Either BuildTargetProblem BuildTarget
resolveBuildTarget PackageDescription
pkg UserBuildTarget
userTarget Bool
fexists =
case Match BuildTarget -> MaybeAmbiguous BuildTarget
forall b. Eq b => Match b -> MaybeAmbiguous b
findMatch (PackageDescription -> UserBuildTarget -> Bool -> Match BuildTarget
matchBuildTarget PackageDescription
pkg UserBuildTarget
userTarget Bool
fexists) of
Unambiguous BuildTarget
target -> BuildTarget -> Either BuildTargetProblem BuildTarget
forall a b. b -> Either a b
Right BuildTarget
target
Ambiguous [BuildTarget]
targets -> BuildTargetProblem -> Either BuildTargetProblem BuildTarget
forall a b. a -> Either a b
Left (UserBuildTarget
-> [(UserBuildTarget, BuildTarget)] -> BuildTargetProblem
BuildTargetAmbiguous UserBuildTarget
userTarget [(UserBuildTarget, BuildTarget)]
targets')
where targets' :: [(UserBuildTarget, BuildTarget)]
targets' = PackageId
-> UserBuildTarget
-> [BuildTarget]
-> [(UserBuildTarget, BuildTarget)]
disambiguateBuildTargets
(PackageDescription -> PackageId
forall pkg. Package pkg => pkg -> PackageId
packageId PackageDescription
pkg)
UserBuildTarget
userTarget
[BuildTarget]
targets
None [MatchError]
errs -> BuildTargetProblem -> Either BuildTargetProblem BuildTarget
forall a b. a -> Either a b
Left ([MatchError] -> BuildTargetProblem
classifyMatchErrors [MatchError]
errs)
where
classifyMatchErrors :: [MatchError] -> BuildTargetProblem
classifyMatchErrors [MatchError]
errs
| Just NonEmpty (String, String)
expected' <- [(String, String)] -> Maybe (NonEmpty (String, String))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [(String, String)]
expected
= let (NonEmpty String
things, String
got:|[String]
_) = NonEmpty (String, String) -> (NonEmpty String, NonEmpty String)
forall (f :: * -> *) a b. Functor f => f (a, b) -> (f a, f b)
NE.unzip NonEmpty (String, String)
expected' in
UserBuildTarget -> [String] -> String -> BuildTargetProblem
BuildTargetExpected UserBuildTarget
userTarget (NonEmpty String -> [String]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty String
things) String
got
| Bool -> Bool
not ([(String, String)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(String, String)]
nosuch) = UserBuildTarget -> [(String, String)] -> BuildTargetProblem
BuildTargetNoSuch UserBuildTarget
userTarget [(String, String)]
nosuch
| Bool
otherwise = String -> BuildTargetProblem
forall a. HasCallStack => String -> a
error (String -> BuildTargetProblem) -> String -> BuildTargetProblem
forall a b. (a -> b) -> a -> b
$ String
"resolveBuildTarget: internal error in matching"
where
expected :: [(String, String)]
expected = [ (String
thing, String
got) | MatchErrorExpected String
thing String
got <- [MatchError]
errs ]
nosuch :: [(String, String)]
nosuch = [ (String
thing, String
got) | MatchErrorNoSuch String
thing String
got <- [MatchError]
errs ]
data BuildTargetProblem
= BuildTargetExpected UserBuildTarget [String] String
| BuildTargetNoSuch UserBuildTarget [(String, String)]
| BuildTargetAmbiguous UserBuildTarget [(UserBuildTarget, BuildTarget)]
deriving Int -> BuildTargetProblem -> ShowS
[BuildTargetProblem] -> ShowS
BuildTargetProblem -> String
(Int -> BuildTargetProblem -> ShowS)
-> (BuildTargetProblem -> String)
-> ([BuildTargetProblem] -> ShowS)
-> Show BuildTargetProblem
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BuildTargetProblem] -> ShowS
$cshowList :: [BuildTargetProblem] -> ShowS
show :: BuildTargetProblem -> String
$cshow :: BuildTargetProblem -> String
showsPrec :: Int -> BuildTargetProblem -> ShowS
$cshowsPrec :: Int -> BuildTargetProblem -> ShowS
Show
disambiguateBuildTargets :: PackageId -> UserBuildTarget -> [BuildTarget]
-> [(UserBuildTarget, BuildTarget)]
disambiguateBuildTargets :: PackageId
-> UserBuildTarget
-> [BuildTarget]
-> [(UserBuildTarget, BuildTarget)]
disambiguateBuildTargets PackageId
pkgid UserBuildTarget
original =
QualLevel -> [BuildTarget] -> [(UserBuildTarget, BuildTarget)]
disambiguate (UserBuildTarget -> QualLevel
userTargetQualLevel UserBuildTarget
original)
where
disambiguate :: QualLevel -> [BuildTarget] -> [(UserBuildTarget, BuildTarget)]
disambiguate QualLevel
ql [BuildTarget]
ts
| [BuildTarget] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [BuildTarget]
amb = [(UserBuildTarget, BuildTarget)]
unamb
| Bool
otherwise = [(UserBuildTarget, BuildTarget)]
unamb [(UserBuildTarget, BuildTarget)]
-> [(UserBuildTarget, BuildTarget)]
-> [(UserBuildTarget, BuildTarget)]
forall a. [a] -> [a] -> [a]
++ QualLevel -> [BuildTarget] -> [(UserBuildTarget, BuildTarget)]
disambiguate (QualLevel -> QualLevel
forall a. Enum a => a -> a
succ QualLevel
ql) [BuildTarget]
amb
where
([BuildTarget]
amb, [(UserBuildTarget, BuildTarget)]
unamb) = QualLevel
-> [BuildTarget]
-> ([BuildTarget], [(UserBuildTarget, BuildTarget)])
step QualLevel
ql [BuildTarget]
ts
userTargetQualLevel :: UserBuildTarget -> QualLevel
userTargetQualLevel (UserBuildTargetSingle String
_ ) = QualLevel
QL1
userTargetQualLevel (UserBuildTargetDouble String
_ String
_ ) = QualLevel
QL2
userTargetQualLevel (UserBuildTargetTriple String
_ String
_ String
_) = QualLevel
QL3
step :: QualLevel -> [BuildTarget]
-> ([BuildTarget], [(UserBuildTarget, BuildTarget)])
step :: QualLevel
-> [BuildTarget]
-> ([BuildTarget], [(UserBuildTarget, BuildTarget)])
step QualLevel
ql = (\([[(UserBuildTarget, BuildTarget)]]
amb, [[(UserBuildTarget, BuildTarget)]]
unamb) -> (((UserBuildTarget, BuildTarget) -> BuildTarget)
-> [(UserBuildTarget, BuildTarget)] -> [BuildTarget]
forall a b. (a -> b) -> [a] -> [b]
map (UserBuildTarget, BuildTarget) -> BuildTarget
forall a b. (a, b) -> b
snd ([(UserBuildTarget, BuildTarget)] -> [BuildTarget])
-> [(UserBuildTarget, BuildTarget)] -> [BuildTarget]
forall a b. (a -> b) -> a -> b
$ [[(UserBuildTarget, BuildTarget)]]
-> [(UserBuildTarget, BuildTarget)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[(UserBuildTarget, BuildTarget)]]
amb, [[(UserBuildTarget, BuildTarget)]]
-> [(UserBuildTarget, BuildTarget)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[(UserBuildTarget, BuildTarget)]]
unamb))
(([[(UserBuildTarget, BuildTarget)]],
[[(UserBuildTarget, BuildTarget)]])
-> ([BuildTarget], [(UserBuildTarget, BuildTarget)]))
-> ([BuildTarget]
-> ([[(UserBuildTarget, BuildTarget)]],
[[(UserBuildTarget, BuildTarget)]]))
-> [BuildTarget]
-> ([BuildTarget], [(UserBuildTarget, BuildTarget)])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(UserBuildTarget, BuildTarget)] -> Bool)
-> [[(UserBuildTarget, BuildTarget)]]
-> ([[(UserBuildTarget, BuildTarget)]],
[[(UserBuildTarget, BuildTarget)]])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\[(UserBuildTarget, BuildTarget)]
g -> [(UserBuildTarget, BuildTarget)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(UserBuildTarget, BuildTarget)]
g Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1)
([[(UserBuildTarget, BuildTarget)]]
-> ([[(UserBuildTarget, BuildTarget)]],
[[(UserBuildTarget, BuildTarget)]]))
-> ([BuildTarget] -> [[(UserBuildTarget, BuildTarget)]])
-> [BuildTarget]
-> ([[(UserBuildTarget, BuildTarget)]],
[[(UserBuildTarget, BuildTarget)]])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((UserBuildTarget, BuildTarget)
-> (UserBuildTarget, BuildTarget) -> Bool)
-> [(UserBuildTarget, BuildTarget)]
-> [[(UserBuildTarget, BuildTarget)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (((UserBuildTarget, BuildTarget) -> UserBuildTarget)
-> (UserBuildTarget, BuildTarget)
-> (UserBuildTarget, BuildTarget)
-> Bool
forall a b. Eq a => (b -> a) -> b -> b -> Bool
equating (UserBuildTarget, BuildTarget) -> UserBuildTarget
forall a b. (a, b) -> a
fst)
([(UserBuildTarget, BuildTarget)]
-> [[(UserBuildTarget, BuildTarget)]])
-> ([BuildTarget] -> [(UserBuildTarget, BuildTarget)])
-> [BuildTarget]
-> [[(UserBuildTarget, BuildTarget)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((UserBuildTarget, BuildTarget)
-> (UserBuildTarget, BuildTarget) -> Ordering)
-> [(UserBuildTarget, BuildTarget)]
-> [(UserBuildTarget, BuildTarget)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((UserBuildTarget, BuildTarget) -> UserBuildTarget)
-> (UserBuildTarget, BuildTarget)
-> (UserBuildTarget, BuildTarget)
-> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (UserBuildTarget, BuildTarget) -> UserBuildTarget
forall a b. (a, b) -> a
fst)
([(UserBuildTarget, BuildTarget)]
-> [(UserBuildTarget, BuildTarget)])
-> ([BuildTarget] -> [(UserBuildTarget, BuildTarget)])
-> [BuildTarget]
-> [(UserBuildTarget, BuildTarget)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BuildTarget -> (UserBuildTarget, BuildTarget))
-> [BuildTarget] -> [(UserBuildTarget, BuildTarget)]
forall a b. (a -> b) -> [a] -> [b]
map (\BuildTarget
t -> (QualLevel -> BuildTarget -> PackageId -> UserBuildTarget
renderBuildTarget QualLevel
ql BuildTarget
t PackageId
pkgid, BuildTarget
t))
data QualLevel = QL1 | QL2 | QL3
deriving (Int -> QualLevel
QualLevel -> Int
QualLevel -> [QualLevel]
QualLevel -> QualLevel
QualLevel -> QualLevel -> [QualLevel]
QualLevel -> QualLevel -> QualLevel -> [QualLevel]
(QualLevel -> QualLevel)
-> (QualLevel -> QualLevel)
-> (Int -> QualLevel)
-> (QualLevel -> Int)
-> (QualLevel -> [QualLevel])
-> (QualLevel -> QualLevel -> [QualLevel])
-> (QualLevel -> QualLevel -> [QualLevel])
-> (QualLevel -> QualLevel -> QualLevel -> [QualLevel])
-> Enum QualLevel
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: QualLevel -> QualLevel -> QualLevel -> [QualLevel]
$cenumFromThenTo :: QualLevel -> QualLevel -> QualLevel -> [QualLevel]
enumFromTo :: QualLevel -> QualLevel -> [QualLevel]
$cenumFromTo :: QualLevel -> QualLevel -> [QualLevel]
enumFromThen :: QualLevel -> QualLevel -> [QualLevel]
$cenumFromThen :: QualLevel -> QualLevel -> [QualLevel]
enumFrom :: QualLevel -> [QualLevel]
$cenumFrom :: QualLevel -> [QualLevel]
fromEnum :: QualLevel -> Int
$cfromEnum :: QualLevel -> Int
toEnum :: Int -> QualLevel
$ctoEnum :: Int -> QualLevel
pred :: QualLevel -> QualLevel
$cpred :: QualLevel -> QualLevel
succ :: QualLevel -> QualLevel
$csucc :: QualLevel -> QualLevel
Enum, Int -> QualLevel -> ShowS
[QualLevel] -> ShowS
QualLevel -> String
(Int -> QualLevel -> ShowS)
-> (QualLevel -> String)
-> ([QualLevel] -> ShowS)
-> Show QualLevel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QualLevel] -> ShowS
$cshowList :: [QualLevel] -> ShowS
show :: QualLevel -> String
$cshow :: QualLevel -> String
showsPrec :: Int -> QualLevel -> ShowS
$cshowsPrec :: Int -> QualLevel -> ShowS
Show)
renderBuildTarget :: QualLevel -> BuildTarget -> PackageId -> UserBuildTarget
renderBuildTarget :: QualLevel -> BuildTarget -> PackageId -> UserBuildTarget
renderBuildTarget QualLevel
ql BuildTarget
target PackageId
pkgid =
case QualLevel
ql of
QualLevel
QL1 -> String -> UserBuildTarget
UserBuildTargetSingle String
s1 where s1 :: String
s1 = BuildTarget -> String
single BuildTarget
target
QualLevel
QL2 -> String -> String -> UserBuildTarget
UserBuildTargetDouble String
s1 String
s2 where (String
s1, String
s2) = BuildTarget -> (String, String)
double BuildTarget
target
QualLevel
QL3 -> String -> String -> String -> UserBuildTarget
UserBuildTargetTriple String
s1 String
s2 String
s3 where (String
s1, String
s2, String
s3) = BuildTarget -> (String, String, String)
triple BuildTarget
target
where
single :: BuildTarget -> String
single (BuildTargetComponent ComponentName
cn ) = ComponentName -> String
dispCName ComponentName
cn
single (BuildTargetModule ComponentName
_ ModuleName
m) = ModuleName -> String
forall a. Pretty a => a -> String
prettyShow ModuleName
m
single (BuildTargetFile ComponentName
_ String
f) = String
f
double :: BuildTarget -> (String, String)
double (BuildTargetComponent ComponentName
cn ) = (ComponentName -> String
dispKind ComponentName
cn, ComponentName -> String
dispCName ComponentName
cn)
double (BuildTargetModule ComponentName
cn ModuleName
m) = (ComponentName -> String
dispCName ComponentName
cn, ModuleName -> String
forall a. Pretty a => a -> String
prettyShow ModuleName
m)
double (BuildTargetFile ComponentName
cn String
f) = (ComponentName -> String
dispCName ComponentName
cn, String
f)
triple :: BuildTarget -> (String, String, String)
triple (BuildTargetComponent ComponentName
_ ) = String -> (String, String, String)
forall a. HasCallStack => String -> a
error String
"triple BuildTargetComponent"
triple (BuildTargetModule ComponentName
cn ModuleName
m) = (ComponentName -> String
dispKind ComponentName
cn, ComponentName -> String
dispCName ComponentName
cn, ModuleName -> String
forall a. Pretty a => a -> String
prettyShow ModuleName
m)
triple (BuildTargetFile ComponentName
cn String
f) = (ComponentName -> String
dispKind ComponentName
cn, ComponentName -> String
dispCName ComponentName
cn, String
f)
dispCName :: ComponentName -> String
dispCName = PackageId -> ComponentName -> String
forall pkg. Package pkg => pkg -> ComponentName -> String
componentStringName PackageId
pkgid
dispKind :: ComponentName -> String
dispKind = ComponentKind -> String
showComponentKindShort (ComponentKind -> String)
-> (ComponentName -> ComponentKind) -> ComponentName -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ComponentName -> ComponentKind
componentKind
reportBuildTargetProblems :: Verbosity -> [BuildTargetProblem] -> IO ()
reportBuildTargetProblems :: Verbosity -> [BuildTargetProblem] -> IO ()
reportBuildTargetProblems Verbosity
verbosity [BuildTargetProblem]
problems = do
case [ (UserBuildTarget
t, [String]
e, String
g) | BuildTargetExpected UserBuildTarget
t [String]
e String
g <- [BuildTargetProblem]
problems ] of
[] -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
[(UserBuildTarget, [String], String)]
targets ->
Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ String
"Unrecognised build target '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ UserBuildTarget -> String
showUserBuildTarget UserBuildTarget
target
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"'.\n"
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"Expected a " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" or " [String]
expected
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", rather than '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
got String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"'."
| (UserBuildTarget
target, [String]
expected, String
got) <- [(UserBuildTarget, [String], String)]
targets ]
case [ (UserBuildTarget
t, [(String, String)]
e) | BuildTargetNoSuch UserBuildTarget
t [(String, String)]
e <- [BuildTargetProblem]
problems ] of
[] -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
[(UserBuildTarget, [(String, String)])]
targets ->
Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ String
"Unknown build target '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ UserBuildTarget -> String
showUserBuildTarget UserBuildTarget
target
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"'.\nThere is no "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" or " [ ShowS
mungeThing String
thing String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
got String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"'"
| (String
thing, String
got) <- [(String, String)]
nosuch ] String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"."
| (UserBuildTarget
target, [(String, String)]
nosuch) <- [(UserBuildTarget, [(String, String)])]
targets ]
where
mungeThing :: ShowS
mungeThing String
"file" = String
"file target"
mungeThing String
thing = String
thing
case [ (UserBuildTarget
t, [(UserBuildTarget, BuildTarget)]
ts) | BuildTargetAmbiguous UserBuildTarget
t [(UserBuildTarget, BuildTarget)]
ts <- [BuildTargetProblem]
problems ] of
[] -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
[(UserBuildTarget, [(UserBuildTarget, BuildTarget)])]
targets ->
Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ String
"Ambiguous build target '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ UserBuildTarget -> String
showUserBuildTarget UserBuildTarget
target
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"'. It could be:\n "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ [String] -> String
unlines [ String
" "String -> ShowS
forall a. [a] -> [a] -> [a]
++ UserBuildTarget -> String
showUserBuildTarget UserBuildTarget
ut String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
" (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ BuildTarget -> String
showBuildTargetKind BuildTarget
bt String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
| (UserBuildTarget
ut, BuildTarget
bt) <- [(UserBuildTarget, BuildTarget)]
amb ]
| (UserBuildTarget
target, [(UserBuildTarget, BuildTarget)]
amb) <- [(UserBuildTarget, [(UserBuildTarget, BuildTarget)])]
targets ]
where
showBuildTargetKind :: BuildTarget -> String
showBuildTargetKind (BuildTargetComponent ComponentName
_ ) = String
"component"
showBuildTargetKind (BuildTargetModule ComponentName
_ ModuleName
_) = String
"module"
showBuildTargetKind (BuildTargetFile ComponentName
_ String
_) = String
"file"
matchBuildTarget :: PackageDescription
-> UserBuildTarget -> Bool -> Match BuildTarget
matchBuildTarget :: PackageDescription -> UserBuildTarget -> Bool -> Match BuildTarget
matchBuildTarget PackageDescription
pkg = \UserBuildTarget
utarget Bool
fexists ->
case UserBuildTarget
utarget of
UserBuildTargetSingle String
str1 ->
[ComponentInfo] -> String -> Bool -> Match BuildTarget
matchBuildTarget1 [ComponentInfo]
cinfo String
str1 Bool
fexists
UserBuildTargetDouble String
str1 String
str2 ->
[ComponentInfo] -> String -> String -> Bool -> Match BuildTarget
matchBuildTarget2 [ComponentInfo]
cinfo String
str1 String
str2 Bool
fexists
UserBuildTargetTriple String
str1 String
str2 String
str3 ->
[ComponentInfo]
-> String -> String -> String -> Bool -> Match BuildTarget
matchBuildTarget3 [ComponentInfo]
cinfo String
str1 String
str2 String
str3 Bool
fexists
where
cinfo :: [ComponentInfo]
cinfo = PackageDescription -> [ComponentInfo]
pkgComponentInfo PackageDescription
pkg
matchBuildTarget1 :: [ComponentInfo] -> String -> Bool -> Match BuildTarget
matchBuildTarget1 :: [ComponentInfo] -> String -> Bool -> Match BuildTarget
matchBuildTarget1 [ComponentInfo]
cinfo String
str1 Bool
fexists =
[ComponentInfo] -> String -> Match BuildTarget
matchComponent1 [ComponentInfo]
cinfo String
str1
Match BuildTarget -> Match BuildTarget -> Match BuildTarget
forall a. Match a -> Match a -> Match a
`matchPlusShadowing` [ComponentInfo] -> String -> Match BuildTarget
matchModule1 [ComponentInfo]
cinfo String
str1
Match BuildTarget -> Match BuildTarget -> Match BuildTarget
forall a. Match a -> Match a -> Match a
`matchPlusShadowing` [ComponentInfo] -> String -> Bool -> Match BuildTarget
matchFile1 [ComponentInfo]
cinfo String
str1 Bool
fexists
matchBuildTarget2 :: [ComponentInfo] -> String -> String -> Bool
-> Match BuildTarget
matchBuildTarget2 :: [ComponentInfo] -> String -> String -> Bool -> Match BuildTarget
matchBuildTarget2 [ComponentInfo]
cinfo String
str1 String
str2 Bool
fexists =
[ComponentInfo] -> String -> String -> Match BuildTarget
matchComponent2 [ComponentInfo]
cinfo String
str1 String
str2
Match BuildTarget -> Match BuildTarget -> Match BuildTarget
forall a. Match a -> Match a -> Match a
`matchPlusShadowing` [ComponentInfo] -> String -> String -> Match BuildTarget
matchModule2 [ComponentInfo]
cinfo String
str1 String
str2
Match BuildTarget -> Match BuildTarget -> Match BuildTarget
forall a. Match a -> Match a -> Match a
`matchPlusShadowing` [ComponentInfo] -> String -> String -> Bool -> Match BuildTarget
matchFile2 [ComponentInfo]
cinfo String
str1 String
str2 Bool
fexists
matchBuildTarget3 :: [ComponentInfo] -> String -> String -> String -> Bool
-> Match BuildTarget
matchBuildTarget3 :: [ComponentInfo]
-> String -> String -> String -> Bool -> Match BuildTarget
matchBuildTarget3 [ComponentInfo]
cinfo String
str1 String
str2 String
str3 Bool
fexists =
[ComponentInfo] -> String -> String -> String -> Match BuildTarget
matchModule3 [ComponentInfo]
cinfo String
str1 String
str2 String
str3
Match BuildTarget -> Match BuildTarget -> Match BuildTarget
forall a. Match a -> Match a -> Match a
`matchPlusShadowing` [ComponentInfo]
-> String -> String -> String -> Bool -> Match BuildTarget
matchFile3 [ComponentInfo]
cinfo String
str1 String
str2 String
str3 Bool
fexists
data ComponentInfo = ComponentInfo {
ComponentInfo -> ComponentName
cinfoName :: ComponentName,
ComponentInfo -> String
cinfoStrName :: ComponentStringName,
ComponentInfo -> [String]
cinfoSrcDirs :: [FilePath],
ComponentInfo -> [ModuleName]
cinfoModules :: [ModuleName],
ComponentInfo -> [String]
cinfoHsFiles :: [FilePath],
ComponentInfo -> [String]
cinfoAsmFiles:: [FilePath],
ComponentInfo -> [String]
cinfoCmmFiles:: [FilePath],
ComponentInfo -> [String]
cinfoCFiles :: [FilePath],
ComponentInfo -> [String]
cinfoCxxFiles:: [FilePath],
ComponentInfo -> [String]
cinfoJsFiles :: [FilePath]
}
type ComponentStringName = String
pkgComponentInfo :: PackageDescription -> [ComponentInfo]
pkgComponentInfo :: PackageDescription -> [ComponentInfo]
pkgComponentInfo PackageDescription
pkg =
[ ComponentInfo :: ComponentName
-> String
-> [String]
-> [ModuleName]
-> [String]
-> [String]
-> [String]
-> [String]
-> [String]
-> [String]
-> ComponentInfo
ComponentInfo {
cinfoName :: ComponentName
cinfoName = Component -> ComponentName
componentName Component
c,
cinfoStrName :: String
cinfoStrName = PackageDescription -> ComponentName -> String
forall pkg. Package pkg => pkg -> ComponentName -> String
componentStringName PackageDescription
pkg (Component -> ComponentName
componentName Component
c),
cinfoSrcDirs :: [String]
cinfoSrcDirs = BuildInfo -> [String]
hsSourceDirs BuildInfo
bi,
cinfoModules :: [ModuleName]
cinfoModules = Component -> [ModuleName]
componentModules Component
c,
cinfoHsFiles :: [String]
cinfoHsFiles = Component -> [String]
componentHsFiles Component
c,
cinfoAsmFiles :: [String]
cinfoAsmFiles= BuildInfo -> [String]
asmSources BuildInfo
bi,
cinfoCmmFiles :: [String]
cinfoCmmFiles= BuildInfo -> [String]
cmmSources BuildInfo
bi,
cinfoCFiles :: [String]
cinfoCFiles = BuildInfo -> [String]
cSources BuildInfo
bi,
cinfoCxxFiles :: [String]
cinfoCxxFiles= BuildInfo -> [String]
cxxSources BuildInfo
bi,
cinfoJsFiles :: [String]
cinfoJsFiles = BuildInfo -> [String]
jsSources BuildInfo
bi
}
| Component
c <- PackageDescription -> [Component]
pkgComponents PackageDescription
pkg
, let bi :: BuildInfo
bi = Component -> BuildInfo
componentBuildInfo Component
c ]
componentStringName :: Package pkg => pkg -> ComponentName -> ComponentStringName
componentStringName :: pkg -> ComponentName -> String
componentStringName pkg
pkg (CLibName LibraryName
LMainLibName ) = PackageName -> String
forall a. Pretty a => a -> String
prettyShow (pkg -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName pkg
pkg)
componentStringName pkg
_ (CLibName (LSubLibName UnqualComponentName
name)) = UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
name
componentStringName pkg
_ (CFLibName UnqualComponentName
name) = UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
name
componentStringName pkg
_ (CExeName UnqualComponentName
name) = UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
name
componentStringName pkg
_ (CTestName UnqualComponentName
name) = UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
name
componentStringName pkg
_ (CBenchName UnqualComponentName
name) = UnqualComponentName -> String
unUnqualComponentName UnqualComponentName
name
componentModules :: Component -> [ModuleName]
componentModules :: Component -> [ModuleName]
componentModules (CLib Library
lib) = Library -> [ModuleName]
explicitLibModules Library
lib
componentModules (CFLib ForeignLib
flib) = ForeignLib -> [ModuleName]
foreignLibModules ForeignLib
flib
componentModules (CExe Executable
exe) = Executable -> [ModuleName]
exeModules Executable
exe
componentModules (CTest TestSuite
test) = TestSuite -> [ModuleName]
testModules TestSuite
test
componentModules (CBench Benchmark
bench) = Benchmark -> [ModuleName]
benchmarkModules Benchmark
bench
componentHsFiles :: Component -> [FilePath]
componentHsFiles :: Component -> [String]
componentHsFiles (CExe Executable
exe) = [Executable -> String
modulePath Executable
exe]
componentHsFiles (CTest TestSuite {
testInterface :: TestSuite -> TestSuiteInterface
testInterface = TestSuiteExeV10 Version
_ String
mainfile
}) = [String
mainfile]
componentHsFiles (CBench Benchmark {
benchmarkInterface :: Benchmark -> BenchmarkInterface
benchmarkInterface = BenchmarkExeV10 Version
_ String
mainfile
}) = [String
mainfile]
componentHsFiles Component
_ = []
data ComponentKind = LibKind | FLibKind | ExeKind | TestKind | BenchKind
deriving (ComponentKind -> ComponentKind -> Bool
(ComponentKind -> ComponentKind -> Bool)
-> (ComponentKind -> ComponentKind -> Bool) -> Eq ComponentKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ComponentKind -> ComponentKind -> Bool
$c/= :: ComponentKind -> ComponentKind -> Bool
== :: ComponentKind -> ComponentKind -> Bool
$c== :: ComponentKind -> ComponentKind -> Bool
Eq, Eq ComponentKind
Eq ComponentKind
-> (ComponentKind -> ComponentKind -> Ordering)
-> (ComponentKind -> ComponentKind -> Bool)
-> (ComponentKind -> ComponentKind -> Bool)
-> (ComponentKind -> ComponentKind -> Bool)
-> (ComponentKind -> ComponentKind -> Bool)
-> (ComponentKind -> ComponentKind -> ComponentKind)
-> (ComponentKind -> ComponentKind -> ComponentKind)
-> Ord ComponentKind
ComponentKind -> ComponentKind -> Bool
ComponentKind -> ComponentKind -> Ordering
ComponentKind -> ComponentKind -> ComponentKind
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ComponentKind -> ComponentKind -> ComponentKind
$cmin :: ComponentKind -> ComponentKind -> ComponentKind
max :: ComponentKind -> ComponentKind -> ComponentKind
$cmax :: ComponentKind -> ComponentKind -> ComponentKind
>= :: ComponentKind -> ComponentKind -> Bool
$c>= :: ComponentKind -> ComponentKind -> Bool
> :: ComponentKind -> ComponentKind -> Bool
$c> :: ComponentKind -> ComponentKind -> Bool
<= :: ComponentKind -> ComponentKind -> Bool
$c<= :: ComponentKind -> ComponentKind -> Bool
< :: ComponentKind -> ComponentKind -> Bool
$c< :: ComponentKind -> ComponentKind -> Bool
compare :: ComponentKind -> ComponentKind -> Ordering
$ccompare :: ComponentKind -> ComponentKind -> Ordering
$cp1Ord :: Eq ComponentKind
Ord, Int -> ComponentKind -> ShowS
[ComponentKind] -> ShowS
ComponentKind -> String
(Int -> ComponentKind -> ShowS)
-> (ComponentKind -> String)
-> ([ComponentKind] -> ShowS)
-> Show ComponentKind
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ComponentKind] -> ShowS
$cshowList :: [ComponentKind] -> ShowS
show :: ComponentKind -> String
$cshow :: ComponentKind -> String
showsPrec :: Int -> ComponentKind -> ShowS
$cshowsPrec :: Int -> ComponentKind -> ShowS
Show, Int -> ComponentKind
ComponentKind -> Int
ComponentKind -> [ComponentKind]
ComponentKind -> ComponentKind
ComponentKind -> ComponentKind -> [ComponentKind]
ComponentKind -> ComponentKind -> ComponentKind -> [ComponentKind]
(ComponentKind -> ComponentKind)
-> (ComponentKind -> ComponentKind)
-> (Int -> ComponentKind)
-> (ComponentKind -> Int)
-> (ComponentKind -> [ComponentKind])
-> (ComponentKind -> ComponentKind -> [ComponentKind])
-> (ComponentKind -> ComponentKind -> [ComponentKind])
-> (ComponentKind
-> ComponentKind -> ComponentKind -> [ComponentKind])
-> Enum ComponentKind
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ComponentKind -> ComponentKind -> ComponentKind -> [ComponentKind]
$cenumFromThenTo :: ComponentKind -> ComponentKind -> ComponentKind -> [ComponentKind]
enumFromTo :: ComponentKind -> ComponentKind -> [ComponentKind]
$cenumFromTo :: ComponentKind -> ComponentKind -> [ComponentKind]
enumFromThen :: ComponentKind -> ComponentKind -> [ComponentKind]
$cenumFromThen :: ComponentKind -> ComponentKind -> [ComponentKind]
enumFrom :: ComponentKind -> [ComponentKind]
$cenumFrom :: ComponentKind -> [ComponentKind]
fromEnum :: ComponentKind -> Int
$cfromEnum :: ComponentKind -> Int
toEnum :: Int -> ComponentKind
$ctoEnum :: Int -> ComponentKind
pred :: ComponentKind -> ComponentKind
$cpred :: ComponentKind -> ComponentKind
succ :: ComponentKind -> ComponentKind
$csucc :: ComponentKind -> ComponentKind
Enum, ComponentKind
ComponentKind -> ComponentKind -> Bounded ComponentKind
forall a. a -> a -> Bounded a
maxBound :: ComponentKind
$cmaxBound :: ComponentKind
minBound :: ComponentKind
$cminBound :: ComponentKind
Bounded)
componentKind :: ComponentName -> ComponentKind
componentKind :: ComponentName -> ComponentKind
componentKind (CLibName LibraryName
_) = ComponentKind
LibKind
componentKind (CFLibName UnqualComponentName
_) = ComponentKind
FLibKind
componentKind (CExeName UnqualComponentName
_) = ComponentKind
ExeKind
componentKind (CTestName UnqualComponentName
_) = ComponentKind
TestKind
componentKind (CBenchName UnqualComponentName
_) = ComponentKind
BenchKind
cinfoKind :: ComponentInfo -> ComponentKind
cinfoKind :: ComponentInfo -> ComponentKind
cinfoKind = ComponentName -> ComponentKind
componentKind (ComponentName -> ComponentKind)
-> (ComponentInfo -> ComponentName)
-> ComponentInfo
-> ComponentKind
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ComponentInfo -> ComponentName
cinfoName
matchComponentKind :: String -> Match ComponentKind
matchComponentKind :: String -> Match ComponentKind
matchComponentKind String
s
| String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"lib", String
"library"] = ComponentKind -> Match ComponentKind
forall b. b -> Match b
return' ComponentKind
LibKind
| String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"flib", String
"foreign-lib", String
"foreign-library"] = ComponentKind -> Match ComponentKind
forall b. b -> Match b
return' ComponentKind
FLibKind
| String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"exe", String
"executable"] = ComponentKind -> Match ComponentKind
forall b. b -> Match b
return' ComponentKind
ExeKind
| String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"tst", String
"test", String
"test-suite"] = ComponentKind -> Match ComponentKind
forall b. b -> Match b
return' ComponentKind
TestKind
| String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"bench", String
"benchmark"] = ComponentKind -> Match ComponentKind
forall b. b -> Match b
return' ComponentKind
BenchKind
| Bool
otherwise = String -> String -> Match ComponentKind
forall a. String -> String -> Match a
matchErrorExpected String
"component kind" String
s
where
return' :: b -> Match b
return' b
ck = Match ()
increaseConfidence Match () -> Match b -> Match b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> b -> Match b
forall (m :: * -> *) a. Monad m => a -> m a
return b
ck
showComponentKind :: ComponentKind -> String
showComponentKind :: ComponentKind -> String
showComponentKind ComponentKind
LibKind = String
"library"
showComponentKind ComponentKind
FLibKind = String
"foreign-library"
showComponentKind ComponentKind
ExeKind = String
"executable"
showComponentKind ComponentKind
TestKind = String
"test-suite"
showComponentKind ComponentKind
BenchKind = String
"benchmark"
showComponentKindShort :: ComponentKind -> String
showComponentKindShort :: ComponentKind -> String
showComponentKindShort ComponentKind
LibKind = String
"lib"
showComponentKindShort ComponentKind
FLibKind = String
"flib"
showComponentKindShort ComponentKind
ExeKind = String
"exe"
showComponentKindShort ComponentKind
TestKind = String
"test"
showComponentKindShort ComponentKind
BenchKind = String
"bench"
matchComponent1 :: [ComponentInfo] -> String -> Match BuildTarget
matchComponent1 :: [ComponentInfo] -> String -> Match BuildTarget
matchComponent1 [ComponentInfo]
cs = \String
str1 -> do
String -> Match ()
guardComponentName String
str1
ComponentInfo
c <- [ComponentInfo] -> String -> Match ComponentInfo
matchComponentName [ComponentInfo]
cs String
str1
BuildTarget -> Match BuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentName -> BuildTarget
BuildTargetComponent (ComponentInfo -> ComponentName
cinfoName ComponentInfo
c))
matchComponent2 :: [ComponentInfo] -> String -> String -> Match BuildTarget
matchComponent2 :: [ComponentInfo] -> String -> String -> Match BuildTarget
matchComponent2 [ComponentInfo]
cs = \String
str1 String
str2 -> do
ComponentKind
ckind <- String -> Match ComponentKind
matchComponentKind String
str1
String -> Match ()
guardComponentName String
str2
ComponentInfo
c <- [ComponentInfo] -> ComponentKind -> String -> Match ComponentInfo
matchComponentKindAndName [ComponentInfo]
cs ComponentKind
ckind String
str2
BuildTarget -> Match BuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentName -> BuildTarget
BuildTargetComponent (ComponentInfo -> ComponentName
cinfoName ComponentInfo
c))
guardComponentName :: String -> Match ()
guardComponentName :: String -> Match ()
guardComponentName String
s
| (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
validComponentChar String
s
Bool -> Bool -> Bool
&& Bool -> Bool
not (String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
s) = Match ()
increaseConfidence
| Bool
otherwise = String -> String -> Match ()
forall a. String -> String -> Match a
matchErrorExpected String
"component name" String
s
where
validComponentChar :: Char -> Bool
validComponentChar Char
c = Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.'
Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\''
matchComponentName :: [ComponentInfo] -> String -> Match ComponentInfo
matchComponentName :: [ComponentInfo] -> String -> Match ComponentInfo
matchComponentName [ComponentInfo]
cs String
str =
String -> String -> Match ComponentInfo -> Match ComponentInfo
forall a. String -> String -> Match a -> Match a
orNoSuchThing String
"component" String
str
(Match ComponentInfo -> Match ComponentInfo)
-> Match ComponentInfo -> Match ComponentInfo
forall a b. (a -> b) -> a -> b
$ Match ComponentInfo -> Match ComponentInfo
forall a. Match a -> Match a
increaseConfidenceFor
(Match ComponentInfo -> Match ComponentInfo)
-> Match ComponentInfo -> Match ComponentInfo
forall a b. (a -> b) -> a -> b
$ ShowS -> [(String, ComponentInfo)] -> String -> Match ComponentInfo
forall a a' b.
(Ord a, Ord a') =>
(a -> a') -> [(a, b)] -> a -> Match b
matchInexactly ShowS
caseFold
[ (ComponentInfo -> String
cinfoStrName ComponentInfo
c, ComponentInfo
c) | ComponentInfo
c <- [ComponentInfo]
cs ]
String
str
matchComponentKindAndName :: [ComponentInfo] -> ComponentKind -> String
-> Match ComponentInfo
matchComponentKindAndName :: [ComponentInfo] -> ComponentKind -> String -> Match ComponentInfo
matchComponentKindAndName [ComponentInfo]
cs ComponentKind
ckind String
str =
String -> String -> Match ComponentInfo -> Match ComponentInfo
forall a. String -> String -> Match a -> Match a
orNoSuchThing (ComponentKind -> String
showComponentKind ComponentKind
ckind String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" component") String
str
(Match ComponentInfo -> Match ComponentInfo)
-> Match ComponentInfo -> Match ComponentInfo
forall a b. (a -> b) -> a -> b
$ Match ComponentInfo -> Match ComponentInfo
forall a. Match a -> Match a
increaseConfidenceFor
(Match ComponentInfo -> Match ComponentInfo)
-> Match ComponentInfo -> Match ComponentInfo
forall a b. (a -> b) -> a -> b
$ ((ComponentKind, String) -> (ComponentKind, String))
-> [((ComponentKind, String), ComponentInfo)]
-> (ComponentKind, String)
-> Match ComponentInfo
forall a a' b.
(Ord a, Ord a') =>
(a -> a') -> [(a, b)] -> a -> Match b
matchInexactly (\(ComponentKind
ck, String
cn) -> (ComponentKind
ck, ShowS
caseFold String
cn))
[ ((ComponentInfo -> ComponentKind
cinfoKind ComponentInfo
c, ComponentInfo -> String
cinfoStrName ComponentInfo
c), ComponentInfo
c) | ComponentInfo
c <- [ComponentInfo]
cs ]
(ComponentKind
ckind, String
str)
matchModule1 :: [ComponentInfo] -> String -> Match BuildTarget
matchModule1 :: [ComponentInfo] -> String -> Match BuildTarget
matchModule1 [ComponentInfo]
cs = \String
str1 -> do
String -> Match ()
guardModuleName String
str1
Match BuildTarget -> Match BuildTarget
forall a. Match a -> Match a
nubMatchErrors (Match BuildTarget -> Match BuildTarget)
-> Match BuildTarget -> Match BuildTarget
forall a b. (a -> b) -> a -> b
$ do
ComponentInfo
c <- [ComponentInfo] -> Match ComponentInfo
forall a. [a] -> Match a
tryEach [ComponentInfo]
cs
let ms :: [ModuleName]
ms = ComponentInfo -> [ModuleName]
cinfoModules ComponentInfo
c
ModuleName
m <- [ModuleName] -> String -> Match ModuleName
matchModuleName [ModuleName]
ms String
str1
BuildTarget -> Match BuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentName -> ModuleName -> BuildTarget
BuildTargetModule (ComponentInfo -> ComponentName
cinfoName ComponentInfo
c) ModuleName
m)
matchModule2 :: [ComponentInfo] -> String -> String -> Match BuildTarget
matchModule2 :: [ComponentInfo] -> String -> String -> Match BuildTarget
matchModule2 [ComponentInfo]
cs = \String
str1 String
str2 -> do
String -> Match ()
guardComponentName String
str1
String -> Match ()
guardModuleName String
str2
ComponentInfo
c <- [ComponentInfo] -> String -> Match ComponentInfo
matchComponentName [ComponentInfo]
cs String
str1
let ms :: [ModuleName]
ms = ComponentInfo -> [ModuleName]
cinfoModules ComponentInfo
c
ModuleName
m <- [ModuleName] -> String -> Match ModuleName
matchModuleName [ModuleName]
ms String
str2
BuildTarget -> Match BuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentName -> ModuleName -> BuildTarget
BuildTargetModule (ComponentInfo -> ComponentName
cinfoName ComponentInfo
c) ModuleName
m)
matchModule3 :: [ComponentInfo] -> String -> String -> String
-> Match BuildTarget
matchModule3 :: [ComponentInfo] -> String -> String -> String -> Match BuildTarget
matchModule3 [ComponentInfo]
cs String
str1 String
str2 String
str3 = do
ComponentKind
ckind <- String -> Match ComponentKind
matchComponentKind String
str1
String -> Match ()
guardComponentName String
str2
ComponentInfo
c <- [ComponentInfo] -> ComponentKind -> String -> Match ComponentInfo
matchComponentKindAndName [ComponentInfo]
cs ComponentKind
ckind String
str2
String -> Match ()
guardModuleName String
str3
let ms :: [ModuleName]
ms = ComponentInfo -> [ModuleName]
cinfoModules ComponentInfo
c
ModuleName
m <- [ModuleName] -> String -> Match ModuleName
matchModuleName [ModuleName]
ms String
str3
BuildTarget -> Match BuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentName -> ModuleName -> BuildTarget
BuildTargetModule (ComponentInfo -> ComponentName
cinfoName ComponentInfo
c) ModuleName
m)
guardModuleName :: String -> Match ()
guardModuleName :: String -> Match ()
guardModuleName String
s
| (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
validModuleChar String
s
Bool -> Bool -> Bool
&& Bool -> Bool
not (String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
s) = Match ()
increaseConfidence
| Bool
otherwise = String -> String -> Match ()
forall a. String -> String -> Match a
matchErrorExpected String
"module name" String
s
where
validModuleChar :: Char -> Bool
validModuleChar Char
c = Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\''
matchModuleName :: [ModuleName] -> String -> Match ModuleName
matchModuleName :: [ModuleName] -> String -> Match ModuleName
matchModuleName [ModuleName]
ms String
str =
String -> String -> Match ModuleName -> Match ModuleName
forall a. String -> String -> Match a -> Match a
orNoSuchThing String
"module" String
str
(Match ModuleName -> Match ModuleName)
-> Match ModuleName -> Match ModuleName
forall a b. (a -> b) -> a -> b
$ Match ModuleName -> Match ModuleName
forall a. Match a -> Match a
increaseConfidenceFor
(Match ModuleName -> Match ModuleName)
-> Match ModuleName -> Match ModuleName
forall a b. (a -> b) -> a -> b
$ ShowS -> [(String, ModuleName)] -> String -> Match ModuleName
forall a a' b.
(Ord a, Ord a') =>
(a -> a') -> [(a, b)] -> a -> Match b
matchInexactly ShowS
caseFold
[ (ModuleName -> String
forall a. Pretty a => a -> String
prettyShow ModuleName
m, ModuleName
m)
| ModuleName
m <- [ModuleName]
ms ]
String
str
matchFile1 :: [ComponentInfo] -> String -> Bool -> Match BuildTarget
matchFile1 :: [ComponentInfo] -> String -> Bool -> Match BuildTarget
matchFile1 [ComponentInfo]
cs String
str1 Bool
exists =
Match BuildTarget -> Match BuildTarget
forall a. Match a -> Match a
nubMatchErrors (Match BuildTarget -> Match BuildTarget)
-> Match BuildTarget -> Match BuildTarget
forall a b. (a -> b) -> a -> b
$ do
ComponentInfo
c <- [ComponentInfo] -> Match ComponentInfo
forall a. [a] -> Match a
tryEach [ComponentInfo]
cs
String
filepath <- ComponentInfo -> String -> Bool -> Match String
matchComponentFile ComponentInfo
c String
str1 Bool
exists
BuildTarget -> Match BuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentName -> String -> BuildTarget
BuildTargetFile (ComponentInfo -> ComponentName
cinfoName ComponentInfo
c) String
filepath)
matchFile2 :: [ComponentInfo] -> String -> String -> Bool -> Match BuildTarget
matchFile2 :: [ComponentInfo] -> String -> String -> Bool -> Match BuildTarget
matchFile2 [ComponentInfo]
cs String
str1 String
str2 Bool
exists = do
String -> Match ()
guardComponentName String
str1
ComponentInfo
c <- [ComponentInfo] -> String -> Match ComponentInfo
matchComponentName [ComponentInfo]
cs String
str1
String
filepath <- ComponentInfo -> String -> Bool -> Match String
matchComponentFile ComponentInfo
c String
str2 Bool
exists
BuildTarget -> Match BuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentName -> String -> BuildTarget
BuildTargetFile (ComponentInfo -> ComponentName
cinfoName ComponentInfo
c) String
filepath)
matchFile3 :: [ComponentInfo] -> String -> String -> String -> Bool
-> Match BuildTarget
matchFile3 :: [ComponentInfo]
-> String -> String -> String -> Bool -> Match BuildTarget
matchFile3 [ComponentInfo]
cs String
str1 String
str2 String
str3 Bool
exists = do
ComponentKind
ckind <- String -> Match ComponentKind
matchComponentKind String
str1
String -> Match ()
guardComponentName String
str2
ComponentInfo
c <- [ComponentInfo] -> ComponentKind -> String -> Match ComponentInfo
matchComponentKindAndName [ComponentInfo]
cs ComponentKind
ckind String
str2
String
filepath <- ComponentInfo -> String -> Bool -> Match String
matchComponentFile ComponentInfo
c String
str3 Bool
exists
BuildTarget -> Match BuildTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentName -> String -> BuildTarget
BuildTargetFile (ComponentInfo -> ComponentName
cinfoName ComponentInfo
c) String
filepath)
matchComponentFile :: ComponentInfo -> String -> Bool -> Match FilePath
matchComponentFile :: ComponentInfo -> String -> Bool -> Match String
matchComponentFile ComponentInfo
c String
str Bool
fexists =
String -> String -> Match String -> Match String
forall a. String -> String -> Match a -> Match a
expecting String
"file" String
str (Match String -> Match String) -> Match String -> Match String
forall a b. (a -> b) -> a -> b
$
Match String -> Match String -> Match String
forall a. Match a -> Match a -> Match a
matchPlus
(String -> Bool -> Match String
forall a. String -> Bool -> Match a
matchFileExists String
str Bool
fexists)
(Match String -> Match String -> Match String
forall a. Match a -> Match a -> Match a
matchPlusShadowing
([Match String] -> Match String
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [ [String] -> [ModuleName] -> String -> Match String
matchModuleFileRooted [String]
dirs [ModuleName]
ms String
str
, [String] -> [String] -> String -> Match String
matchOtherFileRooted [String]
dirs [String]
hsFiles String
str ])
([Match String] -> Match String
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [ [ModuleName] -> String -> Match String
matchModuleFileUnrooted [ModuleName]
ms String
str
, [String] -> String -> Match String
matchOtherFileUnrooted [String]
hsFiles String
str
, [String] -> String -> Match String
matchOtherFileUnrooted [String]
cFiles String
str
, [String] -> String -> Match String
matchOtherFileUnrooted [String]
jsFiles String
str ]))
where
dirs :: [String]
dirs = ComponentInfo -> [String]
cinfoSrcDirs ComponentInfo
c
ms :: [ModuleName]
ms = ComponentInfo -> [ModuleName]
cinfoModules ComponentInfo
c
hsFiles :: [String]
hsFiles = ComponentInfo -> [String]
cinfoHsFiles ComponentInfo
c
cFiles :: [String]
cFiles = ComponentInfo -> [String]
cinfoCFiles ComponentInfo
c
jsFiles :: [String]
jsFiles = ComponentInfo -> [String]
cinfoJsFiles ComponentInfo
c
matchFileExists :: FilePath -> Bool -> Match a
matchFileExists :: String -> Bool -> Match a
matchFileExists String
_ Bool
False = Match a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
matchFileExists String
fname Bool
True = do Match ()
increaseConfidence
String -> String -> Match a
forall a. String -> String -> Match a
matchErrorNoSuch String
"file" String
fname
matchModuleFileUnrooted :: [ModuleName] -> String -> Match FilePath
matchModuleFileUnrooted :: [ModuleName] -> String -> Match String
matchModuleFileUnrooted [ModuleName]
ms String
str = do
let filepath :: String
filepath = ShowS
normalise String
str
ModuleName
_ <- [ModuleName] -> String -> Match ModuleName
matchModuleFileStem [ModuleName]
ms String
filepath
String -> Match String
forall (m :: * -> *) a. Monad m => a -> m a
return String
filepath
matchModuleFileRooted :: [FilePath] -> [ModuleName] -> String -> Match FilePath
matchModuleFileRooted :: [String] -> [ModuleName] -> String -> Match String
matchModuleFileRooted [String]
dirs [ModuleName]
ms String
str = Match String -> Match String
forall a. Eq a => Match a -> Match a
nubMatches (Match String -> Match String) -> Match String -> Match String
forall a b. (a -> b) -> a -> b
$ do
let filepath :: String
filepath = ShowS
normalise String
str
String
filepath' <- [String] -> String -> Match String
matchDirectoryPrefix [String]
dirs String
filepath
ModuleName
_ <- [ModuleName] -> String -> Match ModuleName
matchModuleFileStem [ModuleName]
ms String
filepath'
String -> Match String
forall (m :: * -> *) a. Monad m => a -> m a
return String
filepath
matchModuleFileStem :: [ModuleName] -> FilePath -> Match ModuleName
matchModuleFileStem :: [ModuleName] -> String -> Match ModuleName
matchModuleFileStem [ModuleName]
ms =
Match ModuleName -> Match ModuleName
forall a. Match a -> Match a
increaseConfidenceFor
(Match ModuleName -> Match ModuleName)
-> (String -> Match ModuleName) -> String -> Match ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS -> [(String, ModuleName)] -> String -> Match ModuleName
forall a a' b.
(Ord a, Ord a') =>
(a -> a') -> [(a, b)] -> a -> Match b
matchInexactly ShowS
caseFold
[ (ModuleName -> String
toFilePath ModuleName
m, ModuleName
m) | ModuleName
m <- [ModuleName]
ms ]
(String -> Match ModuleName) -> ShowS -> String -> Match ModuleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
dropExtension
matchOtherFileRooted :: [FilePath] -> [FilePath] -> FilePath -> Match FilePath
matchOtherFileRooted :: [String] -> [String] -> String -> Match String
matchOtherFileRooted [String]
dirs [String]
fs String
str = do
let filepath :: String
filepath = ShowS
normalise String
str
String
filepath' <- [String] -> String -> Match String
matchDirectoryPrefix [String]
dirs String
filepath
String
_ <- [String] -> String -> Match String
matchFile [String]
fs String
filepath'
String -> Match String
forall (m :: * -> *) a. Monad m => a -> m a
return String
filepath
matchOtherFileUnrooted :: [FilePath] -> FilePath -> Match FilePath
matchOtherFileUnrooted :: [String] -> String -> Match String
matchOtherFileUnrooted [String]
fs String
str = do
let filepath :: String
filepath = ShowS
normalise String
str
String
_ <- [String] -> String -> Match String
matchFile [String]
fs String
filepath
String -> Match String
forall (m :: * -> *) a. Monad m => a -> m a
return String
filepath
matchFile :: [FilePath] -> FilePath -> Match FilePath
matchFile :: [String] -> String -> Match String
matchFile [String]
fs = Match String -> Match String
forall a. Match a -> Match a
increaseConfidenceFor
(Match String -> Match String)
-> (String -> Match String) -> String -> Match String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS -> [(String, String)] -> String -> Match String
forall a a' b.
(Ord a, Ord a') =>
(a -> a') -> [(a, b)] -> a -> Match b
matchInexactly ShowS
caseFold [ (String
f, String
f) | String
f <- [String]
fs ]
matchDirectoryPrefix :: [FilePath] -> FilePath -> Match FilePath
matchDirectoryPrefix :: [String] -> String -> Match String
matchDirectoryPrefix [String]
dirs String
filepath =
[String] -> Match String
forall a. [a] -> Match a
exactMatches ([String] -> Match String) -> [String] -> Match String
forall a b. (a -> b) -> a -> b
$
[Maybe String] -> [String]
forall a. [Maybe a] -> [a]
catMaybes
[ String -> String -> Maybe String
stripDirectory (ShowS
normalise String
dir) String
filepath | String
dir <- [String]
dirs ]
where
stripDirectory :: FilePath -> FilePath -> Maybe FilePath
stripDirectory :: String -> String -> Maybe String
stripDirectory String
dir String
fp =
[String] -> String
joinPath ([String] -> String) -> Maybe [String] -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` [String] -> [String] -> Maybe [String]
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix (String -> [String]
splitDirectories String
dir) (String -> [String]
splitDirectories String
fp)
data Match a = NoMatch Confidence [MatchError]
| ExactMatch Confidence [a]
| InexactMatch Confidence [a]
deriving Int -> Match a -> ShowS
[Match a] -> ShowS
Match a -> String
(Int -> Match a -> ShowS)
-> (Match a -> String) -> ([Match a] -> ShowS) -> Show (Match a)
forall a. Show a => Int -> Match a -> ShowS
forall a. Show a => [Match a] -> ShowS
forall a. Show a => Match a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Match a] -> ShowS
$cshowList :: forall a. Show a => [Match a] -> ShowS
show :: Match a -> String
$cshow :: forall a. Show a => Match a -> String
showsPrec :: Int -> Match a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Match a -> ShowS
Show
type Confidence = Int
data MatchError = MatchErrorExpected String String
| MatchErrorNoSuch String String
deriving (Int -> MatchError -> ShowS
[MatchError] -> ShowS
MatchError -> String
(Int -> MatchError -> ShowS)
-> (MatchError -> String)
-> ([MatchError] -> ShowS)
-> Show MatchError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MatchError] -> ShowS
$cshowList :: [MatchError] -> ShowS
show :: MatchError -> String
$cshow :: MatchError -> String
showsPrec :: Int -> MatchError -> ShowS
$cshowsPrec :: Int -> MatchError -> ShowS
Show, MatchError -> MatchError -> Bool
(MatchError -> MatchError -> Bool)
-> (MatchError -> MatchError -> Bool) -> Eq MatchError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MatchError -> MatchError -> Bool
$c/= :: MatchError -> MatchError -> Bool
== :: MatchError -> MatchError -> Bool
$c== :: MatchError -> MatchError -> Bool
Eq)
instance Alternative Match where
empty :: Match a
empty = Match a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
<|> :: Match a -> Match a -> Match a
(<|>) = Match a -> Match a -> Match a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus
instance MonadPlus Match where
mzero :: Match a
mzero = Match a
forall a. Match a
matchZero
mplus :: Match a -> Match a -> Match a
mplus = Match a -> Match a -> Match a
forall a. Match a -> Match a -> Match a
matchPlus
matchZero :: Match a
matchZero :: Match a
matchZero = Int -> [MatchError] -> Match a
forall a. Int -> [MatchError] -> Match a
NoMatch Int
0 []
matchPlus :: Match a -> Match a -> Match a
matchPlus :: Match a -> Match a -> Match a
matchPlus (ExactMatch Int
d1 [a]
xs) (ExactMatch Int
d2 [a]
xs') =
Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
ExactMatch (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
d1 Int
d2) ([a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
xs')
matchPlus a :: Match a
a@(ExactMatch Int
_ [a]
_ ) (InexactMatch Int
_ [a]
_ ) = Match a
a
matchPlus a :: Match a
a@(ExactMatch Int
_ [a]
_ ) (NoMatch Int
_ [MatchError]
_ ) = Match a
a
matchPlus (InexactMatch Int
_ [a]
_ ) b :: Match a
b@(ExactMatch Int
_ [a]
_ ) = Match a
b
matchPlus (InexactMatch Int
d1 [a]
xs) (InexactMatch Int
d2 [a]
xs') =
Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
InexactMatch (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
d1 Int
d2) ([a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
xs')
matchPlus a :: Match a
a@(InexactMatch Int
_ [a]
_ ) (NoMatch Int
_ [MatchError]
_ ) = Match a
a
matchPlus (NoMatch Int
_ [MatchError]
_ ) b :: Match a
b@(ExactMatch Int
_ [a]
_ ) = Match a
b
matchPlus (NoMatch Int
_ [MatchError]
_ ) b :: Match a
b@(InexactMatch Int
_ [a]
_ ) = Match a
b
matchPlus a :: Match a
a@(NoMatch Int
d1 [MatchError]
ms) b :: Match a
b@(NoMatch Int
d2 [MatchError]
ms')
| Int
d1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
d2 = Match a
a
| Int
d1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
d2 = Match a
b
| Bool
otherwise = Int -> [MatchError] -> Match a
forall a. Int -> [MatchError] -> Match a
NoMatch Int
d1 ([MatchError]
ms [MatchError] -> [MatchError] -> [MatchError]
forall a. [a] -> [a] -> [a]
++ [MatchError]
ms')
matchPlusShadowing :: Match a -> Match a -> Match a
matchPlusShadowing :: Match a -> Match a -> Match a
matchPlusShadowing a :: Match a
a@(ExactMatch Int
_ [a]
_) (ExactMatch Int
_ [a]
_) = Match a
a
matchPlusShadowing Match a
a Match a
b = Match a -> Match a -> Match a
forall a. Match a -> Match a -> Match a
matchPlus Match a
a Match a
b
instance Functor Match where
fmap :: (a -> b) -> Match a -> Match b
fmap a -> b
_ (NoMatch Int
d [MatchError]
ms) = Int -> [MatchError] -> Match b
forall a. Int -> [MatchError] -> Match a
NoMatch Int
d [MatchError]
ms
fmap a -> b
f (ExactMatch Int
d [a]
xs) = Int -> [b] -> Match b
forall a. Int -> [a] -> Match a
ExactMatch Int
d ((a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f [a]
xs)
fmap a -> b
f (InexactMatch Int
d [a]
xs) = Int -> [b] -> Match b
forall a. Int -> [a] -> Match a
InexactMatch Int
d ((a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f [a]
xs)
instance Applicative Match where
pure :: a -> Match a
pure a
a = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
ExactMatch Int
0 [a
a]
<*> :: Match (a -> b) -> Match a -> Match b
(<*>) = Match (a -> b) -> Match a -> Match b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad Match where
return :: a -> Match a
return = a -> Match a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
NoMatch Int
d [MatchError]
ms >>= :: Match a -> (a -> Match b) -> Match b
>>= a -> Match b
_ = Int -> [MatchError] -> Match b
forall a. Int -> [MatchError] -> Match a
NoMatch Int
d [MatchError]
ms
ExactMatch Int
d [a]
xs >>= a -> Match b
f = Int -> Match b -> Match b
forall a. Int -> Match a -> Match a
addDepth Int
d
(Match b -> Match b) -> Match b -> Match b
forall a b. (a -> b) -> a -> b
$ (Match b -> Match b -> Match b) -> Match b -> [Match b] -> Match b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Match b -> Match b -> Match b
forall a. Match a -> Match a -> Match a
matchPlus Match b
forall a. Match a
matchZero ((a -> Match b) -> [a] -> [Match b]
forall a b. (a -> b) -> [a] -> [b]
map a -> Match b
f [a]
xs)
InexactMatch Int
d [a]
xs >>= a -> Match b
f = Int -> Match b -> Match b
forall a. Int -> Match a -> Match a
addDepth Int
d (Match b -> Match b) -> (Match b -> Match b) -> Match b -> Match b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Match b -> Match b
forall a. Match a -> Match a
forceInexact
(Match b -> Match b) -> Match b -> Match b
forall a b. (a -> b) -> a -> b
$ (Match b -> Match b -> Match b) -> Match b -> [Match b] -> Match b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Match b -> Match b -> Match b
forall a. Match a -> Match a -> Match a
matchPlus Match b
forall a. Match a
matchZero ((a -> Match b) -> [a] -> [Match b]
forall a b. (a -> b) -> [a] -> [b]
map a -> Match b
f [a]
xs)
addDepth :: Confidence -> Match a -> Match a
addDepth :: Int -> Match a -> Match a
addDepth Int
d' (NoMatch Int
d [MatchError]
msgs) = Int -> [MatchError] -> Match a
forall a. Int -> [MatchError] -> Match a
NoMatch (Int
d'Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) [MatchError]
msgs
addDepth Int
d' (ExactMatch Int
d [a]
xs) = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
ExactMatch (Int
d'Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) [a]
xs
addDepth Int
d' (InexactMatch Int
d [a]
xs) = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
InexactMatch (Int
d'Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) [a]
xs
forceInexact :: Match a -> Match a
forceInexact :: Match a -> Match a
forceInexact (ExactMatch Int
d [a]
ys) = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
InexactMatch Int
d [a]
ys
forceInexact Match a
m = Match a
m
matchErrorExpected, matchErrorNoSuch :: String -> String -> Match a
matchErrorExpected :: String -> String -> Match a
matchErrorExpected String
thing String
got = Int -> [MatchError] -> Match a
forall a. Int -> [MatchError] -> Match a
NoMatch Int
0 [String -> String -> MatchError
MatchErrorExpected String
thing String
got]
matchErrorNoSuch :: String -> String -> Match a
matchErrorNoSuch String
thing String
got = Int -> [MatchError] -> Match a
forall a. Int -> [MatchError] -> Match a
NoMatch Int
0 [String -> String -> MatchError
MatchErrorNoSuch String
thing String
got]
expecting :: String -> String -> Match a -> Match a
expecting :: String -> String -> Match a -> Match a
expecting String
thing String
got (NoMatch Int
0 [MatchError]
_) = String -> String -> Match a
forall a. String -> String -> Match a
matchErrorExpected String
thing String
got
expecting String
_ String
_ Match a
m = Match a
m
orNoSuchThing :: String -> String -> Match a -> Match a
orNoSuchThing :: String -> String -> Match a -> Match a
orNoSuchThing String
thing String
got (NoMatch Int
0 [MatchError]
_) = String -> String -> Match a
forall a. String -> String -> Match a
matchErrorNoSuch String
thing String
got
orNoSuchThing String
_ String
_ Match a
m = Match a
m
increaseConfidence :: Match ()
increaseConfidence :: Match ()
increaseConfidence = Int -> [()] -> Match ()
forall a. Int -> [a] -> Match a
ExactMatch Int
1 [()]
increaseConfidenceFor :: Match a -> Match a
increaseConfidenceFor :: Match a -> Match a
increaseConfidenceFor Match a
m = Match a
m Match a -> (a -> Match a) -> Match a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
r -> Match ()
increaseConfidence Match () -> Match a -> Match a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> Match a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
nubMatches :: Eq a => Match a -> Match a
nubMatches :: Match a -> Match a
nubMatches (NoMatch Int
d [MatchError]
msgs) = Int -> [MatchError] -> Match a
forall a. Int -> [MatchError] -> Match a
NoMatch Int
d [MatchError]
msgs
nubMatches (ExactMatch Int
d [a]
xs) = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
ExactMatch Int
d ([a] -> [a]
forall a. Eq a => [a] -> [a]
nub [a]
xs)
nubMatches (InexactMatch Int
d [a]
xs) = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
InexactMatch Int
d ([a] -> [a]
forall a. Eq a => [a] -> [a]
nub [a]
xs)
nubMatchErrors :: Match a -> Match a
nubMatchErrors :: Match a -> Match a
nubMatchErrors (NoMatch Int
d [MatchError]
msgs) = Int -> [MatchError] -> Match a
forall a. Int -> [MatchError] -> Match a
NoMatch Int
d ([MatchError] -> [MatchError]
forall a. Eq a => [a] -> [a]
nub [MatchError]
msgs)
nubMatchErrors (ExactMatch Int
d [a]
xs) = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
ExactMatch Int
d [a]
xs
nubMatchErrors (InexactMatch Int
d [a]
xs) = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
InexactMatch Int
d [a]
xs
exactMatches, inexactMatches :: [a] -> Match a
exactMatches :: [a] -> Match a
exactMatches [] = Match a
forall a. Match a
matchZero
exactMatches [a]
xs = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
ExactMatch Int
0 [a]
xs
inexactMatches :: [a] -> Match a
inexactMatches [] = Match a
forall a. Match a
matchZero
inexactMatches [a]
xs = Int -> [a] -> Match a
forall a. Int -> [a] -> Match a
InexactMatch Int
0 [a]
xs
tryEach :: [a] -> Match a
tryEach :: [a] -> Match a
tryEach = [a] -> Match a
forall a. [a] -> Match a
exactMatches
findMatch :: Eq b => Match b -> MaybeAmbiguous b
findMatch :: Match b -> MaybeAmbiguous b
findMatch Match b
match =
case Match b
match of
NoMatch Int
_ [MatchError]
msgs -> [MatchError] -> MaybeAmbiguous b
forall a. [MatchError] -> MaybeAmbiguous a
None ([MatchError] -> [MatchError]
forall a. Eq a => [a] -> [a]
nub [MatchError]
msgs)
ExactMatch Int
_ [b]
xs -> [b] -> MaybeAmbiguous b
forall a. Eq a => [a] -> MaybeAmbiguous a
checkAmbiguous [b]
xs
InexactMatch Int
_ [b]
xs -> [b] -> MaybeAmbiguous b
forall a. Eq a => [a] -> MaybeAmbiguous a
checkAmbiguous [b]
xs
where
checkAmbiguous :: [a] -> MaybeAmbiguous a
checkAmbiguous [a]
xs = case [a] -> [a]
forall a. Eq a => [a] -> [a]
nub [a]
xs of
[a
x] -> a -> MaybeAmbiguous a
forall a. a -> MaybeAmbiguous a
Unambiguous a
x
[a]
xs' -> [a] -> MaybeAmbiguous a
forall a. [a] -> MaybeAmbiguous a
Ambiguous [a]
xs'
data MaybeAmbiguous a = None [MatchError] | Unambiguous a | Ambiguous [a]
deriving Int -> MaybeAmbiguous a -> ShowS
[MaybeAmbiguous a] -> ShowS
MaybeAmbiguous a -> String
(Int -> MaybeAmbiguous a -> ShowS)
-> (MaybeAmbiguous a -> String)
-> ([MaybeAmbiguous a] -> ShowS)
-> Show (MaybeAmbiguous a)
forall a. Show a => Int -> MaybeAmbiguous a -> ShowS
forall a. Show a => [MaybeAmbiguous a] -> ShowS
forall a. Show a => MaybeAmbiguous a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MaybeAmbiguous a] -> ShowS
$cshowList :: forall a. Show a => [MaybeAmbiguous a] -> ShowS
show :: MaybeAmbiguous a -> String
$cshow :: forall a. Show a => MaybeAmbiguous a -> String
showsPrec :: Int -> MaybeAmbiguous a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> MaybeAmbiguous a -> ShowS
Show
matchInexactly :: (Ord a, Ord a') =>
(a -> a') ->
[(a, b)] -> (a -> Match b)
matchInexactly :: (a -> a') -> [(a, b)] -> a -> Match b
matchInexactly a -> a'
cannonicalise [(a, b)]
xs =
\a
x -> case a -> Map a [b] -> Maybe [b]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup a
x Map a [b]
m of
Just [b]
ys -> [b] -> Match b
forall a. [a] -> Match a
exactMatches [b]
ys
Maybe [b]
Nothing -> case a' -> Map a' [b] -> Maybe [b]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (a -> a'
cannonicalise a
x) Map a' [b]
m' of
Just [b]
ys -> [b] -> Match b
forall a. [a] -> Match a
inexactMatches [b]
ys
Maybe [b]
Nothing -> Match b
forall a. Match a
matchZero
where
m :: Map a [b]
m = ([b] -> [b] -> [b]) -> [(a, [b])] -> Map a [b]
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith [b] -> [b] -> [b]
forall a. [a] -> [a] -> [a]
(++) [ (a
k,[b
x]) | (a
k,b
x) <- [(a, b)]
xs ]
m' :: Map a' [b]
m' = ([b] -> [b] -> [b]) -> (a -> a') -> Map a [b] -> Map a' [b]
forall k2 a k1.
Ord k2 =>
(a -> a -> a) -> (k1 -> k2) -> Map k1 a -> Map k2 a
Map.mapKeysWith [b] -> [b] -> [b]
forall a. [a] -> [a] -> [a]
(++) a -> a'
cannonicalise Map a [b]
m
caseFold :: String -> String
caseFold :: ShowS
caseFold = ShowS
lowercase
checkBuildTargets :: Verbosity -> PackageDescription -> LocalBuildInfo -> [BuildTarget]
-> IO [TargetInfo]
checkBuildTargets :: Verbosity
-> PackageDescription
-> LocalBuildInfo
-> [BuildTarget]
-> IO [TargetInfo]
checkBuildTargets Verbosity
_ PackageDescription
pkg_descr LocalBuildInfo
lbi [] =
[TargetInfo] -> IO [TargetInfo]
forall (m :: * -> *) a. Monad m => a -> m a
return (PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi)
checkBuildTargets Verbosity
verbosity PackageDescription
pkg_descr LocalBuildInfo
lbi [BuildTarget]
targets = do
let ([(ComponentName, Maybe (Either ModuleName String))]
enabled, [(ComponentName, ComponentDisabledReason)]
disabled) =
[Either
(ComponentName, Maybe (Either ModuleName String))
(ComponentName, ComponentDisabledReason)]
-> ([(ComponentName, Maybe (Either ModuleName String))],
[(ComponentName, ComponentDisabledReason)])
forall a b. [Either a b] -> ([a], [b])
partitionEithers
[ case ComponentRequestedSpec
-> Component -> Maybe ComponentDisabledReason
componentDisabledReason (LocalBuildInfo -> ComponentRequestedSpec
componentEnabledSpec LocalBuildInfo
lbi) Component
comp of
Maybe ComponentDisabledReason
Nothing -> (ComponentName, Maybe (Either ModuleName String))
-> Either
(ComponentName, Maybe (Either ModuleName String))
(ComponentName, ComponentDisabledReason)
forall a b. a -> Either a b
Left (ComponentName, Maybe (Either ModuleName String))
target'
Just ComponentDisabledReason
reason -> (ComponentName, ComponentDisabledReason)
-> Either
(ComponentName, Maybe (Either ModuleName String))
(ComponentName, ComponentDisabledReason)
forall a b. b -> Either a b
Right (ComponentName
cname, ComponentDisabledReason
reason)
| BuildTarget
target <- [BuildTarget]
targets
, let target' :: (ComponentName, Maybe (Either ModuleName String))
target'@(ComponentName
cname,Maybe (Either ModuleName String)
_) = BuildTarget -> (ComponentName, Maybe (Either ModuleName String))
swizzleTarget BuildTarget
target
, let comp :: Component
comp = PackageDescription -> ComponentName -> Component
getComponent PackageDescription
pkg_descr ComponentName
cname ]
case [(ComponentName, ComponentDisabledReason)]
disabled of
[] -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
((ComponentName
cname,ComponentDisabledReason
reason):[(ComponentName, ComponentDisabledReason)]
_) -> Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> ComponentDisabledReason -> String
formatReason (ComponentName -> String
showComponentName ComponentName
cname) ComponentDisabledReason
reason
[(ComponentName, Either ModuleName String)]
-> ((ComponentName, Either ModuleName String) -> IO ()) -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [ (ComponentName
c, Either ModuleName String
t) | (ComponentName
c, Just Either ModuleName String
t) <- [(ComponentName, Maybe (Either ModuleName String))]
enabled ] (((ComponentName, Either ModuleName String) -> IO ()) -> IO ())
-> ((ComponentName, Either ModuleName String) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(ComponentName
c, Either ModuleName String
t) ->
Verbosity -> String -> IO ()
warn Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Ignoring '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (ModuleName -> String)
-> ShowS -> Either ModuleName String -> String
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ModuleName -> String
forall a. Pretty a => a -> String
prettyShow ShowS
forall a. a -> a
id Either ModuleName String
t String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
". The whole "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ ComponentName -> String
showComponentName ComponentName
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" will be processed. (Support for "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"module and file targets has not been implemented yet.)"
[TargetInfo]
enabled' <- [(ComponentName, Maybe (Either ModuleName String))]
-> ((ComponentName, Maybe (Either ModuleName String))
-> IO TargetInfo)
-> IO [TargetInfo]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [(ComponentName, Maybe (Either ModuleName String))]
enabled (((ComponentName, Maybe (Either ModuleName String))
-> IO TargetInfo)
-> IO [TargetInfo])
-> ((ComponentName, Maybe (Either ModuleName String))
-> IO TargetInfo)
-> IO [TargetInfo]
forall a b. (a -> b) -> a -> b
$ \(ComponentName
cname, Maybe (Either ModuleName String)
_) -> do
case PackageDescription
-> LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets' PackageDescription
pkg_descr LocalBuildInfo
lbi ComponentName
cname of
[] -> String -> IO TargetInfo
forall a. HasCallStack => String -> a
error String
"checkBuildTargets: nothing enabled"
[TargetInfo
target] -> TargetInfo -> IO TargetInfo
forall (m :: * -> *) a. Monad m => a -> m a
return TargetInfo
target
[TargetInfo]
_targets -> String -> IO TargetInfo
forall a. HasCallStack => String -> a
error String
"checkBuildTargets: multiple copies enabled"
[TargetInfo] -> IO [TargetInfo]
forall (m :: * -> *) a. Monad m => a -> m a
return [TargetInfo]
enabled'
where
swizzleTarget :: BuildTarget -> (ComponentName, Maybe (Either ModuleName String))
swizzleTarget (BuildTargetComponent ComponentName
c) = (ComponentName
c, Maybe (Either ModuleName String)
forall a. Maybe a
Nothing)
swizzleTarget (BuildTargetModule ComponentName
c ModuleName
m) = (ComponentName
c, Either ModuleName String -> Maybe (Either ModuleName String)
forall a. a -> Maybe a
Just (ModuleName -> Either ModuleName String
forall a b. a -> Either a b
Left ModuleName
m))
swizzleTarget (BuildTargetFile ComponentName
c String
f) = (ComponentName
c, Either ModuleName String -> Maybe (Either ModuleName String)
forall a. a -> Maybe a
Just (String -> Either ModuleName String
forall a b. b -> Either a b
Right String
f))
formatReason :: String -> ComponentDisabledReason -> String
formatReason String
cn ComponentDisabledReason
DisabledComponent =
String
"Cannot process the " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
cn String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" because the component is marked "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"as disabled in the .cabal file."
formatReason String
cn ComponentDisabledReason
DisabledAllTests =
String
"Cannot process the " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
cn String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" because test suites are not "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"enabled. Run configure with the flag --enable-tests"
formatReason String
cn ComponentDisabledReason
DisabledAllBenchmarks =
String
"Cannot process the " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
cn String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" because benchmarks are not "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"enabled. Re-run configure with the flag --enable-benchmarks"
formatReason String
cn (DisabledAllButOne String
cn') =
String
"Cannot process the " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
cn String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" because this package was "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"configured only to build " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
cn' String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
". Re-run configure "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"with the argument " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
cn