imp 0.2024.3.20.1 → 0.2024.3.21
raw patch · 5 files changed
+91/−20 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- README.md +78/−3
- imp.cabal +5/−9
- source/ghc-9.4/Imp/Ghc.hs +1/−1
- source/ghc-9.6/Imp/Ghc.hs +1/−1
- source/test-suite/Main.hs +6/−6
README.md view
@@ -1,5 +1,80 @@ # Imp -Imp is a GHC plugin that automatically imports modules when they are used, like-GHCi does. This allows writing code using qualified identifiers without-manually importing the modules.+[](https://github.com/tfausak/imp/actions/workflows/workflow.yaml)+[](https://hackage.haskell.org/package/imp)+[](https://www.stackage.org/package/imp)++Imp is a GHC plugin for automatically importing modules. This behavior is+similar to the [`-fimplicit-import-qualified`][1] flag for GHCi. In short, Imp+allows you to use fully-qualified identifiers without explicitly importing any+modules.++[1]: https://downloads.haskell.org/ghc/9.8.2/docs/users_guide/ghci.html#qualified-names++## Basic Usage++To use Imp, add it to your package's `build-depends`, like this:++``` cabal+library+ build-depends: imp+```++Then you can enable it with the `-fplugin=Imp` flag for GHC, like this:++``` hs+{-# OPTIONS_GHC -fplugin=Imp #-}+main = System.IO.print ()+```++For the above module, Imp will automatically import `System.IO` for you. It's+as though you wrote this instead:++``` hs+import qualified System.IO+main = System.IO.print ()+```++## Enabling Everywhere++More often than not, you'll probably want to enable Imp for an entire component+rather than for a single module. To do that, add it to your package's+`ghc-options`, like this:++``` cabal+library+ ghc-options: -fplugin=Imp+```++Then you don't need to use the `OPTIONS_GHC` pragma to enable Imp.++## Aliasing Modules++Sometimes you may want to refer to modules by an alias. For example you may+prefer using `System.IO` as simply `IO`. Imp supports this with the+`--alias=SOURCE:TARGET` option. Here's an example:++``` hs+{-# OPTIONS_GHC+ -fplugin=Imp+ -fplugin-opt=Imp:--alias=System.IO:IO #-}+main = IO.print ()+```++That is the same as writing this:++``` hs+import qualified System.IO as IO+main = IO.print ()+```++Later aliases will override earlier ones.++## Notes++Imp operates purely syntactically. It doesn't know anything about the+identifiers that you use. So if you refer to something that doesn't exist, like+`System.IO.undefined`, you'll get an error from GHC.++Imp will never insert an import for a module that you've explicitly imported.+It will only insert an import when the module is not in scope already.
imp.cabal view
@@ -1,12 +1,8 @@ cabal-version: 2.2 name: imp-version: 0.2024.3.20.1-synopsis: Automatically import modules.-description:- Imp is a GHC plugin that automatically imports modules when they are used,- like GHCi does. This allows writing code using qualified identifiers without- manually importing the modules.-+version: 0.2024.3.21+synopsis: A GHC plugin for automatically importing modules.+description: Imp is a GHC plugin for automatically importing modules. category: Plugin maintainer: Taylor Fausak license: MIT@@ -54,8 +50,7 @@ exceptions ^>=0.10.5, ghc ^>=9.4.1 || ^>=9.6.1 || ^>=9.8.1, - exposed-modules: Imp.Ghc- -- cabal-gild: discover source/library+ -- cabal-gild: discover source/ghc-9.4 source/ghc-9.6 source/library exposed-modules: Imp Imp.Exception.InvalidAlias@@ -72,6 +67,7 @@ Imp.Extra.ModuleName Imp.Extra.ParsedResult Imp.Extra.ReadP+ Imp.Ghc Imp.Type.Alias Imp.Type.Config Imp.Type.Context
source/ghc-9.4/Imp/Ghc.hs view
@@ -13,7 +13,7 @@ Hs.ImportDecl { Hs.ideclExt = Hs.noAnn, Hs.ideclSourceSrc = SourceText.NoSourceText,- Hs.ideclImplicit = False,+ Hs.ideclImplicit = True, Hs.ideclName = Hs.noLocA moduleName, Hs.ideclPkgQual = Plugin.NoRawPkgQual, Hs.ideclSource = Plugin.NotBoot,
source/ghc-9.6/Imp/Ghc.hs view
@@ -15,7 +15,7 @@ Hs.XImportDeclPass { Hs.ideclAnn = Hs.noAnn, Hs.ideclSourceText = SourceText.NoSourceText,- Hs.ideclImplicit = False+ Hs.ideclImplicit = True }, Hs.ideclName = Hs.noLocA moduleName, Hs.ideclPkgQual = Plugin.NoRawPkgQual,
source/test-suite/Main.hs view
@@ -32,31 +32,31 @@ expectImp [] "true = Data.Bool.True"- "import qualified Data.Bool\ntrue = Data.Bool.True"+ "import (implicit) qualified Data.Bool\ntrue = Data.Bool.True" Hspec.it "inserts an aliased import" $ do expectImp ["--alias=Data.Bool:Bool"] "true = Bool.True"- "import qualified Data.Bool as Bool\ntrue = Bool.True"+ "import (implicit) qualified Data.Bool as Bool\ntrue = Bool.True" Hspec.it "prefers later aliases over earlier ones" $ do expectImp ["--alias=Relude.Bool:Bool", "--alias=Data.Bool:Bool"] "true = Bool.True"- "import qualified Data.Bool as Bool\ntrue = Bool.True"+ "import (implicit) qualified Data.Bool as Bool\ntrue = Bool.True" Hspec.it "inserts an import for a qualified type" $ do expectImp [] "true = True :: Data.Bool.Bool"- "import qualified Data.Bool\ntrue = True :: Data.Bool.Bool"+ "import (implicit) qualified Data.Bool\ntrue = True :: Data.Bool.Bool" Hspec.it "inserts multiple imports sorted" $ do expectImp [] "true :: Relude.Bool.Bool\ntrue = Data.Bool.True"- "import qualified Data.Bool\nimport qualified Relude.Bool\ntrue :: Relude.Bool.Bool\ntrue = Data.Bool.True"+ "import (implicit) qualified Data.Bool\nimport (implicit) qualified Relude.Bool\ntrue :: Relude.Bool.Bool\ntrue = Data.Bool.True" Hspec.it "does not re-import an open import" $ do expectImp@@ -80,7 +80,7 @@ expectImp [] "import qualified Relude.Bool\ntrue :: Relude.Bool.Bool\ntrue = Data.Bool.True"- "import qualified Relude.Bool\nimport qualified Data.Bool\ntrue :: Relude.Bool.Bool\ntrue = Data.Bool.True"+ "import qualified Relude.Bool\nimport (implicit) qualified Data.Bool\ntrue :: Relude.Bool.Bool\ntrue = Data.Bool.True" expectImp :: (Stack.HasCallStack) => [String] -> String -> String -> Hspec.Expectation expectImp arguments input expected = do