smuggler2 0.3.4.2 → 0.3.5.1
raw patch · 144 files changed
+1479/−751 lines, 144 filesdep +splitdep ~ghcPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: split
Dependency ranges changed: ghc
API changes (from Hackage documentation)
- Smuggler2.Options: instance GHC.Show.Show Smuggler2.Options.Options
+ Smuggler2.Options: [leaveOpenImports] :: Options -> [ModuleName]
+ Smuggler2.Options: [makeOpenImports] :: Options -> [ModuleName]
+ Smuggler2.Options: instance Outputable.Outputable Smuggler2.Options.Options
- Smuggler2.Options: Options :: ImportAction -> ExportAction -> Maybe String -> Options
+ Smuggler2.Options: Options :: ImportAction -> ExportAction -> Maybe String -> [ModuleName] -> [ModuleName] -> Options
Files
- CHANGELOG.md +4/−0
- Makefile +10/−3
- README.md +55/−30
- TODO.md +3/−1
- app/Main.hs +13/−11
- smuggler2.cabal +7/−4
- src/Smuggler2/Options.hs +29/−8
- src/Smuggler2/Plugin.hs +143/−79
- test/Test.hs +37/−17
- test/tests/Bare.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/Bare.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/Bare.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/Bare.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/BareHello.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/BareHello.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +5/−0
- test/tests/BareHello.MinimiseImportsReplaceExports-golden +3/−0
- test/tests/BareHello.NoImportProcessingAddExplicitExports-golden +3/−0
- test/tests/BareHello.NoImportProcessingReplaceExports-golden +3/−0
- test/tests/BareHello.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/BareHello.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/BareHello.hs +2/−0
- test/tests/BoolBoolUnused.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/BoolBoolUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +1/−0
- test/tests/BoolBoolUnused.PreserveInstanceImportsNoExportProcessing-golden +0/−3
- test/tests/BoolBoolUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden +3/−0
- test/tests/BoolBoolUsed.MinimiseImportsNoExportProcessing-golden +0/−5
- test/tests/BoolBoolUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +5/−0
- test/tests/BoolBoolUsed.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/BoolBoolUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/BoolPartlyUsedFirst.MinimiseImportsNoExportProcessing-golden +0/−5
- test/tests/BoolPartlyUsedFirst.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +5/−0
- test/tests/BoolPartlyUsedFirst.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/BoolPartlyUsedFirst.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/BoolPartlyUsedLast.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/BoolPartlyUsedLast.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/BoolPartlyUsedLast.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/BoolPartlyUsedLast.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/CPP.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/CPP.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +1/−0
- test/tests/CPP.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/CPP.PreserveInstanceImportsNoExportProcessingPrelude-golden +1/−0
- test/tests/Class.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/Class.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +42/−0
- test/tests/Class.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/Class.PreserveInstanceImportsNoExportProcessingPrelude-golden +42/−0
- test/tests/ConstructorsUnused.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/ConstructorsUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/ConstructorsUnused.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/ConstructorsUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/Dummy.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/Dummy.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +4/−0
- test/tests/Dummy.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/Dummy.PreserveInstanceImportsNoExportProcessingPrelude-golden +4/−0
- test/tests/Duplicated.MinimiseImportsNoExportProcessing-golden +0/−7
- test/tests/Duplicated.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +7/−0
- test/tests/Duplicated.PreserveInstanceImportsNoExportProcessing-golden +0/−8
- test/tests/Duplicated.PreserveInstanceImportsNoExportProcessingPrelude-golden +8/−0
- test/tests/ExportExplicit.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/ExportExplicit.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +10/−0
- test/tests/ExportExplicit.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/ExportExplicit.PreserveInstanceImportsNoExportProcessingPrelude-golden +10/−0
- test/tests/ExportImplicit.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/ExportImplicit.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +10/−0
- test/tests/ExportImplicit.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/ExportImplicit.PreserveInstanceImportsNoExportProcessingPrelude-golden +10/−0
- test/tests/ExportPattern2.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/ExportPattern2.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +142/−0
- test/tests/ExportPattern2.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/ExportPattern2.PreserveInstanceImportsNoExportProcessingPrelude-golden +142/−0
- test/tests/ImplicitImportUnused.MinimiseImportsNoExportProcessing-golden +0/−7
- test/tests/ImplicitImportUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +7/−0
- test/tests/ImplicitImportUnused.PreserveInstanceImportsNoExportProcessing-golden +0/−9
- test/tests/ImplicitImportUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden +9/−0
- test/tests/ImplicitImportUsed.MinimiseImportsNoExportProcessing-golden +0/−5
- test/tests/ImplicitImportUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +5/−0
- test/tests/ImplicitImportUsed.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/ImplicitImportUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/ImportEmpty.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/ImportEmpty.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +1/−0
- test/tests/ImportEmpty.PreserveInstanceImportsNoExportProcessing-golden +0/−3
- test/tests/ImportEmpty.PreserveInstanceImportsNoExportProcessingPrelude-golden +3/−0
- test/tests/ImportPattern.MinimiseImportsNoExportProcessing-golden +0/−147
- test/tests/ImportPattern.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +147/−0
- test/tests/ImportPattern.PreserveInstanceImportsNoExportProcessing-golden +0/−149
- test/tests/ImportPattern.PreserveInstanceImportsNoExportProcessingPrelude-golden +149/−0
- test/tests/MoreExports.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/MoreExports.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +20/−0
- test/tests/MoreExports.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/MoreExports.PreserveInstanceImportsNoExportProcessingPrelude-golden +20/−0
- test/tests/MultilineUnused.MinimiseImportsNoExportProcessing-golden +0/−5
- test/tests/MultilineUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +5/−0
- test/tests/MultilineUnused.PreserveInstanceImportsNoExportProcessing-golden +0/−6
- test/tests/MultilineUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden +6/−0
- test/tests/NoImplicitPrelude.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +15/−0
- test/tests/NoImplicitPrelude.MinimiseImportsReplaceExports-golden +19/−0
- test/tests/NoImplicitPrelude.NoImportProcessingAddExplicitExports-golden +19/−0
- test/tests/NoImplicitPrelude.NoImportProcessingNoExportProcessing-golden +1/−0
- test/tests/NoImplicitPrelude.NoImportProcessingReplaceExports-golden +19/−0
- test/tests/NoImplicitPrelude.PreserveInstanceImportsNoExportProcessingPrelude-golden +15/−0
- test/tests/NoImplicitPrelude.hs +15/−0
- test/tests/Operator.MinimiseImportsNoExportProcessing-golden +0/−1
- test/tests/Operator.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +8/−0
- test/tests/Operator.PreserveInstanceImportsNoExportProcessing-golden +0/−1
- test/tests/Operator.PreserveInstanceImportsNoExportProcessingPrelude-golden +8/−0
- test/tests/Pattern.MinimiseImportsNoExportProcessing-golden +0/−10
- test/tests/Pattern.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +10/−0
- test/tests/Pattern.PreserveInstanceImportsNoExportProcessing-golden +0/−10
- test/tests/Pattern.PreserveInstanceImportsNoExportProcessingPrelude-golden +10/−0
- test/tests/QualUnqual.MinimiseImportsNoExportProcessing-golden +0/−6
- test/tests/QualUnqual.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +6/−0
- test/tests/QualUnqual.PreserveInstanceImportsNoExportProcessing-golden +0/−6
- test/tests/QualUnqual.PreserveInstanceImportsNoExportProcessingPrelude-golden +6/−0
- test/tests/TypeConstructorUnused.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/TypeConstructorUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/TypeConstructorUnused.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/TypeConstructorUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/TypeConstructorUnusedComma.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/TypeConstructorUnusedComma.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/TypeConstructorUnusedComma.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/TypeConstructorUnusedComma.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/TypeConstructorUsed.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/TypeConstructorUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/TypeConstructorUsed.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/TypeConstructorUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/TypeFam.MinimiseImportsNoExportProcessing-golden +0/−43
- test/tests/TypeFam.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +43/−0
- test/tests/TypeFam.PreserveInstanceImportsNoExportProcessing-golden +0/−47
- test/tests/TypeFam.PreserveInstanceImportsNoExportProcessingPrelude-golden +47/−0
- test/tests/TypeUnused.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/TypeUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/TypeUnused.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/TypeUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/TypeUsed.MinimiseImportsNoExportProcessing-golden +0/−4
- test/tests/TypeUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +4/−0
- test/tests/TypeUsed.PreserveInstanceImportsNoExportProcessing-golden +0/−6
- test/tests/TypeUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden +6/−0
- test/tests/WildcardUnused.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/WildcardUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/WildcardUnused.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/WildcardUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
- test/tests/WildcardUsed.MinimiseImportsNoExportProcessing-golden +0/−3
- test/tests/WildcardUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden +3/−0
- test/tests/WildcardUsed.PreserveInstanceImportsNoExportProcessing-golden +0/−5
- test/tests/WildcardUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden +5/−0
CHANGELOG.md view
@@ -5,6 +5,10 @@ `smuggler2` uses [PVP Versioning][1]. The change log is available [on GitHub][2]. +## [0.3.5.1]: -- 14 June 2020+- fix bug that left some files with open imports unprocessed+- add `LeaveOpenImports` and `MakeOpenImports` options+ ## [0.3.4.2]: -- 10 June 2020 - Add test golden files to the distribution
Makefile view
@@ -1,7 +1,7 @@ # For convenience # -.PHONY: build install test clean accept doc hlint ghcid weed+.PHONY: build install test clean accept doc hlint ghcid upload weed all: build test doc @@ -27,8 +27,15 @@ doc: cabal haddock- cabal v2-haddock --haddock-for-hackage --enable-doc-# cabal upload -d --publish dist-newstyle/smuggler2-0.3.x.y-docs.tar.gz+ cabal haddock --haddock-for-hackage --enable-doc --haddock-option=--hyperlinked-source++upload:+ cabal check+ cabal gen-bounds+ cabal sdist+ cabal haddock --haddock-for-hackage --enable-doc --haddock-option=--hyperlinked-source+ cabal upload dist-newstyle/sdist/smuggler2-0.3.*.*.tar.gz+# cabal upload -d --publish dist-newstyle/smuggler2-0.3.*.*-docs.tar.gz hlint: hlint src test/Test.hs
README.md view
@@ -17,15 +17,21 @@ name is used elsewhere in your package. Limiting exports may make it easier for `ghc` to optimise some code. -While writing code, it may be convenient to import a complete module (by not-specifiying what is to be imported from it) and then get Smuggler2 to limit the-import to include only the names that are used.+The [Haskell Wiki](https://wiki.haskell.org/Import_modules_properly) sets out+the pros and cons of using explicit import lists. `Smuggler2` offers the option+of leaving a module imports open (by not specifiying explcitly what is to be+imported from them) while developing and then getting `Smuggler2` to add minimal+lists of explicit exports. This helps to document modules and, arguably, makes+them easier to read by avoiding the need to qualify names to give an indication+of where they came from. It could also provides a cross-check that only expected+names are being used. ## How to use Install `smuggler2` using `cabal install --lib smuggler2`. -If you also want the `ghc` wrapper, install it using `cabal install exe:smuggler2`.+If you also want the `ghc` wrapper, install it using+`cabal install exe:smuggler2`. ### Adding Smuggler2 to your dependencies @@ -63,8 +69,8 @@ ### Alternatively, using a local version If you have installed `smuggler2` from a local copy of this repository, you may-need to add `-package smuggler2` to your `ghc-options` if you did not-install using the `--lib` flag to `cabal install`.+need to add `-package smuggler2` to your `ghc-options` if you did not install+using the `--lib` flag to `cabal install`. ### Or use a `ghc` wrapper @@ -83,6 +89,14 @@ $ cabal build -w ghc-smuggler2 ``` +Smuggler2 tries not to change files when there is no work to do.++You can just run `ghcid` as usual:++```bash+$ ghcid --command='cabal repl'+```+ ## Options `Smuggler2` has several (case-insensitive) options, which can be set by adding@@ -107,31 +121,42 @@ all available exports (which, again, you can, of course, then prune to your requirements). -Any other option value is used to generate a source file with a new extension of-the option value (`new` in the following example) rather than replacing the-original file.+- `LeaveOpenImports` and `MakeOpenImports` take a comma-separated list of module+ names. The specified modules are to be left open if they were open in the+ sourcee (in the case of `LeaveOpenImports`) and made open even if they were+ not originall (in the case of `MakeOpenImports`). For example, you could add -```Cabal- ghc-options: -fplugin=Smuggler2.Plugin -fplugin-opt=Smuggler2.Plugin:new-```+ ```bash+ -fplugin-opt=Smuggler2.Plugin:LeaveOpenImports:Relude,RIO,Prelude,Some.Module+ ``` -This will create output files with a `.new` suffix rather the overwriting the-originals.+ This may be helpful if you use ghc's `NoImplicitPrelude` language feature and+ import a prelude manually. -Smuggler2 tries not to change files when there is no work to do.-So you can just run `ghcid` as usual:+ If the `PreserveInstanceImports` option was sepecified, the `LeaveOpenImports`+ and `MakeOpenImports` options override it for the specified modules, They have+ no effect, if `NoImportProcessing` was specified. If a module is specified+ both to be left open and made open, it will be made open. -```bash-$ ghcid --command='cabal repl'-```+- Any other option value is used to generate a source file with a new extension+ of the option value (`new` in the following example) rather than replacing the+ original file. + ```Cabal+ ghc-options: -fplugin=Smuggler2.Plugin -fplugin-opt=Smuggler2.Plugin:new+ ```++ This will create output files with a `.new` suffix rather the overwriting the+ originals.+ ## Caveats Because `cabal` and `ghc` don't have full support for distinguishing dependent-packages from plug-ins you will probably want to ensure that the build-dependencies for your project are installed into your local package db first,-before enabling sumuggler, otherwise they will all be processed by it too,-as your project builds, which should do no harm, but will increase your build time.+packages from plug-ins you will probably want to ensure that the build the+dependencies for your project tha are installed into your local package db+first, before enabling sumuggler, otherwise they will all be processed by it+too, as your project builds, which should do no harm, but will increase your+build time. `Smuggler2` is robust -- it can chew through the [Agda](https://github.com/agda/agda) codebase of over 370 modules with complex@@ -149,13 +174,13 @@ - `Smuggler2` rewrites the existing imports, rather than attempting to prune them. (This is a more aggressive approach than `smuggler` which focuses on- removing redundant imports.) It has advantages and disadvantages.- The advantage is that a minimal set of imports is generated in a reproducable+ removing redundant imports.) It has advantages and disadvantages. The+ advantage is that a minimal set of imports is generated in a reproducable format. So you can just import a library without specifying any specific- imports and `Smuggler2` will add an explict list of things that are- used from it. This can be a useful check and better document your modules.- The disdvantage is that imports may be reordered, comments and- blank lines dropped, external imports mixed with external, etc.+ imports and `Smuggler2` will add an explict list of things that are used from+ it. This can be a useful check and better document your modules. The+ disdvantage is that imports may be reordered, comments and blank lines+ dropped, external imports mixed with external, etc. - By default `Smuggler2` does not remove imports completely because an import may be being used to only import instances of typeclasses, So it will leave@@ -189,7 +214,7 @@ - Multiple separate import lines referring to the same library are not consolidated -- Literate Haskell `.lhs` files will procssed into ordinary haskell files a+- Literate Haskell `.lhs` files will procssed into ordinary haskell files wth a `-lhs` suffix. * `hiding` clauses may not be properly analysed. So hiding things that are not
TODO.md view
@@ -14,7 +14,7 @@ - [ ] Do a better job of preserving comments -- [ ] Running test suite on both an imported module and the module that imports+- [X] Running test suite on both an imported module and the module that imports it creates race conditions because both cases will generate the same minimum imprts dump file @@ -34,3 +34,5 @@ - [ ] Check that an export does not need to be qualified - [ ]- Figure out fhy github workflow uses ghc 8.10.1 when it should be running 8.8.3++- [ ] #1 Add options for handling `NoImplictPrelude` and keeping it pristine?
app/Main.hs view
@@ -1,21 +1,23 @@-module Main (- main ) where+module Main where -import GHC.Paths ( ghc )-import System.Environment ( getArgs )-import System.Exit ( exitWith )+import GHC.Paths (ghc)+import System.Environment (getArgs)+import System.Exit (exitWith) import System.Process.Typed- ( runProcess, setEnvInherit, setWorkingDirInherit, shell )+ ( proc,+ runProcess,+ setEnvInherit,+ setWorkingDirInherit,+ ) main :: IO () main = do args <- getArgs+ runProcess ( setWorkingDirInherit . setEnvInherit $- shell- ( ghc- ++ " -fplugin=Smuggler2.Plugin "- ++ unwords args- )+ proc+ ghc+ ("-fplugin=Smuggler2.Plugin" : args) ) >>= exitWith
smuggler2.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: smuggler2-version: 0.3.4.2+version: 0.3.5.1 synopsis: GHC Source Plugin that helps to minimise imports and generate explicit exports @@ -18,7 +18,7 @@ license-file: LICENSE author: jrp2014, Dmitrii Kovanikov, Veronika Romashkina maintainer: jrp2014-copyright: 2020 jrp2014, Dmitrii Kovanikov+copyright: 2020 jrp2014, Dmitrii Kovanikov, Veronika Romashkina category: Development, Refactoring, Compiler Plugin build-type: Simple extra-doc-files:@@ -28,12 +28,12 @@ extra-source-files: test/tests/**/*.hs- test/tests/**/*.MinimiseImportsNoExportProcessing-golden+ test/tests/**/*.MinimiseImportsNoExportProcessingPreludeDataVersion-golden test/tests/**/*.MinimiseImportsReplaceExports-golden test/tests/**/*.NoImportProcessingAddExplicitExports-golden test/tests/**/*.NoImportProcessingNoExportProcessing-golden test/tests/**/*.NoImportProcessingReplaceExports-golden- test/tests/**/*.PreserveInstanceImportsNoExportProcessing-golden+ test/tests/**/*.PreserveInstanceImportsNoExportProcessingPrelude-golden Makefile Setup.hs weeder.dhall@@ -66,6 +66,7 @@ -O2 -Wall -Wextra -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths+ -fobject-code if impl(ghc >=8.10.0) ghc-options: -Wunused-packages -fwrite-ide-info@@ -114,6 +115,7 @@ , ghc >=8.6.5 && <8.11 , ghc-boot >=8.6.5 && <8.11 , ghc-exactprint ^>=0.6.3+ , split ^>=0.2.3 , syb ^>=0.7.1 if flag(debug)@@ -136,6 +138,7 @@ , containers , directory , filepath+ , ghc , ghc-paths , smuggler2 , tasty
src/Smuggler2/Options.hs view
@@ -1,6 +1,6 @@+{-# LANGUAGE DeriveAnyClass #-} -- | -- Description: handling of command line options- module Smuggler2.Options ( Options (..), parseCommandLineOptions,@@ -9,9 +9,12 @@ ) where -import Data.Char (toLower)-import Data.List (foldl')-import Plugins (CommandLineOption)+import Data.Char ( isSpace, toLower )+import Data.List ( foldl' )+import Data.List.Split ( splitOn )+import GHC ( mkModuleName, ModuleName )+import Outputable ( Outputable )+import Plugins ( CommandLineOption ) -- | Ways of performing import processing data ImportAction = NoImportProcessing | PreserveInstanceImports | MinimiseImports@@ -25,14 +28,16 @@ data Options = Options { importAction :: ImportAction, exportAction :: ExportAction,- newExtension :: Maybe String+ newExtension :: Maybe String,+ leaveOpenImports :: [ModuleName],+ makeOpenImports :: [ModuleName] }- deriving (Show)+ deriving (Outputable) -- | The default is to retain instance-only imports (eg, Data.List () ) -- and add explict exports only if they are not already present defaultOptions :: Options-defaultOptions = Options PreserveInstanceImports AddExplicitExports Nothing+defaultOptions = Options PreserveInstanceImports AddExplicitExports Nothing [] [] -- | Simple command line option parser. Last occurrence wins. parseCommandLineOptions :: [CommandLineOption] -> Options@@ -46,4 +51,20 @@ "noexportprocessing" -> opts {exportAction = NoExportProcessing} "addexplicitexports" -> opts {exportAction = AddExplicitExports} "replaceexports" -> opts {exportAction = ReplaceExports}- _ -> opts {newExtension = Just clo}+ _+ | Just modulenames <- stripPrefixCI "leaveopenimports:" clo ->+ opts {leaveOpenImports = parseModuleNames modulenames}+ | Just modulenames <- stripPrefixCI "makeopenimports:" clo ->+ opts {makeOpenImports = parseModuleNames modulenames}+ | otherwise -> opts {newExtension = Just clo}++-- | split on comma. Not v robust (+parseModuleNames :: String -> [ModuleName]+parseModuleNames arg = mkModuleName <$> splitOn "," (filter (not . isSpace) arg)++-- | case-insensitive version of @Data.List.stripPrefix@+stripPrefixCI :: String -> String -> Maybe String+stripPrefixCI [] ys = Just ys+stripPrefixCI (x : xs) (y : ys)+ | toLower x == toLower y = stripPrefixCI xs ys+stripPrefixCI _ _ = Nothing
src/Smuggler2/Plugin.hs view
@@ -7,70 +7,73 @@ ) where -import Avail ( AvailInfo, Avails )-import Control.Monad ( unless )-import Data.Bool ( bool )-import Data.Maybe ( fromMaybe, isNothing )-import Data.Version ( showVersion )-import DynFlags- ( DynFlags(dumpDir), HasDynFlags(getDynFlags), xopt )-import ErrUtils ( compilationProgressMsg, fatalErrorMsg )+import Avail (AvailInfo, Avails)+import Control.Monad (unless, when)+import Data.Bool (bool)+import Data.List (intersect)+import Data.Maybe (fromMaybe, isJust, isNothing)+import Data.Version (showVersion)+import DynFlags (DynFlags (dumpDir), HasDynFlags (getDynFlags), xopt)+import ErrUtils (compilationProgressMsg, fatalErrorMsg, warningMsg) import GHC- ( GenLocated(L),- GhcPs,- HsModule(hsmodExports, hsmodImports),- ImportDecl(ideclHiding, ideclImplicit),- LIE,- LImportDecl,- Located,- ms_location,- ml_hs_file,- ModSummary(ms_hspp_buf, ms_mod),- Module(moduleName),- ParsedSource,- moduleNameString,- unLoc )-import GHC.LanguageExtensions ( Extension(Cpp) )-import GHC.IO.Encoding ( setLocaleEncoding, utf8 )-import IOEnv ( MonadIO(liftIO), readMutVar )+ ( GenLocated (L),+ GhcPs,+ GhcRn,+ HsModule (hsmodExports, hsmodImports),+ ImportDecl (ideclHiding, ideclImplicit, ideclName),+ LIE,+ LImportDecl,+ Located,+ ModSummary (ms_hspp_buf, ms_mod),+ Module (moduleName),+ ParsedSource,+ ml_hs_file,+ moduleNameString,+ ms_location,+ unLoc,+ )+import GHC.IO.Encoding (setLocaleEncoding, utf8)+import GHC.LanguageExtensions (Extension (Cpp))+import IOEnv (MonadIO (liftIO), readMutVar) import Language.Haskell.GHC.ExactPrint- ( Anns,- TransformT,- addTrailingCommaT,- exactPrint,- graftT,- runTransform,- setEntryDPT )-import Language.Haskell.GHC.ExactPrint.Types ( DeltaPos(DP) )-import Outputable- ( Outputable(ppr), neverQualify, printForUser, text, vcat )-import Paths_smuggler2 ( version )+ ( Anns,+ TransformT,+ addTrailingCommaT,+ exactPrint,+ graftT,+ runTransform,+ setEntryDPT,+ )+import Language.Haskell.GHC.ExactPrint.Types (DeltaPos (DP))+import Outputable (Outputable (ppr), neverQualify, printForUser, text, vcat)+import Paths_smuggler2 (version) import Plugins- ( CommandLineOption,- Plugin(pluginRecompile, typeCheckResultAction),- defaultPlugin,- purePlugin )-import RnNames ( ImportDeclUsage, findImportUsage )-import Smuggler2.Anns ( mkLoc, mkParenT )-import Smuggler2.Imports ( getMinimalImports )-import Smuggler2.Exports ( mkExportAnnT )+ ( CommandLineOption,+ Plugin (pluginRecompile, typeCheckResultAction),+ defaultPlugin,+ purePlugin,+ )+import RnNames (ImportDeclUsage, findImportUsage)+import Smuggler2.Anns (mkLoc, mkParenT)+import Smuggler2.Exports (mkExportAnnT)+import Smuggler2.Imports (getMinimalImports) import Smuggler2.Options- ( ExportAction(AddExplicitExports, NoExportProcessing,- ReplaceExports),- ImportAction(MinimiseImports, NoImportProcessing),- Options(exportAction, importAction, newExtension),- parseCommandLineOptions )-import Smuggler2.Parser ( runParser )-import StringBuffer ( StringBuffer(StringBuffer), lexemeToString )-import System.Directory ( removeFile )-import System.FilePath ( (-<.>), (</>), isExtensionOf, takeExtension )-import System.IO ( IOMode(WriteMode), withFile )-import TcRnExports ( exports_from_avail )+ ( ExportAction (AddExplicitExports, NoExportProcessing, ReplaceExports),+ ImportAction (MinimiseImports, NoImportProcessing),+ Options (..),+ parseCommandLineOptions,+ )+import Smuggler2.Parser (runParser)+import StringBuffer (StringBuffer (StringBuffer), lexemeToString)+import System.Directory (removeFile)+import System.FilePath (isExtensionOf, takeExtension, (-<.>), (</>))+import System.IO (IOMode (WriteMode), withFile)+import TcRnExports (exports_from_avail) import TcRnTypes- ( TcGblEnv(tcg_rdr_env, tcg_imports, tcg_mod, tcg_exports,- tcg_rn_imports, tcg_used_gres, tcg_rn_exports),- TcM,- RnM )+ ( RnM,+ TcGblEnv (tcg_exports, tcg_imports, tcg_mod, tcg_rdr_env, tcg_rn_exports, tcg_rn_imports, tcg_used_gres),+ TcM,+ ) -- | 'Plugin' interface to GHC plugin :: Plugin@@ -83,19 +86,27 @@ -- | The plugin itself smugglerPlugin :: [CommandLineOption] -> ModSummary -> TcGblEnv -> TcM TcGblEnv smugglerPlugin clopts modSummary tcEnv- -- short circuit, if nothing to do+ -- short circuit silently, if nothing to do | (importAction options == NoImportProcessing) && (exportAction options == NoExportProcessing) = return tcEnv | otherwise = do- -- Get the imports and their usage- let imports = tcg_rn_imports tcEnv+ dflags <- getDynFlags+ liftIO $ compilationProgressMsg dflags ("smuggler2 " ++ showVersion version)++ -- Get imports usage uses <- readMutVar $ tcg_used_gres tcEnv let usage = findImportUsage imports uses -- This ensures that the source file is not touched if there are no unused- -- imports, or exports already exist and we are not replacing them- let noUnusedImports = all (\(_decl, used, unused) -> not (null used) && null unused) usage+ -- imports, or exports already exist and we are not replacing them. Assumes+ -- that an open import (ideclHiding Nothing) has unused imports.+ let noUnusedImports =+ all+ ( \(L _ decl, used, unused) ->+ null unused && not (null used) && isJust (ideclHiding decl)+ )+ usage let hasExplicitExports = case tcg_rn_exports tcEnv of Nothing -> False -- There is not even a module header@@ -110,25 +121,41 @@ && ( exportAction options == NoExportProcessing || (hasExplicitExports && exportAction options /= ReplaceExports) )- then return tcEnv+ then do+ liftIO $+ compilationProgressMsg+ dflags+ ( "smuggler2: nothing to do for module "+ ++ (moduleNameString . moduleName $ ms_mod modSummary)+ )+ return tcEnv else do- dflags <- getDynFlags- liftIO $ compilationProgressMsg dflags ("smuggler2 " ++ showVersion version)+ when (importAction options == NoImportProcessing && not (null $ leaveOpenImports options))+ . liftIO+ $ warningMsg dflags (text "LeaveOpenModules ignored as NoImportProcessing also specified")+ when (importAction options == NoImportProcessing && not (null $ makeOpenImports options))+ . liftIO+ $ warningMsg dflags (text "MakeOpenModules ignored as NoImportProcessing also specified") -- Dump GHC's view of what the minimal imports are for the current- -- module, so that they can be annotated when parsed back in+ -- module, so that they can be annotated when parsed back in. -- This is needed because there too much information loss between -- the parsed and renamed AST to use the latter for reconstituting the- -- source. An alternative would be to "index" each name location with+ -- source. @ghc-exactprint@ "index"es ('Anns') each name location with -- a SrcSpan to allow the name matchup, and to make the 'ParsedSource' a -- 100% representation of the original source (modulo tabs, trailing -- whitespace per line). let minImpFilePath = mkMinimalImportsPath dflags (ms_mod modSummary) printMinimalImports' dflags minImpFilePath usage - -- Run smuggling only for its side effects+ -- Run smuggling only for its side effects; don't change the tcEnv we+ -- were givem. tcEnv <$ smuggling dflags minImpFilePath where+ -- The original imports+ imports :: [LImportDecl GhcRn]+ imports = tcg_rn_imports tcEnv+ -- Does all the work smuggling :: DynFlags -> FilePath -> RnM () smuggling dflags minImpFilePath = do@@ -159,7 +186,8 @@ liftIO $ fatalErrorMsg dflags (text $ "smuggler: failed to parse minimal imports from " ++ minImpFilePath) Right (annsImpMod, L _ impMod) -> do- -- The actual minimal imports themselves, as generated by GHC+ -- The actual minimal imports themselves, as generated by GHC,+ -- with open imports processed as specified let minImports = hsmodImports impMod -- What is exported by the module@@ -187,20 +215,25 @@ -- Print the result let newContent = exactPrint astHsMod' annsHsMod'- liftIO $ writeFile (modulePath -<.> ext) newContent+ let newModulePath = modulePath -<.> ext+ liftIO $ writeFile newModulePath newContent + liftIO $+ compilationProgressMsg+ dflags+ ( "smuggler2: output written to " ++ newModulePath )+ -- Clean up: delete the GHC-generated imports file liftIO $ removeFile minImpFilePath where- -- Generates the things that would be exportabe if there were no -- explicit export header, so suitable for replacing one exportable :: RnM [AvailInfo] exportable = do let rdr_env = tcg_rdr_env tcEnv- let imports = tcg_imports tcEnv -- actually not needed for the Nothing case+ let importAvails = tcg_imports tcEnv -- actually not needed for the Nothing case let this_mod = tcg_mod tcEnv- exports <- exports_from_avail Nothing rdr_env imports this_mod+ exports <- exports_from_avail Nothing rdr_env importAvails this_mod return (snd exports) -- Replace a target module's imports@@ -254,6 +287,7 @@ | otherwise = do -- Generate the exports list exportsList <- mapM mkExportAnnT exports+ -- add commas in between and parens around mapM_ addTrailingCommaT (init exportsList) lExportsList <- mkLoc exportsList >>= mkParenT unLoc@@ -264,7 +298,9 @@ -- This version of the GHC function ignores implicit imports, as they -- cannot be parsed back in. (There is an extraneous (implicit))- -- It also provides for leaving out instance-only imports (eg, Data.List() )+ -- It also provides for leaving out instance-only imports (eg,+ -- @import Data.List ()@) and handles the preservation of open imports+ -- (eg, @import Prelude@) printMinimalImports' :: DynFlags -> FilePath -> [ImportDeclUsage] -> RnM () printMinimalImports' dflags filename imports_w_usage = do@@ -279,19 +315,46 @@ -- we never qualify things inside there -- E.g. import Blag( f, b ) -- not import Blag( Blag.f, Blag.g )!- printForUser dflags h neverQualify (vcat (map ppr (filter (letThrough . unLoc) imports')))+ printForUser+ dflags+ h+ neverQualify+ ( vcat+ ( map+ (ppr . leaveOpen)+ (filter letThrough imports')+ )+ ) ) where notImplicit :: ImportDecl pass -> Bool notImplicit = not . ideclImplicit+ -- notInstancesOnly :: ImportDecl pass -> Bool notInstancesOnly i = case ideclHiding i of Just (False, L _ []) -> False _ -> True+ -- keepInstanceOnlyImports :: Bool keepInstanceOnlyImports = importAction options /= MinimiseImports- letThrough :: ImportDecl pass -> Bool- letThrough i = notImplicit i && (keepInstanceOnlyImports || notInstancesOnly i)+ -- Ignore explicit instance only imports, unless the 'MinimiseImports'+ -- option is specified+ letThrough :: LImportDecl pass -> Bool+ letThrough (L _ i) = notImplicit i && (keepInstanceOnlyImports || notInstancesOnly i)+ --+ leaveOpen :: LImportDecl pass -> LImportDecl pass+ leaveOpen (L l decl) = L l $ case ideclHiding decl of+ Just (False, L _ _) -- ie, not hiding+ | thisModule `elem` kModules || thisModule `elem` mModules -> decl {ideclHiding = Nothing}+ _ -> decl+ where+ thisModule = unLoc (ideclName decl)+ mModules = makeOpenImports options+ lModules = leaveOpenImports options+ oModules = unLoc . ideclName <$> filter isOpen (unLoc <$> imports) -- original open imports+ where+ isOpen = isNothing . ideclHiding+ kModules = lModules `intersect` oModules -- original open imports to leave open -- Construct the path into which GHC's version of minimal imports is dumped mkMinimalImportsPath :: DynFlags -> Module -> FilePath@@ -307,5 +370,6 @@ options :: Options options = parseCommandLineOptions clopts + -- strBufToStr :: StringBuffer -> String strBufToStr sb@(StringBuffer _ len _) = lexemeToString sb len
test/Test.hs view
@@ -3,10 +3,11 @@ module Main where import Control.Monad (forM)-import Data.List (sort)+import Data.List (intercalate, sort) import Data.Maybe (fromMaybe) import qualified Data.Set as Set (fromList, member) import GHC.Paths (ghc)+import GHC (mkModuleName, moduleNameString) import Smuggler2.Options (ExportAction (..), ImportAction (..), Options (..)) import System.Directory (doesDirectoryExist, getDirectoryContents) import System.Environment (lookupEnv)@@ -28,20 +29,29 @@ -- | Combinations of import and export action options to be tested optionsList :: [Options] optionsList =- [ mkOptions PreserveInstanceImports NoExportProcessing,- mkOptions MinimiseImports ReplaceExports,- mkOptions MinimiseImports NoExportProcessing,- mkOptions NoImportProcessing AddExplicitExports,- mkOptions NoImportProcessing NoExportProcessing,- mkOptions NoImportProcessing ReplaceExports+ [ mkOptions PreserveInstanceImports NoExportProcessing [] ["Prelude"],+ mkOptions MinimiseImports ReplaceExports [] [],+ mkOptions MinimiseImports NoExportProcessing ["Prelude", "Data.Version"] [],+ mkOptions NoImportProcessing AddExplicitExports [] [],+ mkOptions NoImportProcessing NoExportProcessing [] [],+ mkOptions NoImportProcessing ReplaceExports [] [] ] where- mkOptions :: ImportAction -> ExportAction -> Options- mkOptions ia ea = Options ia ea (Just $ mkExt ia ea)+ mkOptions :: ImportAction -> ExportAction -> [String] -> [String] -> Options+ mkOptions ia ea lo mo =+ Options+ ia+ ea+ (Just $ mkExt ia ea lo mo)+ (mkModuleName <$> lo)+ (mkModuleName <$> mo) -- | Make an extention for an output file-mkExt :: ImportAction -> ExportAction -> String-mkExt ia ea = show ia ++ show ea -- ++ "-" ++ takeFileName ghc+mkExt :: ImportAction -> ExportAction -> [String] -> [String] -> String+mkExt ia ea lo mo =+ show ia+ ++ show ea+ ++ filter (/= '.') ( concat lo ++ concat mo ) -- ++ "-" ++ takeFileName ghc -- | Generate test for a list of 'Options' each of which specify what action to -- take on imports and exports@@ -59,11 +69,13 @@ testName [ goldenVsFileDiff (takeBaseName testFile) -- test name- (\ref new -> ["git", "diff", "--no-index", ref, new]) -- how to display diffs+ -- The -G. is needed because cabal sdist changes the golden file+ -- permissions and so all the tests fail.+ (\ref new -> ["git", "diff", "--no-index", "-G.", ref, new]) -- how to display diffs (testFile -<.> testName ++ "-golden") -- golden file outputFilename ( do- -- Write a default output file for those tests where smuggler+ -- Write a default output file for those tests where smuggler2 -- (deliberately) does not generate a new one writeBinaryFile outputFilename "Source file was not touched\r\n" compile testFile opts@@ -119,14 +131,15 @@ setWorkingDirInherit . setEnvInherit $ proc (head cabalCmd)- (tail cabalCmd ++ cabalArgs) :: ProcessConfig () () ()+ (tail cabalCmd ++ cabalArgs) ::+ ProcessConfig () () () runProcess_ cabalConfig where cabalArgs :: [String] cabalArgs = -- - not sure why it is necessary to mention the smuggler2 package explicitly, -- but it appears to be hidden otherwise.- -- - This also puts the .imports files that smuggler generates somewhere they+ -- - This also puts the .imports files that smuggler2 generates somewhere they -- can easily be found [ "--with-compiler=" ++ ghc, "exec",@@ -143,7 +156,14 @@ ("-fplugin-opt=Smuggler2.Plugin:" ++) ( let ia = importAction opts ea = exportAction opts- -- the extension should have been set by 'optionsList'- in (fromMaybe "missng" (newExtension opts) : [show ia, show ea])+ ne = newExtension opts+ lo = intercalate "," (moduleNameString <$> leaveOpenImports opts)+ mo = intercalate "," (moduleNameString <$> makeOpenImports opts)+ in -- The extension should have been set by 'optionsList'+ -- The rest of the list are the other arguments for the test+ ( fromMaybe "missng" ne : [show ia, show ea]+ ++ ["LeaveOpenImports:" ++ lo | not (null lo)]+ ++ ["MakeOpenImports:" ++ mo | not (null mo)]+ ) ) ++ [testcase]
− test/tests/Bare.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@---main = undefined
+ test/tests/Bare.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+++main = undefined
− test/tests/Bare.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@---import Data.List ()--main = undefined
+ test/tests/Bare.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+++import Data.List ()++main = undefined
− test/tests/BareHello.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/BareHello.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,5 @@+module BareHello where++foo = (+1)++main = putStrLn "Hello, World"
test/tests/BareHello.MinimiseImportsReplaceExports-golden view
@@ -1,4 +1,7 @@ module BareHello (+ foo, main ) where++foo = (+1) main = putStrLn "Hello, World"
test/tests/BareHello.NoImportProcessingAddExplicitExports-golden view
@@ -1,4 +1,7 @@ module BareHello (+ foo, main ) where++foo = (+1) main = putStrLn "Hello, World"
test/tests/BareHello.NoImportProcessingReplaceExports-golden view
@@ -1,4 +1,7 @@ module BareHello (+ foo, main ) where++foo = (+1) main = putStrLn "Hello, World"
− test/tests/BareHello.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/BareHello.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module BareHello where++foo = (+1)++main = putStrLn "Hello, World"
test/tests/BareHello.hs view
@@ -1,3 +1,5 @@ module BareHello where +foo = (+1)+ main = putStrLn "Hello, World"
− test/tests/BoolBoolUnused.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-module Test.BoolBoolUnused where
+ test/tests/BoolBoolUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,1 @@+module Test.BoolBoolUnused where
− test/tests/BoolBoolUnused.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.BoolBoolUnused where--import Data.Bool ()
+ test/tests/BoolBoolUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,3 @@+module Test.BoolBoolUnused where++import Data.Bool ()
− test/tests/BoolBoolUsed.MinimiseImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.BoolBoolUsed where--import Data.Bool ( bool )--func = bool
+ test/tests/BoolBoolUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,5 @@+module Test.BoolBoolUsed where++import Data.Bool ( bool )++func = bool
− test/tests/BoolBoolUsed.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.BoolBoolUsed where--import Data.Bool ( bool )--func = bool
+ test/tests/BoolBoolUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.BoolBoolUsed where++import Data.Bool ( bool )++func = bool
− test/tests/BoolPartlyUsedFirst.MinimiseImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.BoolPartlyUsedFirst where--import Data.Bool ( bool )--foo = bool
+ test/tests/BoolPartlyUsedFirst.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,5 @@+module Test.BoolPartlyUsedFirst where++import Data.Bool ( bool )++foo = bool
− test/tests/BoolPartlyUsedFirst.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.BoolPartlyUsedFirst where--import Data.Bool ( bool )--foo = bool
+ test/tests/BoolPartlyUsedFirst.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.BoolPartlyUsedFirst where++import Data.Bool ( bool )++foo = bool
− test/tests/BoolPartlyUsedLast.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.BoolPartlyUsedLast where--foo = not
+ test/tests/BoolPartlyUsedLast.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+module Test.BoolPartlyUsedLast where++foo = not
− test/tests/BoolPartlyUsedLast.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.BoolPartlyUsedLast where--import Data.Bool ()--foo = not
+ test/tests/BoolPartlyUsedLast.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.BoolPartlyUsedLast where++import Data.Bool ()++foo = not
− test/tests/CPP.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/CPP.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,1 @@+Source file was not touched
− test/tests/CPP.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/CPP.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,1 @@+Source file was not touched
− test/tests/Class.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/Class.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,42 @@+module Class where+++data Record a = Record { aa :: a, b :: String }++data Impossible++ = Impossible String Integer+ -- ^ We reached a program point which should be unreachable.++ | Unreachable String Integer+ -- ^ @Impossible@ with a different error message.+ -- Used when we reach a program point which can in principle+ -- be reached, but not for a certain run.++ | ImpMissingDefinitions [String] String+ -- ^ We reached a program point without all the required+ -- primitives or BUILTIN to proceed forward.+ -- @ImpMissingDefinitions neededDefs forThis@+++class CatchImpossible m where++ -- | Catch any 'Impossible' exception.+ catchImpossible :: m a -> (Impossible -> m a) -> m a+ catchImpossible = catchImpossibleJust Just++ -- | Catch only 'Impossible' exceptions selected by the filter.+ catchImpossibleJust :: (Impossible -> Maybe b) -> m a -> (b -> m a) -> m a+ catchImpossibleJust = flip . handleImpossibleJust++ -- | Version of 'catchImpossible' with argument order suiting short handlers.+ handleImpossible :: (Impossible -> m a) -> m a -> m a+ handleImpossible = flip catchImpossible++ -- | Version of 'catchImpossibleJust' with argument order suiting short handlers.+ handleImpossibleJust :: (Impossible -> Maybe b) -> (b -> m a) -> m a -> m a+ handleImpossibleJust = flip . catchImpossibleJust++ {-# MINIMAL catchImpossibleJust | handleImpossibleJust #-}++
− test/tests/Class.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/Class.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,42 @@+module Class where+++data Record a = Record { aa :: a, b :: String }++data Impossible++ = Impossible String Integer+ -- ^ We reached a program point which should be unreachable.++ | Unreachable String Integer+ -- ^ @Impossible@ with a different error message.+ -- Used when we reach a program point which can in principle+ -- be reached, but not for a certain run.++ | ImpMissingDefinitions [String] String+ -- ^ We reached a program point without all the required+ -- primitives or BUILTIN to proceed forward.+ -- @ImpMissingDefinitions neededDefs forThis@+++class CatchImpossible m where++ -- | Catch any 'Impossible' exception.+ catchImpossible :: m a -> (Impossible -> m a) -> m a+ catchImpossible = catchImpossibleJust Just++ -- | Catch only 'Impossible' exceptions selected by the filter.+ catchImpossibleJust :: (Impossible -> Maybe b) -> m a -> (b -> m a) -> m a+ catchImpossibleJust = flip . handleImpossibleJust++ -- | Version of 'catchImpossible' with argument order suiting short handlers.+ handleImpossible :: (Impossible -> m a) -> m a -> m a+ handleImpossible = flip catchImpossible++ -- | Version of 'catchImpossibleJust' with argument order suiting short handlers.+ handleImpossibleJust :: (Impossible -> Maybe b) -> (b -> m a) -> m a -> m a+ handleImpossibleJust = flip . catchImpossibleJust++ {-# MINIMAL catchImpossibleJust | handleImpossibleJust #-}++
− test/tests/ConstructorsUnused.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.ConstructorsUnused where--foo = not
+ test/tests/ConstructorsUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+module Test.ConstructorsUnused where++foo = not
− test/tests/ConstructorsUnused.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.ConstructorsUnused where--import Data.Bool ()--foo = not
+ test/tests/ConstructorsUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.ConstructorsUnused where++import Data.Bool ()++foo = not
− test/tests/Dummy.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/Dummy.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,4 @@+module Test.Dummy where++main :: IO ()+main = pure ()
− test/tests/Dummy.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/Dummy.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,4 @@+module Test.Dummy where++main :: IO ()+main = pure ()
− test/tests/Duplicated.MinimiseImportsNoExportProcessing-golden
@@ -1,7 +0,0 @@-module Duplicated where--import Data.Char ( isDigit )-import Data.Char ( isLetter )---test x = isDigit x || isLetter x
+ test/tests/Duplicated.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,7 @@+module Duplicated where++import Data.Char ( isDigit )+import Data.Char ( isLetter )+++test x = isDigit x || isLetter x
− test/tests/Duplicated.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,8 +0,0 @@-module Duplicated where--import Data.Char ( isDigit )-import Data.Char ()-import Data.Char ( isLetter )---test x = isDigit x || isLetter x
+ test/tests/Duplicated.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,8 @@+module Duplicated where++import Data.Char ( isDigit )+import Data.Char ()+import Data.Char ( isLetter )+++test x = isDigit x || isLetter x
− test/tests/ExportExplicit.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/ExportExplicit.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,10 @@+module Test.ExportExplicit (isExported, anotherExport) where++isExported = (+1)++anotherExport = True++andAnother = 27++main :: IO ()+main = pure ()
− test/tests/ExportExplicit.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/ExportExplicit.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,10 @@+module Test.ExportExplicit (isExported, anotherExport) where++isExported = (+1)++anotherExport = True++andAnother = 27++main :: IO ()+main = pure ()
− test/tests/ExportImplicit.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/ExportImplicit.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,10 @@+module Test.ExportImplicit where++import Data.Char ( toLower )++isExported = (+1)++alsoExported = map toLower "AbC"++main :: IO ()+main = print $ isExported 1
− test/tests/ExportImplicit.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/ExportImplicit.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,10 @@+module Test.ExportImplicit where++import Data.Char ( toLower )++isExported = (+1)++alsoExported = map toLower "AbC"++main :: IO ()+main = print $ isExported 1
− test/tests/ExportPattern2.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/ExportPattern2.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,142 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++module ExportPattern2 where++import Control.Monad ( guard )+import qualified Data.Sequence as Seq+ ( viewl, viewr, ViewL((:<), EmptyL), ViewR((:>)) )++pattern P = 42++--useP P = 43++--++data Type = App String [Type]++pattern Arrow :: Type -> Type -> Type+pattern Arrow t1 t2 = App "->" [t1, t2]++pattern Int = App "Int" []++pattern Maybe t = App "Maybe" [t]+++{-+collectArgs :: Type -> [Type]+collectArgs (Arrow t1 t2) = t1 : collectArgs t2+collectArgs _ = []++isInt :: Type -> Bool+isInt Int = True+isInt _ = False++isIntEndo :: Type -> Bool+isIntEndo (Arrow Int Int) = True+isIntEndo _ = False++arrows :: [Type] -> Type -> Type+arrows = flip $ foldr Arrow+-}++--+++pattern Empty <- (Seq.viewl -> Seq.EmptyL)+pattern x :< xs <- (Seq.viewl -> x Seq.:< xs)+pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)++{-+viewPL (x :< Empty) = x+viewPR (Empty :> y) = y+-}++--+++pattern Succ n <-+ (\x -> (x -1) <$ guard (x > 0) -> Just n)+ where+ Succ n = n + 1++{-+fac (Succ n) = Succ n * fac n+fac 0 = 1+-}++--+++data Showable where+ MkShowable :: (Show a) => a -> Showable++-- Required context is empty, but provided context is not+pattern Sh :: () => (Show a) => a -> Showable+pattern Sh x <- MkShowable x++{-+showable :: (Show a) => a -> Showable+showable x = MkShowable x+-}++--+++-- Provided context is empty+pattern One :: (Num a, Eq a) => a+pattern One <- 1+++-- one One = 2++--+++pattern Pair x y <- [x, y]++++{-+f (Pair True True) = True+f _ = False++g [True, True] = True+g _ = False+-}++++--++data Nat = Z | S Nat deriving (Show)++pattern Ess p = S p+++--two = S ( S Z)++--++pattern Single x = [x]++pattern Head x <- x : xs++{- single (Single x) = x+hd :: [a] -> a+hd (Head x) = x+-}++--+++data T a where+ MkT :: (Show b) => a -> b -> T a++pattern ExNumPat x = MkT 42 x++{-+h :: (Num t, Eq t) => T t -> String+h (ExNumPat x) = show x+-}
− test/tests/ExportPattern2.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/ExportPattern2.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,142 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++module ExportPattern2 where++import Control.Monad ( guard )+import qualified Data.Sequence as Seq+ ( viewl, viewr, ViewL((:<), EmptyL), ViewR((:>)) )++pattern P = 42++--useP P = 43++--++data Type = App String [Type]++pattern Arrow :: Type -> Type -> Type+pattern Arrow t1 t2 = App "->" [t1, t2]++pattern Int = App "Int" []++pattern Maybe t = App "Maybe" [t]+++{-+collectArgs :: Type -> [Type]+collectArgs (Arrow t1 t2) = t1 : collectArgs t2+collectArgs _ = []++isInt :: Type -> Bool+isInt Int = True+isInt _ = False++isIntEndo :: Type -> Bool+isIntEndo (Arrow Int Int) = True+isIntEndo _ = False++arrows :: [Type] -> Type -> Type+arrows = flip $ foldr Arrow+-}++--+++pattern Empty <- (Seq.viewl -> Seq.EmptyL)+pattern x :< xs <- (Seq.viewl -> x Seq.:< xs)+pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)++{-+viewPL (x :< Empty) = x+viewPR (Empty :> y) = y+-}++--+++pattern Succ n <-+ (\x -> (x -1) <$ guard (x > 0) -> Just n)+ where+ Succ n = n + 1++{-+fac (Succ n) = Succ n * fac n+fac 0 = 1+-}++--+++data Showable where+ MkShowable :: (Show a) => a -> Showable++-- Required context is empty, but provided context is not+pattern Sh :: () => (Show a) => a -> Showable+pattern Sh x <- MkShowable x++{-+showable :: (Show a) => a -> Showable+showable x = MkShowable x+-}++--+++-- Provided context is empty+pattern One :: (Num a, Eq a) => a+pattern One <- 1+++-- one One = 2++--+++pattern Pair x y <- [x, y]++++{-+f (Pair True True) = True+f _ = False++g [True, True] = True+g _ = False+-}++++--++data Nat = Z | S Nat deriving (Show)++pattern Ess p = S p+++--two = S ( S Z)++--++pattern Single x = [x]++pattern Head x <- x : xs++{- single (Single x) = x+hd :: [a] -> a+hd (Head x) = x+-}++--+++data T a where+ MkT :: (Show b) => a -> b -> T a++pattern ExNumPat x = MkT 42 x++{-+h :: (Num t, Eq t) => T t -> String+h (ExNumPat x) = show x+-}
− test/tests/ImplicitImportUnused.MinimiseImportsNoExportProcessing-golden
@@ -1,7 +0,0 @@-module Test.ImplicitImportUnused where--import Data.Maybe ( isJust )--foo = isJust--bar = 27
+ test/tests/ImplicitImportUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,7 @@+module Test.ImplicitImportUnused where++import Data.Maybe ( isJust )++foo = isJust++bar = 27
− test/tests/ImplicitImportUnused.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,9 +0,0 @@-module Test.ImplicitImportUnused where--import Data.List ()-import Data.Bool ()-import Data.Maybe ( isJust )--foo = isJust--bar = 27
+ test/tests/ImplicitImportUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,9 @@+module Test.ImplicitImportUnused where++import Data.List ()+import Data.Bool ()+import Data.Maybe ( isJust )++foo = isJust++bar = 27
− test/tests/ImplicitImportUsed.MinimiseImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.ImplicitImportUsed where--import Data.List ( intercalate )--foo = intercalate ","
+ test/tests/ImplicitImportUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,5 @@+module Test.ImplicitImportUsed where++import Data.List ( intercalate )++foo = intercalate ","
− test/tests/ImplicitImportUsed.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.ImplicitImportUsed where--import Data.List ( intercalate )--foo = intercalate ","
+ test/tests/ImplicitImportUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.ImplicitImportUsed where++import Data.List ( intercalate )++foo = intercalate ","
− test/tests/ImportEmpty.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-module Test.ImportEmpty where
+ test/tests/ImportEmpty.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,1 @@+module Test.ImportEmpty where
− test/tests/ImportEmpty.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.ImportEmpty where--import Data.Bool ()
+ test/tests/ImportEmpty.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,3 @@+module Test.ImportEmpty where++import Data.Bool ()
− test/tests/ImportPattern.MinimiseImportsNoExportProcessing-golden
@@ -1,147 +0,0 @@-{-# LANGUAGE GADTs #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE ViewPatterns #-}--module ImportPattern where--import Imported.ExportPattern- ( T,- Nat(Z, S),- Showable(..),- Type,- pattern ExNumPat,- pattern Head,- pattern Single,- pattern Pair,- pattern One,- pattern Succ,- pattern (:>),- pattern (:<),- pattern Empty,- pattern Int,- pattern Arrow,- pattern P )---- pattern P = 42--useP P = 43------{--data Type = App String [Type]--pattern Arrow :: Type -> Type -> Type-pattern Arrow t1 t2 = App "->" [t1, t2]--pattern Int = App "Int" []--pattern Maybe t = App "Maybe" [t]---}--collectArgs :: Type -> [Type]-collectArgs (Arrow t1 t2) = t1 : collectArgs t2-collectArgs _ = []--isInt :: Type -> Bool-isInt Int = True-isInt _ = False--isIntEndo :: Type -> Bool-isIntEndo (Arrow Int Int) = True-isIntEndo _ = False--arrows :: [Type] -> Type -> Type-arrows = flip $ foldr Arrow-----{---pattern Empty <- (Seq.viewl -> Seq.EmptyL)-pattern x :< xs <- (Seq.viewl -> x Seq.:< xs)-pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)--}--viewPL (x :< Empty) = x-viewPR (Empty :> y) = y------{--pattern Succ n <-- (\x -> (x -1) <$ guard (x > 0) -> Just n)- where- Succ n = n + 1--}--fac (Succ n) = Succ n * fac n-fac 0 = 1------{--data Showable where- MkShowable :: (Show a) => a -> Showable---- Required context is empty, but provided context is not-pattern Sh :: () => (Show a) => a -> Showable-pattern Sh x <- MkShowable x--}--showable :: (Show a) => a -> Showable-showable x = MkShowable x------{---- Provided context is empty-pattern One :: (Num a, Eq a) => a-pattern One <- 1--}--one One = 2---------pattern Pair x y <- [x, y]---f (Pair True True) = True-f _ = False--g [True, True] = True-g _ = False------{--data Nat = Z | S Nat deriving (Show)--pattern Ess p = S p--}--two = S ( S Z)-------- pattern Single x = [x]---- pattern Head x <- x : xs--single (Single x) = x-hd :: [a] -> a-hd (Head x) = x------{--data T a where- MkT :: (Show b) => a -> b -> T a--pattern ExNumPat x = MkT 42 x--}--h :: (Num t, Eq t) => T t -> String-h (ExNumPat x) = show x
+ test/tests/ImportPattern.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,147 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++module ImportPattern where++import Imported.ExportPattern+ ( T,+ Nat(Z, S),+ Showable(..),+ Type,+ pattern ExNumPat,+ pattern Head,+ pattern Single,+ pattern Pair,+ pattern One,+ pattern Succ,+ pattern (:>),+ pattern (:<),+ pattern Empty,+ pattern Int,+ pattern Arrow,+ pattern P )++-- pattern P = 42++useP P = 43++--++{-+data Type = App String [Type]++pattern Arrow :: Type -> Type -> Type+pattern Arrow t1 t2 = App "->" [t1, t2]++pattern Int = App "Int" []++pattern Maybe t = App "Maybe" [t]++-}++collectArgs :: Type -> [Type]+collectArgs (Arrow t1 t2) = t1 : collectArgs t2+collectArgs _ = []++isInt :: Type -> Bool+isInt Int = True+isInt _ = False++isIntEndo :: Type -> Bool+isIntEndo (Arrow Int Int) = True+isIntEndo _ = False++arrows :: [Type] -> Type -> Type+arrows = flip $ foldr Arrow++--+{-++pattern Empty <- (Seq.viewl -> Seq.EmptyL)+pattern x :< xs <- (Seq.viewl -> x Seq.:< xs)+pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)+-}++viewPL (x :< Empty) = x+viewPR (Empty :> y) = y++--++{-+pattern Succ n <-+ (\x -> (x -1) <$ guard (x > 0) -> Just n)+ where+ Succ n = n + 1+-}++fac (Succ n) = Succ n * fac n+fac 0 = 1++--++{-+data Showable where+ MkShowable :: (Show a) => a -> Showable++-- Required context is empty, but provided context is not+pattern Sh :: () => (Show a) => a -> Showable+pattern Sh x <- MkShowable x+-}++showable :: (Show a) => a -> Showable+showable x = MkShowable x++--++{-+-- Provided context is empty+pattern One :: (Num a, Eq a) => a+pattern One <- 1+-}++one One = 2++--+++--pattern Pair x y <- [x, y]+++f (Pair True True) = True+f _ = False++g [True, True] = True+g _ = False+++--+{-+data Nat = Z | S Nat deriving (Show)++pattern Ess p = S p+-}++two = S ( S Z)++--++-- pattern Single x = [x]++-- pattern Head x <- x : xs++single (Single x) = x+hd :: [a] -> a+hd (Head x) = x++--++{-+data T a where+ MkT :: (Show b) => a -> b -> T a++pattern ExNumPat x = MkT 42 x+-}++h :: (Num t, Eq t) => T t -> String+h (ExNumPat x) = show x
− test/tests/ImportPattern.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,149 +0,0 @@-{-# LANGUAGE GADTs #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE ViewPatterns #-}--module ImportPattern where--import Control.Monad ()-import qualified Data.Sequence as Seq ()-import Imported.ExportPattern- ( T,- Nat(Z, S),- Showable(..),- Type,- pattern ExNumPat,- pattern Head,- pattern Single,- pattern Pair,- pattern One,- pattern Succ,- pattern (:>),- pattern (:<),- pattern Empty,- pattern Int,- pattern Arrow,- pattern P )---- pattern P = 42--useP P = 43------{--data Type = App String [Type]--pattern Arrow :: Type -> Type -> Type-pattern Arrow t1 t2 = App "->" [t1, t2]--pattern Int = App "Int" []--pattern Maybe t = App "Maybe" [t]---}--collectArgs :: Type -> [Type]-collectArgs (Arrow t1 t2) = t1 : collectArgs t2-collectArgs _ = []--isInt :: Type -> Bool-isInt Int = True-isInt _ = False--isIntEndo :: Type -> Bool-isIntEndo (Arrow Int Int) = True-isIntEndo _ = False--arrows :: [Type] -> Type -> Type-arrows = flip $ foldr Arrow-----{---pattern Empty <- (Seq.viewl -> Seq.EmptyL)-pattern x :< xs <- (Seq.viewl -> x Seq.:< xs)-pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)--}--viewPL (x :< Empty) = x-viewPR (Empty :> y) = y------{--pattern Succ n <-- (\x -> (x -1) <$ guard (x > 0) -> Just n)- where- Succ n = n + 1--}--fac (Succ n) = Succ n * fac n-fac 0 = 1------{--data Showable where- MkShowable :: (Show a) => a -> Showable---- Required context is empty, but provided context is not-pattern Sh :: () => (Show a) => a -> Showable-pattern Sh x <- MkShowable x--}--showable :: (Show a) => a -> Showable-showable x = MkShowable x------{---- Provided context is empty-pattern One :: (Num a, Eq a) => a-pattern One <- 1--}--one One = 2---------pattern Pair x y <- [x, y]---f (Pair True True) = True-f _ = False--g [True, True] = True-g _ = False------{--data Nat = Z | S Nat deriving (Show)--pattern Ess p = S p--}--two = S ( S Z)-------- pattern Single x = [x]---- pattern Head x <- x : xs--single (Single x) = x-hd :: [a] -> a-hd (Head x) = x------{--data T a where- MkT :: (Show b) => a -> b -> T a--pattern ExNumPat x = MkT 42 x--}--h :: (Num t, Eq t) => T t -> String-h (ExNumPat x) = show x
+ test/tests/ImportPattern.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,149 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++module ImportPattern where++import Control.Monad ()+import qualified Data.Sequence as Seq ()+import Imported.ExportPattern+ ( T,+ Nat(Z, S),+ Showable(..),+ Type,+ pattern ExNumPat,+ pattern Head,+ pattern Single,+ pattern Pair,+ pattern One,+ pattern Succ,+ pattern (:>),+ pattern (:<),+ pattern Empty,+ pattern Int,+ pattern Arrow,+ pattern P )++-- pattern P = 42++useP P = 43++--++{-+data Type = App String [Type]++pattern Arrow :: Type -> Type -> Type+pattern Arrow t1 t2 = App "->" [t1, t2]++pattern Int = App "Int" []++pattern Maybe t = App "Maybe" [t]++-}++collectArgs :: Type -> [Type]+collectArgs (Arrow t1 t2) = t1 : collectArgs t2+collectArgs _ = []++isInt :: Type -> Bool+isInt Int = True+isInt _ = False++isIntEndo :: Type -> Bool+isIntEndo (Arrow Int Int) = True+isIntEndo _ = False++arrows :: [Type] -> Type -> Type+arrows = flip $ foldr Arrow++--+{-++pattern Empty <- (Seq.viewl -> Seq.EmptyL)+pattern x :< xs <- (Seq.viewl -> x Seq.:< xs)+pattern xs :> x <- (Seq.viewr -> xs Seq.:> x)+-}++viewPL (x :< Empty) = x+viewPR (Empty :> y) = y++--++{-+pattern Succ n <-+ (\x -> (x -1) <$ guard (x > 0) -> Just n)+ where+ Succ n = n + 1+-}++fac (Succ n) = Succ n * fac n+fac 0 = 1++--++{-+data Showable where+ MkShowable :: (Show a) => a -> Showable++-- Required context is empty, but provided context is not+pattern Sh :: () => (Show a) => a -> Showable+pattern Sh x <- MkShowable x+-}++showable :: (Show a) => a -> Showable+showable x = MkShowable x++--++{-+-- Provided context is empty+pattern One :: (Num a, Eq a) => a+pattern One <- 1+-}++one One = 2++--+++--pattern Pair x y <- [x, y]+++f (Pair True True) = True+f _ = False++g [True, True] = True+g _ = False+++--+{-+data Nat = Z | S Nat deriving (Show)++pattern Ess p = S p+-}++two = S ( S Z)++--++-- pattern Single x = [x]++-- pattern Head x <- x : xs++single (Single x) = x+hd :: [a] -> a+hd (Head x) = x++--++{-+data T a where+ MkT :: (Show b) => a -> b -> T a++pattern ExNumPat x = MkT 42 x+-}++h :: (Num t, Eq t) => T t -> String+h (ExNumPat x) = show x
− test/tests/MoreExports.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/MoreExports.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,20 @@+module MoreExports where++--Another comment+--++newtype N a = Int a++data D a = A a | B | C a++data R = R { a :: Int, b :: Bool }++data H = I | J | K deriving Show+++foo = (+1)++-- A further Comment++main :: IO ()+main = print J
− test/tests/MoreExports.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/MoreExports.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,20 @@+module MoreExports where++--Another comment+--++newtype N a = Int a++data D a = A a | B | C a++data R = R { a :: Int, b :: Bool }++data H = I | J | K deriving Show+++foo = (+1)++-- A further Comment++main :: IO ()+main = print J
− test/tests/MultilineUnused.MinimiseImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.MultilineUnused where--import Data.Bool ( bool )--foo = bool
+ test/tests/MultilineUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,5 @@+module Test.MultilineUnused where++import Data.Bool ( bool )++foo = bool
− test/tests/MultilineUnused.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,6 +0,0 @@-module Test.MultilineUnused where--import Data.Bool ( bool )-import Data.List ()--foo = bool
+ test/tests/MultilineUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,6 @@+module Test.MultilineUnused where++import Data.Bool ( bool )+import Data.List ()++foo = bool
+ test/tests/NoImplicitPrelude.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,15 @@+{-# LANGUAGE NoImplicitPrelude #-}++module NoImplicitPrelude where++import Data.List ( (++), intercalate )+import Data.Version ( makeVersion )+import Prelude++export = intercalate ", " ["Lorem", "ipsum", "dolor"]++version = makeVersion [1, 2, 3]++useprelude = "abc" <> "def"++useprelude2 = "efg" ++ "ghi"
+ test/tests/NoImplicitPrelude.MinimiseImportsReplaceExports-golden view
@@ -0,0 +1,19 @@+{-# LANGUAGE NoImplicitPrelude #-}++module NoImplicitPrelude (+ export,+ version,+ useprelude,+ useprelude2 ) where++import Data.List ( (++), intercalate )+import Data.Version ( makeVersion )+import Prelude ( Semigroup((<>)) )++export = intercalate ", " ["Lorem", "ipsum", "dolor"]++version = makeVersion [1, 2, 3]++useprelude = "abc" <> "def"++useprelude2 = "efg" ++ "ghi"
+ test/tests/NoImplicitPrelude.NoImportProcessingAddExplicitExports-golden view
@@ -0,0 +1,19 @@+{-# LANGUAGE NoImplicitPrelude #-}++module NoImplicitPrelude (+ export,+ version,+ useprelude,+ useprelude2 ) where++import Data.List+import Data.Version (makeVersion)+import Prelude++export = intercalate ", " ["Lorem", "ipsum", "dolor"]++version = makeVersion [1, 2, 3]++useprelude = "abc" <> "def"++useprelude2 = "efg" ++ "ghi"
+ test/tests/NoImplicitPrelude.NoImportProcessingNoExportProcessing-golden view
@@ -0,0 +1,1 @@+Source file was not touched
+ test/tests/NoImplicitPrelude.NoImportProcessingReplaceExports-golden view
@@ -0,0 +1,19 @@+{-# LANGUAGE NoImplicitPrelude #-}++module NoImplicitPrelude (+ export,+ version,+ useprelude,+ useprelude2 ) where++import Data.List+import Data.Version (makeVersion)+import Prelude++export = intercalate ", " ["Lorem", "ipsum", "dolor"]++version = makeVersion [1, 2, 3]++useprelude = "abc" <> "def"++useprelude2 = "efg" ++ "ghi"
+ test/tests/NoImplicitPrelude.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,15 @@+{-# LANGUAGE NoImplicitPrelude #-}++module NoImplicitPrelude where++import Data.List ( (++), intercalate )+import Data.Version ( makeVersion )+import Prelude++export = intercalate ", " ["Lorem", "ipsum", "dolor"]++version = makeVersion [1, 2, 3]++useprelude = "abc" <> "def"++useprelude2 = "efg" ++ "ghi"
+ test/tests/NoImplicitPrelude.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE NoImplicitPrelude #-}++module NoImplicitPrelude where++import Data.List +import Data.Version (makeVersion)+import Prelude++export = intercalate ", " ["Lorem", "ipsum", "dolor"]++version = makeVersion [1, 2, 3]++useprelude = "abc" <> "def"++useprelude2 = "efg" ++ "ghi"
− test/tests/Operator.MinimiseImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/Operator.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,8 @@+module Operator where++infixl 5 $+$++($+$) :: [a] -> [a] -> [a]+[] $+$ d = d+d $+$ [] = d+d $+$ d' = d ++ d'
− test/tests/Operator.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,1 +0,0 @@-Source file was not touched
+ test/tests/Operator.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,8 @@+module Operator where++infixl 5 $+$++($+$) :: [a] -> [a] -> [a]+[] $+$ d = d+d $+$ [] = d+d $+$ d' = d ++ d'
− test/tests/Pattern.MinimiseImportsNoExportProcessing-golden
@@ -1,10 +0,0 @@-{-# LANGUAGE PatternSynonyms #-}-module Pattern where--import qualified Data.List.NonEmpty as List1 ( cycle )-import Data.List.NonEmpty ( NonEmpty((:|)) )---test = List1.cycle (1 :| [2,3])--test2 = 1 :| [2,3,1,2,3]
+ test/tests/Pattern.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,10 @@+{-# LANGUAGE PatternSynonyms #-}+module Pattern where++import qualified Data.List.NonEmpty as List1 ( cycle )+import Data.List.NonEmpty ( NonEmpty((:|)) )+++test = List1.cycle (1 :| [2,3])++test2 = 1 :| [2,3,1,2,3]
− test/tests/Pattern.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,10 +0,0 @@-{-# LANGUAGE PatternSynonyms #-}-module Pattern where--import qualified Data.List.NonEmpty as List1 ( cycle )-import Data.List.NonEmpty ( NonEmpty((:|)) )---test = List1.cycle (1 :| [2,3])--test2 = 1 :| [2,3,1,2,3]
+ test/tests/Pattern.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,10 @@+{-# LANGUAGE PatternSynonyms #-}+module Pattern where++import qualified Data.List.NonEmpty as List1 ( cycle )+import Data.List.NonEmpty ( NonEmpty((:|)) )+++test = List1.cycle (1 :| [2,3])++test2 = 1 :| [2,3,1,2,3]
− test/tests/QualUnqual.MinimiseImportsNoExportProcessing-golden
@@ -1,6 +0,0 @@-module QualUnqual where--import qualified Data.Char as C ( isDigit )-import Data.Char ( isDigit )--test x = C.isDigit x || isDigit x
+ test/tests/QualUnqual.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,6 @@+module QualUnqual where++import qualified Data.Char as C ( isDigit )+import Data.Char ( isDigit )++test x = C.isDigit x || isDigit x
− test/tests/QualUnqual.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,6 +0,0 @@-module QualUnqual where--import qualified Data.Char as C ( isDigit )-import Data.Char ( isDigit )--test x = C.isDigit x || isDigit x
+ test/tests/QualUnqual.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,6 @@+module QualUnqual where++import qualified Data.Char as C ( isDigit )+import Data.Char ( isDigit )++test x = C.isDigit x || isDigit x
− test/tests/TypeConstructorUnused.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.TypeConstructorUnused where--true = True
+ test/tests/TypeConstructorUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+module Test.TypeConstructorUnused where++true = True
− test/tests/TypeConstructorUnused.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.TypeConstructorUnused where--import Data.Bool ()--true = True
+ test/tests/TypeConstructorUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.TypeConstructorUnused where++import Data.Bool ()++true = True
− test/tests/TypeConstructorUnusedComma.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.TypeConstructorUnusedComma where--false = False
+ test/tests/TypeConstructorUnusedComma.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+module Test.TypeConstructorUnusedComma where++false = False
− test/tests/TypeConstructorUnusedComma.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.TypeConstructorUnusedComma where--import Data.Bool ()--false = False
+ test/tests/TypeConstructorUnusedComma.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.TypeConstructorUnusedComma where++import Data.Bool ()++false = False
− test/tests/TypeConstructorUsed.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.TypeConstructorUsed where--true = True
+ test/tests/TypeConstructorUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+module Test.TypeConstructorUsed where++true = True
− test/tests/TypeConstructorUsed.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.TypeConstructorUsed where--import Data.Bool ()--true = True
+ test/tests/TypeConstructorUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.TypeConstructorUsed where++import Data.Bool ()++true = True
− test/tests/TypeFam.MinimiseImportsNoExportProcessing-golden
@@ -1,43 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeFamilies #-}---- http://www.mchaver.com/posts/2017-06-21-type-families.html--module TypeFam where--import Data.Text ( Text )-import Imported.TypeFam ( Concat(cat, type ConcatTy) )---result :: ConcatTy Text String-result = cat ("Hello" :: Text) (" World!" :: String)--main = print result--class Container c where- type Elem c- empty :: c- insert :: Elem c -> c -> c- member :: Elem c -> c -> Bool- toList :: c -> [Elem c]--instance Eq e => Container [e] where- type Elem [e] = e- empty = []- insert e l = (e:l)- member e [] = False- member e (x:xs)- | e == x = True- | otherwise = member e xs- toList l = l--instance Eq e => Container (Maybe e) where- type Elem (Maybe e) = e -- type synonym- empty = Nothing- insert e l = Just e -- destructive, replaces previous element- member e Nothing = False- member e (Just x) = e == x- toList Nothing = []- toList (Just x) = [x]
+ test/tests/TypeFam.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,43 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeFamilies #-}++-- http://www.mchaver.com/posts/2017-06-21-type-families.html++module TypeFam where++import Data.Text ( Text )+import Imported.TypeFam ( Concat(cat, type ConcatTy) )+++result :: ConcatTy Text String+result = cat ("Hello" :: Text) (" World!" :: String)++main = print result++class Container c where+ type Elem c+ empty :: c+ insert :: Elem c -> c -> c+ member :: Elem c -> c -> Bool+ toList :: c -> [Elem c]++instance Eq e => Container [e] where+ type Elem [e] = e+ empty = []+ insert e l = (e:l)+ member e [] = False+ member e (x:xs)+ | e == x = True+ | otherwise = member e xs+ toList l = l++instance Eq e => Container (Maybe e) where+ type Elem (Maybe e) = e -- type synonym+ empty = Nothing+ insert e l = Just e -- destructive, replaces previous element+ member e Nothing = False+ member e (Just x) = e == x+ toList Nothing = []+ toList (Just x) = [x]
− test/tests/TypeFam.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,47 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeFamilies #-}---- http://www.mchaver.com/posts/2017-06-21-type-families.html--module TypeFam where--import qualified Data.ByteString.Char8 as BS ()-import Data.ByteString ()-import Data.Monoid ()-import qualified Data.Text as T ()-import Data.Text ( Text )-import Imported.TypeFam ( Concat(cat, type ConcatTy) )---result :: ConcatTy Text String-result = cat ("Hello" :: Text) (" World!" :: String)--main = print result--class Container c where- type Elem c- empty :: c- insert :: Elem c -> c -> c- member :: Elem c -> c -> Bool- toList :: c -> [Elem c]--instance Eq e => Container [e] where- type Elem [e] = e- empty = []- insert e l = (e:l)- member e [] = False- member e (x:xs)- | e == x = True- | otherwise = member e xs- toList l = l--instance Eq e => Container (Maybe e) where- type Elem (Maybe e) = e -- type synonym- empty = Nothing- insert e l = Just e -- destructive, replaces previous element- member e Nothing = False- member e (Just x) = e == x- toList Nothing = []- toList (Just x) = [x]
+ test/tests/TypeFam.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,47 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeFamilies #-}++-- http://www.mchaver.com/posts/2017-06-21-type-families.html++module TypeFam where++import qualified Data.ByteString.Char8 as BS ()+import Data.ByteString ()+import Data.Monoid ()+import qualified Data.Text as T ()+import Data.Text ( Text )+import Imported.TypeFam ( Concat(cat, type ConcatTy) )+++result :: ConcatTy Text String+result = cat ("Hello" :: Text) (" World!" :: String)++main = print result++class Container c where+ type Elem c+ empty :: c+ insert :: Elem c -> c -> c+ member :: Elem c -> c -> Bool+ toList :: c -> [Elem c]++instance Eq e => Container [e] where+ type Elem [e] = e+ empty = []+ insert e l = (e:l)+ member e [] = False+ member e (x:xs)+ | e == x = True+ | otherwise = member e xs+ toList l = l++instance Eq e => Container (Maybe e) where+ type Elem (Maybe e) = e -- type synonym+ empty = Nothing+ insert e l = Just e -- destructive, replaces previous element+ member e Nothing = False+ member e (Just x) = e == x+ toList Nothing = []+ toList (Just x) = [x]
− test/tests/TypeUnused.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.TypeUnused where--foo = not
+ test/tests/TypeUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+module Test.TypeUnused where++foo = not
− test/tests/TypeUnused.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.TypeUnused where--import Data.Bool ()--foo = not
+ test/tests/TypeUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.TypeUnused where++import Data.Bool ()++foo = not
− test/tests/TypeUsed.MinimiseImportsNoExportProcessing-golden
@@ -1,4 +0,0 @@-module Test.TypeUsed where--foo :: Bool-foo = undefined
+ test/tests/TypeUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,4 @@+module Test.TypeUsed where++foo :: Bool+foo = undefined
− test/tests/TypeUsed.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,6 +0,0 @@-module Test.TypeUsed where--import Data.Bool ()--foo :: Bool-foo = undefined
+ test/tests/TypeUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,6 @@+module Test.TypeUsed where++import Data.Bool ()++foo :: Bool+foo = undefined
− test/tests/WildcardUnused.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.WildcardUnused where--foo = not
+ test/tests/WildcardUnused.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+module Test.WildcardUnused where++foo = not
− test/tests/WildcardUnused.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.WildcardUnused where--import Data.Bool ()--foo = not
+ test/tests/WildcardUnused.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.WildcardUnused where++import Data.Bool ()++foo = not
− test/tests/WildcardUsed.MinimiseImportsNoExportProcessing-golden
@@ -1,3 +0,0 @@-module Test.WildcardUsed where--foo = False
+ test/tests/WildcardUsed.MinimiseImportsNoExportProcessingPreludeDataVersion-golden view
@@ -0,0 +1,3 @@+module Test.WildcardUsed where++foo = False
− test/tests/WildcardUsed.PreserveInstanceImportsNoExportProcessing-golden
@@ -1,5 +0,0 @@-module Test.WildcardUsed where--import Data.Bool ()--foo = False
+ test/tests/WildcardUsed.PreserveInstanceImportsNoExportProcessingPrelude-golden view
@@ -0,0 +1,5 @@+module Test.WildcardUsed where++import Data.Bool ()++foo = False