@@ -106,8 +106,8 @@ import GHC (AddEpAnn (Ad
106
106
DeltaPos (.. ),
107
107
EpAnn (.. ),
108
108
EpaLocation (.. ),
109
- hsmodAnn ,
110
- LEpaComment )
109
+ LEpaComment ,
110
+ hsmodAnn )
111
111
#else
112
112
import Language.Haskell.GHC.ExactPrint.Types (Annotation (annsDP ),
113
113
DeltaPos ,
@@ -150,6 +150,7 @@ iePluginDescriptor recorder plId =
150
150
, wrap suggestNewOrExtendImportForClassMethod
151
151
, wrap suggestHideShadow
152
152
, wrap suggestNewImport
153
+ , wrap suggestAddRecordFieldImport
153
154
]
154
155
plId
155
156
in mkExactprintPluginDescriptor recorder $ old {pluginHandlers = pluginHandlers old <> mkPluginHandler STextDocumentCodeAction codeAction }
@@ -1211,6 +1212,25 @@ suggestFixConstructorImport Diagnostic{_range=_range,..}
1211
1212
in [(" Fix import of " <> fixedImport, TextEdit _range fixedImport)]
1212
1213
| otherwise = []
1213
1214
1215
+ suggestAddRecordFieldImport :: ExportsMap -> DynFlags -> Annotated ParsedSource -> T. Text -> Diagnostic -> [(T. Text , CodeActionKind , TextEdit )]
1216
+ suggestAddRecordFieldImport exportsMap df ps fileContents Diagnostic {.. }
1217
+ | Just fieldName <- findMissingField _message
1218
+ , Just (range, indent) <- newImportInsertRange ps fileContents
1219
+ = let qis = qualifiedImportStyle df
1220
+ suggestions = nubSortBy simpleCompareImportSuggestion (constructNewImportSuggestions exportsMap (Nothing , NotInScopeThing fieldName) Nothing qis)
1221
+ in map (\ (ImportSuggestion _ kind (unNewImport -> imp)) -> (imp, kind, TextEdit range (imp <> " \n " <> T. replicate indent " " ))) suggestions
1222
+ | otherwise = []
1223
+ where
1224
+ findMissingField :: T. Text -> Maybe T. Text
1225
+ findMissingField t =
1226
+ let
1227
+ hasfieldRegex = " ((.+\\ .)?HasField) \" (.+)\" ([^ ]+) ([^ ]+)"
1228
+ regex = " (No instance for|Could not deduce):? (\\ (" <> hasfieldRegex <> " \\ )|‘" <> hasfieldRegex <> " ’|" <> hasfieldRegex <> " )"
1229
+ match = filter (/= " " ) <$> matchRegexUnifySpaces t regex
1230
+ in case match of
1231
+ Just [_, _, _, _, fieldName, _, _] -> Just fieldName
1232
+ _ -> Nothing
1233
+
1214
1234
-- | Suggests a constraint for a declaration for which a constraint is missing.
1215
1235
suggestConstraint :: DynFlags -> ParsedSource -> Diagnostic -> [(T. Text , Rewrite )]
1216
1236
suggestConstraint df (makeDeltaAst -> parsedModule) diag@ Diagnostic {.. }
@@ -1608,10 +1628,11 @@ findPositionAfterModuleName ps hsmodName' = do
1608
1628
epaLocationToLine :: EpaLocation -> Maybe Int
1609
1629
#if MIN_VERSION_ghc(9,5,0)
1610
1630
epaLocationToLine (EpaSpan sp _)
1631
+ = Just . srcLocLine . realSrcSpanEnd $ sp
1611
1632
#else
1612
1633
epaLocationToLine (EpaSpan sp)
1613
- #endif
1614
1634
= Just . srcLocLine . realSrcSpanEnd $ sp
1635
+ #endif
1615
1636
epaLocationToLine (EpaDelta (SameLine _) priorComments) = Just $ sumCommentsOffset priorComments
1616
1637
-- 'priorComments' contains the comments right before the current EpaLocation
1617
1638
-- Summing line offset of priorComments is necessary, as 'line' is the gap between the last comment and
@@ -1852,16 +1873,21 @@ textInRange (Range (Position (fromIntegral -> startRow) (fromIntegral -> startCo
1852
1873
1853
1874
-- | Returns the ranges for a binding in an import declaration
1854
1875
rangesForBindingImport :: ImportDecl GhcPs -> String -> [Range ]
1855
- rangesForBindingImport ImportDecl {
1856
1876
#if MIN_VERSION_ghc(9,5,0)
1877
+ rangesForBindingImport ImportDecl {
1857
1878
ideclImportList = Just (Exactly , L _ lies)
1879
+ } b =
1880
+ concatMap (mapMaybe srcSpanToRange . rangesForBinding' b') lies
1881
+ where
1882
+ b' = wrapOperatorInParens b
1858
1883
#else
1884
+ rangesForBindingImport ImportDecl {
1859
1885
ideclHiding = Just (False , L _ lies)
1860
- #endif
1861
1886
} b =
1862
1887
concatMap (mapMaybe srcSpanToRange . rangesForBinding' b') lies
1863
1888
where
1864
1889
b' = wrapOperatorInParens b
1890
+ #endif
1865
1891
rangesForBindingImport _ _ = []
1866
1892
1867
1893
wrapOperatorInParens :: String -> String
0 commit comments