@@ -35,12 +35,14 @@ import Data.Bifunctor
3535import qualified Data.ByteString.Base16 as B16
3636import qualified Data.ByteString.Char8 as B
3737import Data.Default
38+ import Data.Char (isLower )
3839import Data.Either.Extra
3940import Data.Function
4041import Data.Hashable
4142import qualified Data.HashMap.Strict as HM
4243import Data.IORef
4344import Data.List
45+ import Data.List.Extra (dropPrefix , split )
4446import qualified Data.Map.Strict as Map
4547import Data.Maybe
4648import Data.Proxy
@@ -68,6 +70,7 @@ import Development.IDE.Types.Location
6870import Development.IDE.Types.Options
6971import GHC.Check
7072import qualified HIE.Bios as HieBios
73+ import qualified HIE.Bios.Cradle as HieBios
7174import HIE.Bios.Environment hiding (getCacheDir )
7275import HIE.Bios.Types hiding (Log )
7376import qualified HIE.Bios.Types as HieBios
@@ -681,7 +684,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
681684 Left err -> do
682685 dep_info <- getDependencyInfo (maybeToList hieYaml)
683686 let ncfp = toNormalizedFilePath' cfp
684- let res = (map (renderCradleError ncfp) err, Nothing )
687+ let res = (map (renderCradleError cradle ncfp) err, Nothing )
685688 void $ modifyVar' fileToFlags $
686689 Map. insertWith HM. union hieYaml (HM. singleton ncfp (res, dep_info))
687690 void $ modifyVar' filesMap $ HM. insert ncfp hieYaml
@@ -924,9 +927,80 @@ setCacheDirs recorder CacheDirs{..} dflags = do
924927 & maybe id setODir oCacheDir
925928
926929
927- renderCradleError :: NormalizedFilePath -> CradleError -> FileDiagnostic
928- renderCradleError nfp (CradleError _ _ec t) =
929- ideErrorWithSource (Just " cradle" ) (Just DiagnosticSeverity_Error ) nfp (T. unlines (map T. pack t))
930+ renderCradleError :: Cradle a -> NormalizedFilePath -> CradleError -> FileDiagnostic
931+ renderCradleError cradle nfp (CradleError _ _ec ms) =
932+ ideErrorWithSource (Just " cradle" ) (Just DiagnosticSeverity_Error ) nfp $ T. unlines $ map T. pack userFriendlyMessage
933+ where
934+
935+ userFriendlyMessage :: [String ]
936+ userFriendlyMessage
937+ | HieBios. isCabalCradle cradle = fromMaybe ms fileMissingMessage
938+ | otherwise = ms
939+
940+ fileMissingMessage :: Maybe [String ]
941+ fileMissingMessage =
942+ multiCradleErrMessage <$> parseMultiCradleErr ms
943+
944+ -- | Information included in Multi Cradle error messages
945+ data MultiCradleErr = MultiCradleErr
946+ { mcPwd :: FilePath
947+ , mcFilePath :: FilePath
948+ , mcPrefixes :: [(FilePath , String )]
949+ } deriving (Show )
950+
951+ -- | Attempt to parse a multi-cradle message
952+ parseMultiCradleErr :: [String ] -> Maybe MultiCradleErr
953+ parseMultiCradleErr ms = do
954+ _ <- lineAfter " Multi Cradle: "
955+ wd <- lineAfter " pwd: "
956+ fp <- lineAfter " filepath: "
957+ ps <- prefixes
958+ pure $ MultiCradleErr wd fp ps
959+
960+ where
961+ lineAfter :: String -> Maybe String
962+ lineAfter pre = listToMaybe $ mapMaybe (stripPrefix pre) ms
963+
964+ prefixes :: Maybe [(FilePath , String )]
965+ prefixes = do
966+ pure $ mapMaybe tuple ms
967+
968+ tuple :: String -> Maybe (String , String )
969+ tuple line = do
970+ line' <- surround ' (' line ' )'
971+ [f, s] <- pure $ split (== ' ,' ) line'
972+ pure (f, s)
973+
974+ -- extracts the string surrounded by required characters
975+ surround :: Char -> String -> Char -> Maybe String
976+ surround start s end = do
977+ guard (listToMaybe s == Just start)
978+ guard (listToMaybe (reverse s) == Just end)
979+ pure $ drop 1 $ take (length s - 1 ) s
980+
981+
982+
983+
984+
985+
986+ multiCradleErrMessage :: MultiCradleErr -> [String ]
987+ multiCradleErrMessage e =
988+ [ " Loading the module '" <> moduleFileName <> " ' failed. It seems that it is not listed in your .cabal file!"
989+ , " Perhaps you need to add `" <> moduleName <> " ` to other-modules or exposed-modules" -- named 'example' in example.cabal."
990+ , " For more information, visit: https://cabal.readthedocs.io/en/3.4/developing-packages.html#modules-included-in-the-package"
991+ , " "
992+ ] <> map prefix (mcPrefixes e)
993+ where
994+ localFilePath f = dropWhile (== pathSeparator) $ dropPrefix (mcPwd e) f
995+ moduleFileName = localFilePath $ mcFilePath e
996+ moduleName = intercalate " ." $ map dropExtension $ dropWhile isSourceFolder $ splitDirectories moduleFileName
997+ isSourceFolder p = all isLower $ take 1 p
998+ prefix (f, r) = f <> " - " <> r
999+
1000+
1001+
1002+
1003+
9301004
9311005-- See Note [Multi Cradle Dependency Info]
9321006type DependencyInfo = Map. Map FilePath (Maybe UTCTime )
0 commit comments