@@ -19,7 +19,6 @@ module Development.IDE.Plugin.CodeAction
1919
2020import Control.Applicative ((<|>) )
2121import Control.Arrow (second ,
22- (&&&) ,
2322 (>>>) )
2423import Control.Concurrent.STM.Stats (atomically )
2524import Control.Monad.Extra
@@ -37,7 +36,6 @@ import Data.List.NonEmpty (NonEmpty ((:
3736import qualified Data.List.NonEmpty as NE
3837import qualified Data.Map.Strict as M
3938import Data.Maybe
40- import Data.Ord (comparing )
4139import qualified Data.Set as S
4240import qualified Data.Text as T
4341import qualified Data.Text.Encoding as T
@@ -151,9 +149,8 @@ codeAction state _ (CodeActionParams _ _ (TextDocumentIdentifier uri) range _) =
151149iePluginDescriptor :: Recorder (WithPriority E. Log ) -> PluginId -> PluginDescriptor IdeState
152150iePluginDescriptor recorder plId =
153151 let old =
154- mkGhcideCAsPlugin [
155- wrap suggestExportUnusedTopBinding
156- , wrap suggestModuleTypo
152+ mkGhcideCAsPlugin
153+ [ wrap suggestModuleTypo
157154 , wrap suggestFixConstructorImport
158155 , wrap suggestExtendImport
159156 , wrap suggestImportDisambiguation
@@ -710,100 +707,9 @@ suggestDeleteUnusedBinding
710707 isSameName :: IdP GhcPs -> String -> Bool
711708 isSameName x name = T. unpack (printOutputable x) == name
712709
713- data ExportsAs = ExportName | ExportPattern | ExportFamily | ExportAll
714- deriving (Eq )
715-
716710getLocatedRange :: HasSrcSpan a => a -> Maybe Range
717711getLocatedRange = srcSpanToRange . getLoc
718712
719- suggestExportUnusedTopBinding :: Maybe T. Text -> ParsedModule -> Diagnostic -> Maybe (T. Text , TextEdit )
720- suggestExportUnusedTopBinding srcOpt ParsedModule {pm_parsed_source = L _ HsModule {.. }} Diagnostic {.. }
721- -- Foo.hs:4:1: warning: [-Wunused-top-binds] Defined but not used: ‘f’
722- -- Foo.hs:5:1: warning: [-Wunused-top-binds] Defined but not used: type constructor or class ‘F’
723- -- Foo.hs:6:1: warning: [-Wunused-top-binds] Defined but not used: data constructor ‘Bar’
724- | Just source <- srcOpt
725- , Just [_, name] <-
726- matchRegexUnifySpaces
727- _message
728- " .*Defined but not used: (type constructor or class |data constructor )?‘([^ ]+)’"
729- , Just (exportType, _) <-
730- find (matchWithDiagnostic _range . snd )
731- . mapMaybe (\ (L l b) -> if isTopLevel (locA l) then exportsAs b else Nothing )
732- $ hsmodDecls
733- , Just exports <- fmap (fmap reLoc) . reLoc <$> hsmodExports
734- , Just exportsEndPos <- _end <$> getLocatedRange exports
735- , let name' = printExport exportType name
736- sep = exportSep source $ map getLocatedRange <$> exports
737- exportName = case sep of
738- Nothing -> (if needsComma source exports then " , " else " " ) <> name'
739- Just s -> s <> name'
740- exportsEndPos' = exportsEndPos { _character = pred $ _character exportsEndPos }
741- insertPos = fromMaybe exportsEndPos' $ case (sep, unLoc exports) of
742- (Just _, exports'@ (_: _)) -> fmap _end . getLocatedRange $ last exports'
743- _ -> Nothing
744- = Just (" Export ‘" <> name <> " ’" , TextEdit (Range insertPos insertPos) exportName)
745- | otherwise = Nothing
746- where
747- exportSep :: T. Text -> Located [Maybe Range ] -> Maybe T. Text
748- exportSep src (L (RealSrcSpan _ _) xs@ (_ : tl@ (_ : _))) =
749- case mapMaybe (\ (e, s) -> (,) <$> e <*> s) $ zip (fmap _end <$> xs) (fmap _start <$> tl) of
750- [] -> Nothing
751- bounds -> Just smallestSep
752- where
753- smallestSep
754- = snd
755- $ minimumBy (comparing fst )
756- $ map (T. length &&& id )
757- $ nubOrd
758- $ map (\ (prevEnd, nextStart) -> textInRange (Range prevEnd nextStart) src) bounds
759- exportSep _ _ = Nothing
760-
761- -- We get the last export and the closing bracket and check for comma in that range.
762- needsComma :: T. Text -> Located [Located (IE GhcPs )] -> Bool
763- needsComma _ (L _ [] ) = False
764- needsComma source (L (RealSrcSpan l _) exports) =
765- let closeParen = _end $ realSrcSpanToRange l
766- lastExport = fmap _end . getLocatedRange $ last exports
767- in
768- case lastExport of
769- Just lastExport ->
770- not $ T. any (== ' ,' ) $ textInRange (Range lastExport closeParen) source
771- _ -> False
772- needsComma _ _ = False
773-
774- opLetter :: T. Text
775- opLetter = " :!#$%&*+./<=>?@\\ ^|-~"
776-
777- parenthesizeIfNeeds :: Bool -> T. Text -> T. Text
778- parenthesizeIfNeeds needsTypeKeyword x
779- | T. any (c == ) opLetter = (if needsTypeKeyword then " type " else " " ) <> " (" <> x <> " )"
780- | otherwise = x
781- where
782- c = T. head x
783-
784- matchWithDiagnostic :: Range -> Located (IdP GhcPs ) -> Bool
785- matchWithDiagnostic Range {_start= l,_end= r} x =
786- let loc = fmap _start . getLocatedRange $ x
787- in loc >= Just l && loc <= Just r
788-
789- printExport :: ExportsAs -> T. Text -> T. Text
790- printExport ExportName x = parenthesizeIfNeeds False x
791- printExport ExportPattern x = " pattern " <> parenthesizeIfNeeds False x
792- printExport ExportFamily x = parenthesizeIfNeeds True x
793- printExport ExportAll x = parenthesizeIfNeeds True x <> " (..)"
794-
795- isTopLevel :: SrcSpan -> Bool
796- isTopLevel span = fmap (_character . _start) (srcSpanToRange span ) == Just 0
797-
798- exportsAs :: HsDecl GhcPs -> Maybe (ExportsAs , Located (IdP GhcPs ))
799- exportsAs (ValD _ FunBind {fun_id}) = Just (ExportName , reLoc fun_id)
800- exportsAs (ValD _ (PatSynBind _ PSB {psb_id})) = Just (ExportPattern , reLoc psb_id)
801- exportsAs (TyClD _ SynDecl {tcdLName}) = Just (ExportName , reLoc tcdLName)
802- exportsAs (TyClD _ DataDecl {tcdLName}) = Just (ExportAll , reLoc tcdLName)
803- exportsAs (TyClD _ ClassDecl {tcdLName}) = Just (ExportAll , reLoc tcdLName)
804- exportsAs (TyClD _ FamDecl {tcdFam}) = Just (ExportFamily , reLoc $ fdLName tcdFam)
805- exportsAs _ = Nothing
806-
807713suggestAddTypeAnnotationToSatisfyConstraints :: Maybe T. Text -> Diagnostic -> [(T. Text , [TextEdit ])]
808714suggestAddTypeAnnotationToSatisfyConstraints sourceOpt Diagnostic {_range= _range,.. }
809715-- File.hs:52:41: warning:
0 commit comments