diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2cd314dbf1..3557db1a6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,7 @@ on: - purescript.cabal - Setup.hs - stack.yaml + - stack.yaml.lock - update-changelog.hs - weeder.dhall release: @@ -32,7 +33,7 @@ defaults: env: CI_PRERELEASE: "${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}" CI_RELEASE: "${{ github.event_name == 'release' }}" - STACK_VERSION: "2.15.1" + STACK_VERSION: "3.3.1" concurrency: # We never want two prereleases building at the same time, since they would @@ -53,16 +54,18 @@ jobs: fail-fast: false # do not cancel builds for other OSes if one fails matrix: include: - - # If upgrading the Haskell image, also upgrade it in the lint job below - os: ["ubuntu-latest"] - image: haskell:9.2.8@sha256:b3b2f3909c7381bb96b8f18766f9407a3d6f61e0f07ea95e812583ac4f442cbb - - os: ["macOS-14"] - - os: ["windows-2019"] - - os: ["self-hosted", "macos", "ARM64"] - - os: ["self-hosted", "Linux", "ARM64"] + - image: haskell:9.6.6 # Also upgrade version in the lint job below + os: ubuntu-latest # Exact version is not important, as it's only the container host) + + - image: haskell:9.6.6 + os: ubuntu-24.04-arm # Exact version is not important, as it's only the container host + + - os: macos-13 # x64 + - os: macos-14 # arm64 + - os: windows-2019 # x64 runs-on: "${{ matrix.os }}" - container: "${{ matrix.image }}" + container: "${{ matrix.image }}" outputs: do-not-prerelease: "${{ steps.build.outputs.do-not-prerelease }}" @@ -71,43 +74,40 @@ jobs: steps: - # We need `gh` installed on the Linux version. Otherwise, release artifacts won't be uploaded. name: "(Linux only) Install gh" - if: "contains(matrix.os, 'ubuntu-latest')" + if: startsWith(matrix.image, 'haskell') run: | curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null apt-get update - apt-get install gh + apt-get install -y gh - - uses: "actions/checkout@v2" - - uses: "actions/setup-node@v2" + - uses: "actions/checkout@v4" + - uses: "actions/setup-node@v4" with: - node-version: "16" + node-version: "22" - id: "haskell" name: "(Non-Linux only) Install Haskell" - # Note: here we exclude the self-hosted runners because this action does not work on ARM - # and their Haskell environment is instead provided by a nix-shell - # See https://github.com/purescript/purescript/pulls/4455 - if: "!contains(matrix.os, 'ubuntu-latest') && !contains(matrix.os, 'self-hosted')" + if: startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'windows') uses: "haskell-actions/setup@v2" with: + ghc-version: "9.6.6" enable-stack: true stack-version: "${{ env.STACK_VERSION }}" stack-no-global: true - - name: "(Linux only) Check Stack version and fix working directory ownership" - if: "contains(matrix.os, 'ubuntu-latest')" + - name: "(Linux only) Fix working directory ownership" + if: startsWith(matrix.image, 'haskell') run: | - [ "$(stack --numeric-version)" = "$STACK_VERSION" ] chown root:root . - - uses: "actions/cache@v2" + - uses: "actions/cache@v4" with: path: | /root/.stack ${{ steps.haskell.outputs.stack-root }} - key: "${{ matrix.image || runner.os }}--MdyPsf-${{ hashFiles('stack.yaml') }}" + key: "${{ matrix.image || runner.os }}--MdyPsf-${{ hashFiles('stack.yaml.lock', 'purescript.cabal') }}" - name: "(Windows only) Configure Stack to store its programs in STACK_ROOT" # This ensures that the local GHC and MSYS binaries that Stack installs @@ -122,16 +122,16 @@ jobs: run: "ci/fix-home ci/build.sh" - name: "(Linux only) Glob tests" - if: "contains(matrix.os, 'ubuntu-latest')" + if: startsWith(matrix.image, 'haskell') working-directory: "sdist-test" # We build in this directory in build.sh, so this is where we need to # launch `stack exec`. The actual glob checks happen in a temporary directory. run: | - apt-get install tree + apt-get install -y tree ../ci/fix-home stack exec bash ../glob-test.sh - name: "(Linux only) Build the entire package set" - if: "contains(matrix.os, 'ubuntu-latest')" + if: startsWith(matrix.image, 'haskell') # We build in this directory in build.sh, so this is where we need to # launch `stack exec`. The actual package-set building happens in a # temporary directory. @@ -144,11 +144,11 @@ jobs: # Moreover, npm has a hook issue that will cause spago to fail to install # We upgrade npm to fix this run: | - npm i -g npm@8.8.0 + apt-get install -y jq ../ci/fix-home stack --haddock exec ../ci/build-package-set.sh - name: Verify that 'libtinfo' isn't in binary - if: "runner.os == 'Linux'" + if: runner.os == 'Linux' working-directory: "sdist-test" run: | if [ $(ldd $(../ci/fix-home stack path --local-doc-root)/../bin/purs | grep 'libtinfo' | wc -l) -ge 1 ]; then @@ -157,17 +157,6 @@ jobs: exit 1 fi - - name: "(Self-hosted Linux ARM64 only) Patch the binary to work on non-Nix systems" - if: "runner.os == 'Linux' && runner.arch == 'ARM64'" - working-directory: "sdist-test" - # The self-hosted build happens inside a nix-shell that provides a working stack binary - # on ARM systems, and while the macOS binary is fine - because macOS binaries are almost - # statically linked), the linux ones are all pointing at the nix store. - # So here we first point the binary to the right linker that should work on a generic linux, - # and then fix the RUNPATH with the right location to load the shared libraries from - run: | - patchelf --set-interpreter /usr/lib/ld-linux-aarch64.so.1 --set-rpath /usr/lib/aarch64-linux-gnu $(stack path --local-doc-root)/../bin/purs - - name: "(Release/prerelease only) Create bundle" if: "${{ env.CI_RELEASE == 'true' || env.CI_PRERELEASE == 'true' && steps.build.outputs.do-not-prerelease != 'true' }}" run: | @@ -199,7 +188,7 @@ jobs: - name: "(Prerelease only) Upload bundle" if: "${{ env.CI_PRERELEASE == 'true' && steps.build.outputs.do-not-prerelease != 'true' }}" - uses: "actions/upload-artifact@v3" + uses: "actions/upload-artifact@v4.6.0" with: name: "${{ runner.os }}-${{ runner.arch }}-bundle" path: | @@ -208,59 +197,39 @@ jobs: - name: "(Release only) Publish bundle" if: "${{ env.CI_RELEASE == 'true' }}" - # This requires the gh command line tool to be installed on our - # self-hosted runners env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" run: "gh release upload --clobber ${{ github.ref_name }} sdist-test/bundle/*.{tar.gz,sha}" lint: - runs-on: "ubuntu-latest" - # At the moment, this is a different image from the image used for - # compilation, though the GHC versions match. This is because the - # compilation image uses an old version of glibc, which we want because it - # means our published binaries will work on the widest number of platforms. - # But the HLint binary downloaded by this job requires a newer glibc - # version. - container: haskell:9.2.8@sha256:b3b2f3909c7381bb96b8f18766f9407a3d6f61e0f07ea95e812583ac4f442cbb + container: haskell:9.6.6 + runs-on: ubuntu-latest # Exact version is not important, as it's only the container host steps: - - uses: "actions/checkout@v2" + - uses: "actions/checkout@v4" - name: "Fix working directory ownership" run: | chown root:root . - - uses: "actions/cache@v2" + - uses: "actions/cache@v4" with: path: | /root/.stack - key: "lint-${{ hashFiles('stack.yaml') }}" + key: "lint-${{ hashFiles('stack.yaml.lock', 'purescript.cabal') }}" - run: "ci/fix-home ci/run-hlint.sh --git" env: VERSION: "3.5" - # Note: the weeder version will need to be updated when we next update our version - # of GHC. - # - # weeder-2.2.0 has somewhat strange version deps. It doesn't appear to - # support the exact versions of dhall and generic-lens in LTS-18. - # However, forcing it to use the versions of dhall and generic-lens in - # LTS-18 doesn't cause any problems when building, so the following - # commands build weeder while ignoring version constraints. - name: Install weeder run: | - # The `stack.yaml` file is copied to a separate file so that - # adding `allow-newer: true` doesn't affect any subsequant - # calls to `stack`. - cp stack.yaml stack-weeder.yaml - # `allow-newer: true` is needed so that weeder-2.2.0 can be - # installed with the dependencies present in LTS-18. - echo 'allow-newer: true' >> stack-weeder.yaml - ci/fix-home stack --no-terminal --jobs=2 build --copy-compiler-tool --stack-yaml ./stack-weeder.yaml weeder-2.4.0 + ci/fix-home stack --no-terminal --jobs=2 \ + build --copy-compiler-tool weeder-2.8.0 - - run: "ci/fix-home stack --no-terminal --jobs=2 build --fast --ghc-options -fwrite-ide-info" + - run: | + ci/fix-home stack --no-terminal --jobs=2 \ + build --fast --ghc-options -fwrite-ide-info - run: "ci/fix-home stack exec weeder" @@ -268,26 +237,28 @@ jobs: # reference from our test suite to count in the above check; the fact # that a function is tested is not evidence that it's needed. But we also # don't want to leave weeds lying around in our test suite either. - - run: "ci/fix-home stack --no-terminal --jobs=2 build --fast --test --no-run-tests --ghc-options -fwrite-ide-info" + - run: | + ci/fix-home stack --no-terminal --jobs=2 \ + build --fast --test --no-run-tests --ghc-options -fwrite-ide-info - run: "ci/fix-home stack exec weeder" make-prerelease: - runs-on: "ubuntu-latest" + runs-on: ubuntu-latest needs: - "build" - "lint" if: "${{ github.event_name == 'push' && needs.build.outputs.do-not-prerelease != 'true' }}" steps: - - uses: "actions/download-artifact@v3" + - uses: "actions/download-artifact@v4" - uses: "ncipollo/release-action@v1.10.0" with: tag: "v${{ needs.build.outputs.version }}" artifacts: "*-bundle/*" prerelease: true body: "This is an automated preview release. Get the latest stable release [here](https://github.com/purescript/purescript/releases/latest)." - - uses: "actions/checkout@v3" - - uses: "actions/setup-node@v3" + - uses: "actions/checkout@v4" + - uses: "actions/setup-node@v4" with: node-version: "16.x" registry-url: "https://registry.npmjs.org" diff --git a/.gitignore b/.gitignore index 0454beffcb..73b2b4678f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ bin dist cabal-dev .cabal-sandbox -stack.yaml.lock cabal.sandbox.config dist-newstyle/ cabal.project.local* diff --git a/CHANGELOG.d/internal_upgrade_to_ghc_9.6.md b/CHANGELOG.d/internal_upgrade_to_ghc_9.6.md new file mode 100644 index 0000000000..6622b6baed --- /dev/null +++ b/CHANGELOG.d/internal_upgrade_to_ghc_9.6.md @@ -0,0 +1,2 @@ +* Upgrade GHC to [`9.6.6`](https://downloads.haskell.org/~ghc/9.6.6/docs/users_guide/9.6.6-notes.html), Stackage LTS `22.43` +* Minimum required glibc version is bumped from [`2.28` to `2.31`](https://sourceware.org/glibc/wiki/Glibc%20Timeline) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index aa5ddefd3f..cfbb98e362 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -16,6 +16,7 @@ If you would prefer to use different terms, please use the section below instead | :------- | :--- | :------ | | [@5outh](https://github.com/5outh) | Benjamin Kovach | [MIT license] | | [@actionshrimp](https://github.com/actionshrimp) | David Aitken | [MIT license] | +| [@ad-si](https://github.com/ad-si) | Adrian Sieber | [MIT license] | | [@adnelson](https://github.com/adnelson) | Allen Nelson | [MIT license] | | [@alexbiehl](https://github.com/alexbiehl) | Alexander Biehl | [MIT license] | | [@andreypopp](https://github.com/andreypopp) | Andrey Popp | [MIT license] | diff --git a/INSTALL.md b/INSTALL.md index 0bccc516c7..03f7748636 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -4,12 +4,13 @@ If you are having difficulty installing the PureScript compiler, feel free to as ## Requirements -The PureScript compiler is built using GHC 9.2.8, and should be able to run on any operating system supported by GHC 9.2.8. In particular: +The PureScript compiler is built using GHC 9.6.6, and should be able to run on any operating system supported by GHC 9.6.6. +In particular: * for Windows users, versions predating Vista are not officially supported, * for macOS / OS X users, versions predating Mac OS X 10.7 (Lion) are not officially supported. -See also for more details about the operating systems which GHC 9.2.8 supports. +See also for more details about the operating systems which GHC 9.6.6 supports. ## Official prebuilt binaries diff --git a/LICENSE b/LICENSE index 490ff3651c..713d3371a3 100644 --- a/LICENSE +++ b/LICENSE @@ -107,7 +107,6 @@ PureScript uses the following Haskell library packages. Their license files foll optparse-applicative parallel parsec - pattern-arrows pretty primitive process @@ -3186,29 +3185,6 @@ parsec LICENSE file: negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. -pattern-arrows LICENSE file: - - The MIT License (MIT) - - Copyright (c) 2013 Phil Freeman - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - pretty LICENSE file: This library (libraries/pretty) is derived from code from diff --git a/Makefile b/Makefile index 53da1f3710..91235d9c8f 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ package = purescript exe_target = purs stack_yaml = STACK_YAML="stack.yaml" stack = $(stack_yaml) stack +stack_dir = .stack-work .DEFAULT_GOAL := help @@ -14,6 +15,10 @@ $(bin_dir)/hlint: ci/install-hlint.sh clean: ## Remove build artifacts rm -fr $(bin_dir) rm -fr $(build_dir) + rm -fr $(stack_dir) + rm -fr dist-newstyle + rm -fr .psci_modules + rm -fr .test_modules help: ## Print documentation @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/app/Command/Docs.hs b/app/Command/Docs.hs index 987023c98c..22bd6bdd3f 100644 --- a/app/Command/Docs.hs +++ b/app/Command/Docs.hs @@ -15,7 +15,8 @@ import Language.PureScript.Docs qualified as D import Language.PureScript.Docs.Tags (dumpCtags, dumpEtags) import Language.PureScript.Glob (PSCGlobs(..), toInputGlobs, warnFileTypeNotFound) import Options.Applicative qualified as Opts -import Text.PrettyPrint.ANSI.Leijen qualified as PP +import Prettyprinter qualified as PP +import Prettyprinter.Render.Terminal (AnsiStyle) import SharedCLI qualified import System.Directory (getCurrentDirectory, createDirectoryIfMissing, removeFile) import System.Exit (exitFailure) @@ -113,10 +114,10 @@ defaultOutputForFormat fmt = Ctags -> "tags" pscDocsOptions :: Opts.Parser PSCDocsOptions -pscDocsOptions = - PSCDocsOptions <$> format - <*> output - <*> compileOutputDir +pscDocsOptions = + PSCDocsOptions <$> format + <*> output + <*> compileOutputDir <*> many SharedCLI.inputFile <*> SharedCLI.globInputFile <*> many SharedCLI.excludeFiles @@ -150,9 +151,9 @@ infoModList :: Opts.InfoMod a infoModList = Opts.fullDesc <> footerInfo where footerInfo = Opts.footerDoc $ Just examples -examples :: PP.Doc +examples :: PP.Doc AnsiStyle examples = - PP.vcat $ map PP.text + PP.vcat [ "Examples:" , " write documentation for all modules to ./generated-docs:" , " purs docs \"src/**/*.purs\" \".psc-package/*/*/*/src/**/*.purs\"" diff --git a/app/Command/Ide.hs b/app/Command/Ide.hs index f5a501af75..38fc9c7e36 100644 --- a/app/Command/Ide.hs +++ b/app/Command/Ide.hs @@ -28,7 +28,7 @@ import Data.ByteString.Char8 qualified as BS8 import Data.ByteString.Lazy.Char8 qualified as BSL8 import GHC.IO.Exception (IOErrorType(..), IOException(..)) import Language.PureScript.Ide (handleCommand) -import Language.PureScript.Ide.Command (Command(..), commandName) +import Language.PureScript.Ide.Command (commandName, Command(..)) import Language.PureScript.Ide.Util (decodeT, displayTimeSpec, encodeT, logPerf, runLogger) import Language.PureScript.Ide.Error (IdeError(..)) import Language.PureScript.Ide.State (updateCacheTimestamp) @@ -199,14 +199,22 @@ startServer port env = Network.withSocketsDo $ do logPerf message $ do result <- runExceptT $ do updateCacheTimestamp >>= \case - Nothing -> pure () + Nothing -> + handleCommand cmd' Just (before, after) -> do -- If the cache db file was changed outside of the IDE -- we trigger a reset before processing the command $(logInfo) ("cachedb was changed from: " <> show before <> ", to: " <> show after) - unless (isLoadAll cmd') $ - void (handleCommand Reset *> handleCommand (LoadSync [])) - handleCommand cmd' + let doReload = handleCommand Reset *> handleCommand (LoadSync []) + case cmd' of + -- handleCommand on Load [] already resets the state. + Load [] -> handleCommand cmd' + -- Focus needs to fire before doReload, because we + -- want to set the focused modules first before + -- loading everything with LoadSync []. + Focus _ -> handleCommand cmd' <* doReload + -- Otherwise, just doReload and then handle. + _ -> doReload *> handleCommand cmd' liftIO $ catchGoneHandle $ BSL8.hPutStrLn h $ case result of Right r -> Aeson.encode r Left err -> Aeson.encode err @@ -219,11 +227,6 @@ startServer port env = Network.withSocketsDo $ do hFlush stdout liftIO $ catchGoneHandle (hClose h) -isLoadAll :: Command -> Bool -isLoadAll = \case - Load [] -> True - _ -> False - catchGoneHandle :: IO () -> IO () catchGoneHandle = handle (\e -> case e of diff --git a/app/Main.hs b/app/Main.hs index c925a4a313..ff4e04ab6d 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -13,9 +13,10 @@ import Command.REPL qualified as REPL import Control.Monad (join) import Data.Foldable (fold) import Options.Applicative qualified as Opts +import Prettyprinter qualified as Doc +import Prettyprinter.Render.Terminal (AnsiStyle) import System.Environment (getArgs) import System.IO qualified as IO -import Text.PrettyPrint.ANSI.Leijen qualified as Doc import Version (versionString) @@ -39,11 +40,11 @@ main = do "For example, `purs compile --help` displays options specific to the `compile` command." , Doc.hardline , Doc.hardline - , Doc.text $ "purs " ++ versionString + , Doc.pretty $ "purs " ++ versionString ] - para :: String -> Doc.Doc - para = foldr (Doc.) Doc.empty . map Doc.text . words + para :: String -> Doc.Doc AnsiStyle + para = foldr (\x y -> x <> Doc.softline <> y) mempty . map Doc.pretty . words -- | Displays full command help when invoked with no arguments. execParserPure :: Opts.ParserInfo a -> [String] -> Opts.ParserResult a diff --git a/cabal.project b/cabal.project index 51c7ecb87d..61c5c9bd35 100644 --- a/cabal.project +++ b/cabal.project @@ -1,2 +1,7 @@ packages: purescript.cabal + +source-repository-package + type: git + location: https://github.com/purescript/cheapskate.git + tag: 8bfaf4beeb108e97a274ed51303f278905979e87 diff --git a/ci/build-package-set.sh b/ci/build-package-set.sh index 12a6fcb34c..f11b556871 100755 --- a/ci/build-package-set.sh +++ b/ci/build-package-set.sh @@ -5,7 +5,7 @@ shopt -s nullglob psroot=$(dirname "$(dirname "$(realpath "$0")")") -if [[ "${CI:-}" && "$(echo $psroot/CHANGELOG.d/breaking_*)" ]]; then +if [[ "${CI:-}" && "$(echo "$psroot"/CHANGELOG.d/breaking_*)" ]]; then echo "Skipping package-set build due to unreleased breaking changes" exit 0 fi @@ -16,23 +16,17 @@ export PATH="$tmpdir/node_modules/.bin:$PATH" cd "$tmpdir" echo ::group::Ensure Spago is available -which spago || npm install spago@0.20.8 +which spago || npm install spago@0.93.43 echo ::endgroup:: echo ::group::Create dummy project -echo 'let upstream = https://github.com/purescript/package-sets/releases/download/XXX/packages.dhall in upstream' > packages.dhall -echo '{ name = "my-project", dependencies = [] : List Text, packages = ./packages.dhall, sources = [] : List Text }' > spago.dhall -spago upgrade-set -# Override the `metadata` package's version to match `purs` version -# so that `spago build` actually works -sed -i'' "\$c in upstream with metadata.version = \"v$(purs --version | { read v z && echo $v; })\"" packages.dhall -spago install $(spago ls packages | while read name z; do if [[ $name != metadata ]]; then echo $name; fi; done) +spago init --name purescript-dummy echo ::endgroup:: echo ::group::Compile package set -spago build +spago ls packages --json | jq -r 'keys[]' | xargs spago install echo ::endgroup:: echo ::group::Document package set -spago docs --no-search +spago docs echo ::endgroup:: diff --git a/purescript.cabal b/purescript.cabal index 0d32ce4814..93b02ebbc9 100644 --- a/purescript.cabal +++ b/purescript.cabal @@ -153,18 +153,17 @@ common defaults -- modules must be parseable by this library otherwise the compiler -- will reject them. It should therefore always be pinned to a single -- specific version. - aeson >=2.0.3.0 && <2.1, - aeson-better-errors >=0.9.1.1 && <0.10, - ansi-terminal >=0.11.3 && <0.12, + aeson >=2.0.3.0 && <2.2, + aeson-better-errors >=0.9.1.3 && <0.10, + ansi-terminal >=0.11.3 && <1.1, array >=0.5.4.0 && <0.6, - base >=4.16.2.0 && <4.17, + base >=4.16.2.0 && <4.19, blaze-html >=0.9.1.2 && <0.10, bower-json >=1.1.0.0 && <1.2, boxes >=0.1.5 && <0.2, bytestring >=0.11.3.1 && <0.12, - Cabal >=3.6.3.0 && <3.7, + Cabal >=3.10.3.0 && <3.11, cborg >=0.2.7.0 && <0.3, - serialise >=0.2.5.0 && <0.3, cheapskate >=0.1.1.2 && <0.2, clock >=0.8.3 && <0.9, containers >=0.6.5.1 && <0.7, @@ -177,38 +176,38 @@ common defaults file-embed >=0.0.15.0 && <0.1, filepath >=1.4.2.2 && <1.5, Glob >=0.10.2 && <0.11, - haskeline >=0.8.2 && <0.9, + haskeline ==0.8.2, language-javascript ==0.7.0.0, - lens >=5.1.1 && <5.2, + lens >=5.1.1 && <5.3, lifted-async >=0.10.2.2 && <0.11, lifted-base >=0.2.3.12 && <0.3, - memory >=0.17.0 && <0.18, + memory >=0.17.0 && <0.19, monad-control >=1.0.3.1 && <1.1, monad-logger >=0.3.36 && <0.4, monoidal-containers >=0.6.2.0 && <0.7, - mtl >=2.2.2 && <2.3, + mtl >=2.2.2 && <2.4, parallel >=3.2.2.0 && <3.3, parsec >=3.1.15.0 && <3.2, - pattern-arrows >=0.0.2 && <0.1, - process ==1.6.13.1, + process >=1.6.19.0 && <1.7, protolude >=0.3.1 && <0.4, regex-tdfa >=1.3.1.2 && <1.4, safe >=0.3.19 && <0.4, scientific >=0.3.7.0 && <0.4, + semialign >=1.2.0.1 && <1.4, semigroups ==0.20.*, - semialign >=1.2.0.1 && <1.3, + serialise >=0.2.5.0 && <0.3, sourcemap >=0.1.7 && <0.2, stm >=2.5.0.2 && <2.6, stringsearch >=0.3.6.6 && <0.4, - template-haskell >=2.18.0.0 && <2.19, - text >=1.2.5.0 && <1.3, - these >=1.1.1.1 && <1.2, - time >=1.11.1.1 && <1.12, - transformers >=0.5.6.2 && <0.6, + template-haskell >=2.18.0.0 && <2.21, + text >=1.2.5.0 && <2.1, + these >=1.1.1.1 && <1.3, + time >=1.11.1.1 && <1.13, + transformers >=0.5.6.2 && <0.7, transformers-base >=0.4.6 && <0.5, utf8-string >=1.0.2 && <1.1, - vector >=0.12.3.1 && <0.13, - witherable >=0.4.2 && <0.5 + vector >=0.12.3.1 && <0.14, + witherable >=0.4.2 && <0.5, library import: defaults @@ -217,6 +216,7 @@ library Control.Monad.Logger Control.Monad.Supply Control.Monad.Supply.Class + Control.PatternArrows Language.PureScript Language.PureScript.AST Language.PureScript.AST.Binders @@ -403,10 +403,11 @@ executable purs main-is: Main.hs ghc-options: -fno-warn-unused-do-bind -threaded -rtsopts -with-rtsopts=-N -Wno-unused-packages build-depends: - ansi-wl-pprint >=0.6.9 && <0.7, + prettyprinter >=1.6 && <1.8, + prettyprinter-ansi-terminal >=1.1.1 && <1.2, exceptions >=0.10.4 && <0.11, network >=3.1.2.7 && <3.2, - optparse-applicative >=0.17.0.0 && <0.18, + optparse-applicative >=0.17.0.0 && <0.19, purescript if flag(release) cpp-options: -DRELEASE @@ -440,7 +441,7 @@ test-suite tests build-depends: purescript, generic-random >=1.5.0.1 && <1.6, - hspec >= 2.10.7 && < 3, + hspec >= 2.11.10 && < 3, HUnit >=1.6.2.0 && <1.7, newtype >=0.2.2.0 && <0.3, QuickCheck >=2.14.2 && <2.15, diff --git a/src/Control/Monad/Supply/Class.hs b/src/Control/Monad/Supply/Class.hs index e8656f0c69..b10b42d549 100644 --- a/src/Control/Monad/Supply/Class.hs +++ b/src/Control/Monad/Supply/Class.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE TypeOperators #-} + -- | -- A class for monads supporting a supply of fresh names -- diff --git a/src/Control/PatternArrows.hs b/src/Control/PatternArrows.hs new file mode 100644 index 0000000000..b01d1cccdc --- /dev/null +++ b/src/Control/PatternArrows.hs @@ -0,0 +1,118 @@ +----------------------------------------------------------------------------- +-- +-- Module : Control.PatternArrows +-- Copyright : (c) Phil Freeman 2013 +-- License : MIT +-- +-- Maintainer : Phil Freeman +-- Stability : experimental +-- Portability : +-- +-- | +-- Arrows for Pretty Printing +-- +----------------------------------------------------------------------------- + +{-# LANGUAGE GeneralizedNewtypeDeriving, GADTs #-} + +module Control.PatternArrows where + +import Prelude + +import Control.Arrow ((***), (<+>)) +import Control.Arrow qualified as A +import Control.Category ((>>>)) +import Control.Category qualified as C +import Control.Monad.State +import Control.Monad.Fix (fix) + +-- | +-- A first-order pattern match +-- +-- A pattern is a Kleisli arrow for the @StateT Maybe@ monad. That is, patterns can fail, and can carry user-defined state. +-- +newtype Pattern u a b = Pattern { runPattern :: A.Kleisli (StateT u Maybe) a b } deriving (A.Arrow, A.ArrowZero, A.ArrowPlus) + +instance C.Category (Pattern u) where + id = Pattern C.id + Pattern p1 . Pattern p2 = Pattern (p1 C.. p2) + +instance Functor (Pattern u a) where + fmap f (Pattern p) = Pattern $ A.Kleisli $ fmap f . A.runKleisli p + +-- | +-- Run a pattern with an input and initial user state +-- +-- Returns Nothing if the pattern fails to match +-- +pattern_ :: Pattern u a b -> u -> a -> Maybe b +pattern_ p u = flip evalStateT u . A.runKleisli (runPattern p) + +-- | +-- Construct a pattern from a function +-- +mkPattern :: (a -> Maybe b) -> Pattern u a b +mkPattern f = Pattern $ A.Kleisli (lift . f) + +-- | +-- Construct a pattern from a stateful function +-- +mkPattern' :: (a -> StateT u Maybe b) -> Pattern u a b +mkPattern' = Pattern . A.Kleisli + +-- | +-- Construct a pattern which recursively matches on the left-hand-side +-- +chainl :: Pattern u a (a, a) -> (r -> r -> r) -> Pattern u a r -> Pattern u a r +chainl g f p = fix $ \c -> g >>> ((c <+> p) *** p) >>> A.arr (uncurry f) + +-- | +-- Construct a pattern which recursively matches on the right-hand side +-- +chainr :: Pattern u a (a, a) -> (r -> r -> r) -> Pattern u a r -> Pattern u a r +chainr g f p = fix $ \c -> g >>> (p *** (c <+> p)) >>> A.arr (uncurry f) + +-- | +-- Construct a pattern which recursively matches on one-side of a tuple +-- +wrap :: Pattern u a (s, a) -> (s -> r -> r) -> Pattern u a r -> Pattern u a r +wrap g f p = fix $ \c -> g >>> (C.id *** (c <+> p)) >>> A.arr (uncurry f) + +-- | +-- Construct a pattern which matches a part of a tuple +-- +split :: Pattern u a (s, t) -> (s -> t -> r) -> Pattern u a r +split s f = s >>> A.arr (uncurry f) + +-- | +-- A table of operators +-- +data OperatorTable u a r = OperatorTable { runOperatorTable :: [ [Operator u a r] ] } + +-- | +-- An operator: +-- +-- [@AssocL@] A left-associative operator +-- +-- [@AssocR@] A right-associative operator +-- +-- [@Wrap@] A prefix-like or postfix-like operator +-- +-- [@Split@] A prefix-like or postfix-like operator which does not recurse into its operand +-- +data Operator u a r where + AssocL :: Pattern u a (a, a) -> (r -> r -> r) -> Operator u a r + AssocR :: Pattern u a (a, a) -> (r -> r -> r) -> Operator u a r + Wrap :: Pattern u a (s, a) -> (s -> r -> r) -> Operator u a r + Split :: Pattern u a (s, t) -> (s -> t -> r) -> Operator u a r + +-- | +-- Build a pretty printer from an operator table and an indecomposable pattern +-- +buildPrettyPrinter :: OperatorTable u a r -> Pattern u a r -> Pattern u a r +buildPrettyPrinter table p = foldl (\p' ops -> foldl1 (<+>) (flip map ops $ \case + AssocL pat g -> chainl pat g p' + AssocR pat g -> chainr pat g p' + Wrap pat g -> wrap pat g p' + Split pat g -> split pat g + ) <+> p') p $ runOperatorTable table diff --git a/src/Language/PureScript/CodeGen/JS.hs b/src/Language/PureScript/CodeGen/JS.hs index 14d122a37d..3a4e371187 100644 --- a/src/Language/PureScript/CodeGen/JS.hs +++ b/src/Language/PureScript/CodeGen/JS.hs @@ -9,7 +9,6 @@ module Language.PureScript.CodeGen.JS import Prelude import Protolude (ordNub) -import Control.Applicative (liftA2) import Control.Monad (forM, replicateM, void) import Control.Monad.Except (MonadError, throwError) import Control.Monad.Reader (MonadReader, asks) diff --git a/src/Language/PureScript/CoreImp/Optimizer/TCO.hs b/src/Language/PureScript/CoreImp/Optimizer/TCO.hs index 34746ae3db..a1d4a47c2b 100644 --- a/src/Language/PureScript/CoreImp/Optimizer/TCO.hs +++ b/src/Language/PureScript/CoreImp/Optimizer/TCO.hs @@ -3,7 +3,7 @@ module Language.PureScript.CoreImp.Optimizer.TCO (tco) where import Prelude -import Control.Applicative (empty, liftA2) +import Control.Applicative (empty) import Control.Monad (guard) import Control.Monad.State (State, evalState, get, modify) import Data.Functor (($>), (<&>)) diff --git a/src/Language/PureScript/Docs/RenderedCode/RenderType.hs b/src/Language/PureScript/Docs/RenderedCode/RenderType.hs index a082b4b833..c6a985b09b 100644 --- a/src/Language/PureScript/Docs/RenderedCode/RenderType.hs +++ b/src/Language/PureScript/Docs/RenderedCode/RenderType.hs @@ -233,7 +233,7 @@ renderTypeWithRole = \case renderType' :: PrettyPrintType -> RenderedCode renderType' = fromMaybe (internalError "Incomplete pattern") - . PA.pattern matchType () + . PA.pattern_ matchType () renderTypeVars :: [(TypeVarVisibility, Text, Maybe PrettyPrintType)] -> RenderedCode renderTypeVars tyVars = mintersperse sp (map renderTypeVar tyVars) @@ -252,4 +252,4 @@ renderTypeAtom = renderTypeAtom' . convertPrettyPrintType maxBound renderTypeAtom' :: PrettyPrintType -> RenderedCode renderTypeAtom' = fromMaybe (internalError "Incomplete pattern") - . PA.pattern matchTypeAtom () + . PA.pattern_ matchTypeAtom () diff --git a/src/Language/PureScript/Ide.hs b/src/Language/PureScript/Ide.hs index 57601c3d45..e0ecc4a8f7 100644 --- a/src/Language/PureScript/Ide.hs +++ b/src/Language/PureScript/Ide.hs @@ -22,6 +22,7 @@ import Protolude hiding (moduleName) import "monad-logger" Control.Monad.Logger (MonadLogger, logWarnN) import Data.Map qualified as Map +import Data.Set qualified as Set import Data.Text qualified as T import Language.PureScript qualified as P import Language.PureScript.Glob (toInputGlobs, PSCGlobs(..)) @@ -37,7 +38,7 @@ import Language.PureScript.Ide.Matcher (Matcher) import Language.PureScript.Ide.Prim (idePrimDeclarations) import Language.PureScript.Ide.Rebuild (rebuildFileAsync, rebuildFileSync) import Language.PureScript.Ide.SourceFile (parseModulesFromFiles) -import Language.PureScript.Ide.State (getAllModules, getLoadedModulenames, insertExterns, insertModule, populateVolatileState, populateVolatileStateSync, resetIdeState) +import Language.PureScript.Ide.State (getAllModules, getLoadedModulenames, insertExterns, insertModule, populateVolatileState, populateVolatileStateSync, resetIdeState, setFocusedModules, getFocusedModules) import Language.PureScript.Ide.Types (Annotation(..), Ide, IdeConfiguration(..), IdeDeclarationAnn(..), IdeEnvironment(..), Success(..)) import Language.PureScript.Ide.Util (discardAnn, identifierFromIdeDeclaration, namespaceForDeclaration, withEmptyAnn) import Language.PureScript.Ide.Usage (findUsages) @@ -102,6 +103,8 @@ handleCommand c = case c of rebuildFileAsync file actualFile targets RebuildSync file actualFile targets -> rebuildFileSync file actualFile targets + Focus modulesToFocus -> + setFocusedModules modulesToFocus $> TextResult "Focused modules have been set." Cwd -> TextResult . T.pack <$> liftIO getCurrentDirectory Reset -> @@ -215,10 +218,18 @@ loadModules => [P.ModuleName] -> m Success loadModules moduleNames = do + focusedModules <- getFocusedModules -- We resolve all the modulenames to externs files and load these into memory. oDir <- outputDirectory - let efPaths = - map (\mn -> oDir toS (P.runModuleName mn) P.externsFileName) moduleNames + let + -- But we only load the externs files that are in the focusedModules. + efModules = + if Set.null focusedModules then + moduleNames + else + Set.toList $ Set.fromList moduleNames `Set.intersection` focusedModules + efPaths = + map (\mn -> oDir toS (P.runModuleName mn) P.externsFileName) efModules efiles <- traverse readExternFile efPaths traverse_ insertExterns efiles diff --git a/src/Language/PureScript/Ide/Command.hs b/src/Language/PureScript/Ide/Command.hs index ae4b6c9d8e..49e99a4474 100644 --- a/src/Language/PureScript/Ide/Command.hs +++ b/src/Language/PureScript/Ide/Command.hs @@ -62,6 +62,7 @@ data Command | List { listType :: ListType } | Rebuild FilePath (Maybe FilePath) (Set P.CodegenTarget) | RebuildSync FilePath (Maybe FilePath) (Set P.CodegenTarget) + | Focus [P.ModuleName] | Cwd | Reset | Quit @@ -79,6 +80,7 @@ commandName c = case c of List{} -> "List" Rebuild{} -> "Rebuild" RebuildSync{} -> "RebuildSync" + Focus{} -> "Focus" Cwd{} -> "Cwd" Reset{} -> "Reset" Quit{} -> "Quit" @@ -176,6 +178,13 @@ instance FromJSON Command where <$> params .: "file" <*> params .:? "actualFile" <*> (parseCodegenTargets =<< params .:? "codegen" .!= [ "js" ]) + "focus" -> do + params' <- o .:? "params" + case params' of + Nothing -> + pure (Focus []) + Just params -> + Focus <$> (map P.moduleNameFromString <$> params .:? "modules" .!= []) c -> fail ("Unknown command: " <> show c) where parseCodegenTargets ts = diff --git a/src/Language/PureScript/Ide/State.hs b/src/Language/PureScript/Ide/State.hs index 32478d7000..f11f00ad81 100644 --- a/src/Language/PureScript/Ide/State.hs +++ b/src/Language/PureScript/Ide/State.hs @@ -31,6 +31,9 @@ module Language.PureScript.Ide.State , populateVolatileStateSTM , getOutputDirectory , updateCacheTimestamp + , getFocusedModules + , setFocusedModules + , setFocusedModulesSTM -- for tests , resolveOperatorsForModule , resolveInstances @@ -44,6 +47,7 @@ import Control.Lens (Ixed(..), preview, view, (%~), (.~), (^.)) import "monad-logger" Control.Monad.Logger (MonadLogger, logWarnN) import Data.IORef (readIORef, writeIORef) import Data.Map.Lazy qualified as Map +import Data.Set qualified as Set import Data.Time.Clock (UTCTime) import Data.Zip (unzip) import Language.PureScript qualified as P @@ -61,7 +65,8 @@ import System.Directory (getModificationTime) resetIdeState :: Ide m => m () resetIdeState = do ideVar <- ideStateVar <$> ask - liftIO (atomically (writeTVar ideVar emptyIdeState)) + durableState <- getDurableState + liftIO (atomically (writeTVar ideVar (emptyIdeState { ideDurableState = durableState }))) getOutputDirectory :: Ide m => m FilePath getOutputDirectory = do @@ -141,6 +146,23 @@ setVolatileStateSTM ref vs = do x {ideVolatileState = vs} pure () +-- | Retrieves the DurableState from the State. +getDurableState :: Ide m => m IdeDurableState +getDurableState = do + st <- ideStateVar <$> ask + liftIO (atomically (getDurableStateSTM st)) + +-- | STM version of getDurableState +getDurableStateSTM :: TVar IdeState -> STM IdeDurableState +getDurableStateSTM ref = ideDurableState <$> readTVar ref + +-- | Sets the DurableState inside Ide's state +setDurableStateSTM :: TVar IdeState -> IdeDurableState -> STM () +setDurableStateSTM ref md = do + modifyTVar ref $ \x -> + x {ideDurableState = md} + pure () + -- | Checks if the given ModuleName matches the last rebuild cache and if it -- does returns all loaded definitions + the definitions inside the rebuild -- cache @@ -447,3 +469,17 @@ resolveDataConstructorsForModule decls = & mapMaybe (preview (idaDeclaration . _IdeDeclDataConstructor)) & foldr (\(IdeDataConstructor name typeName type') -> Map.insertWith (<>) typeName [(name, type')]) Map.empty + +getFocusedModules :: Ide m => m (Set P.ModuleName) +getFocusedModules = do + IdeDurableState{drFocusedModules = focusedModules} <- getDurableState + pure focusedModules + +setFocusedModules :: Ide m => [P.ModuleName] -> m () +setFocusedModules modulesToFocus = do + st <- ideStateVar <$> ask + liftIO (atomically (setFocusedModulesSTM st modulesToFocus)) + +setFocusedModulesSTM :: TVar IdeState -> [P.ModuleName] -> STM () +setFocusedModulesSTM ref modulesToFocus = do + setDurableStateSTM ref (IdeDurableState (Set.fromList modulesToFocus)) diff --git a/src/Language/PureScript/Ide/Types.hs b/src/Language/PureScript/Ide/Types.hs index 41532a3c51..e51acc69a0 100644 --- a/src/Language/PureScript/Ide/Types.hs +++ b/src/Language/PureScript/Ide/Types.hs @@ -15,6 +15,7 @@ import Data.Aeson qualified as Aeson import Data.IORef (IORef) import Data.Time.Clock (UTCTime) import Data.Map.Lazy qualified as M +import Data.Set qualified as S import Language.PureScript qualified as P import Language.PureScript.Errors.JSON qualified as P import Language.PureScript.Ide.Filter.Declaration (DeclarationType(..)) @@ -178,10 +179,11 @@ type Ide m = (MonadIO m, MonadReader IdeEnvironment m) data IdeState = IdeState { ideFileState :: IdeFileState , ideVolatileState :: IdeVolatileState + , ideDurableState :: IdeDurableState } deriving (Show) emptyIdeState :: IdeState -emptyIdeState = IdeState emptyFileState emptyVolatileState +emptyIdeState = IdeState emptyFileState emptyVolatileState emptyDurableState emptyFileState :: IdeFileState emptyFileState = IdeFileState M.empty M.empty @@ -189,6 +191,8 @@ emptyFileState = IdeFileState M.empty M.empty emptyVolatileState :: IdeVolatileState emptyVolatileState = IdeVolatileState (AstData M.empty) M.empty Nothing +emptyDurableState :: IdeDurableState +emptyDurableState = IdeDurableState S.empty -- | @IdeFileState@ holds data that corresponds 1-to-1 to an entity on the -- filesystem. Externs correspond to the ExternsFiles the compiler emits into @@ -213,6 +217,15 @@ data IdeVolatileState = IdeVolatileState , vsCachedRebuild :: Maybe (P.ModuleName, P.ExternsFile) } deriving (Show) +-- | @IdeDurableState@ holds data that persists across resets of the @IdeState@. +-- This is particularly useful for configuration variables that can be modified +-- during runtime. For instance, the module names for the "focus" feature are +-- stored in the drFocusedModules field, which the client populates using the +-- @Focus@ command to specify only which modules to load. +data IdeDurableState = IdeDurableState + { drFocusedModules :: Set P.ModuleName + } deriving (Show) + newtype Match a = Match (P.ModuleName, a) deriving (Show, Eq, Functor) diff --git a/src/Language/PureScript/Linter/Exhaustive.hs b/src/Language/PureScript/Linter/Exhaustive.hs index 697fefe8a0..eb03da41e0 100644 --- a/src/Language/PureScript/Linter/Exhaustive.hs +++ b/src/Language/PureScript/Linter/Exhaustive.hs @@ -11,7 +11,6 @@ module Language.PureScript.Linter.Exhaustive import Prelude import Protolude (ordNub) -import Control.Applicative (Applicative(..)) import Control.Arrow (first, second) import Control.Monad (unless) import Control.Monad.Writer.Class (MonadWriter(..)) diff --git a/src/Language/PureScript/Pretty/Types.hs b/src/Language/PureScript/Pretty/Types.hs index 20de0ed9e2..9b3be46937 100644 --- a/src/Language/PureScript/Pretty/Types.hs +++ b/src/Language/PureScript/Pretty/Types.hs @@ -238,7 +238,7 @@ forall_ = mkPattern match typeAtomAsBox' :: PrettyPrintType -> Box typeAtomAsBox' = fromMaybe (internalError "Incomplete pattern") - . PA.pattern (matchTypeAtom defaultOptions) () + . PA.pattern_ (matchTypeAtom defaultOptions) () typeAtomAsBox :: Int -> Type a -> Box typeAtomAsBox maxDepth = typeAtomAsBox' . convertPrettyPrintType maxDepth @@ -280,7 +280,7 @@ unicodeOptions = TypeRenderOptions False True False typeAsBoxImpl :: TypeRenderOptions -> PrettyPrintType -> Box typeAsBoxImpl tro = fromMaybe (internalError "Incomplete pattern") - . PA.pattern (matchType tro) () + . PA.pattern_ (matchType tro) () -- | Generate a pretty-printed string representing a 'Type' prettyPrintType :: Int -> Type a -> String diff --git a/src/Language/PureScript/Sugar/BindingGroups.hs b/src/Language/PureScript/Sugar/BindingGroups.hs index d2f9aebf2b..835e775f81 100644 --- a/src/Language/PureScript/Sugar/BindingGroups.hs +++ b/src/Language/PureScript/Sugar/BindingGroups.hs @@ -114,8 +114,8 @@ createBindingGroups moduleName = mapM f <=< handleDecls valueDeclarationInfo = M.fromList $ swap <$> valueDeclarationKeys findDeclarationInfo i = (M.findWithDefault False i valueDeclarationInfo, i) - computeValueDependencies = (`intersect` valueDeclarationKeys) . fmap findDeclarationInfo . usedIdents moduleName - + computeValueDependencies = (`intersect` valueDeclarationKeys) . fmap findDeclarationInfo . usedIdents moduleName + makeValueDeclarationVert = (,,) <$> id <*> makeValueDeclarationKey <*> computeValueDependencies valueDeclarationVerts = makeValueDeclarationVert <$> values @@ -267,7 +267,7 @@ toDataBindingGroup -> m Declaration toDataBindingGroup (AcyclicSCC (d, _, _)) = return d toDataBindingGroup (CyclicSCC ds') - | Just kds@((ss, _):|_) <- nonEmpty $ concatMap (kindDecl . getDecl) ds' = throwError . errorMessage' ss . CycleInKindDeclaration $ fmap snd kds + | Just kds@((ss, _) :| _) <- nonEmpty $ concatMap (kindDecl . getDecl) ds' = throwError . errorMessage' ss . CycleInKindDeclaration $ fmap snd kds | not (null typeSynonymCycles) = throwError . MultipleErrors diff --git a/src/Language/PureScript/TypeChecker/Monad.hs b/src/Language/PureScript/TypeChecker/Monad.hs index b6382e6707..b33127200d 100644 --- a/src/Language/PureScript/TypeChecker/Monad.hs +++ b/src/Language/PureScript/TypeChecker/Monad.hs @@ -1,4 +1,5 @@ {-# LANGUAGE GADTs #-} +{-# LANGUAGE TypeOperators #-} -- | -- Monads for type checking and type inference and associated data types diff --git a/src/Language/PureScript/TypeChecker/Synonyms.hs b/src/Language/PureScript/TypeChecker/Synonyms.hs index 567ae415ef..8d2cf7886c 100644 --- a/src/Language/PureScript/TypeChecker/Synonyms.hs +++ b/src/Language/PureScript/TypeChecker/Synonyms.hs @@ -1,4 +1,5 @@ {-# LANGUAGE GADTs #-} +{-# LANGUAGE TypeOperators #-} -- | -- Functions for replacing fully applied type synonyms diff --git a/stack.yaml b/stack.yaml index 88b27b1a46..afbac89bca 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,6 +1,6 @@ # Please update Haskell image versions under .github/workflows/ci.yml together to use the same GHC version # (or the CI build will fail) -resolver: lts-20.26 +resolver: lts-22.43 pvp-bounds: both packages: - '.' @@ -13,20 +13,14 @@ extra-deps: # `async` to be used as an object key: # https://github.com/erikd/language-javascript/issues/131 - language-javascript-0.7.0.0 -# Fix issue with libtinfo. -# See https://github.com/purescript/purescript/issues/4253 -- process-1.6.13.1 -# The Cabal library is not in Stackage -- Cabal-3.6.3.0 -# hspec versions 2.9.3 to 2.10.6 depend on ghc -# ghc depends on terminfo by default, but that can be ignored -# if one uses the '-terminfo' flag. -# Unfortunately, hspec doesn't expose a similar flag. -# -# Using hspec >= 2.10.7 addresses this. -- hspec-2.10.9 -- hspec-core-2.10.9 -- hspec-discover-2.10.9 +- bower-json-1.1.0.0 +- haskeline-0.8.2 +- these-1.2.1 +- aeson-better-errors-0.9.1.3 + +- github: purescript/cheapskate + commit: 8bfaf4beeb108e97a274ed51303f278905979e87 + nix: packages: - zlib @@ -37,8 +31,10 @@ nix: flags: aeson-pretty: lib-only: true - these: - assoc: false haskeline: # Avoids a libtinfo dynamic library dependency terminfo: false + +allow-newer: true +allow-newer-deps: +- haskeline diff --git a/stack.yaml.lock b/stack.yaml.lock new file mode 100644 index 0000000000..0af2cebb41 --- /dev/null +++ b/stack.yaml.lock @@ -0,0 +1,58 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/topics/lock_files + +packages: +- completed: + hackage: language-javascript-0.7.0.0@sha256:3eab0262b8ac5621936a4beab6a0f97d0e00a63455a8b0e3ac1547b4088dae7d,3898 + pantry-tree: + sha256: b0f28d836cb3fbde203fd7318a896c3a20acd8653a905e1950ae2d9a64bccebf + size: 2244 + original: + hackage: language-javascript-0.7.0.0 +- completed: + hackage: bower-json-1.1.0.0@sha256:a136aaca67bf0d15c336f5864f7e9d40ebe046ca2cb4b25bc4895617ea35f9f6,1864 + pantry-tree: + sha256: 3acd48e7012f246ad44c7c17cd6340362b1dc448c1d93156280814e76d9e0589 + size: 419 + original: + hackage: bower-json-1.1.0.0 +- completed: + hackage: haskeline-0.8.2@sha256:3b4b594095d64f5fa199b07bdca7d6b790313ed7f380a1b061845507e6563880,6005 + pantry-tree: + sha256: 17ee6b093c5135399b8e6bc3a63d9c6a4b0bc2100b495d2d974bc1464769de39 + size: 2955 + original: + hackage: haskeline-0.8.2 +- completed: + hackage: these-1.2.1@sha256:35c57aede96c15ea1fed559ac287b1168eb2b2869d79e62ed8c845780b7ea136,2294 + pantry-tree: + sha256: dc6366ac715dfdf5338a615f71b9ed0542c403a6afcbedcddbc879e947aea6b3 + size: 351 + original: + hackage: these-1.2.1 +- completed: + hackage: aeson-better-errors-0.9.1.3@sha256:1bfdda3982368cafc7317b9f0c1f7267a6b0bbac9515ae1fad37f2b19178f567,2071 + pantry-tree: + sha256: 1c14247866dfb8052506c179e4725b8a7ce1472a4fb227d61576d862d9494551 + size: 492 + original: + hackage: aeson-better-errors-0.9.1.3 +- completed: + name: cheapskate + pantry-tree: + sha256: a2253619f50d26f0137a802e51e5e7103ee52b1f71bc060d93a0979dcbefa2c8 + size: 12069 + sha256: 959fc7a6ca7e0a743b06b0c287aa4a1c3ec7fc740e5830a4a841d43e925a6d73 + size: 62502 + url: https://github.com/purescript/cheapskate/archive/8bfaf4beeb108e97a274ed51303f278905979e87.tar.gz + version: 0.1.1.2 + original: + url: https://github.com/purescript/cheapskate/archive/8bfaf4beeb108e97a274ed51303f278905979e87.tar.gz +snapshots: +- completed: + sha256: 08bd13ce621b41a8f5e51456b38d5b46d7783ce114a50ab604d6bbab0d002146 + size: 720271 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/43.yaml + original: lts-22.43 diff --git a/update-changelog.hs b/update-changelog.hs index b9296440d4..291160ceca 100755 --- a/update-changelog.hs +++ b/update-changelog.hs @@ -25,7 +25,8 @@ , RecordWildCards , TupleSections , ViewPatterns -#-} + #-} -- Hlint requires this leading space + -- | -- This script updates CHANGELOG.md with the contents of CHANGELOG.d, and -- empties CHANGELOG.d. It takes care of: diff --git a/weeder.dhall b/weeder.dhall deleted file mode 100644 index 95686c45e8..0000000000 --- a/weeder.dhall +++ /dev/null @@ -1,41 +0,0 @@ -{ roots = - [ "^Main\\.main$" - , "^PscIdeSpec\\.main$" - - -- These declarations are used in Pursuit. (The Types declarations are - -- reexported in the L.P.Docs module, and referenced from there, but Weeder - -- isn't that smart.) - , "^Language\\.PureScript\\.Docs\\.AsHtml\\.packageAsHtml$" - , "^Language\\.PureScript\\.Docs\\.Types\\.asUploadedPackage$" - , "^Language\\.PureScript\\.Docs\\.Types\\.getLink$" - , "^Language\\.PureScript\\.Docs\\.Types\\.getLinksContext$" - , "^Language\\.PureScript\\.Docs\\.Types\\.packageName$" - , "^Language\\.PureScript\\.Docs\\.Types\\.verifyPackage$" - - -- These declarations are believed to be used in other projects that we want - -- to continue to support. - , "^Language\\.PureScript\\.CoreFn\\.FromJSON\\.moduleFromJSON$" - , "^Language\\.PureScript\\.CST\\.Print\\.printModule$" - - -- These declarations are there to be used during development or testing. - , "^Language\\.PureScript\\.Ide\\.Imports\\.parseImport$" - , "^Language\\.PureScript\\.TypeChecker\\.Monad\\.debug" - - -- These declarations are used by Template Haskell code. - , "^Language\\.PureScript\\.Constants\\.TH\\." - - -- These declarations are produced by Template Haskell when generating - -- pattern synonyms; this confuses Weeder. - , "^Language\\.PureScript\\.Constants\\..*\\.\\$[bm]" - - -- These declarations are unprincipled exceptions that we don't mind - -- supporting just in case they're used now or in the future. - , "^Language\\.PureScript\\.CST\\.Parser\\.parseExpr$" - - -- These declarations are generated by tools; it doesn't matter if they're - -- unused because we can't do anything about them. - , "^Language\\.PureScript\\.CST\\.Parser\\.happy" - , "^Paths_purescript?\\." - ] -, type-class-roots = True -} diff --git a/weeder.toml b/weeder.toml new file mode 100644 index 0000000000..1a8249a2e2 --- /dev/null +++ b/weeder.toml @@ -0,0 +1,40 @@ +roots = [ + "^Main\\.main$", + "^PscIdeSpec\\.main$", + + # These declarations are used in Pursuit. (The Types declarations are + # reexported in the L.P.Docs module, and referenced from there, but Weeder + # isn't that smart.) + "^Language\\.PureScript\\.Docs\\.AsHtml\\.packageAsHtml$", + "^Language\\.PureScript\\.Docs\\.Types\\.asUploadedPackage$", + "^Language\\.PureScript\\.Docs\\.Types\\.getLink$", + "^Language\\.PureScript\\.Docs\\.Types\\.getLinksContext$", + "^Language\\.PureScript\\.Docs\\.Types\\.packageName$", + "^Language\\.PureScript\\.Docs\\.Types\\.verifyPackage$", + + # These declarations are believed to be used in other projects that we want + # to continue to support. + "^Language\\.PureScript\\.CoreFn\\.FromJSON\\.moduleFromJSON$", + "^Language\\.PureScript\\.CST\\.Print\\.printModule$", + + # These declarations are there to be used during development or testing. + "^Language\\.PureScript\\.Ide\\.Imports\\.parseImport$", + "^Language\\.PureScript\\.TypeChecker\\.Monad\\.debug", + + # These declarations are used by Template Haskell code. + "^Language\\.PureScript\\.Constants\\.TH\\.", + + # These declarations are produced by Template Haskell when generating + # pattern synonyms; this confuses Weeder. + "^Language\\.PureScript\\.Constants\\..*\\.\\$[bm]", + + # These declarations are unprincipled exceptions that we don't mind + # supporting just in case they're used now or in the future. + "^Language\\.PureScript\\.CST\\.Parser\\.parseExpr$", + + # These declarations are generated by tools; it doesn't matter if they're + # unused because we can't do anything about them. + "^Language\\.PureScript\\.CST\\.Parser\\.happy", + "^Paths_purescript?\\.", +] +type-class-roots = true