@@ -35,12 +35,14 @@ import Data.Bifunctor
35
35
import qualified Data.ByteString.Base16 as B16
36
36
import qualified Data.ByteString.Char8 as B
37
37
import Data.Default
38
+ import Data.Char (isLower )
38
39
import Data.Either.Extra
39
40
import Data.Function
40
41
import Data.Hashable
41
42
import qualified Data.HashMap.Strict as HM
42
43
import Data.IORef
43
44
import Data.List
45
+ import Data.List.Extra (dropPrefix , split )
44
46
import qualified Data.Map.Strict as Map
45
47
import Data.Maybe
46
48
import Data.Proxy
@@ -68,6 +70,7 @@ import Development.IDE.Types.Location
68
70
import Development.IDE.Types.Options
69
71
import GHC.Check
70
72
import qualified HIE.Bios as HieBios
73
+ import qualified HIE.Bios.Cradle as HieBios
71
74
import HIE.Bios.Environment hiding (getCacheDir )
72
75
import HIE.Bios.Types hiding (Log )
73
76
import qualified HIE.Bios.Types as HieBios
@@ -681,7 +684,7 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do
681
684
Left err -> do
682
685
dep_info <- getDependencyInfo (maybeToList hieYaml)
683
686
let ncfp = toNormalizedFilePath' cfp
684
- let res = (map (renderCradleError ncfp) err, Nothing )
687
+ let res = (map (renderCradleError cradle ncfp) err, Nothing )
685
688
void $ modifyVar' fileToFlags $
686
689
Map. insertWith HM. union hieYaml (HM. singleton ncfp (res, dep_info))
687
690
void $ modifyVar' filesMap $ HM. insert ncfp hieYaml
@@ -924,9 +927,80 @@ setCacheDirs recorder CacheDirs{..} dflags = do
924
927
& maybe id setODir oCacheDir
925
928
926
929
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
+
930
1004
931
1005
-- See Note [Multi Cradle Dependency Info]
932
1006
type DependencyInfo = Map. Map FilePath (Maybe UTCTime )
0 commit comments