@@ -18,6 +18,7 @@ module GHC.Diagnostic (
1818, extractIdentifiers
1919, qualifiedName
2020, analyzeAnnotation
21+ , takeGhcSourceSpan
2122, applyReplace
2223#endif
2324) where
@@ -65,6 +66,7 @@ formatSolutions start = zipWith formatNumbered [start..] >>> reverse >>> \ case
6566 ImportName module_ qualification name -> importStatement module_ qualification [name] <> faint package
6667 where
6768 package = " (" <> Builder. fromText module_. package <> " )"
69+ AddToImportList module_ text _span -> " Add " <> Builder. fromText text <> " to import list of " <> Builder. fromText module_
6870
6971 faint :: Builder -> Builder
7072 faint = Builder. withSGR [SetConsoleIntensity FaintIntensity ]
@@ -98,10 +100,10 @@ annotate getAvailableImports diagnostic = getAvailableImports >>= \ case
98100 ++ maybe [] (analyzeAnnotation availableImports) annotation
99101
100102analyzeHints :: [Text ] -> [Solution ]
101- analyzeHints = concat . mapMaybe analyzeHint
103+ analyzeHints = concatMap analyzeHint
102104
103- analyzeHint :: Text -> Maybe [Solution ]
104- analyzeHint hint = asum [
105+ analyzeHint :: Text -> [Solution ]
106+ analyzeHint hint = (fromMaybe [] $ asum [
105107 prefix " Perhaps you intended to use " <&> takeExtensions
106108
107109 , requiredFor GHC_910 $ prefix " Enable any of the following extensions: " <&>
@@ -110,7 +112,7 @@ analyzeHint hint = asum [
110112 , prefix " Perhaps use `" <&> return . takeIdentifier
111113 , prefix " Perhaps use variable `" <&> return . takeIdentifier
112114 , prefix " Perhaps use one of these:" <&> extractIdentifiers
113- ]
115+ ]) <> maybeToList addToImportList
114116 where
115117 prefix :: Text -> Maybe Text
116118 prefix p = stripPrefix p hint
@@ -133,6 +135,37 @@ analyzeHint hint = asum [
133135 takeIdentifier :: Text -> Solution
134136 takeIdentifier = UseName . T. takeWhile (/= ' \' ' )
135137
138+ addToImportList :: Maybe Solution
139+ addToImportList = case T. splitOn " ' to the import list in the import of `" $ T. unwords $ T. lines $ hint of
140+ [T. takeWhileEnd (/= ' `' ) -> name, T. splitOn " '" -> [module_, r]] -> AddToImportList module_ name <$> do
141+ takeGhcSourceSpan r
142+ _ -> Nothing
143+
144+ takeGhcSourceSpan :: Text -> Maybe Span
145+ takeGhcSourceSpan input = stripPrefix " (at " input <&> T. splitOn " :" >>= \ case
146+ file
147+ : (int -> Just line)
148+ : (T. splitOn " -" . (T. takeWhile (/= ' )' )) -> [int -> Just start, int -> Just end])
149+ : _ ->
150+ Just $ span file (line, start) (line, end)
151+
152+ file
153+ : (T. splitOn " -" -> [foo -> Just start, (takeFoo >>> foo) -> Just end])
154+ : _ ->
155+ Just $ span file start end
156+ _ -> Nothing
157+ where
158+ span :: Text -> (Int , Int ) -> (Int , Int ) -> Span
159+ span file start end = Span (T. unpack file) (uncurry Location start) (uncurry Location end)
160+
161+ int :: Text -> Maybe Int
162+ int = T. unpack >>> readMaybe
163+
164+ foo :: Text -> Maybe (Int , Int )
165+ foo = T. unpack >>> readMaybe
166+
167+ takeFoo t = T. take ((T. length $ T. takeWhile (/= ' )' ) t) + 1 ) t
168+
136169extractIdentifiers :: Text -> [Solution ]
137170extractIdentifiers input = case T. breakOn " `" >>> snd >>> T. breakOn " \' " $ input of
138171 (T. drop 1 -> identifier, rest)
@@ -307,6 +340,7 @@ edits annotated = case annotated.diagnostic.span of
307340 RemoveImport -> removeLines
308341 UseName name -> Replace span name
309342 ImportName module_ qualification name -> AddImport file module_ qualification [name]
343+ AddToImportList _ text loc -> Replace (Span loc. file loc. end loc. end) $ text <> " (..))" -- FIXME this is not correct and would need HIE lookup
310344
311345 file :: FilePath
312346 file = span . file
0 commit comments