imp 1.0.0.0 → 1.0.0.1
raw patch · 4 files changed
+80/−5 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Imp.Extra.SrcSpanAnnN: leftmostSmallest :: SrcSpanAnnN -> SrcSpanAnnN -> SrcSpanAnnN
- Imp: updateImports :: Map ModuleName ModuleName -> Set ModuleName -> [LImportDecl GhcPs] -> [LImportDecl GhcPs]
+ Imp: updateImports :: Map ModuleName ModuleName -> Map ModuleName SrcSpanAnnN -> [LImportDecl GhcPs] -> [LImportDecl GhcPs]
Files
- README.md +56/−0
- imp.cabal +2/−1
- source/library/Imp.hs +11/−4
- source/library/Imp/Extra/SrcSpanAnnN.hs +11/−0
README.md view
@@ -11,6 +11,11 @@ [1]: https://downloads.haskell.org/ghc/9.8.2/docs/users_guide/ghci.html#qualified-names +This is similar to [qualified-imports-plugin][2], but it works differently+behind the scenes and supports newer versions of GHC.++[2]: https://github.com/utdemir/qualified-imports-plugin+ ## Basic Usage To use Imp, add it to your package's `build-depends`, like this:@@ -69,6 +74,57 @@ ``` Later aliases will override earlier ones.++## Recommended Usage++Combining the previous sections, the recommended usage of Imp is to enable it+in your package description (`*.cabal` file) along with any aliases that you+want in your project. For example:++``` cabal+library+ build-depends: imp ^>= 1.0.0.0+ ghc-options:+ -fplugin=Imp+ -fplugin-opt=Imp:--alias=Data.Map.Strict:Map+ -fplugin-opt=Imp:--alias=Data.Sequence:Seq+ -fplugin-opt=Imp:--alias=Data.Set:Set+ -- and so on ...+```++## Limitations++Due to limitations in how GHC plugins work, Imp cannot be used to automatically+import modules from the same compilation unit. In typical usage this means that+you cannot import modules from the same package. For example, this will not+work:++``` hs+-- A.hs+module A where+aThing = ()++-- B.hs+{-# OPTIONS_GHC -fplugin=Imp #-}+module B where+bThing = A.aThing+```++If you attempt to compile those modules in a single package, you'll get an+error like this:++```+B.hs:1:1: error: [GHC-58427]+ attempting to use module ‘example-0:A’ (A.hs) which is not loaded+ |+1 | module B where+ | ^+```++The only workarounds are to either import the module manually or move the+modules into separate packages. See [issue 11][] for details.++[issue 11]: https://github.com/tfausak/imp/issues/11 ## Notes
imp.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: imp-version: 1.0.0.0+version: 1.0.0.1 synopsis: A GHC plugin for automatically importing modules. description: Imp is a GHC plugin for automatically importing modules. category: Plugin@@ -67,6 +67,7 @@ Imp.Extra.ModuleName Imp.Extra.ParsedResult Imp.Extra.ReadP+ Imp.Extra.SrcSpanAnnN Imp.Ghc Imp.Type.Alias Imp.Type.Config
source/library/Imp.hs view
@@ -5,6 +5,7 @@ import qualified Control.Monad.Catch as Exception import qualified Data.Data as Data import qualified Data.Map as Map+import qualified Data.Maybe as Maybe import qualified Data.Set as Set import qualified GHC.Hs as Hs import qualified GHC.Plugins as Plugin@@ -15,6 +16,7 @@ import qualified Imp.Extra.HsParsedModule as HsParsedModule import qualified Imp.Extra.ImportDecl as ImportDecl import qualified Imp.Extra.ParsedResult as ParsedResult+import qualified Imp.Extra.SrcSpanAnnN as SrcSpanAnnN import qualified Imp.Ghc as Ghc import qualified Imp.Type.Config as Config import qualified Imp.Type.Context as Context@@ -61,7 +63,12 @@ context <- Context.fromConfig config let aliases = Context.aliases context moduleNames =- Set.fromList @Plugin.ModuleName+ Map.fromListWith SrcSpanAnnN.leftmostSmallest+ . Maybe.mapMaybe+ ( \lRdrName -> case Plugin.unLoc lRdrName of+ Plugin.Qual moduleName _ -> Just (moduleName, Plugin.getLoc lRdrName)+ _ -> Nothing+ ) . biplate . Hs.hsmodDecls $ Plugin.unLoc lHsModule@@ -72,13 +79,13 @@ updateImports :: Map.Map Plugin.ModuleName Plugin.ModuleName ->- Set.Set Plugin.ModuleName ->+ Map.Map Plugin.ModuleName Hs.SrcSpanAnnN -> [Hs.LImportDecl Hs.GhcPs] -> [Hs.LImportDecl Hs.GhcPs] updateImports aliases want imports = let have = Set.fromList $ fmap (ImportDecl.toModuleName . Plugin.unLoc) imports- need = Set.toList $ Set.difference want have- in imports <> fmap (Hs.noLocA . createImport aliases) need+ need = Map.toList $ Map.withoutKeys want have+ in imports <> fmap (\(m, l) -> Plugin.L (Hs.na2la l) $ createImport aliases m) need createImport :: Map.Map Plugin.ModuleName Plugin.ModuleName ->
+ source/library/Imp/Extra/SrcSpanAnnN.hs view
@@ -0,0 +1,11 @@+module Imp.Extra.SrcSpanAnnN where++import qualified Data.Function as Function+import qualified GHC.Hs as Hs+import qualified GHC.Plugins as Plugin++leftmostSmallest :: Hs.SrcSpanAnnN -> Hs.SrcSpanAnnN -> Hs.SrcSpanAnnN+leftmostSmallest x y = case Function.on Plugin.leftmost_smallest Hs.locA x y of+ LT -> x+ EQ -> x+ GT -> y