Finds (badly) unused imports based on Agda HTML output
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

67 lines
2.1 KiB

#!/usr/bin/env stack
{- stack --resolver lts-18.14 script
--package text
--package unordered-containers
--package tagsoup
--package filepath
--package hashable
-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import qualified Data.Text.Lazy.IO as Text
import qualified Data.HashSet as HashSet
import qualified Data.Text.Lazy as Text
import Data.HashSet (HashSet)
import Data.Text.Lazy (Text)
import Data.Hashable
import System.Environment
import Text.HTML.TagSoup
import Data.Function
import Data.Int
import Data.Foldable
import System.FilePath
import Control.Monad
main :: IO ()
main = do
args <- getArgs
for_ args $ \mod -> do
contents <- Text.readFile mod
let unused = findUnusedImports mempty (parseTags contents)
unless (null unused) $ do
putStrLn $ "Potentially unused imports for: \x1b[1m" <> dropExtension (takeFileName mod) <> "\x1b[0m"
Text.putStrLn $ " * " <> Text.intercalate ", " (toList unused)
findUnusedImports :: HashSet Text -> [Tag Text] -> HashSet Text
findUnusedImports unused (TagOpen "pre" attrs:ts)
| Just "Agda" <- lookup "class" attrs
= goAgda 0 unused ts
findUnusedImports unused (_:ts) = findUnusedImports unused ts
findUnusedImports unused [] = unused
goAgda :: Int64 -> HashSet Text -> [Tag Text] -> HashSet Text
goAgda line unused (TagOpen "a" attrs:TagText text:TagClose "a":ts)
| Just "Module" <- lookup "class" attrs
, Just href <- lookup "href" attrs
, ".html" `Text.isSuffixOf` href
= let
imp = Text.take (Text.length href - 5) href
in goAgda line (HashSet.insert imp unused) ts
| Just href <- lookup "href" attrs
, let (mod, ident) = Text.break (== '#') href
, not (Text.null mod), not (Text.null (Text.drop 1 ident))
= let
imp = Text.take (Text.length mod - 5) mod
in goAgda line (HashSet.delete imp unused) ts
goAgda line unused (TagClose "pre":ts) = findUnusedImports unused ts
goAgda line unused (TagText text:ts)
| newlines <- Text.filter (== '\n') text = goAgda (line + Text.length newlines) unused ts
goAgda line unused (t:ts) = goAgda line unused ts
goAgda line unused [] = error "Unclosed <pre class=Agda> tag"