ghc-usage (empty) → 0.1.0.0
raw patch · 5 files changed
+185/−0 lines, 5 filesdep +basedep +containersdep +ghcsetup-changed
Dependencies added: base, containers, ghc, ghc-paths, unix
Files
- GhcUsage.hs +107/−0
- GhcUsageWrapper.hs +15/−0
- LICENSE +28/−0
- Setup.hs +2/−0
- ghc-usage.cabal +33/−0
+ GhcUsage.hs view
@@ -0,0 +1,107 @@+module GhcUsage (frontendPlugin) where++import qualified GHC+import GhcPlugins+import DriverPhases+import GhcMonad+import UniqDFM+import UniqDSet+import Avail+import Outputable++import System.IO+import System.Exit+import Control.Monad+import Data.Maybe+import Data.List+import Data.Map (Map)+import qualified Data.Map as Map++frontendPlugin :: FrontendPlugin+frontendPlugin = defaultFrontendPlugin {+ frontend = usage+ }++usage :: [String] -> [(String, Maybe Phase)] -> Ghc ()+usage _flags args = do+ dflags0 <- getDynFlags+ -- NB: frontend plugin defaults to OneShot+ _ <- GHC.setSessionDynFlags dflags0 { ghcMode = CompManager }+ dflags <- getDynFlags+ let (hs_srcs, non_hs_srcs) = partition isHaskellishTarget args+ targets <- mapM (uncurry GHC.guessTarget) hs_srcs+ GHC.setTargets targets+ ok_flag <- GHC.load GHC.LoadAllTargets+ when (failed ok_flag) (liftIO $ exitWith (ExitFailure 1))+ hsc_env <- GHC.getSession+ let ifaces = map hm_iface+ . eltsHpt+ $ hsc_HPT hsc_env+ usages = Map.unionsWith unionUniqDSets+ . map usageModIface+ $ ifaces+ liftIO . printForUser dflags stdout neverQualify+ . vcat+ . vpunctuate (text "")+ . map (renderHeader usages)+ -- . filter ((==HsigFile) . mi_hsc_src)+ $ ifaces+ return ()++vpunctuate :: SDoc -- ^ The punctuation+ -> [SDoc] -- ^ The list that will have punctuation added between every adjacent pair of elements+ -> [SDoc] -- ^ Punctuated list+vpunctuate _ [] = []+vpunctuate p (d:ds) = go d ds+ where+ go d [] = [d]+ go d (e:es) = (d $$ p) : go e es++usageModIface :: ModIface -> Map ModuleName (UniqDSet OccName)+usageModIface iface = Map.fromList $+ [ (mod_name, mkUniqDSet (map fst occs_w_fp))+ | UsageHomeModule{ usg_mod_name = mod_name+ , usg_entities = occs_w_fp } <- mi_usages iface ]++renderName :: Name -> SDoc+renderName n = let occ = occName n+ in parenSymOcc occ (ppr occ)++renderField :: FieldLabel -> SDoc+renderField f = ftext (flLabel f)++renderAvailInfo :: AvailInfo -> SDoc+renderAvailInfo a+ = renderName n <>+ if null ns && null fs+ then empty+ else parens . fsep . punctuate comma+ $ map renderName (sortOn (occNameFS . occName) ns)+ ++ map renderField (sortOn flLabel fs)+ where+ n = availName a+ ns = filter (n /=) (availNonFldNames a)+ fs = availFlds a++renderHeader :: Map ModuleName (UniqDSet OccName) -> ModIface -> SDoc+renderHeader usages iface+ = header <+> ppr mod_name <+> text "(" $$+ nest 4 pp_exports $$+ text ") where"+ where+ mod_name = moduleName (mi_module iface)+ usage = fromMaybe emptyUniqDSet (Map.lookup mod_name usages)+ header | HsigFile <- mi_hsc_src iface = text "signature"+ | otherwise = text "module"+ pp_exports = vcat+ . punctuate comma+ . map renderAvailInfo+ . sortOn availSortKey+ $ exports+ exports = filterAvails ((`elementOfUniqDSet` usage) . occName)+ $ mi_exports iface++availSortKey :: AvailInfo -> String+availSortKey a+ -- Fortuitously, capital letters sort first.+ = occNameString . occName $ availName a
+ GhcUsageWrapper.hs view
@@ -0,0 +1,15 @@+import GHC.Paths+import System.Posix.Process+import System.Environment++main = do+ args <- getArgs+ let interactive = "--interactive" `elem` args+ args' = do+ arg <- args+ case arg of+ "--interactive" ->+ ["--frontend", "GhcUsage",+ "-plugin-package", "ghc-usage"]+ _ -> return arg+ executeFile ghc False (args' ++ if interactive then ["-user-package-db"] else []) Nothing
+ LICENSE view
@@ -0,0 +1,28 @@+Copyright 2017 Edward Z. Yang++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++1. Redistributions of source code must retain the above copyright+notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright+notice, this list of conditions and the following disclaimer in the+documentation and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its+contributors may be used to endorse or promote products derived from+this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ghc-usage.cabal view
@@ -0,0 +1,33 @@+name: ghc-usage+version: 0.1.0.0+license: BSD3+license-file: LICENSE+author: Edward Z. Yang+maintainer: ezyang@cs.stanford.edu+synopsis: Print minimal export lists+category: Development+bug-reports: https://github.com/ezyang/ghc-usage/issues+description: A frontend plugin for computing the minimal export list+ of a module or signature within a package. This can+ be used in conjunction with Backpack to easily determine+ the true set of identifiers which are required from a+ signature, so that the requirement can be pared down+ to precisely what is required.+build-type: Simple+cabal-version: >=1.10++source-repository head+ type: git+ location: https://github.com/ezyang/ghc-usage++library+ exposed-modules: GhcUsage+ build-depends: base >= 4.10 && < 4.11,+ ghc >= 8.1 && < 8.3,+ containers+ default-language: Haskell2010++executable ghc-usage+ main-is: GhcUsageWrapper.hs+ build-depends: base, ghc-paths, unix+ default-language: Haskell2010