@@ -18,6 +18,7 @@ module GHC.Diagnostic (
1818, extractIdentifiers
1919, qualifiedName
2020, analyzeAnnotation
21+ , takeGhcSourceSpan
2122#endif
2223) where
2324
@@ -66,6 +67,7 @@ formatSolutions start = zipWith formatNumbered [start..] >>> reverse >>> \ case
6667 ImportName module_ qualification name -> importStatement module_ qualification [name] <> faint package
6768 where
6869 package = " (" <> Builder. fromText module_. package. name <> " )"
70+ AddToImportList module_ text _span -> " Add " <> Builder. fromText text <> " to import list of " <> Builder. fromText module_
6971
7072 faint :: Builder -> Builder
7173 faint = Builder. withSGR [SetConsoleIntensity FaintIntensity ]
@@ -96,10 +98,10 @@ annotate getAvailableImports diagnostic = getAvailableImports >>= \ case
9698 ++ maybe [] (analyzeAnnotation availableImports) annotation
9799
98100analyzeHints :: [Text ] -> [Solution ]
99- analyzeHints = concat . mapMaybe analyzeHint
101+ analyzeHints = concatMap analyzeHint
100102
101- analyzeHint :: Text -> Maybe [Solution ]
102- analyzeHint hint = asum [
103+ analyzeHint :: Text -> [Solution ]
104+ analyzeHint hint = (fromMaybe [] $ asum [
103105 prefix " Perhaps you intended to use " <&> takeExtensions
104106
105107 , requiredFor GHC_910 $ prefix " Enable any of the following extensions: " <&>
@@ -108,7 +110,7 @@ analyzeHint hint = asum [
108110 , prefix " Perhaps use `" <&> return . takeIdentifier
109111 , prefix " Perhaps use variable `" <&> return . takeIdentifier
110112 , prefix " Perhaps use one of these:" <&> extractIdentifiers
111- ]
113+ ]) <> maybeToList addToImportList
112114 where
113115 prefix :: Text -> Maybe Text
114116 prefix p = stripPrefix p hint
@@ -131,6 +133,37 @@ analyzeHint hint = asum [
131133 takeIdentifier :: Text -> Solution
132134 takeIdentifier = UseName . T. takeWhile (/= ' \' ' )
133135
136+ addToImportList :: Maybe Solution
137+ addToImportList = case T. splitOn " ' to the import list in the import of `" $ T. unwords $ T. lines $ hint of
138+ [T. takeWhileEnd (/= ' `' ) -> name, T. splitOn " '" -> [module_, r]] -> AddToImportList module_ name <$> do
139+ takeGhcSourceSpan r
140+ _ -> Nothing
141+
142+ takeGhcSourceSpan :: Text -> Maybe Span
143+ takeGhcSourceSpan input = stripPrefix " (at " input <&> T. splitOn " :" >>= \ case
144+ file
145+ : (int -> Just line)
146+ : (T. splitOn " -" . (T. takeWhile (/= ' )' )) -> [int -> Just start, int -> Just end])
147+ : _ ->
148+ Just $ span file (line, start) (line, end)
149+
150+ file
151+ : (T. splitOn " -" -> [foo -> Just start, (takeFoo >>> foo) -> Just end])
152+ : _ ->
153+ Just $ span file start end
154+ _ -> Nothing
155+ where
156+ span :: Text -> (Int , Int ) -> (Int , Int ) -> Span
157+ span file start end = Span (T. unpack file) (uncurry Location start) (uncurry Location end)
158+
159+ int :: Text -> Maybe Int
160+ int = T. unpack >>> readMaybe
161+
162+ foo :: Text -> Maybe (Int , Int )
163+ foo = T. unpack >>> readMaybe
164+
165+ takeFoo t = T. take ((T. length $ T. takeWhile (/= ' )' ) t) + 1 ) t
166+
134167extractIdentifiers :: Text -> [Solution ]
135168extractIdentifiers input = case T. breakOn " `" >>> snd >>> T. breakOn " \' " $ input of
136169 (T. drop 1 -> identifier, rest)
@@ -324,6 +357,7 @@ edits annotated = case annotated.diagnostic.span of
324357 ReplaceImport old new -> ReplaceFirst span old new
325358 UseName name -> Replace span name
326359 ImportName module_ qualification name -> AddImport file module_ qualification [name]
360+ AddToImportList _ text loc -> Replace (Span loc. file loc. end loc. end) $ text <> " (..))" -- FIXME this is not correct and would need HIE lookup
327361
328362 file :: FilePath
329363 file = span . file
0 commit comments