{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module HsDev.Tools.AutoFix (
corrections,
CorrectorMatch,
correctors,
match,
findCorrector,
module Data.Text.Region,
module HsDev.Tools.Refact,
module HsDev.Tools.Types
) where
import Control.Applicative
import Control.Lens hiding ((.=), at)
import Data.Maybe (listToMaybe, mapMaybe)
import Data.String (fromString)
import Data.Text (Text)
import Data.Text.Lens (unpacked)
import Data.Text.Region hiding (Region(..), update)
import qualified Data.Text.Region as R
import HsDev.Tools.Refact
import HsDev.Tools.Base
import HsDev.Tools.Types
instance Regioned a => Regioned (Note a) where
regions = note . regions
corrections :: [Note OutputMessage] -> [Note Refact]
corrections = mapMaybe toRefact where
toRefact :: Note OutputMessage -> Maybe (Note Refact)
toRefact n = useSuggestion <|> findCorrector n where
useSuggestion :: Maybe (Note Refact)
useSuggestion = do
sugg <- view (note . messageSuggestion) n
return $ set
note
(Refact
(view (note . message) n)
(replace (fromRegion $ view noteRegion n) sugg))
n
type CorrectorMatch = Note OutputMessage -> Maybe (Note Refact)
correctors :: [CorrectorMatch]
correctors = [
match "^The (?:qualified )?import of .([\\w\\.]+). is redundant" $ \_ rgn -> Refact
"Redundant import"
(cut
(expandLines rgn)),
match "^(.*?)\nFound:\n (.*?)\nWhy not:\n (.*?)$" $ \g rgn -> Refact
(g `at` 1)
(replace
((rgn ^. regionFrom) `regionSize` pt 0 (contentsLength $ g `at` 2))
(g `at` 3))]
match :: String -> ((Int -> Maybe Text) -> R.Region -> Refact) -> CorrectorMatch
match pat f n = do
g <- matchRx pat (view (note . message . unpacked) n)
return $ set note (f (fmap fromString . g) (fromRegion $ view noteRegion n)) n
findCorrector :: Note OutputMessage -> Maybe (Note Refact)
findCorrector n = listToMaybe $ mapMaybe ($ n) correctors