git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge branch 'pure11-0.9' into pure11
f8cc122Andy Arvanitis
.gitignore+1
@@ -17,3 +17,4 @@ tmp/
17output
17output
18examples/docs/docs/
18examples/docs/docs/
19core-tests/full-core-docs.md
19core-tests/full-core-docs.md
20+.psc-ide-port
.gitmodulesdeleted−3
@@ -1,3 +0,0 @@
1−[submodule "tests/support/prelude"]
2− path = tests/support/prelude
3− url = https://github.com/purescript/purescript-prelude
.travis.yml+72−59
@@ -1,73 +1,86 @@
1language: c
1language: c
2−dist: trusty
2+dist: trusty # because of perf issues
3sudo: required
3sudo: required
4matrix:
4matrix:
5 include:
5 include:
6− - env: GHCVER=7.10.3 CABALVER=1.22 STACKAGE=lts-5.4 RUNSDISTTESTS=YES
6+ # The 'compiler' key is a hack to get Travis to use different caches for
7− compiler: ": #GHC 7.10.3 lts-5.4"
7+ # each job in a build, in order to avoid the separate jobs stomping on each
8− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
8+ # other's caches. See https://github.com/travis-ci/travis-ci/issues/4393
9− - env: GHCVER=7.10.3 CABALVER=1.22 STACKAGE=nightly-2016-02-25
9+ #
10− compiler: ": #GHC 7.10.3 nightly-2016-02-25"
10+ # We use trusty boxes because they seem to be a bit faster.
11− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
11+ - compiler: cc-linux-lts-normal
12− - env: GHCVER=7.10.3 CABALVER=1.22 DEPLOY=yes
12+ os: linux
13+ dist: trusty
14+ sudo: required
15+ env: BUILD_TYPE=normal DEPLOY=true
16+
17+ # - compiler: cc-linux-nightly-normal
18+ # os: linux
19+ # dist: trusty
20+ # sudo: required
21+ # env: BUILD_TYPE=normal STACKAGE_NIGHTLY=true
22+ # allow_failures: true
23+
24+ - compiler: cc-linux-ghc8.0-normal
25+ os: linux
26+ dist: trusty
27+ sudo: required
28+ env: BUILD_TYPE=normal STACK_YAML=stack-ghc-8.0.yaml
29+
30+ - compiler: cc-linux-lts-sdist
31+ os: linux
32+ dist: trusty
33+ sudo: required
34+ env: BUILD_TYPE=sdist COVERAGE=true
35+
13− compiler: ": #GHC 7.10.3"
36+ - compiler: cc-linux-lts-haddock
14− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
37+ os: linux
15−before_install:
38+ dist: trusty
16− - unset CC
39+ sudo: required
17− - export PATH="/opt/ghc/$GHCVER/bin:$PATH"
40+ env: BUILD_TYPE=haddock
18− - export PATH="/opt/cabal/$CABALVER/bin:$PATH"
41+
19− - export PATH="$HOME/.cabal/bin:$PATH"
42+ - compiler: cc-osx-lts-normal
20− - export PATH="/opt/happy/1.19.5/bin:/$PATH"
43+ os: osx
21− - export PATH="/opt/alex/3.1.4/bin:/$PATH"
44+ env: BUILD_TYPE=normal DEPLOY=true
22− - export PATH="$HOME/build/purescript/purescript/dist/build/psc:/$PATH"
45+
23− - export PATH="$HOME/build/purescript/purescript/dist/build/psc-ide-server:/$PATH"
46+ - compiler: cc-osx-lts-sdist
24− - export PATH="$HOME/build/purescript/purescript/dist/build/psc-ide-client:/$PATH"
47+ os: osx
48+ env: BUILD_TYPE=sdist
49+addons:
50+ apt:
51+ packages:
52+ - libgmp-dev
53+cache:
54+ directories:
55+ - $HOME/.local/bin
56+ - $HOME/.stack
25install:
57install:
26− - cabal --version
58+- | # Install stack.
27− - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
59+ if test ! -f "$HOME/.local/bin/stack"
28− - travis_retry cabal update
60+ then
29− # Run sequentially
61+ URL="https://www.stackage.org/stack/$TRAVIS_OS_NAME-x86_64"
30− # Travis container infrastructure seems to expose all host CPUs (16?), thus
62+ curl --location "$URL" > stack.tar.gz
31− # cabal and ghc tries to use them all. Which is bad idea on a shared box.
63+ gunzip stack.tar.gz
32− # See also: https://ghc.haskell.org/trac/ghc/ticket/9221
64+ tar -x -f stack.tar --strip-components 1
33− - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
65+ mkdir -p "$HOME/.local/bin"
34− # Cache sandboxes in ~/cabal-sandboxes
66+ mv stack "$HOME/.local/bin/"
35− # Move right sandbox to .cabal-sandbox if exists
67+ fi
36− - if [ -d ~/cabal-sandboxes/$GHCVER-${STACKAGE:-none} ]; then
37− mv ~/cabal-sandboxes/$GHCVER-${STACKAGE:-none} .cabal-sandbox;
38− fi
39− - mkdir -p .cabal-sandbox
40− - cabal sandbox init --sandbox .cabal-sandbox
41− # Download stackage cabal.config. Filter this package and 'extra deps'
42− - if [ -n "$STACKAGE" ]; then curl https://www.stackage.org/$STACKAGE/cabal.config | egrep -v 'purescript|language-javascript|bower-json' > cabal.config; fi
43− - cabal install --only-dependencies --enable-tests
44− - cabal install hpc-coveralls
45− # Snapshot state of the sandbox now, so we don't need to make new one for test install
46− - rm -rf ~/cabal-sandboxes/$GHCVER-${STACKAGE:-none}
47− - cp -r .cabal-sandbox ~/cabal-sandboxes/$GHCVER-${STACKAGE:-none}
48− # Install bower globally (for psc-docs/psc-publish tests)
68+- npm install -g bower # for psc-docs / psc-publish tests
49− - npm install -g bower
69+# Fix the CC environment variable, because Travis changes it
70+- export CC=gcc
71+- export OS_NAME=$(./travis/convert-os-name.sh)
50script:
72script:
51− - ./travis/configure.sh
73+- travis/build.sh
52− - cabal build --ghc-options="-Werror"
53− - cabal test
54− - ./travis/test-install.sh
55−after_script:
56− - ./travis/after.sh
57−notifications:
58− email: true
59−before_deploy: "./bundle/build.sh linux64"
74+before_deploy:
75+- ./bundle/build.sh $OS_NAME
60deploy:
76deploy:
61 provider: releases
77 provider: releases
62 api_key: $RELEASE_KEY
78 api_key: $RELEASE_KEY
63 file:
79 file:
64− - bundle/linux64.tar.gz
80+ - bundle/$OS_NAME.tar.gz
65− - bundle/linux64.sha
81+ - bundle/$OS_NAME.sha
66 skip_cleanup: true
82 skip_cleanup: true
67 on:
83 on:
68 all_branches: true
84 all_branches: true
69 tags: true
85 tags: true
70− condition: "$DEPLOY = yes"
86+ condition: "$DEPLOY = true"
71−cache:
72− directories:
73− - ~/cabal-sandboxes
CONTRIBUTORS.md+6−3
@@ -12,7 +12,9 @@ This file lists the contributors to the PureScript compiler project, and the ter
12- [@bagl](https://github.com/bagl) (Petr Vapenka) My existing contributions and all future contributions until further notice are Copyright Petr Vapenka, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
12- [@bagl](https://github.com/bagl) (Petr Vapenka) My existing contributions and all future contributions until further notice are Copyright Petr Vapenka, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
13- [@balajirrao](https://github.com/balajirrao) (Balaji Rao) - My existing contributions and all future contributions until further notice are Copyright Balaji Rao, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
13- [@balajirrao](https://github.com/balajirrao) (Balaji Rao) - My existing contributions and all future contributions until further notice are Copyright Balaji Rao, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
14- [@bergmark](https://github.com/bergmark) (Adam Bergmark) - My existing contributions and all future contributions until further notice are Copyright Adam Bergmark, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
14- [@bergmark](https://github.com/bergmark) (Adam Bergmark) - My existing contributions and all future contributions until further notice are Copyright Adam Bergmark, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
15+- [@bmjames](https://github.com/bmjames) (Ben James) My existing contributions and all future contributions until further notice are Copyright Ben James, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
15- [@Bogdanp](https://github.com/Bogdanp) (Bogdan Paul Popa) My existing contributions and all future contributions until further notice are Copyright Bogdan Paul Popa, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
16- [@Bogdanp](https://github.com/Bogdanp) (Bogdan Paul Popa) My existing contributions and all future contributions until further notice are Copyright Bogdan Paul Popa, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
17+- [@bsermons](https://github.com/bsermons) (Brian Sermons) My existing contributions and all future contributions until further notice are Copyright Brian Sermons, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
16- [@cdepillabout](https://github.com/cdepillabout) (Dennis Gosnell) My existing contributions and all future contributions until further notice are Copyright Dennis Gosnell, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
18- [@cdepillabout](https://github.com/cdepillabout) (Dennis Gosnell) My existing contributions and all future contributions until further notice are Copyright Dennis Gosnell, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
17- [@chrissmoak](https://github.com/chrissmoak) (Chris Smoak) My existing contributions to the PureScript compiler and all future contributions to the PureScript compiler until further notice, are Copyright Chris Smoak, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
19- [@chrissmoak](https://github.com/chrissmoak) (Chris Smoak) My existing contributions to the PureScript compiler and all future contributions to the PureScript compiler until further notice, are Copyright Chris Smoak, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
18- [@codedmart](https://github.com/codedmart) (Brandon Martin) My existing contributions and all future contributions until further notice are Copyright Brandon Martin, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
20- [@codedmart](https://github.com/codedmart) (Brandon Martin) My existing contributions and all future contributions until further notice are Copyright Brandon Martin, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -25,8 +27,10 @@ This file lists the contributors to the PureScript compiler project, and the ter
25- [@erdeszt](https://github.com/erdeszt) (Tibor Erdesz) My existing contributions and all future contributions until further notice are Copyright Tibor Erdesz, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
27- [@erdeszt](https://github.com/erdeszt) (Tibor Erdesz) My existing contributions and all future contributions until further notice are Copyright Tibor Erdesz, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
26- [@etrepum](https://github.com/etrepum) (Bob Ippolito) My existing contributions and all future contributions until further notice are Copyright Bob Ippolito, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
28- [@etrepum](https://github.com/etrepum) (Bob Ippolito) My existing contributions and all future contributions until further notice are Copyright Bob Ippolito, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
27- [@faineance](https://github.com/faineance) My existing contributions and all future contributions until further notice are Copyright faineance, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
29- [@faineance](https://github.com/faineance) My existing contributions and all future contributions until further notice are Copyright faineance, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
30+- [@felixSchl](https://github.com/felixSchl) (Felix Schlitter) My existing contributions and all future contributions until further notice are Copyright Felix Schlitter, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
28- [@garyb](https://github.com/garyb) (Gary Burgess) My existing contributions and all future contributions until further notice are Copyright Gary Burgess, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
31- [@garyb](https://github.com/garyb) (Gary Burgess) My existing contributions and all future contributions until further notice are Copyright Gary Burgess, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
29- [@hdgarrood](https://github.com/hdgarrood) (Harry Garrood) My existing contributions and all future contributions until further notice are Copyright Harry Garrood, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
32- [@hdgarrood](https://github.com/hdgarrood) (Harry Garrood) My existing contributions and all future contributions until further notice are Copyright Harry Garrood, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
33+- [@ilovezfs](https://github.com/ilovezfs) - My existing contributions and all future contributions until further notice are Copyright ilovezfs, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license
30- [@izgzhen](https://github.com/izgzhen) (Zhen Zhang) My existing contributions and all future contributions until further notice are Copyright Zhen Zhang, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
34- [@izgzhen](https://github.com/izgzhen) (Zhen Zhang) My existing contributions and all future contributions until further notice are Copyright Zhen Zhang, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
31- [@jacereda](https://github.com/jacereda) (Jorge Acereda) My existing contributions and all future contributions until further notice are Copyright Jorge Acereda, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
35- [@jacereda](https://github.com/jacereda) (Jorge Acereda) My existing contributions and all future contributions until further notice are Copyright Jorge Acereda, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
32- [@japesinator](https://github.com/japesinator) (JP Smith) My existing contributions and all future contributions until further notice are Copyright JP Smith, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
36- [@japesinator](https://github.com/japesinator) (JP Smith) My existing contributions and all future contributions until further notice are Copyright JP Smith, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -35,6 +39,7 @@ This file lists the contributors to the PureScript compiler project, and the ter
35- [@kRITZCREEK](https://github.com/kRITZCREEK) (Christoph Hegemann) - My existing contributions and all future contributions until further notice are Copyright Christoph Hegemann, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
39- [@kRITZCREEK](https://github.com/kRITZCREEK) (Christoph Hegemann) - My existing contributions and all future contributions until further notice are Copyright Christoph Hegemann, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
36- [@L8D](https://github.com/L8D) (Tenor Biel) My existing contributions and all future contributions until further notice are Copyright Tenor Biel, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
40- [@L8D](https://github.com/L8D) (Tenor Biel) My existing contributions and all future contributions until further notice are Copyright Tenor Biel, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
37- [@leighman](http://github.com/leighman) (Jack Leigh) My existing contributions and all future contributions until further notice are Copyright Jack Leigh, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
41- [@leighman](http://github.com/leighman) (Jack Leigh) My existing contributions and all future contributions until further notice are Copyright Jack Leigh, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
42+- [@LiamGoodacre](https://github.com/LiamGoodacre) (Liam Goodacre) My existing contributions and all future contributions until further notice are Copyright Liam Goodacre, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
38- [@lukerandall](https://github.com/lukerandall) (Luke Randall) My existing contributions and all future contributions until further notice are Copyright Luke Randall, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
43- [@lukerandall](https://github.com/lukerandall) (Luke Randall) My existing contributions and all future contributions until further notice are Copyright Luke Randall, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
39- [@mgmeier](https://github.com/mgmeier) (Michael Karg) My existing contributions and all future contributions until further notice are Copyright Michael Gilliland, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
44- [@mgmeier](https://github.com/mgmeier) (Michael Karg) My existing contributions and all future contributions until further notice are Copyright Michael Gilliland, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
40- [@michaelficarra](https://github.com/michaelficarra) (Michael Ficarra) My existing contributions and all future contributions until further notice are Copyright Michael Ficarra, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
45- [@michaelficarra](https://github.com/michaelficarra) (Michael Ficarra) My existing contributions and all future contributions until further notice are Copyright Michael Ficarra, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -58,6 +63,7 @@ This file lists the contributors to the PureScript compiler project, and the ter
58- [@puffnfresh](https://github.com/puffnfresh) (Brian McKenna) All contributions I made during June 2015 were during employment at [SlamData, Inc.](#companies) who owns the copyright. I assign copyright of all my personal contributions before June 2015 to the owners of the PureScript compiler.
63- [@puffnfresh](https://github.com/puffnfresh) (Brian McKenna) All contributions I made during June 2015 were during employment at [SlamData, Inc.](#companies) who owns the copyright. I assign copyright of all my personal contributions before June 2015 to the owners of the PureScript compiler.
59- [@robdaemon](https://github.com/robdaemon) (Robert Roland) My existing contributions and all future contributions until further notice are Copyright Robert Roland, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
64- [@robdaemon](https://github.com/robdaemon) (Robert Roland) My existing contributions and all future contributions until further notice are Copyright Robert Roland, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
60- [@RossMeikleham](https://github.com/RossMeikleham) (Ross Meikleham) My existing contributions and all future contributions until further notice are Copyright Ross Meikleham, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
65- [@RossMeikleham](https://github.com/RossMeikleham) (Ross Meikleham) My existing contributions and all future contributions until further notice are Copyright Ross Meikleham, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
66+- [@rvion](https://github.com/rvion) (Rémi Vion) My existing contributions and all future contributions until further notice are Copyright Rémi Vion, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
61- [@sebastiaanvisser](https://github.com/sebastiaanvisser) (Sebastiaan Visser) - My existing contributions and all future contributions until further notice are Copyright Sebastiaan Visser, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
67- [@sebastiaanvisser](https://github.com/sebastiaanvisser) (Sebastiaan Visser) - My existing contributions and all future contributions until further notice are Copyright Sebastiaan Visser, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
62- [@senju](https://github.com/senju) - My existing contributions and all future contributions until further notice are Copyright senju, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
68- [@senju](https://github.com/senju) - My existing contributions and all future contributions until further notice are Copyright senju, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
63- [@sharkdp](https://github.com/sharkdp) (David Peter) My existing contributions and all future contributions until further notice are Copyright David Peter, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
69- [@sharkdp](https://github.com/sharkdp) (David Peter) My existing contributions and all future contributions until further notice are Copyright David Peter, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -69,9 +75,6 @@ This file lists the contributors to the PureScript compiler project, and the ter
69- [@utkarshkukreti](https://github.com/utkarshkukreti) (Utkarsh Kukreti) My existing contributions and all future contributions until further notice are Copyright Utkarsh Kukreti, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
75- [@utkarshkukreti](https://github.com/utkarshkukreti) (Utkarsh Kukreti) My existing contributions and all future contributions until further notice are Copyright Utkarsh Kukreti, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
70- [@vkorablin](https://github.com/vkorablin) (Vladimir Korablin) - My existing contributions and all future contributions until further notice are Copyright Vladimir Korablin, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
76- [@vkorablin](https://github.com/vkorablin) (Vladimir Korablin) - My existing contributions and all future contributions until further notice are Copyright Vladimir Korablin, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
71- [@zudov](https://github.com/zudov) (Konstantin Zudov) My existing contributions and all future contributions until further notice are Copyright Konstantin Zudov, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
77- [@zudov](https://github.com/zudov) (Konstantin Zudov) My existing contributions and all future contributions until further notice are Copyright Konstantin Zudov, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
72−- [@LiamGoodacre](https://github.com/LiamGoodacre) (Liam Goodacre) My existing contributions and all future contributions until further notice are Copyright Liam Goodacre, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
73−- [@bsermons](https://github.com/bsermons) (Brian Sermons) My existing contributions and all future contributions until further notice are Copyright Brian Sermons, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
74−- [@bmjames](https://github.com/bmjames) (Ben James) My existing contributions and all future contributions until further notice are Copyright Ben James, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
75
78
76### Companies
79### Companies
77
80
LICENSE+270−10
@@ -46,6 +46,7 @@ PureScript uses the following Haskell library packages. Their license files foll
46 bytestring-builder
46 bytestring-builder
47 case-insensitive
47 case-insensitive
48 cereal
48 cereal
49+ clock
49 conduit
50 conduit
50 conduit-extra
51 conduit-extra
51 connection
52 connection
@@ -56,8 +57,10 @@ PureScript uses the following Haskell library packages. Their license files foll
56 deepseq
57 deepseq
57 directory
58 directory
58 dlist
59 dlist
60+ easy-file
59 edit-distance
61 edit-distance
60 exceptions
62 exceptions
63+ fail
61 fast-logger
64 fast-logger
62 filepath
65 filepath
63 fsnotify
66 fsnotify
@@ -82,6 +85,7 @@ PureScript uses the following Haskell library packages. Their license files foll
82 network
85 network
83 network-uri
86 network-uri
84 old-locale
87 old-locale
88+ old-time
85 optparse-applicative
89 optparse-applicative
86 parallel
90 parallel
87 parsec
91 parsec
@@ -91,6 +95,7 @@ PureScript uses the following Haskell library packages. Their license files foll
91 pipes-http
95 pipes-http
92 primitive
96 primitive
93 process
97 process
98+ protolude
94 random
99 random
95 regex-base
100 regex-base
96 regex-tdfa
101 regex-tdfa
@@ -105,6 +110,7 @@ PureScript uses the following Haskell library packages. Their license files foll
105 stm
110 stm
106 stm-chans
111 stm-chans
107 streaming-commons
112 streaming-commons
113+ string-conv
108 syb
114 syb
109 tagged
115 tagged
110 template-haskell
116 template-haskell
@@ -117,6 +123,7 @@ PureScript uses the following Haskell library packages. Their license files foll
117 transformers-compat
123 transformers-compat
118 unix
124 unix
119 unix-compat
125 unix-compat
126+ unix-time
120 unordered-containers
127 unordered-containers
121 utf8-string
128 utf8-string
122 vector
129 vector
@@ -955,6 +962,41 @@ cereal LICENSE file:
955 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
962 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
956 POSSIBILITY OF SUCH DAMAGE.
963 POSSIBILITY OF SUCH DAMAGE.
957
964
965+clock LICENSE file:
966+
967+ Copyright (c) 2009-2012, Cetin Sert
968+ Copyright (c) 2010, Eugene Kirpichov
969+
970+ All rights reserved.
971+
972+ Redistribution and use in source and binary forms, with or without
973+ modification, are permitted provided that the following conditions are
974+ met:
975+
976+ * Redistributions of source code must retain the above copyright
977+ notice, this list of conditions and the following disclaimer.
978+
979+ * Redistributions in binary form must reproduce the above
980+ copyright notice, this list of conditions and the following
981+ disclaimer in the documentation and/or other materials provided
982+ with the distribution.
983+
984+ * The names of contributors may not be used to endorse or promote
985+ products derived from this software without specific prior
986+ written permission.
987+
988+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
989+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
990+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
991+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
992+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
993+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
994+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
995+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
996+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
997+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
998+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
999+
958conduit LICENSE file:
1000conduit LICENSE file:
959
1001
960 Copyright (c) 2012 Michael Snoyman, http://www.yesodweb.com/
1002 Copyright (c) 2012 Michael Snoyman, http://www.yesodweb.com/
@@ -1142,16 +1184,16 @@ data-default-class LICENSE file:
1142 may be used to endorse or promote products derived from this software
1184 may be used to endorse or promote products derived from this software
1143 without specific prior written permission.
1185 without specific prior written permission.
1144
1186
1145− THIS SOFTWARE IS PROVIDED BY LUKAS MAI AND CONTRIBUTORS "AS IS" AND ANY
1187+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1146− EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1188+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1147 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1189 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1148− DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
1190+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
1149− DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1191+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1150− (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1192+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1151− LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1193+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1152− ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1194+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1153− (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1195+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1154− SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1196+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1155
1197
1156deepseq LICENSE file:
1198deepseq LICENSE file:
1157
1199
@@ -1295,6 +1337,38 @@ dlist LICENSE file:
1295 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1337 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1296 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1338 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1297
1339
1340+easy-file LICENSE file:
1341+
1342+ Copyright (c) 2009, IIJ Innovation Institute Inc.
1343+ All rights reserved.
1344+
1345+ Redistribution and use in source and binary forms, with or without
1346+ modification, are permitted provided that the following conditions
1347+ are met:
1348+
1349+ * Redistributions of source code must retain the above copyright
1350+ notice, this list of conditions and the following disclaimer.
1351+ * Redistributions in binary form must reproduce the above copyright
1352+ notice, this list of conditions and the following disclaimer in
1353+ the documentation and/or other materials provided with the
1354+ distribution.
1355+ * Neither the name of the copyright holders nor the names of its
1356+ contributors may be used to endorse or promote products derived
1357+ from this software without specific prior written permission.
1358+
1359+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1360+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1361+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1362+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1363+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
1364+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1365+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1366+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1367+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1368+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
1369+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1370+ POSSIBILITY OF SUCH DAMAGE.
1371+
1298edit-distance LICENSE file:
1372edit-distance LICENSE file:
1299
1373
1300 Copyright (c) 2008-2013 Maximilian Bolingbroke
1374 Copyright (c) 2008-2013 Maximilian Bolingbroke
@@ -1354,6 +1428,39 @@ exceptions LICENSE file:
1354 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1428 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1355 POSSIBILITY OF SUCH DAMAGE.
1429 POSSIBILITY OF SUCH DAMAGE.
1356
1430
1431+fail LICENSE file:
1432+
1433+ Copyright (c) 2015, David Luposchainsky & Herbert Valerio Riedel
1434+
1435+ All rights reserved.
1436+
1437+ Redistribution and use in source and binary forms, with or without
1438+ modification, are permitted provided that the following conditions are met:
1439+
1440+ * Redistributions of source code must retain the above copyright
1441+ notice, this list of conditions and the following disclaimer.
1442+
1443+ * Redistributions in binary form must reproduce the above
1444+ copyright notice, this list of conditions and the following
1445+ disclaimer in the documentation and/or other materials provided
1446+ with the distribution.
1447+
1448+ * Neither the name of Herbert Valerio Riedel nor the names of other
1449+ contributors may be used to endorse or promote products derived
1450+ from this software without specific prior written permission.
1451+
1452+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1453+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1454+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1455+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1456+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1457+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1458+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1459+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1460+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1461+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1462+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1463+
1357fast-logger LICENSE file:
1464fast-logger LICENSE file:
1358
1465
1359 Copyright (c) 2009, IIJ Innovation Institute Inc.
1466 Copyright (c) 2009, IIJ Innovation Institute Inc.
@@ -2122,6 +2229,72 @@ old-locale LICENSE file:
2122
2229
2123 -----------------------------------------------------------------------------
2230 -----------------------------------------------------------------------------
2124
2231
2232+old-time LICENSE file:
2233+
2234+ This library (libraries/base) is derived from code from two
2235+ sources:
2236+
2237+ * Code from the GHC project which is largely (c) The University of
2238+ Glasgow, and distributable under a BSD-style license (see below),
2239+
2240+ * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
2241+ and freely redistributable (but see the full license for
2242+ restrictions).
2243+
2244+ The full text of these licenses is reproduced below. Both of the
2245+ licenses are BSD-style or compatible.
2246+
2247+ -----------------------------------------------------------------------------
2248+
2249+ The Glasgow Haskell Compiler License
2250+
2251+ Copyright 2004, The University Court of the University of Glasgow.
2252+ All rights reserved.
2253+
2254+ Redistribution and use in source and binary forms, with or without
2255+ modification, are permitted provided that the following conditions are met:
2256+
2257+ - Redistributions of source code must retain the above copyright notice,
2258+ this list of conditions and the following disclaimer.
2259+
2260+ - Redistributions in binary form must reproduce the above copyright notice,
2261+ this list of conditions and the following disclaimer in the documentation
2262+ and/or other materials provided with the distribution.
2263+
2264+ - Neither name of the University nor the names of its contributors may be
2265+ used to endorse or promote products derived from this software without
2266+ specific prior written permission.
2267+
2268+ THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
2269+ GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
2270+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
2271+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2272+ UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
2273+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2274+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2275+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2276+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2277+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2278+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
2279+ DAMAGE.
2280+
2281+ -----------------------------------------------------------------------------
2282+
2283+ Code derived from the document "Report on the Programming Language
2284+ Haskell 98", is distributed under the following license:
2285+
2286+ Copyright (c) 2002 Simon Peyton Jones
2287+
2288+ The authors intend this Report to belong to the entire Haskell
2289+ community, and so we grant permission to copy and distribute it for
2290+ any purpose, provided that it is reproduced in its entirety,
2291+ including this Notice. Modified versions of this Report may also be
2292+ copied and distributed for any purpose, provided that the modified
2293+ version is clearly presented as such, and that it does not claim to
2294+ be a definition of the Haskell 98 Language.
2295+
2296+ -----------------------------------------------------------------------------
2297+
2125optparse-applicative LICENSE file:
2298optparse-applicative LICENSE file:
2126
2299
2127 Copyright (c) 2012, Paolo Capriotti
2300 Copyright (c) 2012, Paolo Capriotti
@@ -2276,7 +2449,7 @@ pem LICENSE file:
2276
2449
2277pipes LICENSE file:
2450pipes LICENSE file:
2278
2451
2279− Copyright (c) 2012-2014 Gabriel Gonzalez
2452+ Copyright (c) 2012-2016 Gabriel Gonzalez
2280 All rights reserved.
2453 All rights reserved.
2281
2454
2282 Redistribution and use in source and binary forms, with or without modification,
2455 Redistribution and use in source and binary forms, with or without modification,
@@ -2427,6 +2600,28 @@ process LICENSE file:
2427
2600
2428 -----------------------------------------------------------------------------
2601 -----------------------------------------------------------------------------
2429
2602
2603+protolude LICENSE file:
2604+
2605+ Copyright (c) 2016, Stephen Diehl
2606+
2607+ Permission is hereby granted, free of charge, to any person obtaining a copy
2608+ of this software and associated documentation files (the "Software"), to
2609+ deal in the Software without restriction, including without limitation the
2610+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
2611+ sell copies of the Software, and to permit persons to whom the Software is
2612+ furnished to do so, subject to the following conditions:
2613+
2614+ The above copyright notice and this permission notice shall be included in
2615+ all copies or substantial portions of the Software.
2616+
2617+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2618+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2619+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2620+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2621+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2622+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2623+ IN THE SOFTWARE.
2624+
2430random LICENSE file:
2625random LICENSE file:
2431
2626
2432 This library (libraries/base) is derived from code from two
2627 This library (libraries/base) is derived from code from two
@@ -2873,6 +3068,39 @@ streaming-commons LICENSE file:
2873 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3068 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2874 SOFTWARE.
3069 SOFTWARE.
2875
3070
3071+string-conv LICENSE file:
3072+
3073+ Copyright (c) 2012, Ozgun Ataman
3074+
3075+ All rights reserved.
3076+
3077+ Redistribution and use in source and binary forms, with or without
3078+ modification, are permitted provided that the following conditions are met:
3079+
3080+ * Redistributions of source code must retain the above copyright
3081+ notice, this list of conditions and the following disclaimer.
3082+
3083+ * Redistributions in binary form must reproduce the above
3084+ copyright notice, this list of conditions and the following
3085+ disclaimer in the documentation and/or other materials provided
3086+ with the distribution.
3087+
3088+ * Neither the name of Ozgun Ataman nor the names of other
3089+ contributors may be used to endorse or promote products derived
3090+ from this software without specific prior written permission.
3091+
3092+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3093+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3094+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3095+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3096+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3097+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3098+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3099+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3100+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3101+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3102+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3103+
2876syb LICENSE file:
3104syb LICENSE file:
2877
3105
2878 This library (libraries/syb) is derived from code from several
3106 This library (libraries/syb) is derived from code from several
@@ -3289,6 +3517,38 @@ unix-compat LICENSE file:
3289 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3517 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3290 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3518 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3291
3519
3520+unix-time LICENSE file:
3521+
3522+ Copyright (c) 2009, IIJ Innovation Institute Inc.
3523+ All rights reserved.
3524+
3525+ Redistribution and use in source and binary forms, with or without
3526+ modification, are permitted provided that the following conditions
3527+ are met:
3528+
3529+ * Redistributions of source code must retain the above copyright
3530+ notice, this list of conditions and the following disclaimer.
3531+ * Redistributions in binary form must reproduce the above copyright
3532+ notice, this list of conditions and the following disclaimer in
3533+ the documentation and/or other materials provided with the
3534+ distribution.
3535+ * Neither the name of the copyright holders nor the names of its
3536+ contributors may be used to endorse or promote products derived
3537+ from this software without specific prior written permission.
3538+
3539+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3540+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3541+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
3542+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
3543+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
3544+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
3545+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3546+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3547+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3548+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
3549+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3550+ POSSIBILITY OF SUCH DAMAGE.
3551+
3292unordered-containers LICENSE file:
3552unordered-containers LICENSE file:
3293
3553
3294 Copyright (c) 2010, Johan Tibell
3554 Copyright (c) 2010, Johan Tibell
appveyor.yml+2−8
@@ -3,13 +3,10 @@ version: '{build}'
3environment:
3environment:
4 # Keep the path as short as possible, just in case.
4 # Keep the path as short as possible, just in case.
5 STACK_ROOT: c:\s
5 STACK_ROOT: c:\s
6− # Appveyor does not seem to be able to cope with the symbolic link
7− # stack.yaml, so this is a workaround.
8− STACK_YAML: stack-lts-5.yaml
9 RELEASE_USER: purescript
6 RELEASE_USER: purescript
10 RELEASE_REPO: purescript
7 RELEASE_REPO: purescript
11cache:
8cache:
12−- c:\s
9+- c:\s -> appveyor/cache-buster.txt
13install:
10install:
14- git submodule update --init
11- git submodule update --init
15- ps: Install-Product node 5
12- ps: Install-Product node 5
@@ -31,9 +28,6 @@ build_script:
31test_script:
28test_script:
32- stack -j1 --no-terminal test --pedantic
29- stack -j1 --no-terminal test --pedantic
33on_success:
30on_success:
34−# this seems to be necessary; if omitted, the bash script fails to find the
35−# tool 'strip'.
36−- copy C:\MinGW\bin\strip.exe C:\tools\strip.exe
37- ps: |
31- ps: |
38 function UploadFile
32 function UploadFile
39 {
33 {
@@ -42,7 +36,7 @@ on_success:
42
36
43 if ($env:APPVEYOR_REPO_TAG_NAME)
37 if ($env:APPVEYOR_REPO_TAG_NAME)
44 {
38 {
45− bash ./bundle/build-stack.sh win64
39+ bash ./bundle/build.sh win64
46
40
47 (New-Object Net.WebClient).DownloadFile('https://github.com/aktau/github-release/releases/download/v0.6.2/windows-amd64-github-release.zip', 'c:\tools\github-release.zip')
41 (New-Object Net.WebClient).DownloadFile('https://github.com/aktau/github-release/releases/download/v0.6.2/windows-amd64-github-release.zip', 'c:\tools\github-release.zip')
48 pushd c:\tools
42 pushd c:\tools
appveyor/cache-buster.txtnew file+8
@@ -0,0 +1,8 @@
1+This file acts as a cache buster for the AppVeyor (Windows CI) build
2+cache. In order to invalidate the AppVeyor build cache, simply make a
3+change to the number at the end of this file and commit.
4+
5+See http://www.appveyor.com/docs/build-cache#cache-dependencies for more
6+information.
7+
8+Increment me to invalidate the cache: 0
bundle/build-stack.sh → bundle/build.shrenamed+4−2
@@ -29,8 +29,10 @@ mkdir -p bundle/build/purescript
29for BIN in psc psci psc-docs psc-publish psc-bundle psc-ide-server psc-ide-client
29for BIN in psc psci psc-docs psc-publish psc-bundle psc-ide-server psc-ide-client
30do
30do
31 FULL_BIN="$LOCAL_INSTALL_ROOT/bin/${BIN}${BIN_EXT}"
31 FULL_BIN="$LOCAL_INSTALL_ROOT/bin/${BIN}${BIN_EXT}"
32+ if [ "$OS" != "win64" ]
33+ then
32− strip "$FULL_BIN" || true # not the end of the world if this fails, and
34+ strip "$FULL_BIN"
33− # AppVeyor can't seem to handle it for some reason
35+ fi
34 cp "$FULL_BIN" bundle/build/purescript
36 cp "$FULL_BIN" bundle/build/purescript
35done
37done
36
38
core-tests/.gitignore+1
@@ -1,2 +1,3 @@
1+core-docs.md
1bower_components/
2bower_components/
2output/
3output/
core-tests/bower.jsonnew file+60
@@ -0,0 +1,60 @@
1+{
2+ "name": "core-tests",
3+ "homepage": "https://github.com/purescript/purescript",
4+ "authors": [
5+ "Phil Freeman <paf31@cantab.net>"
6+ ],
7+ "ignore": [
8+ "**/.*",
9+ "node_modules",
10+ "bower_components",
11+ "test",
12+ "tests"
13+ ],
14+ "dependencies": {
15+ "purescript-arrays": "#8c9ada5762",
16+ "purescript-bifunctors": "#9e3b2864ce",
17+ "purescript-console": "#db29da9aca",
18+ "purescript-const": "#cf538a65d8",
19+ "purescript-contravariant": "#9ae6d7c99c",
20+ "purescript-control": "#97096c7e26",
21+ "purescript-distributive": "#ba81c64ffd",
22+ "purescript-eff": "#dbd6c4a415",
23+ "purescript-either": "#54f4efd423",
24+ "purescript-enums": "#9332412e52",
25+ "purescript-exceptions": "#522a0cea50",
26+ "purescript-exists": "#e828c8341e",
27+ "purescript-foldable-traversable": "#df37787855",
28+ "purescript-foreign": "#64890cbbdb",
29+ "purescript-free": "#f8ab7c5f05",
30+ "purescript-functions": "#e417541936",
31+ "purescript-functor-coproducts": "#7654d9dea4",
32+ "purescript-generics": "#d09cb16ca3",
33+ "purescript-globals": "#113ee398be",
34+ "purescript-graphs": "#0b7089afa2",
35+ "purescript-identity": "#204ac5f46a",
36+ "purescript-inject": "#3ae4880bad",
37+ "purescript-integers": "#58d7605dd5",
38+ "purescript-lazy": "#bf4b34d673",
39+ "purescript-maps": "#d9e4c6599a",
40+ "purescript-math": "#99797b6494",
41+ "purescript-maybe": "#1b60a07038",
42+ "purescript-monoid": "#a8c8bb9d73",
43+ "purescript-parallel": "#c7296ab008",
44+ "purescript-prelude": "#318ee857bd",
45+ "purescript-profunctor": "#a649126cea",
46+ "purescript-proxy": "#c494b11bd7",
47+ "purescript-quickcheck": "#4a15c93f12",
48+ "purescript-random": "#68314c21e2",
49+ "purescript-refs": "#f47e1059a3",
50+ "purescript-semirings": "#c40efda15f",
51+ "purescript-sets": "#1eaabf177f",
52+ "purescript-st": "#077d9a2d7e",
53+ "purescript-strings": "#87dd5f1694",
54+ "purescript-tailrec": "#3c11db00ba",
55+ "purescript-transformers": "#2d0a471ce4",
56+ "purescript-tuples": "#4fe689ef93",
57+ "purescript-unfoldable": "#e2382f30d8",
58+ "purescript-validation": "#f43ff0fbdd"
59+ }
60+}
core-tests/test-everything.sh+6−52
@@ -18,62 +18,16 @@ if [ "$force_reinstall" = "true" ] && [ -d "bower_components" ]; then
18 rm -r bower_components
18 rm -r bower_components
19fi
19fi
20
20
21+# todo : fix this once core libraries reach 1.0
21−bower i \
22+yes 1 | bower i
22− purescript-prelude \
23− purescript-eff \
24− purescript-st \
25− purescript-integers \
26− purescript-functions \
27− purescript-console \
28− purescript-profunctor \
29− purescript-contravariant \
30− purescript-parallel \
31− purescript-control \
32− purescript-tailrec \
33− purescript-maps \
34− purescript-free \
35− purescript-transformers \
36− purescript-exists \
37− purescript-monoid \
38− purescript-either \
39− purescript-maybe \
40− purescript-inject \
41− purescript-graphs \
42− purescript-enums \
43− purescript-unfoldable \
44− purescript-coproducts \
45− purescript-lazy \
46− purescript-distributive \
47− purescript-identity \
48− purescript-bifunctors \
49− purescript-const \
50− purescript-sets \
51− purescript-quickcheck \
52− purescript-foreign \
53− purescript-foldable-traversable \
54− purescript-tuples \
55− purescript-strings \
56− purescript-arrays \
57− purescript-random \
58− purescript-refs \
59− purescript-globals \
60− purescript-exceptions \
61− purescript-validation \
62− purescript-parallel \
63− purescript-proxy \
64− purescript-semirings \
65− purescript-math \
66− purescript-generics
67
23
68if [ "$force_recompile" = "true" ] && [ -d "output" ]; then
24if [ "$force_recompile" = "true" ] && [ -d "output" ]; then
69 echo "Recompiling..."
25 echo "Recompiling..."
70 rm -r output
26 rm -r output
71fi
27fi
72
28
73−../dist/build/psc/psc tests/*/*.purs \
74− 'bower_components/purescript-*/src/**/*.purs' \
75− --ffi 'bower_components/purescript-*/src/**/*.js'
29+stack exec psc 'tests/**/*.purs' 'bower_components/purescript-*/src/**/*.purs'
76
30
77−../dist/build/psc-docs/psc-docs tests/*/*.purs \
78− 'bower_components/purescript-*/src/**/*.purs' \
31+stack exec psc-docs 'bower_components/purescript-*/src/**/*.purs' > core-docs.md
79− > full-core-docs.md
32+
33+NODE_PATH=output node -e "require('Test.Main').main()"
core-tests/tests/GenericDeriving.pursnew file+30
@@ -0,0 +1,30 @@
1+module Test.GenericDeriving where
2+
3+import Prelude
4+
5+import Control.Monad.Eff (Eff)
6+import Control.Monad.Eff.Console (CONSOLE, log, logShow)
7+import Data.Generic (class Generic, gShow, gEq)
8+import Partial.Unsafe (unsafePartial)
9+
10+data Empty
11+
12+derive instance genericEmpty :: Partial => Generic Empty
13+
14+data A a
15+ = A Number String
16+ | B Int
17+ | C (Array (A a))
18+ | D { "asgård" :: a }
19+ | E Empty
20+
21+derive instance genericA :: (Partial, Generic b) => Generic (A b)
22+
23+newtype X b = X b
24+
25+derive instance genericX :: Generic (X String)
26+
27+main :: forall eff. Eff (console :: CONSOLE | eff) Unit
28+main = unsafePartial do
29+ log $ gShow (D { "asgård": C [ A 1.0 "test", B 42, D { "asgård": true } ] })
30+ logShow $ gEq (C [B 0]) (C [B 0] :: A Empty)
core-tests/tests/Main.pursnew file+9
@@ -0,0 +1,9 @@
1+module Test.Main where
2+
3+import Prelude
4+import Control.Monad.Eff (Eff)
5+import Control.Monad.Eff.Console (CONSOLE)
6+import Test.GenericDeriving as GenericDeriving
7+
8+main :: forall eff. Eff (console :: CONSOLE | eff) Unit
9+main = GenericDeriving.main
core-tests/tests/generic-deriving/Main.pursdeleted−27
@@ -1,27 +0,0 @@
1−module GenericDeriving where
2−
3−import Prelude
4−
5−import Control.Monad.Eff (Eff())
6−import Control.Monad.Eff.Console (CONSOLE())
7−import Data.Generic
8−
9−data Void
10−
11−derive instance genericVoid :: Generic Void
12−
13−data A a
14− = A Number String
15− | B Int
16− | C (Array (A a))
17− | D { "asgård" :: a }
18− | E Void
19−
20−derive instance genericA :: (Generic b) => Generic (A b)
21−
22−newtype X b = X b
23−
24−derive instance genericX :: Generic (X String)
25−
26−main :: forall eff. Eff (console :: CONSOLE | eff) Unit
27−main = Control.Monad.Eff.Console.log (gShow (D { "asgård": C [ A 1.0 "test", B 42, D { "asgård": true } ] }))
examples/docs/src/Clash.purs−28
@@ -2,31 +2,3 @@ module Clash (module Clash1) where
2
2
3import Clash1 as Clash1
3import Clash1 as Clash1
4import Clash2 as Clash2
4import Clash2 as Clash2
5−
6−module Clash1 (module Clash1a) where
7−
8−import Clash1a
9−
10−module Clash1a where
11−
12−value :: Int
13−value = 0
14−
15−type Type = Int
16−
17−class TypeClass a where
18− typeClassMember :: a
19−
20−module Clash2 (module Clash2a) where
21−
22−import Clash2a
23−
24−module Clash2a where
25−
26−value :: String
27−value = "hello"
28−
29−type Type = String
30−
31−class TypeClass a b where
32− typeClassMember :: a -> b
examples/docs/src/Clash1.pursnew file+3
@@ -0,0 +1,3 @@
1+module Clash1 (module Clash1a) where
2+
3+import Clash1a
examples/docs/src/Clash1a.pursnew file+9
@@ -0,0 +1,9 @@
1+module Clash1a where
2+
3+value :: Int
4+value = 0
5+
6+type Type = Int
7+
8+class TypeClass a where
9+ typeClassMember :: a
examples/docs/src/Clash2.pursnew file+3
@@ -0,0 +1,3 @@
1+module Clash2 (module Clash2a) where
2+
3+import Clash2a
examples/docs/src/Clash2a.pursnew file+9
@@ -0,0 +1,9 @@
1+module Clash2a where
2+
3+value :: String
4+value = "hello"
5+
6+type Type = String
7+
8+class TypeClass a b where
9+ typeClassMember :: a -> b
examples/docs/src/ImportedTwice.purs+4−18
@@ -4,24 +4,10 @@
4-- re-exports it from Control.Monad.Trans).
4-- re-exports it from Control.Monad.Trans).
5
5
6module ImportedTwice
6module ImportedTwice
7− ( module A
7+ ( module ImportedTwiceA
8− , module B
8+ , module ImportedTwiceB
9 )
9 )
10 where
10 where
11
11
12−import A
12+import ImportedTwiceA
13−import B
14−
15−module A
16− ( module B )
17− where
18−
19−import B
13+import ImportedTwiceB
20−
21−bar :: Int
22−bar = 1
23−
24−module B where
25−
26−foo :: Int
27−foo = 0
examples/docs/src/ImportedTwiceA.pursnew file+8
@@ -0,0 +1,8 @@
1+module ImportedTwiceA
2+ ( module ImportedTwiceB )
3+ where
4+
5+import ImportedTwiceB
6+
7+bar :: Int
8+bar = 1
examples/docs/src/ImportedTwiceB.pursnew file+4
@@ -0,0 +1,4 @@
1+module ImportedTwiceB where
2+
3+foo :: Int
4+foo = 0
examples/docs/src/MultiVirtual.purs−21
@@ -4,24 +4,3 @@ module MultiVirtual
4
4
5import MultiVirtual1 as X
5import MultiVirtual1 as X
6import MultiVirtual2 as X
6import MultiVirtual2 as X
7−
8−
9−module MultiVirtual1 where
10−
11−foo :: Int
12−foo = 1
13−
14−module MultiVirtual2
15− ( module MultiVirtual2
16− , module MultiVirtual3
17− ) where
18−
19−import MultiVirtual3
20−
21−bar :: Int
22−bar = 2
23−
24−module MultiVirtual3 where
25−
26−baz :: Int
27−baz = 3
examples/docs/src/MultiVirtual1.pursnew file+4
@@ -0,0 +1,4 @@
1+module MultiVirtual1 where
2+
3+foo :: Int
4+foo = 1
examples/docs/src/MultiVirtual2.pursnew file+9
@@ -0,0 +1,9 @@
1+module MultiVirtual2
2+ ( module MultiVirtual2
3+ , module MultiVirtual3
4+ ) where
5+
6+import MultiVirtual3
7+
8+bar :: Int
9+bar = 2
examples/docs/src/MultiVirtual3.pursnew file+4
@@ -0,0 +1,4 @@
1+module MultiVirtual3 where
2+
3+baz :: Int
4+baz = 3
examples/docs/src/NewOperators.purs−7
@@ -3,10 +3,3 @@ module NewOperators
3 where
3 where
4
4
5import NewOperators2
5import NewOperators2
6−
7−module NewOperators2 where
8−
9−infixl 8 _compose as >>>
10−
11−_compose :: forall a b c. (b -> c) -> (a -> b) -> (a -> c)
12−_compose f g x = f (g x)
examples/docs/src/NewOperators2.pursnew file+6
@@ -0,0 +1,6 @@
1+module NewOperators2 where
2+
3+infixl 8 _compose as >>>
4+
5+_compose :: forall a b c. (b -> c) -> (a -> b) -> (a -> c)
6+_compose f g x = f (g x)
examples/docs/src/OldOperators.pursdeleted−10
@@ -1,10 +0,0 @@
1−
2−-- Remove this after 0.9.
3−module OldOperators (module OldOperators2) where
4−
5−import OldOperators2
6−
7−module OldOperators2 where
8−
9−(>>) :: forall a. a -> a -> a
10−(>>) a b = b
examples/docs/src/TypeClassWithoutMembers.purs+2−8
@@ -1,11 +1,5 @@
1module TypeClassWithoutMembers
1module TypeClassWithoutMembers
2− ( module Intermediate )
2+ ( module TypeClassWithoutMembersIntermediate )
3 where
3 where
4
4
5−import Intermediate
5+import TypeClassWithoutMembersIntermediate
6−
7−module Intermediate
8− ( module SomeTypeClass )
9− where
10−
11−import SomeTypeClass (SomeClass)
examples/docs/src/TypeClassWithoutMembersIntermediate.pursnew file+5
@@ -0,0 +1,5 @@
1+module TypeClassWithoutMembersIntermediate
2+ ( module SomeTypeClass )
3+ where
4+
5+import SomeTypeClass (class SomeClass)
examples/failing/1733.purs+1−8
@@ -1,13 +1,6 @@
1−-- @shouldFailWith UnknownValue
1+-- @shouldFailWith UnknownName
2−
3module Main where
2module Main where
4
3
5import Thingy as Thing
4import Thingy as Thing
6
5
7main = Thing.doesntExist "hi"
6main = Thing.doesntExist "hi"
8−
9−module Thingy where
10−
11−foo :: Int
12−foo = 1
13−
examples/failing/1733/Thingy.pursnew file+4
@@ -0,0 +1,4 @@
1+module Thingy where
2+
3+foo :: Int
4+foo = 1
examples/failing/1825.purs+4−4
@@ -1,9 +1,9 @@
1−-- @shouldFailWith UnknownValue
1+-- @shouldFailWith UnknownName
2
2
3module Main where
3module Main where
4
4
5data W = X | Y | Z
5data W = X | Y | Z
6
6
7−bad X a = a
7+bad X a = a
8−bad Y _ = a
8+bad Y _ = a
9−bad Z a = a
9+bad Z a = a
examples/failing/1881.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith ErrorParsingModule
2+module Main where
3+
4+foo =
5+bar :: Int
6+bar = 3
examples/manual/failing/ArgLengthMismatch.purs → examples/failing/ArgLengthMismatch.pursrenamed+7−6
@@ -1,6 +1,7 @@
1+-- @shouldFailWith ArgListLengthsDiffer
1−module ArgLengthMismatch where
2+module ArgLengthMismatch where
2−
3+
3−import Prelude
4+import Prelude
4−
5+
5−f x y = true
6+f x y = true
6−f = false
7+f = false
examples/failing/Arrays.purs+2−4
@@ -1,8 +1,6 @@
1-- @shouldFailWith TypesDoNotUnify
1-- @shouldFailWith TypesDoNotUnify
2module Main where
2module Main where
3
3
4−import Prelude
4+foreign import ix :: forall a. Array a -> Int -> a
5
5
6−foreign import (!!) :: forall a. Array a -> Int -> a
7−
8−test = \arr -> arr !! (0 !! 0)
6+test = \arr -> arr `ix` (0 `ix` 0)
examples/failing/ConflictingExports.purs−10
@@ -1,14 +1,4 @@
1-- @shouldFailWith ScopeConflict
1-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
12-- Fails here because re-exporting forces any scope conflicts to be resolved
2-- Fails here because re-exporting forces any scope conflicts to be resolved
13module Main (module A, module B) where
3module Main (module A, module B) where
14
4
examples/failing/ConflictingExports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingExports/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/ConflictingImports.purs+5−15
@@ -1,19 +1,9 @@
1-- @shouldFailWith ScopeConflict
1-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
12module Main where
2module Main where
13
3
14− import A
4+import A
15− import B
5+import B
16
6
17− -- Error due to referencing `thing` which is in scope as A.thing and B.thing
7+-- Error due to referencing `thing` which is in scope as A.thing and B.thing
18− what :: Int
8+what :: Int
19− what = thing
9+what = thing
examples/failing/ConflictingImports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingImports/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/ConflictingImports2.purs+6−16
@@ -1,20 +1,10 @@
1-- @shouldFailWith ScopeConflict
1-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
12module Main where
2module Main where
13
3
14− import A (thing)
4+import A (thing)
15− import B (thing)
5+import B (thing)
16
6
17− -- Error due to referencing `thing` which is explicitly in scope as A.thing
7+-- Error due to referencing `thing` which is explicitly in scope as A.thing
18− -- and B.thing
8+-- and B.thing
19− what :: Int
9+what :: Int
20− what = thing
10+what = thing
examples/failing/ConflictingImports2/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingImports2/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/ConflictingQualifiedImports.purs+3−13
@@ -1,17 +1,7 @@
1-- @shouldFailWith ScopeConflict
1-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
12module Main where
2module Main where
13
3
14− import A as X
4+import A as X
15− import B as X
5+import B as X
16
6
17− foo = X.thing
7+foo = X.thing
examples/failing/ConflictingQualifiedImports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingQualifiedImports/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/ConflictingQualifiedImports2.purs+2−12
@@ -1,15 +1,5 @@
1-- @shouldFailWith ScopeConflict
1-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
12module Main (module X) where
2module Main (module X) where
13
3
14− import A as X
4+import A as X
15− import B as X
5+import B as X
examples/failing/ConflictingQualifiedImports2/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingQualifiedImports2/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/DeclConflictClassCtor.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+data T = Fail
5+
6+class Fail
examples/failing/DeclConflictClassSynonym.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+import Prelude
5+
6+type Fail = Unit
7+
8+class Fail
examples/failing/DeclConflictClassType.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+class Fail
5+
6+data Fail
examples/failing/DeclConflictCtorClass.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+class Fail
5+
6+data T = Fail
examples/failing/DeclConflictCtorCtor.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+data T1 = Fail
5+
6+data T2 = Fail
examples/failing/DeclConflictSynonymClass.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+import Prelude
5+
6+class Fail
7+
8+type Fail = Unit
examples/failing/DeclConflictSynonymType.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+import Prelude
5+
6+data Fail
7+
8+type Fail = Unit
examples/failing/DeclConflictTypeClass.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+class Fail
5+
6+data Fail
examples/failing/DeclConflictTypeSynonym.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+import Prelude
5+
6+type Fail = Unit
7+
8+data Fail
examples/failing/DeclConflictTypeType.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+data Fail
5+
6+data Fail
examples/failing/Do.purs+2−2
@@ -8,5 +8,5 @@ test1 = do let x = 1
8
8
9test2 y = do x <- y
9test2 y = do x <- y
10
10
11−test3 = do return 1
11+test3 = do pure 1
12− return 2
12+ pure 2
examples/failing/ExportConflictClass.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictClass/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A where
2+
3+class X
examples/failing/ExportConflictClass/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+class X
examples/failing/ExportConflictCtor.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictCtor/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A where
2+
3+data T1 = X
examples/failing/ExportConflictCtor/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+data T2 = X
examples/failing/ExportConflictType.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictType/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A where
2+
3+data T
examples/failing/ExportConflictType/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+data T
examples/failing/ExportConflictTypeOp.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictTypeOp/A.pursnew file+5
@@ -0,0 +1,5 @@
1+module A where
2+
3+type T1 a b = a -> b
4+
5+infixr 4 type T1 as ??
examples/failing/ExportConflictTypeOp/B.pursnew file+5
@@ -0,0 +1,5 @@
1+module B where
2+
3+type T2 a b = a -> b
4+
5+infixr 4 type T2 as ??
examples/failing/ExportConflictValue.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictValue/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+x :: Boolean
4+x = true
examples/failing/ExportConflictValue/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+x :: Boolean
4+x = false
examples/failing/ExportConflictValueOp.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictValueOp/A.pursnew file+6
@@ -0,0 +1,6 @@
1+module A where
2+
3+f1 :: forall a b. a -> b -> a
4+f1 x _ = x
5+
6+infix 0 f1 as !!
examples/failing/ExportConflictValueOp/B.pursnew file+6
@@ -0,0 +1,6 @@
1+module B where
2+
3+f2 :: forall a b. a -> b -> a
4+f2 x _ = x
5+
6+infix 0 f2 as !!
examples/manual/failing/ExportExplicit.purs → examples/failing/ExportExplicit.pursrenamed+8−7
@@ -1,7 +1,8 @@
1+-- @shouldFailWith UnknownExport
1−-- should fail as z does not exist in the module
2+-- should fail as z does not exist in the module
2−module M1 (x, y, z) where
3+module M1 (x, y, z) where
3−
4+
4−import Prelude
5+import Prelude
5−
6+
6−x = 1
7+x = 1
7−y = 2
8+y = 2
examples/failing/ExportExplicit1.pursnew file+12
@@ -0,0 +1,12 @@
1+-- @shouldFailWith UnknownName
2+module Main where
3+
4+import M1
5+import Control.Monad.Eff.Console (log)
6+
7+testX = X
8+
9+-- should fail as Y constructor is not exported from M1
10+testY = Y
11+
12+main = log "Done"
examples/failing/ExportExplicit1/M1.pursnew file+3
@@ -0,0 +1,3 @@
1+module M1 (X(X)) where
2+
3+data X = X | Y
examples/manual/failing/ExportExplicit2.purs → examples/failing/ExportExplicit2.pursrenamed+8−7
@@ -1,7 +1,8 @@
1+-- @shouldFailWith UnknownExportDataConstructor
1−-- should fail as Y is not a data constructor for X
2+-- should fail as Y is not a data constructor for X
2−module M1 (X(Y)) where
3+module M1 (X(Y)) where
3−
4+
4−import Prelude
5+import Prelude
5−
6+
6−data X = X
7+data X = X
7−data Y = Y
8+data Y = Y
examples/failing/ExportExplicit3.pursnew file+10
@@ -0,0 +1,10 @@
1+-- @shouldFailWith UnknownName
2+module Main where
3+
4+import M1 as M
5+import Control.Monad.Eff.Console (log)
6+
7+-- should fail as Z is not exported from M1
8+testZ = M.Z
9+
10+main = log "Done"
examples/failing/ExportExplicit3/M1.pursnew file+4
@@ -0,0 +1,4 @@
1+module M1 (X(..)) where
2+
3+data X = X | Y
4+data Z = Z
examples/failing/ImportExplicit.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldFailWith UnknownImport
2+module Main where
3+
4+import M1 (X(..))
examples/failing/ImportExplicit/M1.pursnew file+3
@@ -0,0 +1,3 @@
1+module M1 where
2+
3+foo = "foo"
examples/failing/ImportExplicit2.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldFailWith UnknownImportDataConstructor
2+module Main where
3+
4+import M1 (X(Z, Q))
examples/failing/ImportExplicit2/M1.pursnew file+3
@@ -0,0 +1,3 @@
1+module M1 where
2+
3+data X = Y
examples/failing/ImportHidingModule.purs+4−10
@@ -1,10 +1,4 @@
1−-- @shouldFailWith ImportHidingModule
1+-- @shouldFailWith ImportHidingModule
2−module A where
2+module Main where
3− x = 1
3+
4−
5−module B (module B, module A) where
6− import A
7− y = 1
8−
9−module C where
10− import B hiding (module A)
4+import B hiding (module A)
examples/failing/ImportHidingModule/A.pursnew file+2
@@ -0,0 +1,2 @@
1+module A where
2+x = 1
examples/failing/ImportHidingModule/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B (module B, module A) where
2+import A
3+y = 1
examples/failing/ImportModule.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldFailWith UnknownName
2+module Main where
3+
4+import M1
examples/failing/ImportModule/M2.pursnew file+3
@@ -0,0 +1,3 @@
1+module M2 where
2+
3+data X = X
examples/failing/InstanceExport.purs+7−19
@@ -1,19 +1,7 @@
1−-- @shouldFailWith TransitiveExportError
1+-- @shouldFailWith TransitiveExportError
2−module InstanceExport (S(..), f) where
3−
4−import Prelude
5−
6−newtype S = S String
7−
8−class F a where
9− f :: a -> String
10−
11−instance fs :: F S where
12− f (S s) = s
13−
14−module Test where
2+module Test where
15−
3+
16−import InstanceExport
4+import InstanceExport
17−import Prelude
5+import Prelude
18−
6+
19−test = f $ S "Test"
7+test = f $ S "Test"
examples/failing/InstanceExport/InstanceExport.pursnew file+11
@@ -0,0 +1,11 @@
1+module InstanceExport (S(..), f) where
2+
3+import Prelude
4+
5+newtype S = S String
6+
7+class F a where
8+ f :: a -> String
9+
10+instance fs :: F S where
11+ f (S s) = s
examples/failing/MissingClassMemberExport.purs+1−1
@@ -1,5 +1,5 @@
1-- @shouldFailWith TransitiveExportError
1-- @shouldFailWith TransitiveExportError
2−module Test (Foo) where
2+module Test (class Foo) where
3
3
4import Prelude
4import Prelude
5
5
examples/failing/MultipleErrors2.purs+2−2
@@ -1,5 +1,5 @@
1−-- @shouldFailWith UnknownValue
1+-- @shouldFailWith UnknownName
2−-- @shouldFailWith UnknownValue
2+-- @shouldFailWith UnknownName
3module MultipleErrors2 where
3module MultipleErrors2 where
4
4
5import Prelude
5import Prelude
examples/failing/MultipleTypeOpFixities.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldFailWith MultipleTypeOpFixities
2+module MultipleTypeOpFixities where
3+
4+import Prelude
5+
6+type Op x y = Op x y
7+
8+infix 2 type Op as !?
9+infix 2 type Op as !?
examples/failing/MultipleValueOpFixities.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldFailWith MultipleValueOpFixities
2+module MultipleValueOpFixities where
3+
4+import Prelude
5+
6+add x y = x + y
7+
8+infix 2 add as !?
9+infix 2 add as !?
examples/failing/OrphanInstance.purs+7−12
@@ -1,12 +1,7 @@
1−-- @shouldFailWith OrphanInstance
1+-- @shouldFailWith OrphanInstance
2−module Class where
3−
4− class C a where
5− op :: a -> a
6−
7−module Test where
2+module Test where
8−
3+
9− import Class
4+import Class
10−
5+
11− instance cBoolean :: C Boolean where
6+instance cBoolean :: C Boolean where
12− op a = a
7+ op a = a
examples/failing/OrphanInstance/Class.pursnew file+4
@@ -0,0 +1,4 @@
1+module Class where
2+
3+class C a where
4+ op :: a -> a
examples/manual/failing/OrphanTypeDecl.purs → examples/failing/OrphanTypeDecl.pursrenamed+4−3
@@ -1,3 +1,4 @@
1+-- @shouldFailWith OrphanTypeDeclaration
1−module OrphanTypeDecl where
2+module OrphanTypeDecl where
2−
3+
3−fn :: Number -> Boolean
4+fn :: Number -> Boolean
examples/failing/OverlappingReExport.pursdeleted−10
@@ -1,10 +0,0 @@
1−-- @shouldFailWith DuplicateValueExport
2−module A where
3− x = true
4−
5−module B where
6− x = false
7−
8−module C (module A, module M2) where
9− import A
10− import qualified B as M2
examples/failing/ProgrammableTypeErrors.pursnew file+16
@@ -0,0 +1,16 @@
1+-- @shouldFailWith NoInstanceFound
2+
3+module Main where
4+
5+import Prelude
6+import Control.Monad.Eff (Eff)
7+import Control.Monad.Eff.Console (log)
8+
9+class MyShow a where
10+ myShow :: a -> String
11+
12+instance cannotShowFunctions :: Fail "Cannot show functions" => MyShow (a -> b) where
13+ myShow _ = "unreachable"
14+
15+main :: Eff _ _
16+main = log (myShow (_ + 1))
examples/manual/failing/RequiredHiddenType.purs → examples/failing/RequiredHiddenType.pursrenamed+9−8
@@ -1,8 +1,9 @@
1+-- @shouldFailWith TransitiveExportError
1−-- exporting `a` should fail as `A` is hidden
2+-- exporting `a` should fail as `A` is hidden
2−module Foo (B(..), a, b) where
3+module Foo (B(..), a, b) where
3−
4+
4−data A = A
5+data A = A
5−data B = B
6+data B = B
6−
7+
7−a = A
8+a = A
8−b = B
9+b = B
examples/failing/RowConstructors1.purs+2−2
@@ -1,9 +1,9 @@
1-- @shouldFailWith KindsDoNotUnify
1-- @shouldFailWith KindsDoNotUnify
2module Main where
2module Main where
3
3
4−import Prelude
4+import Control.Monad.Eff.Console (log)
5
5
6data Foo = Bar
6data Foo = Bar
7type Baz = { | Foo }
7type Baz = { | Foo }
8
8
9−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/failing/RowConstructors2.purs+2−2
@@ -1,9 +1,9 @@
1-- @shouldFailWith KindsDoNotUnify
1-- @shouldFailWith KindsDoNotUnify
2module Main where
2module Main where
3
3
4−import Prelude
4+import Control.Monad.Eff.Console (log)
5
5
6type Foo r = (x :: Number | r)
6type Foo r = (x :: Number | r)
7type Bar = { | Foo }
7type Bar = { | Foo }
8
8
9−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/failing/RowConstructors3.purs+2−2
@@ -1,9 +1,9 @@
1-- @shouldFailWith KindsDoNotUnify
1-- @shouldFailWith KindsDoNotUnify
2module Main where
2module Main where
3
3
4−import Prelude
4+import Control.Monad.Eff.Console (log)
5
5
6type Foo = { x :: Number }
6type Foo = { x :: Number }
7type Bar = { | Foo }
7type Bar = { | Foo }
8
8
9−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/failing/SkolemEscape2.purs+1−1
@@ -7,4 +7,4 @@ import Control.Monad.ST
7
7
8test _ = do
8test _ = do
9 r <- runST (newSTRef 0)
9 r <- runST (newSTRef 0)
10− return 0
10+ pure 0
examples/failing/SuggestComposition.purs+1−1
@@ -4,4 +4,4 @@ module SuggestComposition where
4
4
5import Prelude
5import Prelude
6
6
7−f = g . g where g = (+1)
7+f = g . g where g = (_ + 1)
examples/failing/Superclasses5.purs+2−1
@@ -3,6 +3,7 @@
3module Main where
3module Main where
4
4
5import Prelude
5import Prelude
6+import Control.Monad.Eff.Console (logShow)
6
7
7class Su a where
8class Su a where
8 su :: a -> a
9 su :: a -> a
@@ -22,4 +23,4 @@ instance clNumber :: Cl Number where
22test :: forall a. (Cl a) => a -> Array a
23test :: forall a. (Cl a) => a -> Array a
23test x = su [cl x x]
24test x = su [cl x x]
24
25
25−main = Control.Monad.Eff.Console.print $ test 10.0
26+main = logShow $ test 10.0
examples/failing/TypeError.purs+1−1
@@ -3,4 +3,4 @@ module Main where
3
3
4import Prelude
4import Prelude
5
5
6−test = 1 ++ "A"
6+test = 1 <> "A"
examples/failing/TypedBinders.purs+3−3
@@ -1,10 +1,10 @@
1−-- @shouldFailWith ErrorParsingModule
1+-- @shouldFailWith ErrorParsingModule
2module Main where
2module Main where
3
3
4−import Prelude
4+import Control.Monad.Eff.Console (log)
5
5
6test = (\f :: Int -> Int -> f 10) id
6test = (\f :: Int -> Int -> f 10) id
7
7
8main = do
8main = do
9 let t1 = test
9 let t1 = test
10− Control.Monad.Eff.Console.log "Done"
10+ log "Done"
examples/failing/TypedBinders2.purs+3−3
@@ -2,8 +2,8 @@
2module Main where
2module Main where
3
3
4import Prelude
4import Prelude
5+import Control.Monad.Eff.Console (log)
5
6
6main = do
7main = do
7− s :: String <- Control.Monad.Eff.Console.log "Foo"
8+ s :: String <- log "Foo"
8− Control.Monad.Eff.Console.log "Done"
9+ log "Done"
9−
examples/failing/TypedBinders3.purs+2−1
@@ -2,6 +2,7 @@
2module Main where
2module Main where
3
3
4import Prelude
4import Prelude
5+import Control.Monad.Eff.Console (log)
5
6
6test = case 1 of
7test = case 1 of
7 (0 :: String) -> true
8 (0 :: String) -> true
@@ -9,4 +10,4 @@ test = case 1 of
9
10
10main = do
11main = do
11 let t = test
12 let t = test
12− Control.Monad.Eff.Console.log "Done"
13+ log "Done"
examples/failing/UnderscoreModuleName.purs+2−2
@@ -1,6 +1,6 @@
1-- @shouldFailWith ErrorParsingModule
1-- @shouldFailWith ErrorParsingModule
2module Bad_Module where
2module Bad_Module where
3
3
4−import Prelude
4+import Control.Monad.Eff.Console (log)
5
5
6−main = Control.Monad.Eff.Console.log "Done"
6+main = log "Done"
examples/failing/UnknownType.purs+1−1
@@ -1,4 +1,4 @@
1−-- @shouldFailWith UnknownType
1+-- @shouldFailWith UnknownName
2module Main where
2module Main where
3
3
4import Prelude
4import Prelude
examples/manual/QualifiedNames.pursdeleted−13
@@ -1,13 +0,0 @@
1−module Data.Either where
2−
3−import Prelude
4−
5−data Either a b = Left a | Right b
6−
7−module Main where
8−
9−either :: forall a b c. (a -> c) -> (b -> c) -> Data.Either.Either a b -> c
10−either f _ (Data.Either.Left x) = f x
11−either _ g (Data.Either.Right y) = g y
12−
13−main = Control.Monad.Eff.Console.log (either id id (Data.Either.Left "Done"))
examples/manual/failing/ExportExplicit1.pursdeleted−14
@@ -1,14 +0,0 @@
1−module M1 (X(X)) where
2−
3− data X = X | Y
4−
5−module Main where
6−
7− import M1
8−
9− testX = X
10−
11− -- should fail as Y constructor is not exported from M1
12− testY = Y
13−
14− main = Control.Monad.Eff.Console.log "Done"
examples/manual/failing/ExportExplicit3.pursdeleted−13
@@ -1,13 +0,0 @@
1−module M1 (X(..)) where
2−
3− data X = X | Y
4− data Z = Z
5−
6−module Main where
7−
8− import M1
9−
10− -- should fail as Z is not exported from M1
11− testZ = M1.Z
12−
13− main = Control.Monad.Eff.Console.log "Done"
examples/manual/failing/ImportExplicit.pursdeleted−7
@@ -1,7 +0,0 @@
1−module M1 where
2−
3− foo = "foo"
4−
5−module Main where
6−
7− import M1 (X(..))
examples/manual/failing/ImportExplicit2.pursdeleted−7
@@ -1,7 +0,0 @@
1−module M1 where
2−
3− data X = Y
4−
5−module Main where
6−
7− import M1 (X(Z, Q))
examples/manual/failing/ImportModule.pursdeleted−7
@@ -1,7 +0,0 @@
1−module M2 where
2−
3− data X = X
4−
5−module Main where
6−
7− import M1
examples/manual/failing/RedefinedFixity.pursdeleted−8
@@ -1,8 +0,0 @@
1−module RedefinedFixity where
2−
3−import Prelude
4−
5−(!?) x y = x + y
6−
7−infix 2 !?
8−infix 2 !?
examples/manual/passing/ExportExplicit.pursdeleted−20
@@ -1,20 +0,0 @@
1−module M1 (X(X), Z(..), foo) where
2−
3− data X = X | Y
4− data Z = Z
5−
6− foo :: Number
7− foo = 0
8−
9− bar :: Number
10− bar = 1
11−
12−module Main where
13−
14− import M1
15−
16− testX = X
17− testZ = Z
18− testFoo = foo
19−
20− main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/ExportExplicit2.pursdeleted−15
@@ -1,15 +0,0 @@
1−module M1 (bar) where
2−
3− foo :: Number
4− foo = 0
5−
6− bar :: Number
7− bar = foo
8−
9−module Main where
10−
11− import M1
12−
13− testBar = bar
14−
15− main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/Import.pursdeleted−19
@@ -1,19 +0,0 @@
1−module M1 where
2−
3− import Prelude ()
4−
5− id :: forall a. a -> a
6− id = \x -> x
7−
8− foo = id
9−
10−module M2 where
11−
12− import Prelude ()
13− import M1
14−
15− main = \_ -> foo 42
16−
17−module Main where
18−
19−main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/ImportExplicit.pursdeleted−14
@@ -1,14 +0,0 @@
1−module M1 where
2−
3− data X = X | Y
4− data Z = Z
5−
6−module Main where
7−
8− import M1 (X(..))
9−
10− testX :: X
11− testX = X
12− testY = Y
13−
14− main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/ImportQualified.pursdeleted−12
@@ -1,12 +0,0 @@
1−module M1 where
2−
3− log x = x
4−
5−module Main where
6−
7− import Prelude
8− import Control.Monad.Eff
9− import M1
10− import qualified Control.Monad.Eff.Console as C
11−
12− main = C.log (log "Done")
examples/manual/passing/Module.pursdeleted−28
@@ -1,28 +0,0 @@
1−module M1 where
2−
3− import Prelude
4−
5− data Foo = Foo String
6−
7− foo :: M1.Foo -> String
8− foo = \f -> case f of Foo s -> s ++ "foo"
9−
10− bar :: Foo -> String
11− bar = foo
12−
13− incr :: Number -> Number
14− incr x = x + 1
15−
16−module M2 where
17−
18− import Prelude
19−
20− baz :: M1.Foo -> String
21− baz = M1.foo
22−
23− match :: M1.Foo -> String
24− match = \f -> case f of M1.Foo s -> s ++ "foo"
25−
26−module Main where
27−
28−main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/ModuleDeps.pursdeleted−17
@@ -1,17 +0,0 @@
1−module M1 where
2−
3−import M2
4−
5−foo = M3.baz
6−
7−module M2 where
8−
9−bar = M3.baz
10−
11−module M3 where
12−
13−baz = 1
14−
15−module Main where
16−
17−main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/RedefinedFixity.pursdeleted−24
@@ -1,24 +0,0 @@
1−module M1 where
2−
3−import Prelude ()
4−
5−($) f a = f a
6−
7−infixr 1000 $
8−
9−module M2 where
10−
11−import Prelude ()
12−
13−import M1
14−
15−module M3 where
16−
17−import Prelude ()
18−
19−import M1
20−import M2
21−
22−module Main where
23−
24−main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/TransitiveImport.pursdeleted−24
@@ -1,24 +0,0 @@
1−module Test where
2−
3− import Prelude
4−
5− class TestCls a where
6− test :: a -> a
7−
8− instance unitTestCls :: TestCls Unit where
9− test _ = unit
10−
11−module Middle where
12−
13− middle = Test.test
14−
15−module Main where
16−
17− import Prelude
18− import Middle
19− import Control.Monad.Eff.Console
20−
21− main = do
22− print (middle unit)
23− trace "Done"
24− return unit
examples/passing/1185.purs+3−1
@@ -1,5 +1,7 @@
1module Main where
1module Main where
2
2
3+import Control.Monad.Eff.Console (log)
4+
3data Person = Person String Boolean
5data Person = Person String Boolean
4
6
5getName :: Person -> String
7getName :: Person -> String
@@ -10,4 +12,4 @@ getName p = case p of
10name :: String
12name :: String
11name = getName (Person "John Smith" true)
13name = getName (Person "John Smith" true)
12
14
13−main = Control.Monad.Eff.Console.log "Done"
15+main = log "Done"
examples/passing/1335.purs+14−12
@@ -1,12 +1,14 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−import Control.Monad.Eff.Console (log)
4+import Control.Monad.Eff.Console (log)
5−
5+
6−x :: forall a. a -> String
6+x :: forall a. a -> String
7−x a = y "Done"
7+x a = y "Test"
8− where
8+ where
9− y :: forall a. (Show a) => a -> String
9+ y :: forall a. (Show a) => a -> String
10− y a = show (a :: a)
10+ y a = show (a :: a)
11−
11+
12+main = do
12−main = log (x 0)
13+ log (x 0)
14+ log "Done"
examples/passing/1570.purs+3−1
@@ -1,6 +1,8 @@
1module Main where
1module Main where
2
2
3+import Control.Monad.Eff.Console (log)
4+
3test :: forall a. a -> a
5test :: forall a. a -> a
4test = \(x :: a) -> x
6test = \(x :: a) -> x
5
7
6−main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/passing/1664.purs+1−1
@@ -11,6 +11,6 @@ newtype IdentityEff e a = IdentityEff (Eff e (Identity a))
11test :: forall e a. IdentityEff e a -> IdentityEff e Unit
11test :: forall e a. IdentityEff e a -> IdentityEff e Unit
12test (IdentityEff action) = IdentityEff $ do
12test (IdentityEff action) = IdentityEff $ do
13 (Identity x :: Identity _) <- action
13 (Identity x :: Identity _) <- action
14− return $ Identity unit
14+ pure $ Identity unit
15
15
16main = log "Done"
16main = log "Done"
examples/passing/1697.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5_2 :: forall a. a -> a
6_2 :: forall a. a -> a
6_2 a = a
7_2 a = a
@@ -21,4 +22,4 @@ wtf = do
21 let tmp = _2 1
22 let tmp = _2 1
22 pure unit
23 pure unit
23
24
24−main = Control.Monad.Eff.Console.log "Done"
25+main = log "Done"
examples/passing/1881.pursnew file+19
@@ -0,0 +1,19 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console (log)
4+
5+foo =
6+ 1
7+
8+bar
9+ = 2
10+
11+baz
12+ =
13+ 3
14+
15+qux
16+ =
17+ 3
18+
19+main = log "Done"
examples/passing/1991.purs+4−2
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5singleton :: forall a. a -> Array a
6singleton :: forall a. a -> Array a
6singleton x = [x]
7singleton x = [x]
@@ -10,11 +11,12 @@ empty = []
10
11
11foldMap :: forall a m. (Semigroup m) => (a -> m) -> Array a -> m
12foldMap :: forall a m. (Semigroup m) => (a -> m) -> Array a -> m
12foldMap f [a, b, c, d, e] = f a <> f b <> f c <> f d <> f e
13foldMap f [a, b, c, d, e] = f a <> f b <> f c <> f d <> f e
14+foldMap f xs = foldMap f xs -- spin, not used
13
15
14regression :: Array Int
16regression :: Array Int
15regression =
17regression =
16 let as = [1,2,3,4,5]
18 let as = [1,2,3,4,5]
17 as' = foldMap (\x -> if 1 < x && x < 4 then singleton x else empty) as
19 as' = foldMap (\x -> if 1 < x && x < 4 then singleton x else empty) as
18 in as'
20 in as'
19−
21+
20−main = Control.Monad.Eff.Console.log "Done"
22+main = log "Done"
examples/passing/2018.purs−13
@@ -1,15 +1,3 @@
1−module B where
2−
3− data Foo = X | Y
4−
5−module A where
6−
7− import B as Main
8−
9− -- Prior to the 2018 fix this would be detected as a cycle between A and Main.
10− foo ∷ Main.Foo → Main.Foo
11− foo x = x
12−
13module Main where
1module Main where
14
2
15import Prelude
3import Prelude
@@ -22,4 +10,3 @@ main :: forall e. Eff (console :: CONSOLE | e) Unit
22main = do
10main = do
23 let tmp = foo X
11 let tmp = foo X
24 log "Done"
12 log "Done"
25−
examples/passing/2018/A.pursnew file+7
@@ -0,0 +1,7 @@
1+module A where
2+
3+import B as Main
4+
5+-- Prior to the 2018 fix this would be detected as a cycle between A and Main.
6+foo ∷ Main.Foo → Main.Foo
7+foo x = x
examples/passing/2018/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+data Foo = X | Y
examples/passing/2049.pursnew file+14
@@ -0,0 +1,14 @@
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+data List a = Cons a (List a) | Nil
7+
8+infixr 6 Cons as :
9+
10+f :: List { x :: Int, y :: Int } -> Int
11+f ( r@{ x } : _) = x + r.y
12+f _ = 0
13+
14+main = log "Done"
examples/passing/2138.pursnew file+7
@@ -0,0 +1,7 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console (log)
4+
5+import Lib (A(B,C))
6+
7+main = log "Done"
examples/passing/2138/Lib.pursnew file+3
@@ -0,0 +1,3 @@
1+module Lib (A(..), A) where
2+
3+data A = B | C
examples/passing/2172.jsnew file+5
@@ -0,0 +1,5 @@
1+exports['a\''] = 0;
2+exports["\x62\x27"] = 1;
3+// NOTE: I wanted to use "\c'" here, but langauge-javascript doesn't support it...
4+exports["c'"] = 2;
5+exports["\u0064\u0027"] = 3;
examples/passing/2172.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console (log)
4+
5+foreign import a' :: Number
6+foreign import b' :: Number
7+foreign import c' :: Number
8+foreign import d' :: Number
9+
10+main = log "Done"
examples/passing/2252.pursnew file+15
@@ -0,0 +1,15 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console (log)
4+
5+data T a = T
6+
7+ti :: T Int
8+ti = T
9+
10+t :: forall a. T a
11+t = T
12+
13+xs = [ti, t, t]
14+
15+main = log "Done"
examples/passing/652.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5class Foo a b
6class Foo a b
6
7
@@ -14,4 +15,4 @@ instance bar :: Bar (a -> b) b
14
15
15instance baz :: (Eq a) => Baz (a -> b) a b
16instance baz :: (Eq a) => Baz (a -> b) a b
16
17
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/810.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Maybe a = Nothing | Just a
6data Maybe a = Nothing | Just a
6
7
@@ -10,4 +11,4 @@ test m = o.x
10 o = case m of Nothing -> { x : Nothing }
11 o = case m of Nothing -> { x : Nothing }
11 Just a -> { x : Just a }
12 Just a -> { x : Just a }
12
13
13−main = Control.Monad.Eff.Console.log "Done"
14+main = log "Done"
examples/passing/Applicative.purs+2−2
@@ -1,6 +1,6 @@
1module Main where
1module Main where
2
2
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
4
4
5class Applicative f where
5class Applicative f where
6 pure :: forall a. a -> f a
6 pure :: forall a. a -> f a
@@ -13,4 +13,4 @@ instance applicativeMaybe :: Applicative Maybe where
13 apply (Just f) (Just a) = Just (f a)
13 apply (Just f) (Just a) = Just (f a)
14 apply _ _ = Nothing
14 apply _ _ = Nothing
15
15
16−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/ArrayType.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5class Pointed p where
6class Pointed p where
6 point :: forall a. a -> p a
7 point :: forall a. a -> p a
@@ -8,4 +9,4 @@ class Pointed p where
8instance pointedArray :: Pointed Array where
9instance pointedArray :: Pointed Array where
9 point a = [a]
10 point a = [a]
10
11
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/Auto.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Auto s i o = Auto { state :: s, step :: s -> i -> o }
6data Auto s i o = Auto { state :: s, step :: s -> i -> o }
6
7
@@ -12,4 +13,4 @@ exists = \state step f -> f (Auto { state: state, step: step })
12run :: forall i o. SomeAuto i o -> i -> o
13run :: forall i o. SomeAuto i o -> i -> o
13run = \s i -> s (\a -> case a of Auto a -> a.step a.state i)
14run = \s i -> s (\a -> case a of Auto a -> a.step a.state i)
14
15
15−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/AutoPrelude.purs+11−9
@@ -1,9 +1,11 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (log)
5−
5+
6−f x = x * 10.0
6+f x = x * 10.0
7−g y = y - 10.0
7+g y = y - 10.0
8−
8+
9+main = do
9−main = log $ show $ (f <<< g) 100.0
10+ log $ show $ (f <<< g) 100.0
11+ log "Done"
examples/passing/AutoPrelude2.purs+1−1
@@ -1,7 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import qualified Prelude as P
4+import Prelude as P
5import Control.Monad.Eff.Console
5import Control.Monad.Eff.Console
6
6
7f :: forall a. a -> a
7f :: forall a. a -> a
examples/passing/BindersInFunctions.purs+8−3
@@ -1,11 +1,16 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Partial.Unsafe (unsafePartial)
4−import Test.Assert
5+import Test.Assert (assert')
6+import Control.Monad.Eff (Eff)
7+import Control.Monad.Eff.Console (log)
5
8
9+snd :: forall a. Partial => Array a -> a
6snd = \[_, y] -> y
10snd = \[_, y] -> y
7
11
12+main :: Eff _ _
8main = do
13main = do
9− let ts = snd [1.0, 2.0]
14+ let ts = unsafePartial (snd [1.0, 2.0])
10 assert' "Incorrect result from 'snd'." (ts == 2.0)
15 assert' "Incorrect result from 'snd'." (ts == 2.0)
11− Control.Monad.Eff.Console.log "Done"
16+ log "Done"
examples/passing/BindingGroups.purs+2−1
@@ -1,10 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5foo = bar
6foo = bar
6 where bar r = r + 1.0
7 where bar r = r + 1.0
7
8
8r = foo 2.0
9r = foo 2.0
9
10
10−main = Control.Monad.Eff.Console.log "Done"
11+main = log "Done"
examples/passing/BlockString.purs+2−1
@@ -1,8 +1,9 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5foo :: String
6foo :: String
6foo = """foo"""
7foo = """foo"""
7
8
8−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/CaseInDo.purs+4−2
@@ -1,19 +1,21 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Partial.Unsafe (unsafeCrashWith)
4import Control.Monad.Eff.Console
5import Control.Monad.Eff.Console
5import Control.Monad.Eff
6import Control.Monad.Eff
6
7
7doIt :: forall eff. Eff eff Boolean
8doIt :: forall eff. Eff eff Boolean
8−doIt = return true
9+doIt = pure true
9
10
10set = do
11set = do
11 log "Testing..."
12 log "Testing..."
12 case 0 of
13 case 0 of
13 0 -> doIt
14 0 -> doIt
14− _ -> return false
15+ _ -> pure false
15
16
16main = do
17main = do
17 b <- set
18 b <- set
18 case b of
19 case b of
19 true -> log "Done"
20 true -> log "Done"
21+ false -> unsafeCrashWith "Failed"
examples/passing/CaseMultipleExpressions.purs+4−2
@@ -1,19 +1,21 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Partial.Unsafe (unsafeCrashWith)
4import Control.Monad.Eff.Console
5import Control.Monad.Eff.Console
5import Control.Monad.Eff
6import Control.Monad.Eff
6
7
7doIt :: forall eff. Eff eff Boolean
8doIt :: forall eff. Eff eff Boolean
8−doIt = return true
9+doIt = pure true
9
10
10set = do
11set = do
11 log "Testing..."
12 log "Testing..."
12 case 42, 10 of
13 case 42, 10 of
13 42, 10 -> doIt
14 42, 10 -> doIt
14− _ , _ -> return false
15+ _ , _ -> pure false
15
16
16main = do
17main = do
17 b <- set
18 b <- set
18 case b of
19 case b of
19 true -> log "Done"
20 true -> log "Done"
21+ false -> unsafeCrashWith "Failed"
examples/passing/CaseStatement.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data A = A | B | C
6data A = A | B | C
6
7
@@ -18,4 +19,4 @@ h f N a = a
18h f a N = a
19h f a N = a
19h f (J a) (J b) = J (f a b)
20h f (J a) (J b) = J (f a b)
20
21
21−main = Control.Monad.Eff.Console.log $ f "Done" "Failed" A
22+main = log $ f "Done" "Failed" A
examples/passing/CheckFunction.purs+2−1
@@ -1,7 +1,8 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5test = ((\x -> x+1.0) >>> (\x -> x*2.0)) 4.0
6test = ((\x -> x+1.0) >>> (\x -> x*2.0)) 4.0
6
7
7−main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/passing/CheckSynonymBug.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5length :: forall a. Array a -> Int
6length :: forall a. Array a -> Int
6length _ = 0
7length _ = 0
@@ -9,4 +10,4 @@ type Foo a = Array a
9
10
10foo _ = length ([] :: Foo Number)
11foo _ = length ([] :: Foo Number)
11
12
12−main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/CheckTypeClass.purs+2−2
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Bar a = Bar
6data Bar a = Bar
6data Baz
7data Baz
@@ -14,5 +15,4 @@ foo_ x = foo ((mkBar :: forall a. (Foo a) => a -> Bar a) x)
14mkBar :: forall a. a -> Bar a
15mkBar :: forall a. a -> Bar a
15mkBar _ = Bar
16mkBar _ = Bar
16
17
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
18−
examples/passing/Church.purs+2−2
@@ -1,6 +1,6 @@
1module Main where
1module Main where
2
2
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
4
4
5type List a = forall r. r -> (a -> r -> r) -> r
5type List a = forall r. r -> (a -> r -> r) -> r
6
6
@@ -15,4 +15,4 @@ append = \l1 l2 r f -> l2 (l1 r f) f
15
15
16test = append (cons 1 empty) (cons 2 empty)
16test = append (cons 1 empty) (cons 2 empty)
17
17
18−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/ClassRefSyntax.purs+5−9
@@ -1,13 +1,9 @@
1−module Lib (class X, go) where
2−
3− class X a where
4− go :: a -> a
5−
6module Main where
1module Main where
7
2
8− import Lib (class X, go)
3+import Lib (class X, go)
4+import Control.Monad.Eff.Console (log)
9
5
10− go' :: forall a. (X a) => a -> a
6+go' :: forall a. (X a) => a -> a
11− go' = go
7+go' = go
12
8
13− main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/ClassRefSyntax/Lib.pursnew file+4
@@ -0,0 +1,4 @@
1+module Lib (class X, go) where
2+
3+class X a where
4+ go :: a -> a
examples/passing/Collatz.purs+5−2
@@ -3,6 +3,7 @@ module Main where
3import Prelude
3import Prelude
4import Control.Monad.Eff
4import Control.Monad.Eff
5import Control.Monad.ST
5import Control.Monad.ST
6+import Control.Monad.Eff.Console (log, logShow)
6
7
7collatz :: Int -> Int
8collatz :: Int -> Int
8collatz n = runPure (runST (do
9collatz n = runPure (runST (do
@@ -12,7 +13,9 @@ collatz n = runPure (runST (do
12 modifySTRef count $ (+) 1
13 modifySTRef count $ (+) 1
13 m <- readSTRef r
14 m <- readSTRef r
14 writeSTRef r $ if m `mod` 2 == 0 then m / 2 else 3 * m + 1
15 writeSTRef r $ if m `mod` 2 == 0 then m / 2 else 3 * m + 1
15− return $ m == 1
16+ pure $ m == 1
16 readSTRef count))
17 readSTRef count))
17
18
18−main = Control.Monad.Eff.Console.print $ collatz 1000
19+main = do
20+ logShow $ collatz 1000
21+ log "Done"
examples/passing/Comparisons.purs+15−15
@@ -1,15 +1,15 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−import Control.Monad.Eff
4+import Control.Monad.Eff
5−import Control.Monad.Eff.Console
5+import Control.Monad.Eff.Console
6−import Test.Assert
6+import Test.Assert
7−
7+
8−main = do
8+main = do
9− assert (1.0 < 2.0)
9+ assert (1.0 < 2.0)
10− assert (2.0 == 2.0)
10+ assert (2.0 == 2.0)
11− assert (3.0 > 1.0)
11+ assert (3.0 > 1.0)
12− assert ("a" < "b")
12+ assert ("a" < "b")
13− assert ("a" == "a")
13+ assert ("a" == "a")
14− assert ("z" > "a")
14+ assert ("z" > "a")
15− log "Done!"
15+ log "Done"
examples/passing/Conditional.purs+2−2
@@ -1,9 +1,9 @@
1module Main where
1module Main where
2
2
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
4
4
5fns = \f -> if f true then f else \x -> x
5fns = \f -> if f true then f else \x -> x
6
6
7not = \x -> if x then false else true
7not = \x -> if x then false else true
8
8
9−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/Console.purs+4−2
@@ -5,9 +5,11 @@ import Control.Monad.Eff
5import Control.Monad.Eff.Console
5import Control.Monad.Eff.Console
6
6
7replicateM_ :: forall m a. (Monad m) => Number -> m a -> m {}
7replicateM_ :: forall m a. (Monad m) => Number -> m a -> m {}
8−replicateM_ 0.0 _ = return {}
8+replicateM_ 0.0 _ = pure {}
9replicateM_ n act = do
9replicateM_ n act = do
10 act
10 act
11 replicateM_ (n - 1.0) act
11 replicateM_ (n - 1.0) act
12
12
13+main = do
13−main = replicateM_ 10.0 (log "Hello World!")
14+ replicateM_ 10.0 (log "Hello World!")
15+ log "Done"
examples/passing/ConstraintInference.purs+5−2
@@ -1,7 +1,10 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5−shout = Control.Monad.Eff.Console.log <<< (<> "!") <<< show
6+shout = log <<< (_ <> "!") <<< show
6
7
8+main = do
7−main = shout "Done"
9+ shout "Test"
10+ log "Done"
examples/passing/ContextSimplification.purs+5−3
@@ -3,11 +3,13 @@ module Main where
3import Prelude
3import Prelude
4import Control.Monad.Eff.Console
4import Control.Monad.Eff.Console
5
5
6−shout = log <<< (<> "!") <<< show
6+shout = log <<< (_ <> "!") <<< show
7
7
8-- Here, we should simplify the context so that only one Show
8-- Here, we should simplify the context so that only one Show
9-- constraint is added.
9-- constraint is added.
10usesShowTwice true = shout
10usesShowTwice true = shout
11−usesShowTwice false = print
11+usesShowTwice false = logShow
12
12
13+main = do
13−main = usesShowTwice true "Done"
14+ usesShowTwice true "Test"
15+ log "Done"
examples/passing/DataAndType.purs+2−1
@@ -1,9 +1,10 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data A = A B
6data A = A B
6
7
7type B = A
8type B = A
8
9
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/DctorOperatorAlias.purs+2−8
@@ -1,17 +1,11 @@
1−module Data.List where
2−
3− data List a = Cons a (List a) | Nil
4−
5− infixr 6 Cons as :
6−
7module Main where
1module Main where
8
2
9 import Prelude (Unit, bind, (==))
3 import Prelude (Unit, bind, (==))
10 import Control.Monad.Eff (Eff)
4 import Control.Monad.Eff (Eff)
11 import Control.Monad.Eff.Console (CONSOLE, log)
5 import Control.Monad.Eff.Console (CONSOLE, log)
12 import Test.Assert (ASSERT, assert')
6 import Test.Assert (ASSERT, assert')
13− import Data.List (List(..), (:))
7+ import List (List(..), (:))
14− import Data.List as L
8+ import List as L
15
9
16 -- unqualified
10 -- unqualified
17 infixl 6 Cons as !
11 infixl 6 Cons as !
examples/passing/DctorOperatorAlias/List.pursnew file+5
@@ -0,0 +1,5 @@
1+module List where
2+
3+data List a = Cons a (List a) | Nil
4+
5+infixr 6 Cons as :
examples/passing/DeepArrayBinder.purs+2−1
@@ -2,6 +2,7 @@ module Main where
2
2
3import Prelude
3import Prelude
4import Control.Monad.Eff
4import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log)
5import Test.Assert
6import Test.Assert
6
7
7data List a = Cons a (List a) | Nil
8data List a = Cons a (List a) | Nil
@@ -13,4 +14,4 @@ match2 _ = 0.0
13main = do
14main = do
14 let result = match2 (Cons 1.0 (Cons 2.0 (Cons 3.0 (Cons 4.0 (Cons 5.0 (Cons 6.0 (Cons 7.0 (Cons 8.0 (Cons 9.0 Nil)))))))))
15 let result = match2 (Cons 1.0 (Cons 2.0 (Cons 3.0 (Cons 4.0 (Cons 5.0 (Cons 6.0 (Cons 7.0 (Cons 8.0 (Cons 9.0 Nil)))))))))
15 assert' "Incorrect result!" (result == 100.0)
16 assert' "Incorrect result!" (result == 100.0)
16− Control.Monad.Eff.Console.log "Done"
17+ log "Done"
examples/passing/DeepCase.purs+4−4
@@ -1,9 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (log, logShow)
5−import Control.Monad.Eff
6−import Control.Monad.ST
7
5
8f x y =
6f x y =
9 let
7 let
@@ -12,4 +10,6 @@ f x y =
12 x -> 1.0 + x * x
10 x -> 1.0 + x * x
13 in g + x + y
11 in g + x + y
14
12
13+main = do
15−main = print $ f 1.0 10.0
14+ logShow $ f 1.0 10.0
15+ log "Done"
examples/passing/Deriving.purs+5−2
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4import Test.Assert
5import Test.Assert
5
6
6data V
7data V
@@ -27,5 +28,7 @@ main = do
27 assert $ X 0 < X 1
28 assert $ X 0 < X 1
28 assert $ X 0 < Y "Foo"
29 assert $ X 0 < Y "Foo"
29 assert $ Y "Bar" < Y "Baz"
30 assert $ Y "Bar" < Y "Baz"
30− assert $ z == z where
31+ assert $ z == z
32+ log "Done"
33+ where
31− z = Z { left: X 0, right: Y "Foo" }
34+ z = Z { left: X 0, right: Y "Foo" }
examples/passing/Do.purs+3−2
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Maybe a = Nothing | Just a
6data Maybe a = Nothing | Just a
6
7
@@ -19,7 +20,7 @@ instance bindMaybe :: Bind Maybe where
19 bind Nothing _ = Nothing
20 bind Nothing _ = Nothing
20 bind (Just a) f = f a
21 bind (Just a) f = f a
21
22
22−instance monadMaybe :: Prelude.Monad Maybe
23+instance monadMaybe :: Monad Maybe
23
24
24test1 = \_ -> do
25test1 = \_ -> do
25 Just "abc"
26 Just "abc"
@@ -64,4 +65,4 @@ test10 _ = do
64 g x = f x / 2.0
65 g x = f x / 2.0
65 Just (f 10.0)
66 Just (f 10.0)
66
67
67−main = Control.Monad.Eff.Console.log "Done"
68+main = log "Done"
examples/passing/Dollar.purs+5−5
@@ -1,11 +1,11 @@
1module Main where
1module Main where
2
2
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
4
4
5−($) :: forall a b. (a -> b) -> a -> b
5+applyFn :: forall a b. (a -> b) -> a -> b
6−($) f x = f x
6+applyFn f x = f x
7
7
8−infixr 1000 $
8+infixr 1000 applyFn as $
9
9
10id x = x
10id x = x
11
11
@@ -13,4 +13,4 @@ test1 x = id $ id $ id $ id $ x
13
13
14test2 x = id id $ id x
14test2 x = id id $ id x
15
15
16−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/Eff.purs+4−3
@@ -3,7 +3,7 @@ module Main where
3import Prelude
3import Prelude
4import Control.Monad.Eff
4import Control.Monad.Eff
5import Control.Monad.ST
5import Control.Monad.ST
6−import Control.Monad.Eff.Console
6+import Control.Monad.Eff.Console (log, logShow)
7
7
8test1 = do
8test1 = do
9 log "Line 1"
9 log "Line 1"
@@ -21,5 +21,6 @@ test3 = pureST (do
21
21
22main = do
22main = do
23 test1
23 test1
24− Control.Monad.Eff.Console.print test2
24+ logShow test2
25− Control.Monad.Eff.Console.print test3
25+ logShow test3
26+ log "Done"
examples/passing/EmptyDataDecls.purs+2−1
@@ -2,6 +2,7 @@ module Main where
2
2
3import Prelude
3import Prelude
4import Test.Assert
4import Test.Assert
5+import Control.Monad.Eff.Console (log)
5
6
6data Z
7data Z
7data S n
8data S n
@@ -15,5 +16,5 @@ cons' :: forall a n. a -> ArrayBox n a -> ArrayBox (S n) a
15cons' x (ArrayBox xs) = ArrayBox $ append [x] xs
16cons' x (ArrayBox xs) = ArrayBox $ append [x] xs
16
17
17main = case cons' 1 $ cons' 2 $ cons' 3 nil of
18main = case cons' 1 $ cons' 2 $ cons' 3 nil of
18− ArrayBox [1, 2, 3] -> Control.Monad.Eff.Console.log "Done"
19+ ArrayBox [1, 2, 3] -> log "Done"
19 _ -> assert' "Failed" false
20 _ -> assert' "Failed" false
examples/passing/EmptyRow.purs+2−1
@@ -1,10 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Foo r = Foo { | r }
6data Foo r = Foo { | r }
6
7
7test :: Foo ()
8test :: Foo ()
8test = Foo {}
9test = Foo {}
9
10
10−main = Control.Monad.Eff.Console.log "Done"
11+main = log "Done"
examples/passing/EmptyTypeClass.purs+5−6
@@ -1,12 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff
5+import Control.Monad.Eff.Console
4
6
5−class PartialP
6−
7−head :: forall a. (PartialP) => Array a -> a
7+head :: forall a. Partial => Array a -> a
8head [x] = x
8head [x] = x
9
9
10−instance allowPartials :: PartialP
10+main :: Eff _ _
11−
12−main = Control.Monad.Eff.Console.log $ head ["Done"]
11+main = log "Done"
examples/passing/EqOrd.purs+4−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
4
5
5data Pair a b = Pair a b
6data Pair a b = Pair a b
6
7
@@ -12,4 +13,6 @@ instance ordPair :: (Ord a, Ord b) => Ord (Pair a b) where
12instance eqPair :: (Eq a, Eq b) => Eq (Pair a b) where
13instance eqPair :: (Eq a, Eq b) => Eq (Pair a b) where
13 eq (Pair a1 b1) (Pair a2 b2) = a1 == a2 && b1 == b2
14 eq (Pair a1 b1) (Pair a2 b2) = a1 == a2 && b1 == b2
14
15
16+main = do
15−main = Control.Monad.Eff.Console.print $ Pair 1.0 2.0 == Pair 1.0 2.0
17+ logShow $ Pair 1.0 2.0 == Pair 1.0 2.0
18+ log "Done"
examples/passing/ExplicitImportReExport.purs+11−16
@@ -1,16 +1,11 @@
1−-- from #1244
1+-- from #1244
2−module Foo where
2+module Main where
3−
3+
4− foo :: Int
4+import Prelude
5− foo = 3
5+import Control.Monad.Eff.Console (log)
6−
7−module Bar (module Foo) where
8−
9− import Foo
10−
11−module Baz where
12−
13− import Bar (foo)
6+import Bar (foo)
14−
7+
15− baz :: Int
8+baz :: Int
16− baz = foo
9+baz = foo
10+
11+main = log "Done"
examples/passing/ExplicitImportReExport/Bar.pursnew file+3
@@ -0,0 +1,3 @@
1+module Bar (module Foo) where
2+
3+import Foo
examples/passing/ExplicitImportReExport/Foo.pursnew file+4
@@ -0,0 +1,4 @@
1+module Foo where
2+
3+foo :: Int
4+foo = 3
examples/passing/ExplicitOperatorSections.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5subtractOne :: Int -> Int
6subtractOne :: Int -> Int
6subtractOne = (_ - 1)
7subtractOne = (_ - 1)
@@ -11,4 +12,4 @@ addOne = (1 + _)
11named :: Int -> Int
12named :: Int -> Int
12named = (_ `sub` 1)
13named = (_ `sub` 1)
13
14
14−main = Control.Monad.Eff.Console.log "Done"
15+main = log "Done"
examples/passing/ExportExplicit.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+import M1
4+import Control.Monad.Eff.Console (log)
5+
6+testX = X
7+testZ = Z
8+testFoo = foo
9+
10+main = log "Done"
examples/passing/ExportExplicit/M1.pursnew file+10
@@ -0,0 +1,10 @@
1+module M1 (X(X), Z(..), foo) where
2+
3+data X = X | Y
4+data Z = Z
5+
6+foo :: Int
7+foo = 0
8+
9+bar :: Int
10+bar = 1
examples/passing/ExportExplicit2.pursnew file+8
@@ -0,0 +1,8 @@
1+module Main where
2+
3+import M1
4+import Control.Monad.Eff.Console (log)
5+
6+testBar = bar
7+
8+main = log "Done"
examples/passing/ExportExplicit2/M1.pursnew file+7
@@ -0,0 +1,7 @@
1+module M1 (bar) where
2+
3+foo :: Int
4+foo = 0
5+
6+bar :: Int
7+bar = foo
examples/manual/passing/ExportedInstanceDeclarations.purs → examples/passing/ExportedInstanceDeclarations.pursrenamed+7−5
@@ -1,14 +1,14 @@
1−
2-- Tests that instances for non-exported classes / types do not appear in the
1-- Tests that instances for non-exported classes / types do not appear in the
3-- result of `exportedDeclarations`.
2-- result of `exportedDeclarations`.
4−
3+module Main
5−module ExportedInstanceDeclarations
6 ( Const(..)
4 ( Const(..)
7− , Foo
5+ , class Foo
8 , foo
6 , foo
7+ , main
9 ) where
8 ) where
10
9
11import Prelude
10import Prelude
11+import Control.Monad.Eff.Console (log)
12
12
13data Const a b = Const a
13data Const a b = Const a
14
14
@@ -35,9 +35,11 @@ instance nonExportedFoo2 :: (Foo NonexportedType) => Foo (a -> a) where
35 foo = id
35 foo = id
36
36
37-- Case 2: type class
37-- Case 2: type class
38−instance nonExportedNonexportedType :: NonexportedClass (Const Number a) where
38+instance nonExportedNonexportedType :: NonexportedClass (Const Int a) where
39 notExported = Const 0
39 notExported = Const 0
40
40
41-- Case 3: instance types
41-- Case 3: instance types
42instance constFoo :: Foo (Const NonexportedType b) where
42instance constFoo :: Foo (Const NonexportedType b) where
43 foo = Const NonexportedType
43 foo = Const NonexportedType
44+
45+main = log "Done"
examples/passing/ExtendedInfixOperators.purs+5−2
@@ -1,9 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+import Data.Function (on)
4
6
5comparing :: forall a b. (Ord b) => (a -> b) -> a -> a -> Ordering
7comparing :: forall a b. (Ord b) => (a -> b) -> a -> a -> Ordering
6−comparing f = compare `Data.Function.on` f
8+comparing f = compare `on` f
7
9
8null [] = true
10null [] = true
9null _ = false
11null _ = false
@@ -11,4 +13,5 @@ null _ = false
11test = [1.0, 2.0, 3.0] `comparing null` [4.0, 5.0, 6.0]
13test = [1.0, 2.0, 3.0] `comparing null` [4.0, 5.0, 6.0]
12
14
13main = do
15main = do
14− Control.Monad.Eff.Console.print test
16+ logShow test
17+ log "Done"
examples/passing/Fib.purs+14−11
@@ -1,15 +1,18 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Control.Monad.Eff
4+import Control.Monad.Eff (whileE)
5+import Control.Monad.Eff.Console (log, logShow)
5−import Control.Monad.ST
6+import Control.Monad.ST (runST, newSTRef, readSTRef, writeSTRef)
6
7
8+main = do
7−main = runST (do
9+ runST do
8− n1 <- newSTRef 1.0
10+ n1 <- newSTRef 1.0
9− n2 <- newSTRef 1.0
11+ n2 <- newSTRef 1.0
10− whileE ((>) 1000.0 <$> readSTRef n1) $ do
12+ whileE ((>) 1000.0 <$> readSTRef n1) $ do
11− n1' <- readSTRef n1
13+ n1' <- readSTRef n1
12− n2' <- readSTRef n2
14+ n2' <- readSTRef n2
13− writeSTRef n2 $ n1' + n2'
15+ writeSTRef n2 $ n1' + n2'
14− writeSTRef n1 n2'
16+ writeSTRef n1 n2'
15− Control.Monad.Eff.Console.print n2')
17+ logShow n2'
18+ log "Done"
examples/passing/FieldConsPuns.purs+13−10
@@ -1,10 +1,13 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (log, logShow)
5−
5+
6−greet { greeting, name } = log $ greeting <> ", " <> name <> "."
6+greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7−
7+
8+main = do
8−main = greet { greeting, name} where
9+ greet { greeting, name }
10+ log "Done"
11+ where
9− greeting = "Hello"
12+ greeting = "Hello"
10− name = "World"
13+ name = "World"
examples/passing/FieldPuns.purs+10−8
@@ -1,8 +1,10 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console
5−
5+
6−greet { greeting, name } = log $ greeting <> ", " <> name <> "."
6+greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7−
7+
8+main = do
8−main = greet { greeting: "Hello", name: "World" }
9+ greet { greeting: "Hello", name: "World" }
10+ log "Done"
examples/passing/FinalTagless.purs+4−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude hiding (add)
3import Prelude hiding (add)
4+import Control.Monad.Eff.Console (log, logShow)
4
5
5class E e where
6class E e where
6 num :: Number -> e Number
7 num :: Number -> e Number
@@ -19,4 +20,6 @@ runId (Id a) = a
19three :: Expr Number
20three :: Expr Number
20three = add (num 1.0) (num 2.0)
21three = add (num 1.0) (num 2.0)
21
22
22−main = Control.Monad.Eff.Console.print $ runId three
23+main = do
24+ logShow $ runId three
25+ log "Done"
examples/passing/FunctionScope.purs+2−1
@@ -2,6 +2,7 @@ module Main where
2
2
3import Prelude
3import Prelude
4import Test.Assert
4import Test.Assert
5+import Control.Monad.Eff.Console (log)
5
6
6mkValue :: Number -> Number
7mkValue :: Number -> Number
7mkValue id = id
8mkValue id = id
@@ -9,4 +10,4 @@ mkValue id = id
9main = do
10main = do
10 let value = mkValue 1.0
11 let value = mkValue 1.0
11 assert $ value == 1.0
12 assert $ value == 1.0
12− Control.Monad.Eff.Console.log "Done"
13+ log "Done"
examples/passing/Functions.purs+2−5
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5test1 = \_ -> 0.0
6test1 = \_ -> 0.0
6
7
@@ -8,8 +9,4 @@ test2 = \a b -> a + b + 1.0
8
9
9test3 = \a -> a
10test3 = \a -> a
10
11
11−test4 = \(%%) -> 1.0 %% 2.0
12−
13−test5 = \(+++) (***) -> 1.0 +++ 2.0 *** 3.0
14−
15−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/Functions2.purs+2−1
@@ -2,6 +2,7 @@ module Main where
2
2
3import Prelude
3import Prelude
4import Test.Assert
4import Test.Assert
5+import Control.Monad.Eff.Console (log)
5
6
6test :: forall a b. a -> b -> a
7test :: forall a b. a -> b -> a
7test = \const _ -> const
8test = \const _ -> const
@@ -9,4 +10,4 @@ test = \const _ -> const
9main = do
10main = do
10 let value = test "Done" {}
11 let value = test "Done" {}
11 assert' "Not done" $ value == "Done"
12 assert' "Not done" $ value == "Done"
12− Control.Monad.Eff.Console.log "Done"
13+ log "Done"
examples/passing/Generalization1.purs+4−3
@@ -1,10 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Control.Monad.Eff.Console (print)
4+import Control.Monad.Eff.Console (logShow, log)
5
5
6main = do
6main = do
7− print (sum 1.0 2.0)
7+ logShow (sum 1.0 2.0)
8− print (sum 1 2)
8+ logShow (sum 1 2)
9+ log "Done"
9
10
10sum x y = x + y
11sum x y = x + y
examples/passing/Guards.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5collatz = \x -> case x of
6collatz = \x -> case x of
6 y | y `mod` 2.0 == 0.0 -> y / 2.0
7 y | y `mod` 2.0 == 0.0 -> y / 2.0
@@ -26,4 +27,4 @@ testIndentation x y | x > 0.0
26 | otherwise
27 | otherwise
27 = y - x
28 = y - x
28
29
29−main = Control.Monad.Eff.Console.log $ min "Done" "ZZZZ"
30+main = log $ min "Done" "ZZZZ"
examples/passing/IfThenElseMaybe.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Maybe a = Nothing | Just a
6data Maybe a = Nothing | Just a
6
7
@@ -8,4 +9,4 @@ test1 = if true then Just 10 else Nothing
8
9
9test2 = if true then Nothing else Just 10
10test2 = if true then Nothing else Just 10
10
11
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/ImplicitEmptyImport.purs+4−3
@@ -1,8 +1,9 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5main = do
6main = do
6− Control.Monad.Eff.Console.log "Hello"
7+ log "Hello"
7− Control.Monad.Eff.Console.log "Goodbye"
8+ log "Goodbye"
8− Control.Monad.Eff.Console.log "Done"
9+ log "Done"
examples/passing/Import.pursnew file+6
@@ -0,0 +1,6 @@
1+module Main where
2+
3+import M2
4+import Control.Monad.Eff.Console (log)
5+
6+main = log "Done"
examples/passing/Import/M1.pursnew file+8
@@ -0,0 +1,8 @@
1+module M1 where
2+
3+import Prelude ()
4+
5+id :: forall a. a -> a
6+id = \x -> x
7+
8+foo = id
examples/passing/Import/M2.pursnew file+6
@@ -0,0 +1,6 @@
1+module M2 where
2+
3+import Prelude ()
4+import M1
5+
6+main = \_ -> foo 42
examples/passing/ImportExplicit.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+import M1 (X(..))
4+import Control.Monad.Eff.Console (log)
5+
6+testX :: X
7+testX = X
8+testY = Y
9+
10+main = log "Done"
examples/passing/ImportExplicit/M1.pursnew file+4
@@ -0,0 +1,4 @@
1+module M1 where
2+
3+data X = X | Y
4+data Z = Z
examples/passing/ImportHiding.purs+3−2
@@ -3,7 +3,7 @@ module Main where
3import Control.Monad.Eff.Console
3import Control.Monad.Eff.Console
4import Prelude hiding (
4import Prelude hiding (
5 show, -- a value
5 show, -- a value
6− Show, -- a type class
6+ class Show, -- a type class
7 Unit(..) -- a constructor
7 Unit(..) -- a constructor
8 )
8 )
9
9
@@ -15,4 +15,5 @@ class Show a where
15data Unit = X | Y
15data Unit = X | Y
16
16
17main = do
17main = do
18− print show
18+ logShow show
19+ log "Done"
examples/passing/ImportQualified.pursnew file+8
@@ -0,0 +1,8 @@
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff
5+import M1
6+import Control.Monad.Eff.Console as C
7+
8+main = C.log (log "Done")
examples/passing/ImportQualified/M1.pursnew file+3
@@ -0,0 +1,3 @@
1+module M1 where
2+
3+log x = x
examples/passing/InferRecFunWithConstrainedArgument.purs+4−1
@@ -1,8 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
4
5
5test 100 = 100
6test 100 = 100
6test n = test(1 + n)
7test n = test(1 + n)
7
8
8−main = Control.Monad.Eff.Console.print $ test 0
9+main = do
10+ logShow (test 0)
11+ log "Done"
examples/passing/InstanceBeforeClass.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5instance fooNumber :: Foo Number where
6instance fooNumber :: Foo Number where
6 foo = 0.0
7 foo = 0.0
@@ -8,4 +9,4 @@ instance fooNumber :: Foo Number where
8class Foo a where
9class Foo a where
9 foo :: a
10 foo :: a
10
11
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/IntAndChar.purs+2−1
@@ -2,6 +2,7 @@ module Main where
2
2
3import Prelude
3import Prelude
4import Control.Monad.Eff
4import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log)
5import Test.Assert
6import Test.Assert
6
7
7f 1 = 1
8f 1 = 1
@@ -15,4 +16,4 @@ main = do
15 assert $ f 0 == 0
16 assert $ f 0 == 0
16 assert $ g 'a' == 'a'
17 assert $ g 'a' == 'a'
17 assert $ g 'b' == 'b'
18 assert $ g 'b' == 'b'
18− Control.Monad.Eff.Console.log "Done"
19+ log "Done"
examples/passing/JSReserved.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5yield = 0
6yield = 0
6member = 1
7member = 1
@@ -9,4 +10,4 @@ public = \return -> return
9
10
10this catch = catch
11this catch = catch
11
12
12−main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/KindedType.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5type Star2Star f = f :: * -> *
6type Star2Star f = f :: * -> *
6
7
@@ -30,4 +31,4 @@ class Clazz (a :: *) where
30instance clazzString :: Clazz String where
31instance clazzString :: Clazz String where
31 def = "test"
32 def = "test"
32
33
33−main = Control.Monad.Eff.Console.log "Done"
34+main = log "Done"
examples/passing/LargeSumType.purs+4−2
@@ -1,5 +1,7 @@
1module Main where
1module Main where
2−
2+
3+import Control.Monad.Eff.Console (log)
4+
3data Large = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
5data Large = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
4
6
5explode A A = "A"
7explode A A = "A"
@@ -30,4 +32,4 @@ explode Y Y = "Y"
30explode Z Z = "Z"
32explode Z Z = "Z"
31explode _ _ = ""
33explode _ _ = ""
32
34
33−main = Control.Monad.Eff.Console.log "Done"
35+main = log "Done"
examples/passing/Let.purs+14−9
@@ -1,7 +1,9 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Partial.Unsafe (unsafePartial)
4import Control.Monad.Eff
5import Control.Monad.Eff
6+import Control.Monad.Eff.Console (log, logShow)
5import Control.Monad.ST
7import Control.Monad.ST
6
8
7test1 x = let
9test1 x = let
@@ -17,8 +19,9 @@ test2 x y =
17test3 = let f x y z = x + y + z in
19test3 = let f x y z = x + y + z in
18 f 1.0 2.0 3.0
20 f 1.0 2.0 3.0
19
21
20−test4 = let f x [y, z] = x y z in
22+test4 = let
23+ f x [y, z] = x y z
21− f (+) [1.0, 2.0]
24+ in f (+) [1.0, 2.0]
22
25
23test5 = let
26test5 = let
24 f x | x > 0.0 = g (x / 2.0) + 1.0
27 f x | x > 0.0 = g (x / 2.0) + 1.0
@@ -43,11 +46,13 @@ test10 _ =
43 g x = f x / 2.0
46 g x = f x / 2.0
44 in f 10.0
47 in f 10.0
45
48
49+main :: Eff _ _
46main = do
50main = do
47− Control.Monad.Eff.Console.print (test1 1.0)
51+ logShow (test1 1.0)
48− Control.Monad.Eff.Console.print (test2 1.0 2.0)
52+ logShow (test2 1.0 2.0)
49− Control.Monad.Eff.Console.print test3
53+ logShow test3
50− Control.Monad.Eff.Console.print test4
54+ unsafePartial (logShow test4)
51− Control.Monad.Eff.Console.print test5
55+ logShow test5
52− Control.Monad.Eff.Console.print test7
56+ logShow test7
53− Control.Monad.Eff.Console.print (test8 100.0)
57+ logShow (test8 100.0)
58+ log "Done"
examples/passing/Let2.purs+4−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
4
5
5test =
6test =
6 let f :: Number -> Boolean
7 let f :: Number -> Boolean
@@ -14,4 +15,6 @@ test =
14 x = f 1.0
15 x = f 1.0
15 in not x
16 in not x
16
17
17−main = Control.Monad.Eff.Console.print test
18+main = do
19+ logShow test
20+ log "Done"
examples/passing/LetInInstance.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5class Foo a where
6class Foo a where
6 foo :: a -> String
7 foo :: a -> String
@@ -11,4 +12,4 @@ instance fooString :: Foo String where
11 go :: String -> String
12 go :: String -> String
12 go s = s
13 go s = s
13
14
14−main = Control.Monad.Eff.Console.log "Done"
15+main = log "Done"
examples/passing/LiberalTypeSynonyms.purs+4−3
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5type Reader = (->) String
6type Reader = (->) String
6
7
@@ -9,13 +10,13 @@ foo s = s
9
10
10type AndFoo r = (foo :: String | r)
11type AndFoo r = (foo :: String | r)
11
12
12−getFoo :: forall r. Prim.Object (AndFoo r) -> String
13+getFoo :: forall r. Prim.Record (AndFoo r) -> String
13getFoo o = o.foo
14getFoo o = o.foo
14
15
15type F r = { | r } -> { | r }
16type F r = { | r } -> { | r }
16
17
17f :: (forall r. F r) -> String
18f :: (forall r. F r) -> String
18f g = case g { x: "Hello" } of
19f g = case g { x: "Hello" } of
19− { x = x } -> x
20+ { x: x } -> x
20
21
21−main = Control.Monad.Eff.Console.log "Done"
22+main = log "Done"
examples/passing/MPTCs.purs+3−2
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5class NullaryTypeClass where
6class NullaryTypeClass where
6 greeting :: String
7 greeting :: String
@@ -14,7 +15,7 @@ class Coerce a b where
14instance coerceRefl :: Coerce a a where
15instance coerceRefl :: Coerce a a where
15 coerce a = a
16 coerce a = a
16
17
17−instance coerceShow :: (Prelude.Show a) => Coerce a String where
18+instance coerceShow :: Show a => Coerce a String where
18 coerce = show
19 coerce = show
19
20
20−main = Control.Monad.Eff.Console.log "Done"
21+main = log "Done"
examples/passing/Match.purs+2−1
@@ -1,9 +1,10 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Foo a = Foo
6data Foo a = Foo
6
7
7foo = \f -> case f of Foo -> "foo"
8foo = \f -> case f of Foo -> "foo"
8
9
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/Module.pursnew file+7
@@ -0,0 +1,7 @@
1+module Main where
2+
3+import M1
4+import M2
5+import Control.Monad.Eff.Console (log)
6+
7+main = log "Done"
examples/passing/Module/M1.pursnew file+14
@@ -0,0 +1,14 @@
1+module M1 where
2+
3+import Prelude
4+
5+data Foo = Foo String
6+
7+foo :: Foo -> String
8+foo = \f -> case f of Foo s -> s <> "foo"
9+
10+bar :: Foo -> String
11+bar = foo
12+
13+incr :: Int -> Int
14+incr x = x + 1
examples/passing/Module/M2.pursnew file+10
@@ -0,0 +1,10 @@
1+module M2 where
2+
3+import Prelude
4+import M1 as M1
5+
6+baz :: M1.Foo -> String
7+baz = M1.foo
8+
9+match :: M1.Foo -> String
10+match = \f -> case f of M1.Foo s -> s <> "foo"
examples/passing/ModuleDeps.pursnew file+6
@@ -0,0 +1,6 @@
1+module Main where
2+
3+import M1
4+import Control.Monad.Eff.Console (log)
5+
6+main = log "Done"
examples/passing/ModuleDeps/M1.pursnew file+5
@@ -0,0 +1,5 @@
1+module M1 where
2+
3+import M2 as M2
4+
5+foo = M2.bar
examples/passing/ModuleDeps/M2.pursnew file+5
@@ -0,0 +1,5 @@
1+module M2 where
2+
3+import M3 as M3
4+
5+bar = M3.baz
examples/passing/ModuleDeps/M3.pursnew file+3
@@ -0,0 +1,3 @@
1+module M3 where
2+
3+baz = 1
examples/passing/ModuleExport.purs+6−7
@@ -1,9 +1,8 @@
1−module A (module Prelude) where
2− import Prelude
3−
4module Main where
1module Main where
5− import Control.Monad.Eff.Console
6− import A
7
2
3+import Control.Monad.Eff.Console (log, logShow)
4+import A
5+
8− main = do
6+main = do
9− print (show 1.0)
7+ logShow (show 1.0)
8+ log "Done"
examples/passing/ModuleExport/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A (module Prelude) where
2+
3+import Prelude
examples/passing/ModuleExportDupes.purs+3−11
@@ -1,14 +1,5 @@
1−module A (module Prelude) where
2− import Prelude
3−
4−module B (module Prelude) where
5− import Prelude
6−
7−module C (module Prelude, module A) where
8− import Prelude
9− import A
10−
11module Main where
1module Main where
2+
12 import Control.Monad.Eff.Console
3 import Control.Monad.Eff.Console
13 import A
4 import A
14 import B
5 import B
@@ -16,4 +7,5 @@ module Main where
16 import Prelude
7 import Prelude
17
8
18 main = do
9 main = do
19− print (show 1.0)
10+ logShow (show 1.0)
11+ log "Done"
examples/passing/ModuleExportDupes/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A (module Prelude) where
2+
3+import Prelude
examples/passing/ModuleExportDupes/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B (module Prelude) where
2+
3+import Prelude
examples/passing/ModuleExportDupes/C.pursnew file+4
@@ -0,0 +1,4 @@
1+module C (module Prelude, module A) where
2+
3+import Prelude
4+import A
examples/passing/ModuleExportExcluded.purs+8−11
@@ -1,14 +1,11 @@
1−module A (module Prelude, foo) where
2− import Prelude
3−
4− foo :: Number -> Number
5− foo _ = 0.0
6−
7module Main where
1module Main where
8− import Control.Monad.Eff.Console
9− import A (foo)
10
2
3+import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+import A (foo)
6+
11− otherwise = false
7+otherwise = false
12
8
13− main = do
9+main = do
14− print "1.0"
10+ logShow "1.0"
11+ log "Done"
examples/passing/ModuleExportExcluded/A.pursnew file+6
@@ -0,0 +1,6 @@
1+module A (module Prelude, foo) where
2+
3+import Prelude
4+
5+foo :: Number -> Number
6+foo _ = 0.0
examples/passing/ModuleExportQualified.purs+7−7
@@ -1,9 +1,9 @@
1−module A (module Prelude) where
2− import Prelude
3−
4module Main where
1module Main where
5− import Control.Monad.Eff.Console
6− import qualified A as B
7
2
3+import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+import A as B
6+
8− main = do
7+main = do
9− print (B.show 1.0)
8+ logShow (B.show 1.0)
9+ log "Done"
examples/passing/ModuleExportQualified/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A (module Prelude) where
2+
3+import Prelude
examples/passing/ModuleExportSelf.purs+8−11
@@ -1,14 +1,11 @@
1−module A (module A, module Prelude) where
2− import Prelude
3−
4− type Foo = Boolean
5−
6module Main where
1module Main where
7− import Control.Monad.Eff.Console
8− import A
9
2
3+import Control.Monad.Eff.Console
4+import A
5+
10− bar :: Foo
6+bar :: Foo
11− bar = true
7+bar = true
12
8
13− main = do
9+main = do
14− print (show bar)
10+ logShow (show bar)
11+ log "Done"
examples/passing/ModuleExportSelf/A.pursnew file+5
@@ -0,0 +1,5 @@
1+module A (module A, module Prelude) where
2+
3+import Prelude
4+
5+type Foo = Boolean
examples/passing/Monad.purs+2−2
@@ -1,6 +1,6 @@
1module Main where
1module Main where
2
2
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
4
4
5type Monad m = { return :: forall a. a -> m a
5type Monad m = { return :: forall a. a -> m a
6 , bind :: forall a b. m a -> (a -> m b) -> m b }
6 , bind :: forall a b. m a -> (a -> m b) -> m b }
@@ -29,4 +29,4 @@ test1 = test id
29
29
30test2 = test maybe
30test2 = test maybe
31
31
32−main = Control.Monad.Eff.Console.log "Done"
32+main = log "Done"
examples/passing/MonadState.purs+3−1
@@ -58,4 +58,6 @@ modify f =
58 same :: forall a. (a -> a) -> (a -> a)
58 same :: forall a. (a -> a) -> (a -> a)
59 same = id
59 same = id
60
60
61+main = do
61−main = print $ runState 0 (modify (+ 1))
62+ logShow $ runState 0 (modify (_ + 1))
63+ log "Done"
examples/passing/MultiArgFunctions.purs+3−3
@@ -1,7 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Data.Function
4+import Data.Function.Uncurried
5import Control.Monad.Eff
5import Control.Monad.Eff
6import Control.Monad.Eff.Console
6import Control.Monad.Eff.Console
7
7
@@ -23,5 +23,5 @@ main = do
23 runFn8 (mkFn8 $ \a b c d e f g h -> log $ show [a, b, c, d, e, f, g, h]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
23 runFn8 (mkFn8 $ \a b c d e f g h -> log $ show [a, b, c, d, e, f, g, h]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
24 runFn9 (mkFn9 $ \a b c d e f g h i -> log $ show [a, b, c, d, e, f, g, h, i]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
24 runFn9 (mkFn9 $ \a b c d e f g h i -> log $ show [a, b, c, d, e, f, g, h, i]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
25 runFn10 (mkFn10 $ \a b c d e f g h i j-> log $ show [a, b, c, d, e, f, g, h, i, j]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
25 runFn10 (mkFn10 $ \a b c d e f g h i j-> log $ show [a, b, c, d, e, f, g, h, i, j]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
26− print $ runFn2 g 0.0 0.0
26+ logShow $ runFn2 g 0.0 0.0
27− log "Done!"
27+ log "Done"
examples/passing/MutRec.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5f 0.0 = 0.0
6f 0.0 = 0.0
6f x = g x + 0.0
7f x = g x + 0.0
@@ -16,4 +17,4 @@ evenToNumber (Even n) = oddToNumber n + 0.0
16
17
17oddToNumber (Odd n) = evenToNumber n + 0.0
18oddToNumber (Odd n) = evenToNumber n + 0.0
18
19
19−main = Control.Monad.Eff.Console.log "Done"
20+main = log "Done"
examples/passing/MutRec2.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data A = A B
6data A = A B
6
7
@@ -16,4 +17,4 @@ g b = case b of B a -> f a
16showN :: A -> S
17showN :: A -> S
17showN a = f a
18showN a = f a
18
19
19−main = Control.Monad.Eff.Console.log "Done"
20+main = log "Done"
examples/passing/MutRec3.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data A = A B
6data A = A B
6
7
@@ -16,4 +17,4 @@ g b = case b of B a -> f a
16showN :: A -> S
17showN :: A -> S
17showN a = f a
18showN a = f a
18
19
19−main = Control.Monad.Eff.Console.log "Done"
20+main = log "Done"
examples/passing/NamedPatterns.purs+3−2
@@ -1,9 +1,10 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5foo = \x -> case x of
6foo = \x -> case x of
6− y@{ foo = "Foo" } -> y
7+ y@{ foo: "Foo" } -> y
7 y -> y
8 y -> y
8
9
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/NegativeBinder.purs+2−1
@@ -1,9 +1,10 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5test :: Number -> Boolean
6test :: Number -> Boolean
6test -1.0 = false
7test -1.0 = false
7test _ = true
8test _ = true
8
9
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/NegativeIntInRange.purs+2−1
@@ -1,8 +1,9 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5n :: Int
6n :: Int
6n = -2147483648
7n = -2147483648
7
8
8−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/Nested.purs+2−1
@@ -1,9 +1,10 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Extend r a = Extend { prev :: r a, next :: a }
6data Extend r a = Extend { prev :: r a, next :: a }
6
7
7data Matrix r a = Square (r (r a)) | Bigger (Matrix (Extend r) a)
8data Matrix r a = Square (r (r a)) | Bigger (Matrix (Extend r) a)
8
9
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/NestedTypeSynonyms.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5type X = String
6type X = String
6type Y = X -> X
7type Y = X -> X
@@ -8,4 +9,4 @@ type Y = X -> X
8fn :: Y
9fn :: Y
9fn a = a
10fn a = a
10
11
11−main = Control.Monad.Eff.Console.print (fn "Done")
12+main = log (fn "Done")
examples/passing/NestedWhere.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5f x = g x
6f x = g x
6 where
7 where
@@ -9,4 +10,4 @@ f x = g x
9 go x = go1 (x - 1.0)
10 go x = go1 (x - 1.0)
10 go1 x = go x
11 go1 x = go x
11
12
12−main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/Newtype.purs+5−5
@@ -7,17 +7,17 @@ import Control.Monad.Eff.Console
7newtype Thing = Thing String
7newtype Thing = Thing String
8
8
9instance showThing :: Show Thing where
9instance showThing :: Show Thing where
10− show (Thing x) = "Thing " ++ show x
10+ show (Thing x) = "Thing " <> show x
11
11
12newtype Box a = Box a
12newtype Box a = Box a
13
13
14instance showBox :: (Show a) => Show (Box a) where
14instance showBox :: (Show a) => Show (Box a) where
15− show (Box x) = "Box " ++ show x
15+ show (Box x) = "Box " <> show x
16
16
17apply f x = f x
17apply f x = f x
18
18
19main = do
19main = do
20− print $ Thing "hello"
20+ logShow $ Thing "hello"
21− print $ Box 42.0
21+ logShow $ Box 42.0
22− print $ apply Box 9000.0
22+ logShow $ apply Box 9000.0
23 log "Done"
23 log "Done"
examples/passing/NewtypeWithRecordUpdate.purs+2−2
@@ -5,9 +5,9 @@ module Main where
5import Prelude
5import Prelude
6import Control.Monad.Eff.Console
6import Control.Monad.Eff.Console
7
7
8−newtype NewType a = NewType (Object a)
8+newtype NewType a = NewType (Record a)
9
9
10−rec1 :: Object (a :: Number, b :: Number, c:: Number)
10+rec1 :: Record (a :: Number, b :: Number, c:: Number)
11rec1 = { a: 0.0, b: 0.0, c: 0.0 }
11rec1 = { a: 0.0, b: 0.0, c: 0.0 }
12
12
13rec2 :: NewType (a :: Number, b :: Number, c :: Number)
13rec2 :: NewType (a :: Number, b :: Number, c :: Number)
examples/passing/NonConflictingExports.purs+5−9
@@ -1,14 +1,10 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
6-- No failure here as the export `thing` only refers to Main.thing
1-- No failure here as the export `thing` only refers to Main.thing
7module Main (thing, main) where
2module Main (thing, main) where
8
3
9− import A
4+import A
5+import Control.Monad.Eff.Console (log)
10
6
11− thing :: Int
7+thing :: Int
12− thing = 2
8+thing = 2
13
9
14− main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/NonConflictingExports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/NumberLiterals.pursnew file+39
@@ -0,0 +1,39 @@
1+module Main where
2+
3+-- See issue #2115.
4+
5+import Prelude
6+import Test.Assert (assert')
7+import Control.Monad.Eff.Console (log)
8+
9+main = do
10+ test "0.17" 0.17
11+ test "0.25996181067141905" 0.25996181067141905
12+ test "0.3572019862807257" 0.3572019862807257
13+ test "0.46817723004874223" 0.46817723004874223
14+ test "0.9640035681058178" 0.9640035681058178
15+ test "4.23808622486133" 4.23808622486133
16+ test "4.540362294799751" 4.540362294799751
17+ test "5.212384849884261" 5.212384849884261
18+ test "13.958257048123212" 13.958257048123212
19+ test "32.96176575630599" 32.96176575630599
20+ test "38.47735512322269" 38.47735512322269
21+
22+ test "10000000000" 1e10
23+ test "10000000000" 1.0e10
24+ test "0.00001" 1e-5
25+ test "0.00001" 1.0e-5
26+ test "1.5339794352098402e-118" 1.5339794352098402e-118
27+ test "2.108934760892056e-59" 2.108934760892056e-59
28+ test "2.250634744599241e-19" 2.250634744599241e-19
29+ test "5.960464477539063e-8" 5.960464477539063e-8
30+ test "5e-324" 5e-324
31+ test "5e-324" 5.0e-324
32+
33+ log "Done"
34+
35+test str num =
36+ if (show num == str)
37+ then pure unit
38+ else flip assert' false $
39+ "Expected " <> show str <> ", got " <> show (show num) <> "."
examples/passing/ObjectGetter.purs+5−4
@@ -1,13 +1,14 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
4
5
5getX = _.x
6getX = _.x
6
7
7point = { x: 1.0, y: 0.0 }
8point = { x: 1.0, y: 0.0 }
8
9
9main = do
10main = do
10− Control.Monad.Eff.Console.print $ getX point
11+ logShow $ getX point
11− Control.Monad.Eff.Console.log $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
12+ log $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
12− Control.Monad.Eff.Console.log $ (_.x >>> _.y) { x: { y: "Nested" } }
13+ log $ (_.x >>> _.y) { x: { y: "Nested" } }
13− Control.Monad.Eff.Console.log $ _.value { value: "Done!" }
14+ log $ _.value { value: "Done" }
examples/passing/ObjectSynonym.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5type Inner = Number
6type Inner = Number
6
7
@@ -12,4 +13,4 @@ type Outer = { inner :: Inner }
12outer :: Outer
13outer :: Outer
13outer = { inner: inner }
14outer = { inner: inner }
14
15
15−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/ObjectUpdate.purs+23−20
@@ -1,20 +1,23 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−
4+import Control.Monad.Eff.Console (log)
5+
5−update1 = \o -> o { foo = "Foo" }
6+update1 = \o -> o { foo = "Foo" }
6−
7+
7−update2 :: forall r. { foo :: String | r } -> { foo :: String | r }
8+update2 :: forall r. { foo :: String | r } -> { foo :: String | r }
8−update2 = \o -> o { foo = "Foo" }
9+update2 = \o -> o { foo = "Foo" }
9−
10+
10−replace = \o -> case o of
11+replace = \o -> case o of
11− { foo = "Foo" } -> o { foo = "Bar" }
12+ { foo: "Foo" } -> o { foo = "Bar" }
12− { foo = "Bar" } -> o { bar = "Baz" }
13+ { foo: "Bar" } -> o { bar = "Baz" }
13− o -> o
14+ o -> o
14−
15+
15−polyUpdate :: forall a r. { foo :: a | r } -> { foo :: String | r }
16+polyUpdate :: forall a r. { foo :: a | r } -> { foo :: String | r }
16−polyUpdate = \o -> o { foo = "Foo" }
17+polyUpdate = \o -> o { foo = "Foo" }
17−
18+
18−inferPolyUpdate = \o -> o { foo = "Foo" }
19+inferPolyUpdate = \o -> o { foo = "Foo" }
19−
20+
21+main = do
20−main = Control.Monad.Eff.Console.log ((update1 {foo: ""}).foo)
22+ log ((update1 {foo: ""}).foo)
23+ log "Done"
examples/passing/ObjectUpdate2.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5type X r = { | r }
6type X r = { | r }
6
7
@@ -14,4 +15,4 @@ test = blah x
14 { baz = "blah"
15 { baz = "blah"
15 }
16 }
16
17
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/ObjectUpdater.purs+3−1
@@ -6,7 +6,7 @@ import Control.Monad.Eff.Console
6import Test.Assert
6import Test.Assert
7
7
8getValue :: forall e. Eff (| e) Boolean
8getValue :: forall e. Eff (| e) Boolean
9−getValue = return true
9+getValue = pure true
10
10
11main = do
11main = do
12 let record = { value: false }
12 let record = { value: false }
@@ -22,3 +22,5 @@ main = do
22
22
23 let record2 = (_ { x = _ }) { x: 0.0 } 10.0
23 let record2 = (_ { x = _ }) { x: 0.0 } 10.0
24 assert $ record2.x == 10.0
24 assert $ record2.x == 10.0
25+
26+ log "Done"
examples/passing/ObjectWildcards.purs+4−4
@@ -8,13 +8,13 @@ import Test.Assert
8mkRecord = { foo: _, bar: _, baz: "baz" }
8mkRecord = { foo: _, bar: _, baz: "baz" }
9
9
10getValue :: forall e. Eff (| e) Boolean
10getValue :: forall e. Eff (| e) Boolean
11−getValue = return true
11+getValue = pure true
12
12
13main = do
13main = do
14 obj <- { value: _ } <$> getValue
14 obj <- { value: _ } <$> getValue
15− print obj.value
15+ logShow obj.value
16 let x = 1.0
16 let x = 1.0
17− point <- { x: _, y: x } <$> return 2.0
17+ point <- { x: _, y: x } <$> pure 2.0
18 assert $ point.x == 2.0
18 assert $ point.x == 2.0
19 assert $ point.y == 1.0
19 assert $ point.y == 1.0
20− log (mkRecord 1.0 "Done!").bar
20+ log (mkRecord 1.0 "Done").bar
examples/passing/Objects.purs+3−2
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude hiding (append)
3import Prelude hiding (append)
4+import Control.Monad.Eff.Console (log)
4
5
5test = \x -> x.foo + x.bar + 1.0
6test = \x -> x.foo + x.bar + 1.0
6
7
@@ -25,11 +26,11 @@ test4 = test2 weirdObj
25 weirdObj = { "!@#": 1.0 }
26 weirdObj = { "!@#": 1.0 }
26
27
27test5 = case { "***": 1.0 } of
28test5 = case { "***": 1.0 } of
28− { "***" = n } -> n
29+ { "***": n } -> n
29
30
30test6 = case { "***": 1.0 } of
31test6 = case { "***": 1.0 } of
31 { "***": n } -> n
32 { "***": n } -> n
32
33
33test7 {a: snoog , b : blah } = blah
34test7 {a: snoog , b : blah } = blah
34
35
35−main = Control.Monad.Eff.Console.log "Done"
36+main = log "Done"
examples/passing/OneConstructor.purs+2−1
@@ -1,9 +1,10 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data One a = One a
6data One a = One a
6
7
7one' (One a) = a
8one' (One a) = a
8
9
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/OperatorAliasElsewhere.purs−5
@@ -1,8 +1,3 @@
1−module Def where
2−
3−what :: forall a b. a -> b -> a
4−what a _ = a
5−
6module Main where
1module Main where
7
2
8import Prelude
3import Prelude
examples/passing/OperatorAliasElsewhere/Def.pursnew file+4
@@ -0,0 +1,4 @@
1+module Def where
2+
3+what :: forall a b. a -> b -> a
4+what a _ = a
examples/passing/OperatorAssociativity.purs+25−25
@@ -1,25 +1,25 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−import Control.Monad.Eff
4+import Control.Monad.Eff
5−import Control.Monad.Eff.Console
5+import Control.Monad.Eff.Console
6−import Test.Assert
6+import Test.Assert
7−
7+
8−bug :: Number -> Number -> Number
8+bug :: Number -> Number -> Number
9−bug a b = 0.0 - (a - b)
9+bug a b = 0.0 - (a - b)
10−
10+
11−main = do
11+main = do
12− assert (bug 0.0 2.0 == 2.0)
12+ assert (bug 0.0 2.0 == 2.0)
13− assert (0.0 - (0.0 - 2.0) == 2.0)
13+ assert (0.0 - (0.0 - 2.0) == 2.0)
14− assert (0.0 - (0.0 + 2.0) == -2.0)
14+ assert (0.0 - (0.0 + 2.0) == -2.0)
15− assert (6.0 / (3.0 * 2.0) == 1.0)
15+ assert (6.0 / (3.0 * 2.0) == 1.0)
16− assert ((6.0 / 3.0) * 2.0 == 4.0)
16+ assert ((6.0 / 3.0) * 2.0 == 4.0)
17− assert (not (1.0 < 0.0) == true)
17+ assert (not (1.0 < 0.0) == true)
18− assert (not ((negate 1.0) < 0.0) == false)
18+ assert (not ((negate 1.0) < 0.0) == false)
19− assert (negate (1.0 + 10.0) == -11.0)
19+ assert (negate (1.0 + 10.0) == -11.0)
20− assert (2.0 * 3.0 / 4.0 == 1.5)
20+ assert (2.0 * 3.0 / 4.0 == 1.5)
21− assert (1.0 * 2.0 * 3.0 * 4.0 * 5.0 / 6.0 == 20.0)
21+ assert (1.0 * 2.0 * 3.0 * 4.0 * 5.0 / 6.0 == 20.0)
22− assert (1.0 + 10.0 - 5.0 == 6.0)
22+ assert (1.0 + 10.0 - 5.0 == 6.0)
23− assert (1.0 + 10.0 * 5.0 == 51.0)
23+ assert (1.0 + 10.0 * 5.0 == 51.0)
24− assert (10.0 * 5.0 - 1.0 == 49.0)
24+ assert (10.0 * 5.0 - 1.0 == 49.0)
25− log "Success!"
25+ log "Done"
examples/passing/OperatorInlining.purs+23−22
@@ -1,47 +1,48 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (logShow, log)
5
5
6main = do
6main = do
7
7
8 -- semiringNumber
8 -- semiringNumber
9− print (1.0 + 2.0)
9+ logShow (1.0 + 2.0)
10− print (1.0 * 2.0)
10+ logShow (1.0 * 2.0)
11
11
12 -- ringNumber
12 -- ringNumber
13− print (1.0 - 2.0)
13+ logShow (1.0 - 2.0)
14− print (negate 1.0)
14+ logShow (negate 1.0)
15
15
16 -- moduleSemiringNumber
16 -- moduleSemiringNumber
17− print (1.0 / 2.0)
17+ logShow (1.0 / 2.0)
18
18
19 -- ordNumber
19 -- ordNumber
20− print (1.0 > 2.0)
20+ logShow (1.0 > 2.0)
21− print (1.0 < 2.0)
21+ logShow (1.0 < 2.0)
22− print (1.0 <= 2.0)
22+ logShow (1.0 <= 2.0)
23− print (1.0 >= 2.0)
23+ logShow (1.0 >= 2.0)
24− print (1.0 == 2.0)
24+ logShow (1.0 == 2.0)
25
25
26 -- eqNumber
26 -- eqNumber
27− print (1.0 == 2.0)
27+ logShow (1.0 == 2.0)
28− print (1.0 /= 2.0)
28+ logShow (1.0 /= 2.0)
29
29
30 -- eqString
30 -- eqString
31− print ("foo" == "bar")
31+ logShow ("foo" == "bar")
32− print ("foo" /= "bar")
32+ logShow ("foo" /= "bar")
33
33
34 -- eqBoolean
34 -- eqBoolean
35− print (true == false)
35+ logShow (true == false)
36− print (true /= false)
36+ logShow (true /= false)
37
37
38 -- semigroupString
38 -- semigroupString
39− print ("foo" ++ "bar")
40− print ("foo" <> "bar")
39+ logShow ("foo" <> "bar")
41
40
42 -- latticeBoolean
41 -- latticeBoolean
43− print (top && true)
42+ logShow (top && true)
44− print (bottom || false)
43+ logShow (bottom || false)
45
44
46 -- complementedLatticeBoolean
45 -- complementedLatticeBoolean
47− print (not true)
46+ logShow (not true)
47+
48+ log "Done"
examples/passing/OperatorSections.purs+11−10
@@ -1,17 +1,18 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4import Test.Assert
5import Test.Assert
5
6
6main = do
7main = do
7− assert $ (/ 2.0) 4.0 == 2.0
8+ assert $ (_ / 2.0) 4.0 == 2.0
8− assert $ (2.0 /) 4.0 == 0.5
9+ assert $ (2.0 / _) 4.0 == 0.5
9− assert $ (`const` 1.0) 2.0 == 2.0
10+ assert $ (_ `const` 1.0) 2.0 == 2.0
10− assert $ (1.0 `const`) 2.0 == 1.0
11+ assert $ (1.0 `const` _) 2.0 == 1.0
11 let foo = { x: 2.0 }
12 let foo = { x: 2.0 }
12− assert $ (/ foo.x) 4.0 == 2.0
13+ assert $ (_ / foo.x) 4.0 == 2.0
13− assert $ (foo.x /) 4.0 == 0.5
14+ assert $ (foo.x / _) 4.0 == 0.5
14− let (//) x y = x.x / y.x
15+ let div x y = x.x / y.x
15− assert $ (// foo { x = 4.0 }) { x: 4.0 } == 1.0
16+ assert $ (_ `div` foo { x = 4.0 }) { x: 4.0 } == 1.0
16− assert $ (foo { x = 4.0 } //) { x: 4.0 } == 1.0
17+ assert $ (foo { x = 4.0 } `div` _) { x: 4.0 } == 1.0
17− Control.Monad.Eff.Console.log "Done!"
18+ log "Done"
examples/passing/Operators.purs+22−30
@@ -1,16 +1,17 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Other (foo)
5+import Other as Other
4import Control.Monad.Eff
6import Control.Monad.Eff
5import Control.Monad.Eff.Console
7import Control.Monad.Eff.Console
6
8
7−(?!) :: forall a. a -> a -> a
9+op1 :: forall a. a -> a -> a
8−(?!) x _ = x
10+op1 x _ = x
9
11
10−bar :: String -> String -> String
12+infix 4 op1 as ?!
11−bar = \s1 s2 -> s1 ++ s2
12
13
13−test1 :: forall n. (Num n) => n -> n -> (n -> n -> n) -> n
14+test1 :: forall n. (Semiring n) => n -> n -> (n -> n -> n) -> n
14test1 x y z = x * y + z x y
15test1 x y z = x * y + z x y
15
16
16test2 = (\x -> x.foo false) { foo : \_ -> 1.0 }
17test2 = (\x -> x.foo false) { foo : \_ -> 1.0 }
@@ -21,40 +22,39 @@ k = \x -> \y -> x
21
22
22test4 = 1 `k` 2
23test4 = 1 `k` 2
23
24
24−infixl 5 %%
25+op2 :: Number -> Number -> Number
26+op2 x y = x * y + y
25
27
26−(%%) :: Number -> Number -> Number
28+infixl 5 op2 as %%
27−(%%) x y = x * y + y
28
29
29test5 = 1.0 %% 2.0 %% 3.0
30test5 = 1.0 %% 2.0 %% 3.0
30
31
31test6 = ((\x -> x) `k` 2.0) 3.0
32test6 = ((\x -> x) `k` 2.0) 3.0
32
33
33−(<+>) :: String -> String -> String
34+op3 :: String -> String -> String
34−(<+>) = \s1 s2 -> s1 ++ s2
35+op3 = \s1 s2 -> s1 <> s2
36+
37+infix 4 op3 as <+>
35
38
36test7 = "Hello" <+> "World!"
39test7 = "Hello" <+> "World!"
37
40
38−(@@) :: forall a b. (a -> b) -> a -> b
41+op4 :: forall a b. (a -> b) -> a -> b
39−(@@) = \f x -> f x
42+op4 = \f x -> f x
40
43
41−foo :: String -> String
44+infix 4 op4 as @@
42−foo = \s -> s
43
45
44test8 = foo @@ "Hello World"
46test8 = foo @@ "Hello World"
45
47
46−test9 = Main.foo @@ "Hello World"
48+test9 = Other.foo @@ "Hello World"
47−
48−test10 = "Hello" `Main.bar` "World"
49
49
50−(...) :: forall a. Array a -> Array a -> Array a
50+test10 = "Hello" `Other.baz` "World"
51−(...) = \as -> \bs -> as
52
51
53−test11 = [1.0, 2.0, 0.0] ... [4.0, 5.0, 6.0]
52+op5 :: forall a. Array a -> Array a -> Array a
53+op5 = \as -> \bs -> as
54
54
55−test12 (<%>) a b = a <%> b
55+infix 4 op5 as ...
56
56
57−test13 = \(<%>) a b -> a <%> b
57+test11 = [1.0, 2.0, 0.0] ... [4.0, 5.0, 6.0]
58
58
59test14 :: Number -> Number -> Boolean
59test14 :: Number -> Number -> Boolean
60test14 a b = a < b
60test14 a b = a < b
@@ -71,11 +71,6 @@ test18 = negate $ negate 1.0
71test19 :: Number
71test19 :: Number
72test19 = negate $ negate (-1.0)
72test19 = negate $ negate (-1.0)
73
73
74−test20 :: Number
75−test20 = 1.0 @ 2.0
76− where
77− (@) x y = x + y * y
78−
79main = do
74main = do
80 let t1 = test1 1.0 2.0 (\x y -> x + y)
75 let t1 = test1 1.0 2.0 (\x y -> x + y)
81 let t2 = test2
76 let t2 = test2
@@ -88,12 +83,9 @@ main = do
88 let t9 = test9
83 let t9 = test9
89 let t10 = test10
84 let t10 = test10
90 let t11 = test11
85 let t11 = test11
91− let t12 = test12 k 1.0 2.0
92− let t13 = test13 k 1.0 2.0
93 let t14 = test14 1.0 2.0
86 let t14 = test14 1.0 2.0
94 let t15 = test15 1.0 2.0
87 let t15 = test15 1.0 2.0
95 let t17 = test17
88 let t17 = test17
96 let t18 = test18
89 let t18 = test18
97 let t19 = test19
90 let t19 = test19
98− let t20 = test20
99 log "Done"
91 log "Done"
examples/passing/Operators/Other.pursnew file+7
@@ -0,0 +1,7 @@
1+module Other where
2+
3+foo :: String -> String
4+foo s = s
5+
6+baz :: String -> String -> String
7+baz s _ = s
examples/passing/OptimizerBug.purs+2−1
@@ -1,9 +1,10 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5x a = 1.0 + y a
6x a = 1.0 + y a
6
7
7y a = x a
8y a = x a
8
9
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/OptionalQualified.purs+2−3
@@ -1,7 +1,6 @@
1module Main where
1module Main where
2
2
3−-- qualified import with the "qualified" keyword
4−import qualified Prelude as P
3+import Prelude as P
5
4
6-- qualified import without the "qualified" keyword
5-- qualified import without the "qualified" keyword
7import Control.Monad.Eff.Console as Console
6import Control.Monad.Eff.Console as Console
@@ -9,5 +8,5 @@ import Control.Monad.Eff.Console as Console
9bind = P.bind
8bind = P.bind
10
9
11main = do
10main = do
12− message <- P.return "success!"
11+ message <- P.pure "Done"
13 Console.log message
12 Console.log message
examples/passing/OverlappingInstances.purs+17−13
@@ -1,13 +1,17 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
5−data A = A
7+data A = A
6−
8+
7−instance showA1 :: Show A where
9+instance showA1 :: Show A where
8− show A = "Instance 1"
10+ show A = "Instance 1"
9−
11+
10−instance showA2 :: Show A where
12+instance showA2 :: Show A where
11− show A = "Instance 2"
13+ show A = "Instance 2"
12−
14+
15+main = do
13−main = Test.Assert.assert $ show A == "Instance 1"
16+ assert $ show A == "Instance 1"
17+ log "Done"
examples/passing/OverlappingInstances2.purs+27−23
@@ -1,23 +1,27 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
5−data A = A | B
7+data A = A | B
6−
8+
7−instance eqA1 :: Eq A where
9+instance eqA1 :: Eq A where
8− eq A A = true
10+ eq A A = true
9− eq B B = true
11+ eq B B = true
10− eq _ _ = false
12+ eq _ _ = false
11−
13+
12−instance eqA2 :: Eq A where
14+instance eqA2 :: Eq A where
13− eq _ _ = true
15+ eq _ _ = true
14−
16+
15−instance ordA :: Ord A where
17+instance ordA :: Ord A where
16− compare A B = LT
18+ compare A B = LT
17− compare B A = GT
19+ compare B A = GT
18− compare _ _ = EQ
20+ compare _ _ = EQ
19−
21+
20−test :: forall a. (Ord a) => a -> a -> String
22+test :: forall a. (Ord a) => a -> a -> String
21−test x y = show $ x == y
23+test x y = show $ x == y
22−
24+
25+main = do
23−main = Test.Assert.assert $ test A B == "false"
26+ assert $ test A B == "false"
27+ log "Done"
examples/passing/OverlappingInstances3.purs+20−16
@@ -1,16 +1,20 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
5−class Foo a
7+class Foo a
6−
8+
7−instance foo1 :: Foo Number
9+instance foo1 :: Foo Number
8−
10+
9−instance foo2 :: Foo Number
11+instance foo2 :: Foo Number
10−
12+
11−test :: forall a. (Foo a) => a -> a
13+test :: forall a. (Foo a) => a -> a
12−test a = a
14+test a = a
13−
15+
14−test1 = test 0.0
16+test1 = test 0.0
15−
17+
18+main = do
16−main = Test.Assert.assert (test1 == 0.0)
19+ assert (test1 == 0.0)
20+ log "Done"
examples/passing/ParensInTypedBinder.pursnew file+20
@@ -0,0 +1,20 @@
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff (Eff)
5+import Control.Monad.Eff.Console (CONSOLE, log)
6+
7+foo :: Array Int
8+foo = do
9+ xss :: Array (Array Int) <- [[[1,2,3], [4, 5]], [[6]]]
10+ xs :: Array Int <- xss
11+ xs
12+
13+main ::
14+ forall eff.
15+ Eff
16+ ( console :: CONSOLE
17+ | eff
18+ )
19+ Unit
20+main = log "Done"
examples/passing/PartialFunction.purs+4−3
@@ -1,10 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Test.Assert
4+import Control.Monad.Eff
5+import Control.Monad.Eff.Console
5
6
6−fn :: Number -> Number
7+fn :: Partial => Number -> Number
7fn 0.0 = 0.0
8fn 0.0 = 0.0
8fn 1.0 = 2.0
9fn 1.0 = 2.0
9
10
10−main = assertThrows $ \_ -> fn 2.0
11+main = log "Done"
examples/passing/Patterns.purs+5−4
@@ -1,14 +1,15 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5test = \x -> case x of
6test = \x -> case x of
6− { str = "Foo", bool = true } -> true
7+ { str: "Foo", bool: true } -> true
7− { str = "Bar", bool = b } -> b
8+ { str: "Bar", bool: b } -> b
8 _ -> false
9 _ -> false
9
10
10f = \o -> case o of
11f = \o -> case o of
11− { foo = "Foo" } -> o.bar
12+ { foo: "Foo" } -> o.bar
12 _ -> 0
13 _ -> 0
13
14
14h = \o -> case o of
15h = \o -> case o of
@@ -19,4 +20,4 @@ isDesc :: Array Number -> Boolean
19isDesc [x, y] | x > y = true
20isDesc [x, y] | x > y = true
20isDesc _ = false
21isDesc _ = false
21
22
22−main = Control.Monad.Eff.Console.log "Done"
23+main = log "Done"
examples/passing/PendingConflictingImports.purs+5−14
@@ -1,17 +1,8 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
6−module B where
7−
8− thing :: Int
9− thing = 2
10−
11module Main where
1module Main where
12
2
13− -- No error as we never force `thing` to be resolved in `Main`
3+-- No error as we never force `thing` to be resolved in `Main`
14− import A
4+import A
15− import B
5+import B
6+import Control.Monad.Eff.Console (log)
16
7
17− main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/passing/PendingConflictingImports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/PendingConflictingImports/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/passing/PendingConflictingImports2.purs+6−10
@@ -1,14 +1,10 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
6module Main where
1module Main where
7
2
8− import A
3+import A
4+import Control.Monad.Eff.Console (log)
9
5
10− -- No error as we never force `thing` to be resolved in `Main`
6+-- No error as we never force `thing` to be resolved in `Main`
11− thing :: Int
7+thing :: Int
12− thing = 2
8+thing = 2
13
9
14− main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/PendingConflictingImports2/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/Person.purs+3−2
@@ -1,11 +1,12 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Person = Person { name :: String, age :: Number }
6data Person = Person { name :: String, age :: Number }
6
7
7showPerson :: Person -> String
8showPerson :: Person -> String
8showPerson = \p -> case p of
9showPerson = \p -> case p of
9− Person o -> o.name ++ ", aged " ++ show o.age
10+ Person o -> o.name <> ", aged " <> show o.age
10
11
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/PrimedTypeName.pursnew file+20
@@ -0,0 +1,20 @@
1+module Main (T, T', T'', T''', main) where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+data T a = T
7+type T' = T Unit
8+
9+data T'' = TP
10+
11+foreign import data T''' ∷ *
12+
13+instance eqT ∷ Eq T'' where
14+ eq _ _ = true
15+
16+type A' a b = b → a
17+
18+infixr 4 type A' as ↫
19+
20+main = log "Done"
examples/passing/QualifiedNames.pursnew file+11
@@ -0,0 +1,11 @@
1+module Main where
2+
3+import Prelude
4+import Either as Either
5+import Control.Monad.Eff.Console (log)
6+
7+either :: forall a b c. (a -> c) -> (b -> c) -> Either.Either a b -> c
8+either f _ (Either.Left x) = f x
9+either _ g (Either.Right y) = g y
10+
11+main = log (either id id (Either.Left "Done"))
examples/passing/QualifiedNames/Either.pursnew file+5
@@ -0,0 +1,5 @@
1+module Either where
2+
3+import Prelude
4+
5+data Either a b = Left a | Right b
examples/passing/QualifiedQualifiedImports.purs+2−2
@@ -1,6 +1,6 @@
1module Main where
1module Main where
2
2
3-- qualified import with qualified imported names
3-- qualified import with qualified imported names
4−import qualified Control.Monad.Eff.Console (log) as Console
4+import Control.Monad.Eff.Console (log) as Console
5
5
6−main = Console.log "Success!"
6+main = Console.log "Done"
examples/passing/Rank2Data.purs+30−29
@@ -1,29 +1,30 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude hiding (add)
3+import Prelude hiding (add)
4−
4+import Control.Monad.Eff.Console (log)
5+
5−data Id = Id forall a. a -> a
6+data Id = Id forall a. a -> a
6−
7+
7−runId = \id a -> case id of
8+runId = \id a -> case id of
8− Id f -> f a
9+ Id f -> f a
9−
10+
10−data Nat = Nat forall r. r -> (r -> r) -> r
11+data Nat = Nat forall r. r -> (r -> r) -> r
11−
12+
12−runNat = \nat -> case nat of
13+runNat = \nat -> case nat of
13− Nat f -> f 0.0 (\n -> n + 1.0)
14+ Nat f -> f 0.0 (\n -> n + 1.0)
14−
15+
15−zero' = Nat (\zero' _ -> zero')
16+zero' = Nat (\zero' _ -> zero')
16−
17+
17−succ = \n -> case n of
18+succ = \n -> case n of
18− Nat f -> Nat (\zero' succ -> succ (f zero' succ))
19+ Nat f -> Nat (\zero' succ -> succ (f zero' succ))
19−
20+
20−add = \n m -> case n of
21+add = \n m -> case n of
21− Nat f -> case m of
22+ Nat f -> case m of
22− Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
23+ Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
23−
24+
24−one' = succ zero'
25+one' = succ zero'
25−two = succ zero'
26+two = succ zero'
26−four = add two two
27+four = add two two
27−fourNumber = runNat four
28+fourNumber = runNat four
28−
29+
29−main = Control.Monad.Eff.Console.log "Done'"
30+main = log "Done"
examples/passing/Rank2Object.purs+1−1
@@ -6,6 +6,6 @@ import Control.Monad.Eff.Console
6data Foo = Foo { id :: forall a. a -> a }
6data Foo = Foo { id :: forall a. a -> a }
7
7
8foo :: Foo -> Number
8foo :: Foo -> Number
9−foo (Foo { id = f }) = f 0.0
9+foo (Foo { id: f }) = f 0.0
10
10
11main = log "Done"
11main = log "Done"
examples/passing/Rank2TypeSynonym.purs+3−2
@@ -1,7 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Control.Monad.Eff
4+import Control.Monad.Eff.Console (log, logShow)
5
5
6type Foo a = forall f. (Monad f) => f a
6type Foo a = forall f. (Monad f) => f a
7
7
@@ -13,4 +13,5 @@ bar = foo 3.0
13
13
14main = do
14main = do
15 x <- bar
15 x <- bar
16− Control.Monad.Eff.Console.print x
16+ logShow x
17+ log "Done"
examples/passing/Rank2Types.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5test1 :: (forall a. (a -> a)) -> Number
6test1 :: (forall a. (a -> a)) -> Number
6test1 = \f -> f 0.0
7test1 = \f -> f 0.0
@@ -8,4 +9,4 @@ test1 = \f -> f 0.0
8forever :: forall m a b. (forall a b. m a -> (a -> m b) -> m b) -> m a -> m b
9forever :: forall m a b. (forall a b. m a -> (a -> m b) -> m b) -> m a -> m b
9forever = \bind action -> bind action $ \_ -> forever bind action
10forever = \bind action -> bind action $ \_ -> forever bind action
10
11
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/ReExportQualified.purs+4−13
@@ -1,16 +1,7 @@
1−module A where
2− x = "Do"
3−
4−module B where
5− y = "ne"
6−
7−module C (module A, module M2) where
8− import A
9− import qualified B as M2
10−
11module Main where
1module Main where
12
2
13− import Prelude
3+import Prelude
14− import C
4+import C
5+import Control.Monad.Eff.Console (log)
15
6
16− main = Control.Monad.Eff.Console.log (x ++ y)
7+main = log (x <> y)
examples/passing/ReExportQualified/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A where
2+
3+x = "Do"
examples/passing/ReExportQualified/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+y = "ne"
examples/passing/ReExportQualified/C.pursnew file+4
@@ -0,0 +1,4 @@
1+module C (module A, module M2) where
2+
3+import A
4+import B as M2
examples/passing/RebindableSyntax.purs+43−39
@@ -1,39 +1,43 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−
4+import Control.Monad.Eff.Console (log)
5+
5−example1 :: String
6+example1 :: String
6−example1 = do
7+example1 = do
7− "Do"
8+ "Do"
8− " notation"
9+ " notation"
9− " for"
10+ " for"
10− " Semigroup"
11+ " Semigroup"
11− where
12+ where
12− bind x f = x <> f unit
13+ bind x f = x <> f unit
13−
14+
14−(*>) :: forall f a b. (Apply f) => f a -> f b -> f b
15+applySecond :: forall f a b. (Apply f) => f a -> f b -> f b
15−(*>) fa fb = const id <$> fa <*> fb
16+applySecond fa fb = const id <$> fa <*> fb
16−
17+
18+infixl 4 applySecond as *>
19+
17−newtype Const a b = Const a
20+newtype Const a b = Const a
18−
21+
19−runConst :: forall a b. Const a b -> a
22+runConst :: forall a b. Const a b -> a
20−runConst (Const a) = a
23+runConst (Const a) = a
21−
24+
22−instance functorConst :: Functor (Const a) where
25+instance functorConst :: Functor (Const a) where
23− map _ (Const a) = Const a
26+ map _ (Const a) = Const a
24−
27+
25−instance applyConst :: (Semigroup a) => Apply (Const a) where
28+instance applyConst :: (Semigroup a) => Apply (Const a) where
26− apply (Const a1) (Const a2) = Const (a1 <> a2)
29+ apply (Const a1) (Const a2) = Const (a1 <> a2)
27−
30+
28−example2 :: Const String Unit
31+example2 :: Const String Unit
29−example2 = do
32+example2 = do
30− Const "Do"
33+ Const "Do"
31− Const " notation"
34+ Const " notation"
32− Const " for"
35+ Const " for"
33− Const " Apply"
36+ Const " Apply"
34− where
37+ where
35− bind x f = x *> f unit
38+ bind x f = x *> f unit
36−
39+
37−main = do
40+main = do
38− Control.Monad.Eff.Console.log example1
41+ log example1
39− Control.Monad.Eff.Console.log $ runConst example2
42+ log $ runConst example2
43+ log "Done"
examples/passing/Recursion.purs+2−1
@@ -1,10 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5fib = \n -> case n of
6fib = \n -> case n of
6 0.0 -> 1.0
7 0.0 -> 1.0
7 1.0 -> 1.0
8 1.0 -> 1.0
8 n -> fib (n - 1.0) + fib (n - 2.0)
9 n -> fib (n - 1.0) + fib (n - 2.0)
9
10
10−main = Control.Monad.Eff.Console.log "Done"
11+main = log "Done"
examples/passing/RedefinedFixity.pursnew file+6
@@ -0,0 +1,6 @@
1+module Main where
2+
3+import M3
4+import Control.Monad.Eff.Console (log)
5+
6+main = log "Done"
examples/passing/RedefinedFixity/M1.pursnew file+6
@@ -0,0 +1,6 @@
1+module M1 where
2+
3+applyFn :: forall a b. (forall c d. c -> d) -> a -> b
4+applyFn f a = f a
5+
6+infixr 1000 applyFn as $
examples/passing/RedefinedFixity/M2.pursnew file+5
@@ -0,0 +1,5 @@
1+module M2 where
2+
3+import Prelude ()
4+
5+import M1
examples/passing/RedefinedFixity/M3.pursnew file+6
@@ -0,0 +1,6 @@
1+module M3 where
2+
3+import Prelude ()
4+
5+import M1
6+import M2
examples/passing/ReservedWords.purs+6−2
@@ -2,6 +2,8 @@
2module Main where
2module Main where
3
3
4import Prelude
4import Prelude
5+import Control.Monad.Eff
6+import Control.Monad.Eff.Console (log)
5
7
6o :: { type :: String }
8o :: { type :: String }
7o = { type: "o" }
9o = { type: "o" }
@@ -10,6 +12,8 @@ p :: { type :: String }
10p = o { type = "p" }
12p = o { type = "p" }
11
13
12f :: forall r. { type :: String | r } -> String
14f :: forall r. { type :: String | r } -> String
13−f { type = "p" } = "Done"
15+f { type: "p" } = "Done"
16+f _ = "Fail"
14
17
18+main :: Eff _ _
15−main = Control.Monad.Eff.Console.log $ f { type: p.type, foo: "bar" }
19+main = log $ f { type: p.type, foo: "bar" }
examples/passing/ResolvableScopeConflict.purs+9−21
@@ -1,25 +1,13 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
6−module B where
7−
8− thing :: Int
9− thing = 2
10−
11− zing :: Int
12− zing = 3
13−
14module Main where
1module Main where
15
2
16− import A (thing)
3+import A (thing)
17− import B
4+import B
5+import Control.Monad.Eff.Console (log)
18
6
19− -- Not an error as although we have `thing` in scope from both A and B, it is
7+-- Not an error as although we have `thing` in scope from both A and B, it is
20− -- imported explicitly from A, giving it a resolvable solution.
8+-- imported explicitly from A, giving it a resolvable solution.
21− what :: Boolean -> Int
9+what :: Boolean -> Int
22− what true = thing
10+what true = thing
23− what false = zing
11+what false = zing
24
12
25− main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/ResolvableScopeConflict/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/ResolvableScopeConflict/B.pursnew file+7
@@ -0,0 +1,7 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
5+
6+zing :: Int
7+zing = 3
examples/passing/ResolvableScopeConflict2.purs+10−17
@@ -1,22 +1,15 @@
1−module A where
2−
3− thing :: Int
4− thing = 2
5−
6− zing :: Int
7− zing = 3
8−
9module Main where
1module Main where
10
2
11− import A
3+import A
4+import Control.Monad.Eff.Console (log)
12
5
13− thing :: Int
6+thing :: Int
14− thing = 1
7+thing = 1
15
8
16− -- Not an error as although we have `thing` in scope from both Main and A,
9+-- Not an error as although we have `thing` in scope from both Main and A,
17− -- as the local declaration takes precedence over the implicit import
10+-- as the local declaration takes precedence over the implicit import
18− what :: Boolean -> Int
11+what :: Boolean -> Int
19− what true = thing
12+what true = thing
20− what false = zing
13+what false = zing
21
14
22− main = Control.Monad.Eff.Console.log "Done"
15+main = log "Done"
examples/passing/ResolvableScopeConflict2/A.pursnew file+7
@@ -0,0 +1,7 @@
1+module A where
2+
3+thing :: Int
4+thing = 2
5+
6+zing :: Int
7+zing = 3
examples/passing/ResolvableScopeConflict3.purs+5−11
@@ -1,15 +1,9 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
6module Main (thing, main, module A) where
1module Main (thing, main, module A) where
7
2
8− import A
3+import A
9−
10− thing :: Int
11− thing = 2
12−
13− main = Control.Monad.Eff.Console.log "Done"
4+import Control.Monad.Eff.Console (log)
14
5
6+thing :: Int
7+thing = 2
15
8
9+main = log "Done"
examples/passing/ResolvableScopeConflict3/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/RowConstructors.purs+3−2
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5type Foo = (x :: Number | (y :: Number | (z :: Number)))
6type Foo = (x :: Number | (y :: Number | (z :: Number)))
6type Bar = (x :: Number, y :: Number, z :: Number)
7type Bar = (x :: Number, y :: Number, z :: Number)
@@ -12,7 +13,7 @@ foo = { x: 0.0, y: 0.0, z: 0.0 }
12bar :: { | Bar }
13bar :: { | Bar }
13bar = { x: 0.0, y: 0.0, z: 0.0 }
14bar = { x: 0.0, y: 0.0, z: 0.0 }
14
15
15−id' :: Object Foo -> Object Bar
16+id' :: Record Foo -> Record Bar
16id' = id
17id' = id
17
18
18foo' :: { | Foo }
19foo' :: { | Foo }
@@ -39,4 +40,4 @@ wildcard { w: w } = { x: w, y: w, z: w, w: w }
39wildcard' :: { | Quux _ } -> Number
40wildcard' :: { | Quux _ } -> Number
40wildcard' { q: q } = q
41wildcard' { q: q } = q
41
42
42−main = Control.Monad.Eff.Console.log "Done"
43+main = log "Done"
examples/passing/RowPolyInstanceContext.purs+4−3
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5class T s m where
6class T s m where
6 state :: (s -> s) -> m Unit
7 state :: (s -> s) -> m Unit
@@ -11,12 +12,12 @@ instance st :: T s (S s) where
11 state f = S $ \s -> { new: f s, ret: unit }
12 state f = S $ \s -> { new: f s, ret: unit }
12
13
13test1 :: forall r . S { foo :: String | r } Unit
14test1 :: forall r . S { foo :: String | r } Unit
14−test1 = state $ \o -> o { foo = o.foo ++ "!" }
15+test1 = state $ \o -> o { foo = o.foo <> "!" }
15
16
16test2 :: forall m r . (T { foo :: String | r } m) => m Unit
17test2 :: forall m r . (T { foo :: String | r } m) => m Unit
17−test2 = state $ \o -> o { foo = o.foo ++ "!" }
18+test2 = state $ \o -> o { foo = o.foo <> "!" }
18
19
19main = do
20main = do
20 let t1 = test1
21 let t1 = test1
21 let t2 = test2
22 let t2 = test2
22− Control.Monad.Eff.Console.log "Done"
23+ log "Done"
examples/passing/RuntimeScopeIssue.purs+4−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
4
5
5class A a where
6class A a where
6 a :: a -> Boolean
7 a :: a -> Boolean
@@ -16,4 +17,6 @@ instance bNumber :: B Number where
16 b 0.0 = false
17 b 0.0 = false
17 b n = a (n - 1.0)
18 b n = a (n - 1.0)
18
19
19−main = Control.Monad.Eff.Console.print $ a 10.0
20+main = do
21+ logShow $ a 10.0
22+ log "Done"
examples/passing/ScopedTypeVariables.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5test1 :: forall a. (a -> a) -> a -> a
6test1 :: forall a. (a -> a) -> a -> a
6test1 f x = g (g x)
7test1 f x = g (g x)
@@ -33,4 +34,4 @@ test4 = h
33 j x = x
34 j x = x
34
35
35
36
36−main = Control.Monad.Eff.Console.log "Done"
37+main = log "Done"
examples/passing/Sequence.purs+2−1
@@ -2,6 +2,7 @@ module Main where
2
2
3import Prelude
3import Prelude
4import Control.Monad.Eff
4import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log)
5
6
6data List a = Cons a (List a) | Nil
7data List a = Cons a (List a) | Nil
7
8
@@ -12,4 +13,4 @@ instance sequenceList :: Sequence List where
12 sequence Nil = pure Nil
13 sequence Nil = pure Nil
13 sequence (Cons x xs) = Cons <$> x <*> sequence xs
14 sequence (Cons x xs) = Cons <$> x <*> sequence xs
14
15
15−main = sequence $ Cons (Control.Monad.Eff.Console.log "Done") Nil
16+main = sequence $ Cons (log "Done") Nil
examples/passing/SequenceDesugared.purs+5−4
@@ -2,6 +2,7 @@ module Main where
2
2
3import Prelude
3import Prelude
4import Control.Monad.Eff
4import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log)
5
6
6data List a = Cons a (List a) | Nil
7data List a = Cons a (List a) | Nil
7
8
@@ -31,7 +32,7 @@ sequenceList''' = Sequence ((\val -> case val of
31 Cons x xs -> Cons <$> x <*> sequence sequenceList''' xs) :: forall m a. (Monad m) => List (m a) -> m (List a))
32 Cons x xs -> Cons <$> x <*> sequence sequenceList''' xs) :: forall m a. (Monad m) => List (m a) -> m (List a))
32
33
33main = do
34main = do
34− sequence sequenceList $ Cons (Control.Monad.Eff.Console.log "Done") Nil
35+ sequence sequenceList $ Cons (log "Done") Nil
35− sequence sequenceList' $ Cons (Control.Monad.Eff.Console.log "Done") Nil
36+ sequence sequenceList' $ Cons (log "Done") Nil
36− sequence sequenceList'' $ Cons (Control.Monad.Eff.Console.log "Done") Nil
37+ sequence sequenceList'' $ Cons (log "Done") Nil
37− sequence sequenceList''' $ Cons (Control.Monad.Eff.Console.log "Done") Nil
38+ sequence sequenceList''' $ Cons (log "Done") Nil
examples/passing/ShadowedModuleName.purs+4−11
@@ -1,15 +1,8 @@
1−module Test where
2−
3− data Z = Z String
4−
5− runZ :: Z -> String
6− runZ (Z s) = s
7−
8module Main where
1module Main where
9
2
10− import Test
3+import Test
11− import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console
12
5
13− data Test = Test
6+data Test = Test
14
7
15− main = log (runZ (Z "done"))
8+main = log (runZ (Z "Done"))
examples/passing/ShadowedModuleName/Test.pursnew file+6
@@ -0,0 +1,6 @@
1+module Test where
2+
3+data Z = Z String
4+
5+runZ :: Z -> String
6+runZ (Z s) = s
examples/manual/passing/ShadowedName.purs → examples/passing/ShadowedName.pursrenamed+11−10
@@ -1,10 +1,11 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console
5−
5+import Control.Monad.Eff.Console (log)
6+
6−done :: String
7+done :: String
7−done = let str = "Not yet done" in
8+done = let str = "Not yet done" in
8− let str = "Done" in str
9+ let str = "Done" in str
9−
10+
10−main = Control.Monad.Eff.Console.log done
11+main = log done
examples/passing/ShadowedTCO.purs+21−18
@@ -1,18 +1,21 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude hiding (add)
3+import Prelude hiding (add)
4−
4+import Control.Monad.Eff.Console (log)
5+
5−runNat f = f 0.0 (\n -> n + 1.0)
6+runNat f = f 0.0 (\n -> n + 1.0)
6−
7+
7−zero' z _ = z
8+zero' z _ = z
8−
9+
9−succ f zero' succ = succ (f zero' succ)
10+succ f zero' succ = succ (f zero' succ)
10−
11+
11−add f g zero' succ = g (f zero' succ) succ
12+add f g zero' succ = g (f zero' succ) succ
12−
13+
13−one' = succ zero'
14+one' = succ zero'
14−two = succ one'
15+two = succ one'
15−four = add two two
16+four = add two two
16−fourNumber = runNat four
17+fourNumber = runNat four
17−
18+
19+main = do
18−main = Control.Monad.Eff.Console.log $ show fourNumber
20+ log $ show fourNumber
21+ log "Done"
examples/passing/ShadowedTCOLet.purs+15−9
@@ -1,9 +1,15 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−
4+import Partial.Unsafe (unsafePartial)
5+import Control.Monad.Eff
6+import Control.Monad.Eff.Console (log)
7+
5−f x y z =
8+f x y z =
6− let f 1.0 2.0 3.0 = 1.0
9+ let f 1.0 2.0 3.0 = 1.0
7− in f x z y
10+ in f x z y
8−
11+
12+main :: Eff _ _
13+main = do
9−main = Control.Monad.Eff.Console.log $ show $ f 1.0 3.0 2.0
14+ log $ show $ unsafePartial f 1.0 3.0 2.0
15+ log "Done"
examples/passing/SignedNumericLiterals.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5p = 0.5
6p = 0.5
6q = 1.0
7q = 1.0
@@ -14,4 +15,4 @@ f x = -x
14
15
15test1 = 2.0 - 1.0
16test1 = 2.0 - 1.0
16
17
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/StringEscapes.purs+17−15
@@ -1,15 +1,17 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude ((==), bind)
3+import Prelude ((==), bind)
4−import Test.Assert (assert)
4+import Test.Assert (assert)
5−
5+import Control.Monad.Eff.Console (log)
6+
6−singleCharacter = "\0\b\t\n\v\f\r\"\\" == "\x0\x8\x9\xA\xB\xC\xD\x22\x5C"
7+singleCharacter = "\0\b\t\n\v\f\r\"\\" == "\x0\x8\x9\xA\xB\xC\xD\x22\x5C"
7−hex = "\x1D306\x2603\x3C6\xE0\x0" == "𝌆☃φà\0"
8+hex = "\x1D306\x2603\x3C6\xE0\x0" == "𝌆☃φà\0"
8−decimal = "\119558\9731\966\224\0" == "𝌆☃φà\0"
9+decimal = "\119558\9731\966\224\0" == "𝌆☃φà\0"
9−surrogatePair = "\xD834\xDF06" == "\x1D306"
10+surrogatePair = "\xD834\xDF06" == "\x1D306"
10−
11+
11−main = do
12+main = do
12− assert singleCharacter
13+ assert singleCharacter
13− assert hex
14+ assert hex
14− assert decimal
15+ assert decimal
15− assert surrogatePair
16+ assert surrogatePair
17+ log "Done"
examples/passing/Superclasses1.purs+4−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
4
5
5class Su a where
6class Su a where
6 su :: a -> a
7 su :: a -> a
@@ -17,4 +18,6 @@ instance clNumber :: Cl Number where
17test :: forall a. (Cl a) => a -> a
18test :: forall a. (Cl a) => a -> a
18test a = su (cl a a)
19test a = su (cl a a)
19
20
20−main = Control.Monad.Eff.Console.print $ test 10.0
21+main = do
22+ logShow $ test 10.0
23+ log "Done"
examples/passing/Superclasses3.purs+1−1
@@ -28,7 +28,7 @@ instance applyMTrace :: Apply MTrace where
28 apply = ap
28 apply = ap
29
29
30instance applicativeMTrace :: Applicative MTrace where
30instance applicativeMTrace :: Applicative MTrace where
31− pure = MTrace <<< return
31+ pure = MTrace <<< pure
32
32
33instance bindMTrace :: Bind MTrace where
33instance bindMTrace :: Bind MTrace where
34 bind m f = MTrace (runMTrace m >>= (runMTrace <<< f))
34 bind m f = MTrace (runMTrace m >>= (runMTrace <<< f))
examples/passing/TCO.purs+7−7
@@ -1,20 +1,20 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Control.Monad.Eff.Console (print)
4+import Control.Monad.Eff.Console (log, logShow)
5
5
6main = do
6main = do
7 let f x = x + 1
7 let f x = x + 1
8 let v = 0
8 let v = 0
9− print (applyN 0 f v)
9+ logShow (applyN 0 f v)
10− print (applyN 1 f v)
10+ logShow (applyN 1 f v)
11− print (applyN 2 f v)
11+ logShow (applyN 2 f v)
12− print (applyN 3 f v)
12+ logShow (applyN 3 f v)
13− print (applyN 4 f v)
13+ logShow (applyN 4 f v)
14+ log "Done"
14
15
15applyN :: forall a. Int -> (a -> a) -> a -> a
16applyN :: forall a. Int -> (a -> a) -> a -> a
16applyN = go id
17applyN = go id
17 where
18 where
18 go f n _ | n <= 0 = f
19 go f n _ | n <= 0 = f
19 go f n g = go (f >>> g) (n - 1) g
20 go f n g = go (f >>> g) (n - 1) g
20−
examples/passing/TCOCase.purs+2−1
@@ -1,10 +1,11 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Data = One | More Data
6data Data = One | More Data
6
7
7−main = Control.Monad.Eff.Console.log (from (to 10000.0 One))
8+main = log (from (to 10000.0 One))
8 where
9 where
9 to 0.0 a = a
10 to 0.0 a = a
10 to n a = to (n - 1.0) (More a)
11 to n a = to (n - 1.0) (More a)
examples/passing/TailCall.purs+4−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
4
5
5data L a = C a (L a) | N
6data L a = C a (L a) | N
6
7
@@ -14,4 +15,6 @@ loop x = loop (x + 1.0)
14notATailCall = \x ->
15notATailCall = \x ->
15 (\notATailCall -> notATailCall x) (\x -> x)
16 (\notATailCall -> notATailCall x) (\x -> x)
16
17
18+main = do
17−main = Control.Monad.Eff.Console.print (test 0.0 (1.0 `C` (2.0 `C` (3.0 `C` N))))
19+ logShow (test 0.0 (1.0 `C` (2.0 `C` (3.0 `C` N))))
20+ log "Done"
examples/passing/Tick.purs+2−1
@@ -1,7 +1,8 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5test' x = x
6test' x = x
6
7
7−main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/passing/TopLevelCase.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5gcd :: Number -> Number -> Number
6gcd :: Number -> Number -> Number
6gcd 0.0 x = x
7gcd 0.0 x = x
@@ -15,4 +16,4 @@ data A = A
15
16
16parseTest A 0.0 = 0.0
17parseTest A 0.0 = 0.0
17
18
18−main = Control.Monad.Eff.Console.log "Done"
19+main = log "Done"
examples/passing/TransitiveImport.pursnew file+9
@@ -0,0 +1,9 @@
1+module Main where
2+
3+ import Prelude
4+ import Middle
5+ import Control.Monad.Eff.Console
6+
7+ main = do
8+ logShow (middle unit)
9+ log "Done"
examples/passing/TransitiveImport/Middle.pursnew file+5
@@ -0,0 +1,5 @@
1+module Middle where
2+
3+import Test (test)
4+
5+middle = test
examples/passing/TransitiveImport/Test.pursnew file+9
@@ -0,0 +1,9 @@
1+module Test where
2+
3+import Prelude
4+
5+class TestCls a where
6+ test :: a -> a
7+
8+instance unitTestCls :: TestCls Unit where
9+ test _ = unit
examples/passing/TypeClassMemberOrderChange.purs+16−13
@@ -1,13 +1,16 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−
4+import Control.Monad.Eff.Console (log)
5+
5−class Test a where
6+class Test a where
6− fn :: a -> a -> a
7+ fn :: a -> a -> a
7− val :: a
8+ val :: a
8−
9+
9−instance testBoolean :: Test Boolean where
10+instance testBoolean :: Test Boolean where
10− val = true
11+ val = true
11− fn x y = y
12+ fn x y = y
12−
13+
14+main = do
13−main = Control.Monad.Eff.Console.log (show (fn true val))
15+ log (show (fn true val))
16+ log "Done"
examples/passing/TypeClasses.purs+11−9
@@ -1,23 +1,24 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5test1 = \_ -> show "testing"
6test1 = \_ -> show "testing"
6
7
7−f :: forall a. (Prelude.Show a) => a -> String
8+f :: forall a. (Show a) => a -> String
8f x = show x
9f x = show x
9
10
10test2 = \_ -> f "testing"
11test2 = \_ -> f "testing"
11
12
12−test7 :: forall a. (Prelude.Show a) => a -> String
13+test7 :: forall a. (Show a) => a -> String
13test7 = show
14test7 = show
14
15
15test8 = \_ -> show $ "testing"
16test8 = \_ -> show $ "testing"
16
17
17data Data a = Data a
18data Data a = Data a
18
19
19−instance showData :: (Prelude.Show a) => Prelude.Show (Data a) where
20+instance showData :: (Show a) => Show (Data a) where
20− show (Data a) = "Data (" ++ show a ++ ")"
21+ show (Data a) = "Data (" <> show a <> ")"
21
22
22test3 = \_ -> show (Data "testing")
23test3 = \_ -> show (Data "testing")
23
24
@@ -53,9 +54,9 @@ instance bindMaybe :: Bind Maybe where
53instance monadMaybe :: Monad Maybe
54instance monadMaybe :: Monad Maybe
54
55
55test4 :: forall a m. (Monad m) => a -> m Number
56test4 :: forall a m. (Monad m) => a -> m Number
56−test4 = \_ -> return 1.0
57+test4 = \_ -> pure 1.0
57
58
58−test5 = \_ -> Just 1.0 >>= \n -> return (n + 1.0)
59+test5 = \_ -> Just 1.0 >>= \n -> pure (n + 1.0)
59
60
60ask r = r
61ask r = r
61
62
@@ -63,7 +64,8 @@ runReader r f = f r
63
64
64test9 _ = runReader 0.0 $ do
65test9 _ = runReader 0.0 $ do
65 n <- ask
66 n <- ask
66− return $ n + 1.0
67+ pure $ n + 1.0
67−
68−main = Control.Monad.Eff.Console.log (test7 "Done")
69
68
69+main = do
70+ log (test7 "Hello")
71+ log "Done"
examples/passing/TypeClassesInOrder.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5class Foo a where
6class Foo a where
6 foo :: a -> String
7 foo :: a -> String
@@ -8,4 +9,4 @@ class Foo a where
8instance fooString :: Foo String where
9instance fooString :: Foo String where
9 foo s = s
10 foo s = s
10
11
11−main = Control.Monad.Eff.Console.log $ foo "Done"
12+main = log $ foo "Done"
examples/passing/TypeClassesWithOverlappingTypeVariables.purs+3−2
@@ -1,11 +1,12 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Either a b = Left a | Right b
6data Either a b = Left a | Right b
6
7
7−instance functorEither :: Prelude.Functor (Either a) where
8+instance functorEither :: Functor (Either a) where
8 map _ (Left x) = Left x
9 map _ (Left x) = Left x
9 map f (Right y) = Right (f y)
10 map f (Right y) = Right (f y)
10
11
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/TypeDecl.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5k :: String -> Number -> String
6k :: String -> Number -> String
6k x y = x
7k x y = x
@@ -9,4 +10,4 @@ iterate :: forall a. Number -> (a -> a) -> a -> a
9iterate 0.0 f a = a
10iterate 0.0 f a = a
10iterate n f a = iterate (n - 1.0) f (f a)
11iterate n f a = iterate (n - 1.0) f (f a)
11
12
12−main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/TypeOperators.purs+13−27
@@ -1,34 +1,20 @@
1−module A
1+module Main where
2− ( Tuple(..)
3− , type (/\)
4− , (/\)
5− , Natural
6− , type (~>)
7− ) where
8−
9− data Tuple a b = Tuple a b
10−
11− infixl 6 Tuple as /\
12− infixl 6 type Tuple as /\
13−
14− type Natural f g = ∀ a. f a → g a
15−
16− infixr 0 type Natural as ~>
17
2
18− tup ∷ ∀ a b. a → b → b /\ a
3+import A (type (~>), type (/\), (/\))
19− tup a b = b /\ a
4+import Control.Monad.Eff.Console (log)
20
5
21− tupX ∷ ∀ a b c. a /\ b /\ c → c
6+natty ∷ ∀ f. f ~> f
22− tupX (a /\ b /\ c) = c
7+natty x = x
23
8
24−module Main where
9+data Compose f g a = Compose (f (g a))
25
10
26− import A (type (~>), type (/\), (/\))
11+testPrecedence1 ∷ ∀ f g. Compose f g ~> Compose f g
12+testPrecedence1 x = x
27
13
28− natty ∷ ∀ f. f ~> f
14+testPrecedence2 ∷ ∀ f g. f ~> g → f ~> g
29− natty x = x
15+testPrecedence2 nat fx = nat fx
30
16
31− swap ∷ ∀ a b. a /\ b → b /\ a
17+swap ∷ ∀ a b. a /\ b → b /\ a
32− swap (a /\ b) = b /\ a
18+swap (a /\ b) = b /\ a
33
19
34− main = Control.Monad.Eff.Console.log "Done"
20+main = log "Done"
examples/passing/TypeOperators/A.pursnew file+22
@@ -0,0 +1,22 @@
1+module A
2+( Tuple(..)
3+, type (/\)
4+, (/\)
5+, Natural
6+, type (~>)
7+) where
8+
9+data Tuple a b = Tuple a b
10+
11+infixl 6 Tuple as /\
12+infixl 6 type Tuple as /\
13+
14+type Natural f g = ∀ a. f a → g a
15+
16+infixr 0 type Natural as ~>
17+
18+tup ∷ ∀ a b. a → b → b /\ a
19+tup a b = b /\ a
20+
21+tupX ∷ ∀ a b c. a /\ b /\ c → c
22+tupX (a /\ b /\ c) = c
examples/passing/TypeSynonymInData.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5type A a = Array a
6type A a = Array a
6
7
@@ -8,4 +9,4 @@ data Foo a = Foo (A a) | Bar
8
9
9foo (Foo []) = Bar
10foo (Foo []) = Bar
10
11
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/TypeSynonyms.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5type Lens a b =
6type Lens a b =
6 { get :: a -> b
7 { get :: a -> b
@@ -24,4 +25,4 @@ fst =
24test1 :: forall a b c. Lens (Pair (Pair a b) c) a
25test1 :: forall a b c. Lens (Pair (Pair a b) c) a
25test1 = composeLenses fst fst
26test1 = composeLenses fst fst
26
27
27−main = Control.Monad.Eff.Console.log "Done"
28+main = log "Done"
examples/passing/TypeWildcards.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5testTopLevel :: _ -> _
6testTopLevel :: _ -> _
6testTopLevel n = n + 1.0
7testTopLevel n = n + 1.0
@@ -12,4 +13,4 @@ test f a = go (f a) a
12 go a1 a2 | a1 == a2 = a1
13 go a1 a2 | a1 == a2 = a1
13 go a1 _ = go (f a1) a1
14 go a1 _ = go (f a1) a1
14
15
15−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/TypeWildcardsRecordExtension.purs+2−1
@@ -1,8 +1,9 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5foo :: forall a. {b :: Number | a} -> {b :: Number | _}
6foo :: forall a. {b :: Number | a} -> {b :: Number | _}
6foo f = f
7foo f = f
7
8
8−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/TypeWithoutParens.purs+7−11
@@ -1,16 +1,12 @@
1−module Lib (X, Y) where
2−
3− data X = X
4− type Y = X
5−
6module Main where
1module Main where
7
2
8− import Lib (X, Y)
3+import Lib (X, Y)
4+import Control.Monad.Eff.Console (log)
9
5
10− idX :: X -> X
6+idX :: X -> X
11− idX x = x
7+idX x = x
12
8
13− idY :: Y -> Y
9+idY :: Y -> Y
14− idY y = y
10+idY y = y
15
11
16− main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/TypeWithoutParens/Lib.pursnew file+4
@@ -0,0 +1,4 @@
1+module Lib (X, Y) where
2+
3+data X = X
4+type Y = X
examples/passing/TypedBinders.purs+8−7
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Tuple a b = Tuple a b
6data Tuple a b = Tuple a b
6
7
@@ -31,27 +32,27 @@ instance monadStateState :: MonadState s (State s) where
31 get = State (\s -> Tuple s s)
32 get = State (\s -> Tuple s s)
32 put s = State (\_ -> Tuple s {})
33 put s = State (\_ -> Tuple s {})
33
34
34−modify :: forall m s. (Prelude.Monad m, MonadState s m) => (s -> s) -> m {}
35+modify :: forall m s. (Monad m, MonadState s m) => (s -> s) -> m {}
35modify f = do
36modify f = do
36 s <- get
37 s <- get
37 put (f s)
38 put (f s)
38
39
39test :: Tuple String String
40test :: Tuple String String
40test = runState "" $ do
41test = runState "" $ do
41− modify $ (++) "World!"
42+ modify $ (<>) "World!"
42− modify $ (++) "Hello, "
43+ modify $ (<>) "Hello, "
43 str :: String <- get
44 str :: String <- get
44− return str
45+ pure str
45
46
46test2 :: (Int -> Int) -> Int
47test2 :: (Int -> Int) -> Int
47test2 = (\(f :: Int -> Int) -> f 10)
48test2 = (\(f :: Int -> Int) -> f 10)
48
49
49−test3 :: Int -> Boolean
50+test3 :: Int -> Boolean
50test3 n = case n of
51test3 n = case n of
51 (0 :: Int) -> true
52 (0 :: Int) -> true
52 _ -> false
53 _ -> false
53
54
54−test4 :: Tuple Int Int -> Tuple Int Int
55+test4 :: Tuple Int Int -> Tuple Int Int
55test4 = (\(Tuple a b :: Tuple Int Int) -> Tuple b a)
56test4 = (\(Tuple a b :: Tuple Int Int) -> Tuple b a)
56
57
57type Int1 = Int
58type Int1 = Int
@@ -64,4 +65,4 @@ main = do
64 t2 = test2 id
65 t2 = test2 id
65 t3 = test3 1
66 t3 = test3 1
66 t4 = test4 (Tuple 1 0)
67 t4 = test4 (Tuple 1 0)
67− Control.Monad.Eff.Console.log "Done"
68+ log "Done"
examples/passing/TypedWhere.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data E a b = L a | R b
6data E a b = L a | R b
6
7
@@ -14,4 +15,4 @@ lefts = go N
14 go ls (C (L a) rest) = go (C a ls) rest
15 go ls (C (L a) rest) = go (C a ls) rest
15 go ls (C _ rest) = go ls rest
16 go ls (C _ rest) = go ls rest
16
17
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/UTF8Sourcefile.purs+8−10
@@ -1,10 +1,8 @@
1−module Main where
1+module Main where
2−
2+
3−import Control.Monad.Eff.Console
3+import Control.Monad.Eff.Console
4−
4+
5−-- '→' is multibyte sequence \u2192.
5+-- '→' is multibyte sequence \u2192.
6−utf8multibyte = "Hello λ→ world!!"
6+utf8multibyte = "Hello λ→ world!!"
7−
7+
8−main = do
8+main = log "Done"
9− log "done"
10−
examples/passing/UnderscoreIdent.purs+3−1
@@ -1,11 +1,13 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5data Data_type = Con_Structor | Con_2 String
6data Data_type = Con_Structor | Con_2 String
6
7
7type Type_name = Data_type
8type Type_name = Data_type
8
9
9done (Con_2 s) = s
10done (Con_2 s) = s
11+done _ = "Failed"
10
12
11−main = Control.Monad.Eff.Console.log (done (Con_2 "Done"))
13+main = log (done (Con_2 "Done"))
examples/passing/UnicodeIdentifier.purs+3−1
@@ -1,5 +1,7 @@
1module Main where
1module Main where
2
2
3+import Control.Monad.Eff.Console (log)
4+
3f asgård = asgård
5f asgård = asgård
4
6
5−main = Control.Monad.Eff.Console.log (f "Done")
7+main = log (f "Done")
examples/passing/UnicodeOperators.purs+3−1
@@ -1,5 +1,7 @@
1module Main where
1module Main where
2
2
3+import Control.Monad.Eff.Console (log)
4+
3compose :: forall a b c. (b -> c) -> (a -> b) -> a -> c
5compose :: forall a b c. (b -> c) -> (a -> b) -> a -> c
4compose f g a = f (g a)
6compose f g a = f (g a)
5
7
@@ -17,4 +19,4 @@ emptySet _ = true
17
19
18test2 = 1 ∈ emptySet
20test2 = 1 ∈ emptySet
19
21
20−main = Control.Monad.Eff.Console.log "Done"
22+main = log "Done"
examples/passing/UnicodeType.purs+8−9
@@ -1,23 +1,22 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5−class (Monad m) ⇐ Monad1 m where
6+class Monad m ⇐ Monad1 m where
6 f1 :: Int
7 f1 :: Int
7
8
8−class (Monad m) <= Monad2 m where
9+class Monad m <= Monad2 m where
9 f2 :: Int
10 f2 :: Int
10
11
11f ∷ ∀ m. Monad m ⇒ Int → m Int
12f ∷ ∀ m. Monad m ⇒ Int → m Int
12f n = do
13f n = do
13− n' ← return n
14+ n' ← pure n
14− return n'
15+ pure n'
15
16
16f' :: forall m. Monad m => Int -> m Int
17f' :: forall m. Monad m => Int -> m Int
17f' n = do
18f' n = do
18− n' <- return n
19+ n' <- pure n
19− return n'
20+ pure n'
20
21
21−(←→) a b = a ←→ b
22−
23−main = Control.Monad.Eff.Console.log "Done"
22+main = log "Done"
examples/passing/Unit.purs+4−2
@@ -1,6 +1,8 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (logShow, log)
5
5
6+main = do
6−main = print (const unit $ "Hello world")
7+ logShow (const unit $ "Hello world")
8+ log "Done"
examples/passing/UnknownInTypeClassLookup.purs+2−1
@@ -1,6 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5class EQ a b
6class EQ a b
6
7
@@ -11,4 +12,4 @@ test _ _ = "Done"
11
12
12runTest a = test a a
13runTest a = test a a
13
14
14−main = Control.Monad.Eff.Console.log $ runTest 0.0
15+main = log $ runTest 0.0
examples/passing/UntupledConstraints.purs+1−1
@@ -1,7 +1,7 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (log)
5
5
6class Show a <= Nonsense a where
6class Show a <= Nonsense a where
7 method :: a -> a
7 method :: a -> a
examples/passing/Where.purs+11−11
@@ -1,8 +1,9 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Partial.Unsafe (unsafePartial)
4import Control.Monad.Eff
5import Control.Monad.Eff
5−import Control.Monad.ST
6+import Control.Monad.Eff.Console (logShow, log)
6
7
7test1 x = y
8test1 x = y
8 where
9 where
@@ -14,15 +15,12 @@ test2 x y = x' + y'
14 x' = x + 1.0
15 x' = x + 1.0
15 y' = y + 1.0
16 y' = y + 1.0
16
17
17−
18test3 = f 1.0 2.0 3.0
18test3 = f 1.0 2.0 3.0
19 where f x y z = x + y + z
19 where f x y z = x + y + z
20
20
21−
22test4 = f (+) [1.0, 2.0]
21test4 = f (+) [1.0, 2.0]
23 where f x [y, z] = x y z
22 where f x [y, z] = x y z
24
23
25−
26test5 = g 10.0
24test5 = g 10.0
27 where
25 where
28 f x | x > 0.0 = g (x / 2.0) + 1.0
26 f x | x > 0.0 = g (x / 2.0) + 1.0
@@ -39,11 +37,13 @@ test7 x = go x
39 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
37 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
40 go y = go $ (y + x / y) / 2.0
38 go y = go $ (y + x / y) / 2.0
41
39
40+main :: Eff _ _
42main = do
41main = do
43− Control.Monad.Eff.Console.print (test1 1.0)
42+ logShow (test1 1.0)
44− Control.Monad.Eff.Console.print (test2 1.0 2.0)
43+ logShow (test2 1.0 2.0)
45− Control.Monad.Eff.Console.print test3
44+ logShow test3
46− Control.Monad.Eff.Console.print test4
45+ unsafePartial (logShow test4)
47− Control.Monad.Eff.Console.print test5
46+ logShow test5
48− Control.Monad.Eff.Console.print test6
47+ logShow test6
49− Control.Monad.Eff.Console.print (test7 100.0)
48+ logShow (test7 100.0)
49+ log "Done"
examples/manual/passing/WildcardType.purs → examples/passing/WildcardType.pursrenamed+12−13
@@ -1,13 +1,12 @@
1−module Main where
1+module Main where
2−
2+
3−import Prelude
3+import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (log)
5−
5+
6−f1 :: (_ -> _) -> _
6+f1 :: (_ -> _) -> _
7−f1 g = g 1
7+f1 g = g 1
8−
8+
9−f2 :: _ -> _
9+f2 :: _ -> _
10−f2 _ = "Done"
10+f2 _ = "Done"
11−
11+
12−main = Control.Monad.Eff.Console.log $ f1 f2
12+main = log $ f1 f2
13−
examples/passing/iota.purs+3−1
@@ -1,9 +1,11 @@
1module Main where
1module Main where
2
2
3+import Control.Monad.Eff.Console (log)
4+
3s = \x -> \y -> \z -> x z (y z)
5s = \x -> \y -> \z -> x z (y z)
4
6
5k = \x -> \y -> x
7k = \x -> \y -> x
6
8
7iota = \x -> x s k
9iota = \x -> x s k
8
10
9−main = Control.Monad.Eff.Console.log "Done"
11+main = log "Done"
examples/passing/s.purs+2−1
@@ -1,7 +1,8 @@
1module Main where
1module Main where
2
2
3import Prelude
3import Prelude
4+import Control.Monad.Eff.Console (log)
4
5
5s = \x y z -> x z (y z)
6s = \x y z -> x z (y z)
6
7
7−main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/warning/DuplicateExportRef.pursnew file+30
@@ -0,0 +1,30 @@
1+-- @shouldWarnWith DuplicateExportRef
2+-- @shouldWarnWith DuplicateExportRef
3+-- @shouldWarnWith DuplicateExportRef
4+-- @shouldWarnWith DuplicateExportRef
5+-- @shouldWarnWith DuplicateExportRef
6+-- @shouldWarnWith DuplicateExportRef
7+-- @shouldWarnWith DuplicateExportRef
8+module Main
9+ ( X(X, X), X
10+ , fn, fn
11+ , (!), (!)
12+ , class Y, class Y
13+ , Natural, type (~>), type (~>)
14+ , module Prelude, module Prelude
15+ ) where
16+
17+import Prelude (Unit)
18+
19+data X = X
20+
21+fn :: X -> X -> X
22+fn _ _ = X
23+
24+infix 2 fn as !
25+
26+class Y a
27+
28+type Natural f g = forall a. f a -> g a
29+
30+infixl 1 type Natural as ~>
examples/warning/DuplicateImport.pursnew file+10
@@ -0,0 +1,10 @@
1+-- @shouldWarnWith DuplicateImport
2+module Main where
3+
4+import Prelude (Unit, unit, pure)
5+import Prelude (Unit, unit, pure)
6+
7+import Control.Monad.Eff (Eff)
8+
9+main :: Eff () Unit
10+main = pure unit
examples/warning/DuplicateImportRef.pursnew file+18
@@ -0,0 +1,18 @@
1+-- @shouldWarnWith DuplicateImportRef
2+-- @shouldWarnWith DuplicateImportRef
3+-- @shouldWarnWith DuplicateImportRef
4+-- @shouldWarnWith DuplicateImportRef
5+module Main where
6+
7+import Prelude
8+ ( Unit, Unit
9+ , unit, unit
10+ , class Functor, class Functor
11+ , (<>), (<>)
12+ )
13+
14+u :: Unit
15+u = unit <> unit
16+
17+fid :: forall f a. Functor f => f a -> f a
18+fid fa = fa
examples/warning/DuplicateSelectiveImport.pursnew file+10
@@ -0,0 +1,10 @@
1+-- @shouldWarnWith DuplicateSelectiveImport
2+module Main where
3+
4+import Prelude (Unit, unit)
5+import Prelude (pure)
6+
7+import Control.Monad.Eff (Eff)
8+
9+main :: Eff () Unit
10+main = pure unit
examples/warning/HidingImport.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldWarnWith HidingImport
2+-- @shouldWarnWith HidingImport
3+module Main where
4+
5+import Prelude hiding (one)
6+import Control.Monad.Eff hiding (runPure)
7+
8+main :: Eff () Unit
9+main = pure unit
examples/warning/ImplicitImport.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldWarnWith ImplicitImport
2+-- @shouldWarnWith ImplicitImport
3+module Main where
4+
5+import Prelude
6+import Control.Monad.Eff
7+
8+main :: Eff () Unit
9+main = pure unit
examples/warning/ImplicitQualifiedImport.pursnew file+11
@@ -0,0 +1,11 @@
1+-- @shouldWarnWith ImplicitQualifiedImport
2+-- @shouldWarnWith ImplicitQualifiedImport
3+module Main where
4+
5+import Data.Unit
6+
7+import Control.Monad.Eff as E
8+import Control.Monad.Eff.Console as E
9+
10+main :: E.Eff (console :: E.CONSOLE) Unit
11+main = E.log "test"
examples/warning/MissingTypeDeclaration.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldWarnWith MissingTypeDeclaration
2+module Main where
3+
4+x = 0
examples/warning/OverlappingInstances.pursnew file+17
@@ -0,0 +1,17 @@
1+-- @shouldWarnWith OverlappingInstances
2+module Main where
3+
4+class Test a where
5+ test :: a -> a
6+
7+instance testRefl :: Test a where
8+ test x = x
9+
10+instance testInt :: Test Int where
11+ test _ = 0
12+
13+-- The OverlappingInstances instances warning only arises when there are two
14+-- choices for a dictionary, not when the instances are defined. So without
15+-- `value` this module would not raise a warning.
16+value :: Int
17+value = test 1
examples/warning/OverlappingPattern.pursnew file+15
@@ -0,0 +1,15 @@
1+-- @shouldWarnWith OverlappingPattern
2+-- @shouldWarnWith OverlappingPattern
3+module Main where
4+
5+data X = A | B
6+
7+pat1 :: X -> Boolean
8+pat1 A = true
9+pat1 A = true
10+pat1 B = false
11+
12+pat2 :: X -> Boolean
13+pat2 A = true
14+pat2 _ = false
15+pat2 B = false
examples/warning/ScopeShadowing.pursnew file+13
@@ -0,0 +1,13 @@
1+-- @shouldWarnWith ScopeShadowing
2+module Main where
3+
4+import Prelude
5+
6+-- No warning at the definition, only when the name is later resolved
7+data Unit = Unit
8+
9+-- This is only a warning as the `Prelude` import is implicit. If `Unit` was
10+-- named explicitly in an import list, then this refernce to `Unit`
11+-- would be a `ScopeConflict` error instead.
12+test :: Unit
13+test = const Unit unit
examples/warning/ShadowedTypeVar.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldWarnWith ShadowedTypeVar
2+module Main where
3+
4+f :: forall a. (forall a. a -> a) -> a -> a
5+f g x = g x
examples/warning/UnnecessaryFFIModule.jsnew file+1
@@ -0,0 +1 @@
1+exports.out = null;
examples/warning/UnnecessaryFFIModule.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldWarnWith UnnecessaryFFIModule
2+module Main where
3+
4+t :: Boolean
5+t = true
examples/warning/UnusedDctorExplicitImport.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldWarnWith UnusedDctorExplicitImport
2+module Main where
3+
4+import Data.Ordering (Ordering(EQ, LT))
5+
6+f :: Ordering -> Ordering
7+f EQ = EQ
8+f x = x
examples/warning/UnusedDctorImportAll.pursnew file+7
@@ -0,0 +1,7 @@
1+-- @shouldWarnWith UnusedDctorImport
2+module Main where
3+
4+import Data.Ordering (Ordering(..))
5+
6+f :: Ordering -> Ordering
7+f x = x
examples/warning/UnusedDctorImportExplicit.pursnew file+7
@@ -0,0 +1,7 @@
1+-- @shouldWarnWith UnusedDctorImport
2+module Main where
3+
4+import Data.Ordering (Ordering(EQ))
5+
6+f :: Ordering -> Ordering
7+f x = x
examples/warning/UnusedExplicitImport.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldWarnWith UnusedExplicitImport
2+module Main where
3+
4+import Prelude (Unit, unit, pure, bind)
5+import Control.Monad.Eff (Eff)
6+
7+main :: Eff () Unit
8+main = pure unit
examples/warning/UnusedFFIImplementations.jsnew file+2
@@ -0,0 +1,2 @@
1+exports.yes = true;
2+exports.no = false;
examples/warning/UnusedFFIImplementations.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldWarnWith UnusedFFIImplementations
2+module Main where
3+
4+foreign import yes :: Boolean
examples/warning/UnusedImport.pursnew file+14
@@ -0,0 +1,14 @@
1+-- @shouldWarnWith UnusedImport
2+-- @shouldWarnWith UnusedImport
3+-- @shouldWarnWith UnusedImport
4+module Main where
5+
6+import Data.Unit (Unit, unit)
7+
8+-- All of the below are unused
9+import Control.Monad.Eff
10+import Control.Monad.Eff.Console as Console
11+import Test.Assert ()
12+
13+main :: Unit
14+main = unit
examples/warning/UnusedTypeVar.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldWarnWith UnusedTypeVar
2+module Main where
3+
4+f :: forall a b. a -> a
5+f x = x
examples/warning/WildcardInferredType.pursnew file+23
@@ -0,0 +1,23 @@
1+-- @shouldWarnWith WildcardInferredType
2+-- @shouldWarnWith WildcardInferredType
3+-- @shouldWarnWith WildcardInferredType
4+-- @shouldWarnWith WildcardInferredType
5+module Main where
6+
7+x :: Int
8+x = 0 :: _
9+
10+y :: _
11+y = 0
12+
13+z :: Int
14+z =
15+ let n :: _
16+ n = 0
17+ in n
18+
19+w :: Int
20+w = n
21+ where
22+ n :: _
23+ n = 0
hierarchy/Main.hs+2−3
@@ -65,7 +65,7 @@ compile (HierarchyOptions inputGlob mOutput) = do
65 input <- glob inputGlob
65 input <- glob inputGlob
66 modules <- readInput input
66 modules <- readInput input
67 case modules of
67 case modules of
68− Left errs -> hPutStr stderr (P.prettyPrintMultipleErrors False errs) >> exitFailure
68+ Left errs -> hPutStr stderr (P.prettyPrintMultipleErrors P.defaultPPEOptions errs) >> exitFailure
69 Right ms -> do
69 Right ms -> do
70 for_ ms $ \(P.Module _ _ moduleName decls _) ->
70 for_ ms $ \(P.Module _ _ moduleName decls _) ->
71 let name = runModuleName moduleName
71 let name = runModuleName moduleName
@@ -84,7 +84,7 @@ compile (HierarchyOptions inputGlob mOutput) = do
84
84
85superClasses :: P.Declaration -> [SuperMap]
85superClasses :: P.Declaration -> [SuperMap]
86superClasses (P.TypeClassDeclaration sub _ supers@(_:_) _) =
86superClasses (P.TypeClassDeclaration sub _ supers@(_:_) _) =
87− fmap (\(P.Qualified _ super, _) -> SuperMap (Right (super, sub))) supers
87+ fmap (\(P.Constraint (P.Qualified _ super) _ _) -> SuperMap (Right (super, sub))) supers
88superClasses (P.TypeClassDeclaration sub _ _ _) = [SuperMap (Left sub)]
88superClasses (P.TypeClassDeclaration sub _ _ _) = [SuperMap (Left sub)]
89superClasses (P.PositionedDeclaration _ _ decl) = superClasses decl
89superClasses (P.PositionedDeclaration _ _ decl) = superClasses decl
90superClasses _ = []
90superClasses _ = []
@@ -113,4 +113,3 @@ main = execParser opts >>= compile
113 infoModList = fullDesc <> headerInfo <> footerInfo
113 infoModList = fullDesc <> headerInfo <> footerInfo
114 headerInfo = header "hierarchy - Creates a GraphViz directed graph of PureScript TypeClasses"
114 headerInfo = header "hierarchy - Creates a GraphViz directed graph of PureScript TypeClasses"
115 footerInfo = footer $ "hierarchy " ++ showVersion Paths.version
115 footerInfo = footer $ "hierarchy " ++ showVersion Paths.version
116−
pcc/Main.hs+86−75
@@ -15,84 +15,99 @@
15{-# LANGUAGE DataKinds #-}
15{-# LANGUAGE DataKinds #-}
16{-# LANGUAGE FlexibleContexts #-}
16{-# LANGUAGE FlexibleContexts #-}
17{-# LANGUAGE RecordWildCards #-}
17{-# LANGUAGE RecordWildCards #-}
18+{-# LANGUAGE ScopedTypeVariables #-}
18{-# LANGUAGE TupleSections #-}
19{-# LANGUAGE TupleSections #-}
19
20
20module Main where
21module Main where
21
22
22−import Control.Applicative
23+import Control.Applicative
23−import Control.Monad
24+import Control.Monad
24−import Control.Monad.Error.Class (MonadError(..))
25−import Control.Monad.Writer.Strict
25+import Control.Monad.Writer.Strict
26
26
27−import Data.Version (showVersion)
27+import qualified Data.Aeson as A
28+import Data.Bool (bool)
29+import qualified Data.ByteString.Lazy as B
30+import qualified Data.ByteString.UTF8 as BU8
28import qualified Data.Map as M
31import qualified Data.Map as M
32+import Data.Version (showVersion)
29
33
30−import Options.Applicative as Opts
34+import qualified Language.PureScript as P
35+import Language.PureScript.Errors.JSON
31
36
32−import System.Exit (exitSuccess, exitFailure)
37+import Options.Applicative as Opts
33−import System.IO (hPutStrLn, stderr)
34−import System.IO.UTF8
35
38
36−import qualified Language.PureScript as P
37import qualified Paths_purescript as Paths
39import qualified Paths_purescript as Paths
38
40
41+import qualified System.Console.ANSI as ANSI
42+import System.Exit (exitSuccess, exitFailure)
43+import System.FilePath.Glob (glob)
44+import System.IO (hSetEncoding, hPutStrLn, stdout, stderr, utf8)
45+import System.IO.UTF8
46+
39−import Make
47+import Make
40−import Makefile
48+import Makefile
41
49
42−data PCCOptions = PCCOptions
50+data PCCMakeOptions = PCCMakeOptions
43 { pccmInput :: [FilePath]
51 { pccmInput :: [FilePath]
44− , pccmForeignInput :: [FilePath]
45 , pccmOutputDir :: FilePath
52 , pccmOutputDir :: FilePath
46 , pccmOpts :: P.Options
53 , pccmOpts :: P.Options
47 , pccmUsePrefix :: Bool
54 , pccmUsePrefix :: Bool
55+ , pccmJSONErrors :: Bool
48 }
56 }
49
57
50−data InputOptions = InputOptions
58+-- | Argumnets: verbose, use JSON, warnings, errors
51− { ioInputFiles :: [FilePath]
59+printWarningsAndErrors :: Bool -> Bool -> P.MultipleErrors -> Either P.MultipleErrors a -> IO ()
52− }
60+printWarningsAndErrors verbose False warnings errors = do
53−
61+ cc <- bool Nothing (Just P.defaultCodeColor) <$> ANSI.hSupportsANSI stderr
54−compile :: PCCOptions -> IO ()
62+ let ppeOpts = P.defaultPPEOptions { P.ppeCodeColor = cc, P.ppeFull = verbose }
55−compile (PCCOptions input _ outputDir opts usePrefix) = do
63+ when (P.nonEmpty warnings) $
56− when (null input) generateMakefile
64+ hPutStrLn stderr (P.prettyPrintMultipleWarnings ppeOpts warnings)
57− moduleFiles <- readInput (InputOptions input)
65+ case errors of
58− case runWriterT (parseInputs moduleFiles []) of
59 Left errs -> do
66 Left errs -> do
60− hPutStrLn stderr (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
67+ hPutStrLn stderr (P.prettyPrintMultipleErrors ppeOpts errs)
61 exitFailure
68 exitFailure
62− Right ((ms, _), warnings) -> do
69+ Right _ -> return ()
63− when (P.nonEmpty warnings) $
70+printWarningsAndErrors verbose True warnings errors = do
64− hPutStrLn stderr (P.prettyPrintMultipleWarnings (P.optionsVerboseErrors opts) warnings)
71+ hPutStrLn stderr . BU8.toString . B.toStrict . A.encode $
72+ JSONResult (toJSONErrors verbose P.Warning warnings)
73+ (either (toJSONErrors verbose P.Error) (const []) errors)
74+ either (const exitFailure) (const (return ())) errors
75+
76+compile :: PCCMakeOptions -> IO ()
77+compile PCCMakeOptions{..} = do
78+ input <- globWarningOnMisses (unless pccmJSONErrors . warnFileTypeNotFound) pccmInput
79+ when (null input && not pccmJSONErrors) $ do
80+ generateMakefile
81+ exitSuccess
82+ moduleFiles <- readInput input
83+ (makeErrors, makeWarnings) <- runMake pccmOpts $ do
84+ ms <- P.parseModulesFromFiles id moduleFiles
65− let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, fp)) ms
85+ let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, Right fp)) ms
66− makeActions = buildMakeActions outputDir filePathMap usePrefix
86+ let makeActions = buildMakeActions pccmOutputDir filePathMap pccmUsePrefix
67− (e, warnings') <- runMake opts $ P.make makeActions (map snd ms)
87+ P.make makeActions (map snd ms)
68− case e of
88+ printWarningsAndErrors (P.optionsVerboseErrors pccmOpts) pccmJSONErrors makeWarnings makeErrors
69− Left errs -> do
89+ exitSuccess
70− putStrLn (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
90+
71− exitFailure
91+warnFileTypeNotFound :: String -> IO ()
72− Right _ -> exitSuccess
92+warnFileTypeNotFound = hPutStrLn stderr . ("pcc: No files found using pattern: " ++)
73−
93+
94+globWarningOnMisses :: (String -> IO ()) -> [FilePath] -> IO [FilePath]
95+globWarningOnMisses warn = concatMapM globWithWarning
96+ where
97+ globWithWarning pattern = do
98+ paths <- glob pattern
99+ when (null paths) $ warn pattern
100+ return paths
101+ concatMapM f = liftM concat . mapM f
102+
74−readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
103+readInput :: [FilePath] -> IO [(FilePath, String)]
75−readInput InputOptions{..} = forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readUTF8File inFile
104+readInput inputFiles = forM inputFiles $ \inFile -> (inFile, ) <$> readUTF8File inFile
76−
77−parseInputs :: (Functor m, Applicative m, MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m)
78− => [(Either P.RebuildPolicy FilePath, String)]
79− -> [(FilePath, P.ForeignJS)]
80− -> m ([(Either P.RebuildPolicy FilePath, P.Module)], M.Map P.ModuleName FilePath)
81−parseInputs modules foreigns =
82− (,) <$> P.parseModulesFromFiles (either (const "") id) modules
83− <*> P.parseForeignModulesFromFiles foreigns
84
105
85inputFile :: Parser FilePath
106inputFile :: Parser FilePath
86inputFile = strArgument $
107inputFile = strArgument $
87 metavar "FILE"
108 metavar "FILE"
88 <> help "The input .purs file(s)"
109 <> help "The input .purs file(s)"
89
110
90−inputForeignFile :: Parser FilePath
91−inputForeignFile = strOption $
92− short 'f'
93− <> long "ffi"
94− <> help "The input .js file(s) providing foreign import implementations"
95−
96outputDirectory :: Parser FilePath
111outputDirectory :: Parser FilePath
97outputDirectory = strOption $
112outputDirectory = strOption $
98 short 'o'
113 short 'o'
@@ -101,37 +116,26 @@ outputDirectory = strOption $
101 <> showDefault
116 <> showDefault
102 <> help "The output directory"
117 <> help "The output directory"
103
118
104−requirePath :: Parser (Maybe FilePath)
105−requirePath = optional $ strOption $
106− short 'r'
107− <> long "require-path"
108− <> help "The path prefix to use for require() calls in the generated code"
109−
110noTco :: Parser Bool
119noTco :: Parser Bool
111noTco = switch $
120noTco = switch $
112 long "no-tco"
121 long "no-tco"
113 <> help "Disable tail call optimizations"
122 <> help "Disable tail call optimizations"
114
123
115−noPrelude :: Parser Bool
116−noPrelude = switch $
117− long "no-prelude"
118− <> help "Omit the automatic Prelude import"
119−
120noMagicDo :: Parser Bool
124noMagicDo :: Parser Bool
121noMagicDo = switch $
125noMagicDo = switch $
122 long "no-magic-do"
126 long "no-magic-do"
123− <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad."
127+ <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad"
124
128
125noOpts :: Parser Bool
129noOpts :: Parser Bool
126noOpts = switch $
130noOpts = switch $
127 long "no-opts"
131 long "no-opts"
128− <> help "Skip the optimization phase."
132+ <> help "Skip the optimization phase"
129
133
130comments :: Parser Bool
134comments :: Parser Bool
131comments = switch $
135comments = switch $
132 short 'c'
136 short 'c'
133 <> long "comments"
137 <> long "comments"
134− <> help "Include comments in the generated code."
138+ <> help "Include comments in the generated code"
135
139
136verboseErrors :: Parser Bool
140verboseErrors :: Parser Bool
137verboseErrors = switch $
141verboseErrors = switch $
@@ -145,11 +149,16 @@ noPrefix = switch $
145 <> long "no-prefix"
149 <> long "no-prefix"
146 <> help "Do not include comment header"
150 <> help "Do not include comment header"
147
151
152+jsonErrors :: Parser Bool
153+jsonErrors = switch $
154+ long "json-errors"
155+ <> help "Print errors to stderr as JSON"
148sourceMaps :: Parser Bool
156sourceMaps :: Parser Bool
149sourceMaps = switch $
157sourceMaps = switch $
150 long "source-maps"
158 long "source-maps"
151 <> help "Generate source maps"
159 <> help "Generate source maps"
152
160
161+
153options :: Parser P.Options
162options :: Parser P.Options
154options = P.Options <$> noTco
163options = P.Options <$> noTco
155 <*> noMagicDo
164 <*> noMagicDo
@@ -157,20 +166,22 @@ options = P.Options <$> noTco
157 <*> noOpts
166 <*> noOpts
158 <*> verboseErrors
167 <*> verboseErrors
159 <*> (not <$> comments)
168 <*> (not <$> comments)
160− <*> requirePath
161 <*> sourceMaps
169 <*> sourceMaps
162
170
163−pccOptions :: Parser PCCOptions
171+pccMakeOptions :: Parser PCCMakeOptions
164−pccOptions = PCCOptions <$> many inputFile
172+pccMakeOptions = PCCMakeOptions <$> many inputFile
165− <*> many inputForeignFile
166− <*> outputDirectory
173+ <*> outputDirectory
167− <*> options
174+ <*> options
168− <*> (not <$> noPrefix)
175+ <*> (not <$> noPrefix)
176+ <*> jsonErrors
169
177
170main :: IO ()
178main :: IO ()
179+main = do
180+ hSetEncoding stdout utf8
181+ hSetEncoding stderr utf8
171−main = execParser opts >>= compile
182+ execParser opts >>= compile
172 where
183 where
173− opts = info (version <*> helper <*> pccOptions) infoModList
184+ opts = info (version <*> helper <*> pccMakeOptions) infoModList
174 infoModList = fullDesc <> headerInfo <> footerInfo
185 infoModList = fullDesc <> headerInfo <> footerInfo
175 headerInfo = header "pcc - Compiles PureScript to C++11"
186 headerInfo = header "pcc - Compiles PureScript to C++11"
176 footerInfo = footer $ "pcc " ++ showVersion Paths.version
187 footerInfo = footer $ "pcc " ++ showVersion Paths.version
pcc/Make.hs+4−7
@@ -15,6 +15,7 @@
15{-# LANGUAGE DataKinds #-}
15{-# LANGUAGE DataKinds #-}
16{-# LANGUAGE FlexibleContexts #-}
16{-# LANGUAGE FlexibleContexts #-}
17{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17{-# LANGUAGE GeneralizedNewtypeDeriving #-}
18+{-# LANGUAGE PatternGuards #-}
18{-# LANGUAGE TupleSections #-}
19{-# LANGUAGE TupleSections #-}
19{-# LANGUAGE TemplateHaskell #-}
20{-# LANGUAGE TemplateHaskell #-}
20
21
@@ -29,9 +30,7 @@ import Control.Monad.Error.Class (MonadError(..))
29import Control.Monad.Reader
30import Control.Monad.Reader
30
31
31import Data.FileEmbed (embedFile)
32import Data.FileEmbed (embedFile)
32−import Data.List (intercalate)
33import Data.Maybe (fromMaybe)
33import Data.Maybe (fromMaybe)
34−import Data.String (fromString)
35import Data.Time.Clock
34import Data.Time.Clock
36import Data.Version (showVersion)
35import Data.Version (showVersion)
37import qualified Data.Map as M
36import qualified Data.Map as M
@@ -158,11 +157,9 @@ buildMakeActions outputDir filePathMap usePrefix =
158
157
159 writeTextFile :: FilePath -> String -> Make ()
158 writeTextFile :: FilePath -> String -> Make ()
160 writeTextFile path text = makeIO (const (ErrorMessage [] $ CannotWriteFile path)) $ do
159 writeTextFile path text = makeIO (const (ErrorMessage [] $ CannotWriteFile path)) $ do
161− mkdirp path
162− writeFile path text
163− where
164− mkdirp :: FilePath -> IO ()
165− mkdirp = createDirectoryIfMissing True . takeDirectory
160+ createDirectoryIfMissing True (takeDirectory path)
161+ _ <- tryIOError $ writeFile path text -- TODO: intended to ignore "file busy", fix properly asap
162+ return ()
166
163
167 -- | Render a progress message
164 -- | Render a progress message
168 renderProgressMessage :: P.ProgressMessage -> String
165 renderProgressMessage :: P.ProgressMessage -> String
pcc/Makefile+1−1
@@ -55,7 +55,7 @@ DEPS = $(SRCS:.cc=.d)
55$(BIN): $(OBJS)
55$(BIN): $(OBJS)
56 @echo "Linking" $(BIN_DIR)/$(BIN)
56 @echo "Linking" $(BIN_DIR)/$(BIN)
57 @mkdir -p $(BIN_DIR)
57 @mkdir -p $(BIN_DIR)
58− @$(CXX) $(LDFLAGS) $^ -o $(BIN_DIR)/$@
58+ @$(CXX) $^ -o $(BIN_DIR)/$@ $(LDFLAGS)
59
59
60-include $(DEPS)
60-include $(DEPS)
61
61
pcc/Makefile.hs+1−1
@@ -10,13 +10,13 @@
10--
10--
11-------------------------------------------------------------------------------
11-------------------------------------------------------------------------------
12{-# LANGUAGE OverloadedStrings #-}
12{-# LANGUAGE OverloadedStrings #-}
13+{-# LANGUAGE PatternGuards #-}
13{-# LANGUAGE TemplateHaskell #-}
14{-# LANGUAGE TemplateHaskell #-}
14
15
15module Makefile where
16module Makefile where
16
17
17import Control.Monad (when)
18import Control.Monad (when)
18import Data.FileEmbed (embedFile)
19import Data.FileEmbed (embedFile)
19−import Data.List
20import System.Environment (getExecutablePath)
20import System.Environment (getExecutablePath)
21import System.Directory (doesFileExist)
21import System.Directory (doesFileExist)
22
22
pcc/TestMain.hs+15−8
@@ -49,7 +49,7 @@ main = do
49
49
50 -- Auto-generate Makefile
50 -- Auto-generate Makefile
51 setCurrentDirectory outputDir
51 setCurrentDirectory outputDir
52− callProcess "../.cabal-sandbox/bin/pcc" []
52+ callProcess "pcc" []
53
53
54 let tests = filter (`notElem` skipped) passingTestCases
54 let tests = filter (`notElem` skipped) passingTestCases
55
55
@@ -62,6 +62,11 @@ main = do
62 putStrLn $ "Compiling test " ++ inputFile ++ " ..."
62 putStrLn $ "Compiling test " ++ inputFile ++ " ..."
63 setCurrentDirectory outputDir
63 setCurrentDirectory outputDir
64 copyFile (passingDir </> inputFile) (srcDir </> inputFile)
64 copyFile (passingDir </> inputFile) (srcDir </> inputFile)
65+
66+ let testCaseDir = passingDir </> (takeWhile (/='.') inputFile)
67+ testCaseDirExists <- doesDirectoryExist testCaseDir
68+ when testCaseDirExists $ callProcess "cp" ["-R", testCaseDir, srcDir]
69+
65 callProcess "make" ["clean"]
70 callProcess "make" ["clean"]
66 callProcess "make" ["debug"]
71 callProcess "make" ["debug"]
67 --
72 --
@@ -70,6 +75,7 @@ main = do
70 callProcess ("output" </> "bin" </> "main") []
75 callProcess ("output" </> "bin" </> "main") []
71
76
72 removeFile (srcDir </> inputFile)
77 removeFile (srcDir </> inputFile)
78+ when testCaseDirExists $ callProcess "rm" ["-rf", srcDir </> (takeWhile (/='.') inputFile)]
73
79
74 -- TODO: support failing test cases
80 -- TODO: support failing test cases
75 --
81 --
@@ -92,12 +98,13 @@ repo = "git://github.com/pure11/"
92packages :: [(String, String)]
98packages :: [(String, String)]
93-------------------------------------------------------------------------------
99-------------------------------------------------------------------------------
94packages =
100packages =
95− [ ("purescript-eff", "")
101+ [ ("purescript-eff", "pure11-0.9")
96− , ("purescript-prelude", "")
102+ , ("purescript-prelude", "pure11-0.9")
97− , ("purescript-assert", "")
103+ , ("purescript-assert", "pure11-0.9")
98− , ("purescript-st", "")
104+ , ("purescript-st", "pure11-0.9")
99− , ("purescript-console", "")
105+ , ("purescript-console", "pure11-0.9")
100− , ("purescript-functions", "")
106+ , ("purescript-functions", "pure11-0.9")
107+ , ("purescript-partial", "pure11-0.9")
101 ]
108 ]
102
109
103-------------------------------------------------------------------------------
110-------------------------------------------------------------------------------
@@ -116,5 +123,5 @@ fetchPackages = do
116skipped :: [String]
123skipped :: [String]
117-------------------------------------------------------------------------------
124-------------------------------------------------------------------------------
118skipped =
125skipped =
119− [ "ExplicitImportReExport.purs" -- OK, test has no main (would pass otherwise)
126+ [ "NumberLiterals.purs" -- unreliable float comparison, test manually
120 ]
127 ]
pcc/include/purescript.cc+2−2
@@ -45,7 +45,7 @@ auto any::operator()() const -> any {
45 return (*variant.e)();
45 return (*variant.e)();
46}
46}
47
47
48−any::operator integer() const {
48+any::operator int() const {
49 RETURN_VALUE(Type::Integer, i,)
49 RETURN_VALUE(Type::Integer, i,)
50}
50}
51
51
@@ -121,7 +121,7 @@ auto any::operator[](const size_t rhs) const -> const any& {
121auto any::operator[](const any& rhs) const -> const any& {
121auto any::operator[](const any& rhs) const -> const any& {
122 const any& variant = unthunkVariant(*this);
122 const any& variant = unthunkVariant(*this);
123 assert(variant.type == Type::Array);
123 assert(variant.type == Type::Array);
124− return (*variant.a)[cast<integer>(rhs)];
124+ return (*variant.a)[cast<int>(rhs)];
125}
125}
126
126
127auto any::contains(const char key[]) const -> bool {
127auto any::contains(const char key[]) const -> bool {
pcc/include/purescript.hh+14−29
@@ -19,6 +19,7 @@
19
19
20#if defined(DEBUG)
20#if defined(DEBUG)
21 #include <cassert>
21 #include <cassert>
22+ #include <climits>
22#else
23#else
23 #define NDEBUG
24 #define NDEBUG
24 #undef assert
25 #undef assert
@@ -36,7 +37,6 @@
36
37
37namespace PureScript {
38namespace PureScript {
38
39
39−using integer = std::intptr_t;
40using cstring = const char *;
40using cstring = const char *;
41using nullptr_t = std::nullptr_t;
41using nullptr_t = std::nullptr_t;
42
42
@@ -46,9 +46,6 @@ public:
46 runtime_error(const char message[]) : std::runtime_error(std::string(message)) {}
46 runtime_error(const char message[]) : std::runtime_error(std::string(message)) {}
47};
47};
48
48
49−const integer INTEGER_MIN = INTPTR_MIN;
50−const integer INTEGER_MAX = INTPTR_MAX;
51−
52const bool undefined = false;
49const bool undefined = false;
53const size_t constructor = 0;
50const size_t constructor = 0;
54
51
@@ -128,7 +125,7 @@ class any {
128 private:
125 private:
129 union {
126 union {
130 mutable thunk t;
127 mutable thunk t;
131− mutable integer i;
128+ mutable int i;
132 mutable double d;
129 mutable double d;
133 mutable char c;
130 mutable char c;
134 mutable bool b;
131 mutable bool b;
@@ -147,9 +144,11 @@ class any {
147
144
148 public:
145 public:
149
146
150− any(const integer val) noexcept : type(Type::Integer), i(val) {}
151 any(const int val) noexcept : type(Type::Integer), i(val) {}
147 any(const int val) noexcept : type(Type::Integer), i(val) {}
152− any(const unsigned int val) noexcept : type(Type::Integer), i(val) {}
148+ any(const long int_value) noexcept : type(Type::Integer), i(int_value) {
149+ assert(int_value >= INT_MIN && int_value <= INT_MAX);
150+ }
151+
153 any(const double val) noexcept : type(Type::Double), d(val) {}
152 any(const double val) noexcept : type(Type::Double), d(val) {}
154 any(const char val) noexcept : type(Type::Character), c(val) {}
153 any(const char val) noexcept : type(Type::Character), c(val) {}
155
154
@@ -305,7 +304,7 @@ class any {
305 auto operator()(const as_thunk) const -> const any&;
304 auto operator()(const as_thunk) const -> const any&;
306 auto operator()() const -> any;
305 auto operator()() const -> any;
307
306
308− operator integer() const;
307+ operator int() const;
309 operator double() const;
308 operator double() const;
310 operator bool() const;
309 operator bool() const;
311 operator char() const;
310 operator char() const;
@@ -338,20 +337,12 @@ class any {
338 return lhs op (ty)rhs; \
337 return lhs op (ty)rhs; \
339 } \
338 } \
340
339
341− #define DEFINE_INT_OPERATOR(op, rty) \
342− inline friend auto operator op (const any& lhs, int rhs) -> rty { \
343− return (integer)lhs op (integer)rhs; \
344− } \
345− inline friend auto operator op (int lhs, const any& rhs) -> rty { \
346− return (integer)lhs op (integer)rhs; \
347− }
348−
349 #define DECLARE_COMPARISON_OPERATOR(op) \
340 #define DECLARE_COMPARISON_OPERATOR(op) \
350 friend auto operator op (const any&, const any&) -> bool; \
341 friend auto operator op (const any&, const any&) -> bool; \
351− DEFINE_OPERATOR(op, integer, bool) \
342+ DEFINE_OPERATOR(op, int, bool) \
352 DEFINE_OPERATOR(op, double, bool) \
343 DEFINE_OPERATOR(op, double, bool) \
353 DEFINE_OPERATOR(op, char, bool) \
344 DEFINE_OPERATOR(op, char, bool) \
354− DEFINE_INT_OPERATOR(op, bool) \
345+ DEFINE_OPERATOR(op, bool, bool) \
355 friend auto operator op (const any&, const char * const) -> bool; \
346 friend auto operator op (const any&, const char * const) -> bool; \
356 friend auto operator op (const char * const, const any&) -> bool;
347 friend auto operator op (const char * const, const any&) -> bool;
357
348
@@ -364,39 +355,34 @@ class any {
364
355
365 friend auto operator+(const any&, const any&) -> any;
356 friend auto operator+(const any&, const any&) -> any;
366
357
367− DEFINE_OPERATOR(+, integer, integer)
358+ DEFINE_OPERATOR(+, int, int)
368 DEFINE_OPERATOR(+, double, double)
359 DEFINE_OPERATOR(+, double, double)
369 DEFINE_OPERATOR(+, char, char)
360 DEFINE_OPERATOR(+, char, char)
370− DEFINE_INT_OPERATOR(+, integer)
371 friend auto operator+(const any& lhs, const char * const rhs) -> std::string;
361 friend auto operator+(const any& lhs, const char * const rhs) -> std::string;
372 friend auto operator+(const char * const lhs, const any& rhs) -> std::string;
362 friend auto operator+(const char * const lhs, const any& rhs) -> std::string;
373
363
374 friend auto operator-(const any&, const any&) -> any;
364 friend auto operator-(const any&, const any&) -> any;
375
365
376− DEFINE_OPERATOR(-, integer, integer)
366+ DEFINE_OPERATOR(-, int, int)
377 DEFINE_OPERATOR(-, double, double)
367 DEFINE_OPERATOR(-, double, double)
378 DEFINE_OPERATOR(-, char, char)
368 DEFINE_OPERATOR(-, char, char)
379− DEFINE_INT_OPERATOR(-, integer)
380
369
381 friend auto operator*(const any&, const any&) -> any;
370 friend auto operator*(const any&, const any&) -> any;
382
371
383− DEFINE_OPERATOR(*, integer, integer)
372+ DEFINE_OPERATOR(*, int, int)
384 DEFINE_OPERATOR(*, double, double)
373 DEFINE_OPERATOR(*, double, double)
385 DEFINE_OPERATOR(*, char, char)
374 DEFINE_OPERATOR(*, char, char)
386− DEFINE_INT_OPERATOR(*, integer)
387
375
388 friend auto operator/(const any&, const any&) -> any;
376 friend auto operator/(const any&, const any&) -> any;
389
377
390− DEFINE_OPERATOR(/, integer, integer)
378+ DEFINE_OPERATOR(/, int, int)
391 DEFINE_OPERATOR(/, double, double)
379 DEFINE_OPERATOR(/, double, double)
392 DEFINE_OPERATOR(/, char, char)
380 DEFINE_OPERATOR(/, char, char)
393− DEFINE_INT_OPERATOR(/, integer)
394
381
395 friend auto operator%(const any&, const any&) -> any;
382 friend auto operator%(const any&, const any&) -> any;
396
383
397− DEFINE_OPERATOR(%, integer, integer)
384+ DEFINE_OPERATOR(%, int, int)
398 DEFINE_OPERATOR(%, char, char)
385 DEFINE_OPERATOR(%, char, char)
399− DEFINE_INT_OPERATOR(%, integer)
400
386
401 friend auto operator-(const any&) -> any; // unary negate
387 friend auto operator-(const any&) -> any; // unary negate
402};
388};
@@ -435,7 +421,6 @@ inline auto cast(const any& a) ->
435#undef WITH_ALLOCATOR
421#undef WITH_ALLOCATOR
436#undef IS_POINTER_TYPE
422#undef IS_POINTER_TYPE
437#undef DEFINE_OPERATOR
423#undef DEFINE_OPERATOR
438−#undef DEFINE_INT_OPERATOR
439#undef DECLARE_COMPARISON_OPERATOR
424#undef DECLARE_COMPARISON_OPERATOR
440
425
441#endif // PureScript_HH
426#endif // PureScript_HH
psc-bundle/Main.hs+2−20
@@ -6,7 +6,6 @@
6-- | Bundles compiled PureScript modules for the browser.
6-- | Bundles compiled PureScript modules for the browser.
7module Main (main) where
7module Main (main) where
8
8
9−import Data.Maybe
10import Data.Traversable (for)
9import Data.Traversable (for)
11import Data.Version (showVersion)
10import Data.Version (showVersion)
12
11
@@ -16,7 +15,7 @@ import Control.Monad.Error.Class
16import Control.Monad.Trans.Except
15import Control.Monad.Trans.Except
17import Control.Monad.IO.Class
16import Control.Monad.IO.Class
18
17
19−import System.FilePath (takeFileName, takeDirectory)
18+import System.FilePath (takeDirectory)
20import System.FilePath.Glob (glob)
19import System.FilePath.Glob (glob)
21import System.Exit (exitFailure)
20import System.Exit (exitFailure)
22import System.IO (stderr, stdout, hPutStrLn, hSetEncoding, utf8)
21import System.IO (stderr, stdout, hPutStrLn, hSetEncoding, utf8)
@@ -36,17 +35,8 @@ data Options = Options
36 , optionsEntryPoints :: [String]
35 , optionsEntryPoints :: [String]
37 , optionsMainModule :: Maybe String
36 , optionsMainModule :: Maybe String
38 , optionsNamespace :: String
37 , optionsNamespace :: String
39− , optionsRequirePath :: Maybe FilePath
40 } deriving Show
38 } deriving Show
41
39
42−-- | Given a filename, assuming it is in the correct place on disk, infer a ModuleIdentifier.
43−guessModuleIdentifier :: (MonadError ErrorMessage m) => FilePath -> m ModuleIdentifier
44−guessModuleIdentifier filename = ModuleIdentifier (takeFileName (takeDirectory filename)) <$> guessModuleType (takeFileName filename)
45− where
46− guessModuleType "index.js" = pure Regular
47− guessModuleType "foreign.js" = pure Foreign
48− guessModuleType name = throwError $ UnsupportedModulePath name
49−
50-- | The main application function.
40-- | The main application function.
51-- This function parses the input files, performs dead code elimination, filters empty modules
41-- This function parses the input files, performs dead code elimination, filters empty modules
52-- and generates and prints the final Javascript bundle.
42-- and generates and prints the final Javascript bundle.
@@ -63,7 +53,7 @@ app Options{..} = do
63
53
64 let entryIds = map (`ModuleIdentifier` Regular) optionsEntryPoints
54 let entryIds = map (`ModuleIdentifier` Regular) optionsEntryPoints
65
55
66− bundle input entryIds optionsMainModule optionsNamespace optionsRequirePath
56+ bundle input entryIds optionsMainModule optionsNamespace
67
57
68-- | Command line options parser.
58-- | Command line options parser.
69options :: Parser Options
59options :: Parser Options
@@ -72,7 +62,6 @@ options = Options <$> some inputFile
72 <*> many entryPoint
62 <*> many entryPoint
73 <*> optional mainModule
63 <*> optional mainModule
74 <*> namespace
64 <*> namespace
75− <*> optional requirePath
76 where
65 where
77 inputFile :: Parser FilePath
66 inputFile :: Parser FilePath
78 inputFile = strArgument $
67 inputFile = strArgument $
@@ -104,19 +93,12 @@ options = Options <$> some inputFile
104 <> showDefault
93 <> showDefault
105 <> help "Specify the namespace that PureScript modules will be exported to when running in the browser."
94 <> help "Specify the namespace that PureScript modules will be exported to when running in the browser."
106
95
107− requirePath :: Parser FilePath
108− requirePath = strOption $
109− short 'r'
110− <> long "require-path"
111− <> help "The path prefix used in require() calls in the generated JavaScript [deprecated]"
112−
113-- | Make it go.
96-- | Make it go.
114main :: IO ()
97main :: IO ()
115main = do
98main = do
116 hSetEncoding stdout utf8
99 hSetEncoding stdout utf8
117 hSetEncoding stderr utf8
100 hSetEncoding stderr utf8
118 opts <- execParser (info (version <*> helper <*> options) infoModList)
101 opts <- execParser (info (version <*> helper <*> options) infoModList)
119− when (isJust (optionsRequirePath opts)) $ hPutStrLn stderr "The require-path option is deprecated and will be removed in PureScript 0.9."
120 output <- runExceptT (app opts)
102 output <- runExceptT (app opts)
121 case output of
103 case output of
122 Left err -> do
104 Left err -> do
psc-docs/Main.hs+1−1
@@ -95,7 +95,7 @@ docgen (PSCDocsOptions fmt inputGlob output) = do
95 Right x ->
95 Right x ->
96 return x
96 return x
97 Left err -> do
97 Left err -> do
98− hPutStrLn stderr $ P.prettyPrintMultipleErrors False err
98+ hPutStrLn stderr $ P.prettyPrintMultipleErrors P.defaultPPEOptions err
99 exitFailure
99 exitFailure
100
100
101 takeByName = takeModulesByName D.modName
101 takeByName = takeModulesByName D.modName
psc-ide-client/Main.hs+6−16
@@ -5,16 +5,15 @@ import Prelude ()
5import Prelude.Compat
5import Prelude.Compat
6
6
7import Control.Exception
7import Control.Exception
8−import Data.Text (Text)
9−import qualified Data.Text as T
8+import qualified Data.ByteString.Char8 as BS8
10−import qualified Data.Text.IO as T
9+import qualified Data.Text.IO as T
11−import Data.Version (showVersion)
10+import Data.Version (showVersion)
12import Network
11import Network
13import Options.Applicative
12import Options.Applicative
14import System.Exit
13import System.Exit
15import System.IO
14import System.IO
16
15
17−import qualified Paths_purescript as Paths
16+import qualified Paths_purescript as Paths
18
17
19data Options = Options
18data Options = Options
20 { optionsPort :: PortID
19 { optionsPort :: PortID
@@ -41,16 +40,7 @@ client port = do
41 ("Couldn't connect to psc-ide-server on port: " ++
40 ("Couldn't connect to psc-ide-server on port: " ++
42 show port ++ " Error: " ++ show e) >>
41 show port ++ " Error: " ++ show e) >>
43 exitFailure)
42 exitFailure)
44− cmd <- T.getLine
45− -- Temporary fix for emacs windows bug
46− let cleanedCmd = removeSurroundingTicks cmd
47− --
48− T.hPutStrLn h cleanedCmd
43+ T.hPutStrLn h =<< T.getLine
49− res <- T.hGetLine h
44+ BS8.putStrLn =<< BS8.hGetLine h
50− putStrLn (T.unpack res)
51 hFlush stdout
45 hFlush stdout
52 hClose h
46 hClose h
53−
54−-- TODO: Fix this in the emacs plugin by using a real process over shellcommands
55−removeSurroundingTicks :: Text -> Text
56−removeSurroundingTicks = T.dropWhile (== '\'') . T.dropWhileEnd (== '\'')
psc-ide-server/Main.hs+39−56
@@ -12,28 +12,22 @@
12-- The server accepting commands for psc-ide
12-- The server accepting commands for psc-ide
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE ConstraintKinds #-}
16{-# LANGUAGE FlexibleContexts #-}
15{-# LANGUAGE FlexibleContexts #-}
17{-# LANGUAGE MultiParamTypeClasses #-}
16{-# LANGUAGE MultiParamTypeClasses #-}
18{-# LANGUAGE OverloadedStrings #-}
17{-# LANGUAGE OverloadedStrings #-}
19{-# LANGUAGE PackageImports #-}
18{-# LANGUAGE PackageImports #-}
20{-# LANGUAGE TemplateHaskell #-}
19{-# LANGUAGE TemplateHaskell #-}
20+{-# LANGUAGE NoImplicitPrelude #-}
21
21
22module Main where
22module Main where
23
23
24−import Prelude ()
24+import Protolude
25−import Prelude.Compat
26
25
27−import Control.Concurrent (forkFinally)
26+import qualified Data.Aeson as Aeson
28import Control.Concurrent.STM
27import Control.Concurrent.STM
29−import Control.Exception (bracketOnError, catchJust)
30−import Control.Monad
31−import Control.Monad.Error.Class
32import "monad-logger" Control.Monad.Logger
28import "monad-logger" Control.Monad.Logger
33−import Control.Monad.Reader
34−import Control.Monad.Trans.Except
35−import qualified Data.Text as T
36import qualified Data.Text.IO as T
29import qualified Data.Text.IO as T
30+import qualified Data.ByteString.Lazy.Char8 as BS8
37import Data.Version (showVersion)
31import Data.Version (showVersion)
38import Language.PureScript.Ide
32import Language.PureScript.Ide
39import Language.PureScript.Ide.Util
33import Language.PureScript.Ide.Util
@@ -44,19 +38,16 @@ import Network hiding (socketPort, accept)
44import Network.BSD (getProtocolNumber)
38import Network.BSD (getProtocolNumber)
45import Network.Socket hiding (PortNumber, Type,
39import Network.Socket hiding (PortNumber, Type,
46 sClose)
40 sClose)
47−import Options.Applicative
41+import Options.Applicative hiding ((<>))
48import System.Directory
42import System.Directory
49import System.FilePath
43import System.FilePath
50−import System.IO
44+import System.IO hiding (putStrLn, print)
51import System.IO.Error (isEOFError)
45import System.IO.Error (isEOFError)
52
46
53import qualified Paths_purescript as Paths
47import qualified Paths_purescript as Paths
54
48
55−-- "Borrowed" from the Idris Compiler
56−-- Copied from upstream impl of listenOn
57−-- bound to localhost interface instead of iNADDR_ANY
58−listenOnLocalhost :: PortID -> IO Socket
49+listenOnLocalhost :: PortNumber -> IO Socket
59−listenOnLocalhost (PortNumber port) = do
50+listenOnLocalhost port = do
60 proto <- getProtocolNumber "tcp"
51 proto <- getProtocolNumber "tcp"
61 localhost <- inet_addr "127.0.0.1"
52 localhost <- inet_addr "127.0.0.1"
62 bracketOnError
53 bracketOnError
@@ -67,66 +58,59 @@ listenOnLocalhost (PortNumber port) = do
67 bindSocket sock (SockAddrInet port localhost)
58 bindSocket sock (SockAddrInet port localhost)
68 listen sock maxListenQueue
59 listen sock maxListenQueue
69 pure sock)
60 pure sock)
70−listenOnLocalhost _ = error "Wrong Porttype"
71
61
72data Options = Options
62data Options = Options
73 { optionsDirectory :: Maybe FilePath
63 { optionsDirectory :: Maybe FilePath
64+ , optionsGlobs :: [FilePath]
74 , optionsOutputPath :: FilePath
65 , optionsOutputPath :: FilePath
75− , optionsPort :: PortID
66+ , optionsPort :: PortNumber
67+ , optionsNoWatch :: Bool
76 , optionsDebug :: Bool
68 , optionsDebug :: Bool
77 }
69 }
78
70
79main :: IO ()
71main :: IO ()
80main = do
72main = do
81− Options dir outputPath port debug <- execParser opts
73+ Options dir globs outputPath port noWatch debug <- execParser opts
82 maybe (pure ()) setCurrentDirectory dir
74 maybe (pure ()) setCurrentDirectory dir
83− serverState <- newTVarIO emptyPscIdeState
75+ ideState <- newTVarIO emptyIdeState
84 cwd <- getCurrentDirectory
76 cwd <- getCurrentDirectory
85 let fullOutputPath = cwd </> outputPath
77 let fullOutputPath = cwd </> outputPath
86
78
87− doesDirectoryExist fullOutputPath
79+ unlessM (doesDirectoryExist fullOutputPath) $ do
88− >>= flip unless
89− (do putStrLn ("Your output directory didn't exist. I'll create it at: " <> fullOutputPath)
80+ putStrLn ("Your output directory didn't exist. I'll create it at: " <> fullOutputPath)
90− createDirectory fullOutputPath
81+ createDirectory fullOutputPath
91− putStrLn "This usually means you didn't compile your project yet."
82+ putText "This usually means you didn't compile your project yet."
92− putStrLn "psc-ide needs you to compile your project (for example by running pulp build)"
83+ putText "psc-ide needs you to compile your project (for example by running pulp build)"
93− )
94
84
85+ unless noWatch $
95− _ <- forkFinally (watcher serverState fullOutputPath) print
86+ void (forkFinally (watcher ideState fullOutputPath) print)
96− let conf =
87+
97− Configuration
98− {
99− confDebug = debug
100− , confOutputPath = outputPath
88+ let conf = Configuration {confDebug = debug, confOutputPath = outputPath, confGlobs = globs}
101− }
89+ env = IdeEnvironment {ideStateVar = ideState, ideConfiguration = conf}
102− let env =
103− PscIdeEnvironment
104− {
105− envStateVar = serverState
106− , envConfiguration = conf
107− }
108 startServer port env
90 startServer port env
109 where
91 where
110 parser =
92 parser =
111− Options <$>
93+ Options
112− optional (strOption (long "directory" <> short 'd')) <*>
94+ <$> optional (strOption (long "directory" `mappend` short 'd'))
95+ <*> many (argument str (metavar "Source GLOBS..."))
113− strOption (long "output-directory" <> value "output/") <*>
96+ <*> strOption (long "output-directory" `mappend` value "output/")
114− (PortNumber . fromIntegral <$>
97+ <*> (fromIntegral <$>
115− option auto (long "port" <> short 'p' <> value (4242 :: Integer))) <*>
98+ option auto (long "port" `mappend` short 'p' `mappend` value (4242 :: Integer)))
99+ <*> switch (long "no-watch")
116− switch (long "debug")
100+ <*> switch (long "debug")
117 opts = info (version <*> helper <*> parser) mempty
101 opts = info (version <*> helper <*> parser) mempty
118 version = abortOption
102 version = abortOption
119 (InfoMsg (showVersion Paths.version))
103 (InfoMsg (showVersion Paths.version))
120− (long "version" <> help "Show the version number")
104+ (long "version" `mappend` help "Show the version number")
121
105
122−startServer :: PortID -> PscIdeEnvironment -> IO ()
106+startServer :: PortNumber -> IdeEnvironment -> IO ()
123startServer port env = withSocketsDo $ do
107startServer port env = withSocketsDo $ do
124 sock <- listenOnLocalhost port
108 sock <- listenOnLocalhost port
125 runLogger (runReaderT (forever (loop sock)) env)
109 runLogger (runReaderT (forever (loop sock)) env)
126 where
110 where
127− runLogger = runStdoutLoggingT . filterLogger (\_ _ -> confDebug (envConfiguration env))
111+ runLogger = runStdoutLoggingT . filterLogger (\_ _ -> confDebug (ideConfiguration env))
128
112
129− loop :: (PscIde m, MonadLogger m) => Socket -> m ()
113+ loop :: (Ide m, MonadLogger m) => Socket -> m ()
130 loop sock = do
114 loop sock = do
131 accepted <- runExceptT $ acceptCommand sock
115 accepted <- runExceptT $ acceptCommand sock
132 case accepted of
116 case accepted of
@@ -138,9 +122,8 @@ startServer port env = withSocketsDo $ do
138 -- $(logDebug) ("Answer was: " <> T.pack (show result))
122 -- $(logDebug) ("Answer was: " <> T.pack (show result))
139 liftIO (hFlush stdout)
123 liftIO (hFlush stdout)
140 case result of
124 case result of
141− -- What function can I use to clean this up?
142− Right r -> liftIO $ T.hPutStrLn h (encodeT r)
125+ Right r -> liftIO $ BS8.hPutStrLn h (Aeson.encode r)
143− Left err -> liftIO $ T.hPutStrLn h (encodeT err)
126+ Left err -> liftIO $ BS8.hPutStrLn h (Aeson.encode err)
144 Nothing -> do
127 Nothing -> do
145 $(logDebug) ("Parsing the command failed. Command: " <> cmd)
128 $(logDebug) ("Parsing the command failed. Command: " <> cmd)
146 liftIO $ do
129 liftIO $ do
@@ -149,8 +132,8 @@ startServer port env = withSocketsDo $ do
149 liftIO (hClose h)
132 liftIO (hClose h)
150
133
151
134
152−acceptCommand :: (MonadIO m, MonadLogger m, MonadError T.Text m)
135+acceptCommand :: (MonadIO m, MonadLogger m, MonadError Text m)
153− => Socket -> m (T.Text, Handle)
136+ => Socket -> m (Text, Handle)
154acceptCommand sock = do
137acceptCommand sock = do
155 h <- acceptConnection
138 h <- acceptConnection
156 $(logDebug) "Accepted a connection"
139 $(logDebug) "Accepted a connection"
psc-ide-server/PROTOCOL.md+52−25
@@ -14,64 +14,88 @@ to detect all the compiled modules in your project and load them.
14
14
15**Params:**
15**Params:**
16 - `modules :: (optional) [ModuleName]`: A list of modules to load.
16 - `modules :: (optional) [ModuleName]`: A list of modules to load.
17− psc-ide-server will try to parse all the declarations in these modules
17+ psc-ide-server will try to parse all the declarations in these modules
18− - `dependencies :: (optional) [ModuleName]`: A list of modules to load
19− including their dependencies. In contrast to the `module` field, all the
20− imports in these Modules will also be loaded.
21
18
22```json
19```json
23{
20{
24 "command": "load",
21 "command": "load",
25 "params": (optional) {
22 "params": (optional) {
26− "modules": (optional)["Module.Name1", "Module.Name2"],
23+ "modules": (optional)["Module.Name1", "Module.Name2"]
27− "dependencies": (optional)["Module.Name3"]
28 }
24 }
29}
25}
30```
26```
31
27
32**Result:**
28**Result:**
33
29
34−The Load Command returns a string.
30+The Load Command returns a string with a summary about the loading process.
35
31
36### Type
32### Type
37−The `type` command looks up the type for a given identifier.
33+The `type` command looks up the type for a given identifier. It also returns the
34+definition position, if it can be found in the passed source files.
38
35
39**Params:**
36**Params:**
40 - `search :: String`: The identifier to look for. Only matches on equality.
37 - `search :: String`: The identifier to look for. Only matches on equality.
41− - `filters :: [Filter]`: These filters will be applied before looking for the
38+ - `filters :: (optional) [Filter]`: These filters will be applied before looking for the
42 identifier. These filters get combined with *AND*, so a candidate must match *ALL*
39 identifier. These filters get combined with *AND*, so a candidate must match *ALL*
43 of them to be eligible.
40 of them to be eligible.
41+ - `currentModule :: (optional) String`: see *Complete* command
44```json
42```json
45{
43{
46 "command": "type",
44 "command": "type",
47 "params": {
45 "params": {
48 "search": "filterM",
46 "search": "filterM",
49− "filters": [Filter]
47+ "filters": [{..}],
48+ "currentModule": "Main"
50 }
49 }
51}
50}
52```
51```
53
52
54**Result:**
53**Result:**
55−The possible types are returned in the same format as completions
54+The possible types are returned in the same format as completions + eventual position information
55+```json
56+[
57+ {
58+ "module": "Data.Array",
59+ "identifier": "filter",
60+ "type": "forall a. (a -> Boolean) -> Array a -> Array a"
61+ },
62+ {
63+ "module": "Data.Array",
64+ "identifier": "filter",
65+ "type": "forall a. (a -> Boolean) -> Array a -> Array a",
66+ "definedAt":
67+ {
68+ "name": "/path/to/file",
69+ "start": [1, 3],
70+ "end": [3, 1]
71+ }
72+ }
73+]
74+```
56
75
57### Complete
76### Complete
58The `complete` command looks up possible completions/corrections.
77The `complete` command looks up possible completions/corrections.
59
78
60**Params**:
79**Params**:
61− - `filters :: [Filter]`: The same as for the `type` command. A candidate must match
80+ - `filters :: [Filter]`: The same as for the `type` command. A candidate must
62− all filters.
81+ match all filters.
63− - `matcher :: (optional) Matcher`: The strategy used for matching candidates after filtering.
82+ - `matcher :: (optional) Matcher`: The strategy used for matching candidates
64− Results are scored internally and will be returned in the descending order where
83+ after filtering. Results are scored internally and will be returned in the
65− the nth element is better then the n+1-th.
84+ descending order where the nth element is better then the n+1-th.
66−
85+ - `currentModule :: (optional) String`: The current modules name. If it matches
86+ with the rebuild cache non-exported modules will also be completed. You can
87+ fill the rebuild cache by using the "Rebuild" command.
88+
67− If no matcher is given every candidate, that passes the filters, is returned in no
89+ If no matcher is given every candidate, that passes the filters, is returned
68− particular order.
90+ in no particular order.
91+
69```json
92```json
70{
93{
71 "command": "complete",
94 "command": "complete",
72 "params": {
95 "params": {
73− "filters": [Filter],
96+ "filters": [{..}, {..}],
74− "matcher": (optional) Matcher
97+ "matcher": {..}
98+ "currentModule": "Main"
75 }
99 }
76}
100}
77```
101```
@@ -244,10 +268,11 @@ Example:
244
268
245The `rebuild` command provides a fast rebuild for a single module. It doesn't
269The `rebuild` command provides a fast rebuild for a single module. It doesn't
246recompile the entire project though. All the modules dependencies need to be
270recompile the entire project though. All the modules dependencies need to be
247−loaded.
271+loaded. A successful rebuild will be stored to allow for completions of private
272+identifiers.
248
273
249Arguments:
274Arguments:
250−- `file :: String` the path to the module to rebuild
275+ - `file :: String` the path to the module to rebuild
251
276
252```json
277```json
253{
278{
@@ -407,14 +432,16 @@ Hiding Import(`import Data.Array hiding (filter, filterM, join)`):
407 }
432 }
408]
433]
409```
434```
410−### Cwd/Quit
435+### Cwd/Quit/Reset
411`cwd` returns the working directory of the server(should be your project root).
436`cwd` returns the working directory of the server(should be your project root).
412
437
413`quit` quits the server.
438`quit` quits the server.
414
439
440+`reset` resets all loaded modules.
441+
415```json
442```json
416{
443{
417− "command": "cwd|quit"
444+ "command": "cwd|quit|reset"
418}
445}
419```
446```
420
447
psc-ide-server/README.md+5−1
@@ -10,7 +10,10 @@ A tool which provides editor support for the PureScript programming language.
10* Vim integration is available here: https://github.com/FrigoEU/psc-ide-vim.
10* Vim integration is available here: https://github.com/FrigoEU/psc-ide-vim.
11
11
12## Running the Server
12## Running the Server
13+
13−Start the server by running the `psc-ide-server` executable.
14+Start the server by running the `psc-ide-server [SOURCEGLOBS]` executable, where
15+`SOURCEGLOBS` are (optional) globs that match your PureScript sourcefiles.
16+
14It supports the following options:
17It supports the following options:
15
18
16- `-p / --port` specify a port. Defaults to 4242
19- `-p / --port` specify a port. Defaults to 4242
@@ -20,6 +23,7 @@ It supports the following options:
20 project directory. Defaults to `output/`, relative to either the current
23 project directory. Defaults to `output/`, relative to either the current
21 directory or the directory specified by `-d`.
24 directory or the directory specified by `-d`.
22- `--debug`: Enables some logging meant for debugging
25- `--debug`: Enables some logging meant for debugging
26+- `--no-watch`: Disables the filewatcher
23- `--version`: Output psc-ide version
27- `--version`: Output psc-ide version
24
28
25## Issuing queries
29## Issuing queries
psc/Main.hs+27−53
@@ -1,56 +1,54 @@
1{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE RecordWildCards #-}
4+{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE TupleSections #-}
5{-# LANGUAGE TupleSections #-}
5
6
6module Main where
7module Main where
7
8
8−import Control.Applicative
9+import Control.Applicative
9−import Control.Monad
10+import Control.Monad
10−import Control.Monad.Error.Class (MonadError(..))
11−import Control.Monad.Writer.Strict
11+import Control.Monad.Writer.Strict
12
12
13−import Data.List (isSuffixOf, partition)
14−import Data.Version (showVersion)
15−import qualified Data.Map as M
16import qualified Data.Aeson as A
13import qualified Data.Aeson as A
14+import Data.Bool (bool)
17import qualified Data.ByteString.Lazy as B
15import qualified Data.ByteString.Lazy as B
18import qualified Data.ByteString.UTF8 as BU8
16import qualified Data.ByteString.UTF8 as BU8
17+import qualified Data.Map as M
18+import Data.Version (showVersion)
19
19
20−import Options.Applicative as Opts
20+import qualified Language.PureScript as P
21+import Language.PureScript.Errors.JSON
22+import Language.PureScript.Make
21
23
22−import System.Exit (exitSuccess, exitFailure)
24+import Options.Applicative as Opts
23−import System.IO (hSetEncoding, hPutStrLn, stdout, stderr, utf8)
24−import System.IO.UTF8
25−import System.FilePath.Glob (glob)
26
25
27−import qualified Language.PureScript as P
28import qualified Paths_purescript as Paths
26import qualified Paths_purescript as Paths
29
27
30−import Language.PureScript.Make
28+import qualified System.Console.ANSI as ANSI
31−import Language.PureScript.Errors.JSON
29+import System.Exit (exitSuccess, exitFailure)
30+import System.FilePath.Glob (glob)
31+import System.IO (hSetEncoding, hPutStrLn, stdout, stderr, utf8)
32+import System.IO.UTF8
32
33
33data PSCMakeOptions = PSCMakeOptions
34data PSCMakeOptions = PSCMakeOptions
34 { pscmInput :: [FilePath]
35 { pscmInput :: [FilePath]
35− , pscmForeignInput :: [FilePath]
36 , pscmOutputDir :: FilePath
36 , pscmOutputDir :: FilePath
37 , pscmOpts :: P.Options
37 , pscmOpts :: P.Options
38 , pscmUsePrefix :: Bool
38 , pscmUsePrefix :: Bool
39 , pscmJSONErrors :: Bool
39 , pscmJSONErrors :: Bool
40 }
40 }
41
41
42−data InputOptions = InputOptions
43− { ioInputFiles :: [FilePath]
44− }
45−
46-- | Argumnets: verbose, use JSON, warnings, errors
42-- | Argumnets: verbose, use JSON, warnings, errors
47printWarningsAndErrors :: Bool -> Bool -> P.MultipleErrors -> Either P.MultipleErrors a -> IO ()
43printWarningsAndErrors :: Bool -> Bool -> P.MultipleErrors -> Either P.MultipleErrors a -> IO ()
48printWarningsAndErrors verbose False warnings errors = do
44printWarningsAndErrors verbose False warnings errors = do
45+ cc <- bool Nothing (Just P.defaultCodeColor) <$> ANSI.hSupportsANSI stderr
46+ let ppeOpts = P.defaultPPEOptions { P.ppeCodeColor = cc, P.ppeFull = verbose }
49 when (P.nonEmpty warnings) $
47 when (P.nonEmpty warnings) $
50− hPutStrLn stderr (P.prettyPrintMultipleWarnings verbose warnings)
48+ hPutStrLn stderr (P.prettyPrintMultipleWarnings ppeOpts warnings)
51 case errors of
49 case errors of
52 Left errs -> do
50 Left errs -> do
53− hPutStrLn stderr (P.prettyPrintMultipleErrors verbose errs)
51+ hPutStrLn stderr (P.prettyPrintMultipleErrors ppeOpts errs)
54 exitFailure
52 exitFailure
55 Right _ -> return ()
53 Right _ -> return ()
56printWarningsAndErrors verbose True warnings errors = do
54printWarningsAndErrors verbose True warnings errors = do
@@ -65,14 +63,12 @@ compile PSCMakeOptions{..} = do
65 when (null input && not pscmJSONErrors) $ do
63 when (null input && not pscmJSONErrors) $ do
66 hPutStrLn stderr "psc: No input files."
64 hPutStrLn stderr "psc: No input files."
67 exitFailure
65 exitFailure
68− let (jsFiles, pursFiles) = partition (isSuffixOf ".js") input
69− moduleFiles <- readInput (InputOptions pursFiles)
66+ moduleFiles <- readInput input
70− inputForeign <- globWarningOnMisses (unless pscmJSONErrors . warnFileTypeNotFound) pscmForeignInput
71− foreignFiles <- forM (inputForeign ++ jsFiles) (\inFile -> (inFile,) <$> readUTF8File inFile)
72 (makeErrors, makeWarnings) <- runMake pscmOpts $ do
67 (makeErrors, makeWarnings) <- runMake pscmOpts $ do
73− (ms, foreigns) <- parseInputs moduleFiles foreignFiles
68+ ms <- P.parseModulesFromFiles id moduleFiles
74− let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, fp)) ms
69+ let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, Right fp)) ms
70+ foreigns <- inferForeignModules filePathMap
75− makeActions = buildMakeActions pscmOutputDir filePathMap foreigns pscmUsePrefix
71+ let makeActions = buildMakeActions pscmOutputDir filePathMap foreigns pscmUsePrefix
76 P.make makeActions (map snd ms)
72 P.make makeActions (map snd ms)
77 printWarningsAndErrors (P.optionsVerboseErrors pscmOpts) pscmJSONErrors makeWarnings makeErrors
73 printWarningsAndErrors (P.optionsVerboseErrors pscmOpts) pscmJSONErrors makeWarnings makeErrors
78 exitSuccess
74 exitSuccess
@@ -89,28 +85,14 @@ globWarningOnMisses warn = concatMapM globWithWarning
89 return paths
85 return paths
90 concatMapM f = liftM concat . mapM f
86 concatMapM f = liftM concat . mapM f
91
87
92−readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
88+readInput :: [FilePath] -> IO [(FilePath, String)]
93−readInput InputOptions{..} = forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readUTF8File inFile
89+readInput inputFiles = forM inputFiles $ \inFile -> (inFile, ) <$> readUTF8File inFile
94−
95−parseInputs :: (MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m)
96− => [(Either P.RebuildPolicy FilePath, String)]
97− -> [(FilePath, P.ForeignJS)]
98− -> m ([(Either P.RebuildPolicy FilePath, P.Module)], M.Map P.ModuleName FilePath)
99−parseInputs modules foreigns =
100− (,) <$> P.parseModulesFromFiles (either (const "") id) modules
101− <*> P.parseForeignModulesFromFiles foreigns
102
90
103inputFile :: Parser FilePath
91inputFile :: Parser FilePath
104inputFile = strArgument $
92inputFile = strArgument $
105 metavar "FILE"
93 metavar "FILE"
106 <> help "The input .purs file(s)"
94 <> help "The input .purs file(s)"
107
95
108−inputForeignFile :: Parser FilePath
109−inputForeignFile = strOption $
110− short 'f'
111− <> long "ffi"
112− <> help "The input .js file(s) providing foreign import implementations"
113−
114outputDirectory :: Parser FilePath
96outputDirectory :: Parser FilePath
115outputDirectory = strOption $
97outputDirectory = strOption $
116 short 'o'
98 short 'o'
@@ -119,12 +101,6 @@ outputDirectory = strOption $
119 <> showDefault
101 <> showDefault
120 <> help "The output directory"
102 <> help "The output directory"
121
103
122−requirePath :: Parser (Maybe FilePath)
123−requirePath = optional $ strOption $
124− short 'r'
125− <> long "require-path"
126− <> help "The path prefix to use for require() calls in the generated JavaScript [deprecated]"
127−
128noTco :: Parser Bool
104noTco :: Parser Bool
129noTco = switch $
105noTco = switch $
130 long "no-tco"
106 long "no-tco"
@@ -175,12 +151,10 @@ options = P.Options <$> noTco
175 <*> noOpts
151 <*> noOpts
176 <*> verboseErrors
152 <*> verboseErrors
177 <*> (not <$> comments)
153 <*> (not <$> comments)
178− <*> requirePath
179 <*> sourceMaps
154 <*> sourceMaps
180
155
181pscMakeOptions :: Parser PSCMakeOptions
156pscMakeOptions :: Parser PSCMakeOptions
182pscMakeOptions = PSCMakeOptions <$> many inputFile
157pscMakeOptions = PSCMakeOptions <$> many inputFile
183− <*> many inputForeignFile
184 <*> outputDirectory
158 <*> outputDirectory
185 <*> options
159 <*> options
186 <*> (not <$> noPrefix)
160 <*> (not <$> noPrefix)
psci/Main.hsnew file+364
@@ -0,0 +1,364 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE DoAndIfThenElse #-}
3+{-# LANGUAGE GADTs #-}
4+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5+{-# LANGUAGE MultiParamTypeClasses #-}
6+{-# LANGUAGE OverloadedStrings #-}
7+{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE RecordWildCards #-}
9+{-# LANGUAGE ScopedTypeVariables #-}
10+{-# LANGUAGE TemplateHaskell #-}
11+{-# LANGUAGE TupleSections #-}
12+
13+module Main (main) where
14+
15+import Prelude ()
16+import Prelude.Compat
17+
18+import Data.FileEmbed (embedStringFile)
19+import Data.Monoid ((<>))
20+import Data.String (IsString(..))
21+import Data.Text (Text, unpack)
22+import Data.Traversable (for)
23+import Data.Version (showVersion)
24+
25+import Control.Applicative (many, (<|>))
26+import Control.Concurrent (forkIO)
27+import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar,
28+ tryPutMVar)
29+import Control.Concurrent.STM (TVar, atomically, newTVarIO, writeTVar,
30+ readTVarIO,
31+ TChan, newBroadcastTChanIO, dupTChan,
32+ readTChan, writeTChan)
33+import Control.Exception (fromException)
34+import Control.Monad
35+import Control.Monad.IO.Class (liftIO)
36+import Control.Monad.Trans.Class
37+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
38+import Control.Monad.Trans.State.Strict (StateT, evalStateT)
39+import Control.Monad.Trans.Reader (ReaderT, runReaderT)
40+
41+import qualified Language.PureScript as P
42+import qualified Language.PureScript.Bundle as Bundle
43+import Language.PureScript.Interactive
44+
45+import Network.HTTP.Types.Header (hContentType, hCacheControl,
46+ hPragma, hExpires)
47+import Network.HTTP.Types.Status (status200, status404, status503)
48+import qualified Network.Wai as Wai
49+import qualified Network.Wai.Handler.Warp as Warp
50+import qualified Network.Wai.Handler.WebSockets as WS
51+import qualified Network.WebSockets as WS
52+
53+import qualified Options.Applicative as Opts
54+
55+import qualified Paths_purescript as Paths
56+
57+import System.Console.Haskeline
58+import System.IO.UTF8 (readUTF8File)
59+import System.Exit
60+import System.FilePath ((</>))
61+import System.FilePath.Glob (glob)
62+import System.Process (readProcessWithExitCode)
63+
64+-- | Command line options
65+data PSCiOptions = PSCiOptions
66+ { psciMultiLineMode :: Bool
67+ , psciInputFile :: [FilePath]
68+ , psciBackend :: Backend
69+ }
70+
71+multiLineMode :: Opts.Parser Bool
72+multiLineMode = Opts.switch $
73+ Opts.long "multi-line-mode"
74+ <> Opts.short 'm'
75+ <> Opts.help "Run in multi-line mode (use ^D to terminate commands)"
76+
77+inputFile :: Opts.Parser FilePath
78+inputFile = Opts.strArgument $
79+ Opts.metavar "FILE"
80+ <> Opts.help "Optional .purs files to load on start"
81+
82+nodeFlagsFlag :: Opts.Parser [String]
83+nodeFlagsFlag = Opts.option parser $
84+ Opts.long "node-opts"
85+ <> Opts.metavar "NODE_OPTS"
86+ <> Opts.value []
87+ <> Opts.help "Flags to pass to node, separated by spaces"
88+ where
89+ parser = words <$> Opts.str
90+
91+port :: Opts.Parser Int
92+port = Opts.option Opts.auto $
93+ Opts.long "port"
94+ <> Opts.short 'p'
95+ <> Opts.help "The web server port"
96+
97+backend :: Opts.Parser Backend
98+backend =
99+ (browserBackend <$> port)
100+ <|> (nodeBackend <$> nodeFlagsFlag)
101+
102+psciOptions :: Opts.Parser PSCiOptions
103+psciOptions = PSCiOptions <$> multiLineMode
104+ <*> many inputFile
105+ <*> backend
106+
107+version :: Opts.Parser (a -> a)
108+version = Opts.abortOption (Opts.InfoMsg (showVersion Paths.version)) $
109+ Opts.long "version" <>
110+ Opts.help "Show the version number" <>
111+ Opts.hidden
112+
113+getOpt :: IO PSCiOptions
114+getOpt = Opts.execParser opts
115+ where
116+ opts = Opts.info (version <*> Opts.helper <*> psciOptions) infoModList
117+ infoModList = Opts.fullDesc <> headerInfo <> footerInfo
118+ headerInfo = Opts.header "psci - Interactive mode for PureScript"
119+ footerInfo = Opts.footer $ "psci " ++ showVersion Paths.version
120+
121+-- | Parses the input and returns either a command, or an error as a 'String'.
122+getCommand :: forall m. MonadException m => Bool -> InputT m (Either String (Maybe Command))
123+getCommand singleLineMode = handleInterrupt (return (Right Nothing)) $ do
124+ firstLine <- withInterrupt $ getInputLine "> "
125+ case firstLine of
126+ Nothing -> return (Right (Just QuitPSCi)) -- Ctrl-D when input is empty
127+ Just "" -> return (Right Nothing)
128+ Just s | singleLineMode || head s == ':' -> return . fmap Just $ parseCommand s
129+ Just s -> fmap Just . parseCommand <$> go [s]
130+ where
131+ go :: [String] -> InputT m String
132+ go ls = maybe (return . unlines $ reverse ls) (go . (:ls)) =<< getInputLine " "
133+
134+-- | Make a JavaScript bundle for the browser.
135+bundle :: IO (Either Bundle.ErrorMessage String)
136+bundle = runExceptT $ do
137+ inputFiles <- liftIO (glob (".psci_modules" </> "node_modules" </> "*" </> "*.js"))
138+ input <- for inputFiles $ \filename -> do
139+ js <- liftIO (readUTF8File filename)
140+ mid <- Bundle.guessModuleIdentifier filename
141+ length js `seq` return (mid, js)
142+ Bundle.bundle input [] Nothing "PSCI"
143+
144+indexJS :: IsString string => string
145+indexJS = $(embedStringFile "psci/static/index.js")
146+
147+indexPage :: IsString string => string
148+indexPage = $(embedStringFile "psci/static/index.html")
149+
150+-- | All of the functions required to implement a PSCi backend
151+data Backend = forall state. Backend
152+ { _backendSetup :: IO state
153+ -- ^ Initialize, and call the continuation when the backend is ready
154+ , _backendEval :: state -> String -> IO ()
155+ -- ^ Evaluate JavaScript code
156+ , _backendReload :: state -> IO ()
157+ -- ^ Reload the compiled code
158+ , _backendShutdown :: state -> IO ()
159+ -- ^ Shut down the backend
160+ }
161+
162+-- | Commands which can be sent to the browser
163+data BrowserCommand
164+ = Eval (MVar String)
165+ -- ^ Evaluate the latest JS
166+ | Reload
167+ -- ^ Reload the page
168+
169+-- | State for the browser backend
170+data BrowserState = BrowserState
171+ { browserCommands :: TChan BrowserCommand
172+ -- ^ A channel which receives data when the compiled JS has
173+ -- been updated
174+ , browserShutdownNotice :: MVar ()
175+ -- ^ An MVar which becomes full when the server should shut down
176+ , browserIndexJS :: TVar (Maybe String)
177+ -- ^ A TVar holding the latest compiled JS
178+ , browserBundleJS :: TVar (Maybe String)
179+ -- ^ A TVar holding the latest bundled JS
180+ }
181+
182+browserBackend :: Int -> Backend
183+browserBackend serverPort = Backend setup evaluate reload shutdown
184+ where
185+ setup :: IO BrowserState
186+ setup = do
187+ shutdownVar <- newEmptyMVar
188+ cmdChan <- newBroadcastTChanIO
189+ indexJs <- newTVarIO Nothing
190+ bundleJs <- newTVarIO Nothing
191+
192+ let
193+ handleWebsocket :: WS.PendingConnection -> IO ()
194+ handleWebsocket pending = do
195+ conn <- WS.acceptRequest pending
196+ -- Fork a thread to keep the connection alive
197+ WS.forkPingThread conn 10
198+ -- Clone the command channel
199+ cmdChanCopy <- atomically $ dupTChan cmdChan
200+ -- Listen for commands
201+ forever $ do
202+ cmd <- atomically $ readTChan cmdChanCopy
203+ case cmd of
204+ Eval resultVar -> void $ do
205+ WS.sendTextData conn ("eval" :: Text)
206+ result <- WS.receiveData conn
207+ -- With many connected clients, all but one of
208+ -- these attempts will fail.
209+ tryPutMVar resultVar (unpack result)
210+ Reload -> do
211+ WS.sendTextData conn ("reload" :: Text)
212+
213+ shutdownHandler :: IO () -> IO ()
214+ shutdownHandler stopServer = void . forkIO $ do
215+ () <- takeMVar shutdownVar
216+ stopServer
217+
218+ onException :: Maybe Wai.Request -> SomeException -> IO ()
219+ onException req ex
220+ | Just (_ :: WS.ConnectionException) <- fromException ex
221+ = return () -- ignore websocket disconnects
222+ | otherwise = Warp.defaultOnException req ex
223+
224+ staticServer :: Wai.Application
225+ staticServer req respond =
226+ case Wai.pathInfo req of
227+ [] ->
228+ respond $ Wai.responseLBS status200
229+ [(hContentType, "text/html")]
230+ indexPage
231+ ["js", "index.js"] ->
232+ respond $ Wai.responseLBS status200
233+ [(hContentType, "application/javascript")]
234+ indexJS
235+ ["js", "latest.js"] -> do
236+ may <- readTVarIO indexJs
237+ case may of
238+ Nothing ->
239+ respond $ Wai.responseLBS status503 [] "Service not available"
240+ Just js ->
241+ respond $ Wai.responseLBS status200
242+ [ (hContentType, "application/javascript")
243+ , (hCacheControl, "no-cache, no-store, must-revalidate")
244+ , (hPragma, "no-cache")
245+ , (hExpires, "0")
246+ ]
247+ (fromString js)
248+ ["js", "bundle.js"] -> do
249+ may <- readTVarIO bundleJs
250+ case may of
251+ Nothing ->
252+ respond $ Wai.responseLBS status503 [] "Service not available"
253+ Just js ->
254+ respond $ Wai.responseLBS status200
255+ [ (hContentType, "application/javascript")]
256+ (fromString js)
257+ _ -> respond $ Wai.responseLBS status404 [] "Not found"
258+
259+ let browserState = BrowserState cmdChan shutdownVar indexJs bundleJs
260+ createBundle browserState
261+
262+ putStrLn $ "Serving http://localhost:" <> show serverPort <> "/. Waiting for connections..."
263+ _ <- forkIO $ Warp.runSettings ( Warp.setInstallShutdownHandler shutdownHandler
264+ . Warp.setPort serverPort
265+ . Warp.setOnException onException
266+ $ Warp.defaultSettings
267+ ) $
268+ WS.websocketsOr WS.defaultConnectionOptions
269+ handleWebsocket
270+ staticServer
271+ return browserState
272+
273+ createBundle :: BrowserState -> IO ()
274+ createBundle state = do
275+ putStrLn "Bundling Javascript..."
276+ ejs <- bundle
277+ case ejs of
278+ Left err -> do
279+ putStrLn (unlines (Bundle.printErrorMessage err))
280+ exitFailure
281+ Right js -> do
282+ atomically $ writeTVar (browserBundleJS state) (Just js)
283+
284+ reload :: BrowserState -> IO ()
285+ reload state = do
286+ createBundle state
287+ atomically $ writeTChan (browserCommands state) Reload
288+
289+ shutdown :: BrowserState -> IO ()
290+ shutdown state = putMVar (browserShutdownNotice state) ()
291+
292+ evaluate :: BrowserState -> String -> IO ()
293+ evaluate state js = liftIO $ do
294+ resultVar <- newEmptyMVar
295+ atomically $ do
296+ writeTVar (browserIndexJS state) (Just js)
297+ writeTChan (browserCommands state) (Eval resultVar)
298+ result <- takeMVar resultVar
299+ putStrLn result
300+
301+nodeBackend :: [String] -> Backend
302+nodeBackend nodeArgs = Backend setup eval reload shutdown
303+ where
304+ setup :: IO ()
305+ setup = return ()
306+
307+ eval :: () -> String -> IO ()
308+ eval _ _ = do
309+ writeFile indexFile "require('$PSCI')['$main']();"
310+ process <- findNodeProcess
311+ result <- traverse (\node -> readProcessWithExitCode node (nodeArgs ++ [indexFile]) "") process
312+ case result of
313+ Just (ExitSuccess, out, _) -> putStrLn out
314+ Just (ExitFailure _, _, err) -> putStrLn err
315+ Nothing -> putStrLn "Couldn't find node.js"
316+
317+ reload :: () -> IO ()
318+ reload _ = return ()
319+
320+ shutdown :: () -> IO ()
321+ shutdown _ = return ()
322+
323+-- | Get command line options and drop into the REPL
324+main :: IO ()
325+main = getOpt >>= loop
326+ where
327+ loop :: PSCiOptions -> IO ()
328+ loop PSCiOptions{..} = do
329+ inputFiles <- concat <$> traverse glob psciInputFile
330+ e <- runExceptT $ do
331+ modules <- ExceptT (loadAllModules inputFiles)
332+ unless (supportModuleIsDefined (map snd modules)) . liftIO $ do
333+ putStrLn supportModuleMessage
334+ exitFailure
335+ (externs, env) <- ExceptT . runMake . make $ modules
336+ return (modules, externs, env)
337+ case psciBackend of
338+ Backend setup eval reload (shutdown :: state -> IO ()) -> do
339+ case e of
340+ Left errs -> putStrLn (P.prettyPrintMultipleErrors P.defaultPPEOptions errs) >> exitFailure
341+ Right (modules, externs, env) -> do
342+ historyFilename <- getHistoryFilename
343+ let settings = defaultSettings { historyFile = Just historyFilename }
344+ initialState = PSCiState [] [] (zip (map snd modules) externs)
345+ config = PSCiConfig inputFiles env
346+ runner = flip runReaderT config
347+ . flip evalStateT initialState
348+ . runInputT (setComplete completion settings)
349+
350+ go :: state -> InputT (StateT PSCiState (ReaderT PSCiConfig IO)) ()
351+ go state = do
352+ c <- getCommand (not psciMultiLineMode)
353+ case c of
354+ Left err -> outputStrLn err >> go state
355+ Right Nothing -> go state
356+ Right (Just QuitPSCi) -> do
357+ outputStrLn quitMessage
358+ liftIO $ shutdown state
359+ Right (Just c') -> do
360+ handleInterrupt (outputStrLn "Interrupted.")
361+ (withInterrupt (lift (handleCommand (liftIO . eval state) (liftIO (reload state)) c')))
362+ go state
363+ putStrLn prologueMessage
364+ setup >>= runner . go
psci/PSCi.hsdeleted−372
@@ -1,372 +0,0 @@
1−{-# LANGUAGE DoAndIfThenElse #-}
2−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3−{-# LANGUAGE RecordWildCards #-}
4−{-# LANGUAGE TupleSections #-}
5−{-# LANGUAGE DataKinds #-}
6−
7−-- |
8−-- PureScript Compiler Interactive.
9−--
10−module PSCi (runPSCi) where
11−
12−import Prelude ()
13−import Prelude.Compat
14−
15−import Data.Foldable (traverse_)
16−import Data.List (intercalate, nub, sort, find)
17−import Data.Tuple (swap)
18−import qualified Data.Map as M
19−
20−import Control.Arrow (first)
21−import Control.Monad
22−import Control.Monad.Error.Class (MonadError(..))
23−import Control.Monad.Trans.Class
24−import Control.Monad.Trans.Except (ExceptT(), runExceptT)
25−import Control.Monad.Trans.State.Strict
26−import Control.Monad.IO.Class (liftIO)
27−import Control.Monad.Writer.Strict (Writer(), runWriter)
28−
29−import System.Console.Haskeline
30−import System.Directory (doesFileExist, getHomeDirectory, getCurrentDirectory)
31−import System.Exit
32−import System.FilePath ((</>))
33−import System.FilePath.Glob (glob)
34−import System.Process (readProcessWithExitCode)
35−import System.IO.Error (tryIOError)
36−import System.IO.UTF8 (readUTF8File)
37−
38−import qualified Language.PureScript as P
39−import qualified Language.PureScript.Names as N
40−
41−import PSCi.Completion (completion)
42−import PSCi.Parser (parseCommand)
43−import PSCi.Option
44−import PSCi.Types
45−import PSCi.Message
46−import PSCi.IO
47−import PSCi.Printer
48−import PSCi.Module
49−
50−-- |
51−-- PSCI monad
52−--
53−newtype PSCI a = PSCI { runPSCI :: InputT (StateT PSCiState IO) a } deriving (Functor, Applicative, Monad)
54−
55−psciIO :: IO a -> PSCI a
56−psciIO io = PSCI . lift $ lift io
57−
58−-- |
59−-- The runner
60−--
61−runPSCi :: IO ()
62−runPSCi = getOpt >>= loop
63−
64−-- |
65−-- The PSCI main loop.
66−--
67−loop :: PSCiOptions -> IO ()
68−loop PSCiOptions{..} = do
69− config <- loadUserConfig
70− inputFiles <- concat <$> traverse glob psciInputFile
71− foreignFiles <- concat <$> traverse glob psciForeignInputFiles
72− modulesOrFirstError <- loadAllModules inputFiles
73− case modulesOrFirstError of
74− Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> exitFailure
75− Right modules -> do
76− historyFilename <- getHistoryFilename
77− let settings = defaultSettings { historyFile = Just historyFilename }
78− foreignsOrError <- runMake $ do
79− foreignFilesContent <- forM foreignFiles (\inFile -> (inFile,) <$> makeIO (const (P.ErrorMessage [] $ P.CannotReadFile inFile)) (readUTF8File inFile))
80− P.parseForeignModulesFromFiles foreignFilesContent
81− case foreignsOrError of
82− Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> exitFailure
83− Right foreigns ->
84− flip evalStateT (mkPSCiState [] modules foreigns [] psciInputNodeFlags) . runInputT (setComplete completion settings) $ do
85− outputStrLn prologueMessage
86− traverse_ (traverse_ (runPSCI . handleCommand)) config
87− modules' <- lift $ gets psciLoadedModules
88− unless (consoleIsDefined (map snd modules')) . outputStrLn $ unlines
89− [ "PSCi requires the purescript-console module to be installed."
90− , "For help getting started, visit http://wiki.purescript.org/PSCi"
91− ]
92− go
93− where
94− go :: InputT (StateT PSCiState IO) ()
95− go = do
96− c <- getCommand (not psciMultiLineMode)
97− case c of
98− Left err -> outputStrLn err >> go
99− Right Nothing -> go
100− Right (Just QuitPSCi) -> outputStrLn quitMessage
101− Right (Just c') -> do
102− handleInterrupt (outputStrLn "Interrupted.")
103− (withInterrupt (runPSCI (loadAllImportedModules >> handleCommand c')))
104− go
105−
106−-- Compile the module
107−
108−-- |
109−-- Load all modules, updating the application state
110−--
111−loadAllImportedModules :: PSCI ()
112−loadAllImportedModules = do
113− files <- PSCI . lift $ fmap psciImportedFilenames get
114− modulesOrFirstError <- psciIO $ loadAllModules files
115− case modulesOrFirstError of
116− Left errs -> PSCI $ printErrors errs
117− Right modules -> PSCI . lift . modify $ updateModules modules
118−
119−-- | This is different than the runMake in 'Language.PureScript.Make' in that it specifies the
120−-- options and ignores the warning messages.
121−runMake :: P.Make a -> IO (Either P.MultipleErrors a)
122−runMake mk = fst <$> P.runMake P.defaultOptions mk
123−
124−makeIO :: (IOError -> P.ErrorMessage) -> IO a -> P.Make a
125−makeIO f io = do
126− e <- liftIO $ tryIOError io
127− either (throwError . P.singleError . f) return e
128−
129−make :: PSCiState -> [P.Module] -> P.Make P.Environment
130−make st@PSCiState{..} ms = P.make actions' (map snd loadedModules ++ ms)
131− where
132− filePathMap = M.fromList $ (first P.getModuleName . swap) `map` allModules
133− actions = P.buildMakeActions modulesDir filePathMap psciForeignFiles False
134− actions' = actions { P.progress = const (return ()) }
135− loadedModules = psciLoadedModules st
136− allModules = map (first Right) loadedModules ++ map (Left P.RebuildAlways,) ms
137−
138−
139−-- Commands
140−
141−-- |
142−-- Parses the input and returns either a Metacommand, or an error as a string.
143−--
144−getCommand :: Bool -> InputT (StateT PSCiState IO) (Either String (Maybe Command))
145−getCommand singleLineMode = handleInterrupt (return (Right Nothing)) $ do
146− firstLine <- withInterrupt $ getInputLine "> "
147− case firstLine of
148− Nothing -> return (Right (Just QuitPSCi)) -- Ctrl-D when input is empty
149− Just "" -> return (Right Nothing)
150− Just s | singleLineMode || head s == ':' -> return .fmap Just $ parseCommand s
151− Just s -> fmap Just . parseCommand <$> go [s]
152− where
153− go :: [String] -> InputT (StateT PSCiState IO) String
154− go ls = maybe (return . unlines $ reverse ls) (go . (:ls)) =<< getInputLine " "
155−
156−-- |
157−-- Performs an action for each meta-command given, and also for expressions.
158−--
159−handleCommand :: Command -> PSCI ()
160−handleCommand (Expression val) = handleExpression val
161−handleCommand ShowHelp = PSCI $ outputStrLn helpMessage
162−handleCommand (Import im) = handleImport im
163−handleCommand (Decls l) = handleDecls l
164−handleCommand (LoadFile filePath) = PSCI $ whenFileExists filePath $ \absPath -> do
165− m <- lift . lift $ loadModule absPath
166− case m of
167− Left err -> outputStrLn err
168− Right mods -> lift $ modify (updateModules (map (absPath,) mods))
169−handleCommand (LoadForeign filePath) = PSCI $ whenFileExists filePath $ \absPath -> do
170− foreignsOrError <- lift . lift . runMake $ do
171− foreignFile <- makeIO (const (P.ErrorMessage [] $ P.CannotReadFile absPath)) (readUTF8File absPath)
172− P.parseForeignModulesFromFiles [(absPath, foreignFile)]
173− case foreignsOrError of
174− Left err -> outputStrLn $ P.prettyPrintMultipleErrors False err
175− Right foreigns -> lift $ modify (updateForeignFiles foreigns)
176−handleCommand ResetState = do
177− PSCI . lift . modify $ \st ->
178− st { psciImportedModules = []
179− , psciLetBindings = []
180− }
181− loadAllImportedModules
182−handleCommand (TypeOf val) = handleTypeOf val
183−handleCommand (KindOf typ) = handleKindOf typ
184−handleCommand (BrowseModule moduleName) = handleBrowse moduleName
185−handleCommand (ShowInfo QueryLoaded) = handleShowLoadedModules
186−handleCommand (ShowInfo QueryImport) = handleShowImportedModules
187−handleCommand QuitPSCi = P.internalError "`handleCommand QuitPSCi` was called. This is a bug."
188−
189−
190−-- |
191−-- Takes a value expression and evaluates it with the current state.
192−--
193−handleExpression :: P.Expr -> PSCI ()
194−handleExpression val = do
195− st <- PSCI $ lift get
196− let m = createTemporaryModule True st val
197− let nodeArgs = psciNodeFlags st ++ [indexFile]
198− e <- psciIO . runMake $ make st [supportModule, m]
199− case e of
200− Left errs -> PSCI $ printErrors errs
201− Right _ -> do
202− psciIO $ writeFile indexFile "require('$PSCI')['$main']();"
203− process <- psciIO findNodeProcess
204− result <- psciIO $ traverse (\node -> readProcessWithExitCode node nodeArgs "") process
205− case result of
206− Just (ExitSuccess, out, _) -> PSCI $ outputStrLn out
207− Just (ExitFailure _, _, err) -> PSCI $ outputStrLn err
208− Nothing -> PSCI $ outputStrLn "Couldn't find node.js"
209−
210−-- |
211−-- Takes a list of declarations and updates the environment, then run a make. If the declaration fails,
212−-- restore the original environment.
213−--
214−handleDecls :: [P.Declaration] -> PSCI ()
215−handleDecls ds = do
216− st <- PSCI $ lift get
217− let st' = updateLets ds st
218− let m = createTemporaryModule False st' (P.Literal (P.ObjectLiteral []))
219− e <- psciIO . runMake $ make st' [m]
220− case e of
221− Left err -> PSCI $ printErrors err
222− Right _ -> PSCI $ lift (put st')
223−
224−-- |
225−-- Show actual loaded modules in psci.
226−--
227−handleShowLoadedModules :: PSCI ()
228−handleShowLoadedModules = do
229− loadedModules <- PSCI $ lift $ gets psciLoadedModules
230− psciIO $ readModules loadedModules >>= putStrLn
231− return ()
232− where readModules = return . unlines . sort . nub . map toModuleName
233− toModuleName = N.runModuleName . (\ (P.Module _ _ mdName _ _) -> mdName) . snd
234−
235−-- |
236−-- Show the imported modules in psci.
237−--
238−handleShowImportedModules :: PSCI ()
239−handleShowImportedModules = do
240− PSCiState { psciImportedModules = importedModules } <- PSCI $ lift get
241− psciIO $ showModules importedModules >>= putStrLn
242− return ()
243− where
244− showModules = return . unlines . sort . map showModule
245− showModule (mn, declType, asQ) =
246− "import " ++ N.runModuleName mn ++ showDeclType declType ++
247− foldMap (\mn' -> " as " ++ N.runModuleName mn') asQ
248−
249− showDeclType P.Implicit = ""
250− showDeclType (P.Explicit refs) = refsList refs
251− showDeclType (P.Hiding refs) = " hiding " ++ refsList refs
252− refsList refs = " (" ++ commaList (map showRef refs) ++ ")"
253−
254− showRef :: P.DeclarationRef -> String
255− showRef (P.TypeRef pn dctors) = N.runProperName pn ++ "(" ++ maybe ".." (commaList . map N.runProperName) dctors ++ ")"
256− showRef (P.TypeOpRef ident) = "type (" ++ N.runIdent ident ++ ")"
257− showRef (P.ValueRef ident) = N.runIdent ident
258− showRef (P.TypeClassRef pn) = "class " ++ N.runProperName pn
259− showRef (P.ProperRef pn) = pn
260− showRef (P.TypeInstanceRef ident) = N.runIdent ident
261− showRef (P.ModuleRef name) = "module " ++ N.runModuleName name
262− showRef (P.PositionedDeclarationRef _ _ ref) = showRef ref
263−
264− commaList :: [String] -> String
265− commaList = intercalate ", "
266−
267−-- |
268−-- Imports a module, preserving the initial state on failure.
269−--
270−handleImport :: ImportedModule -> PSCI ()
271−handleImport im = do
272− st <- updateImportedModules im <$> PSCI (lift get)
273− let m = createTemporaryModuleForImports st
274− e <- psciIO . runMake $ make st [m]
275− case e of
276− Left errs -> PSCI $ printErrors errs
277− Right _ -> do
278− PSCI $ lift $ put st
279− return ()
280−
281−-- |
282−-- Takes a value and prints its type
283−--
284−handleTypeOf :: P.Expr -> PSCI ()
285−handleTypeOf val = do
286− st <- PSCI $ lift get
287− let m = createTemporaryModule False st val
288− e <- psciIO . runMake $ make st [m]
289− case e of
290− Left errs -> PSCI $ printErrors errs
291− Right env' ->
292− case M.lookup (P.ModuleName [P.ProperName "$PSCI"], P.Ident "it") (P.names env') of
293− Just (ty, _, _) -> PSCI . outputStrLn . P.prettyPrintType $ ty
294− Nothing -> PSCI $ outputStrLn "Could not find type"
295−
296−-- |
297−-- Browse a module and displays its signature (if module exists).
298−--
299−handleBrowse :: P.ModuleName -> PSCI ()
300−handleBrowse moduleName = do
301− st <- PSCI $ lift get
302− env <- psciIO . runMake $ make st []
303− case env of
304− Left errs -> PSCI $ printErrors errs
305− Right env' ->
306− if isModInEnv moduleName st
307− then PSCI $ printModuleSignatures moduleName env'
308− else case lookupUnQualifiedModName moduleName st of
309− Just unQualifiedName ->
310− if isModInEnv unQualifiedName st
311− then PSCI $ printModuleSignatures unQualifiedName env'
312− else failNotInEnv moduleName
313− Nothing ->
314− failNotInEnv moduleName
315− where
316− isModInEnv modName =
317− any ((== modName) . P.getModuleName . snd) . psciLoadedModules
318− failNotInEnv modName =
319− PSCI $ outputStrLn $ "Module '" ++ N.runModuleName modName ++ "' is not valid."
320− lookupUnQualifiedModName quaModName st =
321− (\(modName,_,_) -> modName) <$> find ( \(_, _, mayQuaName) -> mayQuaName == Just quaModName) (psciImportedModules st)
322−
323−-- |
324−-- Takes a value and prints its kind
325−--
326−handleKindOf :: P.Type -> PSCI ()
327−handleKindOf typ = do
328− st <- PSCI $ lift get
329− let m = createTemporaryModuleForKind st typ
330− mName = P.ModuleName [P.ProperName "$PSCI"]
331− e <- psciIO . runMake $ make st [m]
332− case e of
333− Left errs -> PSCI $ printErrors errs
334− Right env' ->
335− case M.lookup (P.Qualified (Just mName) $ P.ProperName "IT") (P.typeSynonyms env') of
336− Just (_, typ') -> do
337− let chk = (P.emptyCheckState env') { P.checkCurrentModule = Just mName }
338− k = check (P.kindOf typ') chk
339−
340− check :: StateT P.CheckState (ExceptT P.MultipleErrors (Writer P.MultipleErrors)) a -> P.CheckState -> Either P.MultipleErrors (a, P.CheckState)
341− check sew = fst . runWriter . runExceptT . runStateT sew
342− case k of
343− Left errStack -> PSCI . outputStrLn . P.prettyPrintMultipleErrors False $ errStack
344− Right (kind, _) -> PSCI . outputStrLn . P.prettyPrintKind $ kind
345− Nothing -> PSCI $ outputStrLn "Could not find kind"
346−
347−-- Misc
348−
349−-- |
350−-- Attempts to read initial commands from '.psci' in the present working
351−-- directory then the user's home
352−--
353−loadUserConfig :: IO (Maybe [Command])
354−loadUserConfig = onFirstFileMatching readCommands pathGetters
355− where
356− pathGetters = [getCurrentDirectory, getHomeDirectory]
357− readCommands :: IO FilePath -> IO (Maybe [Command])
358− readCommands path = do
359− configFile <- (</> ".psci") <$> path
360− exists <- doesFileExist configFile
361− if exists
362− then do
363− ls <- lines <$> readUTF8File configFile
364− case traverse parseCommand ls of
365− Left err -> print err >> exitFailure
366− Right cs -> return $ Just cs
367− else
368− return Nothing
369−
370−-- | Checks if the Console module is defined
371−consoleIsDefined :: [P.Module] -> Bool
372−consoleIsDefined = any ((== P.ModuleName (map P.ProperName [ "Control", "Monad", "Eff", "Console" ])) . P.getModuleName)
psci/PSCi/Message.hsdeleted−53
@@ -1,53 +0,0 @@
1−module PSCi.Message where
2−
3−
4−import Data.List (intercalate)
5−import qualified PSCi.Directive as D
6−import PSCi.Types
7−
8−-- Messages
9−
10−-- |
11−-- The help message.
12−--
13−helpMessage :: String
14−helpMessage = "The following commands are available:\n\n " ++
15− intercalate "\n " (map line D.help) ++
16− "\n\n" ++ extraHelp
17− where
18− line :: (Directive, String, String) -> String
19− line (dir, arg, desc) =
20− let cmd = ':' : D.stringFor dir
21− in unwords [ cmd
22− , replicate (11 - length cmd) ' '
23− , arg
24− , replicate (11 - length arg) ' '
25− , desc
26− ]
27−
28− extraHelp =
29− "Further information is available on the PureScript wiki:\n" ++
30− " --> https://github.com/purescript/purescript/wiki/psci"
31−
32−
33−-- |
34−-- The welcome prologue.
35−--
36−prologueMessage :: String
37−prologueMessage = intercalate "\n"
38− [ " ____ ____ _ _ "
39− , "| _ \\ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_ "
40− , "| |_) | | | | '__/ _ \\___ \\ / __| '__| | '_ \\| __|"
41− , "| __/| |_| | | | __/___) | (__| | | | |_) | |_ "
42− , "|_| \\__,_|_| \\___|____/ \\___|_| |_| .__/ \\__|"
43− , " |_| "
44− , ""
45− , ":? shows help"
46− ]
47−
48−-- |
49−-- The quit message.
50−--
51−quitMessage :: String
52−quitMessage = "See ya!"
53−
psci/PSCi/Module.hsdeleted−107
@@ -1,107 +0,0 @@
1−module PSCi.Module where
2−
3−import Prelude ()
4−import Prelude.Compat
5−
6−import qualified Language.PureScript as P
7−import PSCi.Types
8−import System.FilePath (pathSeparator)
9−import System.IO.UTF8 (readUTF8File)
10−import Control.Monad
11−
12−-- | The name of the PSCI support module
13−supportModuleName :: P.ModuleName
14−supportModuleName = P.ModuleName [P.ProperName "$PSCI", P.ProperName "Support"]
15−
16−-- | Support module, contains code to evaluate terms
17−supportModule :: P.Module
18−supportModule =
19− case P.parseModulesFromFiles id [("", code)] of
20− Right [(_, P.Module ss cs _ ds exps)] -> P.Module ss cs supportModuleName ds exps
21− _ -> P.internalError "Support module could not be parsed"
22− where
23− code :: String
24− code = unlines
25− [ "module S where"
26− , ""
27− , "import Prelude"
28− , "import Control.Monad.Eff"
29− , "import Control.Monad.Eff.Console"
30− , "import Control.Monad.Eff.Unsafe"
31− , ""
32− , "class Eval a where"
33− , " eval :: a -> Eff (console :: CONSOLE) Unit"
34− , ""
35− , "instance evalShow :: (Show a) => Eval a where"
36− , " eval = print"
37− , ""
38− , "instance evalEff :: (Eval a) => Eval (Eff eff a) where"
39− , " eval x = unsafeInterleaveEff x >>= eval"
40− ]
41−
42−-- Module Management
43−
44−-- |
45−-- Loads a file for use with imports.
46−--
47−loadModule :: FilePath -> IO (Either String [P.Module])
48−loadModule filename = do
49− content <- readUTF8File filename
50− return $ either (Left . P.prettyPrintMultipleErrors False) (Right . map snd) $ P.parseModulesFromFiles id [(filename, content)]
51−
52−-- |
53−-- Load all modules.
54−--
55−loadAllModules :: [FilePath] -> IO (Either P.MultipleErrors [(FilePath, P.Module)])
56−loadAllModules files = do
57− filesAndContent <- forM files $ \filename -> do
58− content <- readUTF8File filename
59− return (filename, content)
60− return $ P.parseModulesFromFiles id filesAndContent
61−
62−
63−-- |
64−-- Makes a volatile module to execute the current expression.
65−--
66−createTemporaryModule :: Bool -> PSCiState -> P.Expr -> P.Module
67−createTemporaryModule exec PSCiState{psciImportedModules = imports, psciLetBindings = lets} val =
68− let
69− moduleName = P.ModuleName [P.ProperName "$PSCI"]
70− trace = P.Var (P.Qualified (Just supportModuleName) (P.Ident "eval"))
71− mainValue = P.App trace (P.Var (P.Qualified Nothing (P.Ident "it")))
72− itDecl = P.ValueDeclaration (P.Ident "it") P.Public [] $ Right val
73− mainDecl = P.ValueDeclaration (P.Ident "$main") P.Public [] $ Right mainValue
74− decls = if exec then [itDecl, mainDecl] else [itDecl]
75− in
76− P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ decls) Nothing
77−
78−
79−-- |
80−-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
81−--
82−createTemporaryModuleForKind :: PSCiState -> P.Type -> P.Module
83−createTemporaryModuleForKind PSCiState{psciImportedModules = imports, psciLetBindings = lets} typ =
84− let
85− moduleName = P.ModuleName [P.ProperName "$PSCI"]
86− itDecl = P.TypeSynonymDeclaration (P.ProperName "IT") [] typ
87− in
88− P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ [itDecl]) Nothing
89−
90−-- |
91−-- Makes a volatile module to execute the current imports.
92−--
93−createTemporaryModuleForImports :: PSCiState -> P.Module
94−createTemporaryModuleForImports PSCiState{psciImportedModules = imports} =
95− let
96− moduleName = P.ModuleName [P.ProperName "$PSCI"]
97− in
98− P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName (importDecl `map` imports) Nothing
99−
100−importDecl :: ImportedModule -> P.Declaration
101−importDecl (mn, declType, asQ) = P.ImportDeclaration mn declType asQ False
102−
103−indexFile :: FilePath
104−indexFile = ".psci_modules" ++ pathSeparator : "index.js"
105−
106−modulesDir :: FilePath
107−modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
psci/PSCi/Option.hsdeleted−57
@@ -1,57 +0,0 @@
1−module PSCi.Option (
2− getOpt
3−) where
4−
5−import Prelude ()
6−import Prelude.Compat
7−
8−import Options.Applicative as Opts
9−import Data.Version (showVersion)
10−
11−import PSCi.Types
12−import qualified Paths_purescript as Paths
13−
14−-- Parse Command line option
15−
16−multiLineMode :: Parser Bool
17−multiLineMode = switch $
18− long "multi-line-mode"
19− <> short 'm'
20− <> Opts.help "Run in multi-line mode (use ^D to terminate commands)"
21−
22−inputFile :: Parser FilePath
23−inputFile = strArgument $
24− metavar "FILE"
25− <> Opts.help "Optional .purs files to load on start"
26−
27−inputForeignFile :: Parser FilePath
28−inputForeignFile = strOption $
29− short 'f'
30− <> long "ffi"
31− <> help "The input .js file(s) providing foreign import implementations"
32−
33−nodeFlagsFlag :: Parser [String]
34−nodeFlagsFlag = option parser $
35− long "node-opts"
36− <> metavar "NODE_OPTS"
37− <> value []
38− <> Opts.help "Flags to pass to node, separated by spaces"
39− where
40− parser = words <$> str
41−
42−psciOptions :: Parser PSCiOptions
43−psciOptions = PSCiOptions <$> multiLineMode
44− <*> many inputFile
45− <*> many inputForeignFile
46− <*> nodeFlagsFlag
47−
48−version :: Parser (a -> a)
49−version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> Opts.help "Show the version number" <> hidden
50−
51−getOpt :: IO PSCiOptions
52−getOpt = execParser opts
53− where
54− opts = info (version <*> helper <*> psciOptions) infoModList
55− infoModList = fullDesc <> headerInfo <> footerInfo
56− headerInfo = header "psci - Interactive mode for PureScript"
57− footerInfo = footer $ "psci " ++ showVersion Paths.version
psci/PSCi/Types.hsdeleted−218
@@ -1,218 +0,0 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Types
4−-- Copyright : (c) Phil Freeman 2014
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−-- Type declarations and associated basic functions for PSCI.
13−--
14−-----------------------------------------------------------------------------
15−
16−module PSCi.Types where
17−
18−import Prelude ()
19−import Prelude.Compat
20−
21−import Control.Arrow (second)
22−import Data.Map (Map)
23−import qualified Data.Map as Map
24−import qualified Language.PureScript as P
25−
26−data PSCiOptions = PSCiOptions
27− { psciMultiLineMode :: Bool
28− , psciInputFile :: [FilePath]
29− , psciForeignInputFiles :: [FilePath]
30− , psciInputNodeFlags :: [String]
31− }
32−
33−-- |
34−-- The PSCI state.
35−-- Holds a list of imported modules, loaded files, and partial let bindings.
36−-- The let bindings are partial,
37−-- because it makes more sense to apply the binding to the final evaluated expression.
38−--
39−data PSCiState = PSCiState
40− { psciImportedModules :: [ImportedModule]
41− , _psciLoadedModules :: Map FilePath [P.Module]
42− , psciForeignFiles :: Map P.ModuleName FilePath
43− , psciLetBindings :: [P.Declaration]
44− , psciNodeFlags :: [String]
45− }
46−
47−initialPSCiState :: PSCiState
48−initialPSCiState =
49− PSCiState [] Map.empty Map.empty [] []
50−
51−mkPSCiState :: [ImportedModule]
52− -> [(FilePath, P.Module)]
53− -> Map P.ModuleName FilePath
54− -> [P.Declaration]
55− -> [String]
56− -> PSCiState
57−mkPSCiState imported loaded foreigns lets nodeFlags =
58− (initialPSCiState
59− |> each imported updateImportedModules
60− |> updateModules loaded)
61− { psciForeignFiles = foreigns
62− , psciLetBindings = lets
63− , psciNodeFlags = nodeFlags
64− }
65− where
66− x |> f = f x
67− each xs f st = foldl (flip f) st xs
68−
69−-- Public psci state accessors
70−
71−-- | Get the imported filenames as a list.
72−psciImportedFilenames :: PSCiState -> [FilePath]
73−psciImportedFilenames = Map.keys . _psciLoadedModules
74−
75−-- | Get the loaded modules as a list.
76−psciLoadedModules :: PSCiState -> [(FilePath, P.Module)]
77−psciLoadedModules = collect . Map.toList . _psciLoadedModules
78− where
79− collect :: [(k, [v])] -> [(k, v)]
80− collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
81−
82−-- | All of the data that is contained by an ImportDeclaration in the AST.
83−-- That is:
84−--
85−-- * A module name, the name of the module which is being imported
86−-- * An ImportDeclarationType which specifies whether there is an explicit
87−-- import list, a hiding list, or neither.
88−-- * If the module is imported qualified, its qualified name in the importing
89−-- module. Otherwise, Nothing.
90−--
91−type ImportedModule = (P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)
92−
93−psciImportedModuleNames :: PSCiState -> [P.ModuleName]
94−psciImportedModuleNames (PSCiState{psciImportedModules = is}) =
95− map (\(mn, _, _) -> mn) is
96−
97−allImportsOf :: P.Module -> PSCiState -> [ImportedModule]
98−allImportsOf m (PSCiState{psciImportedModules = is}) =
99− filter isImportOfThis is
100− where
101− name = P.getModuleName m
102− isImportOfThis (name', _, _) = name == name'
103−
104−-- State helpers
105−
106−-- |
107−-- Updates the state to have more imported modules.
108−--
109−updateImportedModules :: ImportedModule -> PSCiState -> PSCiState
110−updateImportedModules im st = st { psciImportedModules = im : psciImportedModules st }
111−
112−-- |
113−-- Updates the state to have more loaded modules (available for import, but
114−-- not necessarily imported).
115−--
116−updateModules :: [(FilePath, P.Module)] -> PSCiState -> PSCiState
117−updateModules modules st =
118− st { _psciLoadedModules = Map.union (go modules) (_psciLoadedModules st) }
119− where
120− go = Map.fromListWith (++) . map (second (:[]))
121−
122−-- |
123−-- Updates the state to have more let bindings.
124−--
125−updateLets :: [P.Declaration] -> PSCiState -> PSCiState
126−updateLets ds st = st { psciLetBindings = psciLetBindings st ++ ds }
127−
128−-- |
129−-- Updates the state to have more let bindings.
130−--
131−updateForeignFiles :: Map P.ModuleName FilePath -> PSCiState -> PSCiState
132−updateForeignFiles fs st = st { psciForeignFiles = psciForeignFiles st `Map.union` fs }
133−
134−-- |
135−-- Valid Meta-commands for PSCI
136−--
137−data Command
138− -- |
139− -- A purescript expression
140− --
141− = Expression P.Expr
142− -- |
143− -- Show the help (ie, list of directives)
144− --
145− | ShowHelp
146− -- |
147− -- Import a module from a loaded file
148− --
149− | Import ImportedModule
150− -- |
151− -- Browse a module
152− --
153− | BrowseModule P.ModuleName
154− -- |
155− -- Load a file for use with importing
156− --
157− | LoadFile FilePath
158− -- |
159− -- Load a foreign module
160− --
161− | LoadForeign FilePath
162− -- |
163− -- Exit PSCI
164− --
165− | QuitPSCi
166− -- |
167− -- Reset the state of the REPL
168− --
169− | ResetState
170− -- |
171− -- Add some declarations to the current evaluation context.
172− --
173− | Decls [P.Declaration]
174− -- |
175− -- Find the type of an expression
176− --
177− | TypeOf P.Expr
178− -- |
179− -- Find the kind of an expression
180− --
181− | KindOf P.Type
182− -- |
183− -- Shows information about the current state of the REPL
184− --
185− | ShowInfo ReplQuery
186−
187−data ReplQuery
188− = QueryLoaded
189− | QueryImport
190− deriving (Eq, Show)
191−
192−-- | A list of all ReplQuery values.
193−replQueries :: [ReplQuery]
194−replQueries = [QueryLoaded, QueryImport]
195−
196−replQueryStrings :: [String]
197−replQueryStrings = map showReplQuery replQueries
198−
199−showReplQuery :: ReplQuery -> String
200−showReplQuery QueryLoaded = "loaded"
201−showReplQuery QueryImport = "import"
202−
203−parseReplQuery :: String -> Maybe ReplQuery
204−parseReplQuery "loaded" = Just QueryLoaded
205−parseReplQuery "import" = Just QueryImport
206−parseReplQuery _ = Nothing
207−
208−data Directive
209− = Help
210− | Quit
211− | Reset
212− | Browse
213− | Load
214− | Foreign
215− | Type
216− | Kind
217− | Show
218− deriving (Eq, Show)
psci/main/Main.hsdeleted−6
@@ -1,6 +0,0 @@
1−module Main where
2−
3−import PSCi
4−
5−main :: IO ()
6−main = runPSCi
psci/static/index.htmlnew file+10
@@ -0,0 +1,10 @@
1+<!DOCTYPE html>
2+<html>
3+<head>
4+ <title>PureScript Interactive</title>
5+ <script src='js/bundle.js'></script>
6+ <script src='js/index.js'></script>
7+</head>
8+<body>
9+</body>
10+</html>
psci/static/index.jsnew file+63
@@ -0,0 +1,63 @@
1+var get = function get(uri, callback, onError) {
2+ var request = new XMLHttpRequest();
3+ request.addEventListener('load', function() {
4+ callback(request.responseText);
5+ });
6+ request.addEventListener('error', onError);
7+ request.open('GET', uri);
8+ request.send();
9+};
10+var evaluate = function evaluate(js) {
11+ var buffer = [];
12+ // Save the old console.log function
13+ var oldLog = console.log;
14+ console.log = function(s) {
15+ // Push log output into a temporary buffer
16+ // which will be returned to PSCi.
17+ buffer.push(s);
18+ };
19+ // Replace any require(...) statements with lookups on the PSCI object.
20+ var replaced = js.replace(/require\("[^"]*"\)/g, function(s) {
21+ return "PSCI['" + s.substring(12, s.length - 2) + "']";
22+ });
23+ // Wrap the module and evaluate it.
24+ var wrapped =
25+ [ 'var module = {};'
26+ , '(function(module) {'
27+ , replaced
28+ , '})(module);'
29+ , 'return module.exports["$main"] && module.exports["$main"]();'
30+ ].join('\n');
31+ new Function(wrapped)();
32+ // Restore console.log
33+ console.log = oldLog;
34+ return buffer.join('\n');
35+};
36+window.onload = function() {
37+ var socket = new WebSocket('ws://0.0.0.0:' + location.port);
38+ var evalNext = function reload() {
39+ get('js/latest.js', function(response) {
40+ try {
41+ var result = evaluate(response);
42+ socket.send(result);
43+ } catch (ex) {
44+ socket.send(ex.stack);
45+ }
46+ }, function(err) {
47+ socket.send('Error sending JavaScript');
48+ });
49+ };
50+ socket.onopen = function() {
51+ console.log('Connected');
52+ socket.onmessage = function(event) {
53+ switch (event.data) {
54+ case 'eval':
55+ evalNext();
56+ break;
57+ case 'reload':
58+ location.reload();
59+ break;
60+ }
61+ };
62+ };
63+};
purescript.cabal+280−126
@@ -1,5 +1,5 @@
1name: purescript
1name: purescript
2−version: 0.8.5.0
2+version: 0.9.3
3cabal-version: >=1.8
3cabal-version: >=1.8
4build-type: Simple
4build-type: Simple
5license: MIT
5license: MIT
@@ -20,27 +20,75 @@ author: Phil Freeman <paf31@cantab.net>,
20tested-with: GHC==7.10.3
20tested-with: GHC==7.10.3
21
21
22extra-source-files: examples/passing/*.purs
22extra-source-files: examples/passing/*.purs
23+ , examples/passing/*.js
24+ , examples/passing/2018/*.purs
25+ , examples/passing/2138/*.purs
26+ , examples/passing/ClassRefSyntax/*.purs
27+ , examples/passing/DctorOperatorAlias/*.purs
28+ , examples/passing/ExplicitImportReExport/*.purs
29+ , examples/passing/ExportExplicit/*.purs
30+ , examples/passing/ExportExplicit2/*.purs
31+ , examples/passing/Import/*.purs
32+ , examples/passing/ImportExplicit/*.purs
33+ , examples/passing/ImportQualified/*.purs
34+ , examples/passing/Module/*.purs
35+ , examples/passing/ModuleDeps/*.purs
36+ , examples/passing/ModuleExport/*.purs
37+ , examples/passing/ModuleExportDupes/*.purs
38+ , examples/passing/ModuleExportExcluded/*.purs
39+ , examples/passing/ModuleExportQualified/*.purs
40+ , examples/passing/ModuleExportSelf/*.purs
41+ , examples/passing/NonConflictingExports/*.purs
42+ , examples/passing/OperatorAliasElsewhere/*.purs
43+ , examples/passing/Operators/*.purs
44+ , examples/passing/PendingConflictingImports/*.purs
45+ , examples/passing/PendingConflictingImports2/*.purs
46+ , examples/passing/QualifiedNames/*.purs
47+ , examples/passing/RedefinedFixity/*.purs
48+ , examples/passing/ReExportQualified/*.purs
49+ , examples/passing/ResolvableScopeConflict/*.purs
50+ , examples/passing/ResolvableScopeConflict2/*.purs
51+ , examples/passing/ResolvableScopeConflict3/*.purs
52+ , examples/passing/ShadowedModuleName/*.purs
53+ , examples/passing/TransitiveImport/*.purs
54+ , examples/passing/TypeOperators/*.purs
55+ , examples/passing/TypeWithoutParens/*.purs
23 , examples/failing/*.purs
56 , examples/failing/*.purs
57+ , examples/failing/1733/*.purs
58+ , examples/failing/ConflictingExports/*.purs
59+ , examples/failing/ConflictingImports/*.purs
60+ , examples/failing/ConflictingImports2/*.purs
61+ , examples/failing/ConflictingQualifiedImports/*.purs
62+ , examples/failing/ConflictingQualifiedImports2/*.purs
63+ , examples/failing/ExportConflictClass/*.purs
64+ , examples/failing/ExportConflictCtor/*.purs
65+ , examples/failing/ExportConflictType/*.purs
66+ , examples/failing/ExportConflictTypeOp/*.purs
67+ , examples/failing/ExportConflictValue/*.purs
68+ , examples/failing/ExportConflictValueOp/*.purs
69+ , examples/failing/ExportExplicit1/*.purs
70+ , examples/failing/ExportExplicit3/*.purs
71+ , examples/failing/ImportExplicit/*.purs
72+ , examples/failing/ImportExplicit2/*.purs
73+ , examples/failing/ImportHidingModule/*.purs
74+ , examples/failing/ImportModule/*.purs
75+ , examples/failing/InstanceExport/*.purs
76+ , examples/failing/OrphanInstance/*.purs
77+ , examples/warning/*.purs
78+ , examples/warning/*.js
24 , examples/docs/bower_components/purescript-prelude/src/*.purs
79 , examples/docs/bower_components/purescript-prelude/src/*.purs
25 , examples/docs/bower.json
80 , examples/docs/bower.json
26 , examples/docs/src/*.purs
81 , examples/docs/src/*.purs
27− , tests/support/setup.js
82+ , psci/static/index.html
83+ , psci/static/index.js
28 , tests/support/package.json
84 , tests/support/package.json
29− , tests/support/prelude/bower.json
30− , tests/support/prelude/src/*.purs
31− , tests/support/prelude/src/*.js
32− , tests/support/prelude/LICENSE
33 , tests/support/bower.json
85 , tests/support/bower.json
34 , tests/support/setup-win.cmd
86 , tests/support/setup-win.cmd
35− , tests/support/flattened/*.purs
36− , tests/support/flattened/*.js
37 , tests/support/psci/*.purs
87 , tests/support/psci/*.purs
38 , tests/support/pscide/src/*.purs
88 , tests/support/pscide/src/*.purs
39 , tests/support/pscide/src/*.js
89 , tests/support/pscide/src/*.js
40 , tests/support/pscide/src/*.fail
90 , tests/support/pscide/src/*.fail
41 , stack.yaml
91 , stack.yaml
42− , stack-lts-5.yaml
43− , stack-nightly.yaml
44 , README.md
92 , README.md
45 , INSTALL.md
93 , INSTALL.md
46 , CONTRIBUTORS.md
94 , CONTRIBUTORS.md
@@ -53,47 +101,52 @@ source-repository head
53
101
54library
102library
55 build-depends: base >=4.8 && <5,
103 build-depends: base >=4.8 && <5,
104+ aeson >= 0.8 && < 1.1,
105+ aeson-better-errors >= 0.8,
106+ ansi-terminal >= 0.6.2 && < 0.7,
56 base-compat >=0.6.0,
107 base-compat >=0.6.0,
57− lifted-base >= 0.2.3 && < 0.2.4,
108+ bower-json >= 0.8,
58− monad-control >= 1.0.0.0 && < 1.1,
109+ boxes >= 0.1.4 && < 0.2.0,
59− transformers-base >= 0.4.0 && < 0.5,
110+ bytestring -any,
60 containers -any,
111 containers -any,
61− unordered-containers -any,
112+ clock -any,
62− dlist -any,
63 directory >= 1.2,
113 directory >= 1.2,
114+ dlist -any,
115+ edit-distance -any,
64 filepath -any,
116 filepath -any,
117+ fsnotify >= 0.2.1,
118+ Glob >= 0.7 && < 0.8,
119+ haskeline >= 0.7.0.0,
120+ http-client >= 0.4.30 && <0.5,
121+ http-types -any,
122+ language-javascript == 0.6.*,
123+ lifted-base >= 0.2.3 && < 0.2.4,
124+ monad-control >= 1.0.0.0 && < 1.1,
125+ monad-logger >= 0.3 && < 0.4,
65 mtl >= 2.1.0 && < 2.3.0,
126 mtl >= 2.1.0 && < 2.3.0,
127+ parallel >= 3.2 && < 3.3,
66− parsec -any,
128+ parsec >=3.1.10,
67− transformers >= 0.3.0 && < 0.6,
68− transformers-compat >= 0.3.0,
69− utf8-string >= 1 && < 2,
70 pattern-arrows >= 0.0.2 && < 0.1,
129 pattern-arrows >= 0.0.2 && < 0.1,
71− time -any,
130+ pipes >= 4.0.0 && < 4.3.0,
72− boxes >= 0.1.4 && < 0.2.0,
131+ pipes-http -any,
73− aeson >= 0.8 && < 0.12,
74− vector -any,
75− bower-json >= 0.8,
76− aeson-better-errors >= 0.8,
77− bytestring -any,
78− text -any,
79− split -any,
80− language-javascript == 0.6.*,
81− syb -any,
82− Glob >= 0.7 && < 0.8,
83 process >= 1.2.0 && < 1.5,
132 process >= 1.2.0 && < 1.5,
133+ protolude >= 0.1.6,
134+ regex-tdfa -any,
84 safe >= 0.3.9 && < 0.4,
135 safe >= 0.3.9 && < 0.4,
85 semigroups >= 0.16.2 && < 0.19,
136 semigroups >= 0.16.2 && < 0.19,
86− parallel >= 3.2 && < 3.3,
87 sourcemap >= 0.1.6,
137 sourcemap >= 0.1.6,
138+ spdx == 0.2.*,
139+ split -any,
88 stm >= 0.2.4.0,
140 stm >= 0.2.4.0,
89− regex-tdfa -any,
141+ syb -any,
90− edit-distance -any,
142+ text -any,
91− fsnotify >= 0.2.1,
143+ time -any,
92− monad-logger >= 0.3 && < 0.4,
144+ transformers >= 0.3.0 && < 0.6,
93− pipes >= 4.0.0 && < 4.2.0 ,
145+ transformers-base >= 0.4.0 && < 0.5,
94− pipes-http -any,
146+ transformers-compat >= 0.3.0,
95− http-types -any,
147+ unordered-containers -any,
96− spdx == 0.2.*
148+ utf8-string >= 1 && < 2,
149+ vector -any
97
150
98 exposed-modules: Language.PureScript
151 exposed-modules: Language.PureScript
99 Language.PureScript.AST
152 Language.PureScript.AST
@@ -158,7 +211,6 @@ library
158 Language.PureScript.Parser.Lexer
211 Language.PureScript.Parser.Lexer
159 Language.PureScript.Parser.Common
212 Language.PureScript.Parser.Common
160 Language.PureScript.Parser.Declarations
213 Language.PureScript.Parser.Declarations
161− Language.PureScript.Parser.JS
162 Language.PureScript.Parser.Kinds
214 Language.PureScript.Parser.Kinds
163 Language.PureScript.Parser.State
215 Language.PureScript.Parser.State
164 Language.PureScript.Parser.Types
216 Language.PureScript.Parser.Types
@@ -174,9 +226,10 @@ library
174 Language.PureScript.Sugar.CaseDeclarations
226 Language.PureScript.Sugar.CaseDeclarations
175 Language.PureScript.Sugar.DoNotation
227 Language.PureScript.Sugar.DoNotation
176 Language.PureScript.Sugar.Names
228 Language.PureScript.Sugar.Names
229+ Language.PureScript.Sugar.Names.Common
177 Language.PureScript.Sugar.Names.Env
230 Language.PureScript.Sugar.Names.Env
178− Language.PureScript.Sugar.Names.Imports
179 Language.PureScript.Sugar.Names.Exports
231 Language.PureScript.Sugar.Names.Exports
232+ Language.PureScript.Sugar.Names.Imports
180 Language.PureScript.Sugar.ObjectWildcards
233 Language.PureScript.Sugar.ObjectWildcards
181 Language.PureScript.Sugar.Operators
234 Language.PureScript.Sugar.Operators
182 Language.PureScript.Sugar.Operators.Common
235 Language.PureScript.Sugar.Operators.Common
@@ -219,22 +272,33 @@ library
219 Language.PureScript.Publish.BoxesHelpers
272 Language.PureScript.Publish.BoxesHelpers
220
273
221 Language.PureScript.Ide
274 Language.PureScript.Ide
275+ Language.PureScript.Ide.CaseSplit
222 Language.PureScript.Ide.Command
276 Language.PureScript.Ide.Command
277+ Language.PureScript.Ide.Completion
278+ Language.PureScript.Ide.Conversions
223 Language.PureScript.Ide.Externs
279 Language.PureScript.Ide.Externs
224 Language.PureScript.Ide.Error
280 Language.PureScript.Ide.Error
225− Language.PureScript.Ide.Pursuit
281+ Language.PureScript.Ide.Imports
226− Language.PureScript.Ide.Completion
227− Language.PureScript.Ide.Matcher
228 Language.PureScript.Ide.Filter
282 Language.PureScript.Ide.Filter
229− Language.PureScript.Ide.Types
283+ Language.PureScript.Ide.Matcher
230− Language.PureScript.Ide.State
284+ Language.PureScript.Ide.Pursuit
231− Language.PureScript.Ide.CaseSplit
285+ Language.PureScript.Ide.Rebuild
232− Language.PureScript.Ide.SourceFile
233− Language.PureScript.Ide.Watcher
234 Language.PureScript.Ide.Reexports
286 Language.PureScript.Ide.Reexports
235− Language.PureScript.Ide.Imports
287+ Language.PureScript.Ide.SourceFile
288+ Language.PureScript.Ide.State
289+ Language.PureScript.Ide.Types
236 Language.PureScript.Ide.Util
290 Language.PureScript.Ide.Util
237− Language.PureScript.Ide.Rebuild
291+ Language.PureScript.Ide.Watcher
292+
293+ Language.PureScript.Interactive
294+ Language.PureScript.Interactive.Types
295+ Language.PureScript.Interactive.Parser
296+ Language.PureScript.Interactive.Directive
297+ Language.PureScript.Interactive.Completion
298+ Language.PureScript.Interactive.IO
299+ Language.PureScript.Interactive.Message
300+ Language.PureScript.Interactive.Module
301+ Language.PureScript.Interactive.Printer
238
302
239 Control.Monad.Logger
303 Control.Monad.Logger
240 Control.Monad.Supply
304 Control.Monad.Supply
@@ -242,7 +306,22 @@ library
242
306
243 System.IO.UTF8
307 System.IO.UTF8
244
308
309+ extensions: ConstraintKinds
245− extensions: DataKinds
310+ DataKinds
311+ DeriveFunctor
312+ EmptyDataDecls
313+ FlexibleContexts
314+ KindSignatures
315+ LambdaCase
316+ MultiParamTypeClasses
317+ NoImplicitPrelude
318+ PatternGuards
319+ PatternSynonyms
320+ RankNTypes
321+ RecordWildCards
322+ ScopedTypeVariables
323+ TupleSections
324+ ViewPatterns
246 exposed: True
325 exposed: True
247 buildable: True
326 buildable: True
248 hs-source-dirs: src
327 hs-source-dirs: src
@@ -250,11 +329,23 @@ library
250 ghc-options: -Wall -O2
329 ghc-options: -Wall -O2
251
330
252executable psc
331executable psc
253− build-depends: base >=4 && <5, base-compat >=0.6.0,
332+ build-depends: base >=4 && <5,
333+ purescript -any,
334+ aeson >= 0.8 && < 1.1,
335+ ansi-terminal >= 0.6.2 && < 0.7,
336+ base-compat >=0.6.0,
337+ bytestring -any,
254− containers -any, directory -any, filepath -any,
338+ containers -any,
339+ directory -any,
340+ filepath -any,
341+ Glob >= 0.7 && < 0.8,
342+ mtl -any,
255− mtl -any, optparse-applicative >= 0.12.1, parsec -any, purescript -any,
343+ optparse-applicative >= 0.12.1,
344+ parsec -any,
345+ time -any,
346+ transformers -any,
256− time -any, transformers -any, transformers-compat -any, Glob >= 0.7 && < 0.8,
347+ transformers-compat -any,
257− aeson >= 0.8 && < 0.12, bytestring -any, utf8-string >= 1 && < 2
348+ utf8-string >= 1 && < 2
258 main-is: Main.hs
349 main-is: Main.hs
259 buildable: True
350 buildable: True
260 hs-source-dirs: psc
351 hs-source-dirs: psc
@@ -262,33 +353,49 @@ executable psc
262 ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
353 ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
263
354
264executable psci
355executable psci
265− build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
356+ build-depends: base >=4 && <5,
357+ purescript -any,
358+ base-compat >=0.6.0,
359+ boxes >= 0.1.4 && < 0.2.0,
360+ bytestring -any,
361+ containers -any,
362+ directory -any,
363+ filepath -any,
364+ file-embed -any,
365+ Glob -any,
366+ haskeline >= 0.7.0.0,
367+ http-types == 0.9.*,
368+ mtl -any,
266− mtl -any, optparse-applicative >= 0.12.1, parsec -any,
369+ optparse-applicative >= 0.12.1,
267− haskeline >= 0.7.0.0, purescript -any, transformers -any,
370+ parsec -any,
268− transformers-compat -any, process -any, time -any, Glob -any, base-compat >=0.6.0,
371+ process -any,
269− boxes >= 0.1.4 && < 0.2.0
372+ stm >= 0.2.4.0,
270−
373+ text -any,
374+ time -any,
375+ transformers -any,
376+ transformers-compat -any,
377+ wai == 3.*,
378+ wai-websockets == 3.*,
379+ warp == 3.*,
380+ websockets >= 0.9 && <0.10
271 main-is: Main.hs
381 main-is: Main.hs
272 buildable: True
382 buildable: True
273− hs-source-dirs: psci psci/main
383+ hs-source-dirs: psci
274− other-modules: PSCi
275− PSCi.Types
276− PSCi.Parser
277− PSCi.Directive
278− PSCi.Completion
279− PSCi.IO
280− PSCi.Message
281− PSCi.Option
282− PSCi.Module
283− PSCi.Printer
284− Paths_purescript
384+ other-modules: Paths_purescript
285 ghc-options: -Wall -O2
385 ghc-options: -Wall -O2
286
386
287executable psc-docs
387executable psc-docs
288− build-depends: base >=4 && <5, purescript -any,
388+ build-depends: base >=4 && <5,
389+ purescript -any,
390+ ansi-wl-pprint -any,
391+ directory -any,
392+ filepath -any,
393+ Glob -any,
394+ mtl -any,
289− optparse-applicative >= 0.12.1, process -any, mtl -any,
395+ optparse-applicative >= 0.12.1,
290− split -any, ansi-wl-pprint -any, directory -any,
396+ process -any,
397+ split -any,
291− filepath -any, Glob -any, transformers -any,
398+ transformers -any,
292 transformers-compat -any
399 transformers-compat -any
293 main-is: Main.hs
400 main-is: Main.hs
294 other-modules: Paths_purescript
401 other-modules: Paths_purescript
@@ -300,7 +407,11 @@ executable psc-docs
300 ghc-options: -Wall -O2
407 ghc-options: -Wall -O2
301
408
302executable psc-publish
409executable psc-publish
410+ build-depends: base >=4 && <5,
411+ purescript -any,
412+ aeson -any,
413+ bytestring -any,
303− build-depends: base >=4 && <5, purescript -any, bytestring -any, aeson -any, optparse-applicative -any
414+ optparse-applicative -any
304 main-is: Main.hs
415 main-is: Main.hs
305 other-modules: Paths_purescript
416 other-modules: Paths_purescript
306 buildable: True
417 buildable: True
@@ -308,9 +419,15 @@ executable psc-publish
308 ghc-options: -Wall -O2
419 ghc-options: -Wall -O2
309
420
310executable psc-hierarchy
421executable psc-hierarchy
422+ build-depends: base >=4 && <5,
423+ purescript -any,
424+ directory -any,
425+ filepath -any,
426+ Glob -any,
427+ mtl -any,
311− build-depends: base >=4 && <5, purescript -any, optparse-applicative >= 0.12.1,
428+ optparse-applicative >= 0.12.1,
312− process -any, mtl -any, parsec -any, filepath -any, directory -any,
429+ parsec -any,
313− Glob -any
430+ process -any
314 main-is: Main.hs
431 main-is: Main.hs
315 other-modules: Paths_purescript
432 other-modules: Paths_purescript
316 buildable: True
433 buildable: True
@@ -324,13 +441,13 @@ executable psc-bundle
324 other-extensions:
441 other-extensions:
325 build-depends: base >=4 && <5,
442 build-depends: base >=4 && <5,
326 purescript -any,
443 purescript -any,
327− filepath -any,
328 directory -any,
444 directory -any,
445+ filepath -any,
446+ Glob -any,
329 mtl -any,
447 mtl -any,
330− transformers -any,
331− transformers-compat -any,
332 optparse-applicative >= 0.12.1,
448 optparse-applicative >= 0.12.1,
333− Glob -any
449+ transformers -any,
450+ transformers-compat -any
334 ghc-options: -Wall -O2
451 ghc-options: -Wall -O2
335 hs-source-dirs: psc-bundle
452 hs-source-dirs: psc-bundle
336
453
@@ -338,19 +455,22 @@ executable psc-ide-server
338 main-is: Main.hs
455 main-is: Main.hs
339 other-modules: Paths_purescript
456 other-modules: Paths_purescript
340 other-extensions:
457 other-extensions:
341− build-depends: base >=4 && <5
458+ build-depends: base >=4 && <5,
459+ aeson >= 0.8 && < 1.1,
460+ bytestring -any,
342− , purescript -any
461+ purescript -any,
462+ base-compat >=0.6.0,
343− , directory -any
463+ directory -any,
344− , filepath -any
464+ filepath -any,
345− , monad-logger -any
465+ monad-logger -any,
346− , mtl -any
466+ mtl -any,
347− , transformers -any
348− , transformers-compat -any
349− , network -any
467+ network -any,
350− , optparse-applicative >= 0.12.1
468+ optparse-applicative >= 0.12.1,
469+ protolude >= 0.1.6,
351− , stm -any
470+ stm -any,
352− , text -any
471+ text -any,
353− , base-compat >=0.6.0
472+ transformers -any,
473+ transformers-compat -any
354 ghc-options: -Wall -O2 -threaded
474 ghc-options: -Wall -O2 -threaded
355 hs-source-dirs: psc-ide-server
475 hs-source-dirs: psc-ide-server
356
476
@@ -358,35 +478,71 @@ executable psc-ide-client
358 main-is: Main.hs
478 main-is: Main.hs
359 other-modules: Paths_purescript
479 other-modules: Paths_purescript
360 other-extensions:
480 other-extensions:
361− build-depends: base >=4 && <5
481+ build-depends: base >=4 && <5,
482+ base-compat >=0.6.0,
483+ bytestring -any,
362− , mtl -any
484+ mtl -any,
363− , text -any
485+ network -any,
364− , optparse-applicative >= 0.12.1
486+ optparse-applicative >= 0.12.1,
365− , network -any
487+ text -any
366− , base-compat >=0.6.0
367 ghc-options: -Wall -O2
488 ghc-options: -Wall -O2
368 hs-source-dirs: psc-ide-client
489 hs-source-dirs: psc-ide-client
369
490
370executable pcc
491executable pcc
371− build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
492+ build-depends: base >=4 && <5,
372− file-embed -any,
493+ purescript -any,
494+ aeson -any,
495+ ansi-terminal >= 0.6.2 && < 0.7,
496+ base-compat >=0.6.0,
373 bytestring -any,
497 bytestring -any,
498+ containers -any,
499+ directory -any,
500+ filepath -any,
501+ file-embed -any,
502+ Glob >= 0.7 && < 0.8,
503+ mtl -any,
374− mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
504+ optparse-applicative >= 0.12.1,
505+ parsec -any,
506+ time -any,
507+ transformers -any,
375− time -any, transformers -any, transformers-compat -any
508+ transformers-compat -any,
509+ utf8-string >= 1 && < 2
376 main-is: Main.hs
510 main-is: Main.hs
377 buildable: True
511 buildable: True
378 hs-source-dirs: pcc
512 hs-source-dirs: pcc
379− other-modules:
513+ other-modules: Paths_purescript
380− ghc-options: -Wall -O2 -fno-warn-unused-do-bind
514+ ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
515+
381
516
382test-suite tests
517test-suite tests
383− build-depends: base >=4 && <5, containers -any, directory -any,
518+ build-depends: base >=4 && <5,
519+ purescript -any,
520+ aeson -any,
521+ aeson-better-errors -any,
522+ base-compat -any,
523+ boxes -any,
524+ bytestring -any,
525+ containers -any,
526+ directory -any,
384− filepath -any, mtl -any, parsec -any, purescript -any,
527+ filepath -any,
385− transformers -any, process -any, transformers-compat -any, time -any,
528+ Glob -any,
386− Glob -any, aeson-better-errors -any, bytestring -any, aeson -any,
529+ haskeline >= 0.7.0.0,
530+ hspec -any,
531+ hspec-discover -any,
532+ HUnit -any,
533+ mtl -any,
387− base-compat -any, haskeline >= 0.7.0.0, optparse-applicative -any,
534+ optparse-applicative -any,
388− boxes -any, HUnit -any, hspec -any, hspec-discover -any, stm -any, text -any,
535+ parsec -any,
536+ process -any,
537+ protolude >= 0.1.6,
538+ silently -any,
539+ stm -any,
540+ text -any,
541+ time -any,
542+ transformers -any,
543+ transformers-compat -any,
389− vector -any, utf8-string -any
544+ utf8-string -any,
545+ vector -any
390 ghc-options: -Wall
546 ghc-options: -Wall
391 type: exitcode-stdio-1.0
547 type: exitcode-stdio-1.0
392 main-is: Main.hs
548 main-is: Main.hs
@@ -404,13 +560,10 @@ test-suite tests
404 Language.PureScript.Ide.MatcherSpec
560 Language.PureScript.Ide.MatcherSpec
405 Language.PureScript.Ide.RebuildSpec
561 Language.PureScript.Ide.RebuildSpec
406 Language.PureScript.Ide.ReexportsSpec
562 Language.PureScript.Ide.ReexportsSpec
407− Language.PureScript.IdeSpec
563+ Language.PureScript.Ide.SourceFile.IntegrationSpec
408− PSCi.Completion
564+ Language.PureScript.Ide.SourceFileSpec
409− PSCi.Directive
410− PSCi.Module
411− PSCi.Types
412 buildable: True
565 buildable: True
413− hs-source-dirs: tests psci
566+ hs-source-dirs: tests
414
567
415test-suite pcc-tests
568test-suite pcc-tests
416 build-depends: base >=4 && <5, directory -any, filepath -any, process -any
569 build-depends: base >=4 && <5, directory -any, filepath -any, process -any
@@ -418,3 +571,4 @@ test-suite pcc-tests
418 main-is: TestMain.hs
571 main-is: TestMain.hs
419 buildable: True
572 buildable: True
420 hs-source-dirs: pcc
573 hs-source-dirs: pcc
574+
src/Control/Monad/Logger.hs+7−20
@@ -1,33 +1,20 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Control.Monad.Logger
4−-- Author : Phil Freeman
5−-- License : MIT (http://opensource.org/licenses/MIT)
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | A replacement for WriterT IO which uses mutable references.
12−--
13−-----------------------------------------------------------------------------
14−
15{-# LANGUAGE FlexibleInstances #-}
1{-# LANGUAGE FlexibleInstances #-}
16−{-# LANGUAGE MultiParamTypeClasses #-}
17{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE TypeFamilies #-}
18
3
4+-- |
5+-- A replacement for WriterT IO which uses mutable references.
6+--
19module Control.Monad.Logger where
7module Control.Monad.Logger where
20
8
21−import Prelude ()
22import Prelude.Compat
9import Prelude.Compat
23
10
24−import Data.IORef
25−
26import Control.Monad (ap)
11import Control.Monad (ap)
27−import Control.Monad.IO.Class
28−import Control.Monad.Writer.Class
29import Control.Monad.Base (MonadBase(..))
12import Control.Monad.Base (MonadBase(..))
13+import Control.Monad.IO.Class
30import Control.Monad.Trans.Control (MonadBaseControl(..))
14import Control.Monad.Trans.Control (MonadBaseControl(..))
15+import Control.Monad.Writer.Class
16+
17+import Data.IORef
31
18
32-- | A replacement for WriterT IO which uses mutable references.
19-- | A replacement for WriterT IO which uses mutable references.
33newtype Logger w a = Logger { runLogger :: IORef w -> IO a }
20newtype Logger w a = Logger { runLogger :: IORef w -> IO a }
src/Control/Monad/Supply.hs+5−18
@@ -1,32 +1,19 @@
1−-----------------------------------------------------------------------------
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2−--
2+
3−-- Module : Control.Monad.Supply
4−-- Copyright : (c) Phil Freeman 2014
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11-- |
3-- |
12-- Fresh variable supply
4-- Fresh variable supply
13--
5--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17−
18module Control.Monad.Supply where
6module Control.Monad.Supply where
19
7
20−import Prelude ()
21import Prelude.Compat
8import Prelude.Compat
22
9
23−import Data.Functor.Identity
24−
25−import Control.Monad.State
26import Control.Monad.Error.Class (MonadError(..))
10import Control.Monad.Error.Class (MonadError(..))
27import Control.Monad.Reader
11import Control.Monad.Reader
12+import Control.Monad.State
28import Control.Monad.Writer
13import Control.Monad.Writer
29
14
15+import Data.Functor.Identity
16+
30newtype SupplyT m a = SupplyT { unSupplyT :: StateT Integer m a }
17newtype SupplyT m a = SupplyT { unSupplyT :: StateT Integer m a }
31 deriving (Functor, Applicative, Monad, MonadTrans, MonadError e, MonadWriter w, MonadReader r)
18 deriving (Functor, Applicative, Monad, MonadTrans, MonadError e, MonadWriter w, MonadReader r)
32
19
src/Control/Monad/Supply/Class.hs+6−6
@@ -1,24 +1,24 @@
1−{-# LANGUAGE MultiParamTypeClasses #-}
2−
3-- |
1-- |
4-- A class for monads supporting a supply of fresh names
2-- A class for monads supporting a supply of fresh names
5--
3--
6module Control.Monad.Supply.Class where
4module Control.Monad.Supply.Class where
7
5
6+import Prelude.Compat
7+
8import Control.Monad.Supply
8import Control.Monad.Supply
9import Control.Monad.State
9import Control.Monad.State
10
10
11−class (Monad m) => MonadSupply m where
11+class Monad m => MonadSupply m where
12 fresh :: m Integer
12 fresh :: m Integer
13
13
14−instance (Monad m) => MonadSupply (SupplyT m) where
14+instance Monad m => MonadSupply (SupplyT m) where
15 fresh = SupplyT $ do
15 fresh = SupplyT $ do
16 n <- get
16 n <- get
17 put (n + 1)
17 put (n + 1)
18 return n
18 return n
19
19
20−instance (MonadSupply m) => MonadSupply (StateT s m) where
20+instance MonadSupply m => MonadSupply (StateT s m) where
21 fresh = lift fresh
21 fresh = lift fresh
22
22
23−freshName :: (MonadSupply m) => m String
23+freshName :: MonadSupply m => m String
24freshName = fmap (('$' :) . show) fresh
24freshName = fmap (('$' :) . show) fresh
src/Language/PureScript.hs+5−17
@@ -1,33 +1,22 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11-- |
1-- |
12-- The main compiler module
2-- The main compiler module
13--
3--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
18−
19module Language.PureScript
4module Language.PureScript
20 ( module P
5 ( module P
21 , version
6 , version
22 ) where
7 ) where
23
8
9+
10+import Control.Monad.Supply as P
11+
24import Data.Version (Version)
12import Data.Version (Version)
25
13
26import Language.PureScript.AST as P
14import Language.PureScript.AST as P
27−import Language.PureScript.Crash as P
28import Language.PureScript.Comments as P
15import Language.PureScript.Comments as P
16+import Language.PureScript.Crash as P
29import Language.PureScript.Environment as P
17import Language.PureScript.Environment as P
30import Language.PureScript.Errors as P hiding (indent)
18import Language.PureScript.Errors as P hiding (indent)
19+import Language.PureScript.Externs as P
31import Language.PureScript.Kinds as P
20import Language.PureScript.Kinds as P
32import Language.PureScript.Linter as P
21import Language.PureScript.Linter as P
33import Language.PureScript.Make as P
22import Language.PureScript.Make as P
@@ -38,7 +27,6 @@ import Language.PureScript.Parser as P
38import Language.PureScript.Pretty as P
27import Language.PureScript.Pretty as P
39import Language.PureScript.Renamer as P
28import Language.PureScript.Renamer as P
40import Language.PureScript.Sugar as P
29import Language.PureScript.Sugar as P
41−import Control.Monad.Supply as P
42import Language.PureScript.TypeChecker as P
30import Language.PureScript.TypeChecker as P
43import Language.PureScript.Types as P
31import Language.PureScript.Types as P
44
32
src/Language/PureScript/AST/Binders.hs+4−2
@@ -3,6 +3,8 @@
3--
3--
4module Language.PureScript.AST.Binders where
4module Language.PureScript.AST.Binders where
5
5
6+import Prelude.Compat
7+
6import Language.PureScript.AST.SourcePos
8import Language.PureScript.AST.SourcePos
7import Language.PureScript.AST.Literals
9import Language.PureScript.AST.Literals
8import Language.PureScript.Names
10import Language.PureScript.Names
@@ -33,7 +35,7 @@ data Binder
33 -- A operator alias binder. During the rebracketing phase of desugaring,
35 -- A operator alias binder. During the rebracketing phase of desugaring,
34 -- this data constructor will be removed.
36 -- this data constructor will be removed.
35 --
37 --
36− | OpBinder (Qualified Ident)
38+ | OpBinder (Qualified (OpName 'ValueOpName))
37 -- |
39 -- |
38 -- Binary operator application. During the rebracketing phase of desugaring,
40 -- Binary operator application. During the rebracketing phase of desugaring,
39 -- this data constructor will be removed.
41 -- this data constructor will be removed.
@@ -59,7 +61,7 @@ data Binder
59 -- A binder with a type annotation
61 -- A binder with a type annotation
60 --
62 --
61 | TypedBinder Type Binder
63 | TypedBinder Type Binder
62− deriving (Show, Read, Eq)
64+ deriving (Show, Eq)
63
65
64-- |
66-- |
65-- Collect all names introduced in binders in an expression
67-- Collect all names introduced in binders in an expression
src/Language/PureScript/AST/Declarations.hs+227−92
@@ -1,23 +1,17 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE TemplateHaskell #-}
1{-# LANGUAGE TemplateHaskell #-}
3−{-# LANGUAGE LambdaCase #-}
4
2
5-- |
3-- |
6-- Data types for modules and declarations
4-- Data types for modules and declarations
7--
5--
8module Language.PureScript.AST.Declarations where
6module Language.PureScript.AST.Declarations where
9
7
10−import Prelude ()
11import Prelude.Compat
8import Prelude.Compat
12
9
13−import Data.Aeson.TH
10+import Control.Monad.Identity
14−import Data.List (nub, (\\))
15−import Data.Maybe (mapMaybe)
16
11
12+import Data.Aeson.TH
17import qualified Data.Map as M
13import qualified Data.Map as M
18
14
19−import Control.Monad.Identity
20−
21import Language.PureScript.AST.Binders
15import Language.PureScript.AST.Binders
22import Language.PureScript.AST.Literals
16import Language.PureScript.AST.Literals
23import Language.PureScript.AST.Operators
17import Language.PureScript.AST.Operators
@@ -28,6 +22,148 @@ import Language.PureScript.Kinds
28import Language.PureScript.TypeClassDictionaries
22import Language.PureScript.TypeClassDictionaries
29import Language.PureScript.Comments
23import Language.PureScript.Comments
30import Language.PureScript.Environment
24import Language.PureScript.Environment
25+import qualified Language.PureScript.Bundle as Bundle
26+
27+import qualified Text.Parsec as P
28+
29+-- | A map of locally-bound names in scope.
30+type Context = [(Ident, Type)]
31+
32+-- | A type of error messages
33+data SimpleErrorMessage
34+ = ErrorParsingFFIModule FilePath (Maybe Bundle.ErrorMessage)
35+ | ErrorParsingModule P.ParseError
36+ | MissingFFIModule ModuleName
37+ | MultipleFFIModules ModuleName [FilePath]
38+ | UnnecessaryFFIModule ModuleName FilePath
39+ | MissingFFIImplementations ModuleName [Ident]
40+ | UnusedFFIImplementations ModuleName [Ident]
41+ | InvalidFFIIdentifier ModuleName String
42+ | CannotGetFileInfo FilePath
43+ | CannotReadFile FilePath
44+ | CannotWriteFile FilePath
45+ | InfiniteType Type
46+ | InfiniteKind Kind
47+ | MultipleValueOpFixities (OpName 'ValueOpName)
48+ | MultipleTypeOpFixities (OpName 'TypeOpName)
49+ | OrphanTypeDeclaration Ident
50+ | RedefinedModule ModuleName [SourceSpan]
51+ | RedefinedIdent Ident
52+ | OverlappingNamesInLet
53+ | UnknownName (Qualified Name)
54+ | UnknownImport ModuleName Name
55+ | UnknownImportDataConstructor ModuleName (ProperName 'TypeName) (ProperName 'ConstructorName)
56+ | UnknownExport Name
57+ | UnknownExportDataConstructor (ProperName 'TypeName) (ProperName 'ConstructorName)
58+ | ScopeConflict Name [ModuleName]
59+ | ScopeShadowing Name (Maybe ModuleName) [ModuleName]
60+ | DeclConflict Name Name
61+ | ExportConflict (Qualified Name) (Qualified Name)
62+ | DuplicateModuleName ModuleName
63+ | DuplicateTypeArgument String
64+ | InvalidDoBind
65+ | InvalidDoLet
66+ | CycleInDeclaration Ident
67+ | CycleInTypeSynonym (Maybe (ProperName 'TypeName))
68+ | CycleInModules [ModuleName]
69+ | NameIsUndefined Ident
70+ | UndefinedTypeVariable (ProperName 'TypeName)
71+ | PartiallyAppliedSynonym (Qualified (ProperName 'TypeName))
72+ | EscapedSkolem (Maybe Expr)
73+ | TypesDoNotUnify Type Type
74+ | KindsDoNotUnify Kind Kind
75+ | ConstrainedTypeUnified Type Type
76+ | OverlappingInstances (Qualified (ProperName 'ClassName)) [Type] [Qualified Ident]
77+ | NoInstanceFound Constraint
78+ | PossiblyInfiniteInstance (Qualified (ProperName 'ClassName)) [Type]
79+ | CannotDerive (Qualified (ProperName 'ClassName)) [Type]
80+ | CannotFindDerivingType (ProperName 'TypeName)
81+ | DuplicateLabel String (Maybe Expr)
82+ | DuplicateValueDeclaration Ident
83+ | ArgListLengthsDiffer Ident
84+ | OverlappingArgNames (Maybe Ident)
85+ | MissingClassMember Ident
86+ | ExtraneousClassMember Ident (Qualified (ProperName 'ClassName))
87+ | ExpectedType Type Kind
88+ | IncorrectConstructorArity (Qualified (ProperName 'ConstructorName))
89+ | ExprDoesNotHaveType Expr Type
90+ | PropertyIsMissing String
91+ | AdditionalProperty String
92+ | CannotApplyFunction Type Expr
93+ | TypeSynonymInstance
94+ | OrphanInstance Ident (Qualified (ProperName 'ClassName)) [Type]
95+ | InvalidNewtype (ProperName 'TypeName)
96+ | InvalidInstanceHead Type
97+ | TransitiveExportError DeclarationRef [DeclarationRef]
98+ | TransitiveDctorExportError DeclarationRef (ProperName 'ConstructorName)
99+ | ShadowedName Ident
100+ | ShadowedTypeVar String
101+ | UnusedTypeVar String
102+ | WildcardInferredType Type Context
103+ | HoleInferredType String Type Context
104+ | MissingTypeDeclaration Ident Type
105+ | OverlappingPattern [[Binder]] Bool
106+ | IncompleteExhaustivityCheck
107+ | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
108+ | ImportHidingModule ModuleName
109+ | UnusedImport ModuleName
110+ | UnusedExplicitImport ModuleName [String] (Maybe ModuleName) [DeclarationRef]
111+ | UnusedDctorImport (ProperName 'TypeName)
112+ | UnusedDctorExplicitImport (ProperName 'TypeName) [ProperName 'ConstructorName]
113+ | DuplicateSelectiveImport ModuleName
114+ | DuplicateImport ModuleName ImportDeclarationType (Maybe ModuleName)
115+ | DuplicateImportRef Name
116+ | DuplicateExportRef Name
117+ | IntOutOfRange Integer String Integer Integer
118+ | ImplicitQualifiedImport ModuleName ModuleName [DeclarationRef]
119+ | ImplicitImport ModuleName [DeclarationRef]
120+ | HidingImport ModuleName [DeclarationRef]
121+ | CaseBinderLengthDiffers Int [Binder]
122+ | IncorrectAnonymousArgument
123+ | InvalidOperatorInBinder (Qualified (OpName 'ValueOpName)) (Qualified Ident)
124+ | DeprecatedRequirePath
125+ | CannotGeneralizeRecursiveFunction Ident Type
126+ deriving (Show)
127+
128+-- | Error message hints, providing more detailed information about failure.
129+data ErrorMessageHint
130+ = ErrorUnifyingTypes Type Type
131+ | ErrorInExpression Expr
132+ | ErrorInModule ModuleName
133+ | ErrorInInstance (Qualified (ProperName 'ClassName)) [Type]
134+ | ErrorInSubsumption Type Type
135+ | ErrorCheckingAccessor Expr String
136+ | ErrorCheckingType Expr Type
137+ | ErrorCheckingKind Type
138+ | ErrorCheckingGuard
139+ | ErrorInferringType Expr
140+ | ErrorInApplication Expr Type Expr
141+ | ErrorInDataConstructor (ProperName 'ConstructorName)
142+ | ErrorInTypeConstructor (ProperName 'TypeName)
143+ | ErrorInBindingGroup [Ident]
144+ | ErrorInDataBindingGroup
145+ | ErrorInTypeSynonym (ProperName 'TypeName)
146+ | ErrorInValueDeclaration Ident
147+ | ErrorInTypeDeclaration Ident
148+ | ErrorInForeignImport Ident
149+ | ErrorSolvingConstraint Constraint
150+ | PositionedError SourceSpan
151+ deriving (Show)
152+
153+-- | Categories of hints
154+data HintCategory
155+ = ExprHint
156+ | KindHint
157+ | CheckHint
158+ | PositionHint
159+ | SolverHint
160+ | OtherHint
161+ deriving (Show, Eq)
162+
163+data ErrorMessage = ErrorMessage
164+ [ErrorMessageHint]
165+ SimpleErrorMessage
166+ deriving (Show)
31
167
32-- |
168-- |
33-- A module declaration, consisting of comments about the module, a module name,
169-- A module declaration, consisting of comments about the module, a module name,
@@ -35,7 +171,7 @@ import Language.PureScript.Environment
35-- explicitly exported. If the export list is Nothing, everything is exported.
171-- explicitly exported. If the export list is Nothing, everything is exported.
36--
172--
37data Module = Module SourceSpan [Comment] ModuleName [Declaration] (Maybe [DeclarationRef])
173data Module = Module SourceSpan [Comment] ModuleName [Declaration] (Maybe [DeclarationRef])
38− deriving (Show, Read)
174+ deriving (Show)
39
175
40-- | Return a module's name.
176-- | Return a module's name.
41getModuleName :: Module -> ModuleName
177getModuleName :: Module -> ModuleName
@@ -47,9 +183,9 @@ getModuleName (Module _ _ name _ _) = name
47addDefaultImport :: ModuleName -> Module -> Module
183addDefaultImport :: ModuleName -> Module -> Module
48addDefaultImport toImport m@(Module ss coms mn decls exps) =
184addDefaultImport toImport m@(Module ss coms mn decls exps) =
49 if isExistingImport `any` decls || mn == toImport then m
185 if isExistingImport `any` decls || mn == toImport then m
50− else Module ss coms mn (ImportDeclaration toImport Implicit Nothing False : decls) exps
186+ else Module ss coms mn (ImportDeclaration toImport Implicit Nothing : decls) exps
51 where
187 where
52− isExistingImport (ImportDeclaration mn' _ _ _) | mn' == toImport = True
188+ isExistingImport (ImportDeclaration mn' _ _) | mn' == toImport = True
53 isExistingImport (PositionedDeclaration _ _ d) = isExistingImport d
189 isExistingImport (PositionedDeclaration _ _ d) = isExistingImport d
54 isExistingImport _ = False
190 isExistingImport _ = False
55
191
@@ -64,16 +200,20 @@ data DeclarationRef
64 -- |
200 -- |
65 -- A type operator
201 -- A type operator
66 --
202 --
67− | TypeOpRef Ident
203+ | TypeOpRef (OpName 'TypeOpName)
68 -- |
204 -- |
69 -- A value
205 -- A value
70 --
206 --
71 | ValueRef Ident
207 | ValueRef Ident
72 -- |
208 -- |
209+ -- A value-level operator
210+ --
211+ | ValueOpRef (OpName 'ValueOpName)
212+ -- |
73 -- A type class
213 -- A type class
74 --
214 --
75 | TypeClassRef (ProperName 'ClassName)
215 | TypeClassRef (ProperName 'ClassName)
76− -- |
216+ -- |
77 -- A type class instance, created during typeclass desugaring (name, class name, instance types)
217 -- A type class instance, created during typeclass desugaring (name, class name, instance types)
78 --
218 --
79 | TypeInstanceRef Ident
219 | TypeInstanceRef Ident
@@ -82,54 +222,59 @@ data DeclarationRef
82 --
222 --
83 | ModuleRef ModuleName
223 | ModuleRef ModuleName
84 -- |
224 -- |
85− -- An unspecified ProperName ref. This will be replaced with a TypeClassRef
225+ -- A value re-exported from another module. These will be inserted during
86− -- or TypeRef during name desugaring.
226+ -- elaboration in name desugaring.
87− | ProperRef String
227+ --
228+ | ReExportRef ModuleName DeclarationRef
88 -- |
229 -- |
89 -- A declaration reference with source position information
230 -- A declaration reference with source position information
90 --
231 --
91 | PositionedDeclarationRef SourceSpan [Comment] DeclarationRef
232 | PositionedDeclarationRef SourceSpan [Comment] DeclarationRef
92− deriving (Show, Read)
233+ deriving (Show)
93
234
94instance Eq DeclarationRef where
235instance Eq DeclarationRef where
95− (TypeRef name dctors) == (TypeRef name' dctors') = name == name' && dctors == dctors'
236+ (TypeRef name dctors) == (TypeRef name' dctors') = name == name' && dctors == dctors'
96− (TypeOpRef name) == (TypeOpRef name') = name == name'
237+ (TypeOpRef name) == (TypeOpRef name') = name == name'
97− (ValueRef name) == (ValueRef name') = name == name'
238+ (ValueRef name) == (ValueRef name') = name == name'
239+ (ValueOpRef name) == (ValueOpRef name') = name == name'
98− (TypeClassRef name) == (TypeClassRef name') = name == name'
240+ (TypeClassRef name) == (TypeClassRef name') = name == name'
99 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
241 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
100− (ModuleRef name) == (ModuleRef name') = name == name'
242+ (ModuleRef name) == (ModuleRef name') = name == name'
101− (ProperRef name) == (ProperRef name') = name == name'
243+ (ReExportRef mn ref) == (ReExportRef mn' ref') = mn == mn' && ref == ref'
102 (PositionedDeclarationRef _ _ r) == r' = r == r'
244 (PositionedDeclarationRef _ _ r) == r' = r == r'
103 r == (PositionedDeclarationRef _ _ r') = r == r'
245 r == (PositionedDeclarationRef _ _ r') = r == r'
104 _ == _ = False
246 _ == _ = False
105
247
248+getTypeRef :: DeclarationRef -> Maybe (ProperName 'TypeName, Maybe [ProperName 'ConstructorName])
249+getTypeRef (TypeRef name dctors) = Just (name, dctors)
250+getTypeRef (PositionedDeclarationRef _ _ r) = getTypeRef r
251+getTypeRef _ = Nothing
252+
253+getTypeOpRef :: DeclarationRef -> Maybe (OpName 'TypeOpName)
254+getTypeOpRef (TypeOpRef op) = Just op
255+getTypeOpRef (PositionedDeclarationRef _ _ r) = getTypeOpRef r
256+getTypeOpRef _ = Nothing
257+
258+getValueRef :: DeclarationRef -> Maybe Ident
259+getValueRef (ValueRef name) = Just name
260+getValueRef (PositionedDeclarationRef _ _ r) = getValueRef r
261+getValueRef _ = Nothing
262+
263+getValueOpRef :: DeclarationRef -> Maybe (OpName 'ValueOpName)
264+getValueOpRef (ValueOpRef op) = Just op
265+getValueOpRef (PositionedDeclarationRef _ _ r) = getValueOpRef r
266+getValueOpRef _ = Nothing
267+
268+getTypeClassRef :: DeclarationRef -> Maybe (ProperName 'ClassName)
269+getTypeClassRef (TypeClassRef name) = Just name
270+getTypeClassRef (PositionedDeclarationRef _ _ r) = getTypeClassRef r
271+getTypeClassRef _ = Nothing
272+
106isModuleRef :: DeclarationRef -> Bool
273isModuleRef :: DeclarationRef -> Bool
107isModuleRef (PositionedDeclarationRef _ _ r) = isModuleRef r
274isModuleRef (PositionedDeclarationRef _ _ r) = isModuleRef r
108isModuleRef (ModuleRef _) = True
275isModuleRef (ModuleRef _) = True
109isModuleRef _ = False
276isModuleRef _ = False
110
277
111−-- |
112−-- Finds duplicate values in a list of declaration refs. The returned values
113−-- are the duplicate refs with data constructors elided, and then a separate
114−-- list of duplicate data constructors.
115−--
116−findDuplicateRefs :: [DeclarationRef] -> ([DeclarationRef], [ProperName 'ConstructorName])
117−findDuplicateRefs refs =
118− let positionless = stripPosInfo `map` refs
119− simplified = simplifyTypeRefs `map` positionless
120− dupeRefs = nub $ simplified \\ nub simplified
121− dupeCtors = concat $ flip mapMaybe positionless $ \case
122− TypeRef _ (Just dctors) ->
123− let dupes = dctors \\ nub dctors
124− in if null dupes then Nothing else Just dupes
125− _ -> Nothing
126− in (dupeRefs, dupeCtors)
127− where
128− stripPosInfo (PositionedDeclarationRef _ _ ref) = stripPosInfo ref
129− stripPosInfo other = other
130− simplifyTypeRefs (TypeRef pn _) = TypeRef pn Nothing
131− simplifyTypeRefs other = other
132−
133-- |
278-- |
134-- The data type which specifies type of import declaration
279-- The data type which specifies type of import declaration
135--
280--
@@ -146,7 +291,7 @@ data ImportDeclarationType
146 -- An import with a list of references to hide: `import M hiding (foo)`
291 -- An import with a list of references to hide: `import M hiding (foo)`
147 --
292 --
148 | Hiding [DeclarationRef]
293 | Hiding [DeclarationRef]
149− deriving (Eq, Show, Read)
294+ deriving (Eq, Show)
150
295
151isImplicit :: ImportDeclarationType -> Bool
296isImplicit :: ImportDeclarationType -> Bool
152isImplicit Implicit = True
297isImplicit Implicit = True
@@ -193,14 +338,13 @@ data Declaration
193 --
338 --
194 | ExternDataDeclaration (ProperName 'TypeName) Kind
339 | ExternDataDeclaration (ProperName 'TypeName) Kind
195 -- |
340 -- |
196− -- A fixity declaration (fixity data, operator name, value the operator is an alias for)
341+ -- A fixity declaration
197 --
342 --
198− | FixityDeclaration Fixity String (Maybe (Qualified FixityAlias))
343+ | FixityDeclaration (Either ValueFixity TypeFixity)
199 -- |
344 -- |
200 -- A module import (module name, qualified/unqualified/hiding, optional "qualified as" name)
345 -- A module import (module name, qualified/unqualified/hiding, optional "qualified as" name)
201− -- TODO: also a boolean specifying whether the old `qualified` syntax was used, so a warning can be raised in desugaring (remove for 0.9)
202 --
346 --
203− | ImportDeclaration ModuleName ImportDeclarationType (Maybe ModuleName) Bool
347+ | ImportDeclaration ModuleName ImportDeclarationType (Maybe ModuleName)
204 -- |
348 -- |
205 -- A type class declaration (name, argument, implies, member declarations)
349 -- A type class declaration (name, argument, implies, member declarations)
206 --
350 --
@@ -214,32 +358,19 @@ data Declaration
214 -- A declaration with source position information
358 -- A declaration with source position information
215 --
359 --
216 | PositionedDeclaration SourceSpan [Comment] Declaration
360 | PositionedDeclaration SourceSpan [Comment] Declaration
217− deriving (Show, Read)
361+ deriving (Show)
218−
362+
219−data FixityAlias
363+data ValueFixity = ValueFixity Fixity (Qualified (Either Ident (ProperName 'ConstructorName))) (OpName 'ValueOpName)
220− = AliasValue Ident
221− | AliasConstructor (ProperName 'ConstructorName)
222− | AliasType (ProperName 'TypeName)
223− deriving (Eq, Ord, Show, Read)
364+ deriving (Eq, Ord, Show)
224−
365+
225−foldFixityAlias
366+data TypeFixity = TypeFixity Fixity (Qualified (ProperName 'TypeName)) (OpName 'TypeOpName)
226− :: (Ident -> a)
367+ deriving (Eq, Ord, Show)
227− -> (ProperName 'ConstructorName -> a)
368+
228− -> (ProperName 'TypeName -> a)
229− -> FixityAlias
230− -> a
231−foldFixityAlias f _ _ (AliasValue name) = f name
232−foldFixityAlias _ g _ (AliasConstructor name) = g name
233−foldFixityAlias _ _ h (AliasType name) = h name
234−
235−getValueAlias :: FixityAlias -> Maybe (Either Ident (ProperName 'ConstructorName))
369+pattern ValueFixityDeclaration :: Fixity -> Qualified (Either Ident (ProperName 'ConstructorName)) -> OpName 'ValueOpName -> Declaration
236−getValueAlias (AliasValue name) = Just $ Left name
370+pattern ValueFixityDeclaration fixity name op = FixityDeclaration (Left (ValueFixity fixity name op))
237−getValueAlias (AliasConstructor name) = Just $ Right name
371+
238−getValueAlias _ = Nothing
372+pattern TypeFixityDeclaration :: Fixity -> Qualified (ProperName 'TypeName) -> OpName 'TypeOpName -> Declaration
239−
373+pattern TypeFixityDeclaration fixity name op = FixityDeclaration (Right (TypeFixity fixity name op))
240−getTypeAlias :: FixityAlias -> Maybe (ProperName 'TypeName)
241−getTypeAlias (AliasType name) = Just name
242−getTypeAlias _ = Nothing
243
374
244-- | The members of a type class instance declaration
375-- | The members of a type class instance declaration
245data TypeInstanceBody
376data TypeInstanceBody
@@ -247,7 +378,7 @@ data TypeInstanceBody
247 = DerivedInstance
378 = DerivedInstance
248 -- | This is a regular (explicit) instance
379 -- | This is a regular (explicit) instance
249 | ExplicitInstance [Declaration]
380 | ExplicitInstance [Declaration]
250− deriving (Show, Read)
381+ deriving (Show)
251
382
252mapTypeInstanceBody :: ([Declaration] -> [Declaration]) -> TypeInstanceBody -> TypeInstanceBody
383mapTypeInstanceBody :: ([Declaration] -> [Declaration]) -> TypeInstanceBody -> TypeInstanceBody
253mapTypeInstanceBody f = runIdentity . traverseTypeInstanceBody (Identity . f)
384mapTypeInstanceBody f = runIdentity . traverseTypeInstanceBody (Identity . f)
@@ -298,6 +429,11 @@ isFixityDecl FixityDeclaration{} = True
298isFixityDecl (PositionedDeclaration _ _ d) = isFixityDecl d
429isFixityDecl (PositionedDeclaration _ _ d) = isFixityDecl d
299isFixityDecl _ = False
430isFixityDecl _ = False
300
431
432+getFixityDecl :: Declaration -> Maybe (Either ValueFixity TypeFixity)
433+getFixityDecl (FixityDeclaration fixity) = Just fixity
434+getFixityDecl (PositionedDeclaration _ _ d) = getFixityDecl d
435+getFixityDecl _ = Nothing
436+
301-- |
437-- |
302-- Test if a declaration is a foreign import
438-- Test if a declaration is a foreign import
303--
439--
@@ -361,16 +497,9 @@ data Expr
361 --
497 --
362 | Parens Expr
498 | Parens Expr
363 -- |
499 -- |
364− -- Operator section. This will be removed during desugaring and replaced with lambda.
500+ -- An record property accessor expression (e.g. `obj.x` or `_.x`).
365− --
501+ -- Anonymous arguments will be removed during desugaring and expanded
366− | OperatorSection Expr (Either Expr Expr)
367− -- |
368− -- An object property getter (e.g. `_.x`). This will be removed during
369− -- desugaring and expanded into a lambda that reads a property from an object.
502+ -- into a lambda that reads a property from a record.
370− --
371− | ObjectGetter String
372− -- |
373− -- An record property accessor expression
374 --
503 --
375 | Accessor String Expr
504 | Accessor String Expr
376 -- |
505 -- |
@@ -390,6 +519,11 @@ data Expr
390 --
519 --
391 | Var (Qualified Ident)
520 | Var (Qualified Ident)
392 -- |
521 -- |
522+ -- An operator. This will be desugared into a function during the "operators"
523+ -- phase of desugaring.
524+ --
525+ | Op (Qualified (OpName 'ValueOpName))
526+ -- |
393 -- Conditional (if-then-else expression)
527 -- Conditional (if-then-else expression)
394 --
528 --
395 | IfThenElse Expr Expr Expr
529 | IfThenElse Expr Expr Expr
@@ -426,7 +560,9 @@ data Expr
426 -- at superclass implementations when searching for a dictionary, the type class name and
560 -- at superclass implementations when searching for a dictionary, the type class name and
427 -- instance type, and the type class dictionaries in scope.
561 -- instance type, and the type class dictionaries in scope.
428 --
562 --
563+ | TypeClassDictionary Constraint
429− | TypeClassDictionary Constraint (M.Map (Maybe ModuleName) (M.Map (Qualified (ProperName 'ClassName)) (M.Map (Qualified Ident) TypeClassDictionaryInScope)))
564+ (M.Map (Maybe ModuleName) (M.Map (Qualified (ProperName 'ClassName)) (M.Map (Qualified Ident) TypeClassDictionaryInScope)))
565+ [ErrorMessageHint]
430 -- |
566 -- |
431 -- A typeclass dictionary accessor, the implementation is left unspecified until CoreFn desugaring.
567 -- A typeclass dictionary accessor, the implementation is left unspecified until CoreFn desugaring.
432 --
568 --
@@ -447,7 +583,7 @@ data Expr
447 -- A value with source position information
583 -- A value with source position information
448 --
584 --
449 | PositionedValue SourceSpan [Comment] Expr
585 | PositionedValue SourceSpan [Comment] Expr
450− deriving (Show, Read)
586+ deriving (Show)
451
587
452-- |
588-- |
453-- An alternative in a case statement
589-- An alternative in a case statement
@@ -461,7 +597,7 @@ data CaseAlternative = CaseAlternative
461 -- The result expression or a collect of guarded expressions
597 -- The result expression or a collect of guarded expressions
462 --
598 --
463 , caseAlternativeResult :: Either [(Guard, Expr)] Expr
599 , caseAlternativeResult :: Either [(Guard, Expr)] Expr
464− } deriving (Show, Read)
600+ } deriving (Show)
465
601
466-- |
602-- |
467-- A statement in a do-notation block
603-- A statement in a do-notation block
@@ -483,8 +619,7 @@ data DoNotationElement
483 -- A do notation element with source position information
619 -- A do notation element with source position information
484 --
620 --
485 | PositionedDoNotationElement SourceSpan [Comment] DoNotationElement
621 | PositionedDoNotationElement SourceSpan [Comment] DoNotationElement
486− deriving (Show, Read)
622+ deriving (Show)
487
623
488$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''DeclarationRef)
624$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''DeclarationRef)
489$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ImportDeclarationType)
625$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ImportDeclarationType)
490−$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''FixityAlias)
src/Language/PureScript/AST/Exported.hs+12−15
@@ -3,7 +3,10 @@ module Language.PureScript.AST.Exported
3 , isExported
3 , isExported
4 ) where
4 ) where
5
5
6+import Prelude.Compat
7+
6import Control.Category ((>>>))
8import Control.Category ((>>>))
9+
7import Data.Maybe (mapMaybe)
10import Data.Maybe (mapMaybe)
8
11
9import Language.PureScript.AST.Declarations
12import Language.PureScript.AST.Declarations
@@ -99,7 +102,7 @@ typeInstanceConstituents (TypeInstanceDeclaration _ constraints className tys _)
99 Left className : (concatMap fromConstraint constraints ++ concatMap fromType tys)
102 Left className : (concatMap fromConstraint constraints ++ concatMap fromType tys)
100 where
103 where
101
104
102− fromConstraint (name, tys') = Left name : concatMap fromType tys'
105+ fromConstraint c = Left (constraintClass c) : concatMap fromType (constraintArgs c)
103 fromType = everythingOnTypes (++) go
106 fromType = everythingOnTypes (++) go
104
107
105 -- Note that type synonyms are disallowed in instance declarations, so
108 -- Note that type synonyms are disallowed in instance declarations, so
@@ -124,21 +127,15 @@ isExported _ TypeInstanceDeclaration{} = True
124isExported exps (PositionedDeclaration _ _ d) = isExported exps d
127isExported exps (PositionedDeclaration _ _ d) = isExported exps d
125isExported (Just exps) decl = any (matches decl) exps
128isExported (Just exps) decl = any (matches decl) exps
126 where
129 where
127− matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
130+ matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
128− matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
131+ matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
129− matches (ExternDeclaration ident _) (ValueRef ident') = ident == ident'
132+ matches (ExternDeclaration ident _) (ValueRef ident') = ident == ident'
130− matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
133+ matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
131− matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
134+ matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
132− matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
135+ matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
133 matches (TypeClassDeclaration ident _ _ _) (TypeClassRef ident') = ident == ident'
136 matches (TypeClassDeclaration ident _ _ _) (TypeClassRef ident') = ident == ident'
134−
137+ matches (ValueFixityDeclaration _ _ op) (ValueOpRef op') = op == op'
135− matches (DataDeclaration _ ident _ _) (ProperRef ident') = runProperName ident == ident'
138+ matches (TypeFixityDeclaration _ _ op) (TypeOpRef op') = op == op'
136− matches (TypeClassDeclaration ident _ _ _) (ProperRef ident') = runProperName ident == ident'
137−
138− matches (FixityDeclaration _ name (Just (Qualified _ (AliasValue _)))) (ValueRef ident') = name == runIdent ident'
139− matches (FixityDeclaration _ name (Just (Qualified _ (AliasConstructor _)))) (ValueRef ident') = name == runIdent ident'
140− matches (FixityDeclaration _ name (Just (Qualified _ (AliasType _)))) (TypeOpRef ident') = name == runIdent ident'
141−
142 matches (PositionedDeclaration _ _ d) r = d `matches` r
139 matches (PositionedDeclaration _ _ d) r = d `matches` r
143 matches d (PositionedDeclarationRef _ _ r) = d `matches` r
140 matches d (PositionedDeclarationRef _ _ r) = d `matches` r
144 matches _ _ = False
141 matches _ _ = False
src/Language/PureScript/AST/Literals.hs+3−3
@@ -1,10 +1,10 @@
1−{-# LANGUAGE DeriveFunctor #-}
2−
3-- |
1-- |
4-- The core functional representation for literal values.
2-- The core functional representation for literal values.
5--
3--
6module Language.PureScript.AST.Literals where
4module Language.PureScript.AST.Literals where
7
5
6+import Prelude.Compat
7+
8-- |
8-- |
9-- Data type for literal values. Parameterised so it can be used for Exprs and
9-- Data type for literal values. Parameterised so it can be used for Exprs and
10-- Binders.
10-- Binders.
@@ -34,4 +34,4 @@ data Literal a
34 -- An object literal
34 -- An object literal
35 --
35 --
36 | ObjectLiteral [(String, a)]
36 | ObjectLiteral [(String, a)]
37− deriving (Eq, Ord, Show, Read, Functor)
37+ deriving (Eq, Ord, Show, Functor)
src/Language/PureScript/AST/Operators.hs+4−2
@@ -5,6 +5,8 @@
5--
5--
6module Language.PureScript.AST.Operators where
6module Language.PureScript.AST.Operators where
7
7
8+import Prelude.Compat
9+
8import Data.Aeson ((.=))
10import Data.Aeson ((.=))
9import qualified Data.Aeson as A
11import qualified Data.Aeson as A
10
12
@@ -19,7 +21,7 @@ type Precedence = Integer
19-- Associativity for infix operators
21-- Associativity for infix operators
20--
22--
21data Associativity = Infixl | Infixr | Infix
23data Associativity = Infixl | Infixr | Infix
22− deriving (Show, Read, Eq, Ord)
24+ deriving (Show, Eq, Ord)
23
25
24showAssoc :: Associativity -> String
26showAssoc :: Associativity -> String
25showAssoc Infixl = "infixl"
27showAssoc Infixl = "infixl"
@@ -42,7 +44,7 @@ instance A.FromJSON Associativity where
42-- Fixity data for infix operators
44-- Fixity data for infix operators
43--
45--
44data Fixity = Fixity Associativity Precedence
46data Fixity = Fixity Associativity Precedence
45− deriving (Show, Read, Eq, Ord)
47+ deriving (Show, Eq, Ord)
46
48
47instance A.ToJSON Fixity where
49instance A.ToJSON Fixity where
48 toJSON (Fixity associativity precedence) =
50 toJSON (Fixity associativity precedence) =
src/Language/PureScript/AST/SourcePos.hs+2−5
@@ -1,5 +1,3 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
4
2
5-- |
3-- |
@@ -7,7 +5,6 @@
7--
5--
8module Language.PureScript.AST.SourcePos where
6module Language.PureScript.AST.SourcePos where
9
7
10−import Prelude ()
11import Prelude.Compat
8import Prelude.Compat
12
9
13import Data.Aeson ((.=), (.:))
10import Data.Aeson ((.=), (.:))
@@ -25,7 +22,7 @@ data SourcePos = SourcePos
25 -- Column number
22 -- Column number
26 --
23 --
27 , sourcePosColumn :: Int
24 , sourcePosColumn :: Int
28− } deriving (Show, Read, Eq, Ord)
25+ } deriving (Show, Eq, Ord)
29
26
30displaySourcePos :: SourcePos -> String
27displaySourcePos :: SourcePos -> String
31displaySourcePos sp =
28displaySourcePos sp =
@@ -53,7 +50,7 @@ data SourceSpan = SourceSpan
53 -- End of the span
50 -- End of the span
54 --
51 --
55 , spanEnd :: SourcePos
52 , spanEnd :: SourcePos
56− } deriving (Show, Read, Eq, Ord)
53+ } deriving (Show, Eq, Ord)
57
54
58displayStartEndPos :: SourceSpan -> String
55displayStartEndPos :: SourceSpan -> String
59displayStartEndPos sp =
56displayStartEndPos sp =
src/Language/PureScript/AST/Traversals.hs+8−25
@@ -1,21 +1,18 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−
3-- |
1-- |
4-- AST traversal helpers
2-- AST traversal helpers
5--
3--
6module Language.PureScript.AST.Traversals where
4module Language.PureScript.AST.Traversals where
7
5
8−import Prelude ()
9import Prelude.Compat
6import Prelude.Compat
10
7
11−import Data.Maybe (mapMaybe)
12−import Data.List (mapAccumL)
13−import Data.Foldable (fold)
14−import qualified Data.Set as S
15−
16import Control.Monad
8import Control.Monad
17import Control.Arrow ((***), (+++))
9import Control.Arrow ((***), (+++))
18
10
11+import Data.Foldable (fold)
12+import Data.List (mapAccumL)
13+import Data.Maybe (mapMaybe)
14+import qualified Data.Set as S
15+
19import Language.PureScript.AST.Binders
16import Language.PureScript.AST.Binders
20import Language.PureScript.AST.Literals
17import Language.PureScript.AST.Literals
21import Language.PureScript.AST.Declarations
18import Language.PureScript.AST.Declarations
@@ -47,8 +44,6 @@ everywhereOnValues f g h = (f', g', h')
47 g' (UnaryMinus v) = g (UnaryMinus (g' v))
44 g' (UnaryMinus v) = g (UnaryMinus (g' v))
48 g' (BinaryNoParens op v1 v2) = g (BinaryNoParens (g' op) (g' v1) (g' v2))
45 g' (BinaryNoParens op v1 v2) = g (BinaryNoParens (g' op) (g' v1) (g' v2))
49 g' (Parens v) = g (Parens (g' v))
46 g' (Parens v) = g (Parens (g' v))
50− g' (OperatorSection op (Left v)) = g (OperatorSection (g' op) (Left $ g' v))
51− g' (OperatorSection op (Right v)) = g (OperatorSection (g' op) (Right $ g' v))
52 g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))
47 g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))
53 g' (Accessor prop v) = g (Accessor prop (g' v))
48 g' (Accessor prop v) = g (Accessor prop (g' v))
54 g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))
49 g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))
@@ -116,8 +111,6 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
116 g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')
111 g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')
117 g' (BinaryNoParens op v1 v2) = BinaryNoParens <$> (g op >>= g') <*> (g v1 >>= g') <*> (g v2 >>= g')
112 g' (BinaryNoParens op v1 v2) = BinaryNoParens <$> (g op >>= g') <*> (g v1 >>= g') <*> (g v2 >>= g')
118 g' (Parens v) = Parens <$> (g v >>= g')
113 g' (Parens v) = Parens <$> (g v >>= g')
119− g' (OperatorSection op (Left v)) = OperatorSection <$> (g op >>= g') <*> (Left <$> (g v >>= g'))
120− g' (OperatorSection op (Right v)) = OperatorSection <$> (g op >>= g') <*> (Right <$> (g v >>= g'))
121 g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')
114 g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')
122 g' (Accessor prop v) = Accessor prop <$> (g v >>= g')
115 g' (Accessor prop v) = Accessor prop <$> (g v >>= g')
123 g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> traverse (sndM (g' <=< g)) vs
116 g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> traverse (sndM (g' <=< g)) vs
@@ -185,8 +178,6 @@ everywhereOnValuesM f g h = (f', g', h')
185 g' (UnaryMinus v) = (UnaryMinus <$> g' v) >>= g
178 g' (UnaryMinus v) = (UnaryMinus <$> g' v) >>= g
186 g' (BinaryNoParens op v1 v2) = (BinaryNoParens <$> g' op <*> g' v1 <*> g' v2) >>= g
179 g' (BinaryNoParens op v1 v2) = (BinaryNoParens <$> g' op <*> g' v1 <*> g' v2) >>= g
187 g' (Parens v) = (Parens <$> g' v) >>= g
180 g' (Parens v) = (Parens <$> g' v) >>= g
188− g' (OperatorSection op (Left v)) = (OperatorSection <$> g' op <*> (Left <$> g' v)) >>= g
189− g' (OperatorSection op (Right v)) = (OperatorSection <$> g' op <*> (Right <$> g' v)) >>= g
190 g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g
181 g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g
191 g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g
182 g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g
192 g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> traverse (sndM g') vs) >>= g
183 g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> traverse (sndM g') vs) >>= g
@@ -259,8 +250,6 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
259 g' v@(UnaryMinus v1) = g v <> g' v1
250 g' v@(UnaryMinus v1) = g v <> g' v1
260 g' v@(BinaryNoParens op v1 v2) = g v <> g' op <> g' v1 <> g' v2
251 g' v@(BinaryNoParens op v1 v2) = g v <> g' op <> g' v1 <> g' v2
261 g' v@(Parens v1) = g v <> g' v1
252 g' v@(Parens v1) = g v <> g' v1
262− g' v@(OperatorSection op (Left v1)) = g v <> g' op <> g' v1
263− g' v@(OperatorSection op (Right v1)) = g v <> g' op <> g' v1
264 g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1
253 g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1
265 g' v@(Accessor _ v1) = g v <> g' v1
254 g' v@(Accessor _ v1) = g v <> g' v1
266 g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
255 g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
@@ -338,8 +327,6 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
338 g' s (UnaryMinus v1) = g'' s v1
327 g' s (UnaryMinus v1) = g'' s v1
339 g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
328 g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
340 g' s (Parens v1) = g'' s v1
329 g' s (Parens v1) = g'' s v1
341− g' s (OperatorSection op (Left v)) = g'' s op <> g'' s v
342− g' s (OperatorSection op (Right v)) = g'' s op <> g'' s v
343 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
330 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
344 g' s (Accessor _ v1) = g'' s v1
331 g' s (Accessor _ v1) = g'' s v1
345 g' s (ObjectUpdate obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)
332 g' s (ObjectUpdate obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)
@@ -419,8 +406,6 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
419 g' s (UnaryMinus v) = UnaryMinus <$> g'' s v
406 g' s (UnaryMinus v) = UnaryMinus <$> g'' s v
420 g' s (BinaryNoParens op v1 v2) = BinaryNoParens <$> g'' s op <*> g'' s v1 <*> g'' s v2
407 g' s (BinaryNoParens op v1 v2) = BinaryNoParens <$> g'' s op <*> g'' s v1 <*> g'' s v2
421 g' s (Parens v) = Parens <$> g'' s v
408 g' s (Parens v) = Parens <$> g'' s v
422− g' s (OperatorSection op (Left v)) = OperatorSection <$> g'' s op <*> (Left <$> g'' s v)
423− g' s (OperatorSection op (Right v)) = OperatorSection <$> g'' s op <*> (Right <$> g'' s v)
424 g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> g'' s v
409 g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> g'' s v
425 g' s (Accessor prop v) = Accessor prop <$> g'' s v
410 g' s (Accessor prop v) = Accessor prop <$> g'' s v
426 g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> traverse (sndM (g'' s)) vs
411 g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> traverse (sndM (g'' s)) vs
@@ -510,8 +495,6 @@ everythingWithScope f g h i j = (f'', g'', h'', i'', \s -> snd . j'' s)
510 g' s (UnaryMinus v1) = g'' s v1
495 g' s (UnaryMinus v1) = g'' s v1
511 g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
496 g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
512 g' s (Parens v1) = g'' s v1
497 g' s (Parens v1) = g'' s v1
513− g' s (OperatorSection op (Left v)) = g'' s op <> g'' s v
514− g' s (OperatorSection op (Right v)) = g'' s op <> g'' s v
515 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
498 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
516 g' s (Accessor _ v1) = g'' s v1
499 g' s (Accessor _ v1) = g'' s v1
517 g' s (ObjectUpdate obj vs) = g'' s obj <> foldMap (g'' s . snd) vs
500 g' s (ObjectUpdate obj vs) = g'' s obj <> foldMap (g'' s . snd) vs
@@ -593,13 +576,13 @@ accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (con
593 where
576 where
594 forDecls (DataDeclaration _ _ _ dctors) = mconcat (concatMap (map f . snd) dctors)
577 forDecls (DataDeclaration _ _ _ dctors) = mconcat (concatMap (map f . snd) dctors)
595 forDecls (ExternDeclaration _ ty) = f ty
578 forDecls (ExternDeclaration _ ty) = f ty
596− forDecls (TypeClassDeclaration _ _ implies _) = mconcat (concatMap (map f . snd) implies)
579+ forDecls (TypeClassDeclaration _ _ implies _) = mconcat (concatMap (map f . constraintArgs) implies)
597− forDecls (TypeInstanceDeclaration _ cs _ tys _) = mconcat (concatMap (map f . snd) cs) `mappend` mconcat (map f tys)
580+ forDecls (TypeInstanceDeclaration _ cs _ tys _) = mconcat (concatMap (map f . constraintArgs) cs) `mappend` mconcat (map f tys)
598 forDecls (TypeSynonymDeclaration _ _ ty) = f ty
581 forDecls (TypeSynonymDeclaration _ _ ty) = f ty
599 forDecls (TypeDeclaration _ ty) = f ty
582 forDecls (TypeDeclaration _ ty) = f ty
600 forDecls _ = mempty
583 forDecls _ = mempty
601
584
602− forValues (TypeClassDictionary (_, cs) _) = mconcat (map f cs)
585+ forValues (TypeClassDictionary c _ _) = mconcat (map f (constraintArgs c))
603 forValues (SuperClassDictionary _ tys) = mconcat (map f tys)
586 forValues (SuperClassDictionary _ tys) = mconcat (map f tys)
604 forValues (TypedValue _ _ ty) = f ty
587 forValues (TypedValue _ _ ty) = f ty
605 forValues _ = mempty
588 forValues _ = mempty
src/Language/PureScript/Bundle.hs+72−56
@@ -1,53 +1,40 @@
1−-----------------------------------------------------------------------------
1+-- |
2−--
3−-- Module : psc-bundle
4−-- Copyright : (c) Phil Freeman 2015
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | Bundles compiled PureScript modules for the browser.
2+-- Bundles compiled PureScript modules for the browser.
12--
3--
13-- This module takes as input the individual generated modules from 'Language.PureScript.Make' and
4-- This module takes as input the individual generated modules from 'Language.PureScript.Make' and
14-- performs dead code elimination, filters empty modules,
5-- performs dead code elimination, filters empty modules,
15-- and generates the final Javascript bundle.
6-- and generates the final Javascript bundle.
16−-----------------------------------------------------------------------------
17−
18−{-# LANGUAGE PatternGuards #-}
19−{-# LANGUAGE FlexibleContexts #-}
20−{-# LANGUAGE ScopedTypeVariables #-}
21−{-# LANGUAGE TupleSections #-}
22−
23−module Language.PureScript.Bundle (
7+module Language.PureScript.Bundle
24− bundle
8+ ( bundle
9+ , guessModuleIdentifier
25− , ModuleIdentifier(..)
10+ , ModuleIdentifier(..)
26− , moduleName
11+ , moduleName
27− , ModuleType(..)
12+ , ModuleType(..)
28− , ErrorMessage(..)
13+ , ErrorMessage(..)
29− , printErrorMessage
14+ , printErrorMessage
30− , getExportedIdentifiers
15+ , getExportedIdentifiers
31−) where
16+ ) where
32−
17+
33−import Prelude ()
34import Prelude.Compat
18import Prelude.Compat
35
19
36−import Data.List (nub, stripPrefix)
20+import Control.Monad
37−import Data.Maybe (mapMaybe, catMaybes, fromMaybe)
21+import Control.Monad.Error.Class
22+
23+import Data.Char (chr, digitToInt)
38import Data.Generics (everything, everywhere, mkQ, mkT)
24import Data.Generics (everything, everywhere, mkQ, mkT)
39import Data.Graph
25import Data.Graph
26+import Data.List (nub, stripPrefix)
27+import Data.Maybe (mapMaybe, catMaybes)
40import Data.Version (showVersion)
28import Data.Version (showVersion)
41−
42import qualified Data.Set as S
29import qualified Data.Set as S
43
30
44−import Control.Monad
45−import Control.Monad.Error.Class
46import Language.JavaScript.Parser
31import Language.JavaScript.Parser
47import Language.JavaScript.Parser.AST
32import Language.JavaScript.Parser.AST
48
33
49import qualified Paths_purescript as Paths
34import qualified Paths_purescript as Paths
50
35
36+import System.FilePath (takeFileName, takeDirectory)
37+
51-- | The type of error messages. We separate generation and rendering of errors using a data
38-- | The type of error messages. We separate generation and rendering of errors using a data
52-- type, in case we need to match on error types later.
39-- type, in case we need to match on error types later.
53data ErrorMessage
40data ErrorMessage
@@ -56,24 +43,32 @@ data ErrorMessage
56 | UnableToParseModule String
43 | UnableToParseModule String
57 | UnsupportedExport
44 | UnsupportedExport
58 | ErrorInModule ModuleIdentifier ErrorMessage
45 | ErrorInModule ModuleIdentifier ErrorMessage
59− deriving (Show, Read)
46+ deriving (Show)
60
47
61-- | Modules are either "regular modules" (i.e. those generated by psc) or foreign modules.
48-- | Modules are either "regular modules" (i.e. those generated by psc) or foreign modules.
62data ModuleType
49data ModuleType
63 = Regular
50 = Regular
64 | Foreign
51 | Foreign
65− deriving (Show, Read, Eq, Ord)
52+ deriving (Show, Eq, Ord)
66
53
67showModuleType :: ModuleType -> String
54showModuleType :: ModuleType -> String
68showModuleType Regular = "Regular"
55showModuleType Regular = "Regular"
69showModuleType Foreign = "Foreign"
56showModuleType Foreign = "Foreign"
70
57
71-- | A module is identified by its module name and its type.
58-- | A module is identified by its module name and its type.
72−data ModuleIdentifier = ModuleIdentifier String ModuleType deriving (Show, Read, Eq, Ord)
59+data ModuleIdentifier = ModuleIdentifier String ModuleType deriving (Show, Eq, Ord)
73
60
74moduleName :: ModuleIdentifier -> String
61moduleName :: ModuleIdentifier -> String
75moduleName (ModuleIdentifier name _) = name
62moduleName (ModuleIdentifier name _) = name
76
63
64+-- | Given a filename, assuming it is in the correct place on disk, infer a ModuleIdentifier.
65+guessModuleIdentifier :: MonadError ErrorMessage m => FilePath -> m ModuleIdentifier
66+guessModuleIdentifier filename = ModuleIdentifier (takeFileName (takeDirectory filename)) <$> guessModuleType (takeFileName filename)
67+ where
68+ guessModuleType "index.js" = pure Regular
69+ guessModuleType "foreign.js" = pure Foreign
70+ guessModuleType name = throwError $ UnsupportedModulePath name
71+
77-- | A piece of code is identified by its module and its name. These keys are used to label vertices
72-- | A piece of code is identified by its module and its name. These keys are used to label vertices
78-- in the dependency graph.
73-- in the dependency graph.
79type Key = (ModuleIdentifier, String)
74type Key = (ModuleIdentifier, String)
@@ -134,13 +129,13 @@ printErrorMessage (ErrorInModule mid e) =
134 name ++ " (" ++ showModuleType ty ++ ")"
129 name ++ " (" ++ showModuleType ty ++ ")"
135
130
136-- | Calculate the ModuleIdentifier which a require(...) statement imports.
131-- | Calculate the ModuleIdentifier which a require(...) statement imports.
137−checkImportPath :: Maybe FilePath -> String -> ModuleIdentifier -> S.Set String -> Either String ModuleIdentifier
132+checkImportPath :: String -> ModuleIdentifier -> S.Set String -> Either String ModuleIdentifier
138−checkImportPath _ "./foreign" m _ =
133+checkImportPath "./foreign" m _ =
139 Right (ModuleIdentifier (moduleName m) Foreign)
134 Right (ModuleIdentifier (moduleName m) Foreign)
140−checkImportPath requirePath name _ names
135+checkImportPath name _ names
141− | Just name' <- stripPrefix (fromMaybe "../" requirePath) name
136+ | Just name' <- stripPrefix "../" name
142 , name' `S.member` names = Right (ModuleIdentifier name' Regular)
137 , name' `S.member` names = Right (ModuleIdentifier name' Regular)
143−checkImportPath _ name _ _ = Left name
138+checkImportPath name _ _ = Left name
144
139
145-- | Compute the dependencies of all elements in a module, and add them to the tree.
140-- | Compute the dependencies of all elements in a module, and add them to the tree.
146--
141--
@@ -203,11 +198,34 @@ withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
203
198
204-- String literals include the quote chars
199-- String literals include the quote chars
205fromStringLiteral :: JSExpression -> Maybe String
200fromStringLiteral :: JSExpression -> Maybe String
206−fromStringLiteral (JSStringLiteral _ str) = Just $ trimStringQuotes str
201+fromStringLiteral (JSStringLiteral _ str) = Just $ strValue str
207fromStringLiteral _ = Nothing
202fromStringLiteral _ = Nothing
208
203
209−trimStringQuotes :: String -> String
204+strValue :: String -> String
210−trimStringQuotes str = reverse $ drop 1 $ reverse $ drop 1 $ str
205+strValue str = go $ drop 1 str
206+ where
207+ go ('\\' : 'b' : xs) = '\b' : go xs
208+ go ('\\' : 'f' : xs) = '\f' : go xs
209+ go ('\\' : 'n' : xs) = '\n' : go xs
210+ go ('\\' : 'r' : xs) = '\r' : go xs
211+ go ('\\' : 't' : xs) = '\t' : go xs
212+ go ('\\' : 'v' : xs) = '\v' : go xs
213+ go ('\\' : '0' : xs) = '\0' : go xs
214+ go ('\\' : 'x' : a : b : xs) = chr (a' + b') : go xs
215+ where
216+ a' = 16 * digitToInt a
217+ b' = digitToInt b
218+ go ('\\' : 'u' : a : b : c : d : xs) = chr (a' + b' + c' + d') : go xs
219+ where
220+ a' = 16 * 16 * 16 * digitToInt a
221+ b' = 16 * 16 * digitToInt b
222+ c' = 16 * digitToInt c
223+ d' = digitToInt d
224+ go ('\\' : x : xs) = x : go xs
225+ go "\"" = ""
226+ go "'" = ""
227+ go (x : xs) = x : go xs
228+ go "" = ""
211
229
212commaList :: JSCommaList a -> [a]
230commaList :: JSCommaList a -> [a]
213commaList JSLNil = []
231commaList JSLNil = []
@@ -222,8 +240,8 @@ trailingCommaList (JSCTLNone l) = commaList l
222--
240--
223-- Each type of module element is matched using pattern guards, and everything else is bundled into the
241-- Each type of module element is matched using pattern guards, and everything else is bundled into the
224-- Other constructor.
242-- Other constructor.
225−toModule :: forall m. (MonadError ErrorMessage m) => Maybe FilePath -> S.Set String -> ModuleIdentifier -> JSAST -> m Module
243+toModule :: forall m. (MonadError ErrorMessage m) => S.Set String -> ModuleIdentifier -> JSAST -> m Module
226−toModule requirePath mids mid top
244+toModule mids mid top
227 | JSAstProgram smts _ <- top = Module mid <$> traverse toModuleElement smts
245 | JSAstProgram smts _ <- top = Module mid <$> traverse toModuleElement smts
228 | otherwise = err InvalidTopLevel
246 | otherwise = err InvalidTopLevel
229 where
247 where
@@ -231,7 +249,7 @@ toModule requirePath mids mid top
231
249
232 toModuleElement :: JSStatement -> m ModuleElement
250 toModuleElement :: JSStatement -> m ModuleElement
233 toModuleElement stmt
251 toModuleElement stmt
234− | Just (importName, importPath) <- matchRequire requirePath mids mid stmt
252+ | Just (importName, importPath) <- matchRequire mids mid stmt
235 = pure (Require stmt importName importPath)
253 = pure (Require stmt importName importPath)
236 toModuleElement stmt
254 toModuleElement stmt
237 | Just (exported, name, decl) <- matchMember stmt
255 | Just (exported, name, decl) <- matchMember stmt
@@ -291,12 +309,11 @@ getExportedIdentifiers mname top
291
309
292-- Matches JS statements like this:
310-- Matches JS statements like this:
293-- var ModuleName = require("file");
311-- var ModuleName = require("file");
294−matchRequire :: Maybe FilePath
295− -> S.Set String
312+matchRequire :: S.Set String
296 -> ModuleIdentifier
313 -> ModuleIdentifier
297 -> JSStatement
314 -> JSStatement
298 -> Maybe (String, Either String ModuleIdentifier)
315 -> Maybe (String, Either String ModuleIdentifier)
299−matchRequire requirePath mids mid stmt
316+matchRequire mids mid stmt
300 | JSVariable _ jsInit _ <- stmt
317 | JSVariable _ jsInit _ <- stmt
301 , [JSVarInitExpression var varInit] <- commaList jsInit
318 , [JSVarInitExpression var varInit] <- commaList jsInit
302 , JSIdentifier _ importName <- var
319 , JSIdentifier _ importName <- var
@@ -304,7 +321,7 @@ matchRequire requirePath mids mid stmt
304 , JSMemberExpression req _ argsE _ <- jsInitEx
321 , JSMemberExpression req _ argsE _ <- jsInitEx
305 , JSIdentifier _ "require" <- req
322 , JSIdentifier _ "require" <- req
306 , [ Just importPath ] <- map fromStringLiteral (commaList argsE)
323 , [ Just importPath ] <- map fromStringLiteral (commaList argsE)
307− , importPath' <- checkImportPath requirePath importPath mid mids
324+ , importPath' <- checkImportPath importPath mid mids
308 = Just (importName, importPath')
325 = Just (importName, importPath')
309 | otherwise
326 | otherwise
310 = Nothing
327 = Nothing
@@ -350,7 +367,7 @@ matchExportsAssignment stmt
350 = Nothing
367 = Nothing
351
368
352extractLabel :: JSPropertyName -> Maybe String
369extractLabel :: JSPropertyName -> Maybe String
353−extractLabel (JSPropertyString _ nm) = Just (trimStringQuotes nm)
370+extractLabel (JSPropertyString _ nm) = Just $ strValue nm
354extractLabel (JSPropertyIdent _ nm) = Just nm
371extractLabel (JSPropertyIdent _ nm) = Just nm
355extractLabel _ = Nothing
372extractLabel _ = Nothing
356
373
@@ -590,16 +607,15 @@ bundle :: (MonadError ErrorMessage m)
590 -> [ModuleIdentifier] -- ^ Entry points. These module identifiers are used as the roots for dead-code elimination
607 -> [ModuleIdentifier] -- ^ Entry points. These module identifiers are used as the roots for dead-code elimination
591 -> Maybe String -- ^ An optional main module.
608 -> Maybe String -- ^ An optional main module.
592 -> String -- ^ The namespace (e.g. PS).
609 -> String -- ^ The namespace (e.g. PS).
593− -> Maybe FilePath -- ^ The require path prefix
594 -> m String
610 -> m String
595−bundle inputStrs entryPoints mainModule namespace requirePath = do
611+bundle inputStrs entryPoints mainModule namespace = do
596 input <- forM inputStrs $ \(ident, js) -> do
612 input <- forM inputStrs $ \(ident, js) -> do
597 ast <- either (throwError . ErrorInModule ident . UnableToParseModule) pure $ parse js (moduleName ident)
613 ast <- either (throwError . ErrorInModule ident . UnableToParseModule) pure $ parse js (moduleName ident)
598 return (ident, ast)
614 return (ident, ast)
599
615
600 let mids = S.fromList (map (moduleName . fst) input)
616 let mids = S.fromList (map (moduleName . fst) input)
601
617
602− modules <- traverse (fmap withDeps . uncurry (toModule requirePath mids)) input
618+ modules <- traverse (fmap withDeps . uncurry (toModule mids)) input
603
619
604 let compiled = compile modules entryPoints
620 let compiled = compile modules entryPoints
605 sorted = sortModules (filter (not . isModuleEmpty) compiled)
621 sorted = sortModules (filter (not . isModuleEmpty) compiled)
src/Language/PureScript/CodeGen.hs+8−20
@@ -1,20 +1,8 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
1+-- |
12−-- A collection of modules related to code generation:
2+-- A collection of modules related to code generation:
13−--
3+--
14−-- [@Language.PureScript.CodeGen.JS@] Code generator for Javascript
4+-- [@Language.PureScript.CodeGen.JS@] Code generator for Javascript
15−--
5+--
16−-----------------------------------------------------------------------------
17−
18−module Language.PureScript.CodeGen (module C) where
6+module Language.PureScript.CodeGen (module C) where
19−
7+
20−import Language.PureScript.CodeGen.JS as C
8+import Language.PureScript.CodeGen.JS as C
src/Language/PureScript/CodeGen/Cpp.hs+17−18
@@ -26,6 +26,8 @@ module Language.PureScript.CodeGen.Cpp
26 , P.prettyPrintCpp
26 , P.prettyPrintCpp
27 ) where
27 ) where
28
28
29+import Prelude.Compat
30+
29import Data.Char (isLetter)
31import Data.Char (isLetter)
30import Data.List
32import Data.List
31import Data.Function (on)
33import Data.Function (on)
@@ -124,9 +126,6 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
124 (supers, members) = span (C.__superclass_ `isPrefixOf`) (identToCpp <$> (fst $ unAbs e []))
126 (supers, members) = span (C.__superclass_ `isPrefixOf`) (identToCpp <$> (fst $ unAbs e []))
125 in return $ CppStruct className [CppEnum Nothing Nothing (sort supers ++ members)]
127 in return $ CppStruct className [CppEnum Nothing Nothing (sort supers ++ members)]
126
128
127− declToCpp _ (_, Op _) (Var (_, _, Nothing, _) _) =
128− return CppNoOp -- skip operator aliases
129−
130 declToCpp vqs (_, ident) (Abs (_, com, ty, _) arg body) = do
129 declToCpp vqs (_, ident) (Abs (_, com, ty, _) arg body) = do
131 fn <- if argcnt > 1 && CppTopLevel `elem` vqs
130 fn <- if argcnt > 1 && CppTopLevel `elem` vqs
132 then do
131 then do
@@ -170,7 +169,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
170 return (CppComment com fn)
169 return (CppComment com fn)
171 where
170 where
172 ty' | Just t <- ty = Just t
171 ty' | Just t <- ty = Just t
173− | Just (t, _, _) <- M.lookup (mn, ident) (E.names env) = Just t
172+ | Just (t, _, _) <- M.lookup (Qualified (Just mn) ident) (E.names env) = Just t
174 | otherwise = Nothing
173 | otherwise = Nothing
175 argcnt = maybe 0 countArgs ty'
174 argcnt = maybe 0 countArgs ty'
176 name = identToCpp ident
175 name = identToCpp ident
@@ -185,7 +184,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
185 isIndexer :: Cpp -> Bool
184 isIndexer :: Cpp -> Bool
186 isIndexer (CppIndexer (CppStringLiteral _) (CppVar _)) = True
185 isIndexer (CppIndexer (CppStringLiteral _) (CppVar _)) = True
187 isIndexer _ = False
186 isIndexer _ = False
188− classes = qualifiedToCpp (Ident . runProperName) . fst <$>
187+ classes = qualifiedToCpp (Ident . runProperName) . T.constraintClass <$>
189 maybe [] extractConstraints ty'
188 maybe [] extractConstraints ty'
190 dictClasses = zip (CppVar . fst <$> arg' : args') classes
189 dictClasses = zip (CppVar . fst <$> arg' : args') classes
191 convertDictIndexers = everywhereOnCpp (dictIndexerToEnum dictClasses)
190 convertDictIndexers = everywhereOnCpp (dictIndexerToEnum dictClasses)
@@ -420,7 +419,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
420 CppArrayLiteral <$> mapM valueToCpp xs
419 CppArrayLiteral <$> mapM valueToCpp xs
421
420
422 valueToCpp (Literal _ (ObjectLiteral ps)) =
421 valueToCpp (Literal _ (ObjectLiteral ps)) =
423− CppObjectLiteral <$> sortBy (compare `on` fst) <$> mapM (sndM valueToCpp) ps
422+ CppObjectLiteral CppRecord <$> sortBy (compare `on` fst) <$> mapM (sndM valueToCpp) ps
424
423
425 valueToCpp (Accessor _ prop val) =
424 valueToCpp (Accessor _ prop val) =
426 CppIndexer <$> pure (CppStringLiteral prop) <*> valueToCpp val
425 CppIndexer <$> pure (CppStringLiteral prop) <*> valueToCpp val
@@ -431,7 +430,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
431 updatedFields <- mapM (sndM valueToCpp) ps
430 updatedFields <- mapM (sndM valueToCpp) ps
432 let origKeys = (allKeys ty) \\ (fst <$> updatedFields)
431 let origKeys = (allKeys ty) \\ (fst <$> updatedFields)
433 origFields = (\key -> (key, CppIndexer (CppStringLiteral key) obj')) <$> origKeys
432 origFields = (\key -> (key, CppIndexer (CppStringLiteral key) obj')) <$> origKeys
434− return $ CppObjectLiteral . sortBy (compare `on` fst) $ origFields ++ updatedFields
433+ return $ CppObjectLiteral CppRecord . sortBy (compare `on` fst) $ origFields ++ updatedFields
435 where
434 where
436 allKeys :: T.Type -> [String]
435 allKeys :: T.Type -> [String]
437 allKeys (T.TypeApp (T.TypeConstructor _) r@(T.RCons {})) = fst <$> (fst $ T.rowToList r)
436 allKeys (T.TypeApp (T.TypeConstructor _) r@(T.RCons {})) = fst <$> (fst $ T.rowToList r)
@@ -452,7 +451,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
452 where
451 where
453 arg' = identToCpp arg
452 arg' = identToCpp arg
454 args' = identToCpp <$> (fst $ unAbs body [])
453 args' = identToCpp <$> (fst $ unAbs body [])
455− classes = qualifiedToCpp (Ident . runProperName) . fst <$>
454+ classes = qualifiedToCpp (Ident . runProperName) . T.constraintClass <$>
456 maybe [] extractConstraints ty
455 maybe [] extractConstraints ty
457 dictClasses = zip (CppVar <$> arg' : args') classes
456 dictClasses = zip (CppVar <$> arg' : args') classes
458 convertDictIndexers = everywhereOnCpp (dictIndexerToEnum dictClasses)
457 convertDictIndexers = everywhereOnCpp (dictIndexerToEnum dictClasses)
@@ -466,7 +465,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
466 return $ CppApp (uncurried' $ qualifiedToCpp id ident) args'
465 return $ CppApp (uncurried' $ qualifiedToCpp id ident) args'
467 Var (_, _, _, Just IsTypeClassConstructor) (Qualified mn' (Ident classname)) ->
466 Var (_, _, _, Just IsTypeClassConstructor) (Qualified mn' (Ident classname)) ->
468 let Just (_, constraints, fns) = findClass (Qualified mn' (ProperName classname)) in
467 let Just (_, constraints, fns) = findClass (Qualified mn' (ProperName classname)) in
469− return . CppObjectLiteral $
468+ return . CppObjectLiteral CppInstance $
470 zip
469 zip
471 ((sort $ superClassDictionaryNames constraints) ++ (fst <$> fns))
470 ((sort $ superClassDictionaryNames constraints) ++ (fst <$> fns))
472 args'
471 args'
@@ -485,7 +484,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
485 return $ foldl (\fn a -> CppApp fn [a]) fn' curriedArgs
484 return $ foldl (\fn a -> CppApp fn [a]) fn' curriedArgs
486 where
485 where
487 ty | (_, _, Just t, _) <- ann = Just t
486 ty | (_, _, Just t, _) <- ann = Just t
488− | Just (t, _, _) <- M.lookup (mn', ident) (E.names env) = Just t
487+ | Just (t, _, _) <- M.lookup (Qualified (Just mn') ident) (E.names env) = Just t
489 | otherwise = Nothing
488 | otherwise = Nothing
490 _ ->
489 _ ->
491 flip (foldl (\fn a -> CppApp fn [a])) args' <$> valueToCpp f
490 flip (foldl (\fn a -> CppApp fn [a])) args' <$> valueToCpp f
@@ -618,7 +617,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
618 SumType ->
617 SumType ->
619 [ CppIfElse
618 [ CppIfElse
620 (CppBinary
619 (CppBinary
621− Equal
620+ EqualTo
622 (CppIndexer
621 (CppIndexer
623 (CppVar ctorKey)
622 (CppVar ctorKey)
624 (CppCast dataType $ CppVar varName))
623 (CppCast dataType $ CppVar varName))
@@ -665,19 +664,19 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
665 -------------------------------------------------------------------------------------------------
664 -------------------------------------------------------------------------------------------------
666 literalToBinderCpp varName done (NumericLiteral num) =
665 literalToBinderCpp varName done (NumericLiteral num) =
667 return [ CppIfElse
666 return [ CppIfElse
668− (CppBinary Equal (CppVar varName) (CppNumericLiteral num))
667+ (CppBinary EqualTo (CppVar varName) (CppNumericLiteral num))
669 (CppBlock done)
668 (CppBlock done)
670 Nothing ]
669 Nothing ]
671
670
672 literalToBinderCpp varName done (CharLiteral c) =
671 literalToBinderCpp varName done (CharLiteral c) =
673 return [ CppIfElse
672 return [ CppIfElse
674− (CppBinary Equal (CppVar varName) (CppCharLiteral c))
673+ (CppBinary EqualTo (CppVar varName) (CppCharLiteral c))
675 (CppBlock done)
674 (CppBlock done)
676 Nothing ]
675 Nothing ]
677
676
678 literalToBinderCpp varName done (StringLiteral str) =
677 literalToBinderCpp varName done (StringLiteral str) =
679 return [ CppIfElse
678 return [ CppIfElse
680− (CppBinary Equal (CppVar varName) (CppStringLiteral str))
679+ (CppBinary EqualTo (CppVar varName) (CppStringLiteral str))
681 (CppBlock done)
680 (CppBlock done)
682 Nothing ]
681 Nothing ]
683
682
@@ -690,7 +689,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
690 literalToBinderCpp varName done (BooleanLiteral False) =
689 literalToBinderCpp varName done (BooleanLiteral False) =
691 return [ CppIfElse
690 return [ CppIfElse
692 (CppUnary
691 (CppUnary
693− CppNot
692+ Not
694 (CppVar varName))
693 (CppVar varName))
695 (CppBlock done)
694 (CppBlock done)
696 Nothing ]
695 Nothing ]
@@ -722,7 +721,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
722 (CppApp (CppVar "empty") [])
721 (CppApp (CppVar "empty") [])
723 n -> let var = CppCast arrayType $ CppVar varName
722 n -> let var = CppCast arrayType $ CppVar varName
724 in CppBinary
723 in CppBinary
725− Equal
724+ EqualTo
726 (CppBinary Dot var (CppApp (CppVar "size") []))
725 (CppBinary Dot var (CppApp (CppVar "size") []))
727 (CppNumericLiteral (Left (fromIntegral n)))
726 (CppNumericLiteral (Left (fromIntegral n)))
728 return [ CppIfElse cond (CppBlock cpp) Nothing ]
727 return [ CppIfElse cond (CppBlock cpp) Nothing ]
@@ -811,8 +810,8 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
811 go _ = return []
810 go _ = return []
812
811
813 allForeigns :: [(Ident, T.Type)]
812 allForeigns :: [(Ident, T.Type)]
814− allForeigns = map (\((_, ident), (ty, _, _)) -> (ident, ty)) .
813+ allForeigns = map (\((Qualified _ ident), (ty, _, _)) -> (ident, ty)) .
815− filter (\((mn', _), (_, kind, _)) -> mn' == mn && kind == E.External) .
814+ filter (\((Qualified mn' _), (_, kind, _)) -> mn' == Just mn && kind == E.External) .
816 M.toList $ E.names env
815 M.toList $ E.names env
817
816
818---------------------------------------------------------------------------------------------------
817---------------------------------------------------------------------------------------------------
src/Language/PureScript/CodeGen/Cpp/AST.hs+22−21
@@ -18,12 +18,13 @@
18
18
19module Language.PureScript.CodeGen.Cpp.AST where
19module Language.PureScript.CodeGen.Cpp.AST where
20
20
21+import Prelude.Compat
22+
21#if __GLASGOW_HASKELL__ < 710
23#if __GLASGOW_HASKELL__ < 710
22import Control.Applicative (Applicative, (<$>), (<*>))
24import Control.Applicative (Applicative, (<$>), (<*>))
23import Data.Traversable (traverse)
25import Data.Traversable (traverse)
24#endif
26#endif
25import Control.Monad.Identity
27import Control.Monad.Identity
26−import Data.Data
27import Language.PureScript.Comments
28import Language.PureScript.Comments
28import Language.PureScript.CodeGen.Cpp.Types
29import Language.PureScript.CodeGen.Cpp.Types
29import Language.PureScript.Traversals
30import Language.PureScript.Traversals
@@ -31,33 +32,33 @@ import Language.PureScript.Traversals
31-- |
32-- |
32-- Built-in unary operators
33-- Built-in unary operators
33--
34--
34−data CppUnaryOp
35+data UnaryOperator
35 -- |
36 -- |
36 -- Numeric negation
37 -- Numeric negation
37 --
38 --
38− = CppNegate
39+ = Negate
39 -- |
40 -- |
40 -- Boolean negation
41 -- Boolean negation
41 --
42 --
42− | CppNot
43+ | Not
43 -- |
44 -- |
44 -- Bitwise negation
45 -- Bitwise negation
45 --
46 --
46− | CppBitwiseNot
47+ | BitwiseNot
47 -- |
48 -- |
48 -- Numeric unary \'plus\'
49 -- Numeric unary \'plus\'
49 --
50 --
50− | CppPositive
51+ | Positive
51 -- |
52 -- |
52 -- Constructor
53 -- Constructor
53 --
54 --
54− | CppNew
55+ | New
55− deriving (Show, Read, Eq)
56+ deriving (Show, Eq)
56
57
57-- |
58-- |
58-- Built-in binary operators
59-- Built-in binary operators
59--
60--
60−data BinaryOp
61+data BinaryOperator
61 -- |
62 -- |
62 -- Numeric addition
63 -- Numeric addition
63 --
64 --
@@ -85,11 +86,11 @@ data BinaryOp
85 -- |
86 -- |
86 -- Generic equality test
87 -- Generic equality test
87 --
88 --
88− | Equal
89+ | EqualTo
89 -- |
90 -- |
90 -- Generic inequality test
91 -- Generic inequality test
91 --
92 --
92− | NotEqual
93+ | NotEqualTo
93 -- |
94 -- |
94 -- Numeric less-than
95 -- Numeric less-than
95 --
96 --
@@ -97,7 +98,7 @@ data BinaryOp
97 -- |
98 -- |
98 -- Numeric less-than-or-equal
99 -- Numeric less-than-or-equal
99 --
100 --
100− | LessThanOrEqual
101+ | LessThanOrEqualTo
101 -- |
102 -- |
102 -- Numeric greater-than
103 -- Numeric greater-than
103 --
104 --
@@ -105,7 +106,7 @@ data BinaryOp
105 -- |
106 -- |
106 -- Numeric greater-than-or-equal
107 -- Numeric greater-than-or-equal
107 --
108 --
108− | GreaterThanOrEqual
109+ | GreaterThanOrEqualTo
109 -- |
110 -- |
110 -- Boolean and
111 -- Boolean and
111 --
112 --
@@ -135,7 +136,7 @@ data BinaryOp
135 --
136 --
136 | ShiftRight
137 | ShiftRight
137 --
138 --
138− deriving (Show, Read, Eq)
139+ deriving (Show, Eq)
139
140
140-- |
141-- |
141-- Data type for simplified C++11 expressions
142-- Data type for simplified C++11 expressions
@@ -160,11 +161,11 @@ data Cpp
160 -- |
161 -- |
161 -- A unary operator application
162 -- A unary operator application
162 --
163 --
163− | CppUnary CppUnaryOp Cpp
164+ | CppUnary UnaryOperator Cpp
164 -- |
165 -- |
165 -- A binary operator application
166 -- A binary operator application
166 --
167 --
167− | CppBinary BinaryOp Cpp Cpp
168+ | CppBinary BinaryOperator Cpp Cpp
168 -- |
169 -- |
169 -- An array literal
170 -- An array literal
170 --
171 --
@@ -184,7 +185,7 @@ data Cpp
184 -- |
185 -- |
185 -- An object literal
186 -- An object literal
186 --
187 --
187− | CppObjectLiteral [(String, Cpp)]
188+ | CppObjectLiteral CppObjectType [(String, Cpp)]
188 -- |
189 -- |
189 -- An general property accessor expression (property, expr)
190 -- An general property accessor expression (property, expr)
190 --
191 --
@@ -281,7 +282,7 @@ data Cpp
281 -- Commented C++11
282 -- Commented C++11
282 --
283 --
283 | CppComment [Comment] Cpp
284 | CppComment [Comment] Cpp
284− deriving (Show, Read, Eq)
285+ deriving (Show, Eq)
285
286
286--
287--
287-- Traversals
288-- Traversals
@@ -296,7 +297,7 @@ everywhereOnCpp f = go
296 go (CppArrayLiteral cpp) = f (CppArrayLiteral (map go cpp))
297 go (CppArrayLiteral cpp) = f (CppArrayLiteral (map go cpp))
297 go (CppDataLiteral cpp) = f (CppDataLiteral (map go cpp))
298 go (CppDataLiteral cpp) = f (CppDataLiteral (map go cpp))
298 go (CppIndexer j1 j2) = f (CppIndexer (go j1) (go j2))
299 go (CppIndexer j1 j2) = f (CppIndexer (go j1) (go j2))
299− go (CppObjectLiteral cpp) = f (CppObjectLiteral (map (fmap go) cpp))
300+ go (CppObjectLiteral t cpp) = f (CppObjectLiteral t (map (fmap go) cpp))
300 go (CppAccessor prop j) = f (CppAccessor (go prop) (go j))
301 go (CppAccessor prop j) = f (CppAccessor (go prop) (go j))
301 go (CppFunction name args rty qs j) = f (CppFunction name args rty qs (go j))
302 go (CppFunction name args rty qs j) = f (CppFunction name args rty qs (go j))
302 go (CppLambda cps args rty j) = f (CppLambda cps args rty (go j))
303 go (CppLambda cps args rty j) = f (CppLambda cps args rty (go j))
@@ -327,7 +328,7 @@ everywhereOnCppTopDownM f = f >=> go
327 go (CppArrayLiteral cpp) = CppArrayLiteral <$> traverse f' cpp
328 go (CppArrayLiteral cpp) = CppArrayLiteral <$> traverse f' cpp
328 go (CppDataLiteral cpp) = CppDataLiteral <$> traverse f' cpp
329 go (CppDataLiteral cpp) = CppDataLiteral <$> traverse f' cpp
329 go (CppIndexer j1 j2) = CppIndexer <$> f' j1 <*> f' j2
330 go (CppIndexer j1 j2) = CppIndexer <$> f' j1 <*> f' j2
330− go (CppObjectLiteral cpp) = CppObjectLiteral <$> traverse (sndM f') cpp
331+ go (CppObjectLiteral t cpp) = CppObjectLiteral t <$> traverse (sndM f') cpp
331 go (CppAccessor prop j) = CppAccessor prop <$> f' j
332 go (CppAccessor prop j) = CppAccessor prop <$> f' j
332 go (CppFunction name args rty qs j) = CppFunction name args rty qs <$> f' j
333 go (CppFunction name args rty qs j) = CppFunction name args rty qs <$> f' j
333 go (CppLambda cps args rty j) = CppLambda cps args rty <$> f' j
334 go (CppLambda cps args rty j) = CppLambda cps args rty <$> f' j
@@ -354,7 +355,7 @@ everythingOnCpp (<>) f = go
354 go j@(CppArrayLiteral cpp) = foldl (<>) (f j) (map go cpp)
355 go j@(CppArrayLiteral cpp) = foldl (<>) (f j) (map go cpp)
355 go j@(CppDataLiteral cpp) = foldl (<>) (f j) (map go cpp)
356 go j@(CppDataLiteral cpp) = foldl (<>) (f j) (map go cpp)
356 go j@(CppIndexer j1 j2) = f j <> go j1 <> go j2
357 go j@(CppIndexer j1 j2) = f j <> go j1 <> go j2
357− go j@(CppObjectLiteral cpp) = foldl (<>) (f j) (map (go . snd) cpp)
358+ go j@(CppObjectLiteral _ cpp) = foldl (<>) (f j) (map (go . snd) cpp)
358 go j@(CppAccessor j1 j2) = f j <> go j1 <> go j2
359 go j@(CppAccessor j1 j2) = f j <> go j1 <> go j2
359 go j@(CppFunction _ _ _ _ j1) = f j <> go j1
360 go j@(CppFunction _ _ _ _ j1) = f j <> go j1
360 go j@(CppLambda _ _ _ j1) = f j <> go j1
361 go j@(CppLambda _ _ _ j1) = f j <> go j1
src/Language/PureScript/CodeGen/Cpp/Common.hs+4−2
@@ -17,9 +17,12 @@
17
17
18module Language.PureScript.CodeGen.Cpp.Common where
18module Language.PureScript.CodeGen.Cpp.Common where
19
19
20+import Prelude.Compat
21+
20import Data.Char
22import Data.Char
21import Data.List (intercalate)
23import Data.List (intercalate)
22
24
25+import Language.PureScript.Crash
23import Language.PureScript.Names
26import Language.PureScript.Names
24
27
25-- |
28-- |
@@ -35,7 +38,7 @@ identToCpp :: Ident -> String
35identToCpp (Ident name) | nameIsCppReserved name = '_' : name ++ "_"
38identToCpp (Ident name) | nameIsCppReserved name = '_' : name ++ "_"
36identToCpp (Ident name@('$' : s)) | all isDigit s = name
39identToCpp (Ident name@('$' : s)) | all isDigit s = name
37identToCpp (Ident name) = concatMap identCharToString name
40identToCpp (Ident name) = concatMap identCharToString name
38−identToCpp (Op op) = concatMap identCharToString op
41+identToCpp (GenIdent _ _) = internalError "GenIdent in identToJs"
39
42
40-- |
43-- |
41-- Test if a string is a valid Cpp identifier without escaping.
44-- Test if a string is a valid Cpp identifier without escaping.
@@ -126,7 +129,6 @@ nameIsCppReserved name =
126 , "import"
129 , "import"
127 , "inline"
130 , "inline"
128 , "int"
131 , "int"
129− , "integer"
130 , "list"
132 , "list"
131 , "long"
133 , "long"
132 , "mutable"
134 , "mutable"
src/Language/PureScript/CodeGen/Cpp/File.hs+16−6
@@ -17,6 +17,8 @@
17
17
18module Language.PureScript.CodeGen.Cpp.File where
18module Language.PureScript.CodeGen.Cpp.File where
19
19
20+import Prelude.Compat
21+
20import Data.Maybe
22import Data.Maybe
21
23
22import Language.PureScript.CodeGen.Cpp.AST
24import Language.PureScript.CodeGen.Cpp.AST
@@ -50,9 +52,14 @@ toHeader = catMaybes . map go
50 Nothing
52 Nothing
51 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty _))) =
53 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty _))) =
52 Just $ CppFunction name [] rty [] CppNoOp
54 Just $ CppFunction name [] rty [] CppNoOp
55+
53 -- Generate thunks for top-level values
56 -- Generate thunks for top-level values
54− go (CppVariableIntroduction (name, _) _ (Just _)) =
57+ go (CppVariableIntroduction (name, vty) _ (Just cpp)) =
55− Just $ CppVariableIntroduction (name, Just $ CppAny [CppConst]) [CppExtern] Nothing
58+ case cpp of
59+ CppObjectLiteral CppInstance vals ->
60+ Just $ CppFunction name [("", Just thunkMarkerType)] (Just $ CppAny [CppConst, CppRef]) [] CppNoOp
61+ _ ->
62+ Just $ CppVariableIntroduction (name, vty) [CppExtern] Nothing
56 go cpp@(CppStruct {}) =
63 go cpp@(CppStruct {}) =
57 Just cpp
64 Just cpp
58 go (CppComment comms cpp')
65 go (CppComment comms cpp')
@@ -113,15 +120,18 @@ toBody = catMaybes . map go
113 Nothing
120 Nothing
114 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty body))) =
121 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty body))) =
115 Just $ CppFunction name [] rty [] body
122 Just $ CppFunction name [] rty [] body
116− -- Generate thunks for top-level values
117− go (CppVariableIntroduction (name, _) _ (Just cpp)) =
123+ go (CppVariableIntroduction (name, vty) _ (Just cpp)) =
118− Just $ CppVariableIntroduction (name, Just $ CppAny [CppConst]) [] (Just lambda)
124+ case cpp of
125+ CppObjectLiteral CppInstance vals ->
126+ Just $ CppFunction name [("", Just thunkMarkerType)] (Just $ CppAny [CppConst, CppRef]) [] block
127+ _ ->
128+ Just $ CppVariableIntroduction (name, vty) [] (Just lambda)
119 where
129 where
120 val = CppVariableIntroduction ("$value$", Just $ CppAny [CppConst]) [CppStatic] (Just $ addCaptures cpp)
130 val = CppVariableIntroduction ("$value$", Just $ CppAny [CppConst]) [CppStatic] (Just $ addCaptures cpp)
121 block = CppBlock [val, CppReturn (CppVar "$value$")]
131 block = CppBlock [val, CppReturn (CppVar "$value$")]
122 lambda = CppLambda [] [("", Just $ thunkMarkerType)] (Just $ CppAny [CppConst, CppRef]) block
132 lambda = CppLambda [] [("", Just $ thunkMarkerType)] (Just $ CppAny [CppConst, CppRef]) block
123 addCaptures :: Cpp -> Cpp
133 addCaptures :: Cpp -> Cpp
124− addCaptures (CppObjectLiteral objs) = CppObjectLiteral (objlam <$> objs)
134+ addCaptures (CppObjectLiteral t objs) = CppObjectLiteral t (objlam <$> objs)
125 where
135 where
126 objlam :: (String, Cpp) -> (String, Cpp)
136 objlam :: (String, Cpp) -> (String, Cpp)
127 objlam (name', (CppLambda _ args rty body)) = (name' , CppLambda [] args rty $ addCaptures body)
137 objlam (name', (CppLambda _ args rty body)) = (name' , CppLambda [] args rty $ addCaptures body)
src/Language/PureScript/CodeGen/Cpp/Optimizer.hs+3−1
@@ -38,6 +38,8 @@ module Language.PureScript.CodeGen.Cpp.Optimizer (
38 optimize
38 optimize
39) where
39) where
40
40
41+import Prelude.Compat
42+
41#if __GLASGOW_HASKELL__ < 710
43#if __GLASGOW_HASKELL__ < 710
42import Control.Applicative (Applicative)
44import Control.Applicative (Applicative)
43#endif
45#endif
@@ -79,7 +81,7 @@ optimize' cpp = do
79 , etaConvert
81 , etaConvert
80 , evaluateIifes
82 , evaluateIifes
81 , inlineVariables
83 , inlineVariables
82− , inlineValues
84+ , inlineCommonValues
83 , inlineOperator (C.prelude, (C.$)) $ \f x -> CppApp f [x]
85 , inlineOperator (C.prelude, (C.$)) $ \f x -> CppApp f [x]
84 , inlineOperator (C.prelude, (C.#)) $ \x f -> CppApp f [x]
86 , inlineOperator (C.prelude, (C.#)) $ \x f -> CppApp f [x]
85 , inlineOperator (C.dataArrayUnsafe, C.unsafeIndex) $ flip CppIndexer
87 , inlineOperator (C.dataArrayUnsafe, C.unsafeIndex) $ flip CppIndexer
src/Language/PureScript/CodeGen/Cpp/Optimizer/Blocks.hs+12−10
@@ -19,6 +19,8 @@ module Language.PureScript.CodeGen.Cpp.Optimizer.Blocks
19 , collapseIfElses
19 , collapseIfElses
20 ) where
20 ) where
21
21
22+import Prelude.Compat
23+
22import Language.PureScript.CodeGen.Cpp.AST
24import Language.PureScript.CodeGen.Cpp.AST
23import qualified Language.PureScript.Constants as C
25import qualified Language.PureScript.Constants as C
24
26
@@ -49,29 +51,29 @@ collapseIfElses = everywhereOnCpp collapse
49 collapse :: Cpp -> Cpp
51 collapse :: Cpp -> Cpp
50 collapse (CppBlock cpps) = CppBlock (go cpps)
52 collapse (CppBlock cpps) = CppBlock (go cpps)
51 where
53 where
52− go (st'@(CppIfElse (CppBinary Equal a _) _ Nothing) : sts') =
54+ go (st'@(CppIfElse (CppBinary EqualTo lhs _) _ Nothing) : sts') =
53 if length (fst cpps') > 1
55 if length (fst cpps') > 1
54− then CppSwitch a (mkCases <$> fst cpps') : snd cpps'
56+ then CppSwitch lhs (mkCases <$> fst cpps') : snd cpps'
55 else st' : sts'
57 else st' : sts'
56 where
58 where
57− cpps' = span (isIntEq a) (st' : sts')
59+ cpps' = span (isIntEq lhs) (st' : sts')
58 isIntEq :: Cpp -> Cpp -> Bool
60 isIntEq :: Cpp -> Cpp -> Bool
59− isIntEq a (CppIfElse (CppBinary Equal a' (CppNumericLiteral (Left _))) (CppBlock [CppReturn _]) Nothing)
61+ isIntEq a (CppIfElse (CppBinary EqualTo a' (CppNumericLiteral (Left _))) (CppBlock [CppReturn _]) Nothing)
60 | a == a' = True
62 | a == a' = True
61− isIntEq a (CppIfElse (CppBinary Equal a' (CppCharLiteral _)) (CppBlock [CppReturn _]) Nothing)
63+ isIntEq a (CppIfElse (CppBinary EqualTo a' (CppCharLiteral _)) (CppBlock [CppReturn _]) Nothing)
62 | a == a' = True
64 | a == a' = True
63− isIntEq a (CppIfElse (CppBinary Equal a' (CppBooleanLiteral _)) (CppBlock [CppReturn _]) Nothing)
65+ isIntEq a (CppIfElse (CppBinary EqualTo a' (CppBooleanLiteral _)) (CppBlock [CppReturn _]) Nothing)
64 | a == a' = True
66 | a == a' = True
65 isIntEq _ _ = False
67 isIntEq _ _ = False
66 mkCases :: Cpp -> (Cpp, Cpp)
68 mkCases :: Cpp -> (Cpp, Cpp)
67− mkCases (CppIfElse (CppBinary Equal _ b') (CppBlock [body]) Nothing) = (b', body)
69+ mkCases (CppIfElse (CppBinary EqualTo _ b') (CppBlock [body]) Nothing) = (b', body)
68− mkCases (CppIfElse (CppUnary CppNot _) (CppBlock [body]) Nothing) = (CppBooleanLiteral False, body)
70+ mkCases (CppIfElse (CppUnary Not _) (CppBlock [body]) Nothing) = (CppBooleanLiteral False, body)
69 mkCases (CppIfElse _ (CppBlock [body]) Nothing) = (CppBooleanLiteral True, body)
71 mkCases (CppIfElse _ (CppBlock [body]) Nothing) = (CppBooleanLiteral True, body)
70 mkCases _ = error ""
72 mkCases _ = error ""
71 go ((CppIfElse cond1 body1 Nothing) : (CppIfElse cond2 body2 Nothing) : _)
73 go ((CppIfElse cond1 body1 Nothing) : (CppIfElse cond2 body2 Nothing) : _)
72 | returns body1 && returns body2 &&
74 | returns body1 && returns body2 &&
73− (CppUnary CppNot cond1 == cond2 ||
75+ (CppUnary Not cond1 == cond2 ||
74− CppUnary CppNot cond2 == cond1) = [CppIfElse cond1 body1 (Just body2)]
76+ CppUnary Not cond2 == cond1) = [CppIfElse cond1 body1 (Just body2)]
75 where
77 where
76 returns :: Cpp -> Bool
78 returns :: Cpp -> Bool
77 returns (CppBlock rets@(_:_)) | CppReturn{} <- last rets = True
79 returns (CppBlock rets@(_:_)) | CppReturn{} <- last rets = True
src/Language/PureScript/CodeGen/Cpp/Optimizer/Common.hs+16
@@ -15,6 +15,8 @@
15
15
16module Language.PureScript.CodeGen.Cpp.Optimizer.Common where
16module Language.PureScript.CodeGen.Cpp.Optimizer.Common where
17
17
18+import Prelude.Compat
19+
18import Data.Maybe (fromMaybe)
20import Data.Maybe (fromMaybe)
19
21
20import Language.PureScript.CodeGen.Cpp.AST
22import Language.PureScript.CodeGen.Cpp.AST
@@ -73,3 +75,17 @@ isUpdated var1 = everythingOnCpp (||) check
73removeFromBlock :: ([Cpp] -> [Cpp]) -> Cpp -> Cpp
75removeFromBlock :: ([Cpp] -> [Cpp]) -> Cpp -> Cpp
74removeFromBlock go (CppBlock sts) = CppBlock (go sts)
76removeFromBlock go (CppBlock sts) = CppBlock (go sts)
75removeFromBlock _ cpp = cpp
77removeFromBlock _ cpp = cpp
78+
79+isFn :: (String, String) -> Cpp -> Bool
80+isFn (moduleName, fnName) (CppAccessor (CppVar x) (CppVar y)) =
81+ x == fnName && y == moduleName
82+isFn (moduleName, fnName) (CppIndexer (CppStringLiteral x) (CppVar y)) =
83+ x == fnName && y == moduleName
84+isFn _ _ = False
85+
86+isDict :: (String, String) -> Cpp -> Bool
87+isDict (moduleName, dictName) (CppAccessor (CppVar x) (CppVar y)) = x == dictName && y == moduleName
88+isDict _ _ = False
89+
90+isDict' :: [(String, String)] -> Cpp -> Bool
91+isDict' xs cpp = any (`isDict` cpp) xs
src/Language/PureScript/CodeGen/Cpp/Optimizer/Inliner.hs+197−142
@@ -12,28 +12,25 @@
12-- This module provides basic inlining capabilities
12-- This module provides basic inlining capabilities
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15+module Language.PureScript.CodeGen.Cpp.Optimizer.Inliner
16+ ( inlineVariables
17+ , inlineCommonValues
18+ , inlineOperator
19+ , inlineCommonOperators
20+ , inlineFnComposition
21+ , etaConvert
22+ , unThunk
23+ , evaluateIifes
24+ ) where
25+
26+import Prelude.Compat
15
27
16−{-# LANGUAGE CPP #-}
17−
18−module Language.PureScript.CodeGen.Cpp.Optimizer.Inliner (
19− inlineVariables,
20− inlineValues,
21− inlineOperator,
22− inlineCommonOperators,
23− inlineFnComposition,
24− etaConvert,
25− unThunk,
26− evaluateIifes
27−) where
28−
29−#if __GLASGOW_HASKELL__ < 710
30−import Control.Applicative (Applicative)
31−#endif
32import Control.Monad.Supply.Class (MonadSupply, freshName)
28import Control.Monad.Supply.Class (MonadSupply, freshName)
33−import Language.PureScript.CodeGen.Cpp.Types
29+
34import Language.PureScript.CodeGen.Cpp.AST
30import Language.PureScript.CodeGen.Cpp.AST
35import Language.PureScript.CodeGen.Cpp.Common
31import Language.PureScript.CodeGen.Cpp.Common
36import Language.PureScript.CodeGen.Cpp.Optimizer.Common
32import Language.PureScript.CodeGen.Cpp.Optimizer.Common
33+import Language.PureScript.CodeGen.Cpp.Types
37import Language.PureScript.Names
34import Language.PureScript.Names
38import qualified Language.PureScript.Constants as C
35import qualified Language.PureScript.Constants as C
39
36
@@ -99,36 +96,34 @@ inlineVariables = everywhereOnCpp $ removeFromBlock go
99 go (map (replaceIdent var cpp) sts)
96 go (map (replaceIdent var cpp) sts)
100 go (s:sts) = s : go sts
97 go (s:sts) = s : go sts
101
98
102−inlineValues :: Cpp -> Cpp
99+inlineCommonValues :: Cpp -> Cpp
103−inlineValues = everywhereOnCpp convert
100+inlineCommonValues = everywhereOnCpp convert
104 where
101 where
105 convert :: Cpp -> Cpp
102 convert :: Cpp -> Cpp
106− convert (CppApp fn [dict]) | isDict semiringNumber dict && isFn fnZero fn = CppNumericLiteral (Left 0)
103+ convert (CppApp fn [dict])
107− | isDict semiringNumber dict && isFn fnOne fn = CppNumericLiteral (Left 1)
108− | isDict semiringInt dict && isFn fnZero fn = CppNumericLiteral (Left 0)
104+ | isDict' [semiringNumber, semiringInt] dict && isFn fnZero fn = CppNumericLiteral (Left 0)
109− | isDict semiringInt dict && isFn fnOne fn = CppNumericLiteral (Left 1)
105+ | isDict' [semiringNumber, semiringInt] dict && isFn fnOne fn = CppNumericLiteral (Left 1)
110− | isDict boundedBoolean dict && isFn fnBottom fn = CppBooleanLiteral False
106+ | isDict boundedBoolean dict && isFn fnBottom fn = CppBooleanLiteral False
111− | isDict boundedBoolean dict && isFn fnTop fn = CppBooleanLiteral True
107+ | isDict boundedBoolean dict && isFn fnTop fn = CppBooleanLiteral True
112 convert (CppApp fn [dict, x, y])
108 convert (CppApp fn [dict, x, y])
113 | isDict semiringInt dict && isFn fnAdd fn = CppBinary Add x y
109 | isDict semiringInt dict && isFn fnAdd fn = CppBinary Add x y
114 | isDict semiringInt dict && isFn fnMultiply fn = CppBinary Multiply x y
110 | isDict semiringInt dict && isFn fnMultiply fn = CppBinary Multiply x y
115− | isDict moduloSemiringInt dict && isFn fnDivide fn = CppBinary Divide x y
111+ | isDict euclideanRingInt dict && isFn fnDivide fn = CppBinary Divide x y
116 | isDict ringInt dict && isFn fnSubtract fn = CppBinary Subtract x y
112 | isDict ringInt dict && isFn fnSubtract fn = CppBinary Subtract x y
117 convert (CppApp (CppApp (CppApp fn [dict]) [x]) [y])
113 convert (CppApp (CppApp (CppApp fn [dict]) [x]) [y])
118 | isDict semiringInt dict && isFn fnAdd fn = CppBinary Add x y
114 | isDict semiringInt dict && isFn fnAdd fn = CppBinary Add x y
119 | isDict semiringInt dict && isFn fnMultiply fn = CppBinary Multiply x y
115 | isDict semiringInt dict && isFn fnMultiply fn = CppBinary Multiply x y
120− | isDict moduloSemiringInt dict && isFn fnDivide fn = CppBinary Divide x y
116+ | isDict euclideanRingInt dict && isFn fnDivide fn = CppBinary Divide x y
121 | isDict ringInt dict && isFn fnSubtract fn = CppBinary Subtract x y
117 | isDict ringInt dict && isFn fnSubtract fn = CppBinary Subtract x y
122−
123 convert other = other
118 convert other = other
124− fnZero = (C.prelude, C.zero)
119+ fnZero = (C.dataSemiring, C.zero)
125− fnOne = (C.prelude, C.one)
120+ fnOne = (C.dataSemiring, C.one)
126− fnBottom = (C.prelude, C.bottom)
121+ fnBottom = (C.dataBounded, C.bottom)
127− fnTop = (C.prelude, C.top)
122+ fnTop = (C.dataBounded, C.top)
128− fnAdd = (C.prelude, (C.+))
123+ fnAdd = (C.dataSemiring, C.add)
129− fnDivide = (C.prelude, (C./))
124+ fnDivide = (C.dataEuclideanRing, C.div)
130− fnMultiply = (C.prelude, (C.*))
125+ fnMultiply = (C.dataSemiring, C.mul)
131− fnSubtract = (C.prelude, (C.-))
126+ fnSubtract = (C.dataRing, C.sub)
132
127
133inlineOperator :: (String, String) -> (Cpp -> Cpp -> Cpp) -> Cpp -> Cpp
128inlineOperator :: (String, String) -> (Cpp -> Cpp -> Cpp) -> Cpp -> Cpp
134inlineOperator (m, op) f = everywhereOnCpp convert
129inlineOperator (m, op) f = everywhereOnCpp convert
@@ -137,49 +132,60 @@ inlineOperator (m, op) f = everywhereOnCpp convert
137 convert (CppApp op' [x, y]) | isOp op' = f x y
132 convert (CppApp op' [x, y]) | isOp op' = f x y
138 convert (CppApp (CppApp op' [x]) [y]) | isOp op' = f x y
133 convert (CppApp (CppApp op' [x]) [y]) | isOp op' = f x y
139 convert other = other
134 convert other = other
140− isOp (CppAccessor (CppVar longForm) (CppVar m')) = m == m' && longForm == identToCpp (Op op)
135+ isOp (CppAccessor (CppVar longForm) (CppVar m')) = m == m' && longForm == identToCpp (Ident op)
141 isOp (CppIndexer (CppStringLiteral op') (CppVar m')) = m == m' && op == op'
136 isOp (CppIndexer (CppStringLiteral op') (CppVar m')) = m == m' && op == op'
142 isOp _ = False
137 isOp _ = False
143
138
144inlineCommonOperators :: Cpp -> Cpp
139inlineCommonOperators :: Cpp -> Cpp
145inlineCommonOperators = applyAll $
140inlineCommonOperators = applyAll $
146− [ binary semiringNumber (C.+) Add
141+ [ binary semiringNumber opAdd Add
147− , binary semiringNumber (C.*) Multiply
142+ , binary semiringNumber opMul Multiply
148−
143+
149− , binary ringNumber (C.-) Subtract
144+ , binary ringNumber opSub Subtract
150− , unary ringNumber C.negate CppNegate
145+ , unary ringNumber opNegate Negate
151− , binary ringInt (C.-) Subtract
146+ , binary ringInt opSub Subtract
152− , unary ringInt C.negate CppNegate
147+ , unary ringInt opNegate Negate
153−
148+
154− , binary moduloSemiringNumber (C./) Divide
149+ , binary euclideanRingNumber opDiv Divide
155− , binary moduloSemiringInt C.mod Modulus
150+ , binary euclideanRingInt opMod Modulus
156−
151+
157− , binary eqNumber (C.==) Equal
152+ , binary eqNumber opEq EqualTo
158− , binary eqNumber (C./=) NotEqual
153+ , binary eqNumber opNotEq NotEqualTo
159− , binary eqInt (C.==) Equal
154+ , binary eqInt opEq EqualTo
160− , binary eqInt (C./=) NotEqual
155+ , binary eqInt opNotEq NotEqualTo
161− , binary eqString (C.==) Equal
156+ , binary eqString opEq EqualTo
162− , binary eqString (C./=) NotEqual
157+ , binary eqString opNotEq NotEqualTo
158+ , binary eqChar opEq EqualTo
159+ , binary eqChar opNotEq NotEqualTo
163− , binary eqBoolean (C.==) Equal
160+ , binary eqBoolean opEq EqualTo
164− , binary eqBoolean (C./=) NotEqual
161+ , binary eqBoolean opNotEq NotEqualTo
165−
162+
166− , binary ordNumber (C.<) LessThan
163+ , binary ordBoolean opLessThan LessThan
167− , binary ordNumber (C.>) GreaterThan
164+ , binary ordBoolean opLessThanOrEq LessThanOrEqualTo
168− , binary ordNumber (C.<=) LessThanOrEqual
165+ , binary ordBoolean opGreaterThan GreaterThan
169− , binary ordNumber (C.>=) GreaterThanOrEqual
166+ , binary ordBoolean opGreaterThanOrEq GreaterThanOrEqualTo
167+ , binary ordChar opLessThan LessThan
168+ , binary ordChar opLessThanOrEq LessThanOrEqualTo
169+ , binary ordChar opGreaterThan GreaterThan
170+ , binary ordChar opGreaterThanOrEq GreaterThanOrEqualTo
170− , binary ordInt (C.<) LessThan
171+ , binary ordInt opLessThan LessThan
171− , binary ordInt (C.>) GreaterThan
172+ , binary ordInt opLessThanOrEq LessThanOrEqualTo
172− , binary ordInt (C.<=) LessThanOrEqual
173+ , binary ordInt opGreaterThan GreaterThan
173− , binary ordInt (C.>=) GreaterThanOrEqual
174+ , binary ordInt opGreaterThanOrEq GreaterThanOrEqualTo
174−
175+ , binary ordNumber opLessThan LessThan
175− , binary semigroupString (C.<>) Add
176+ , binary ordNumber opLessThanOrEq LessThanOrEqualTo
176− , binary semigroupString (C.++) Add
177+ , binary ordNumber opGreaterThan GreaterThan
177−
178+ , binary ordNumber opGreaterThanOrEq GreaterThanOrEqualTo
178− , binary booleanAlgebraBoolean (C.&&) And
179+ , binary ordString opLessThan LessThan
179− , binary booleanAlgebraBoolean (C.||) Or
180+ , binary ordString opLessThanOrEq LessThanOrEqualTo
180− , binaryFunction booleanAlgebraBoolean C.conj And
181+ , binary ordString opGreaterThan GreaterThan
181− , binaryFunction booleanAlgebraBoolean C.disj Or
182+ , binary ordString opGreaterThanOrEq GreaterThanOrEqualTo
182− , unary booleanAlgebraBoolean C.not CppNot
183+
184+ , binary semigroupString opAppend Add
185+
186+ , binary heytingAlgebraBoolean opConj And
187+ , binary heytingAlgebraBoolean opDisj Or
188+ , unary heytingAlgebraBoolean opNot Not
183
189
184 , binary' C.dataIntBits (C..|.) BitwiseOr
190 , binary' C.dataIntBits (C..|.) BitwiseOr
185 , binary' C.dataIntBits (C..&.) BitwiseAnd
191 , binary' C.dataIntBits (C..&.) BitwiseAnd
@@ -187,43 +193,33 @@ inlineCommonOperators = applyAll $
187 , binary' C.dataIntBits C.shl ShiftLeft
193 , binary' C.dataIntBits C.shl ShiftLeft
188 , binary' C.dataIntBits C.shr ShiftRight
194 , binary' C.dataIntBits C.shr ShiftRight
189 -- , binary' C.dataIntBits C.zshr ZeroFillShiftRight
195 -- , binary' C.dataIntBits C.zshr ZeroFillShiftRight
190− , unary' C.dataIntBits C.complement CppBitwiseNot
196+ , unary' C.dataIntBits C.complement BitwiseNot
191− ] -- ++ -- DISABLE mkFn/runFn inlining
197+ ] ++
198+ []
192 -- [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
199 -- [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
193 where
200 where
194− binary :: (String, String) -> String -> BinaryOp -> Cpp -> Cpp
201+ binary :: (String, String) -> (String, String) -> BinaryOperator -> Cpp -> Cpp
195− binary dict opString op = everywhereOnCpp convert
202+ binary dict fns op = everywhereOnCpp convert
196 where
203 where
197 convert :: Cpp -> Cpp
204 convert :: Cpp -> Cpp
198− convert (CppApp fn [dict', CppStringLiteral x, CppStringLiteral y])
199− | isDict dict dict' && isPreludeFn opString fn = CppStringLiteral (x ++ y)
200− convert (CppApp fn [dict', x, y]) | isDict dict dict' && isPreludeFn opString fn = CppBinary op x y
205+ convert (CppApp fn [dict', x, y]) | isDict dict dict' && isFn fns fn = CppBinary op x y
201− convert (CppApp (CppApp (CppApp fn [dict']) [CppStringLiteral x]) [CppStringLiteral y])
206+ convert (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) | isDict dict dict' && isFn fns fn = CppBinary op x y
202− | isDict dict dict' && isPreludeFn opString fn = CppStringLiteral (x ++ y)
203− convert (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) | isDict dict dict' && isPreludeFn opString fn = CppBinary op x y
204 convert other = other
207 convert other = other
205− binary' :: String -> String -> BinaryOp -> Cpp -> Cpp
208+ binary' :: String -> String -> BinaryOperator -> Cpp -> Cpp
206 binary' moduleName opString op = everywhereOnCpp convert
209 binary' moduleName opString op = everywhereOnCpp convert
207 where
210 where
208 convert :: Cpp -> Cpp
211 convert :: Cpp -> Cpp
209 convert (CppApp fn [x, y]) | isFn (moduleName, opString) fn = CppBinary op x y
212 convert (CppApp fn [x, y]) | isFn (moduleName, opString) fn = CppBinary op x y
210 convert (CppApp (CppApp fn [x]) [y]) | isFn (moduleName, opString) fn = CppBinary op x y
213 convert (CppApp (CppApp fn [x]) [y]) | isFn (moduleName, opString) fn = CppBinary op x y
211 convert other = other
214 convert other = other
212− binaryFunction :: (String, String) -> String -> BinaryOp -> Cpp -> Cpp
215+ unary :: (String, String) -> (String, String) -> UnaryOperator -> Cpp -> Cpp
213− binaryFunction dict fnName op = everywhereOnCpp convert
216+ unary dicts fns op = everywhereOnCpp convert
214 where
217 where
215 convert :: Cpp -> Cpp
218 convert :: Cpp -> Cpp
216− convert (CppApp fn [dict', x, y]) | isPreludeFn fnName fn && isDict dict dict' = CppBinary op x y
219+ convert (CppApp fn [dict', x]) | isDict dicts dict' && isFn fns fn = CppUnary op x
217− convert (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) | isPreludeFn fnName fn && isDict dict dict' = CppBinary op x y
220+ convert (CppApp (CppApp fn [dict']) [x]) | isDict dicts dict' && isFn fns fn = CppUnary op x
218 convert other = other
221 convert other = other
219− unary :: (String, String) -> String -> CppUnaryOp -> Cpp -> Cpp
220− unary dict fnName op = everywhereOnCpp convert
221− where
222− convert :: Cpp -> Cpp
223− convert (CppApp fn [dict', x]) | isPreludeFn fnName fn && isDict dict dict' = CppUnary op x
224− convert (CppApp (CppApp fn [dict']) [x]) | isPreludeFn fnName fn && isDict dict dict' = CppUnary op x
225− convert other = other
226− unary' :: String -> String -> CppUnaryOp -> Cpp -> Cpp
222+ unary' :: String -> String -> UnaryOperator -> Cpp -> Cpp
227 unary' moduleName fnName op = everywhereOnCpp convert
223 unary' moduleName fnName op = everywhereOnCpp convert
228 where
224 where
229 convert :: Cpp -> Cpp
225 convert :: Cpp -> Cpp
@@ -233,8 +229,8 @@ inlineCommonOperators = applyAll $
233 -- mkFn 0 = everywhereOnCpp convert
229 -- mkFn 0 = everywhereOnCpp convert
234 -- where
230 -- where
235 -- convert :: Cpp -> Cpp
231 -- convert :: Cpp -> Cpp
236− -- convert (CppApp mkFnN [CppLambda caps [_] _ (CppBlock cpp)]) | isNFn C.mkFn 0 mkFnN =
232+ -- convert (CppApp mkFnN [CppLambda _ [_] _ (CppBlock cpp)]) | isNFn C.mkFn 0 mkFnN =
237− -- CppLambda caps [] Nothing (CppBlock cpp)
233+ -- CppLambda [CppCaptureAll] [] Nothing (CppBlock cpp)
238 -- convert other = other
234 -- convert other = other
239 -- mkFn n = everywhereOnCpp convert
235 -- mkFn n = everywhereOnCpp convert
240 -- where
236 -- where
@@ -244,14 +240,14 @@ inlineCommonOperators = applyAll $
244 -- Just (args, cpp) -> CppLambda [CppCaptureAll] args Nothing (CppBlock cpp)
240 -- Just (args, cpp) -> CppLambda [CppCaptureAll] args Nothing (CppBlock cpp)
245 -- Nothing -> orig
241 -- Nothing -> orig
246 -- convert other = other
242 -- convert other = other
247− -- collectArgs :: Int -> [(String, Maybe CppType)] -> Cpp -> Maybe ([(String, Maybe CppType)], [Cpp])
243+ -- collectArgs :: Int -> [String] -> Cpp -> Maybe ([String], [Cpp])
248 -- collectArgs 1 acc (CppLambda _ [oneArg] _ (CppBlock cpp)) | length acc == n - 1 = Just (reverse (oneArg : acc), cpp)
244 -- collectArgs 1 acc (CppLambda _ [oneArg] _ (CppBlock cpp)) | length acc == n - 1 = Just (reverse (oneArg : acc), cpp)
249 -- collectArgs m acc (CppLambda _ [oneArg] _ (CppBlock [CppReturn ret])) = collectArgs (m - 1) (oneArg : acc) ret
245 -- collectArgs m acc (CppLambda _ [oneArg] _ (CppBlock [CppReturn ret])) = collectArgs (m - 1) (oneArg : acc) ret
250 -- collectArgs _ _ _ = Nothing
246 -- collectArgs _ _ _ = Nothing
251 --
247 --
252 -- isNFn :: String -> Int -> Cpp -> Bool
248 -- isNFn :: String -> Int -> Cpp -> Bool
253 -- isNFn prefix n (CppVar name) = name == (prefix ++ show n)
249 -- isNFn prefix n (CppVar name) = name == (prefix ++ show n)
254− -- isNFn prefix n (CppAccessor (CppVar name) (CppVar dataFunction)) | dataFunction == C.dataFunction = name == (prefix ++ show n)
250+ -- isNFn prefix n (CppAccessor _ name (CppVar dataFunction)) | dataFunction == C.dataFunction = name == (prefix ++ show n)
255 -- isNFn _ _ _ = False
251 -- isNFn _ _ _ = False
256 --
252 --
257 -- runFn :: Int -> Cpp -> Cpp
253 -- runFn :: Int -> Cpp -> Cpp
@@ -267,78 +263,137 @@ inlineCommonOperators = applyAll $
267
263
268-- (f <<< g $ x) = f (g x)
264-- (f <<< g $ x) = f (g x)
269-- (f <<< g) = \x -> f (g x)
265-- (f <<< g) = \x -> f (g x)
270−inlineFnComposition :: (Applicative m, MonadSupply m) => Cpp -> m Cpp
266+inlineFnComposition :: (MonadSupply m) => Cpp -> m Cpp
271inlineFnComposition = everywhereOnCppTopDownM convert
267inlineFnComposition = everywhereOnCppTopDownM convert
272 where
268 where
273 convert :: (MonadSupply m) => Cpp -> m Cpp
269 convert :: (MonadSupply m) => Cpp -> m Cpp
274− convert (CppApp fn [dict', x, y]) | isFnCompose dict' fn = do
270+ convert (CppApp fn [dict', x, y, z])
275− arg <- freshName
271+ | isFnCompose dict' fn = return $ CppApp x [CppApp y [z]]
276− return $ CppLambda [CppCaptureAll] [(arg, Just (CppAny [CppConst, CppRef]))] (Just $ CppAny []) (CppBlock [CppReturn $ CppApp x [CppApp y [CppVar arg]]])
272+ | isFnComposeFlipped dict' fn = return $ CppApp y [CppApp x [z]]
277− convert (CppApp (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) [z]) | isFnCompose dict' fn =
273+ convert (CppApp (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) [z])
278− return $ CppApp x [CppApp y [z]]
274+ | isFnCompose dict' fn = return $ CppApp x [CppApp y [z]]
275+ | isFnComposeFlipped dict' fn = return $ CppApp y [CppApp x [z]]
276+ convert (CppApp fn [dict', x, y])
279− convert (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) | isFnCompose dict' fn = do
277+ | isFnCompose dict' fn = do
280− arg <- freshName
278+ arg <- freshName
281− return $ CppLambda [CppCaptureAll] [(arg, Just (CppAny [CppConst, CppRef]))] (Just $ CppAny []) (CppBlock [CppReturn $ CppApp x [CppApp y [CppVar arg]]])
279+ return $ CppLambda [CppCaptureAll] [(arg, constAnyRef)] Nothing (CppBlock [CppReturn $ CppApp x [CppApp y [CppVar arg]]])
280+ | isFnComposeFlipped dict' fn = do
281+ arg <- freshName
282+ return $ CppLambda [CppCaptureAll] [(arg, constAnyRef)] Nothing (CppBlock [CppReturn $ CppApp y [CppApp x [CppVar arg]]])
282 convert other = return other
283 convert other = return other
283 isFnCompose :: Cpp -> Cpp -> Bool
284 isFnCompose :: Cpp -> Cpp -> Bool
284− isFnCompose dict' fn = isDict semigroupoidFn dict' && (isPreludeFn (C.<<<) fn || isPreludeFn (C.compose) fn)
285+ isFnCompose dict' fn = isDict semigroupoidFn dict' && isFn fnCompose fn
285−
286+ isFnComposeFlipped :: Cpp -> Cpp -> Bool
287+ isFnComposeFlipped dict' fn = isDict semigroupoidFn dict' && isFn fnComposeFlipped fn
288+ fnCompose :: (String, String)
289+ fnCompose = (C.controlSemigroupoid, C.compose)
286−isDict :: (String, String) -> Cpp -> Bool
290+ fnComposeFlipped :: (String, String)
287−isDict (moduleName, dictName) (CppAccessor (CppVar x) (CppVar y)) = x == dictName && y == moduleName
291+ fnComposeFlipped = (C.controlSemigroupoid, C.composeFlipped)
288−isDict _ _ = False
289−
290−isFn :: (String, String) -> Cpp -> Bool
291−isFn (moduleName, fnName) (CppAccessor (CppVar x) (CppVar y)) = x == (identToCpp (Ident fnName)) && y == moduleName
292−isFn (moduleName, fnName) (CppIndexer (CppStringLiteral x) (CppVar y)) = x == fnName && y == moduleName
293−isFn _ _ = False
294−
295−isPreludeFn :: String -> Cpp -> Bool
296−isPreludeFn fnName = isFn (C.prelude, fnName)
297
292
298semiringNumber :: (String, String)
293semiringNumber :: (String, String)
299−semiringNumber = (C.prelude, C.semiringNumber)
294+semiringNumber = (C.dataSemiring, C.semiringNumber)
300
295
301semiringInt :: (String, String)
296semiringInt :: (String, String)
302−semiringInt = (C.prelude, C.semiringInt)
297+semiringInt = (C.dataSemiring, C.semiringInt)
303
298
304ringNumber :: (String, String)
299ringNumber :: (String, String)
305−ringNumber = (C.prelude, C.ringNumber)
300+ringNumber = (C.dataRing, C.ringNumber)
306
301
307ringInt :: (String, String)
302ringInt :: (String, String)
308−ringInt = (C.prelude, C.ringInt)
303+ringInt = (C.dataRing, C.ringInt)
309
304
310−moduloSemiringNumber :: (String, String)
305+euclideanRingNumber :: (String, String)
311−moduloSemiringNumber = (C.prelude, C.moduloSemiringNumber)
306+euclideanRingNumber = (C.dataEuclideanRing, C.euclideanRingNumber)
312
307
313−moduloSemiringInt :: (String, String)
308+euclideanRingInt :: (String, String)
314−moduloSemiringInt = (C.prelude, C.moduloSemiringInt)
309+euclideanRingInt = (C.dataEuclideanRing, C.euclideanRingInt)
315
310
316eqNumber :: (String, String)
311eqNumber :: (String, String)
317−eqNumber = (C.prelude, C.eqNumber)
312+eqNumber = (C.dataEq, C.eqNumber)
318
313
319eqInt :: (String, String)
314eqInt :: (String, String)
320−eqInt = (C.prelude, C.eqInt)
315+eqInt = (C.dataEq, C.eqInt)
321
316
322eqString :: (String, String)
317eqString :: (String, String)
323−eqString = (C.prelude, C.eqNumber)
318+eqString = (C.dataEq, C.eqString)
319+
320+eqChar :: (String, String)
321+eqChar = (C.dataEq, C.eqChar)
324
322
325eqBoolean :: (String, String)
323eqBoolean :: (String, String)
326−eqBoolean = (C.prelude, C.eqNumber)
324+eqBoolean = (C.dataEq, C.eqBoolean)
325+
326+ordBoolean :: (String, String)
327+ordBoolean = (C.dataOrd, C.ordBoolean)
327
328
328ordNumber :: (String, String)
329ordNumber :: (String, String)
329−ordNumber = (C.prelude, C.ordNumber)
330+ordNumber = (C.dataOrd, C.ordNumber)
330
331
331ordInt :: (String, String)
332ordInt :: (String, String)
332−ordInt = (C.prelude, C.ordInt)
333+ordInt = (C.dataOrd, C.ordInt)
334+
335+ordString :: (String, String)
336+ordString = (C.dataOrd, C.ordString)
337+
338+ordChar :: (String, String)
339+ordChar = (C.dataOrd, C.ordChar)
333
340
334semigroupString :: (String, String)
341semigroupString :: (String, String)
335−semigroupString = (C.prelude, C.semigroupString)
342+semigroupString = (C.dataSemigroup, C.semigroupString)
336
343
337boundedBoolean :: (String, String)
344boundedBoolean :: (String, String)
338−boundedBoolean = (C.prelude, C.boundedBoolean)
345+boundedBoolean = (C.dataBounded, C.boundedBoolean)
339
346
340−booleanAlgebraBoolean :: (String, String)
347+heytingAlgebraBoolean :: (String, String)
341−booleanAlgebraBoolean = (C.prelude, C.booleanAlgebraBoolean)
348+heytingAlgebraBoolean = (C.dataHeytingAlgebra, C.heytingAlgebraBoolean)
342
349
343semigroupoidFn :: (String, String)
350semigroupoidFn :: (String, String)
344−semigroupoidFn = (C.prelude, C.semigroupoidFn)
351+semigroupoidFn = (C.controlSemigroupoid, C.semigroupoidFn)
352+
353+opAdd :: (String, String)
354+opAdd = (C.dataSemiring, C.add)
355+
356+opMul :: (String, String)
357+opMul = (C.dataSemiring, C.mul)
358+
359+opEq :: (String, String)
360+opEq = (C.dataEq, C.eq)
361+
362+opNotEq :: (String, String)
363+opNotEq = (C.dataEq, C.notEq)
364+
365+opLessThan :: (String, String)
366+opLessThan = (C.dataOrd, C.lessThan)
367+
368+opLessThanOrEq :: (String, String)
369+opLessThanOrEq = (C.dataOrd, C.lessThanOrEq)
370+
371+opGreaterThan :: (String, String)
372+opGreaterThan = (C.dataOrd, C.greaterThan)
373+
374+opGreaterThanOrEq :: (String, String)
375+opGreaterThanOrEq = (C.dataOrd, C.greaterThanOrEq)
376+
377+opAppend :: (String, String)
378+opAppend = (C.dataSemigroup, C.append)
379+
380+opSub :: (String, String)
381+opSub = (C.dataRing, C.sub)
382+
383+opNegate :: (String, String)
384+opNegate = (C.dataRing, C.negate)
385+
386+opDiv :: (String, String)
387+opDiv = (C.dataEuclideanRing, C.div)
388+
389+opMod :: (String, String)
390+opMod = (C.dataEuclideanRing, C.mod)
391+
392+opConj :: (String, String)
393+opConj = (C.dataHeytingAlgebra, C.conj)
394+
395+opDisj :: (String, String)
396+opDisj = (C.dataHeytingAlgebra, C.disj)
397+
398+opNot :: (String, String)
399+opNot = (C.dataHeytingAlgebra, C.not)
src/Language/PureScript/CodeGen/Cpp/Optimizer/MagicDo.hs+77−42
@@ -13,21 +13,22 @@
13-- and bind for the Eff monad, as well as some of its actions.
13-- and bind for the Eff monad, as well as some of its actions.
14--
14--
15-----------------------------------------------------------------------------
15-----------------------------------------------------------------------------
16+module Language.PureScript.CodeGen.Cpp.Optimizer.MagicDo (magicDo) where
16
17
17−module Language.PureScript.CodeGen.Cpp.Optimizer.MagicDo (
18+import Prelude.Compat
18− magicDo
19+
19−) where
20+import Data.List (nub)
21+import Data.Maybe (fromJust, isJust)
20
22
21import Language.PureScript.CodeGen.Cpp.AST
23import Language.PureScript.CodeGen.Cpp.AST
22−import Language.PureScript.CodeGen.Cpp.Common
24+import Language.PureScript.CodeGen.Cpp.Optimizer.Common
23import Language.PureScript.CodeGen.Cpp.Types
25import Language.PureScript.CodeGen.Cpp.Types
24−import Language.PureScript.Names
25import Language.PureScript.Options
26import Language.PureScript.Options
26import qualified Language.PureScript.Constants as C
27import qualified Language.PureScript.Constants as C
27
28
28magicDo :: Options -> Cpp -> Cpp
29magicDo :: Options -> Cpp -> Cpp
29magicDo opts | optionsNoMagicDo opts = id
30magicDo opts | optionsNoMagicDo opts = id
30− | otherwise = magicDo'
31+ | otherwise = {- inlineST . -} magicDo' -- TODO: fix and test with Collatz.purs
31
32
32-- |
33-- |
33-- Inline type class dictionaries for >>= and return for the Eff monad
34-- Inline type class dictionaries for >>= and return for the Eff monad
@@ -52,59 +53,48 @@ magicDo' = everywhereOnCpp undo . everywhereOnCppTopDown convert
52 fnName = "__do"
53 fnName = "__do"
53 -- Desugar monomorphic calls to >>= and return for the Eff monad
54 -- Desugar monomorphic calls to >>= and return for the Eff monad
54 convert :: Cpp -> Cpp
55 convert :: Cpp -> Cpp
55− -- Desugar return
56+ -- Desugar pure & return
56− convert (CppApp (CppApp ret [effDict, val]) []) | isRetPoly ret && isEffDict C.monadEffDictionary effDict = val
57+ convert (CppApp (CppApp pure' [dict, val]) []) | isPure (CppApp pure' [dict]) = val
57− convert (CppApp (CppApp ret [val]) []) | isReturn ret = val
58− -- Desugar pure
59− convert (CppApp (CppApp pure' [effDict, val]) []) | isPurePoly pure' && isEffDict C.applicativeEffDictionary effDict = val
60 convert (CppApp (CppApp pure' [val]) []) | isPure pure' = val
58 convert (CppApp (CppApp pure' [val]) []) | isPure pure' = val
61 -- Desugar >>
59 -- Desugar >>
62− convert (CppApp bind [effDict, m, CppLambda _ [] rty (CppBlock cpp)]) | isBindPoly bind && isEffDict C.bindEffDictionary effDict =
60+ convert (CppApp bind [dict, m, CppLambda _ [] rty (CppBlock cpp)]) | isBind (CppApp bind [dict]) =
63 CppFunction fnName [] rty [] $ CppBlock (CppApp m [] : map applyReturns cpp )
61 CppFunction fnName [] rty [] $ CppBlock (CppApp m [] : map applyReturns cpp )
64 convert (CppApp (CppApp bind [m]) [CppLambda _ [] rty (CppBlock cpp)]) | isBind bind =
62 convert (CppApp (CppApp bind [m]) [CppLambda _ [] rty (CppBlock cpp)]) | isBind bind =
65 CppFunction fnName [] rty [] $ CppBlock (CppApp m [] : map applyReturns cpp )
63 CppFunction fnName [] rty [] $ CppBlock (CppApp m [] : map applyReturns cpp )
66 -- Desugar >>=
64 -- Desugar >>=
67− convert (CppApp bind [effDict, m, CppLambda _ [arg] rty (CppBlock cpp)]) | isBindPoly bind && isEffDict C.bindEffDictionary effDict =
65+ convert (CppApp bind [dict, m, CppLambda _ [arg] rty (CppBlock cpp)]) | isBind (CppApp bind [dict]) =
68− CppFunction fnName [] rty [] $ CppBlock (CppVariableIntroduction arg [] (Just (CppApp m [])) : map applyReturns cpp)
66+ CppFunction fnName [] rty [] $ CppBlock (app' : map applyReturns cpp)
67+ where
68+ app' | fst arg == C.__unused = CppApp m []
69+ | otherwise = CppVariableIntroduction arg [] (Just (CppApp m []))
69 convert (CppApp (CppApp bind [m]) [CppLambda _ [arg] rty (CppBlock cpp)]) | isBind bind =
70 convert (CppApp (CppApp bind [m]) [CppLambda _ [arg] rty (CppBlock cpp)]) | isBind bind =
70− CppFunction fnName [] rty [] $ CppBlock (CppVariableIntroduction arg [] (Just (CppApp m [])) : map applyReturns cpp)
71+ CppFunction fnName [] rty [] $ CppBlock (app' : map applyReturns cpp)
72+ where
73+ app' | fst arg == C.__unused = CppApp m []
74+ | otherwise = CppVariableIntroduction arg [] (Just (CppApp m []))
71 -- Desugar untilE
75 -- Desugar untilE
72 convert (CppApp (CppApp f [arg]) []) | isEffFunc C.untilE f =
76 convert (CppApp (CppApp f [arg]) []) | isEffFunc C.untilE f =
73− CppApp (CppLambda [CppCaptureAll] [] (Just $ CppAny []) (CppBlock [ CppWhile (CppUnary CppNot (CppApp arg [])) (CppBlock []), CppReturn $ CppObjectLiteral []])) []
77+ CppApp (CppLambda [CppCaptureAll] [] Nothing (CppBlock [ CppWhile (CppUnary Not (CppApp arg [])) (CppBlock []), CppReturn $ CppObjectLiteral CppRecord []])) []
74 -- Desugar whileE
78 -- Desugar whileE
75 convert (CppApp (CppApp f [arg1, arg2]) []) | isEffFunc C.whileE f =
79 convert (CppApp (CppApp f [arg1, arg2]) []) | isEffFunc C.whileE f =
76− CppApp (CppLambda [CppCaptureAll] [] (Just $ CppAny []) (CppBlock [ CppWhile (CppApp arg1 []) (CppBlock [ CppApp arg2 [] ]), CppReturn $ CppObjectLiteral []])) []
80+ CppApp (CppLambda [CppCaptureAll] [] Nothing (CppBlock [ CppWhile (CppApp arg1 []) (CppBlock [ CppApp arg2 [] ]), CppReturn $ CppObjectLiteral CppRecord []])) []
77 convert (CppApp (CppApp (CppApp f [arg1]) [arg2]) []) | isEffFunc C.whileE f =
81 convert (CppApp (CppApp (CppApp f [arg1]) [arg2]) []) | isEffFunc C.whileE f =
78− CppApp (CppLambda [CppCaptureAll] [] (Just $ CppAny []) (CppBlock [ CppWhile (CppApp arg1 []) (CppBlock [ CppApp arg2 [] ]), CppReturn $ CppObjectLiteral []])) []
82+ CppApp (CppLambda [CppCaptureAll] [] Nothing (CppBlock [ CppWhile (CppApp arg1 []) (CppBlock [ CppApp arg2 [] ]), CppReturn $ CppObjectLiteral CppRecord []])) []
79 convert other = other
83 convert other = other
80 -- Check if an expression represents a monomorphic call to >>= for the Eff monad
84 -- Check if an expression represents a monomorphic call to >>= for the Eff monad
81− isBind (CppApp bindPoly [effDict]) | isBindPoly bindPoly && isEffDict C.bindEffDictionary effDict = True
85+ isBind (CppApp fn [dict]) | isDict (C.eff, C.bindEffDictionary) dict && isBindPoly fn = True
82 isBind _ = False
86 isBind _ = False
83− -- Check if an expression represents a monomorphic call to return for the Eff monad
87+ -- Check if an expression represents a monomorphic call to pure or return for the Eff applicative
84− isReturn (CppApp retPoly [effDict]) | isRetPoly retPoly && isEffDict C.monadEffDictionary effDict = True
85− isReturn _ = False
86− -- Check if an expression represents a monomorphic call to pure for the Eff applicative
87− isPure (CppApp purePoly [effDict]) | isPurePoly purePoly && isEffDict C.applicativeEffDictionary effDict = True
88+ isPure (CppApp fn [dict]) | isDict (C.eff, C.applicativeEffDictionary) dict && isPurePoly fn = True
88 isPure _ = False
89 isPure _ = False
89 -- Check if an expression represents the polymorphic >>= function
90 -- Check if an expression represents the polymorphic >>= function
90− isBindPoly (CppAccessor (CppVar prop) (CppVar prelude)) = prelude == C.prelude && (prop `elem` map identToCpp [Ident C.bind, Op (C.>>=)])
91+ isBindPoly = isFn (C.controlBind, C.bind)
91− isBindPoly (CppIndexer (CppStringLiteral bind) (CppVar prelude)) = prelude == C.prelude && (bind `elem` [C.bind, (C.>>=)])
92− isBindPoly _ = False
93− -- Check if an expression represents the polymorphic return function
92+ -- Check if an expression represents the polymorphic pure or return function
94− isRetPoly (CppAccessor (CppVar returnEscaped) (CppVar prelude)) = prelude == C.prelude && returnEscaped == C.returnEscaped
93+ isPurePoly = isFn (C.controlApplicative, C.pure')
95− isRetPoly (CppIndexer (CppStringLiteral return') (CppVar prelude)) = prelude == C.prelude && return' == C.return
96− isRetPoly _ = False
97− -- Check if an expression represents the polymorphic pure function
98− isPurePoly (CppAccessor (CppVar pure') (CppVar prelude)) = prelude == C.prelude && pure' == C.pure'
99− isPurePoly (CppIndexer (CppStringLiteral pure') (CppVar prelude)) = prelude == C.prelude && pure' == C.pure'
100− isPurePoly _ = False
101− -- Check if an expression represents a function in the Ef module
94+ -- Check if an expression represents a function in the Eff module
102 isEffFunc name (CppAccessor (CppVar name') (CppVar eff)) = eff == C.eff && name == name'
95 isEffFunc name (CppAccessor (CppVar name') (CppVar eff)) = eff == C.eff && name == name'
103 isEffFunc _ _ = False
96 isEffFunc _ _ = False
104− -- Check if an expression represents the Monad Eff dictionary
97+
105− isEffDict name (CppVar ident) | ident == name = True
106− isEffDict name (CppAccessor (CppVar prop) (CppVar eff)) = eff == C.eff && prop == name
107− isEffDict _ _ = False
108 -- Remove __do function applications which remain after desugaring
98 -- Remove __do function applications which remain after desugaring
109 undo :: Cpp -> Cpp
99 undo :: Cpp -> Cpp
110 undo (CppReturn (CppApp (CppFunction ident [] _ _ body) [])) | ident == fnName = body
100 undo (CppReturn (CppApp (CppFunction ident [] _ _ body) [])) | ident == fnName = body
@@ -121,5 +111,50 @@ magicDo' = everywhereOnCpp undo . everywhereOnCppTopDown convert
121-- |
111-- |
122-- Inline functions in the ST module
112-- Inline functions in the ST module
123--
113--
124−-- TODO: various issues in C++ backend -- revisit later
114+inlineST :: Cpp -> Cpp
125−--
115+inlineST = everywhereOnCpp convertBlock
116+ where
117+ -- Look for runST blocks and inline the STRefs there.
118+ -- If all STRefs are used in the scope of the same runST, only using { read, write, modify }STRef then
119+ -- we can be more aggressive about inlining, and actually turn STRefs into local variables.
120+ convertBlock (CppApp f [arg]) | isSTFunc C.runST f =
121+ let refs = nub . findSTRefsIn $ arg
122+ usages = findAllSTUsagesIn arg
123+ allUsagesAreLocalVars = all (\u -> let v = toVar u in isJust v && fromJust v `elem` refs) usages
124+ localVarsDoNotEscape = all (\r -> length (r `appearingIn` arg) == length (filter (\u -> let v = toVar u in v == Just r) usages)) refs
125+ in everywhereOnCpp (convert (allUsagesAreLocalVars && localVarsDoNotEscape)) arg
126+ convertBlock other = other
127+ -- Convert a block in a safe way, preserving object wrappers of references,
128+ -- or in a more aggressive way, turning wrappers into local variables depending on the
129+ -- agg(ressive) parameter.
130+ convert agg (CppApp f [arg]) | isSTFunc C.newSTRef f =
131+ CppLambda [CppCaptureAll] [] Nothing (CppBlock [CppReturn $ if agg then arg else CppObjectLiteral CppRecord [(C.stRefValue, arg)]])
132+ convert agg (CppApp (CppApp f [ref]) []) | isSTFunc C.readSTRef f =
133+ if agg then ref else CppAccessor (CppVar C.stRefValue) ref
134+ convert agg (CppApp (CppApp (CppApp f [ref]) [arg]) []) | isSTFunc C.writeSTRef f =
135+ if agg then CppAssignment ref arg else CppAssignment (CppAccessor (CppVar C.stRefValue) ref) arg
136+ convert agg (CppApp (CppApp (CppApp f [ref]) [func]) []) | isSTFunc C.modifySTRef f =
137+ if agg then CppAssignment ref (CppApp func [ref]) else CppAssignment (CppAccessor (CppVar C.stRefValue) ref) (CppApp func [CppAccessor (CppVar C.stRefValue) ref])
138+ convert _ other = other
139+ -- Check if an expression represents a function in the ST module
140+ isSTFunc name (CppAccessor (CppVar name') (CppVar st)) = st == C.st && name == name'
141+ isSTFunc _ _ = False
142+ -- Find all ST Refs initialized in this block
143+ findSTRefsIn = everythingOnCpp (++) isSTRef
144+ where
145+ isSTRef (CppVariableIntroduction (ident, _) _ (Just (CppApp (CppApp f [_]) []))) | isSTFunc C.newSTRef f = [ident]
146+ isSTRef _ = []
147+ -- Find all STRefs used as arguments to readSTRef, writeSTRef, modifySTRef
148+ findAllSTUsagesIn = everythingOnCpp (++) isSTUsage
149+ where
150+ isSTUsage (CppApp (CppApp f [ref]) []) | isSTFunc C.readSTRef f = [ref]
151+ isSTUsage (CppApp (CppApp (CppApp f [ref]) [_]) []) | isSTFunc C.writeSTRef f || isSTFunc C.modifySTRef f = [ref]
152+ isSTUsage _ = []
153+ -- Find all uses of a variable
154+ appearingIn ref = everythingOnCpp (++) isVar
155+ where
156+ isVar e@(CppVar v) | v == ref = [e]
157+ isVar _ = []
158+ -- Convert a Cpp value to a String if it is a CppVar
159+ toVar (CppVar v) = Just v
160+ toVar _ = Nothing
src/Language/PureScript/CodeGen/Cpp/Optimizer/TCO.hs+2
@@ -15,6 +15,8 @@
15
15
16module Language.PureScript.CodeGen.Cpp.Optimizer.TCO (tco) where
16module Language.PureScript.CodeGen.Cpp.Optimizer.TCO (tco) where
17
17
18+import Prelude.Compat
19+
18import Data.List
20import Data.List
19import Data.Monoid
21import Data.Monoid
20
22
src/Language/PureScript/CodeGen/Cpp/Optimizer/Unused.hs+2
@@ -15,6 +15,8 @@
15
15
16module Language.PureScript.CodeGen.Cpp.Optimizer.Unused where
16module Language.PureScript.CodeGen.Cpp.Optimizer.Unused where
17
17
18+import Prelude.Compat
19+
18import Language.PureScript.CodeGen.Cpp.AST
20import Language.PureScript.CodeGen.Cpp.AST
19import Language.PureScript.CodeGen.Cpp.Optimizer.Common
21import Language.PureScript.CodeGen.Cpp.Optimizer.Common
20
22
src/Language/PureScript/CodeGen/Cpp/Types.hs+12−1
@@ -18,6 +18,8 @@
18
18
19module Language.PureScript.CodeGen.Cpp.Types where
19module Language.PureScript.CodeGen.Cpp.Types where
20
20
21+import Prelude.Compat
22+
21import Data.List
23import Data.List
22
24
23import Language.PureScript.CodeGen.Cpp.Common
25import Language.PureScript.CodeGen.Cpp.Common
@@ -68,6 +70,12 @@ data CppValueQual
68data CppCaptureType = CppCaptureAll
70data CppCaptureType = CppCaptureAll
69 deriving (Show, Read, Eq)
71 deriving (Show, Read, Eq)
70
72
73+-- |
74+-- C++ object/map literal type
75+--
76+data CppObjectType = CppInstance | CppRecord
77+ deriving (Show, Eq)
78+
71runType :: CppType -> String
79runType :: CppType -> String
72runType (CppPrimitive t) = t
80runType (CppPrimitive t) = t
73runType CppAuto = "auto"
81runType CppAuto = "auto"
@@ -98,7 +106,7 @@ boolType :: CppType
98boolType = CppPrimitive "bool"
106boolType = CppPrimitive "bool"
99
107
100intType :: CppType
108intType :: CppType
101−intType = CppPrimitive "integer"
109+intType = CppPrimitive "int"
102
110
103doubleType :: CppType
111doubleType :: CppType
104doubleType = CppPrimitive "double"
112doubleType = CppPrimitive "double"
@@ -123,3 +131,6 @@ thunkMarkerType = CppPrimitive "any::as_thunk"
123
131
124ctorKey :: String
132ctorKey :: String
125ctorKey = "constructor"
133ctorKey = "constructor"
134+
135+constAnyRef :: Maybe CppType
136+constAnyRef = Just $ CppAny [CppConst, CppRef]
src/Language/PureScript/CodeGen/JS.hs+20−23
@@ -1,8 +1,3 @@
1−{-# LANGUAGE GADTs #-}
2−{-# LANGUAGE ViewPatterns #-}
3−{-# LANGUAGE FlexibleContexts #-}
4−{-# LANGUAGE ScopedTypeVariables #-}
5−
6-- |
1-- |
7-- This module generates code in the simplified Javascript intermediate representation from Purescript code
2-- This module generates code in the simplified Javascript intermediate representation from Purescript code
8--
3--
@@ -12,29 +7,30 @@ module Language.PureScript.CodeGen.JS
12 , moduleToJs
7 , moduleToJs
13 ) where
8 ) where
14
9
15−import Prelude ()
16import Prelude.Compat
10import Prelude.Compat
17
11
18−import Data.List ((\\), delete, intersect)
19−import Data.Maybe (isNothing, fromMaybe)
20−import qualified Data.Map as M
21−import qualified Data.Foldable as F
22−import qualified Data.Traversable as T
23−
24import Control.Arrow ((&&&))
12import Control.Arrow ((&&&))
25import Control.Monad (replicateM, forM, void)
13import Control.Monad (replicateM, forM, void)
26import Control.Monad.Error.Class (MonadError(..))
14import Control.Monad.Error.Class (MonadError(..))
27import Control.Monad.Reader (MonadReader, asks)
15import Control.Monad.Reader (MonadReader, asks)
28import Control.Monad.Supply.Class
16import Control.Monad.Supply.Class
29
17
30−import Language.PureScript.Crash
18+import Data.List ((\\), delete, intersect)
19+import Data.Maybe (isNothing, fromMaybe)
20+import qualified Data.Foldable as F
21+import qualified Data.Map as M
22+import qualified Data.Traversable as T
23+
31import Language.PureScript.AST.SourcePos
24import Language.PureScript.AST.SourcePos
32import Language.PureScript.CodeGen.JS.AST as AST
25import Language.PureScript.CodeGen.JS.AST as AST
33import Language.PureScript.CodeGen.JS.Common as Common
26import Language.PureScript.CodeGen.JS.Common as Common
27+import Language.PureScript.CodeGen.JS.Optimizer
34import Language.PureScript.CoreFn
28import Language.PureScript.CoreFn
29+import Language.PureScript.Crash
30+import Language.PureScript.Errors (ErrorMessageHint(..), SimpleErrorMessage(..),
31+ MultipleErrors(..), rethrow,
32+ errorMessage, rethrowWithPosition, addHint)
35import Language.PureScript.Names
33import Language.PureScript.Names
36−import Language.PureScript.Errors
37−import Language.PureScript.CodeGen.JS.Optimizer
38import Language.PureScript.Options
34import Language.PureScript.Options
39import Language.PureScript.Traversals (sndM)
35import Language.PureScript.Traversals (sndM)
40import qualified Language.PureScript.Constants as C
36import qualified Language.PureScript.Constants as C
@@ -109,9 +105,8 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
109 --
105 --
110 importToJs :: M.Map ModuleName (Ann, ModuleName) -> ModuleName -> m JS
106 importToJs :: M.Map ModuleName (Ann, ModuleName) -> ModuleName -> m JS
111 importToJs mnLookup mn' = do
107 importToJs mnLookup mn' = do
112− path <- asks optionsRequirePath
113 let ((ss, _, _, _), mnSafe) = fromMaybe (internalError "Missing value in mnLookup") $ M.lookup mn' mnLookup
108 let ((ss, _, _, _), mnSafe) = fromMaybe (internalError "Missing value in mnLookup") $ M.lookup mn' mnLookup
114− let moduleBody = JSApp Nothing (JSVar Nothing "require") [JSStringLiteral Nothing (fromMaybe ".." path </> runModuleName mn')]
109+ let moduleBody = JSApp Nothing (JSVar Nothing "require") [JSStringLiteral Nothing (".." </> runModuleName mn')]
115 withPos ss $ JSVariableIntroduction Nothing (moduleNameToJs mnSafe) (Just moduleBody)
110 withPos ss $ JSVariableIntroduction Nothing (moduleNameToJs mnSafe) (Just moduleBody)
116
111
117 -- |
112 -- |
@@ -180,7 +175,6 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
180 --
175 --
181 accessor :: Ident -> JS -> JS
176 accessor :: Ident -> JS -> JS
182 accessor (Ident prop) = accessorString prop
177 accessor (Ident prop) = accessorString prop
183− accessor (Op op) = JSIndexer Nothing (JSStringLiteral Nothing op)
184 accessor (GenIdent _ _) = internalError "GenIdent in accessor"
178 accessor (GenIdent _ _) = internalError "GenIdent in accessor"
185
179
186 accessorString :: String -> JS -> JS
180 accessorString :: String -> JS -> JS
@@ -288,15 +282,18 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
288 extendObj obj sts = do
282 extendObj obj sts = do
289 newObj <- freshName
283 newObj <- freshName
290 key <- freshName
284 key <- freshName
285+ evaluatedObj <- freshName
291 let
286 let
292 jsKey = JSVar Nothing key
287 jsKey = JSVar Nothing key
293 jsNewObj = JSVar Nothing newObj
288 jsNewObj = JSVar Nothing newObj
289+ jsEvaluatedObj = JSVar Nothing evaluatedObj
294− block = JSBlock Nothing (objAssign:copy:extend ++ [JSReturn Nothing jsNewObj])
290+ block = JSBlock Nothing (evaluate:objAssign:copy:extend ++ [JSReturn Nothing jsNewObj])
291+ evaluate = JSVariableIntroduction Nothing evaluatedObj (Just obj)
295 objAssign = JSVariableIntroduction Nothing newObj (Just $ JSObjectLiteral Nothing [])
292 objAssign = JSVariableIntroduction Nothing newObj (Just $ JSObjectLiteral Nothing [])
296− copy = JSForIn Nothing key obj $ JSBlock Nothing [JSIfElse Nothing cond assign Nothing]
293+ copy = JSForIn Nothing key jsEvaluatedObj $ JSBlock Nothing [JSIfElse Nothing cond assign Nothing]
297− cond = JSApp Nothing (JSAccessor Nothing "hasOwnProperty" obj) [jsKey]
294+ cond = JSApp Nothing (JSAccessor Nothing "hasOwnProperty" jsEvaluatedObj) [jsKey]
298− assign = JSBlock Nothing [JSAssignment Nothing (JSIndexer Nothing jsKey jsNewObj) (JSIndexer Nothing jsKey obj)]
295+ assign = JSBlock Nothing [JSAssignment Nothing (JSIndexer Nothing jsKey jsNewObj) (JSIndexer Nothing jsKey jsEvaluatedObj)]
299− stToAssign (s, js) = JSAssignment Nothing (JSAccessor Nothing s jsNewObj) js
296+ stToAssign (s, js) = JSAssignment Nothing (accessorString s jsNewObj) js
300 extend = map stToAssign sts
297 extend = map stToAssign sts
301 return $ JSApp Nothing (JSFunction Nothing Nothing [] block) []
298 return $ JSApp Nothing (JSFunction Nothing Nothing [] block) []
302
299
src/Language/PureScript/CodeGen/JS/AST.hs+4−5
@@ -3,14 +3,13 @@
3--
3--
4module Language.PureScript.CodeGen.JS.AST where
4module Language.PureScript.CodeGen.JS.AST where
5
5
6−import Prelude ()
7import Prelude.Compat
6import Prelude.Compat
8
7
9import Control.Monad.Identity
8import Control.Monad.Identity
10
9
10+import Language.PureScript.AST (SourceSpan(..))
11import Language.PureScript.Comments
11import Language.PureScript.Comments
12import Language.PureScript.Traversals
12import Language.PureScript.Traversals
13−import Language.PureScript.AST (SourceSpan(..))
14
13
15-- |
14-- |
16-- Built-in unary operators
15-- Built-in unary operators
@@ -36,7 +35,7 @@ data UnaryOperator
36 -- Constructor
35 -- Constructor
37 --
36 --
38 | JSNew
37 | JSNew
39− deriving (Show, Read, Eq)
38+ deriving (Show, Eq)
40
39
41-- |
40-- |
42-- Built-in binary operators
41-- Built-in binary operators
@@ -118,7 +117,7 @@ data BinaryOperator
118 -- Bitwise right shift with zero-fill
117 -- Bitwise right shift with zero-fill
119 --
118 --
120 | ZeroFillShiftRight
119 | ZeroFillShiftRight
121− deriving (Show, Read, Eq)
120+ deriving (Show, Eq)
122
121
123-- |
122-- |
124-- Data type for simplified Javascript expressions
123-- Data type for simplified Javascript expressions
@@ -239,7 +238,7 @@ data JS
239 -- |
238 -- |
240 -- Commented Javascript
239 -- Commented Javascript
241 --
240 --
242− | JSComment (Maybe SourceSpan) [Comment] JS deriving (Show, Read, Eq)
241+ | JSComment (Maybe SourceSpan) [Comment] JS deriving (Show, Eq)
243
242
244withSourceSpan :: SourceSpan -> JS -> JS
243withSourceSpan :: SourceSpan -> JS -> JS
245withSourceSpan withSpan = go
244withSourceSpan withSpan = go
src/Language/PureScript/CodeGen/JS/Common.hs+3−2
@@ -3,6 +3,8 @@
3--
3--
4module Language.PureScript.CodeGen.JS.Common where
4module Language.PureScript.CodeGen.JS.Common where
5
5
6+import Prelude.Compat
7+
6import Data.Char
8import Data.Char
7import Data.List (intercalate)
9import Data.List (intercalate)
8
10
@@ -27,14 +29,13 @@ identToJs :: Ident -> String
27identToJs (Ident name)
29identToJs (Ident name)
28 | nameIsJsReserved name || nameIsJsBuiltIn name = "$$" ++ name
30 | nameIsJsReserved name || nameIsJsBuiltIn name = "$$" ++ name
29 | otherwise = concatMap identCharToString name
31 | otherwise = concatMap identCharToString name
30−identToJs (Op op) = concatMap identCharToString op
31identToJs (GenIdent _ _) = internalError "GenIdent in identToJs"
32identToJs (GenIdent _ _) = internalError "GenIdent in identToJs"
32
33
33-- |
34-- |
34-- Test if a string is a valid JS identifier without escaping.
35-- Test if a string is a valid JS identifier without escaping.
35--
36--
36identNeedsEscaping :: String -> Bool
37identNeedsEscaping :: String -> Bool
37−identNeedsEscaping s = s /= identToJs (Ident s)
38+identNeedsEscaping s = s /= identToJs (Ident s) || null s
38
39
39-- |
40-- |
40-- Attempts to find a human-readable name for a symbol, if none has been specified returns the
41-- Attempts to find a human-readable name for a symbol, if none has been specified returns the
src/Language/PureScript/CodeGen/JS/Optimizer.hs+7−11
@@ -1,5 +1,3 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−
3-- |
1-- |
4-- This module optimizes code in the simplified-Javascript intermediate representation.
2-- This module optimizes code in the simplified-Javascript intermediate representation.
5--
3--
@@ -23,32 +21,30 @@
23--
21--
24module Language.PureScript.CodeGen.JS.Optimizer (optimize) where
22module Language.PureScript.CodeGen.JS.Optimizer (optimize) where
25
23
26−import Prelude ()
27import Prelude.Compat
24import Prelude.Compat
28
25
29import Control.Monad.Reader (MonadReader, ask, asks)
26import Control.Monad.Reader (MonadReader, ask, asks)
30import Control.Monad.Supply.Class (MonadSupply)
27import Control.Monad.Supply.Class (MonadSupply)
31
28
32import Language.PureScript.CodeGen.JS.AST
29import Language.PureScript.CodeGen.JS.AST
33−import Language.PureScript.Options
30+import Language.PureScript.CodeGen.JS.Optimizer.Blocks
34−import qualified Language.PureScript.Constants as C
35−
36import Language.PureScript.CodeGen.JS.Optimizer.Common
31import Language.PureScript.CodeGen.JS.Optimizer.Common
37−import Language.PureScript.CodeGen.JS.Optimizer.TCO
38−import Language.PureScript.CodeGen.JS.Optimizer.MagicDo
39import Language.PureScript.CodeGen.JS.Optimizer.Inliner
32import Language.PureScript.CodeGen.JS.Optimizer.Inliner
33+import Language.PureScript.CodeGen.JS.Optimizer.MagicDo
34+import Language.PureScript.CodeGen.JS.Optimizer.TCO
40import Language.PureScript.CodeGen.JS.Optimizer.Unused
35import Language.PureScript.CodeGen.JS.Optimizer.Unused
41−import Language.PureScript.CodeGen.JS.Optimizer.Blocks
36+import Language.PureScript.Options
37+import qualified Language.PureScript.Constants as C
42
38
43-- |
39-- |
44-- Apply a series of optimizer passes to simplified Javascript code
40-- Apply a series of optimizer passes to simplified Javascript code
45--
41--
46−optimize :: (Monad m, MonadReader Options m, MonadSupply m) => JS -> m JS
42+optimize :: (MonadReader Options m, MonadSupply m) => JS -> m JS
47optimize js = do
43optimize js = do
48 noOpt <- asks optionsNoOptimizations
44 noOpt <- asks optionsNoOptimizations
49 if noOpt then return js else optimize' js
45 if noOpt then return js else optimize' js
50
46
51−optimize' :: (Monad m, MonadReader Options m, MonadSupply m) => JS -> m JS
47+optimize' :: (MonadReader Options m, MonadSupply m) => JS -> m JS
52optimize' js = do
48optimize' js = do
53 opts <- ask
49 opts <- ask
54 js' <- untilFixedPoint (inlineFnComposition . tidyUp . applyAll
50 js' <- untilFixedPoint (inlineFnComposition . tidyUp . applyAll
src/Language/PureScript/CodeGen/JS/Optimizer/Blocks.hs+2−12
@@ -1,23 +1,13 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.Blocks
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11-- |
1-- |
12-- Optimizer steps for simplifying Javascript blocks
2-- Optimizer steps for simplifying Javascript blocks
13--
3--
14−-----------------------------------------------------------------------------
15−
16module Language.PureScript.CodeGen.JS.Optimizer.Blocks
4module Language.PureScript.CodeGen.JS.Optimizer.Blocks
17 ( collapseNestedBlocks
5 ( collapseNestedBlocks
18 , collapseNestedIfs
6 , collapseNestedIfs
19 ) where
7 ) where
20
8
9+import Prelude.Compat
10+
21import Language.PureScript.CodeGen.JS.AST
11import Language.PureScript.CodeGen.JS.AST
22
12
23-- |
13-- |
src/Language/PureScript/CodeGen/JS/Optimizer/Common.hs+6−5
@@ -3,6 +3,8 @@
3--
3--
4module Language.PureScript.CodeGen.JS.Optimizer.Common where
4module Language.PureScript.CodeGen.JS.Optimizer.Common where
5
5
6+import Prelude.Compat
7+
6import Data.Maybe (fromMaybe)
8import Data.Maybe (fromMaybe)
7
9
8import Language.PureScript.Crash
10import Language.PureScript.Crash
@@ -66,13 +68,12 @@ removeFromBlock go (JSBlock ss sts) = JSBlock ss (go sts)
66removeFromBlock _ js = js
68removeFromBlock _ js = js
67
69
68isFn :: (String, String) -> JS -> Bool
70isFn :: (String, String) -> JS -> Bool
69−isFn (moduleName, fnName) (JSAccessor _ x (JSVar _ y)) = x == fnName && y == moduleName
71+isFn (moduleName, fnName) (JSAccessor _ x (JSVar _ y)) =
72+ x == fnName && y == moduleName
70−isFn (moduleName, fnName) (JSIndexer _ (JSStringLiteral _ x) (JSVar _ y)) = x == fnName && y == moduleName
73+isFn (moduleName, fnName) (JSIndexer _ (JSStringLiteral _ x) (JSVar _ y)) =
74+ x == fnName && y == moduleName
71isFn _ _ = False
75isFn _ _ = False
72
76
73−isFn' :: [(String, String)] -> JS -> Bool
74−isFn' xs js = any (`isFn` js) xs
75−
76isDict :: (String, String) -> JS -> Bool
77isDict :: (String, String) -> JS -> Bool
77isDict (moduleName, dictName) (JSAccessor _ x (JSVar _ y)) = x == dictName && y == moduleName
78isDict (moduleName, dictName) (JSAccessor _ x (JSVar _ y)) = x == dictName && y == moduleName
78isDict _ _ = False
79isDict _ _ = False
src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+105−108
@@ -12,15 +12,13 @@ module Language.PureScript.CodeGen.JS.Optimizer.Inliner
12 , evaluateIifes
12 , evaluateIifes
13 ) where
13 ) where
14
14
15−import Prelude ()
16import Prelude.Compat
15import Prelude.Compat
17
16
18import Control.Monad.Supply.Class (MonadSupply, freshName)
17import Control.Monad.Supply.Class (MonadSupply, freshName)
18+
19import Data.Maybe (fromMaybe)
19import Data.Maybe (fromMaybe)
20
20
21import Language.PureScript.CodeGen.JS.AST
21import Language.PureScript.CodeGen.JS.AST
22−import Language.PureScript.CodeGen.JS.Common
23−import Language.PureScript.Names
24import Language.PureScript.CodeGen.JS.Optimizer.Common
22import Language.PureScript.CodeGen.JS.Optimizer.Common
25import qualified Language.PureScript.Constants as C
23import qualified Language.PureScript.Constants as C
26
24
@@ -82,24 +80,24 @@ inlineCommonValues = everywhereOnJS convert
82 where
80 where
83 convert :: JS -> JS
81 convert :: JS -> JS
84 convert (JSApp ss fn [dict])
82 convert (JSApp ss fn [dict])
85− | isDict' (semiringNumber ++ semiringInt) dict && isFn' fnZero fn = JSNumericLiteral ss (Left 0)
83+ | isDict' [semiringNumber, semiringInt] dict && isFn fnZero fn = JSNumericLiteral ss (Left 0)
86− | isDict' (semiringNumber ++ semiringInt) dict && isFn' fnOne fn = JSNumericLiteral ss (Left 1)
84+ | isDict' [semiringNumber, semiringInt] dict && isFn fnOne fn = JSNumericLiteral ss (Left 1)
87− | isDict' boundedBoolean dict && isFn' fnBottom fn = JSBooleanLiteral ss False
85+ | isDict boundedBoolean dict && isFn fnBottom fn = JSBooleanLiteral ss False
88− | isDict' boundedBoolean dict && isFn' fnTop fn = JSBooleanLiteral ss True
86+ | isDict boundedBoolean dict && isFn fnTop fn = JSBooleanLiteral ss True
89 convert (JSApp ss (JSApp _ (JSApp _ fn [dict]) [x]) [y])
87 convert (JSApp ss (JSApp _ (JSApp _ fn [dict]) [x]) [y])
90− | isDict' semiringInt dict && isFn' fnAdd fn = intOp ss Add x y
88+ | isDict semiringInt dict && isFn fnAdd fn = intOp ss Add x y
91− | isDict' semiringInt dict && isFn' fnMultiply fn = intOp ss Multiply x y
89+ | isDict semiringInt dict && isFn fnMultiply fn = intOp ss Multiply x y
92− | isDict' moduloSemiringInt dict && isFn' fnDivide fn = intOp ss Divide x y
90+ | isDict euclideanRingInt dict && isFn fnDivide fn = intOp ss Divide x y
93− | isDict' ringInt dict && isFn' fnSubtract fn = intOp ss Subtract x y
91+ | isDict ringInt dict && isFn fnSubtract fn = intOp ss Subtract x y
94 convert other = other
92 convert other = other
95− fnZero = [(C.prelude, C.zero), (C.dataSemiring, C.zero)]
93+ fnZero = (C.dataSemiring, C.zero)
96− fnOne = [(C.prelude, C.one), (C.dataSemiring, C.one)]
94+ fnOne = (C.dataSemiring, C.one)
97− fnBottom = [(C.prelude, C.bottom), (C.dataBounded, C.bottom)]
95+ fnBottom = (C.dataBounded, C.bottom)
98− fnTop = [(C.prelude, C.top), (C.dataBounded, C.top)]
96+ fnTop = (C.dataBounded, C.top)
99− fnAdd = [(C.prelude, (C.+)), (C.prelude, C.add), (C.dataSemiring, (C.+)), (C.dataSemiring, C.add)]
97+ fnAdd = (C.dataSemiring, C.add)
100− fnDivide = [(C.prelude, (C./)), (C.prelude, C.div), (C.dataModuloSemiring, C.div)]
98+ fnDivide = (C.dataEuclideanRing, C.div)
101− fnMultiply = [(C.prelude, (C.*)), (C.prelude, C.mul), (C.dataSemiring, (C.*)), (C.dataSemiring, C.mul)]
99+ fnMultiply = (C.dataSemiring, C.mul)
102− fnSubtract = [(C.prelude, (C.-)), (C.prelude, C.sub), (C.dataRing, C.sub)]
100+ fnSubtract = (C.dataRing, C.sub)
103 intOp ss op x y = JSBinary ss BitwiseOr (JSBinary ss op x y) (JSNumericLiteral ss (Left 0))
101 intOp ss op x y = JSBinary ss BitwiseOr (JSBinary ss op x y) (JSNumericLiteral ss (Left 0))
104
102
105inlineOperator :: (String, String) -> (JS -> JS -> JS) -> JS -> JS
103inlineOperator :: (String, String) -> (JS -> JS -> JS) -> JS -> JS
@@ -108,7 +106,6 @@ inlineOperator (m, op) f = everywhereOnJS convert
108 convert :: JS -> JS
106 convert :: JS -> JS
109 convert (JSApp _ (JSApp _ op' [x]) [y]) | isOp op' = f x y
107 convert (JSApp _ (JSApp _ op' [x]) [y]) | isOp op' = f x y
110 convert other = other
108 convert other = other
111− isOp (JSAccessor _ longForm (JSVar _ m')) = m == m' && longForm == identToJs (Op op)
112 isOp (JSIndexer _ (JSStringLiteral _ op') (JSVar _ m')) = m == m' && op == op'
109 isOp (JSIndexer _ (JSStringLiteral _ op') (JSVar _ m')) = m == m' && op == op'
113 isOp _ = False
110 isOp _ = False
114
111
@@ -122,8 +119,8 @@ inlineCommonOperators = applyAll $
122 , binary ringInt opSub Subtract
119 , binary ringInt opSub Subtract
123 , unary ringInt opNegate Negate
120 , unary ringInt opNegate Negate
124
121
125− , binary moduloSemiringNumber opDiv Divide
122+ , binary euclideanRingNumber opDiv Divide
126− , binary moduloSemiringInt opMod Modulus
123+ , binary euclideanRingInt opMod Modulus
127
124
128 , binary eqNumber opEq EqualTo
125 , binary eqNumber opEq EqualTo
129 , binary eqNumber opNotEq NotEqualTo
126 , binary eqNumber opNotEq NotEqualTo
@@ -159,9 +156,9 @@ inlineCommonOperators = applyAll $
159
156
160 , binary semigroupString opAppend Add
157 , binary semigroupString opAppend Add
161
158
162− , binary booleanAlgebraBoolean opConj And
159+ , binary heytingAlgebraBoolean opConj And
163− , binary booleanAlgebraBoolean opDisj Or
160+ , binary heytingAlgebraBoolean opDisj Or
164− , unary booleanAlgebraBoolean opNot Not
161+ , unary heytingAlgebraBoolean opNot Not
165
162
166 , binary' C.dataIntBits (C..|.) BitwiseOr
163 , binary' C.dataIntBits (C..|.) BitwiseOr
167 , binary' C.dataIntBits (C..&.) BitwiseAnd
164 , binary' C.dataIntBits (C..&.) BitwiseAnd
@@ -173,11 +170,11 @@ inlineCommonOperators = applyAll $
173 ] ++
170 ] ++
174 [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
171 [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
175 where
172 where
176− binary :: [(String, String)] -> [(String, String)] -> BinaryOperator -> JS -> JS
173+ binary :: (String, String) -> (String, String) -> BinaryOperator -> JS -> JS
177 binary dict fns op = everywhereOnJS convert
174 binary dict fns op = everywhereOnJS convert
178 where
175 where
179 convert :: JS -> JS
176 convert :: JS -> JS
180− convert (JSApp ss (JSApp _ (JSApp _ fn [dict']) [x]) [y]) | isDict' dict dict' && isFn' fns fn = JSBinary ss op x y
177+ convert (JSApp ss (JSApp _ (JSApp _ fn [dict']) [x]) [y]) | isDict dict dict' && isFn fns fn = JSBinary ss op x y
181 convert other = other
178 convert other = other
182 binary' :: String -> String -> BinaryOperator -> JS -> JS
179 binary' :: String -> String -> BinaryOperator -> JS -> JS
183 binary' moduleName opString op = everywhereOnJS convert
180 binary' moduleName opString op = everywhereOnJS convert
@@ -185,11 +182,11 @@ inlineCommonOperators = applyAll $
185 convert :: JS -> JS
182 convert :: JS -> JS
186 convert (JSApp ss (JSApp _ fn [x]) [y]) | isFn (moduleName, opString) fn = JSBinary ss op x y
183 convert (JSApp ss (JSApp _ fn [x]) [y]) | isFn (moduleName, opString) fn = JSBinary ss op x y
187 convert other = other
184 convert other = other
188− unary :: [(String, String)] -> [(String, String)] -> UnaryOperator -> JS -> JS
185+ unary :: (String, String) -> (String, String) -> UnaryOperator -> JS -> JS
189 unary dicts fns op = everywhereOnJS convert
186 unary dicts fns op = everywhereOnJS convert
190 where
187 where
191 convert :: JS -> JS
188 convert :: JS -> JS
192− convert (JSApp ss (JSApp _ fn [dict']) [x]) | isDict' dicts dict' && isFn' fns fn = JSUnary ss op x
189+ convert (JSApp ss (JSApp _ fn [dict']) [x]) | isDict dicts dict' && isFn fns fn = JSUnary ss op x
193 convert other = other
190 convert other = other
194 unary' :: String -> String -> UnaryOperator -> JS -> JS
191 unary' :: String -> String -> UnaryOperator -> JS -> JS
195 unary' moduleName fnName op = everywhereOnJS convert
192 unary' moduleName fnName op = everywhereOnJS convert
@@ -219,7 +216,7 @@ inlineCommonOperators = applyAll $
219
216
220 isNFn :: String -> Int -> JS -> Bool
217 isNFn :: String -> Int -> JS -> Bool
221 isNFn prefix n (JSVar _ name) = name == (prefix ++ show n)
218 isNFn prefix n (JSVar _ name) = name == (prefix ++ show n)
222− isNFn prefix n (JSAccessor _ name (JSVar _ dataFunction)) | dataFunction == C.dataFunction = name == (prefix ++ show n)
219+ isNFn prefix n (JSAccessor _ name (JSVar _ dataFunctionUncurried)) | dataFunctionUncurried == C.dataFunctionUncurried = name == (prefix ++ show n)
223 isNFn _ _ _ = False
220 isNFn _ _ _ = False
224
221
225 runFn :: Int -> JS -> JS
222 runFn :: Int -> JS -> JS
@@ -251,118 +248,118 @@ inlineFnComposition = everywhereOnJSTopDownM convert
251 return $ JSFunction ss Nothing [arg] (JSBlock ss [JSReturn Nothing $ JSApp Nothing y [JSApp Nothing x [JSVar Nothing arg]]])
248 return $ JSFunction ss Nothing [arg] (JSBlock ss [JSReturn Nothing $ JSApp Nothing y [JSApp Nothing x [JSVar Nothing arg]]])
252 convert other = return other
249 convert other = return other
253 isFnCompose :: JS -> JS -> Bool
250 isFnCompose :: JS -> JS -> Bool
254− isFnCompose dict' fn = isDict' semigroupoidFn dict' && isFn' fnCompose fn
251+ isFnCompose dict' fn = isDict semigroupoidFn dict' && isFn fnCompose fn
255 isFnComposeFlipped :: JS -> JS -> Bool
252 isFnComposeFlipped :: JS -> JS -> Bool
256− isFnComposeFlipped dict' fn = isDict' semigroupoidFn dict' && isFn' fnComposeFlipped fn
253+ isFnComposeFlipped dict' fn = isDict semigroupoidFn dict' && isFn fnComposeFlipped fn
257− fnCompose :: [(String, String)]
254+ fnCompose :: (String, String)
258− fnCompose = [(C.prelude, C.compose), (C.prelude, (C.<<<)), (C.controlSemigroupoid, C.compose)]
255+ fnCompose = (C.controlSemigroupoid, C.compose)
259− fnComposeFlipped :: [(String, String)]
256+ fnComposeFlipped :: (String, String)
260− fnComposeFlipped = [(C.prelude, (C.>>>)), (C.controlSemigroupoid, C.composeFlipped)]
257+ fnComposeFlipped = (C.controlSemigroupoid, C.composeFlipped)
261
258
262−semiringNumber :: [(String, String)]
259+semiringNumber :: (String, String)
263−semiringNumber = [(C.prelude, C.semiringNumber), (C.dataSemiring, C.semiringNumber)]
260+semiringNumber = (C.dataSemiring, C.semiringNumber)
264
261
265−semiringInt :: [(String, String)]
262+semiringInt :: (String, String)
266−semiringInt = [(C.prelude, C.semiringInt), (C.dataSemiring, C.semiringInt)]
263+semiringInt = (C.dataSemiring, C.semiringInt)
267
264
268−ringNumber :: [(String, String)]
265+ringNumber :: (String, String)
269−ringNumber = [(C.prelude, C.ringNumber), (C.dataRing, C.ringNumber)]
266+ringNumber = (C.dataRing, C.ringNumber)
270
267
271−ringInt :: [(String, String)]
268+ringInt :: (String, String)
272−ringInt = [(C.prelude, C.ringInt), (C.dataRing, C.ringInt)]
269+ringInt = (C.dataRing, C.ringInt)
273
270
274−moduloSemiringNumber :: [(String, String)]
271+euclideanRingNumber :: (String, String)
275−moduloSemiringNumber = [(C.prelude, C.moduloSemiringNumber), (C.dataModuloSemiring, C.moduloSemiringNumber)]
272+euclideanRingNumber = (C.dataEuclideanRing, C.euclideanRingNumber)
276
273
277−moduloSemiringInt :: [(String, String)]
274+euclideanRingInt :: (String, String)
278−moduloSemiringInt = [(C.prelude, C.moduloSemiringInt), (C.dataModuloSemiring, C.moduloSemiringInt)]
275+euclideanRingInt = (C.dataEuclideanRing, C.euclideanRingInt)
279
276
280−eqNumber :: [(String, String)]
277+eqNumber :: (String, String)
281−eqNumber = [(C.prelude, C.eqNumber), (C.dataEq, C.eqNumber)]
278+eqNumber = (C.dataEq, C.eqNumber)
282
279
283−eqInt :: [(String, String)]
280+eqInt :: (String, String)
284−eqInt = [(C.prelude, C.eqInt), (C.dataEq, C.eqInt)]
281+eqInt = (C.dataEq, C.eqInt)
285
282
286−eqString :: [(String, String)]
283+eqString :: (String, String)
287−eqString = [(C.prelude, C.eqString), (C.dataEq, C.eqString)]
284+eqString = (C.dataEq, C.eqString)
288
285
289−eqChar :: [(String, String)]
286+eqChar :: (String, String)
290−eqChar = [(C.prelude, C.eqChar), (C.dataEq, C.eqChar)]
287+eqChar = (C.dataEq, C.eqChar)
291
288
292−eqBoolean :: [(String, String)]
289+eqBoolean :: (String, String)
293−eqBoolean = [(C.prelude, C.eqBoolean), (C.dataEq, C.eqBoolean)]
290+eqBoolean = (C.dataEq, C.eqBoolean)
294
291
295−ordBoolean :: [(String, String)]
292+ordBoolean :: (String, String)
296−ordBoolean = [(C.prelude, C.ordBoolean), (C.dataOrd, C.ordBoolean)]
293+ordBoolean = (C.dataOrd, C.ordBoolean)
297
294
298−ordNumber :: [(String, String)]
295+ordNumber :: (String, String)
299−ordNumber = [(C.prelude, C.ordNumber), (C.dataOrd, C.ordNumber)]
296+ordNumber = (C.dataOrd, C.ordNumber)
300
297
301−ordInt :: [(String, String)]
298+ordInt :: (String, String)
302−ordInt = [(C.prelude, C.ordInt), (C.dataOrd, C.ordInt)]
299+ordInt = (C.dataOrd, C.ordInt)
303
300
304−ordString :: [(String, String)]
301+ordString :: (String, String)
305−ordString = [(C.prelude, C.ordString), (C.dataOrd, C.ordString)]
302+ordString = (C.dataOrd, C.ordString)
306
303
307−ordChar :: [(String, String)]
304+ordChar :: (String, String)
308−ordChar = [(C.prelude, C.ordChar), (C.dataOrd, C.ordChar)]
305+ordChar = (C.dataOrd, C.ordChar)
309
306
310−semigroupString :: [(String, String)]
307+semigroupString :: (String, String)
311−semigroupString = [(C.prelude, C.semigroupString), (C.dataSemigroup, C.semigroupString)]
308+semigroupString = (C.dataSemigroup, C.semigroupString)
312
309
313−boundedBoolean :: [(String, String)]
310+boundedBoolean :: (String, String)
314−boundedBoolean = [(C.prelude, C.boundedBoolean), (C.dataBounded, C.boundedBoolean)]
311+boundedBoolean = (C.dataBounded, C.boundedBoolean)
315
312
316−booleanAlgebraBoolean :: [(String, String)]
313+heytingAlgebraBoolean :: (String, String)
317−booleanAlgebraBoolean = [(C.prelude, C.booleanAlgebraBoolean), (C.dataBooleanAlgebra, C.booleanAlgebraBoolean)]
314+heytingAlgebraBoolean = (C.dataHeytingAlgebra, C.heytingAlgebraBoolean)
318
315
319−semigroupoidFn :: [(String, String)]
316+semigroupoidFn :: (String, String)
320−semigroupoidFn = [(C.prelude, C.semigroupoidFn), (C.controlSemigroupoid, C.semigroupoidFn)]
317+semigroupoidFn = (C.controlSemigroupoid, C.semigroupoidFn)
321
318
322−opAdd :: [(String, String)]
319+opAdd :: (String, String)
323−opAdd = [(C.prelude, (C.+)), (C.prelude, C.add), (C.dataSemiring, C.add)]
320+opAdd = (C.dataSemiring, C.add)
324
321
325−opMul :: [(String, String)]
322+opMul :: (String, String)
326−opMul = [(C.prelude, (C.*)), (C.prelude, C.mul), (C.dataSemiring, C.mul)]
323+opMul = (C.dataSemiring, C.mul)
327
324
328−opEq :: [(String, String)]
325+opEq :: (String, String)
329−opEq = [(C.prelude, (C.==)), (C.prelude, C.eq), (C.dataEq, C.eq)]
326+opEq = (C.dataEq, C.eq)
330
327
331−opNotEq :: [(String, String)]
328+opNotEq :: (String, String)
332−opNotEq = [(C.prelude, (C./=)), (C.dataEq, C.notEq)]
329+opNotEq = (C.dataEq, C.notEq)
333
330
334−opLessThan :: [(String, String)]
331+opLessThan :: (String, String)
335−opLessThan = [(C.prelude, (C.<)), (C.dataOrd, C.lessThan)]
332+opLessThan = (C.dataOrd, C.lessThan)
336
333
337−opLessThanOrEq :: [(String, String)]
334+opLessThanOrEq :: (String, String)
338−opLessThanOrEq = [(C.prelude, (C.<=)), (C.dataOrd, C.lessThanOrEq)]
335+opLessThanOrEq = (C.dataOrd, C.lessThanOrEq)
339
336
340−opGreaterThan :: [(String, String)]
337+opGreaterThan :: (String, String)
341−opGreaterThan = [(C.prelude, (C.>)), (C.dataOrd, C.greaterThan)]
338+opGreaterThan = (C.dataOrd, C.greaterThan)
342
339
343−opGreaterThanOrEq :: [(String, String)]
340+opGreaterThanOrEq :: (String, String)
344−opGreaterThanOrEq = [(C.prelude, (C.>=)), (C.dataOrd, C.greaterThanOrEq)]
341+opGreaterThanOrEq = (C.dataOrd, C.greaterThanOrEq)
345
342
346−opAppend :: [(String, String)]
343+opAppend :: (String, String)
347−opAppend = [(C.prelude, (C.<>)), (C.prelude, (C.++)), (C.prelude, C.append), (C.dataSemigroup, C.append)]
344+opAppend = (C.dataSemigroup, C.append)
348
345
349−opSub :: [(String, String)]
346+opSub :: (String, String)
350−opSub = [(C.prelude, (C.-)), (C.prelude, C.sub), (C.dataRing, C.sub)]
347+opSub = (C.dataRing, C.sub)
351
348
352−opNegate :: [(String, String)]
349+opNegate :: (String, String)
353−opNegate = [(C.prelude, C.negate), (C.dataRing, C.negate)]
350+opNegate = (C.dataRing, C.negate)
354
351
355−opDiv :: [(String, String)]
352+opDiv :: (String, String)
356−opDiv = [(C.prelude, (C./)), (C.prelude, C.div), (C.dataModuloSemiring, C.div)]
353+opDiv = (C.dataEuclideanRing, C.div)
357
354
358−opMod :: [(String, String)]
355+opMod :: (String, String)
359−opMod = [(C.prelude, C.mod), (C.dataModuloSemiring, C.mod)]
356+opMod = (C.dataEuclideanRing, C.mod)
360
357
361−opConj :: [(String, String)]
358+opConj :: (String, String)
362−opConj = [(C.prelude, (C.&&)), (C.prelude, C.conj), (C.dataBooleanAlgebra, C.conj)]
359+opConj = (C.dataHeytingAlgebra, C.conj)
363
360
364−opDisj :: [(String, String)]
361+opDisj :: (String, String)
365−opDisj = [(C.prelude, (C.||)), (C.prelude, C.disj), (C.dataBooleanAlgebra, C.disj)]
362+opDisj = (C.dataHeytingAlgebra, C.disj)
366
363
367−opNot :: [(String, String)]
364+opNot :: (String, String)
368−opNot = [(C.prelude, C.not), (C.dataBooleanAlgebra, C.not)]
365+opNot = (C.dataHeytingAlgebra, C.not)
src/Language/PureScript/CodeGen/JS/Optimizer/MagicDo.hs+4−2
@@ -4,6 +4,8 @@
4--
4--
5module Language.PureScript.CodeGen.JS.Optimizer.MagicDo (magicDo) where
5module Language.PureScript.CodeGen.JS.Optimizer.MagicDo (magicDo) where
6
6
7+import Prelude.Compat
8+
7import Data.List (nub)
9import Data.List (nub)
8import Data.Maybe (fromJust, isJust)
10import Data.Maybe (fromJust, isJust)
9
11
@@ -61,9 +63,9 @@ magicDo' = everywhereOnJS undo . everywhereOnJSTopDown convert
61 isPure (JSApp _ fn [dict]) | isDict (C.eff, C.applicativeEffDictionary) dict && isPurePoly fn = True
63 isPure (JSApp _ fn [dict]) | isDict (C.eff, C.applicativeEffDictionary) dict && isPurePoly fn = True
62 isPure _ = False
64 isPure _ = False
63 -- Check if an expression represents the polymorphic >>= function
65 -- Check if an expression represents the polymorphic >>= function
64− isBindPoly = isFn' [(C.prelude, C.bind), (C.prelude, (C.>>=)), (C.controlBind, C.bind)]
66+ isBindPoly = isFn (C.controlBind, C.bind)
65 -- Check if an expression represents the polymorphic pure or return function
67 -- Check if an expression represents the polymorphic pure or return function
66− isPurePoly = isFn' [(C.prelude, C.pure'), (C.prelude, C.return), (C.controlApplicative, C.pure')]
68+ isPurePoly = isFn (C.controlApplicative, C.pure')
67 -- Check if an expression represents a function in the Eff module
69 -- Check if an expression represents a function in the Eff module
68 isEffFunc name (JSAccessor _ name' (JSVar _ eff)) = eff == C.eff && name == name'
70 isEffFunc name (JSAccessor _ name' (JSVar _ eff)) = eff == C.eff && name == name'
69 isEffFunc _ _ = False
71 isEffFunc _ _ = False
src/Language/PureScript/CodeGen/JS/Optimizer/TCO.hs+2−12
@@ -1,20 +1,10 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.TCO
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11-- |
1-- |
12-- This module implements tail call elimination.
2-- This module implements tail call elimination.
13--
3--
14−-----------------------------------------------------------------------------
15−
16module Language.PureScript.CodeGen.JS.Optimizer.TCO (tco) where
4module Language.PureScript.CodeGen.JS.Optimizer.TCO (tco) where
17
5
6+import Prelude.Compat
7+
18import Data.Monoid
8import Data.Monoid
19
9
20import Language.PureScript.Options
10import Language.PureScript.Options
src/Language/PureScript/CodeGen/JS/Optimizer/Unused.hs+2−13
@@ -1,27 +1,16 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.Unused
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11-- |
1-- |
12-- Removes unused variables
2-- Removes unused variables
13--
3--
14−-----------------------------------------------------------------------------
15−
16module Language.PureScript.CodeGen.JS.Optimizer.Unused
4module Language.PureScript.CodeGen.JS.Optimizer.Unused
17 ( removeCodeAfterReturnStatements
5 ( removeCodeAfterReturnStatements
18 , removeUnusedArg
6 , removeUnusedArg
19 , removeUndefinedApp
7 , removeUndefinedApp
20 ) where
8 ) where
21
9
10+import Prelude.Compat
11+
22import Language.PureScript.CodeGen.JS.AST
12import Language.PureScript.CodeGen.JS.AST
23import Language.PureScript.CodeGen.JS.Optimizer.Common
13import Language.PureScript.CodeGen.JS.Optimizer.Common
24−
25import qualified Language.PureScript.Constants as C
14import qualified Language.PureScript.Constants as C
26
15
27removeCodeAfterReturnStatements :: JS -> JS
16removeCodeAfterReturnStatements :: JS -> JS
src/Language/PureScript/Comments.hs+3−1
@@ -5,11 +5,13 @@
5--
5--
6module Language.PureScript.Comments where
6module Language.PureScript.Comments where
7
7
8+import Prelude.Compat
9+
8import Data.Aeson.TH
10import Data.Aeson.TH
9
11
10data Comment
12data Comment
11 = LineComment String
13 = LineComment String
12 | BlockComment String
14 | BlockComment String
13− deriving (Show, Read, Eq, Ord)
15+ deriving (Show, Eq, Ord)
14
16
15$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''Comment)
17$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''Comment)
src/Language/PureScript/Constants.hs+33−8
@@ -1,8 +1,10 @@
1−-- |
2−-- Various constants which refer to things in the Prelude
1+-- | Various constants which refer to things in the Prelude
3−--
4module Language.PureScript.Constants where
2module Language.PureScript.Constants where
5
3
4+import Prelude.Compat
5+
6+import Language.PureScript.Names
7+
6-- Operators
8-- Operators
7
9
8($) :: String
10($) :: String
@@ -247,6 +249,12 @@ moduloSemiringNumber = "moduloSemiringNumber"
247moduloSemiringInt :: String
249moduloSemiringInt :: String
248moduloSemiringInt = "moduloSemiringInt"
250moduloSemiringInt = "moduloSemiringInt"
249
251
252+euclideanRingNumber :: String
253+euclideanRingNumber = "euclideanRingNumber"
254+
255+euclideanRingInt :: String
256+euclideanRingInt = "euclideanRingInt"
257+
250ordBoolean :: String
258ordBoolean :: String
251ordBoolean = "ordBoolean"
259ordBoolean = "ordBoolean"
252
260
@@ -283,6 +291,9 @@ boundedBoolean = "boundedBoolean"
283booleanAlgebraBoolean :: String
291booleanAlgebraBoolean :: String
284booleanAlgebraBoolean = "booleanAlgebraBoolean"
292booleanAlgebraBoolean = "booleanAlgebraBoolean"
285
293
294+heytingAlgebraBoolean :: String
295+heytingAlgebraBoolean = "heytingAlgebraBoolean"
296+
286semigroupString :: String
297semigroupString :: String
287semigroupString = "semigroupString"
298semigroupString = "semigroupString"
288
299
@@ -308,6 +319,17 @@ toSignature = "toSignature"
308main :: String
319main :: String
309main = "main"
320main = "main"
310
321
322+-- Prim
323+
324+partial :: String
325+partial = "Partial"
326+
327+pattern Partial :: Qualified (ProperName 'ClassName)
328+pattern Partial = Qualified (Just (ModuleName [ProperName "Prim"])) (ProperName "Partial")
329+
330+pattern Fail :: Qualified (ProperName 'ClassName)
331+pattern Fail = Qualified (Just (ModuleName [ProperName "Prim"])) (ProperName "Fail")
332+
311-- Code Generation
333-- Code Generation
312
334
313__superclass_ :: String
335__superclass_ :: String
@@ -348,11 +370,8 @@ dataBounded = "Data_Bounded"
348dataSemigroup :: String
370dataSemigroup :: String
349dataSemigroup = "Data_Semigroup"
371dataSemigroup = "Data_Semigroup"
350
372
351−dataModuloSemiring :: String
373+dataHeytingAlgebra :: String
352−dataModuloSemiring = "Data_ModuloSemiring"
374+dataHeytingAlgebra = "Data_HeytingAlgebra"
353−
354−dataBooleanAlgebra :: String
355−dataBooleanAlgebra = "Data_BooleanAlgebra"
356
375
357dataEq :: String
376dataEq :: String
358dataEq = "Data_Eq"
377dataEq = "Data_Eq"
@@ -366,8 +385,14 @@ dataSemiring = "Data_Semiring"
366dataRing :: String
385dataRing :: String
367dataRing = "Data_Ring"
386dataRing = "Data_Ring"
368
387
388+dataEuclideanRing :: String
389+dataEuclideanRing = "Data_EuclideanRing"
390+
369dataFunction :: String
391dataFunction :: String
370dataFunction = "Data_Function"
392dataFunction = "Data_Function"
371
393
394+dataFunctionUncurried :: String
395+dataFunctionUncurried = "Data_Function_Uncurried"
396+
372dataIntBits :: String
397dataIntBits :: String
373dataIntBits = "Data_Int_Bits"
398dataIntBits = "Data_Int_Bits"
src/Language/PureScript/CoreFn.hs+1−1
@@ -5,11 +5,11 @@ module Language.PureScript.CoreFn (
5 module C
5 module C
6) where
6) where
7
7
8+import Language.PureScript.AST.Literals as C
8import Language.PureScript.CoreFn.Ann as C
9import Language.PureScript.CoreFn.Ann as C
9import Language.PureScript.CoreFn.Binders as C
10import Language.PureScript.CoreFn.Binders as C
10import Language.PureScript.CoreFn.Desugar as C
11import Language.PureScript.CoreFn.Desugar as C
11import Language.PureScript.CoreFn.Expr as C
12import Language.PureScript.CoreFn.Expr as C
12−import Language.PureScript.AST.Literals as C
13import Language.PureScript.CoreFn.Meta as C
13import Language.PureScript.CoreFn.Meta as C
14import Language.PureScript.CoreFn.Module as C
14import Language.PureScript.CoreFn.Module as C
15import Language.PureScript.CoreFn.Traversals as C
15import Language.PureScript.CoreFn.Traversals as C
src/Language/PureScript/CoreFn/Ann.hs+25−37
@@ -1,37 +1,25 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CoreFn.Ann
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | Type alias for basic annotations
12−--
13−-----------------------------------------------------------------------------
14−
15−module Language.PureScript.CoreFn.Ann where
1+module Language.PureScript.CoreFn.Ann where
16−
2+
3+import Prelude.Compat
4+
17−import Language.PureScript.AST.SourcePos
5+import Language.PureScript.AST.SourcePos
18−import Language.PureScript.CoreFn.Meta
6+import Language.PureScript.Comments
7+import Language.PureScript.CoreFn.Meta
19−import Language.PureScript.Types
8+import Language.PureScript.Types
20−import Language.PureScript.Comments
9+
21−
22−-- |
10+-- |
23−-- Type alias for basic annotations
11+-- Type alias for basic annotations
24−--
12+--
25−type Ann = (Maybe SourceSpan, [Comment], Maybe Type, Maybe Meta)
13+type Ann = (Maybe SourceSpan, [Comment], Maybe Type, Maybe Meta)
26−
14+
27−-- |
15+-- |
28−-- Initial annotation with no metadata
16+-- Initial annotation with no metadata
29−--
17+--
30−nullAnn :: Ann
18+nullAnn :: Ann
31−nullAnn = (Nothing, [], Nothing, Nothing)
19+nullAnn = (Nothing, [], Nothing, Nothing)
32−
20+
33−-- |
21+-- |
34−-- Remove the comments from an annotation
22+-- Remove the comments from an annotation
35−--
23+--
36−removeComments :: Ann -> Ann
24+removeComments :: Ann -> Ann
37−removeComments (ss, _, ty, meta) = (ss, [], ty, meta)
25+removeComments (ss, _, ty, meta) = (ss, [], ty, meta)
src/Language/PureScript/CoreFn/Binders.hs+3−3
@@ -1,10 +1,10 @@
1−{-# LANGUAGE DeriveFunctor #-}
2−
3-- |
1-- |
4-- The core functional representation for binders
2-- The core functional representation for binders
5--
3--
6module Language.PureScript.CoreFn.Binders where
4module Language.PureScript.CoreFn.Binders where
7
5
6+import Prelude.Compat
7+
8import Language.PureScript.AST.Literals
8import Language.PureScript.AST.Literals
9import Language.PureScript.Names
9import Language.PureScript.Names
10
10
@@ -31,7 +31,7 @@ data Binder a
31 -- |
31 -- |
32 -- A binder which binds its input to an identifier
32 -- A binder which binds its input to an identifier
33 --
33 --
34− | NamedBinder a Ident (Binder a) deriving (Show, Read, Functor)
34+ | NamedBinder a Ident (Binder a) deriving (Show, Functor)
35
35
36
36
37extractBinderAnn :: Binder a -> a
37extractBinderAnn :: Binder a -> a
src/Language/PureScript/CoreFn/Desugar.hs+17−25
@@ -1,30 +1,28 @@
1module Language.PureScript.CoreFn.Desugar (moduleToCoreFn) where
1module Language.PureScript.CoreFn.Desugar (moduleToCoreFn) where
2
2
3−import Prelude ()
4import Prelude.Compat
3import Prelude.Compat
5
4
5+import Control.Arrow (second, (***))
6
6
7import Data.Function (on)
7import Data.Function (on)
8import Data.List (sort, sortBy, nub)
8import Data.List (sort, sortBy, nub)
9import Data.Maybe (mapMaybe)
9import Data.Maybe (mapMaybe)
10import qualified Data.Map as M
10import qualified Data.Map as M
11
11
12−import Control.Arrow (second, (***))
13−
14−import Language.PureScript.Crash
12+import Language.PureScript.AST.Literals
15import Language.PureScript.AST.SourcePos
13import Language.PureScript.AST.SourcePos
16import Language.PureScript.AST.Traversals
14import Language.PureScript.AST.Traversals
15+import Language.PureScript.Comments
17import Language.PureScript.CoreFn.Ann
16import Language.PureScript.CoreFn.Ann
18import Language.PureScript.CoreFn.Binders
17import Language.PureScript.CoreFn.Binders
19import Language.PureScript.CoreFn.Expr
18import Language.PureScript.CoreFn.Expr
20−import Language.PureScript.AST.Literals
21import Language.PureScript.CoreFn.Meta
19import Language.PureScript.CoreFn.Meta
22import Language.PureScript.CoreFn.Module
20import Language.PureScript.CoreFn.Module
21+import Language.PureScript.Crash
23import Language.PureScript.Environment
22import Language.PureScript.Environment
24import Language.PureScript.Names
23import Language.PureScript.Names
25import Language.PureScript.Sugar.TypeClasses (typeClassMemberName, superClassDictionaryNames)
24import Language.PureScript.Sugar.TypeClasses (typeClassMemberName, superClassDictionaryNames)
26import Language.PureScript.Types
25import Language.PureScript.Types
27−import Language.PureScript.Comments
28import qualified Language.PureScript.AST as A
26import qualified Language.PureScript.AST as A
29
27
30-- |
28-- |
@@ -72,12 +70,6 @@ moduleToCoreFn env (A.Module _ coms mn decls (Just exps)) =
72 declToCoreFn ss _ (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn ss []) ds
70 declToCoreFn ss _ (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn ss []) ds
73 declToCoreFn ss com (A.ValueDeclaration name _ _ (Right e)) =
71 declToCoreFn ss com (A.ValueDeclaration name _ _ (Right e)) =
74 [NonRec (ssA ss) name (exprToCoreFn ss com Nothing e)]
72 [NonRec (ssA ss) name (exprToCoreFn ss com Nothing e)]
75− declToCoreFn ss com (A.FixityDeclaration _ name (Just (Qualified mn' (A.AliasValue name')))) =
76− let meta = getValueMeta (Qualified mn' name')
77− in [NonRec (ssA ss) (Op name) (Var (ss, com, Nothing, meta) (Qualified mn' name'))]
78− declToCoreFn ss com (A.FixityDeclaration _ name (Just (Qualified mn' (A.AliasConstructor name')))) =
79− let meta = Just $ getConstructorMeta (Qualified mn' name')
80− in [NonRec (ssA ss) (Op name) (Var (ss, com, Nothing, meta) (Qualified mn' (properToIdent name')))]
81 declToCoreFn ss _ (A.BindingGroupDeclaration ds) =
73 declToCoreFn ss _ (A.BindingGroupDeclaration ds) =
82 [Rec $ map (\(name, _, e) -> ((ssA ss, name), exprToCoreFn ss [] Nothing e)) ds]
74 [Rec $ map (\(name, _, e) -> ((ssA ss, name), exprToCoreFn ss [] Nothing e)) ds]
83 declToCoreFn ss com (A.TypeClassDeclaration name _ supers members) =
75 declToCoreFn ss com (A.TypeClassDeclaration name _ supers members) =
@@ -206,31 +198,31 @@ moduleToCoreFn env (A.Module _ coms mn decls (Just exps)) =
206findQualModules :: [A.Declaration] -> [(Ann, ModuleName)]
198findQualModules :: [A.Declaration] -> [(Ann, ModuleName)]
207findQualModules decls =
199findQualModules decls =
208 let (f, _, _, _, _) = everythingOnValues (++) fqDecls fqValues fqBinders (const []) (const [])
200 let (f, _, _, _, _) = everythingOnValues (++) fqDecls fqValues fqBinders (const []) (const [])
209− in f `concatMap` decls
201+ in map (nullAnn,) $ f `concatMap` decls
210 where
202 where
211− fqDecls :: A.Declaration -> [(Ann, ModuleName)]
203+ fqDecls :: A.Declaration -> [ModuleName]
212− fqDecls (A.TypeInstanceDeclaration _ _ q _ _) = getQual q
204+ fqDecls (A.TypeInstanceDeclaration _ _ q _ _) = getQual' q
213− fqDecls (A.FixityDeclaration _ _ (Just q)) = getQual q
205+ fqDecls (A.ValueFixityDeclaration _ q _) = getQual' q
206+ fqDecls (A.TypeFixityDeclaration _ q _) = getQual' q
214 fqDecls _ = []
207 fqDecls _ = []
215
208
216− fqValues :: A.Expr -> [(Ann, ModuleName)]
209+ fqValues :: A.Expr -> [ModuleName]
217− fqValues (A.Var q) = getQual q
210+ fqValues (A.Var q) = getQual' q
218− fqValues (A.Constructor q) = getQual q
211+ fqValues (A.Constructor q) = getQual' q
219 fqValues _ = []
212 fqValues _ = []
220
213
221− fqBinders :: A.Binder -> [(Ann, ModuleName)]
214+ fqBinders :: A.Binder -> [ModuleName]
222− fqBinders (A.ConstructorBinder q _) = getQual q
215+ fqBinders (A.ConstructorBinder q _) = getQual' q
223 fqBinders _ = []
216 fqBinders _ = []
224
217
225− getQual :: Qualified a -> [(Ann, ModuleName)]
218+ getQual' :: Qualified a -> [ModuleName]
226− getQual (Qualified (Just mn) _) = [(nullAnn, mn)]
219+ getQual' = maybe [] return . getQual
227− getQual _ = []
228
220
229-- |
221-- |
230-- Desugars import declarations from AST to CoreFn representation.
222-- Desugars import declarations from AST to CoreFn representation.
231--
223--
232importToCoreFn :: A.Declaration -> Maybe (Ann, ModuleName)
224importToCoreFn :: A.Declaration -> Maybe (Ann, ModuleName)
233−importToCoreFn (A.ImportDeclaration name _ _ _) = Just (nullAnn, name)
225+importToCoreFn (A.ImportDeclaration name _ _) = Just (nullAnn, name)
234importToCoreFn (A.PositionedDeclaration ss _ d) =
226importToCoreFn (A.PositionedDeclaration ss _ d) =
235 ((,) (Just ss, [], Nothing, Nothing) . snd) <$> importToCoreFn d
227 ((,) (Just ss, [], Nothing, Nothing) . snd) <$> importToCoreFn d
236importToCoreFn _ = Nothing
228importToCoreFn _ = Nothing
src/Language/PureScript/CoreFn/Expr.hs+6−6
@@ -1,14 +1,14 @@
1−{-# LANGUAGE DeriveFunctor #-}
2−
3-- |
1-- |
4-- The core functional representation
2-- The core functional representation
5--
3--
6module Language.PureScript.CoreFn.Expr where
4module Language.PureScript.CoreFn.Expr where
7
5
6+import Prelude.Compat
7+
8import Control.Arrow ((***))
8import Control.Arrow ((***))
9
9
10−import Language.PureScript.CoreFn.Binders
11import Language.PureScript.AST.Literals
10import Language.PureScript.AST.Literals
11+import Language.PureScript.CoreFn.Binders
12import Language.PureScript.Names
12import Language.PureScript.Names
13
13
14-- |
14-- |
@@ -51,7 +51,7 @@ data Expr a
51 -- A let binding
51 -- A let binding
52 --
52 --
53 | Let a [Bind a] (Expr a)
53 | Let a [Bind a] (Expr a)
54− deriving (Show, Read, Functor)
54+ deriving (Show, Functor)
55
55
56-- |
56-- |
57-- A let or module binding.
57-- A let or module binding.
@@ -64,7 +64,7 @@ data Bind a
64 -- |
64 -- |
65 -- Mutually recursive binding group for several values
65 -- Mutually recursive binding group for several values
66 --
66 --
67− | Rec [((a, Ident), Expr a)] deriving (Show, Read, Functor)
67+ | Rec [((a, Ident), Expr a)] deriving (Show, Functor)
68
68
69-- |
69-- |
70-- A guard is just a boolean-valued expression that appears alongside a set of binders
70-- A guard is just a boolean-valued expression that appears alongside a set of binders
@@ -83,7 +83,7 @@ data CaseAlternative a = CaseAlternative
83 -- The result expression or a collect of guarded expressions
83 -- The result expression or a collect of guarded expressions
84 --
84 --
85 , caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a)
85 , caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a)
86− } deriving (Show, Read)
86+ } deriving (Show)
87
87
88instance Functor CaseAlternative where
88instance Functor CaseAlternative where
89
89
src/Language/PureScript/CoreFn/Meta.hs+4−2
@@ -3,6 +3,8 @@
3--
3--
4module Language.PureScript.CoreFn.Meta where
4module Language.PureScript.CoreFn.Meta where
5
5
6+import Prelude.Compat
7+
6import Language.PureScript.Names
8import Language.PureScript.Names
7
9
8-- |
10-- |
@@ -24,7 +26,7 @@ data Meta
24 -- |
26 -- |
25 -- The contained reference is for a foreign member
27 -- The contained reference is for a foreign member
26 --
28 --
27− | IsForeign deriving (Show, Read, Eq)
29+ | IsForeign deriving (Show, Eq)
28
30
29-- |
31-- |
30-- Data constructor metadata
32-- Data constructor metadata
@@ -37,4 +39,4 @@ data ConstructorType
37 -- |
39 -- |
38 -- The constructor is for a type with multiple construcors
40 -- The constructor is for a type with multiple construcors
39 --
41 --
40− | SumType deriving (Show, Read, Eq)
42+ | SumType deriving (Show, Eq)
src/Language/PureScript/CoreFn/Module.hs+6−15
@@ -1,24 +1,15 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CoreFn.Module
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | The CoreFn module representation
12−--
13−-----------------------------------------------------------------------------
14−
15module Language.PureScript.CoreFn.Module where
1module Language.PureScript.CoreFn.Module where
16
2
3+import Prelude.Compat
4+
17import Language.PureScript.Comments
5import Language.PureScript.Comments
18import Language.PureScript.CoreFn.Expr
6import Language.PureScript.CoreFn.Expr
19import Language.PureScript.Names
7import Language.PureScript.Names
20import Language.PureScript.Types
8import Language.PureScript.Types
21
9
10+-- |
11+-- The CoreFn module representation
12+--
22data Module a = Module
13data Module a = Module
23 { moduleComments :: [Comment]
14 { moduleComments :: [Comment]
24 , moduleName :: ModuleName
15 , moduleName :: ModuleName
@@ -26,6 +17,6 @@ data Module a = Module
26 , moduleExports :: [Ident]
17 , moduleExports :: [Ident]
27 , moduleForeign :: [ForeignDecl]
18 , moduleForeign :: [ForeignDecl]
28 , moduleDecls :: [Bind a]
19 , moduleDecls :: [Bind a]
29− } deriving (Show, Read)
20+ } deriving (Show)
30
21
31type ForeignDecl = (Ident, Type)
22type ForeignDecl = (Ident, Type)
src/Language/PureScript/CoreFn/Traversals.hs+3−1
@@ -3,11 +3,13 @@
3--
3--
4module Language.PureScript.CoreFn.Traversals where
4module Language.PureScript.CoreFn.Traversals where
5
5
6+import Prelude.Compat
7+
6import Control.Arrow (second, (***), (+++))
8import Control.Arrow (second, (***), (+++))
7
9
10+import Language.PureScript.AST.Literals
8import Language.PureScript.CoreFn.Binders
11import Language.PureScript.CoreFn.Binders
9import Language.PureScript.CoreFn.Expr
12import Language.PureScript.CoreFn.Expr
10−import Language.PureScript.AST.Literals
11
13
12everywhereOnValues :: (Bind a -> Bind a) ->
14everywhereOnValues :: (Bind a -> Bind a) ->
13 (Expr a -> Expr a) ->
15 (Expr a -> Expr a) ->
src/Language/PureScript/Crash.hs+11−9
@@ -1,9 +1,11 @@
1−module Language.PureScript.Crash where
1+module Language.PureScript.Crash where
2−
2+
3+import Prelude.Compat
4+
3−-- | Exit with an error message and a crash report link.
5+-- | Exit with an error message and a crash report link.
4−internalError :: String -> a
6+internalError :: String -> a
5−internalError =
7+internalError =
6− error
8+ error
7− . ("An internal error ocurred during compilation: " ++)
9+ . ("An internal error ocurred during compilation: " ++)
8− . (++ "\nPlease report this at https://github.com/purescript/purescript/issues")
10+ . (++ "\nPlease report this at https://github.com/purescript/purescript/issues")
9− . show
11+ . show
src/Language/PureScript/Docs.hs+4−4
@@ -6,9 +6,9 @@ module Language.PureScript.Docs (
6 module Docs
6 module Docs
7) where
7) where
8
8
9−import Language.PureScript.Docs.Types as Docs
10−import Language.PureScript.Docs.RenderedCode.Types as Docs
11−import Language.PureScript.Docs.RenderedCode.Render as Docs
12import Language.PureScript.Docs.Convert as Docs
9import Language.PureScript.Docs.Convert as Docs
13−import Language.PureScript.Docs.Render as Docs
14import Language.PureScript.Docs.ParseAndBookmark as Docs
10import Language.PureScript.Docs.ParseAndBookmark as Docs
11+import Language.PureScript.Docs.Render as Docs
12+import Language.PureScript.Docs.RenderedCode.Render as Docs
13+import Language.PureScript.Docs.RenderedCode.Types as Docs
14+import Language.PureScript.Docs.Types as Docs
src/Language/PureScript/Docs/AsMarkdown.hs+18−24
@@ -1,6 +1,3 @@
1−{-# LANGUAGE RecordWildCards #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−
4module Language.PureScript.Docs.AsMarkdown
1module Language.PureScript.Docs.AsMarkdown
5 ( renderModulesAsMarkdown
2 ( renderModulesAsMarkdown
6 , Docs
3 , Docs
@@ -9,19 +6,18 @@ module Language.PureScript.Docs.AsMarkdown
9 , codeToString
6 , codeToString
10 ) where
7 ) where
11
8
12−import Prelude ()
13import Prelude.Compat
9import Prelude.Compat
14
10
15import Control.Monad (unless, zipWithM_)
11import Control.Monad (unless, zipWithM_)
16−import Control.Monad.Writer (Writer, tell, execWriter)
17import Control.Monad.Error.Class (MonadError)
12import Control.Monad.Error.Class (MonadError)
13+import Control.Monad.Writer (Writer, tell, execWriter)
14+
18import Data.Foldable (for_)
15import Data.Foldable (for_)
19import Data.List (partition)
16import Data.List (partition)
20
17
21−import qualified Language.PureScript as P
22−
23−import Language.PureScript.Docs.Types
24import Language.PureScript.Docs.RenderedCode
18import Language.PureScript.Docs.RenderedCode
19+import Language.PureScript.Docs.Types
20+import qualified Language.PureScript as P
25import qualified Language.PureScript.Docs.Convert as Convert
21import qualified Language.PureScript.Docs.Convert as Convert
26import qualified Language.PureScript.Docs.Render as Render
22import qualified Language.PureScript.Docs.Render as Render
27
23
@@ -63,8 +59,6 @@ declAsMarkdown mn decl@Declaration{..} = do
63 zipWithM_ (\f c -> tell' (childToString f c)) (First : repeat NotFirst) children
59 zipWithM_ (\f c -> tell' (childToString f c)) (First : repeat NotFirst) children
64 spacer
60 spacer
65
61
66− for_ declFixity (\fixity -> fixityAsMarkdown fixity >> spacer)
67−
68 for_ declComments tell'
62 for_ declComments tell'
69
63
70 unless (null instances) $ do
64 unless (null instances) $ do
@@ -86,19 +80,19 @@ codeToString = outputWith elemAsMarkdown
86 elemAsMarkdown (Keyword x) = x
80 elemAsMarkdown (Keyword x) = x
87 elemAsMarkdown Space = " "
81 elemAsMarkdown Space = " "
88
82
89−fixityAsMarkdown :: P.Fixity -> Docs
83+-- fixityAsMarkdown :: P.Fixity -> Docs
90−fixityAsMarkdown (P.Fixity associativity precedence) =
84+-- fixityAsMarkdown (P.Fixity associativity precedence) =
91− tell' $ concat [ "_"
85+-- tell' $ concat [ "_"
92− , associativityStr
86+-- , associativityStr
93− , " / precedence "
87+-- , " / precedence "
94− , show precedence
88+-- , show precedence
95− , "_"
89+-- , "_"
96− ]
90+-- ]
97− where
91+-- where
98− associativityStr = case associativity of
92+-- associativityStr = case associativity of
99− P.Infixl -> "left-associative"
93+-- P.Infixl -> "left-associative"
100− P.Infixr -> "right-associative"
94+-- P.Infixr -> "right-associative"
101− P.Infix -> "non-associative"
95+-- P.Infix -> "non-associative"
102
96
103childToString :: First -> ChildDeclaration -> String
97childToString :: First -> ChildDeclaration -> String
104childToString f decl@ChildDeclaration{..} =
98childToString f decl@ChildDeclaration{..} =
@@ -116,7 +110,7 @@ childToString f decl@ChildDeclaration{..} =
116data First
110data First
117 = First
111 = First
118 | NotFirst
112 | NotFirst
119− deriving (Show, Read, Eq, Ord)
113+ deriving (Show, Eq, Ord)
120
114
121type Docs = Writer [String] ()
115type Docs = Writer [String] ()
122
116
src/Language/PureScript/Docs/Convert.hs+12−14
@@ -1,6 +1,4 @@
1−{-# LANGUAGE TupleSections #-}
2{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE FlexibleContexts #-}
4
2
5-- | Functions for converting PureScript ASTs into values of the data types
3-- | Functions for converting PureScript ASTs into values of the data types
6-- from Language.PureScript.Docs.
4-- from Language.PureScript.Docs.
@@ -11,24 +9,23 @@ module Language.PureScript.Docs.Convert
11 , collectBookmarks
9 , collectBookmarks
12 ) where
10 ) where
13
11
14−import Prelude ()
15import Prelude.Compat
12import Prelude.Compat
16
13
17import Control.Arrow ((&&&), second)
14import Control.Arrow ((&&&), second)
18import Control.Category ((>>>))
15import Control.Category ((>>>))
19import Control.Monad
16import Control.Monad
17+import Control.Monad.Error.Class (MonadError)
20import Control.Monad.State (runStateT)
18import Control.Monad.State (runStateT)
21import Control.Monad.Writer.Strict (runWriterT)
19import Control.Monad.Writer.Strict (runWriterT)
22−import Control.Monad.Error.Class (MonadError)
23import qualified Data.Map as Map
20import qualified Data.Map as Map
24
21
25−import Text.Parsec (eof)
26−import qualified Language.PureScript as P
27−import qualified Language.PureScript.Constants as C
28−
29import Language.PureScript.Docs.Convert.ReExports (updateReExports)
22import Language.PureScript.Docs.Convert.ReExports (updateReExports)
30import Language.PureScript.Docs.Convert.Single (convertSingleModule, collectBookmarks)
23import Language.PureScript.Docs.Convert.Single (convertSingleModule, collectBookmarks)
31import Language.PureScript.Docs.Types
24import Language.PureScript.Docs.Types
25+import qualified Language.PureScript as P
26+import qualified Language.PureScript.Constants as C
27+
28+import Text.Parsec (eof)
32
29
33-- |
30-- |
34-- Like convertModules, except that it takes a list of modules, together with
31-- Like convertModules, except that it takes a list of modules, together with
@@ -107,8 +104,9 @@ typeCheckIfNecessary modules convertedModules =
107 else pure convertedModules
104 else pure convertedModules
108
105
109 where
106 where
110− hasWildcards =
107+ hasWildcards = any (isWild . declInfo) . modDeclarations
111− any ((==) (ValueDeclaration P.TypeWildcard) . declInfo) . modDeclarations
108+ isWild (ValueDeclaration P.TypeWildcard{}) = True
109+ isWild _ = False
112
110
113 go = do
111 go = do
114 checkEnv <- snd <$> typeCheck modules
112 checkEnv <- snd <$> typeCheck modules
@@ -147,7 +145,7 @@ insertValueTypes ::
147insertValueTypes env m =
145insertValueTypes env m =
148 m { modDeclarations = map go (modDeclarations m) }
146 m { modDeclarations = map go (modDeclarations m) }
149 where
147 where
150− go (d@Declaration { declInfo = ValueDeclaration P.TypeWildcard }) =
148+ go (d@Declaration { declInfo = ValueDeclaration P.TypeWildcard{} }) =
151 let
149 let
152 ident = parseIdent (declTitle d)
150 ident = parseIdent (declTitle d)
153 ty = lookupName ident
151 ty = lookupName ident
@@ -160,7 +158,7 @@ insertValueTypes env m =
160 either (err . ("failed to parse Ident: " ++)) id . runParser P.parseIdent
158 either (err . ("failed to parse Ident: " ++)) id . runParser P.parseIdent
161
159
162 lookupName name =
160 lookupName name =
163− let key = (modName m, name)
161+ let key = P.Qualified (Just (modName m)) name
164 in case Map.lookup key (P.names env) of
162 in case Map.lookup key (P.names env) of
165 Just (ty, _, _) ->
163 Just (ty, _, _) ->
166 ty
164 ty
@@ -187,8 +185,8 @@ partiallyDesugar = P.evalSupplyT 0 . desugar'
187 where
185 where
188 desugar' =
186 desugar' =
189 traverse P.desugarDoModule
187 traverse P.desugarDoModule
190− >=> P.desugarCasesModule
188+ >=> traverse P.desugarCasesModule
191− >=> P.desugarTypeDeclarationsModule
189+ >=> traverse P.desugarTypeDeclarationsModule
192 >=> ignoreWarnings . P.desugarImportsWithEnv []
190 >=> ignoreWarnings . P.desugarImportsWithEnv []
193
191
194 ignoreWarnings = fmap fst . runWriterT
192 ignoreWarnings = fmap fst . runWriterT
src/Language/PureScript/Docs/Convert/ReExports.hs+81−67
@@ -1,29 +1,24 @@
1−{-# LANGUAGE TupleSections #-}
2−{-# LANGUAGE RecordWildCards #-}
3−{-# LANGUAGE FlexibleContexts #-}
4−
5module Language.PureScript.Docs.Convert.ReExports
1module Language.PureScript.Docs.Convert.ReExports
6 ( updateReExports
2 ( updateReExports
7 ) where
3 ) where
8
4
9−import Prelude ()
10import Prelude.Compat
5import Prelude.Compat
11
6
7+import Control.Arrow ((&&&), second)
12import Control.Monad
8import Control.Monad
13−import Control.Monad.Trans.State.Strict (execState)
9+import Control.Monad.Reader.Class (MonadReader, ask)
14import Control.Monad.State.Class (MonadState, gets, modify)
10import Control.Monad.State.Class (MonadState, gets, modify)
15import Control.Monad.Trans.Reader (runReaderT)
11import Control.Monad.Trans.Reader (runReaderT)
16−import Control.Monad.Reader.Class (MonadReader, ask)
12+import Control.Monad.Trans.State.Strict (execState)
17−import Control.Arrow ((&&&), first, second)
13+
18import Data.Either
14import Data.Either
19−import Data.Maybe (mapMaybe)
20import Data.Map (Map)
15import Data.Map (Map)
21−import qualified Data.Map as Map
16+import Data.Maybe (mapMaybe)
22import Data.Monoid ((<>))
17import Data.Monoid ((<>))
23−
24−import qualified Language.PureScript as P
18+import qualified Data.Map as Map
25
19
26import Language.PureScript.Docs.Types
20import Language.PureScript.Docs.Types
21+import qualified Language.PureScript as P
27
22
28-- |
23-- |
29-- Given:
24-- Given:
@@ -40,8 +35,7 @@ updateReExports ::
40 [P.ModuleName] ->
35 [P.ModuleName] ->
41 Map P.ModuleName Module ->
36 Map P.ModuleName Module ->
42 Map P.ModuleName Module
37 Map P.ModuleName Module
43−updateReExports env order modules =
38+updateReExports env order = execState action
44− execState action modules
45 where
39 where
46 action =
40 action =
47 void (traverse go order)
41 void (traverse go order)
@@ -102,39 +96,50 @@ getReExports env mn =
102-- * Filters type class declarations to ensure that only re-exported type
96-- * Filters type class declarations to ensure that only re-exported type
103-- class members are listed.
97-- class members are listed.
104--
98--
105−collectDeclarations ::
99+collectDeclarations :: forall m.
106 (MonadState (Map P.ModuleName Module) m, MonadReader P.ModuleName m) =>
100 (MonadState (Map P.ModuleName Module) m, MonadReader P.ModuleName m) =>
107 P.Imports ->
101 P.Imports ->
108 P.Exports ->
102 P.Exports ->
109 m [(P.ModuleName, [Declaration])]
103 m [(P.ModuleName, [Declaration])]
110collectDeclarations imports exports = do
104collectDeclarations imports exports = do
111− valsAndMembers <- collect lookupValueDeclaration impVals expVals
105+ valsAndMembers <- collect lookupValueDeclaration impVals expVals
106+ valOps <- collect lookupValueOpDeclaration impValOps expValOps
112− typeClasses <- collect lookupTypeClassDeclaration impTCs expTCs
107+ typeClasses <- collect lookupTypeClassDeclaration impTCs expTCs
113− types <- collect lookupTypeDeclaration impTypes expTypes
108+ types <- collect lookupTypeDeclaration impTypes expTypes
114− typeOps <- collect lookupTypeOpDeclaration impTypeOps expTypeOps
109+ typeOps <- collect lookupTypeOpDeclaration impTypeOps expTypeOps
115
110
116 (vals, classes) <- handleTypeClassMembers valsAndMembers typeClasses
111 (vals, classes) <- handleTypeClassMembers valsAndMembers typeClasses
117
112
118 let filteredTypes = filterDataConstructors expCtors types
113 let filteredTypes = filterDataConstructors expCtors types
119− let filteredClasses = filterTypeClassMembers (map fst expVals) classes
114+ let filteredClasses = filterTypeClassMembers (Map.keys expVals) classes
120
115
121− pure (Map.toList (Map.unionsWith (<>) [filteredTypes, typeOps, filteredClasses, vals]))
116+ pure (Map.toList (Map.unionsWith (<>) [filteredTypes, filteredClasses, vals, valOps, typeOps]))
122
117
123 where
118 where
119+
120+ collect
121+ :: (Eq a, Show a)
122+ => (P.ModuleName -> a -> m (P.ModuleName, [b]))
123+ -> [P.ImportRecord a]
124+ -> Map a P.ModuleName
125+ -> m (Map P.ModuleName [b])
124 collect lookup' imps exps = do
126 collect lookup' imps exps = do
125− imps' <- traverse (findImport imps) exps
127+ imps' <- traverse (findImport imps) $ Map.toList exps
126 Map.fromListWith (<>) <$> traverse (uncurry lookup') imps'
128 Map.fromListWith (<>) <$> traverse (uncurry lookup') imps'
127
129
128 expVals = P.exportedValues exports
130 expVals = P.exportedValues exports
129 impVals = concat (Map.elems (P.importedValues imports))
131 impVals = concat (Map.elems (P.importedValues imports))
130
132
133+ expValOps = P.exportedValueOps exports
134+ impValOps = concat (Map.elems (P.importedValueOps imports))
135+
131− expTypes = map (first fst) (P.exportedTypes exports)
136+ expTypes = Map.map snd (P.exportedTypes exports)
132 impTypes = concat (Map.elems (P.importedTypes imports))
137 impTypes = concat (Map.elems (P.importedTypes imports))
133
138
134 expTypeOps = P.exportedTypeOps exports
139 expTypeOps = P.exportedTypeOps exports
135 impTypeOps = concat (Map.elems (P.importedTypeOps imports))
140 impTypeOps = concat (Map.elems (P.importedTypeOps imports))
136
141
137− expCtors = concatMap (snd . fst) (P.exportedTypes exports)
142+ expCtors = concatMap fst (Map.elems (P.exportedTypes exports))
138
143
139 expTCs = P.exportedTypeClasses exports
144 expTCs = P.exportedTypeClasses exports
140 impTCs = concat (Map.elems (P.importedTypeClasses imports))
145 impTCs = concat (Map.elems (P.importedTypeClasses imports))
@@ -226,6 +231,20 @@ lookupValueDeclaration importedFrom ident = do
226 thd :: (a, b, c) -> c
231 thd :: (a, b, c) -> c
227 thd (_, _, x) = x
232 thd (_, _, x) = x
228
233
234+lookupValueOpDeclaration
235+ :: (MonadState (Map P.ModuleName Module) m, MonadReader P.ModuleName m)
236+ => P.ModuleName
237+ -> P.OpName 'P.ValueOpName
238+ -> m (P.ModuleName, [Declaration])
239+lookupValueOpDeclaration importedFrom op = do
240+ decls <- lookupModuleDeclarations "lookupValueOpDeclaration" importedFrom
241+ case filter (\d -> declTitle d == P.showOp op && isValueAlias d) decls of
242+ [d] ->
243+ pure (importedFrom, [d])
244+ other ->
245+ internalErrorInModule
246+ ("lookupValueOpDeclaration: unexpected result for: " ++ show other)
247+
229-- |
248-- |
230-- Extract a particular type declaration. For data declarations, constructors
249-- Extract a particular type declaration. For data declarations, constructors
231-- are only included in the output if they are listed in the arguments.
250-- are only included in the output if they are listed in the arguments.
@@ -247,16 +266,15 @@ lookupTypeDeclaration importedFrom ty = do
247 internalErrorInModule
266 internalErrorInModule
248 ("lookupTypeDeclaration: unexpected result: " ++ show other)
267 ("lookupTypeDeclaration: unexpected result: " ++ show other)
249
268
250−lookupTypeOpDeclaration ::
269+lookupTypeOpDeclaration
251− (MonadState (Map P.ModuleName Module) m,
270+ :: (MonadState (Map P.ModuleName Module) m,MonadReader P.ModuleName m)
252− MonadReader P.ModuleName m) =>
253− P.ModuleName ->
271+ => P.ModuleName
254− P.Ident ->
272+ -> P.OpName 'P.TypeOpName
255− m (P.ModuleName, [Declaration])
273+ -> m (P.ModuleName, [Declaration])
256lookupTypeOpDeclaration importedFrom tyOp = do
274lookupTypeOpDeclaration importedFrom tyOp = do
257 decls <- lookupModuleDeclarations "lookupTypeOpDeclaration" importedFrom
275 decls <- lookupModuleDeclarations "lookupTypeOpDeclaration" importedFrom
258 let
276 let
259− ds = filter (\d -> declTitle d == ("type " ++ P.showIdent tyOp) && isTypeAlias d) decls
277+ ds = filter (\d -> declTitle d == ("type " ++ P.showOp tyOp) && isTypeAlias d) decls
260 case ds of
278 case ds of
261 [d] ->
279 [d] ->
262 pure (importedFrom, [d])
280 pure (importedFrom, [d])
@@ -264,12 +282,11 @@ lookupTypeOpDeclaration importedFrom tyOp = do
264 internalErrorInModule
282 internalErrorInModule
265 ("lookupTypeOpDeclaration: unexpected result: " ++ show other)
283 ("lookupTypeOpDeclaration: unexpected result: " ++ show other)
266
284
267−lookupTypeClassDeclaration ::
285+lookupTypeClassDeclaration
268− (MonadState (Map P.ModuleName Module) m,
286+ :: (MonadState (Map P.ModuleName Module) m, MonadReader P.ModuleName m)
269− MonadReader P.ModuleName m) =>
270− P.ModuleName ->
287+ => P.ModuleName
271− P.ProperName 'P.ClassName ->
288+ -> P.ProperName 'P.ClassName
272− m (P.ModuleName, [Declaration])
289+ -> m (P.ModuleName, [Declaration])
273lookupTypeClassDeclaration importedFrom tyClass = do
290lookupTypeClassDeclaration importedFrom tyClass = do
274 decls <- lookupModuleDeclarations "lookupTypeClassDeclaration" importedFrom
291 decls <- lookupModuleDeclarations "lookupTypeClassDeclaration" importedFrom
275 let
292 let
@@ -374,10 +391,10 @@ instance Monoid TypeClassEnv where
374--
391--
375-- Returns a tuple of (values, type classes).
392-- Returns a tuple of (values, type classes).
376--
393--
377−handleEnv ::
394+handleEnv
378− (MonadReader P.ModuleName m) =>
395+ :: (MonadReader P.ModuleName m)
379− TypeClassEnv ->
396+ => TypeClassEnv
380− m ([Declaration], [Declaration])
397+ -> m ([Declaration], [Declaration])
381handleEnv TypeClassEnv{..} =
398handleEnv TypeClassEnv{..} =
382 envUnhandledMembers
399 envUnhandledMembers
383 |> foldM go (envValues, mkMap envTypeClasses)
400 |> foldM go (envValues, mkMap envTypeClasses)
@@ -405,7 +422,6 @@ handleEnv TypeClassEnv{..} =
405 , declComments = cdeclComments
422 , declComments = cdeclComments
406 , declSourceSpan = cdeclSourceSpan
423 , declSourceSpan = cdeclSourceSpan
407 , declChildren = []
424 , declChildren = []
408− , declFixity = Nothing
409 , declInfo = ValueDeclaration (addConstraint constraint typ)
425 , declInfo = ValueDeclaration (addConstraint constraint typ)
410 }
426 }
411 _ ->
427 _ ->
@@ -426,10 +442,10 @@ splitMap = foldl go (Map.empty, Map.empty) . Map.toList
426-- Given a list of exported constructor names, remove any data constructor
442-- Given a list of exported constructor names, remove any data constructor
427-- names in the provided Map of declarations which are not in the list.
443-- names in the provided Map of declarations which are not in the list.
428--
444--
429−filterDataConstructors ::
445+filterDataConstructors
430− [P.ProperName 'P.ConstructorName] ->
446+ :: [P.ProperName 'P.ConstructorName]
431− Map P.ModuleName [Declaration] ->
447+ -> Map P.ModuleName [Declaration]
432− Map P.ModuleName [Declaration]
448+ -> Map P.ModuleName [Declaration]
433filterDataConstructors =
449filterDataConstructors =
434 filterExportedChildren isDataConstructor P.runProperName
450 filterExportedChildren isDataConstructor P.runProperName
435
451
@@ -438,27 +454,25 @@ filterDataConstructors =
438-- type class member names in the provided Map of declarations which are not in
454-- type class member names in the provided Map of declarations which are not in
439-- the list.
455-- the list.
440--
456--
441−filterTypeClassMembers ::
457+filterTypeClassMembers
442− [P.Ident] ->
458+ :: [P.Ident]
443− Map P.ModuleName [Declaration] ->
459+ -> Map P.ModuleName [Declaration]
444− Map P.ModuleName [Declaration]
460+ -> Map P.ModuleName [Declaration]
445filterTypeClassMembers =
461filterTypeClassMembers =
446 filterExportedChildren isTypeClassMember P.showIdent
462 filterExportedChildren isTypeClassMember P.showIdent
447
463
448−filterExportedChildren ::
464+filterExportedChildren
449− (Functor f) =>
465+ :: (Functor f)
450− (ChildDeclaration -> Bool) ->
466+ => (ChildDeclaration -> Bool)
451− (name -> String) ->
467+ -> (name -> String)
452− [name] ->
468+ -> [name]
453− f [Declaration] ->
469+ -> f [Declaration]
454− f [Declaration]
470+ -> f [Declaration]
455−filterExportedChildren isTargetedKind runName expNames =
471+filterExportedChildren isTargetedKind runName expNames = fmap filterDecls
456− fmap filterDecls
457 where
472 where
458 filterDecls =
473 filterDecls =
459− map (filterChildren (\c -> not (isTargetedKind c) ||
474+ map $ filterChildren $ \c ->
460− cdeclTitle c `elem` expNames'))
475+ not (isTargetedKind c) || cdeclTitle c `elem` expNames'
461−
462 expNames' = map runName expNames
476 expNames' = map runName expNames
463
477
464allDeclarations :: Module -> [Declaration]
478allDeclarations :: Module -> [Declaration]
@@ -471,10 +485,10 @@ x |> f = f x
471internalError :: String -> a
485internalError :: String -> a
472internalError = P.internalError . ("Docs.Convert.ReExports: " ++)
486internalError = P.internalError . ("Docs.Convert.ReExports: " ++)
473
487
474−internalErrorInModule ::
488+internalErrorInModule
475− (MonadReader P.ModuleName m) =>
489+ :: (MonadReader P.ModuleName m)
476− String ->
490+ => String
477− m a
491+ -> m a
478internalErrorInModule msg = do
492internalErrorInModule msg = do
479 mn <- ask
493 mn <- ask
480 internalError
494 internalError
@@ -489,7 +503,7 @@ typeClassConstraintFor :: Declaration -> Maybe P.Constraint
489typeClassConstraintFor Declaration{..} =
503typeClassConstraintFor Declaration{..} =
490 case declInfo of
504 case declInfo of
491 TypeClassDeclaration tyArgs _ ->
505 TypeClassDeclaration tyArgs _ ->
492− Just (P.Qualified Nothing (P.ProperName declTitle), mkConstraint tyArgs)
506+ Just (P.Constraint (P.Qualified Nothing (P.ProperName declTitle)) (mkConstraint tyArgs) Nothing)
493 _ ->
507 _ ->
494 Nothing
508 Nothing
495 where
509 where
src/Language/PureScript/Docs/Convert/Single.hs+16−52
@@ -1,26 +1,19 @@
1−{-# LANGUAGE TupleSections #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
4−{-# LANGUAGE ViewPatterns #-}
5−{-# LANGUAGE FlexibleContexts #-}
6−
7module Language.PureScript.Docs.Convert.Single
1module Language.PureScript.Docs.Convert.Single
8 ( convertSingleModule
2 ( convertSingleModule
9 , collectBookmarks
3 , collectBookmarks
10 ) where
4 ) where
11
5
12−import Prelude ()
13import Prelude.Compat
6import Prelude.Compat
14−import Data.Maybe (mapMaybe, isNothing)
15
7
16−import Control.Monad
17import Control.Category ((>>>))
8import Control.Category ((>>>))
18−import Data.Either
9+import Control.Monad
19−import Data.List (nub, isPrefixOf, isSuffixOf)
20
10
21−import qualified Language.PureScript as P
11+import Data.Either
12+import Data.List (nub)
13+import Data.Maybe (mapMaybe)
22
14
23import Language.PureScript.Docs.Types
15import Language.PureScript.Docs.Types
16+import qualified Language.PureScript as P
24
17
25-- |
18-- |
26-- Convert a single Module, but ignore re-exports; any re-exported types or
19-- Convert a single Module, but ignore re-exports; any re-exported types or
@@ -35,7 +28,6 @@ convertSingleModule m@(P.Module _ coms moduleName _ _) =
35 P.exportedDeclarations
28 P.exportedDeclarations
36 >>> mapMaybe (\d -> getDeclarationTitle d >>= convertDeclaration d)
29 >>> mapMaybe (\d -> getDeclarationTitle d >>= convertDeclaration d)
37 >>> augmentDeclarations
30 >>> augmentDeclarations
38− >>> map addDefaultFixity
39
31
40-- | The data type for an intermediate stage which we go through during
32-- | The data type for an intermediate stage which we go through during
41-- converting.
33-- converting.
@@ -65,12 +57,8 @@ type IntermediateDeclaration
65-- since they appear at the top level in the AST, and since they might need to
57-- since they appear at the top level in the AST, and since they might need to
66-- appear as children in two places (for example, if a data type defined in a
58-- appear as children in two places (for example, if a data type defined in a
67-- module is an instance of a type class also defined in that module).
59-- module is an instance of a type class also defined in that module).
68−--
69−-- The AugmentFixity constructor allows us to augment operator definitions
70−-- with their associativity and precedence.
71data DeclarationAugment
60data DeclarationAugment
72 = AugmentChild ChildDeclaration
61 = AugmentChild ChildDeclaration
73− | AugmentFixity P.Fixity
74
62
75-- | Augment top-level declarations; the second pass. See the comments under
63-- | Augment top-level declarations; the second pass. See the comments under
76-- the type synonym IntermediateDeclaration for more information.
64-- the type synonym IntermediateDeclaration for more information.
@@ -84,28 +72,8 @@ augmentDeclarations (partitionEithers -> (augments, toplevels)) =
84 then augmentWith a d
72 then augmentWith a d
85 else d) ds
73 else d) ds
86
74
87− augmentWith a d =
75+ augmentWith (AugmentChild child) d =
88− case a of
89− AugmentChild child ->
90− d { declChildren = declChildren d ++ [child] }
76+ d { declChildren = declChildren d ++ [child] }
91− AugmentFixity fixity ->
92− d { declFixity = Just fixity }
93−
94−-- | Add the default operator fixity for operators which do not have associated
95−-- fixity declarations.
96−--
97−-- TODO: This may no longer be necessary after issue 806 is resolved, hopefully
98−-- in 0.9.
99−addDefaultFixity :: Declaration -> Declaration
100−addDefaultFixity decl@Declaration{..}
101− | isOp declTitle && isNothing declFixity =
102− decl { declFixity = Just defaultFixity }
103− | otherwise =
104− decl
105− where
106− isOp :: String -> Bool
107− isOp str = "(" `isPrefixOf` str && ")" `isSuffixOf` str
108− defaultFixity = P.Fixity P.Infixl (-1)
109
77
110getDeclarationTitle :: P.Declaration -> Maybe String
78getDeclarationTitle :: P.Declaration -> Maybe String
111getDeclarationTitle (P.ValueDeclaration name _ _ _) = Just (P.showIdent name)
79getDeclarationTitle (P.ValueDeclaration name _ _ _) = Just (P.showIdent name)
@@ -115,8 +83,8 @@ getDeclarationTitle (P.ExternDataDeclaration name _) = Just (P.runProperName nam
115getDeclarationTitle (P.TypeSynonymDeclaration name _ _) = Just (P.runProperName name)
83getDeclarationTitle (P.TypeSynonymDeclaration name _ _) = Just (P.runProperName name)
116getDeclarationTitle (P.TypeClassDeclaration name _ _ _) = Just (P.runProperName name)
84getDeclarationTitle (P.TypeClassDeclaration name _ _ _) = Just (P.runProperName name)
117getDeclarationTitle (P.TypeInstanceDeclaration name _ _ _ _) = Just (P.showIdent name)
85getDeclarationTitle (P.TypeInstanceDeclaration name _ _ _ _) = Just (P.showIdent name)
118−getDeclarationTitle (P.FixityDeclaration _ name (Just (P.Qualified _ P.AliasType{}))) = Just ("type (" ++ name ++ ")")
86+getDeclarationTitle (P.TypeFixityDeclaration _ _ op) = Just ("type " ++ P.showOp op)
119−getDeclarationTitle (P.FixityDeclaration _ name _) = Just ("(" ++ name ++ ")")
87+getDeclarationTitle (P.ValueFixityDeclaration _ _ op) = Just (P.showOp op)
120getDeclarationTitle (P.PositionedDeclaration _ _ d) = getDeclarationTitle d
88getDeclarationTitle (P.PositionedDeclaration _ _ d) = getDeclarationTitle d
121getDeclarationTitle _ = Nothing
89getDeclarationTitle _ = Nothing
122
90
@@ -127,7 +95,6 @@ mkDeclaration title info =
127 , declComments = Nothing
95 , declComments = Nothing
128 , declSourceSpan = Nothing
96 , declSourceSpan = Nothing
129 , declChildren = []
97 , declChildren = []
130− , declFixity = Nothing
131 , declInfo = info
98 , declInfo = info
132 }
99 }
133
100
@@ -137,10 +104,10 @@ basicDeclaration title info = Just $ Right $ mkDeclaration title info
137convertDeclaration :: P.Declaration -> String -> Maybe IntermediateDeclaration
104convertDeclaration :: P.Declaration -> String -> Maybe IntermediateDeclaration
138convertDeclaration (P.ValueDeclaration _ _ _ (Right (P.TypedValue _ _ ty))) title =
105convertDeclaration (P.ValueDeclaration _ _ _ (Right (P.TypedValue _ _ ty))) title =
139 basicDeclaration title (ValueDeclaration ty)
106 basicDeclaration title (ValueDeclaration ty)
140−convertDeclaration (P.ValueDeclaration {}) title =
107+convertDeclaration P.ValueDeclaration{} title =
141 -- If no explicit type declaration was provided, insert a wildcard, so that
108 -- If no explicit type declaration was provided, insert a wildcard, so that
142 -- the actual type will be added during type checking.
109 -- the actual type will be added during type checking.
143− basicDeclaration title (ValueDeclaration P.TypeWildcard)
110+ basicDeclaration title (ValueDeclaration P.TypeWildcard{})
144convertDeclaration (P.ExternDeclaration _ ty) title =
111convertDeclaration (P.ExternDeclaration _ ty) title =
145 basicDeclaration title (ValueDeclaration ty)
112 basicDeclaration title (ValueDeclaration ty)
146convertDeclaration (P.DataDeclaration dtype _ args ctors) title =
113convertDeclaration (P.DataDeclaration dtype _ args ctors) title =
@@ -177,10 +144,10 @@ convertDeclaration (P.TypeInstanceDeclaration _ constraints className tys _) tit
177
144
178 childDecl = ChildDeclaration title Nothing Nothing (ChildInstance constraints classApp)
145 childDecl = ChildDeclaration title Nothing Nothing (ChildInstance constraints classApp)
179 classApp = foldl P.TypeApp (P.TypeConstructor (fmap P.coerceProperName className)) tys
146 classApp = foldl P.TypeApp (P.TypeConstructor (fmap P.coerceProperName className)) tys
180−convertDeclaration (P.FixityDeclaration fixity _ Nothing) title =
147+convertDeclaration (P.ValueFixityDeclaration fixity (P.Qualified mn alias) _) title =
181− Just (Left ([title], AugmentFixity fixity))
148+ Just $ Right $ mkDeclaration title (AliasDeclaration fixity (P.Qualified mn (Right alias)))
182−convertDeclaration (P.FixityDeclaration fixity _ (Just alias)) title =
149+convertDeclaration (P.TypeFixityDeclaration fixity (P.Qualified mn alias) _) title =
183− Just $ Right $ (mkDeclaration title (AliasDeclaration alias fixity)) { declFixity = Just fixity }
150+ Just $ Right $ mkDeclaration title (AliasDeclaration fixity (P.Qualified mn (Left alias)))
184convertDeclaration (P.PositionedDeclaration srcSpan com d') title =
151convertDeclaration (P.PositionedDeclaration srcSpan com d') title =
185 fmap (addComments . addSourceSpan) (convertDeclaration d' title)
152 fmap (addComments . addSourceSpan) (convertDeclaration d' title)
186 where
153 where
@@ -196,10 +163,7 @@ convertDeclaration (P.PositionedDeclaration srcSpan com d') title =
196 Left (withAugmentChild (\d -> d { cdeclSourceSpan = Just srcSpan })
163 Left (withAugmentChild (\d -> d { cdeclSourceSpan = Just srcSpan })
197 augment)
164 augment)
198
165
199− withAugmentChild f (t, a) =
166+ withAugmentChild f (t, AugmentChild d) = (t, AugmentChild (f d))
200− case a of
201− AugmentChild d -> (t, AugmentChild (f d))
202− _ -> (t, a)
203convertDeclaration _ _ = Nothing
167convertDeclaration _ _ = Nothing
204
168
205convertComments :: [P.Comment] -> Maybe String
169convertComments :: [P.Comment] -> Maybe String
src/Language/PureScript/Docs/ParseAndBookmark.hs+7−11
@@ -1,26 +1,22 @@
1−{-# LANGUAGE TupleSections #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−
4module Language.PureScript.Docs.ParseAndBookmark
1module Language.PureScript.Docs.ParseAndBookmark
5 ( parseAndBookmark
2 ( parseAndBookmark
6 ) where
3 ) where
7
4
8−import Prelude ()
9import Prelude.Compat
5import Prelude.Compat
10
6
11−import qualified Data.Map as M
12import Control.Arrow (first)
7import Control.Arrow (first)
13−
14import Control.Monad.Error.Class (MonadError(..))
8import Control.Monad.Error.Class (MonadError(..))
15import Control.Monad.IO.Class (MonadIO(..))
9import Control.Monad.IO.Class (MonadIO(..))
16
10
17−import Web.Bower.PackageMeta (PackageName)
11+import qualified Data.Map as M
12+
13+import Language.PureScript.Docs.Convert (collectBookmarks)
14+import Language.PureScript.Docs.Types
15+import qualified Language.PureScript as P
18
16
19import System.IO.UTF8 (readUTF8File)
17import System.IO.UTF8 (readUTF8File)
20
18
21−import qualified Language.PureScript as P
19+import Web.Bower.PackageMeta (PackageName)
22−import Language.PureScript.Docs.Types
23−import Language.PureScript.Docs.Convert (collectBookmarks)
24
20
25-- |
21-- |
26-- Given:
22-- Given:
@@ -48,7 +44,7 @@ parseAndBookmark inputFiles depsFiles = do
48 addBookmarks <$> parseFiles (inputFiles' ++ depsFiles')
44 addBookmarks <$> parseFiles (inputFiles' ++ depsFiles')
49
45
50parseFiles ::
46parseFiles ::
51− (MonadError P.MultipleErrors m, MonadIO m) =>
47+ (MonadError P.MultipleErrors m) =>
52 [(FileInfo, FilePath)]
48 [(FileInfo, FilePath)]
53 -> m [(FileInfo, P.Module)]
49 -> m [(FileInfo, P.Module)]
54parseFiles =
50parseFiles =
src/Language/PureScript/Docs/Render.hs+26−19
@@ -1,6 +1,5 @@
1−{-# LANGUAGE RecordWildCards #-}
1+-- |
2−
3−-- | Functions for creating `RenderedCode` values from data types in
2+-- Functions for creating `RenderedCode` values from data types in
4-- Language.PureScript.Docs.Types.
3-- Language.PureScript.Docs.Types.
5--
4--
6-- These functions are the ones that are used in markdown/html documentation
5-- These functions are the ones that are used in markdown/html documentation
@@ -10,13 +9,15 @@
10
9
11module Language.PureScript.Docs.Render where
10module Language.PureScript.Docs.Render where
12
11
12+import Prelude.Compat
13+
13import Data.Maybe (maybeToList)
14import Data.Maybe (maybeToList)
14import Data.Monoid ((<>))
15import Data.Monoid ((<>))
15−import qualified Language.PureScript as P
16
16
17−import Language.PureScript.Docs.Types
18import Language.PureScript.Docs.RenderedCode
17import Language.PureScript.Docs.RenderedCode
18+import Language.PureScript.Docs.Types
19import Language.PureScript.Docs.Utils.MonoidExtras
19import Language.PureScript.Docs.Utils.MonoidExtras
20+import qualified Language.PureScript as P
20
21
21renderDeclaration :: Declaration -> RenderedCode
22renderDeclaration :: Declaration -> RenderedCode
22renderDeclaration = renderDeclarationWithOptions defaultRenderTypeOptions
23renderDeclaration = renderDeclarationWithOptions defaultRenderTypeOptions
@@ -58,27 +59,33 @@ renderDeclarationWithOptions opts Declaration{..} =
58 syntax "("
59 syntax "("
59 <> mintersperse (syntax "," <> sp) (map renderConstraint implies)
60 <> mintersperse (syntax "," <> sp) (map renderConstraint implies)
60 <> syntax ")" <> sp <> syntax "<="
61 <> syntax ")" <> sp <> syntax "<="
62+
61− AliasDeclaration for@(P.Qualified _ alias) (P.Fixity associativity precedence) ->
63+ AliasDeclaration (P.Fixity associativity precedence) for@(P.Qualified _ alias) ->
62 [ keywordFixity associativity
64 [ keywordFixity associativity
63 , syntax $ show precedence
65 , syntax $ show precedence
64− , ident $ renderAlias for
66+ , ident $ renderQualAlias for
65 , keyword "as"
67 , keyword "as"
66 , ident $ adjustAliasName alias declTitle
68 , ident $ adjustAliasName alias declTitle
67 ]
69 ]
68
70
69 where
71 where
72+ renderType' :: P.Type -> RenderedCode
70 renderType' = renderTypeWithOptions opts
73 renderType' = renderTypeWithOptions opts
74+
75+ renderQualAlias :: FixityAlias -> String
71− renderAlias (P.Qualified mn alias)
76+ renderQualAlias (P.Qualified mn alias)
72− | mn == currentModule opts =
77+ | mn == currentModule opts = renderAlias id alias
73− P.foldFixityAlias P.runIdent P.runProperName (("type " ++) . P.runProperName) alias
74− | otherwise =
75− P.foldFixityAlias
76− (P.showQualified P.runIdent . P.Qualified mn)
78+ | otherwise = renderAlias (\f -> P.showQualified f . P.Qualified mn) alias
77− (P.showQualified P.runProperName . P.Qualified mn)
79+
78− (("type " ++) . P.showQualified P.runProperName . P.Qualified mn)
80+ renderAlias
79− alias
81+ :: (forall a. (a -> String) -> a -> String)
80−
82+ -> Either (P.ProperName 'P.TypeName) (Either P.Ident (P.ProperName 'P.ConstructorName))
83+ -> String
84+ renderAlias f
85+ = either (("type " ++) . f P.runProperName)
86+ $ either (f P.runIdent) (f P.runProperName)
87+
81− adjustAliasName (P.AliasType{}) title = drop 6 (init title)
88+ -- adjustAliasName (P.AliasType{}) title = drop 6 (init title)
82 adjustAliasName _ title = tail (init title)
89 adjustAliasName _ title = tail (init title)
83
90
84renderChildDeclaration :: ChildDeclaration -> RenderedCode
91renderChildDeclaration :: ChildDeclaration -> RenderedCode
@@ -107,7 +114,7 @@ renderConstraint :: P.Constraint -> RenderedCode
107renderConstraint = renderConstraintWithOptions defaultRenderTypeOptions
114renderConstraint = renderConstraintWithOptions defaultRenderTypeOptions
108
115
109renderConstraintWithOptions :: RenderTypeOptions -> P.Constraint -> RenderedCode
116renderConstraintWithOptions :: RenderTypeOptions -> P.Constraint -> RenderedCode
110−renderConstraintWithOptions opts (pn, tys) =
117+renderConstraintWithOptions opts (P.Constraint pn tys _) =
111 renderTypeWithOptions opts $ foldl P.TypeApp (P.TypeConstructor (fmap P.coerceProperName pn)) tys
118 renderTypeWithOptions opts $ foldl P.TypeApp (P.TypeConstructor (fmap P.coerceProperName pn)) tys
112
119
113renderConstraints :: [P.Constraint] -> Maybe RenderedCode
120renderConstraints :: [P.Constraint] -> Maybe RenderedCode
src/Language/PureScript/Docs/RenderedCode.hs+8−11
@@ -1,11 +1,8 @@
1−
1+
2−-- | Data types and functions for representing a simplified form of PureScript
2+-- | Data types and functions for representing a simplified form of PureScript
3−-- code, intended for use in e.g. HTML documentation.
3+-- code, intended for use in e.g. HTML documentation.
4−
4+
5−module Language.PureScript.Docs.RenderedCode (
5+module Language.PureScript.Docs.RenderedCode (module RenderedCode) where
6− module RenderedCode
6+
7−) where
8−
9−import Language.PureScript.Docs.RenderedCode.Types as RenderedCode
7+import Language.PureScript.Docs.RenderedCode.Types as RenderedCode
10−import Language.PureScript.Docs.RenderedCode.Render as RenderedCode
8+import Language.PureScript.Docs.RenderedCode.Render as RenderedCode
11−
src/Language/PureScript/Docs/RenderedCode/Render.hs+29−28
@@ -1,38 +1,36 @@
1-- | Functions for producing RenderedCode values from PureScript Type values.
1-- | Functions for producing RenderedCode values from PureScript Type values.
2
2
3−module Language.PureScript.Docs.RenderedCode.Render (
3+module Language.PureScript.Docs.RenderedCode.Render
4− renderType,
4+ ( renderType
5− renderTypeAtom,
5+ , renderTypeAtom
6− renderRow,
6+ , renderRow
7− renderKind,
7+ , renderKind
8− RenderTypeOptions(..),
8+ , RenderTypeOptions(..)
9− defaultRenderTypeOptions,
9+ , defaultRenderTypeOptions
10− renderTypeWithOptions
10+ , renderTypeWithOptions
11−) where
11+ ) where
12−
12+
13−import Prelude ()
14import Prelude.Compat
13import Prelude.Compat
15
14
16−import Data.Monoid ((<>))
17import Data.Maybe (fromMaybe)
15import Data.Maybe (fromMaybe)
16+import Data.Monoid ((<>))
18
17
19import Control.Arrow ((<+>))
18import Control.Arrow ((<+>))
20−import Control.PatternArrows
19+import Control.PatternArrows as PA
21
20
22import Language.PureScript.Crash
21import Language.PureScript.Crash
23−import Language.PureScript.Names
24−import Language.PureScript.Types
25−import Language.PureScript.Kinds
26−import Language.PureScript.Pretty.Kinds
27−import Language.PureScript.Environment
28−
29import Language.PureScript.Docs.RenderedCode.Types
22import Language.PureScript.Docs.RenderedCode.Types
30import Language.PureScript.Docs.Utils.MonoidExtras
23import Language.PureScript.Docs.Utils.MonoidExtras
24+import Language.PureScript.Environment
25+import Language.PureScript.Kinds
26+import Language.PureScript.Names
27+import Language.PureScript.Pretty.Kinds
28+import Language.PureScript.Types
31
29
32typeLiterals :: Pattern () Type RenderedCode
30typeLiterals :: Pattern () Type RenderedCode
33typeLiterals = mkPattern match
31typeLiterals = mkPattern match
34 where
32 where
35− match TypeWildcard =
33+ match TypeWildcard{} =
36 Just (syntax "_")
34 Just (syntax "_")
37 match (TypeVar var) =
35 match (TypeVar var) =
38 Just (ident var)
36 Just (ident var)
@@ -51,12 +49,12 @@ typeLiterals = mkPattern match
51 match (BinaryNoParensType op l r) =
49 match (BinaryNoParensType op l r) =
52 Just $ renderTypeAtom l <> sp <> renderTypeAtom op <> sp <> renderTypeAtom r
50 Just $ renderTypeAtom l <> sp <> renderTypeAtom op <> sp <> renderTypeAtom r
53 match (TypeOp (Qualified mn op)) =
51 match (TypeOp (Qualified mn op)) =
54− Just (ident' (runIdent op) (maybeToContainingModule mn))
52+ Just (ident' (runOpName op) (maybeToContainingModule mn))
55 match _ =
53 match _ =
56 Nothing
54 Nothing
57
55
58renderConstraint :: Constraint -> RenderedCode
56renderConstraint :: Constraint -> RenderedCode
59−renderConstraint (pn, tys) =
57+renderConstraint (Constraint pn tys _) =
60 let instApp = foldl TypeApp (TypeConstructor (fmap coerceProperName pn)) tys
58 let instApp = foldl TypeApp (TypeConstructor (fmap coerceProperName pn)) tys
61 in renderType instApp
59 in renderType instApp
62
60
@@ -161,7 +159,7 @@ dePrim other = other
161
159
162convert :: RenderTypeOptions -> Type -> Type
160convert :: RenderTypeOptions -> Type -> Type
163convert _ (TypeApp (TypeApp f arg) ret) | f == tyFunction = PrettyPrintFunction arg ret
161convert _ (TypeApp (TypeApp f arg) ret) | f == tyFunction = PrettyPrintFunction arg ret
164−convert opts (TypeApp o r) | o == tyObject && prettyPrintObjects opts = PrettyPrintObject r
162+convert opts (TypeApp o r) | o == tyRecord && prettyPrintObjects opts = PrettyPrintObject r
165convert _ other = other
163convert _ other = other
166
164
167convertForAlls :: Type -> Type
165convertForAlls :: Type -> Type
@@ -184,9 +182,10 @@ renderKind = kind . prettyPrintKind
184-- Render code representing a Type, as it should appear inside parentheses
182-- Render code representing a Type, as it should appear inside parentheses
185--
183--
186renderTypeAtom :: Type -> RenderedCode
184renderTypeAtom :: Type -> RenderedCode
187−renderTypeAtom =
185+renderTypeAtom
188− fromMaybe (internalError "Incomplete pattern") . pattern matchTypeAtom () . preprocessType defaultRenderTypeOptions
186+ = fromMaybe (internalError "Incomplete pattern")
189−
187+ . PA.pattern matchTypeAtom ()
188+ . preprocessType defaultRenderTypeOptions
190
189
191-- |
190-- |
192-- Render code representing a Type
191-- Render code representing a Type
@@ -207,5 +206,7 @@ defaultRenderTypeOptions =
207 }
206 }
208
207
209renderTypeWithOptions :: RenderTypeOptions -> Type -> RenderedCode
208renderTypeWithOptions :: RenderTypeOptions -> Type -> RenderedCode
210−renderTypeWithOptions opts =
209+renderTypeWithOptions opts
211− fromMaybe (internalError "Incomplete pattern") . pattern matchType () . preprocessType opts
210+ = fromMaybe (internalError "Incomplete pattern")
211+ . PA.pattern matchType ()
212+ . preprocessType opts
src/Language/PureScript/Docs/RenderedCode/Types.hs+3−3
@@ -32,13 +32,13 @@ module Language.PureScript.Docs.RenderedCode.Types
32 , keywordFixity
32 , keywordFixity
33 ) where
33 ) where
34
34
35−import Prelude ()
36import Prelude.Compat
35import Prelude.Compat
37
36
38−import qualified Data.Aeson as A
39−import Data.Aeson.BetterErrors
40import Control.Monad.Error.Class (MonadError(..))
37import Control.Monad.Error.Class (MonadError(..))
41
38
39+import Data.Aeson.BetterErrors
40+import qualified Data.Aeson as A
41+
42import qualified Language.PureScript as P
42import qualified Language.PureScript as P
43
43
44-- |
44-- |
src/Language/PureScript/Docs/Types.hs+24−26
@@ -1,7 +1,4 @@
1−{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE TupleSections #-}
4−{-# LANGUAGE RankNTypes #-}
5
2
6module Language.PureScript.Docs.Types
3module Language.PureScript.Docs.Types
7 ( module Language.PureScript.Docs.Types
4 ( module Language.PureScript.Docs.Types
@@ -9,25 +6,27 @@ module Language.PureScript.Docs.Types
9 )
6 )
10 where
7 where
11
8
12−import Prelude ()
13import Prelude.Compat
9import Prelude.Compat
14
10
15import Control.Arrow (first, (***))
11import Control.Arrow (first, (***))
16import Control.Monad (when)
12import Control.Monad (when)
17−import Data.Maybe (mapMaybe)
13+
18−import Data.Version
19import Data.Aeson ((.=))
14import Data.Aeson ((.=))
20−import qualified Data.Aeson as A
21import Data.Aeson.BetterErrors
15import Data.Aeson.BetterErrors
22−import Text.ParserCombinators.ReadP (readP_to_S)
23−import Data.Text (Text)
24import Data.ByteString.Lazy (ByteString)
16import Data.ByteString.Lazy (ByteString)
17+import Data.Either (isLeft, isRight)
18+import Data.Maybe (mapMaybe)
19+import Data.Text (Text)
20+import Data.Version
21+import qualified Data.Aeson as A
25import qualified Data.Text as T
22import qualified Data.Text as T
26
23
27−import Web.Bower.PackageMeta hiding (Version, displayError)
28−
29import qualified Language.PureScript as P
24import qualified Language.PureScript as P
30
25
26+import Text.ParserCombinators.ReadP (readP_to_S)
27+
28+import Web.Bower.PackageMeta hiding (Version, displayError)
29+
31import Language.PureScript.Docs.RenderedCode as ReExports
30import Language.PureScript.Docs.RenderedCode as ReExports
32 (RenderedCode, asRenderedCode,
31 (RenderedCode, asRenderedCode,
33 ContainingModule(..), asContainingModule,
32 ContainingModule(..), asContainingModule,
@@ -86,7 +85,6 @@ data Declaration = Declaration
86 , declComments :: Maybe String
85 , declComments :: Maybe String
87 , declSourceSpan :: Maybe P.SourceSpan
86 , declSourceSpan :: Maybe P.SourceSpan
88 , declChildren :: [ChildDeclaration]
87 , declChildren :: [ChildDeclaration]
89− , declFixity :: Maybe P.Fixity -- TODO: remove in 0.9
90 , declInfo :: DeclarationInfo
88 , declInfo :: DeclarationInfo
91 }
89 }
92 deriving (Show, Eq, Ord)
90 deriving (Show, Eq, Ord)
@@ -133,9 +131,11 @@ data DeclarationInfo
133 -- An operator alias declaration, with the member the alias is for and the
131 -- An operator alias declaration, with the member the alias is for and the
134 -- operator's fixity.
132 -- operator's fixity.
135 --
133 --
136− | AliasDeclaration (P.Qualified P.FixityAlias) P.Fixity
134+ | AliasDeclaration P.Fixity FixityAlias
137 deriving (Show, Eq, Ord)
135 deriving (Show, Eq, Ord)
138
136
137+type FixityAlias = P.Qualified (Either (P.ProperName 'P.TypeName) (Either P.Ident (P.ProperName 'P.ConstructorName)))
138+
139declInfoToString :: DeclarationInfo -> String
139declInfoToString :: DeclarationInfo -> String
140declInfoToString (ValueDeclaration _) = "value"
140declInfoToString (ValueDeclaration _) = "value"
141declInfoToString (DataDeclaration _ _) = "data"
141declInfoToString (DataDeclaration _ _) = "data"
@@ -167,14 +167,13 @@ isType Declaration{..} =
167isValueAlias :: Declaration -> Bool
167isValueAlias :: Declaration -> Bool
168isValueAlias Declaration{..} =
168isValueAlias Declaration{..} =
169 case declInfo of
169 case declInfo of
170− (AliasDeclaration (P.Qualified _ P.AliasConstructor{}) _) -> True
170+ AliasDeclaration _ (P.Qualified _ d) -> isRight d
171− (AliasDeclaration (P.Qualified _ P.AliasValue{}) _) -> True
172 _ -> False
171 _ -> False
173
172
174isTypeAlias :: Declaration -> Bool
173isTypeAlias :: Declaration -> Bool
175isTypeAlias Declaration{..} =
174isTypeAlias Declaration{..} =
176 case declInfo of
175 case declInfo of
177− (AliasDeclaration (P.Qualified _ P.AliasType{}) _) -> True
176+ AliasDeclaration _ (P.Qualified _ d) -> isLeft d
178 _ -> False
177 _ -> False
179
178
180-- | Discard any children which do not satisfy the given predicate.
179-- | Discard any children which do not satisfy the given predicate.
@@ -364,7 +363,6 @@ asDeclaration =
364 <*> key "comments" (perhaps asString)
363 <*> key "comments" (perhaps asString)
365 <*> key "sourceSpan" (perhaps asSourceSpan)
364 <*> key "sourceSpan" (perhaps asSourceSpan)
366 <*> key "children" (eachInArray asChildDeclaration)
365 <*> key "children" (eachInArray asChildDeclaration)
367− <*> key "fixity" (perhaps asFixity)
368 <*> key "info" asDeclarationInfo
366 <*> key "info" asDeclarationInfo
369
367
370asReExport :: Parse PackageError (P.ModuleName, [Declaration])
368asReExport :: Parse PackageError (P.ModuleName, [Declaration])
@@ -385,6 +383,9 @@ asFixity =
385 P.Fixity <$> key "associativity" asAssociativity
383 P.Fixity <$> key "associativity" asAssociativity
386 <*> key "precedence" asIntegral
384 <*> key "precedence" asIntegral
387
385
386+asFixityAlias :: Parse PackageError FixityAlias
387+asFixityAlias = fromAesonParser
388+
388parseAssociativity :: String -> Maybe P.Associativity
389parseAssociativity :: String -> Maybe P.Associativity
389parseAssociativity str = case str of
390parseAssociativity str = case str of
390 "infix" -> Just P.Infix
391 "infix" -> Just P.Infix
@@ -413,14 +414,11 @@ asDeclarationInfo = do
413 TypeClassDeclaration <$> key "arguments" asTypeArguments
414 TypeClassDeclaration <$> key "arguments" asTypeArguments
414 <*> key "superclasses" (eachInArray asConstraint)
415 <*> key "superclasses" (eachInArray asConstraint)
415 "alias" ->
416 "alias" ->
416− AliasDeclaration <$> key "for" asAliasFor
417+ AliasDeclaration <$> key "fixity" asFixity
417− <*> key "fixity" asFixity
418+ <*> key "alias" asFixityAlias
418 other ->
419 other ->
419 throwCustomError (InvalidDeclarationType other)
420 throwCustomError (InvalidDeclarationType other)
420
421
421−asAliasFor :: Parse e (P.Qualified P.FixityAlias)
422−asAliasFor = fromAesonParser
423−
424asTypeArguments :: Parse PackageError [(String, Maybe P.Kind)]
422asTypeArguments :: Parse PackageError [(String, Maybe P.Kind)]
425asTypeArguments = eachInArray asTypeArgument
423asTypeArguments = eachInArray asTypeArgument
426 where
424 where
@@ -465,8 +463,9 @@ asSourcePos = P.SourcePos <$> nth 0 asIntegral
465 <*> nth 1 asIntegral
463 <*> nth 1 asIntegral
466
464
467asConstraint :: Parse PackageError P.Constraint
465asConstraint :: Parse PackageError P.Constraint
468−asConstraint = (,) <$> nth 0 asQualifiedProperName
466+asConstraint = P.Constraint <$> key "constraintClass" asQualifiedProperName
469− <*> nth 1 (eachInArray asType)
467+ <*> key "constraintArgs" (eachInArray asType)
468+ <*> pure Nothing
470
469
471asQualifiedProperName :: Parse e (P.Qualified (P.ProperName a))
470asQualifiedProperName :: Parse e (P.Qualified (P.ProperName a))
472asQualifiedProperName = fromAesonParser
471asQualifiedProperName = fromAesonParser
@@ -538,7 +537,6 @@ instance A.ToJSON Declaration where
538 , "comments" .= declComments
537 , "comments" .= declComments
539 , "sourceSpan" .= declSourceSpan
538 , "sourceSpan" .= declSourceSpan
540 , "children" .= declChildren
539 , "children" .= declChildren
541− , "fixity" .= declFixity
542 , "info" .= declInfo
540 , "info" .= declInfo
543 ]
541 ]
544
542
@@ -559,7 +557,7 @@ instance A.ToJSON DeclarationInfo where
559 ExternDataDeclaration kind -> ["kind" .= kind]
557 ExternDataDeclaration kind -> ["kind" .= kind]
560 TypeSynonymDeclaration args ty -> ["arguments" .= args, "type" .= ty]
558 TypeSynonymDeclaration args ty -> ["arguments" .= args, "type" .= ty]
561 TypeClassDeclaration args super -> ["arguments" .= args, "superclasses" .= super]
559 TypeClassDeclaration args super -> ["arguments" .= args, "superclasses" .= super]
562− AliasDeclaration for fixity -> ["for" .= for, "fixity" .= fixity]
560+ AliasDeclaration fixity alias -> ["fixity" .= fixity, "alias" .= alias]
563
561
564instance A.ToJSON ChildDeclarationInfo where
562instance A.ToJSON ChildDeclarationInfo where
565 toJSON info = A.object $ "declType" .= childDeclInfoToString info : props
563 toJSON info = A.object $ "declType" .= childDeclInfoToString info : props
src/Language/PureScript/Environment.hs+28−24
@@ -3,11 +3,13 @@
3
3
4module Language.PureScript.Environment where
4module Language.PureScript.Environment where
5
5
6−import Data.Maybe (fromMaybe)
6+import Prelude.Compat
7+
7import Data.Aeson.TH
8import Data.Aeson.TH
9+import Data.Maybe (fromMaybe)
10+import qualified Data.Aeson as A
8import qualified Data.Map as M
11import qualified Data.Map as M
9import qualified Data.Text as T
12import qualified Data.Text as T
10−import qualified Data.Aeson as A
11
13
12import Language.PureScript.Crash
14import Language.PureScript.Crash
13import Language.PureScript.Kinds
15import Language.PureScript.Kinds
@@ -23,7 +25,7 @@ data Environment = Environment {
23 -- |
25 -- |
24 -- Value names currently in scope
26 -- Value names currently in scope
25 --
27 --
26− names :: M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
28+ names :: M.Map (Qualified Ident) (Type, NameKind, NameVisibility)
27 -- |
29 -- |
28 -- Type names currently in scope
30 -- Type names currently in scope
29 --
31 --
@@ -44,7 +46,7 @@ data Environment = Environment {
44 -- Type classes
46 -- Type classes
45 --
47 --
46 , typeClasses :: M.Map (Qualified (ProperName 'ClassName)) ([(String, Maybe Kind)], [(Ident, Type)], [Constraint])
48 , typeClasses :: M.Map (Qualified (ProperName 'ClassName)) ([(String, Maybe Kind)], [(Ident, Type)], [Constraint])
47− } deriving (Show, Read)
49+ } deriving (Show)
48
50
49-- |
51-- |
50-- The initial environment with no values and only the default javascript types defined
52-- The initial environment with no values and only the default javascript types defined
@@ -63,7 +65,7 @@ data NameVisibility
63 -- |
65 -- |
64 -- The name is defined in the another binding group, or has been made visible by a function binder
66 -- The name is defined in the another binding group, or has been made visible by a function binder
65 --
67 --
66− | Defined deriving (Show, Read, Eq)
68+ | Defined deriving (Show, Eq)
67
69
68-- |
70-- |
69-- A flag for whether a name is for an private or public value - only public values will be
71-- A flag for whether a name is for an private or public value - only public values will be
@@ -83,7 +85,7 @@ data NameKind
83 -- A name for member introduced by foreign import
85 -- A name for member introduced by foreign import
84 --
86 --
85 | External
87 | External
86− deriving (Show, Read, Eq)
88+ deriving (Show, Eq)
87
89
88-- |
90-- |
89-- The kinds of a type
91-- The kinds of a type
@@ -109,7 +111,7 @@ data TypeKind
109 -- A scoped type variable
111 -- A scoped type variable
110 --
112 --
111 | ScopedTypeVar
113 | ScopedTypeVar
112− deriving (Show, Read, Eq)
114+ deriving (Show, Eq)
113
115
114-- |
116-- |
115-- The type ('data' or 'newtype') of a data type declaration
117-- The type ('data' or 'newtype') of a data type declaration
@@ -123,7 +125,7 @@ data DataDeclType
123 -- A newtype constructor
125 -- A newtype constructor
124 --
126 --
125 | Newtype
127 | Newtype
126− deriving (Show, Read, Eq, Ord)
128+ deriving (Show, Eq, Ord)
127
129
128showDataDeclType :: DataDeclType -> String
130showDataDeclType :: DataDeclType -> String
129showDataDeclType Data = "data"
131showDataDeclType Data = "data"
@@ -194,16 +196,16 @@ tyArray :: Type
194tyArray = primTy "Array"
196tyArray = primTy "Array"
195
197
196-- |
198-- |
197−-- Type constructor for objects
199+-- Type constructor for records
198--
200--
199−tyObject :: Type
201+tyRecord :: Type
200−tyObject = primTy "Object"
202+tyRecord = primTy "Record"
201
203
202-- |
204-- |
203−-- Check whether a type is an object
205+-- Check whether a type is a record
204--
206--
205isObject :: Type -> Bool
207isObject :: Type -> Bool
206−isObject = isTypeOrApplied tyObject
208+isObject = isTypeOrApplied tyRecord
207
209
208-- |
210-- |
209-- Check whether a type is a function
211-- Check whether a type is a function
@@ -230,14 +232,15 @@ primTypes :: M.Map (Qualified (ProperName 'TypeName)) (Kind, TypeKind)
230primTypes =
232primTypes =
231 M.fromList
233 M.fromList
232 [ (primName "Function", (FunKind Star (FunKind Star Star), ExternData))
234 [ (primName "Function", (FunKind Star (FunKind Star Star), ExternData))
233− , (primName "Array", (FunKind Star Star, ExternData))
235+ , (primName "Array", (FunKind Star Star, ExternData))
234− , (primName "Object", (FunKind (Row Star) Star, ExternData))
236+ , (primName "Record", (FunKind (Row Star) Star, ExternData))
235− , (primName "String", (Star, ExternData))
237+ , (primName "String", (Star, ExternData))
236− , (primName "Char", (Star, ExternData))
238+ , (primName "Char", (Star, ExternData))
237− , (primName "Number", (Star, ExternData))
239+ , (primName "Number", (Star, ExternData))
238− , (primName "Int", (Star, ExternData))
240+ , (primName "Int", (Star, ExternData))
239− , (primName "Boolean", (Star, ExternData))
241+ , (primName "Boolean", (Star, ExternData))
240− , (primName "Partial", (Star, ExternData))
242+ , (primName "Partial", (Star, ExternData))
243+ , (primName "Fail", (FunKind Symbol Star, ExternData))
241 ]
244 ]
242
245
243-- |
246-- |
@@ -247,7 +250,9 @@ primTypes =
247primClasses :: M.Map (Qualified (ProperName 'ClassName)) ([(String, Maybe Kind)], [(Ident, Type)], [Constraint])
250primClasses :: M.Map (Qualified (ProperName 'ClassName)) ([(String, Maybe Kind)], [(Ident, Type)], [Constraint])
248primClasses =
251primClasses =
249 M.fromList
252 M.fromList
250− [ (primName "Partial", ([], [], [])) ]
253+ [ (primName "Partial", ([], [], []))
254+ , (primName "Fail", ([("message", Just Symbol)], [], []))
255+ ]
251
256
252-- |
257-- |
253-- Finds information about data constructors from the current environment.
258-- Finds information about data constructors from the current environment.
@@ -268,7 +273,6 @@ isNewtypeConstructor e ctor = case lookupConstructor e ctor of
268-- Finds information about values from the current environment.
273-- Finds information about values from the current environment.
269--
274--
270lookupValue :: Environment -> Qualified Ident -> Maybe (Type, NameKind, NameVisibility)
275lookupValue :: Environment -> Qualified Ident -> Maybe (Type, NameKind, NameVisibility)
271−lookupValue env (Qualified (Just mn) ident) = (mn, ident) `M.lookup` names env
276+lookupValue env ident = ident `M.lookup` names env
272−lookupValue _ _ = Nothing
273
277
274$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''TypeKind)
278$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''TypeKind)
src/Language/PureScript/Errors.hs+410−554
@@ -1,201 +1,45 @@
1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2−{-# LANGUAGE FlexibleContexts #-}
2+{-# LANGUAGE NamedFieldPuns #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
4
3
5−module Language.PureScript.Errors where
4+module Language.PureScript.Errors
5+ ( module Language.PureScript.AST
6+ , module Language.PureScript.Errors
7+ ) where
6
8
7−import Prelude ()
8import Prelude.Compat
9import Prelude.Compat
9
10
10−import Data.Ord (comparing)
11+import Control.Arrow ((&&&))
12+import Control.Monad
13+import Control.Monad.Error.Class (MonadError(..))
14+import Control.Monad.Trans.State.Lazy
15+import Control.Monad.Writer
16+
11import Data.Char (isSpace)
17import Data.Char (isSpace)
12import Data.Either (lefts, rights)
18import Data.Either (lefts, rights)
13−import Data.List (intercalate, transpose, nub, nubBy, sortBy, partition)
14import Data.Foldable (fold)
19import Data.Foldable (fold)
20+import Data.Functor.Identity (Identity(..))
21+import Data.List (intercalate, transpose, nub, nubBy, sortBy, partition)
15−import Data.Maybe (maybeToList)
22+import Data.Maybe (maybeToList, fromMaybe, mapMaybe)
16−
23+import Data.Ord (comparing)
17import qualified Data.Map as M
24import qualified Data.Map as M
18
25
19−import Control.Monad
20−import Control.Monad.Writer
21−import Control.Monad.Error.Class (MonadError(..))
22−import Control.Monad.Trans.State.Lazy
23−import Control.Arrow ((&&&))
24−
25−import Language.PureScript.Crash
26import Language.PureScript.AST
26import Language.PureScript.AST
27+import Language.PureScript.Crash
28+import Language.PureScript.Names
27import Language.PureScript.Pretty
29import Language.PureScript.Pretty
28−import Language.PureScript.Pretty.Common (before)
30+import Language.PureScript.Traversals
29import Language.PureScript.Types
31import Language.PureScript.Types
30−import Language.PureScript.Names
32+import Language.PureScript.Pretty.Common (endWith)
31−import Language.PureScript.Kinds
32import qualified Language.PureScript.Bundle as Bundle
33import qualified Language.PureScript.Bundle as Bundle
34+import qualified Language.PureScript.Constants as C
33
35
34−import qualified Text.PrettyPrint.Boxes as Box
36+import qualified System.Console.ANSI as ANSI
35
37
36import qualified Text.Parsec as P
38import qualified Text.Parsec as P
37import qualified Text.Parsec.Error as PE
39import qualified Text.Parsec.Error as PE
40+import qualified Text.PrettyPrint.Boxes as Box
38import Text.Parsec.Error (Message(..))
41import Text.Parsec.Error (Message(..))
39
42
40−-- | A type of error messages
41−data SimpleErrorMessage
42− = ErrorParsingFFIModule FilePath (Maybe Bundle.ErrorMessage)
43− | ErrorParsingModule P.ParseError
44− | MissingFFIModule ModuleName
45− | MultipleFFIModules ModuleName [FilePath]
46− | UnnecessaryFFIModule ModuleName FilePath
47− | MissingFFIImplementations ModuleName [Ident]
48− | UnusedFFIImplementations ModuleName [Ident]
49− | InvalidFFIIdentifier ModuleName String
50− | CannotGetFileInfo FilePath
51− | CannotReadFile FilePath
52− | CannotWriteFile FilePath
53− | InfiniteType Type
54− | InfiniteKind Kind
55− | MultipleFixities Ident
56− | OrphanTypeDeclaration Ident
57− | OrphanFixityDeclaration String
58− | RedefinedModule ModuleName [SourceSpan]
59− | RedefinedIdent Ident
60− | OverlappingNamesInLet
61− | UnknownModule ModuleName
62− | UnknownType (Qualified (ProperName 'TypeName))
63− | UnknownTypeOp (Qualified Ident)
64− | UnknownTypeClass (Qualified (ProperName 'ClassName))
65− | UnknownValue (Qualified Ident)
66− | UnknownDataConstructor (Qualified (ProperName 'ConstructorName)) (Maybe (Qualified (ProperName 'ConstructorName)))
67− | UnknownTypeConstructor (Qualified (ProperName 'TypeName))
68− | UnknownImportType ModuleName (ProperName 'TypeName)
69− | UnknownExportType (ProperName 'TypeName)
70− | UnknownImportTypeOp ModuleName Ident
71− | UnknownExportTypeOp Ident
72− | UnknownImportTypeClass ModuleName (ProperName 'ClassName)
73− | UnknownExportTypeClass (ProperName 'ClassName)
74− | UnknownImportValue ModuleName Ident
75− | UnknownExportValue Ident
76− | UnknownExportModule ModuleName
77− | UnknownImportDataConstructor ModuleName (ProperName 'TypeName) (ProperName 'ConstructorName)
78− | UnknownExportDataConstructor (ProperName 'TypeName) (ProperName 'ConstructorName)
79− | ScopeConflict String [ModuleName]
80− | ScopeShadowing String (Maybe ModuleName) [ModuleName]
81− | ConflictingTypeDecls (ProperName 'TypeName)
82− | ConflictingCtorDecls (ProperName 'ConstructorName)
83− | TypeConflictsWithClass (ProperName 'TypeName)
84− | CtorConflictsWithClass (ProperName 'ConstructorName)
85− | ClassConflictsWithType (ProperName 'ClassName)
86− | ClassConflictsWithCtor (ProperName 'ClassName)
87− | DuplicateModuleName ModuleName
88− | DuplicateClassExport (ProperName 'ClassName)
89− | DuplicateValueExport Ident
90− | DuplicateTypeOpExport Ident
91− | DuplicateTypeArgument String
92− | InvalidDoBind
93− | InvalidDoLet
94− | CycleInDeclaration Ident
95− | CycleInTypeSynonym (Maybe (ProperName 'TypeName))
96− | CycleInModules [ModuleName]
97− | NameIsUndefined Ident
98− | UndefinedTypeVariable (ProperName 'TypeName)
99− | PartiallyAppliedSynonym (Qualified (ProperName 'TypeName))
100− | EscapedSkolem (Maybe Expr)
101− | TypesDoNotUnify Type Type
102− | KindsDoNotUnify Kind Kind
103− | ConstrainedTypeUnified Type Type
104− | OverlappingInstances (Qualified (ProperName 'ClassName)) [Type] [Qualified Ident]
105− | NoInstanceFound (Qualified (ProperName 'ClassName)) [Type]
106− | PossiblyInfiniteInstance (Qualified (ProperName 'ClassName)) [Type]
107− | CannotDerive (Qualified (ProperName 'ClassName)) [Type]
108− | CannotFindDerivingType (ProperName 'TypeName)
109− | DuplicateLabel String (Maybe Expr)
110− | DuplicateValueDeclaration Ident
111− | ArgListLengthsDiffer Ident
112− | OverlappingArgNames (Maybe Ident)
113− | MissingClassMember Ident
114− | ExtraneousClassMember Ident (Qualified (ProperName 'ClassName))
115− | ExpectedType Type Kind
116− | IncorrectConstructorArity (Qualified (ProperName 'ConstructorName))
117− | ExprDoesNotHaveType Expr Type
118− | PropertyIsMissing String
119− | AdditionalProperty String
120− | CannotApplyFunction Type Expr
121− | TypeSynonymInstance
122− | OrphanInstance Ident (Qualified (ProperName 'ClassName)) [Type]
123− | InvalidNewtype (ProperName 'TypeName)
124− | InvalidInstanceHead Type
125− | TransitiveExportError DeclarationRef [DeclarationRef]
126− | TransitiveDctorExportError DeclarationRef (ProperName 'ConstructorName)
127− | ShadowedName Ident
128− | ShadowedTypeVar String
129− | UnusedTypeVar String
130− | WildcardInferredType Type
131− | HoleInferredType String Type
132− | MissingTypeDeclaration Ident Type
133− | NotExhaustivePattern [[Binder]] Bool
134− | OverlappingPattern [[Binder]] Bool
135− | IncompleteExhaustivityCheck
136− | ClassOperator (ProperName 'ClassName) Ident
137− | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
138− | ImportHidingModule ModuleName
139− | UnusedImport ModuleName
140− | UnusedExplicitImport ModuleName [String] (Maybe ModuleName) [DeclarationRef]
141− | UnusedDctorImport (ProperName 'TypeName)
142− | UnusedDctorExplicitImport (ProperName 'TypeName) [ProperName 'ConstructorName]
143− | DeprecatedOperatorDecl String
144− | DeprecatedOperatorSection Expr (Either Expr Expr)
145− | DeprecatedQualifiedSyntax ModuleName ModuleName
146− | DeprecatedClassImport ModuleName (ProperName 'ClassName)
147− | DeprecatedClassExport (ProperName 'ClassName)
148− | DuplicateSelectiveImport ModuleName
149− | DuplicateImport ModuleName ImportDeclarationType (Maybe ModuleName)
150− | DuplicateImportRef String
151− | DuplicateExportRef String
152− | IntOutOfRange Integer String Integer Integer
153− | RedundantEmptyHidingImport ModuleName
154− | ImplicitQualifiedImport ModuleName ModuleName [DeclarationRef]
155− | ImplicitImport ModuleName [DeclarationRef]
156− | HidingImport ModuleName [DeclarationRef]
157− | CaseBinderLengthDiffers Int [Binder]
158− | IncorrectAnonymousArgument
159− | InvalidOperatorInBinder Ident Ident
160− | DeprecatedRequirePath
161− | CannotGeneralizeRecursiveFunction Ident Type
162− deriving (Show)
163−
164−-- | Error message hints, providing more detailed information about failure.
165−data ErrorMessageHint
166− = ErrorUnifyingTypes Type Type
167− | ErrorInExpression Expr
168− | ErrorInModule ModuleName
169− | ErrorInInstance (Qualified (ProperName 'ClassName)) [Type]
170− | ErrorInSubsumption Type Type
171− | ErrorCheckingAccessor Expr String
172− | ErrorCheckingType Expr Type
173− | ErrorCheckingKind Type
174− | ErrorCheckingGuard
175− | ErrorInferringType Expr
176− | ErrorInApplication Expr Type Expr
177− | ErrorInDataConstructor (ProperName 'ConstructorName)
178− | ErrorInTypeConstructor (ProperName 'TypeName)
179− | ErrorInBindingGroup [Ident]
180− | ErrorInDataBindingGroup
181− | ErrorInTypeSynonym (ProperName 'TypeName)
182− | ErrorInValueDeclaration Ident
183− | ErrorInTypeDeclaration Ident
184− | ErrorInForeignImport Ident
185− | PositionedError SourceSpan
186− deriving Show
187−
188−-- | Categories of hints
189−data HintCategory
190− = ExprHint
191− | KindHint
192− | CheckHint
193− | PositionHint
194− | OtherHint
195− deriving (Show, Eq)
196−
197−data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
198−
199newtype ErrorSuggestion = ErrorSuggestion String
43newtype ErrorSuggestion = ErrorSuggestion String
200
44
201-- | Get the source span for an error
45-- | Get the source span for an error
@@ -241,42 +85,22 @@ errorCode em = case unwrapErrorMessage em of
241 CannotWriteFile{} -> "CannotWriteFile"
85 CannotWriteFile{} -> "CannotWriteFile"
242 InfiniteType{} -> "InfiniteType"
86 InfiniteType{} -> "InfiniteType"
243 InfiniteKind{} -> "InfiniteKind"
87 InfiniteKind{} -> "InfiniteKind"
244− MultipleFixities{} -> "MultipleFixities"
88+ MultipleValueOpFixities{} -> "MultipleValueOpFixities"
89+ MultipleTypeOpFixities{} -> "MultipleTypeOpFixities"
245 OrphanTypeDeclaration{} -> "OrphanTypeDeclaration"
90 OrphanTypeDeclaration{} -> "OrphanTypeDeclaration"
246− OrphanFixityDeclaration{} -> "OrphanFixityDeclaration"
247 RedefinedModule{} -> "RedefinedModule"
91 RedefinedModule{} -> "RedefinedModule"
248 RedefinedIdent{} -> "RedefinedIdent"
92 RedefinedIdent{} -> "RedefinedIdent"
249 OverlappingNamesInLet -> "OverlappingNamesInLet"
93 OverlappingNamesInLet -> "OverlappingNamesInLet"
250− UnknownModule{} -> "UnknownModule"
94+ UnknownName{} -> "UnknownName"
251− UnknownType{} -> "UnknownType"
95+ UnknownImport{} -> "UnknownImport"
252− UnknownTypeOp{} -> "UnknownTypeOp"
253− UnknownTypeClass{} -> "UnknownTypeClass"
254− UnknownValue{} -> "UnknownValue"
255− UnknownDataConstructor{} -> "UnknownDataConstructor"
256− UnknownTypeConstructor{} -> "UnknownTypeConstructor"
257− UnknownImportType{} -> "UnknownImportType"
258− UnknownImportTypeOp{} -> "UnknownImportTypeOp"
259− UnknownExportType{} -> "UnknownExportType"
260− UnknownExportTypeOp{} -> "UnknownExportTypeOp"
261− UnknownImportTypeClass{} -> "UnknownImportTypeClass"
262− UnknownExportTypeClass{} -> "UnknownExportTypeClass"
263− UnknownImportValue{} -> "UnknownImportValue"
264− UnknownExportValue{} -> "UnknownExportValue"
265− UnknownExportModule{} -> "UnknownExportModule"
266 UnknownImportDataConstructor{} -> "UnknownImportDataConstructor"
96 UnknownImportDataConstructor{} -> "UnknownImportDataConstructor"
97+ UnknownExport{} -> "UnknownExport"
267 UnknownExportDataConstructor{} -> "UnknownExportDataConstructor"
98 UnknownExportDataConstructor{} -> "UnknownExportDataConstructor"
268 ScopeConflict{} -> "ScopeConflict"
99 ScopeConflict{} -> "ScopeConflict"
269 ScopeShadowing{} -> "ScopeShadowing"
100 ScopeShadowing{} -> "ScopeShadowing"
270− ConflictingTypeDecls{} -> "ConflictingTypeDecls"
101+ DeclConflict{} -> "DeclConflict"
271− ConflictingCtorDecls{} -> "ConflictingCtorDecls"
102+ ExportConflict{} -> "ExportConflict"
272− TypeConflictsWithClass{} -> "TypeConflictsWithClass"
273− CtorConflictsWithClass{} -> "CtorConflictsWithClass"
274− ClassConflictsWithType{} -> "ClassConflictsWithType"
275− ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
276 DuplicateModuleName{} -> "DuplicateModuleName"
103 DuplicateModuleName{} -> "DuplicateModuleName"
277− DuplicateClassExport{} -> "DuplicateClassExport"
278− DuplicateValueExport{} -> "DuplicateValueExport"
279− DuplicateTypeOpExport{} -> "DuplicateTypeOpExport"
280 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
104 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
281 InvalidDoBind -> "InvalidDoBind"
105 InvalidDoBind -> "InvalidDoBind"
282 InvalidDoLet -> "InvalidDoLet"
106 InvalidDoLet -> "InvalidDoLet"
@@ -319,27 +143,19 @@ errorCode em = case unwrapErrorMessage em of
319 WildcardInferredType{} -> "WildcardInferredType"
143 WildcardInferredType{} -> "WildcardInferredType"
320 HoleInferredType{} -> "HoleInferredType"
144 HoleInferredType{} -> "HoleInferredType"
321 MissingTypeDeclaration{} -> "MissingTypeDeclaration"
145 MissingTypeDeclaration{} -> "MissingTypeDeclaration"
322− NotExhaustivePattern{} -> "NotExhaustivePattern"
323 OverlappingPattern{} -> "OverlappingPattern"
146 OverlappingPattern{} -> "OverlappingPattern"
324 IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
147 IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
325− ClassOperator{} -> "ClassOperator"
326 MisleadingEmptyTypeImport{} -> "MisleadingEmptyTypeImport"
148 MisleadingEmptyTypeImport{} -> "MisleadingEmptyTypeImport"
327 ImportHidingModule{} -> "ImportHidingModule"
149 ImportHidingModule{} -> "ImportHidingModule"
328 UnusedImport{} -> "UnusedImport"
150 UnusedImport{} -> "UnusedImport"
329 UnusedExplicitImport{} -> "UnusedExplicitImport"
151 UnusedExplicitImport{} -> "UnusedExplicitImport"
330 UnusedDctorImport{} -> "UnusedDctorImport"
152 UnusedDctorImport{} -> "UnusedDctorImport"
331 UnusedDctorExplicitImport{} -> "UnusedDctorExplicitImport"
153 UnusedDctorExplicitImport{} -> "UnusedDctorExplicitImport"
332− DeprecatedOperatorDecl{} -> "DeprecatedOperatorDecl"
333− DeprecatedOperatorSection{} -> "DeprecatedOperatorSection"
334− DeprecatedQualifiedSyntax{} -> "DeprecatedQualifiedSyntax"
335− DeprecatedClassImport{} -> "DeprecatedClassImport"
336− DeprecatedClassExport{} -> "DeprecatedClassExport"
337 DuplicateSelectiveImport{} -> "DuplicateSelectiveImport"
154 DuplicateSelectiveImport{} -> "DuplicateSelectiveImport"
338 DuplicateImport{} -> "DuplicateImport"
155 DuplicateImport{} -> "DuplicateImport"
339 DuplicateImportRef{} -> "DuplicateImportRef"
156 DuplicateImportRef{} -> "DuplicateImportRef"
340 DuplicateExportRef{} -> "DuplicateExportRef"
157 DuplicateExportRef{} -> "DuplicateExportRef"
341 IntOutOfRange{} -> "IntOutOfRange"
158 IntOutOfRange{} -> "IntOutOfRange"
342− RedundantEmptyHidingImport{} -> "RedundantEmptyHidingImport"
343 ImplicitQualifiedImport{} -> "ImplicitQualifiedImport"
159 ImplicitQualifiedImport{} -> "ImplicitQualifiedImport"
344 ImplicitImport{} -> "ImplicitImport"
160 ImplicitImport{} -> "ImplicitImport"
345 HidingImport{} -> "HidingImport"
161 HidingImport{} -> "HidingImport"
@@ -377,18 +193,25 @@ onErrorMessages f = MultipleErrors . map f . runMultipleErrors
377
193
378-- | Add a hint to an error message
194-- | Add a hint to an error message
379addHint :: ErrorMessageHint -> MultipleErrors -> MultipleErrors
195addHint :: ErrorMessageHint -> MultipleErrors -> MultipleErrors
196+addHint hint = addHints [hint]
197+
198+-- | Add hints to an error message
199+addHints :: [ErrorMessageHint] -> MultipleErrors -> MultipleErrors
380−addHint hint = onErrorMessages $ \(ErrorMessage hints se) -> ErrorMessage (hint : hints) se
200+addHints hints = onErrorMessages $ \(ErrorMessage hints' se) -> ErrorMessage (hints ++ hints') se
381
201
382-- | A map from rigid type variable name/unknown variable pairs to new variables.
202-- | A map from rigid type variable name/unknown variable pairs to new variables.
383data TypeMap = TypeMap
203data TypeMap = TypeMap
384− { umSkolemMap :: M.Map Int (String, Int, Maybe SourceSpan)
204+ { umSkolemMap :: M.Map Int (String, Int, Maybe SourceSpan)
385− , umNextSkolem :: Int
205+ -- ^ a map from skolems to their new names, including source and naming info
386− , umUnknownMap :: M.Map Int Int
206+ , umUnknownMap :: M.Map Int Int
387− , umNextUnknown :: Int
207+ -- ^ a map from unification variables to their new names
208+ , umNextIndex :: Int
209+ -- ^ unknowns and skolems share a source of names during renaming, to
210+ -- avoid overlaps in error messages. This is the next label for either case.
388 } deriving Show
211 } deriving Show
389
212
390defaultUnknownMap :: TypeMap
213defaultUnknownMap :: TypeMap
391−defaultUnknownMap = TypeMap M.empty 0 M.empty 0
214+defaultUnknownMap = TypeMap M.empty M.empty 0
392
215
393-- | How critical the issue is
216-- | How critical the issue is
394data Level = Error | Warning deriving Show
217data Level = Error | Warning deriving Show
@@ -407,21 +230,24 @@ replaceUnknowns = everywhereOnTypesM replaceTypes
407 m <- get
230 m <- get
408 case M.lookup u (umUnknownMap m) of
231 case M.lookup u (umUnknownMap m) of
409 Nothing -> do
232 Nothing -> do
410− let u' = umNextUnknown m
233+ let u' = umNextIndex m
411− put $ m { umUnknownMap = M.insert u u' (umUnknownMap m), umNextUnknown = u' + 1 }
234+ put $ m { umUnknownMap = M.insert u u' (umUnknownMap m), umNextIndex = u' + 1 }
412 return (TUnknown u')
235 return (TUnknown u')
413 Just u' -> return (TUnknown u')
236 Just u' -> return (TUnknown u')
414 replaceTypes (Skolem name s sko ss) = do
237 replaceTypes (Skolem name s sko ss) = do
415 m <- get
238 m <- get
416 case M.lookup s (umSkolemMap m) of
239 case M.lookup s (umSkolemMap m) of
417 Nothing -> do
240 Nothing -> do
418− let s' = umNextSkolem m
241+ let s' = umNextIndex m
419− put $ m { umSkolemMap = M.insert s (name, s', ss) (umSkolemMap m), umNextSkolem = s' + 1 }
242+ put $ m { umSkolemMap = M.insert s (name, s', ss) (umSkolemMap m), umNextIndex = s' + 1 }
420 return (Skolem name s' sko ss)
243 return (Skolem name s' sko ss)
421 Just (_, s', _) -> return (Skolem name s' sko ss)
244 Just (_, s', _) -> return (Skolem name s' sko ss)
422 replaceTypes other = return other
245 replaceTypes other = return other
423
246
247+onTypesInErrorMessage :: (Type -> Type) -> ErrorMessage -> ErrorMessage
248+onTypesInErrorMessage f = runIdentity . onTypesInErrorMessageM (Identity . f)
249+
424−onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
250+onTypesInErrorMessageM :: Applicative m => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
425onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
251onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
426 where
252 where
427 gSimple (InfiniteType t) = InfiniteType <$> f t
253 gSimple (InfiniteType t) = InfiniteType <$> f t
@@ -430,17 +256,16 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
430 gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
256 gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
431 gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
257 gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
432 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
258 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
433− gSimple (NoInstanceFound cl ts) = NoInstanceFound cl <$> traverse f ts
259+ gSimple (NoInstanceFound con) = NoInstanceFound <$> overConstraintArgs (traverse f) con
434 gSimple (OverlappingInstances cl ts insts) = OverlappingInstances cl <$> traverse f ts <*> pure insts
260 gSimple (OverlappingInstances cl ts insts) = OverlappingInstances cl <$> traverse f ts <*> pure insts
435 gSimple (PossiblyInfiniteInstance cl ts) = PossiblyInfiniteInstance cl <$> traverse f ts
261 gSimple (PossiblyInfiniteInstance cl ts) = PossiblyInfiniteInstance cl <$> traverse f ts
436 gSimple (CannotDerive cl ts) = CannotDerive cl <$> traverse f ts
262 gSimple (CannotDerive cl ts) = CannotDerive cl <$> traverse f ts
437 gSimple (ExpectedType ty k) = ExpectedType <$> f ty <*> pure k
263 gSimple (ExpectedType ty k) = ExpectedType <$> f ty <*> pure k
438 gSimple (OrphanInstance nm cl ts) = OrphanInstance nm cl <$> traverse f ts
264 gSimple (OrphanInstance nm cl ts) = OrphanInstance nm cl <$> traverse f ts
439− gSimple (WildcardInferredType ty) = WildcardInferredType <$> f ty
265+ gSimple (WildcardInferredType ty ctx) = WildcardInferredType <$> f ty <*> traverse (sndM f) ctx
440− gSimple (HoleInferredType name ty) = HoleInferredType name <$> f ty
266+ gSimple (HoleInferredType name ty ctx) = HoleInferredType name <$> f ty <*> traverse (sndM f) ctx
441 gSimple (MissingTypeDeclaration nm ty) = MissingTypeDeclaration nm <$> f ty
267 gSimple (MissingTypeDeclaration nm ty) = MissingTypeDeclaration nm <$> f ty
442 gSimple (CannotGeneralizeRecursiveFunction nm ty) = CannotGeneralizeRecursiveFunction nm <$> f ty
268 gSimple (CannotGeneralizeRecursiveFunction nm ty) = CannotGeneralizeRecursiveFunction nm <$> f ty
443−
444 gSimple other = pure other
269 gSimple other = pure other
445
270
446 gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
271 gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
@@ -449,6 +274,7 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
449 gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
274 gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
450 gHint (ErrorInApplication e1 t1 e2) = ErrorInApplication e1 <$> f t1 <*> pure e2
275 gHint (ErrorInApplication e1 t1 e2) = ErrorInApplication e1 <$> f t1 <*> pure e2
451 gHint (ErrorInInstance cl ts) = ErrorInInstance cl <$> traverse f ts
276 gHint (ErrorInInstance cl ts) = ErrorInInstance cl <$> traverse f ts
277+ gHint (ErrorSolvingConstraint con) = ErrorSolvingConstraint <$> overConstraintArgs (traverse f) con
452 gHint other = pure other
278 gHint other = pure other
453
279
454wikiUri :: ErrorMessage -> String
280wikiUri :: ErrorMessage -> String
@@ -457,18 +283,16 @@ wikiUri e = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ error
457-- TODO Other possible suggestions:
283-- TODO Other possible suggestions:
458-- WildcardInferredType - source span not small enough
284-- WildcardInferredType - source span not small enough
459-- DuplicateSelectiveImport - would require 2 ranges to remove and 1 insert
285-- DuplicateSelectiveImport - would require 2 ranges to remove and 1 insert
460−-- DeprecatedClassExport, DeprecatedClassImport, DeprecatedOperatorSection, would want to replace smaller span?
461errorSuggestion :: SimpleErrorMessage -> Maybe ErrorSuggestion
286errorSuggestion :: SimpleErrorMessage -> Maybe ErrorSuggestion
462errorSuggestion err = case err of
287errorSuggestion err = case err of
463 UnusedImport{} -> emptySuggestion
288 UnusedImport{} -> emptySuggestion
464− RedundantEmptyHidingImport{} -> emptySuggestion
465 DuplicateImport{} -> emptySuggestion
289 DuplicateImport{} -> emptySuggestion
466− DeprecatedQualifiedSyntax name qualName -> suggest $
467− "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
468 UnusedExplicitImport mn _ qual refs -> suggest $ importSuggestion mn refs qual
290 UnusedExplicitImport mn _ qual refs -> suggest $ importSuggestion mn refs qual
469 ImplicitImport mn refs -> suggest $ importSuggestion mn refs Nothing
291 ImplicitImport mn refs -> suggest $ importSuggestion mn refs Nothing
470 ImplicitQualifiedImport mn asModule refs -> suggest $ importSuggestion mn refs (Just asModule)
292 ImplicitQualifiedImport mn asModule refs -> suggest $ importSuggestion mn refs (Just asModule)
471 HidingImport mn refs -> suggest $ importSuggestion mn refs Nothing
293 HidingImport mn refs -> suggest $ importSuggestion mn refs Nothing
294+ MissingTypeDeclaration ident ty -> suggest $ showIdent ident ++ " :: " ++ prettyPrintType ty
295+ WildcardInferredType ty _ -> suggest $ prettyPrintType ty
472 _ -> Nothing
296 _ -> Nothing
473
297
474 where
298 where
@@ -477,26 +301,87 @@ errorSuggestion err = case err of
477
301
478 importSuggestion :: ModuleName -> [ DeclarationRef ] -> Maybe ModuleName -> String
302 importSuggestion :: ModuleName -> [ DeclarationRef ] -> Maybe ModuleName -> String
479 importSuggestion mn refs qual =
303 importSuggestion mn refs qual =
480− "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")" ++ qstr qual
304+ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (mapMaybe prettyPrintRef refs) ++ ")" ++ qstr qual
481
305
482 qstr :: Maybe ModuleName -> String
306 qstr :: Maybe ModuleName -> String
483 qstr (Just mn) = " as " ++ runModuleName mn
307 qstr (Just mn) = " as " ++ runModuleName mn
484 qstr Nothing = ""
308 qstr Nothing = ""
485
309
310+suggestionSpan :: ErrorMessage -> Maybe SourceSpan
311+suggestionSpan e =
312+ getSpan (unwrapErrorMessage e) <$> errorSpan e
313+ where
314+ startOnly SourceSpan{spanName, spanStart} = SourceSpan {spanName, spanStart, spanEnd = spanStart}
315+
316+ getSpan simple ss =
317+ case simple of
318+ MissingTypeDeclaration{} -> startOnly ss
319+ _ -> ss
320+
486showSuggestion :: SimpleErrorMessage -> String
321showSuggestion :: SimpleErrorMessage -> String
487showSuggestion suggestion = case errorSuggestion suggestion of
322showSuggestion suggestion = case errorSuggestion suggestion of
488 Just (ErrorSuggestion x) -> x
323 Just (ErrorSuggestion x) -> x
489 _ -> ""
324 _ -> ""
490
325
326+ansiColor :: (ANSI.ColorIntensity, ANSI.Color) -> String
327+ansiColor (intesity, color) =
328+ ANSI.setSGRCode [ANSI.SetColor ANSI.Foreground intesity color]
329+
330+ansiColorReset :: String
331+ansiColorReset =
332+ ANSI.setSGRCode [ANSI.Reset]
333+
334+colorCode :: Maybe (ANSI.ColorIntensity, ANSI.Color) -> String -> String
335+colorCode codeColor code = case codeColor of
336+ Nothing -> code
337+ Just cc -> concat [ansiColor cc, code, ansiColorReset]
338+
339+colorCodeBox :: Maybe (ANSI.ColorIntensity, ANSI.Color) -> Box.Box -> Box.Box
340+colorCodeBox codeColor b = case codeColor of
341+ Nothing -> b
342+ Just cc
343+ | Box.rows b == 1 ->
344+ Box.text (ansiColor cc) Box.<> b `endWith` Box.text ansiColorReset
345+
346+ | otherwise -> Box.hcat Box.left -- making two boxes, one for each side of the box so that it will set each row it's own color and will reset it afterwards
347+ [ Box.vcat Box.top $ replicate (Box.rows b) $ Box.text $ ansiColor cc
348+ , b
349+ , Box.vcat Box.top $ replicate (Box.rows b) $ Box.text ansiColorReset
350+ ]
351+
352+
353+-- | Default color intesity and color for code
354+defaultCodeColor :: (ANSI.ColorIntensity, ANSI.Color)
355+defaultCodeColor = (ANSI.Dull, ANSI.Yellow)
356+
357+-- | `prettyPrintSingleError` Options
358+data PPEOptions = PPEOptions
359+ { ppeCodeColor :: Maybe (ANSI.ColorIntensity, ANSI.Color) -- ^ Color code with this color... or not
360+ , ppeFull :: Bool -- ^ Should write a full error message?
361+ , ppeLevel :: Level -- ^ Should this report an error or a warning?
362+ , ppeShowWiki :: Bool -- ^ Should show a link to error message's wiki page?
363+ }
364+
365+-- | Default options for PPEOptions
366+defaultPPEOptions :: PPEOptions
367+defaultPPEOptions = PPEOptions
368+ { ppeCodeColor = Just defaultCodeColor
369+ , ppeFull = False
370+ , ppeLevel = Error
371+ , ppeShowWiki = True
372+ }
373+
374+
491-- |
375-- |
492-- Pretty print a single error, simplifying if necessary
376-- Pretty print a single error, simplifying if necessary
493--
377--
494−prettyPrintSingleError :: Bool -> Level -> Bool -> ErrorMessage -> Box.Box
378+prettyPrintSingleError :: PPEOptions -> ErrorMessage -> Box.Box
495−prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap $ do
379+prettyPrintSingleError (PPEOptions codeColor full level showWiki) e = flip evalState defaultUnknownMap $ do
496 em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
380 em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
497 um <- get
381 um <- get
498 return (prettyPrintErrorMessage um em)
382 return (prettyPrintErrorMessage um em)
499 where
383 where
384+ (markCode, markCodeBox) = (colorCode &&& colorCodeBox) codeColor
500
385
501 -- Pretty print an ErrorMessage
386 -- Pretty print an ErrorMessage
502 prettyPrintErrorMessage :: TypeMap -> ErrorMessage -> Box.Box
387 prettyPrintErrorMessage :: TypeMap -> ErrorMessage -> Box.Box
@@ -505,9 +390,10 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
505 [ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
390 [ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
506 ] ++
391 ] ++
507 maybe [] (return . Box.moveDown 1) typeInformation ++
392 maybe [] (return . Box.moveDown 1) typeInformation ++
393+ [ Box.moveDown 1 $ paras
508− [ Box.moveDown 1 $ paras [ line $ "See " ++ wikiUri e ++ " for more information, "
394+ [ line $ "See " ++ wikiUri e ++ " for more information, "
509− , line $ "or to contribute content related to this " ++ levelText ++ "."
395+ , line $ "or to contribute content related to this " ++ levelText ++ "."
510− ]
396+ ]
511 | showWiki
397 | showWiki
512 ]
398 ]
513 where
399 where
@@ -522,11 +408,11 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
522 skolemInfo :: (String, Int, Maybe SourceSpan) -> Box.Box
408 skolemInfo :: (String, Int, Maybe SourceSpan) -> Box.Box
523 skolemInfo (name, s, ss) =
409 skolemInfo (name, s, ss) =
524 paras $
410 paras $
525− line (name ++ show s ++ " is a rigid type variable")
411+ line (markCode (name ++ show s) ++ " is a rigid type variable")
526 : foldMap (return . line . (" bound at " ++) . displayStartEndPos) ss
412 : foldMap (return . line . (" bound at " ++) . displayStartEndPos) ss
527
413
528 unknownInfo :: Int -> Box.Box
414 unknownInfo :: Int -> Box.Box
529− unknownInfo u = line $ "_" ++ show u ++ " is an unknown type"
415+ unknownInfo u = line $ markCode ("t" ++ show u) ++ " is an unknown type"
530
416
531 renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
417 renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
532 renderSimpleErrorMessage (CannotGetFileInfo path) =
418 renderSimpleErrorMessage (CannotGetFileInfo path) =
@@ -545,35 +431,35 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
545 paras $ [ line "Unable to parse foreign module:"
431 paras $ [ line "Unable to parse foreign module:"
546 , indent . line $ path
432 , indent . line $ path
547 ] ++
433 ] ++
548− (map (indent . line) (concatMap Bundle.printErrorMessage (maybeToList extra)))
434+ map (indent . line) (concatMap Bundle.printErrorMessage (maybeToList extra))
549 renderSimpleErrorMessage (ErrorParsingModule err) =
435 renderSimpleErrorMessage (ErrorParsingModule err) =
550 paras [ line "Unable to parse module: "
436 paras [ line "Unable to parse module: "
551 , prettyPrintParseError err
437 , prettyPrintParseError err
552 ]
438 ]
553 renderSimpleErrorMessage (MissingFFIModule mn) =
439 renderSimpleErrorMessage (MissingFFIModule mn) =
554− line $ "The foreign module implementation for module " ++ runModuleName mn ++ " is missing."
440+ line $ "The foreign module implementation for module " ++ markCode (runModuleName mn) ++ " is missing."
555 renderSimpleErrorMessage (UnnecessaryFFIModule mn path) =
441 renderSimpleErrorMessage (UnnecessaryFFIModule mn path) =
556− paras [ line $ "An unnecessary foreign module implementation was provided for module " ++ runModuleName mn ++ ": "
442+ paras [ line $ "An unnecessary foreign module implementation was provided for module " ++ markCode (runModuleName mn) ++ ": "
557 , indent . line $ path
443 , indent . line $ path
558− , line $ "Module " ++ runModuleName mn ++ " does not contain any foreign import declarations, so a foreign module is not necessary."
444+ , line $ "Module " ++ markCode (runModuleName mn) ++ " does not contain any foreign import declarations, so a foreign module is not necessary."
559 ]
445 ]
560 renderSimpleErrorMessage (MissingFFIImplementations mn idents) =
446 renderSimpleErrorMessage (MissingFFIImplementations mn idents) =
561− paras [ line $ "The following values are not defined in the foreign module for module " ++ runModuleName mn ++ ": "
447+ paras [ line $ "The following values are not defined in the foreign module for module " ++ markCode (runModuleName mn) ++ ": "
562 , indent . paras $ map (line . runIdent) idents
448 , indent . paras $ map (line . runIdent) idents
563 ]
449 ]
564 renderSimpleErrorMessage (UnusedFFIImplementations mn idents) =
450 renderSimpleErrorMessage (UnusedFFIImplementations mn idents) =
565− paras [ line $ "The following definitions in the foreign module for module " ++ runModuleName mn ++ " are unused: "
451+ paras [ line $ "The following definitions in the foreign module for module " ++ markCode (runModuleName mn) ++ " are unused: "
566 , indent . paras $ map (line . runIdent) idents
452 , indent . paras $ map (line . runIdent) idents
567 ]
453 ]
568 renderSimpleErrorMessage (InvalidFFIIdentifier mn ident) =
454 renderSimpleErrorMessage (InvalidFFIIdentifier mn ident) =
569− paras [ line $ "In the FFI module for " ++ runModuleName mn ++ ":"
455+ paras [ line $ "In the FFI module for " ++ markCode (runModuleName mn) ++ ":"
570 , indent . paras $
456 , indent . paras $
571− [ line $ "The identifier `" ++ ident ++ "` is not valid in PureScript."
457+ [ line $ "The identifier " ++ markCode ident ++ " is not valid in PureScript."
572 , line "Note that exported identifiers in FFI modules must be valid PureScript identifiers."
458 , line "Note that exported identifiers in FFI modules must be valid PureScript identifiers."
573 ]
459 ]
574 ]
460 ]
575 renderSimpleErrorMessage (MultipleFFIModules mn paths) =
461 renderSimpleErrorMessage (MultipleFFIModules mn paths) =
576− paras [ line $ "Multiple foreign module implementations have been provided for module " ++ runModuleName mn ++ ": "
462+ paras [ line $ "Multiple foreign module implementations have been provided for module " ++ markCode (runModuleName mn) ++ ": "
577 , indent . paras $ map line paths
463 , indent . paras $ map line paths
578 ]
464 ]
579 renderSimpleErrorMessage InvalidDoBind =
465 renderSimpleErrorMessage InvalidDoBind =
@@ -584,126 +470,78 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
584 line "The same name was used more than once in a let binding."
470 line "The same name was used more than once in a let binding."
585 renderSimpleErrorMessage (InfiniteType ty) =
471 renderSimpleErrorMessage (InfiniteType ty) =
586 paras [ line "An infinite type was inferred for an expression: "
472 paras [ line "An infinite type was inferred for an expression: "
587− , indent $ typeAsBox ty
473+ , markCodeBox $ indent $ typeAsBox ty
588 ]
474 ]
589 renderSimpleErrorMessage (InfiniteKind ki) =
475 renderSimpleErrorMessage (InfiniteKind ki) =
590 paras [ line "An infinite kind was inferred for a type: "
476 paras [ line "An infinite kind was inferred for a type: "
591− , indent $ line $ prettyPrintKind ki
477+ , indent $ line $ markCode $ prettyPrintKind ki
592 ]
478 ]
593− renderSimpleErrorMessage (MultipleFixities name) =
479+ renderSimpleErrorMessage (MultipleValueOpFixities op) =
594− line $ "There are multiple fixity/precedence declarations for " ++ showIdent name
480+ line $ "There are multiple fixity/precedence declarations for operator " ++ markCode (showOp op)
481+ renderSimpleErrorMessage (MultipleTypeOpFixities op) =
482+ line $ "There are multiple fixity/precedence declarations for type operator " ++ markCode (showOp op)
595 renderSimpleErrorMessage (OrphanTypeDeclaration nm) =
483 renderSimpleErrorMessage (OrphanTypeDeclaration nm) =
596− line $ "The type declaration for " ++ showIdent nm ++ " should be followed by its definition."
484+ line $ "The type declaration for " ++ markCode (showIdent nm) ++ " should be followed by its definition."
597− renderSimpleErrorMessage (OrphanFixityDeclaration op) =
598− line $ "The fixity/precedence declaration for " ++ show op ++ " should appear in the same module as its definition."
599 renderSimpleErrorMessage (RedefinedModule name filenames) =
485 renderSimpleErrorMessage (RedefinedModule name filenames) =
600− paras [ line ("The module " ++ runModuleName name ++ " has been defined multiple times:")
486+ paras [ line ("The module " ++ markCode (runModuleName name) ++ " has been defined multiple times:")
601 , indent . paras $ map (line . displaySourceSpan) filenames
487 , indent . paras $ map (line . displaySourceSpan) filenames
602 ]
488 ]
603 renderSimpleErrorMessage (RedefinedIdent name) =
489 renderSimpleErrorMessage (RedefinedIdent name) =
604− line $ "The value " ++ showIdent name ++ " has been defined multiple times"
490+ line $ "The value " ++ markCode (showIdent name) ++ " has been defined multiple times"
605− renderSimpleErrorMessage (UnknownModule mn) =
491+ renderSimpleErrorMessage (UnknownName name) =
606− line $ "Unknown module " ++ runModuleName mn
492+ line $ "Unknown " ++ printName name
607− renderSimpleErrorMessage (UnknownType name) =
608− line $ "Unknown type " ++ showQualified runProperName name
609− renderSimpleErrorMessage (UnknownTypeOp name) =
610− line $ "Unknown type operator " ++ showQualified showIdent name
611− renderSimpleErrorMessage (UnknownTypeClass name) =
612− line $ "Unknown type class " ++ showQualified runProperName name
613− renderSimpleErrorMessage (UnknownValue name) =
614− line $ "Unknown value " ++ showQualified showIdent name
615− renderSimpleErrorMessage (UnknownTypeConstructor name) =
616− line $ "Unknown type constructor " ++ showQualified runProperName name
617− renderSimpleErrorMessage (UnknownDataConstructor dc tc) =
493+ renderSimpleErrorMessage (UnknownImport mn name) =
618− line $ "Unknown data constructor " ++ showQualified runProperName dc ++ foldMap ((" for type constructor " ++) . showQualified runProperName) tc
494+ paras [ line $ "Cannot import " ++ printName (Qualified Nothing name) ++ " from module " ++ markCode (runModuleName mn)
619− renderSimpleErrorMessage (UnknownImportType mn name) =
620− paras [ line $ "Cannot import type " ++ runProperName name ++ " from module " ++ runModuleName mn
621− , line "It either does not exist or the module does not export it."
622− ]
623− renderSimpleErrorMessage (UnknownExportType name) =
624− line $ "Cannot export unknown type " ++ runProperName name
625− renderSimpleErrorMessage (UnknownImportTypeOp mn name) =
626− paras [ line $ "Cannot import type operator " ++ showIdent name ++ " from module " ++ runModuleName mn
627 , line "It either does not exist or the module does not export it."
495 , line "It either does not exist or the module does not export it."
628 ]
496 ]
629− renderSimpleErrorMessage (UnknownExportTypeOp name) =
630− line $ "Cannot export unknown type operator " ++ showIdent name
631− renderSimpleErrorMessage (UnknownImportTypeClass mn name) =
632− paras [ line $ "Cannot import type class " ++ runProperName name ++ " from module " ++ runModuleName mn
633− , line "It either does not exist or the module does not export it."
634− ]
635− renderSimpleErrorMessage (UnknownExportTypeClass name) =
636− line $ "Cannot export unknown type class " ++ runProperName name
637− renderSimpleErrorMessage (UnknownImportValue mn name) =
638− paras [ line $ "Cannot import value " ++ showIdent name ++ " from module " ++ runModuleName mn
639− , line "It either does not exist or the module does not export it."
640− ]
641− renderSimpleErrorMessage (UnknownExportValue name) =
642− line $ "Cannot export unknown value " ++ showIdent name
643− renderSimpleErrorMessage (UnknownExportModule name) =
644− paras [ line $ "Cannot export unknown module " ++ runModuleName name
645− , line "It either does not exist or has not been imported by the current module."
646− ]
647 renderSimpleErrorMessage (UnknownImportDataConstructor mn tcon dcon) =
497 renderSimpleErrorMessage (UnknownImportDataConstructor mn tcon dcon) =
648− line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon
498+ line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ markCode (runProperName dcon) ++ " for type " ++ markCode (runProperName tcon)
499+ renderSimpleErrorMessage (UnknownExport name) =
500+ line $ "Cannot export unknown " ++ printName (Qualified Nothing name)
649 renderSimpleErrorMessage (UnknownExportDataConstructor tcon dcon) =
501 renderSimpleErrorMessage (UnknownExportDataConstructor tcon dcon) =
650− line $ "Cannot export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon ++ ", as it has not been declared."
502+ line $ "Cannot export data constructor " ++ markCode (runProperName dcon) ++ " for type " ++ markCode (runProperName tcon) ++ ", as it has not been declared."
651 renderSimpleErrorMessage (ScopeConflict nm ms) =
503 renderSimpleErrorMessage (ScopeConflict nm ms) =
652− paras [ line $ "Conflicting definitions are in scope for " ++ nm ++ " from the following modules:"
504+ paras [ line $ "Conflicting definitions are in scope for " ++ printName (Qualified Nothing nm) ++ " from the following modules:"
653− , indent $ paras $ map (line . runModuleName) ms
505+ , indent $ paras $ map (line . markCode . runModuleName) ms
654 ]
506 ]
655 renderSimpleErrorMessage (ScopeShadowing nm exmn ms) =
507 renderSimpleErrorMessage (ScopeShadowing nm exmn ms) =
656− paras [ line $ "Shadowed definitions are in scope for " ++ nm ++ " from the following open imports:"
508+ paras [ line $ "Shadowed definitions are in scope for " ++ printName (Qualified Nothing nm) ++ " from the following open imports:"
657− , indent $ paras $ map (line . ("import " ++) . runModuleName) ms
509+ , indent $ paras $ map (line . markCode . ("import " ++) . runModuleName) ms
658 , line $ "These will be ignored and the " ++ case exmn of
510 , line $ "These will be ignored and the " ++ case exmn of
659− Just exmn' -> "declaration from " ++ runModuleName exmn' ++ " will be used."
511+ Just exmn' -> "declaration from " ++ markCode (runModuleName exmn') ++ " will be used."
660 Nothing -> "local declaration will be used."
512 Nothing -> "local declaration will be used."
661 ]
513 ]
662− renderSimpleErrorMessage (ConflictingTypeDecls nm) =
514+ renderSimpleErrorMessage (DeclConflict new existing) =
663− line $ "Conflicting type declarations for " ++ runProperName nm
515+ line $ "Declaration for " ++ printName (Qualified Nothing new) ++ " conflicts with an existing " ++ nameType existing ++ " of the same name."
664− renderSimpleErrorMessage (ConflictingCtorDecls nm) =
665− line $ "Conflicting data constructor declarations for " ++ runProperName nm
666− renderSimpleErrorMessage (TypeConflictsWithClass nm) =
667− line $ "Type " ++ runProperName nm ++ " conflicts with a type class declaration with the same name."
668− renderSimpleErrorMessage (CtorConflictsWithClass nm) =
669− line $ "Data constructor " ++ runProperName nm ++ " conflicts with a type class declaration with the same name."
670− renderSimpleErrorMessage (ClassConflictsWithType nm) =
516+ renderSimpleErrorMessage (ExportConflict new existing) =
671− line $ "Type class " ++ runProperName nm ++ " conflicts with a type declaration with the same name."
517+ line $ "Export for " ++ printName new ++ " conflicts with " ++ runName existing
672− renderSimpleErrorMessage (ClassConflictsWithCtor nm) =
673− line $ "Type class " ++ runProperName nm ++ " conflicts with a data constructor declaration with the same name."
674 renderSimpleErrorMessage (DuplicateModuleName mn) =
518 renderSimpleErrorMessage (DuplicateModuleName mn) =
675− line $ "Module " ++ runModuleName mn ++ " has been defined multiple times."
519+ line $ "Module " ++ markCode (runModuleName mn) ++ " has been defined multiple times."
676− renderSimpleErrorMessage (DuplicateClassExport nm) =
677− line $ "Duplicate export declaration for type class " ++ runProperName nm
678− renderSimpleErrorMessage (DuplicateValueExport nm) =
679− line $ "Duplicate export declaration for value " ++ showIdent nm
680− renderSimpleErrorMessage (DuplicateTypeOpExport nm) =
681− line $ "Duplicate export declaration for type operator " ++ showIdent nm
682 renderSimpleErrorMessage (CycleInDeclaration nm) =
520 renderSimpleErrorMessage (CycleInDeclaration nm) =
683− line $ "The value of " ++ showIdent nm ++ " is undefined here, so this reference is not allowed."
521+ line $ "The value of " ++ markCode (showIdent nm) ++ " is undefined here, so this reference is not allowed."
684 renderSimpleErrorMessage (CycleInModules mns) =
522 renderSimpleErrorMessage (CycleInModules mns) =
685 paras [ line "There is a cycle in module dependencies in these modules: "
523 paras [ line "There is a cycle in module dependencies in these modules: "
686− , indent $ paras (map (line . runModuleName) mns)
524+ , indent $ paras (map (line . markCode . runModuleName) mns)
687 ]
525 ]
688 renderSimpleErrorMessage (CycleInTypeSynonym name) =
526 renderSimpleErrorMessage (CycleInTypeSynonym name) =
689 paras [ line $ case name of
527 paras [ line $ case name of
690− Just pn -> "A cycle appears in the definition of type synonym " ++ runProperName pn
528+ Just pn -> "A cycle appears in the definition of type synonym " ++ markCode (runProperName pn)
691 Nothing -> "A cycle appears in a set of type synonym definitions."
529 Nothing -> "A cycle appears in a set of type synonym definitions."
692 , line "Cycles are disallowed because they can lead to loops in the type checker."
530 , line "Cycles are disallowed because they can lead to loops in the type checker."
693 , line "Consider using a 'newtype' instead."
531 , line "Consider using a 'newtype' instead."
694 ]
532 ]
695 renderSimpleErrorMessage (NameIsUndefined ident) =
533 renderSimpleErrorMessage (NameIsUndefined ident) =
696− line $ "Value " ++ showIdent ident ++ " is undefined."
534+ line $ "Value " ++ markCode (showIdent ident) ++ " is undefined."
697 renderSimpleErrorMessage (UndefinedTypeVariable name) =
535 renderSimpleErrorMessage (UndefinedTypeVariable name) =
698− line $ "Type variable " ++ runProperName name ++ " is undefined."
536+ line $ "Type variable " ++ markCode (runProperName name) ++ " is undefined."
699 renderSimpleErrorMessage (PartiallyAppliedSynonym name) =
537 renderSimpleErrorMessage (PartiallyAppliedSynonym name) =
700− paras [ line $ "Type synonym " ++ showQualified runProperName name ++ " is partially applied."
538+ paras [ line $ "Type synonym " ++ markCode (showQualified runProperName name) ++ " is partially applied."
701 , line "Type synonyms must be applied to all of their type arguments."
539 , line "Type synonyms must be applied to all of their type arguments."
702 ]
540 ]
703 renderSimpleErrorMessage (EscapedSkolem binding) =
541 renderSimpleErrorMessage (EscapedSkolem binding) =
704 paras $ [ line "A type variable has escaped its scope." ]
542 paras $ [ line "A type variable has escaped its scope." ]
705 <> foldMap (\expr -> [ line "Relevant expression: "
543 <> foldMap (\expr -> [ line "Relevant expression: "
706− , indent $ prettyPrintValue valueDepth expr
544+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr
707 ]) binding
545 ]) binding
708 renderSimpleErrorMessage (TypesDoNotUnify u1 u2)
546 renderSimpleErrorMessage (TypesDoNotUnify u1 u2)
709 = let (sorted1, sorted2) = sortRows u1 u2
547 = let (sorted1, sorted2) = sortRows u1 u2
@@ -725,39 +563,56 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
725 , rowFromList (sortBy (comparing fst) sd2 ++ map (fst &&& snd . snd) common, r2)
563 , rowFromList (sortBy (comparing fst) sd2 ++ map (fst &&& snd . snd) common, r2)
726 )
564 )
727 in paras [ line "Could not match type"
565 in paras [ line "Could not match type"
728− , indent $ typeAsBox sorted1
566+ , markCodeBox $ indent $ typeAsBox sorted1
729 , line "with type"
567 , line "with type"
730− , indent $ typeAsBox sorted2
568+ , markCodeBox $ indent $ typeAsBox sorted2
731 ]
569 ]
732
570
733 renderSimpleErrorMessage (KindsDoNotUnify k1 k2) =
571 renderSimpleErrorMessage (KindsDoNotUnify k1 k2) =
734 paras [ line "Could not match kind"
572 paras [ line "Could not match kind"
735− , indent $ line $ prettyPrintKind k1
573+ , indent $ line $ markCode $ prettyPrintKind k1
736 , line "with kind"
574 , line "with kind"
737− , indent $ line $ prettyPrintKind k2
575+ , indent $ line $ markCode $ prettyPrintKind k2
738 ]
576 ]
739 renderSimpleErrorMessage (ConstrainedTypeUnified t1 t2) =
577 renderSimpleErrorMessage (ConstrainedTypeUnified t1 t2) =
740 paras [ line "Could not match constrained type"
578 paras [ line "Could not match constrained type"
741− , indent $ typeAsBox t1
579+ , markCodeBox $ indent $ typeAsBox t1
742 , line "with type"
580 , line "with type"
743− , indent $ typeAsBox t2
581+ , markCodeBox $ indent $ typeAsBox t2
744 ]
582 ]
745 renderSimpleErrorMessage (OverlappingInstances nm ts (d : ds)) =
583 renderSimpleErrorMessage (OverlappingInstances nm ts (d : ds)) =
746 paras [ line "Overlapping type class instances found for"
584 paras [ line "Overlapping type class instances found for"
585+ , markCodeBox $ indent $ Box.hsep 1 Box.left
747− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
586+ [ line (showQualified runProperName nm)
748− , Box.vcat Box.left (map typeAtomAsBox ts)
587+ , Box.vcat Box.left (map typeAtomAsBox ts)
749− ]
588+ ]
750 , line "The following instances were found:"
589 , line "The following instances were found:"
751 , indent $ paras (line (showQualified showIdent d ++ " (chosen)") : map (line . showQualified showIdent) ds)
590 , indent $ paras (line (showQualified showIdent d ++ " (chosen)") : map (line . showQualified showIdent) ds)
752 , line "Overlapping type class instances can lead to different behavior based on the order of module imports, and for that reason are not recommended."
591 , line "Overlapping type class instances can lead to different behavior based on the order of module imports, and for that reason are not recommended."
753 , line "They may be disallowed completely in a future version of the compiler."
592 , line "They may be disallowed completely in a future version of the compiler."
754 ]
593 ]
755 renderSimpleErrorMessage OverlappingInstances{} = internalError "OverlappingInstances: empty instance list"
594 renderSimpleErrorMessage OverlappingInstances{} = internalError "OverlappingInstances: empty instance list"
756− renderSimpleErrorMessage (NoInstanceFound nm ts) =
595+ renderSimpleErrorMessage (NoInstanceFound (Constraint C.Fail [ TypeLevelString message ] _)) =
596+ paras [ line "A custom type error occurred while solving type class constraints:"
597+ , indent . paras . map line . lines $ message
598+ ]
599+ renderSimpleErrorMessage (NoInstanceFound (Constraint C.Partial
600+ _
601+ (Just (PartialConstraintData bs b)))) =
602+ paras [ line "A case expression could not be determined to cover all inputs."
603+ , line "The following additional cases are required to cover all inputs:\n"
604+ , indent $ paras $
605+ Box.hsep 1 Box.left
606+ (map (paras . map (line . markCode)) (transpose bs))
607+ : [line "..." | not b]
608+ , line "Alternatively, add a Partial constraint to the type of the enclosing value."
609+ ]
610+ renderSimpleErrorMessage (NoInstanceFound (Constraint nm ts _)) =
757 paras [ line "No type class instance was found for"
611 paras [ line "No type class instance was found for"
612+ , markCodeBox $ indent $ Box.hsep 1 Box.left
758− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
613+ [ line (showQualified runProperName nm)
759− , Box.vcat Box.left (map typeAtomAsBox ts)
614+ , Box.vcat Box.left (map typeAtomAsBox ts)
760− ]
615+ ]
761 , paras [ line "The instance head contains unknown type variables. Consider adding a type annotation."
616 , paras [ line "The instance head contains unknown type variables. Consider adding a type annotation."
762 | any containsUnknowns ts
617 | any containsUnknowns ts
763 ]
618 ]
@@ -770,130 +625,118 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
770 go _ = False
625 go _ = False
771 renderSimpleErrorMessage (PossiblyInfiniteInstance nm ts) =
626 renderSimpleErrorMessage (PossiblyInfiniteInstance nm ts) =
772 paras [ line "Type class instance for"
627 paras [ line "Type class instance for"
628+ , markCodeBox $ indent $ Box.hsep 1 Box.left
773− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
629+ [ line (showQualified runProperName nm)
774− , Box.vcat Box.left (map typeAtomAsBox ts)
630+ , Box.vcat Box.left (map typeAtomAsBox ts)
775− ]
631+ ]
776 , line "is possibly infinite."
632 , line "is possibly infinite."
777 ]
633 ]
778 renderSimpleErrorMessage (CannotDerive nm ts) =
634 renderSimpleErrorMessage (CannotDerive nm ts) =
779 paras [ line "Cannot derive a type class instance for"
635 paras [ line "Cannot derive a type class instance for"
636+ , markCodeBox $ indent $ Box.hsep 1 Box.left
780− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
637+ [ line (showQualified runProperName nm)
781− , Box.vcat Box.left (map typeAtomAsBox ts)
638+ , Box.vcat Box.left (map typeAtomAsBox ts)
782− ]
639+ ]
783 ]
640 ]
784 renderSimpleErrorMessage (CannotFindDerivingType nm) =
641 renderSimpleErrorMessage (CannotFindDerivingType nm) =
785− line $ "Cannot derive a type class instance, because the type declaration for " ++ runProperName nm ++ " could not be found."
642+ line $ "Cannot derive a type class instance, because the type declaration for " ++ markCode (runProperName nm) ++ " could not be found."
786 renderSimpleErrorMessage (DuplicateLabel l expr) =
643 renderSimpleErrorMessage (DuplicateLabel l expr) =
787− paras $ [ line $ "Label " ++ show l ++ " appears more than once in a row type." ]
644+ paras $ [ line $ "Label " ++ markCode l ++ " appears more than once in a row type." ]
788 <> foldMap (\expr' -> [ line "Relevant expression: "
645 <> foldMap (\expr' -> [ line "Relevant expression: "
789− , indent $ prettyPrintValue valueDepth expr'
646+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr'
790 ]) expr
647 ]) expr
791 renderSimpleErrorMessage (DuplicateTypeArgument name) =
648 renderSimpleErrorMessage (DuplicateTypeArgument name) =
792− line $ "Type argument " ++ show name ++ " appears more than once."
649+ line $ "Type argument " ++ markCode name ++ " appears more than once."
793 renderSimpleErrorMessage (DuplicateValueDeclaration nm) =
650 renderSimpleErrorMessage (DuplicateValueDeclaration nm) =
794− line $ "Multiple value declarations exist for " ++ showIdent nm ++ "."
651+ line $ "Multiple value declarations exist for " ++ markCode (showIdent nm) ++ "."
795 renderSimpleErrorMessage (ArgListLengthsDiffer ident) =
652 renderSimpleErrorMessage (ArgListLengthsDiffer ident) =
796− line $ "Argument list lengths differ in declaration " ++ showIdent ident
653+ line $ "Argument list lengths differ in declaration " ++ markCode (showIdent ident)
797 renderSimpleErrorMessage (OverlappingArgNames ident) =
654 renderSimpleErrorMessage (OverlappingArgNames ident) =
798 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration " ++) . showIdent) ident
655 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration " ++) . showIdent) ident
799 renderSimpleErrorMessage (MissingClassMember ident) =
656 renderSimpleErrorMessage (MissingClassMember ident) =
800− line $ "Type class member " ++ showIdent ident ++ " has not been implemented."
657+ line $ "Type class member " ++ markCode (showIdent ident) ++ " has not been implemented."
801 renderSimpleErrorMessage (ExtraneousClassMember ident className) =
658 renderSimpleErrorMessage (ExtraneousClassMember ident className) =
802− line $ showIdent ident ++ " is not a member of type class " ++ showQualified runProperName className
659+ line $ "" ++ markCode (showIdent ident) ++ " is not a member of type class " ++ markCode (showQualified runProperName className)
803 renderSimpleErrorMessage (ExpectedType ty kind) =
660 renderSimpleErrorMessage (ExpectedType ty kind) =
804− paras [ line "In a type-annotated expression x :: t, the type t must have kind *."
661+ paras [ line $ "In a type-annotated expression " ++ markCode "x :: t" ++ ", the type " ++ markCode "t" ++ " must have kind " ++ markCode "*" ++ "."
805 , line "The error arises from the type"
662 , line "The error arises from the type"
806− , indent $ typeAsBox ty
663+ , markCodeBox $ indent $ typeAsBox ty
807 , line "having the kind"
664 , line "having the kind"
808− , indent $ line $ prettyPrintKind kind
665+ , indent $ line $ markCode $ prettyPrintKind kind
809 , line "instead."
666 , line "instead."
810 ]
667 ]
811 renderSimpleErrorMessage (IncorrectConstructorArity nm) =
668 renderSimpleErrorMessage (IncorrectConstructorArity nm) =
812− line $ "Data constructor " ++ showQualified runProperName nm ++ " was given the wrong number of arguments in a case expression."
669+ line $ "Data constructor " ++ markCode (showQualified runProperName nm) ++ " was given the wrong number of arguments in a case expression."
813 renderSimpleErrorMessage (ExprDoesNotHaveType expr ty) =
670 renderSimpleErrorMessage (ExprDoesNotHaveType expr ty) =
814 paras [ line "Expression"
671 paras [ line "Expression"
815− , indent $ prettyPrintValue valueDepth expr
672+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr
816 , line "does not have type"
673 , line "does not have type"
817− , indent $ typeAsBox ty
674+ , markCodeBox $ indent $ typeAsBox ty
818 ]
675 ]
819 renderSimpleErrorMessage (PropertyIsMissing prop) =
676 renderSimpleErrorMessage (PropertyIsMissing prop) =
820− line $ "Type of expression lacks required label " ++ show prop ++ "."
677+ line $ "Type of expression lacks required label " ++ markCode prop ++ "."
821 renderSimpleErrorMessage (AdditionalProperty prop) =
678 renderSimpleErrorMessage (AdditionalProperty prop) =
822− line $ "Type of expression contains additional label " ++ show prop ++ "."
679+ line $ "Type of expression contains additional label " ++ markCode prop ++ "."
823 renderSimpleErrorMessage (CannotApplyFunction fn arg) =
680 renderSimpleErrorMessage (CannotApplyFunction fn arg) =
824 paras [ line "A function of type"
681 paras [ line "A function of type"
825− , indent $ typeAsBox fn
682+ , markCodeBox $ indent $ typeAsBox fn
826 , line "can not be applied to the argument"
683 , line "can not be applied to the argument"
827− , indent $ prettyPrintValue valueDepth arg
684+ , markCodeBox $ indent $ prettyPrintValue valueDepth arg
828 ]
685 ]
829 renderSimpleErrorMessage TypeSynonymInstance =
686 renderSimpleErrorMessage TypeSynonymInstance =
830 line "Type class instances for type synonyms are disallowed."
687 line "Type class instances for type synonyms are disallowed."
831 renderSimpleErrorMessage (OrphanInstance nm cnm ts) =
688 renderSimpleErrorMessage (OrphanInstance nm cnm ts) =
832− paras [ line $ "Type class instance " ++ showIdent nm ++ " for "
689+ paras [ line $ "Type class instance " ++ markCode (showIdent nm) ++ " for "
690+ , markCodeBox $ indent $ Box.hsep 1 Box.left
833− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName cnm)
691+ [ line (showQualified runProperName cnm)
834− , Box.vcat Box.left (map typeAtomAsBox ts)
692+ , Box.vcat Box.left (map typeAtomAsBox ts)
835− ]
693+ ]
836 , line "is an orphan instance."
694 , line "is an orphan instance."
837 , line "An orphan instance is an instance which is defined in neither the class module nor the data type module."
695 , line "An orphan instance is an instance which is defined in neither the class module nor the data type module."
838 , line "Consider moving the instance, if possible, or using a newtype wrapper."
696 , line "Consider moving the instance, if possible, or using a newtype wrapper."
839 ]
697 ]
840 renderSimpleErrorMessage (InvalidNewtype name) =
698 renderSimpleErrorMessage (InvalidNewtype name) =
841− paras [ line $ "Newtype " ++ runProperName name ++ " is invalid."
699+ paras [ line $ "Newtype " ++ markCode (runProperName name) ++ " is invalid."
842 , line "Newtypes must define a single constructor with a single argument."
700 , line "Newtypes must define a single constructor with a single argument."
843 ]
701 ]
844 renderSimpleErrorMessage (InvalidInstanceHead ty) =
702 renderSimpleErrorMessage (InvalidInstanceHead ty) =
845 paras [ line "Type class instance head is invalid due to use of type"
703 paras [ line "Type class instance head is invalid due to use of type"
846− , indent $ typeAsBox ty
704+ , markCodeBox $ indent $ typeAsBox ty
847 , line "All types appearing in instance declarations must be of the form T a_1 .. a_n, where each type a_i is of the same form."
705 , line "All types appearing in instance declarations must be of the form T a_1 .. a_n, where each type a_i is of the same form."
848 ]
706 ]
849 renderSimpleErrorMessage (TransitiveExportError x ys) =
707 renderSimpleErrorMessage (TransitiveExportError x ys) =
850− paras [ line $ "An export for " ++ prettyPrintExport x ++ " requires the following to also be exported: "
708+ paras [ line $ "An export for " ++ markCode (prettyPrintExport x) ++ " requires the following to also be exported: "
851− , indent $ paras $ map (line . prettyPrintExport) ys
709+ , indent $ paras $ map (line . markCode . prettyPrintExport) ys
852 ]
710 ]
853 renderSimpleErrorMessage (TransitiveDctorExportError x ctor) =
711 renderSimpleErrorMessage (TransitiveDctorExportError x ctor) =
854− paras [ line $ "An export for " ++ prettyPrintExport x ++ " requires the following data constructor to also be exported: "
712+ paras [ line $ "An export for " ++ markCode (prettyPrintExport x) ++ " requires the following data constructor to also be exported: "
855− , indent $ line $ runProperName ctor
713+ , indent $ line $ markCode $ runProperName ctor
856 ]
714 ]
857 renderSimpleErrorMessage (ShadowedName nm) =
715 renderSimpleErrorMessage (ShadowedName nm) =
858− line $ "Name '" ++ showIdent nm ++ "' was shadowed."
716+ line $ "Name " ++ markCode (showIdent nm) ++ " was shadowed."
859 renderSimpleErrorMessage (ShadowedTypeVar tv) =
717 renderSimpleErrorMessage (ShadowedTypeVar tv) =
860− line $ "Type variable '" ++ tv ++ "' was shadowed."
718+ line $ "Type variable " ++ markCode tv ++ " was shadowed."
861 renderSimpleErrorMessage (UnusedTypeVar tv) =
719 renderSimpleErrorMessage (UnusedTypeVar tv) =
862− line $ "Type variable '" ++ tv ++ "' was declared but not used."
720+ line $ "Type variable " ++ markCode tv ++ " was declared but not used."
863− renderSimpleErrorMessage (ClassOperator className opName) =
864− paras [ line $ "Type class '" ++ runProperName className ++ "' declares operator " ++ showIdent opName ++ "."
865− , line "This may be disallowed in the future - consider declaring a named member in the class and making the operator an alias:"
866− , indent . line $ showIdent opName ++ " = someMember"
867− ]
868 renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
721 renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
869− line $ "Importing type " ++ runProperName name ++ "(..) from " ++ runModuleName mn ++ " is misleading as it has no exported data constructors."
722+ line $ "Importing type " ++ markCode (runProperName name ++ "(..)") ++ " from " ++ markCode (runModuleName mn) ++ " is misleading as it has no exported data constructors."
870 renderSimpleErrorMessage (ImportHidingModule name) =
723 renderSimpleErrorMessage (ImportHidingModule name) =
871− paras [ line "'hiding' imports cannot be used to hide modules."
724+ paras [ line "hiding imports cannot be used to hide modules."
872− , line $ "An attempt was made to hide the import of " ++ runModuleName name
725+ , line $ "An attempt was made to hide the import of " ++ markCode (runModuleName name)
873− ]
726+ ]
874− renderSimpleErrorMessage (WildcardInferredType ty) =
727+ renderSimpleErrorMessage (WildcardInferredType ty ctx) =
875− paras [ line "Wildcard type definition has the inferred type "
728+ paras $ [ line "Wildcard type definition has the inferred type "
876− , indent $ typeAsBox ty
729+ , markCodeBox $ indent $ typeAsBox ty
877− ]
730+ ] ++ renderContext ctx
878− renderSimpleErrorMessage (HoleInferredType name ty) =
731+ renderSimpleErrorMessage (HoleInferredType name ty ctx) =
879− paras [ line $ "Hole '" ++ name ++ "' has the inferred type "
732+ paras $ [ line $ "Hole '" ++ markCode name ++ "' has the inferred type "
880− , indent $ typeAsBox ty
733+ , markCodeBox $ indent $ typeAsBox ty
881− ]
734+ ] ++ renderContext ctx
882 renderSimpleErrorMessage (MissingTypeDeclaration ident ty) =
735 renderSimpleErrorMessage (MissingTypeDeclaration ident ty) =
883− paras [ line $ "No type declaration was provided for the top-level declaration of " ++ showIdent ident ++ "."
736+ paras [ line $ "No type declaration was provided for the top-level declaration of " ++ markCode (showIdent ident) ++ "."
884 , line "It is good practice to provide type declarations as a form of documentation."
737 , line "It is good practice to provide type declarations as a form of documentation."
885− , line $ "The inferred type of " ++ showIdent ident ++ " was:"
738+ , line $ "The inferred type of " ++ markCode (showIdent ident) ++ " was:"
886− , indent $ typeAsBox ty
739+ , markCodeBox $ indent $ typeAsBox ty
887− ]
888− renderSimpleErrorMessage (NotExhaustivePattern bs b) =
889− paras [ line "A case expression could not be determined to cover all inputs."
890− , line "The following additional cases are required to cover all inputs:\n"
891− , indent $ paras $
892− Box.hsep 1 Box.left
893− (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
894− : [line "..." | not b]
895− , line "Or alternatively, add a Partial constraint to the type of the enclosing value."
896− , line "Non-exhaustive patterns for values without a `Partial` constraint will be disallowed in PureScript 0.9."
897 ]
740 ]
898 renderSimpleErrorMessage (OverlappingPattern bs b) =
741 renderSimpleErrorMessage (OverlappingPattern bs b) =
899 paras $ [ line "A case expression contains unreachable cases:\n"
742 paras $ [ line "A case expression contains unreachable cases:\n"
@@ -905,109 +748,51 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
905 , line "You may want to decompose your data types into smaller types."
748 , line "You may want to decompose your data types into smaller types."
906 ]
749 ]
907 renderSimpleErrorMessage (UnusedImport name) =
750 renderSimpleErrorMessage (UnusedImport name) =
908− line $ "The import of module " ++ runModuleName name ++ " is redundant"
751+ line $ "The import of module " ++ markCode (runModuleName name) ++ " is redundant"
909
752
910 renderSimpleErrorMessage msg@(UnusedExplicitImport mn names _ _) =
753 renderSimpleErrorMessage msg@(UnusedExplicitImport mn names _ _) =
911− paras [ line $ "The import of module " ++ runModuleName mn ++ " contains the following unused references:"
754+ paras [ line $ "The import of module " ++ markCode (runModuleName mn) ++ " contains the following unused references:"
912 , indent $ paras $ map line names
755 , indent $ paras $ map line names
913 , line "It could be replaced with:"
756 , line "It could be replaced with:"
914− , indent $ line $ showSuggestion msg ]
757+ , indent $ line $ markCode $ showSuggestion msg ]
915
758
916 renderSimpleErrorMessage (UnusedDctorImport name) =
759 renderSimpleErrorMessage (UnusedDctorImport name) =
917− line $ "The import of type " ++ runProperName name ++ " includes data constructors but only the type is used"
760+ line $ "The import of type " ++ markCode (runProperName name) ++ " includes data constructors but only the type is used"
918
761
919 renderSimpleErrorMessage (UnusedDctorExplicitImport name names) =
762 renderSimpleErrorMessage (UnusedDctorExplicitImport name names) =
920− paras [ line $ "The import of type " ++ runProperName name ++ " includes the following unused data constructors:"
763+ paras [ line $ "The import of type " ++ markCode (runProperName name) ++ " includes the following unused data constructors:"
921− , indent $ paras $ map (line .runProperName) names ]
764+ , indent $ paras $ map (line . markCode . runProperName) names ]
922−
923− renderSimpleErrorMessage (DeprecatedOperatorDecl name) =
924− paras [ line $ "The operator (" ++ name ++ ") was declared as a value rather than an alias for a named function."
925− , line "Operator aliases are declared by using a fixity declaration, for example:"
926− , indent $ line $ "infixl 9 someFunction as " ++ name
927− , line "Support for value-declared operators will be removed in PureScript 0.9."
928− ]
929−
930− renderSimpleErrorMessage (DeprecatedOperatorSection op val) =
931− paras [ line "An operator section uses legacy syntax. Operator sections are now written using anonymous function syntax:"
932− , indent $ foldr1 before $
933− case val of
934− Left l ->
935− [ line "("
936− , prettyPrintValue valueDepth l
937− , line " "
938− , renderOperator op
939− , line " _)"
940− ]
941− Right r ->
942− [ line "(_ "
943− , renderOperator op
944− , line " "
945− , prettyPrintValue valueDepth r
946− , line ")"
947− ]
948− , line "Support for legacy operator sections will be removed in PureScript 0.9."
949− ]
950− where
951− renderOperator (PositionedValue _ _ ex) = renderOperator ex
952− renderOperator (Var (Qualified _ (Op ident))) = line ident
953− renderOperator other = Box.hcat Box.top [ line "`", prettyPrintValue valueDepth other, line "`" ]
954− renderSimpleErrorMessage (DeprecatedQualifiedSyntax name qualName) =
955− paras [ line "Import uses the deprecated 'qualified' syntax:"
956− , indent $ line $ "import qualified " ++ runModuleName name ++ " as " ++ runModuleName qualName
957− , line "Should instead use the form:"
958− , indent $ line $ "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
959− , line "The deprecated syntax will be removed in PureScript 0.9."
960− ]
961−
962− renderSimpleErrorMessage (DeprecatedClassImport mn name) =
963− paras [ line $ "Class import from " ++ runModuleName mn ++ " uses deprecated syntax that omits the 'class' keyword:"
964− , indent $ line $ runProperName name
965− , line "Should instead use the form:"
966− , indent $ line $ "class " ++ runProperName name
967− , line "The deprecated syntax will be removed in PureScript 0.9."
968− ]
969−
970− renderSimpleErrorMessage (DeprecatedClassExport name) =
971− paras [ line "Class export uses deprecated syntax that omits the 'class' keyword:"
972− , indent $ line $ runProperName name
973− , line "Should instead use the form:"
974− , indent $ line $ "class " ++ runProperName name
975− , line "The deprecated syntax will be removed in PureScript 0.9."
976− ]
977
765
978 renderSimpleErrorMessage (DuplicateSelectiveImport name) =
766 renderSimpleErrorMessage (DuplicateSelectiveImport name) =
979− line $ "There is an existing import of " ++ runModuleName name ++ ", consider merging the import lists"
767+ line $ "There is an existing import of " ++ markCode (runModuleName name) ++ ", consider merging the import lists"
980
768
981 renderSimpleErrorMessage (DuplicateImport name imp qual) =
769 renderSimpleErrorMessage (DuplicateImport name imp qual) =
982− line $ "Duplicate import of " ++ prettyPrintImport name imp qual
770+ line $ "Duplicate import of " ++ markCode (prettyPrintImport name imp qual)
983
771
984− renderSimpleErrorMessage (DuplicateImportRef ref) =
772+ renderSimpleErrorMessage (DuplicateImportRef name) =
985− line $ "Import list contains multiple references to " ++ ref
773+ line $ "Import list contains multiple references to " ++ printName (Qualified Nothing name)
986
774
987− renderSimpleErrorMessage (DuplicateExportRef ref) =
775+ renderSimpleErrorMessage (DuplicateExportRef name) =
988− line $ "Export list contains multiple references to " ++ ref
776+ line $ "Export list contains multiple references to " ++ printName (Qualified Nothing name)
989
777
990 renderSimpleErrorMessage (IntOutOfRange value backend lo hi) =
778 renderSimpleErrorMessage (IntOutOfRange value backend lo hi) =
991− paras [ line $ "Integer value " ++ show value ++ " is out of range for the " ++ backend ++ " backend."
779+ paras [ line $ "Integer value " ++ markCode (show value) ++ " is out of range for the " ++ backend ++ " backend."
992− , line $ "Acceptable values fall within the range " ++ show lo ++ " to " ++ show hi ++ " (inclusive)." ]
780+ , line $ "Acceptable values fall within the range " ++ markCode (show lo) ++ " to " ++ markCode (show hi) ++ " (inclusive)." ]
993−
994− renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
995− line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
996
781
997 renderSimpleErrorMessage msg@(ImplicitQualifiedImport importedModule asModule _) =
782 renderSimpleErrorMessage msg@(ImplicitQualifiedImport importedModule asModule _) =
998− paras [ line $ "Module " ++ runModuleName importedModule ++ " was imported as " ++ runModuleName asModule ++ " with unspecified imports."
783+ paras [ line $ "Module " ++ markCode (runModuleName importedModule) ++ " was imported as " ++ markCode (runModuleName asModule) ++ " with unspecified imports."
999− , line $ "As there are multiple modules being imported as " ++ runModuleName asModule ++ ", consider using the explicit form:"
784+ , line $ "As there are multiple modules being imported as " ++ markCode (runModuleName asModule) ++ ", consider using the explicit form:"
1000− , indent $ line $ showSuggestion msg
785+ , indent $ line $ markCode $ showSuggestion msg
1001 ]
786 ]
1002
787
1003 renderSimpleErrorMessage msg@(ImplicitImport mn _) =
788 renderSimpleErrorMessage msg@(ImplicitImport mn _) =
1004− paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
789+ paras [ line $ "Module " ++ markCode (runModuleName mn) ++ " has unspecified imports, consider using the explicit form: "
1005− , indent $ line $ showSuggestion msg
790+ , indent $ line $ markCode $ showSuggestion msg
1006 ]
791 ]
1007
792
1008 renderSimpleErrorMessage msg@(HidingImport mn _) =
793 renderSimpleErrorMessage msg@(HidingImport mn _) =
1009− paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the inclusive form: "
794+ paras [ line $ "Module " ++ markCode (runModuleName mn) ++ " has unspecified imports, consider using the inclusive form: "
1010− , indent $ line $ showSuggestion msg
795+ , indent $ line $ markCode $ showSuggestion msg
1011 ]
796 ]
1012
797
1013 renderSimpleErrorMessage (CaseBinderLengthDiffers l bs) =
798 renderSimpleErrorMessage (CaseBinderLengthDiffers l bs) =
@@ -1020,7 +805,7 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1020 line "An anonymous function argument appears in an invalid context."
805 line "An anonymous function argument appears in an invalid context."
1021
806
1022 renderSimpleErrorMessage (InvalidOperatorInBinder op fn) =
807 renderSimpleErrorMessage (InvalidOperatorInBinder op fn) =
1023− paras [ line $ "Operator " ++ showIdent op ++ " cannot be used in a pattern as it is an alias for function " ++ showIdent fn ++ "."
808+ paras [ line $ "Operator " ++ markCode (showQualified showOp op) ++ " cannot be used in a pattern as it is an alias for function " ++ showQualified showIdent fn ++ "."
1024 , line "Only aliases for data constructors may be used in patterns."
809 , line "Only aliases for data constructors may be used in patterns."
1025 ]
810 ]
1026
811
@@ -1028,9 +813,9 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1028 line "The require-path option is deprecated and will be removed in PureScript 0.9."
813 line "The require-path option is deprecated and will be removed in PureScript 0.9."
1029
814
1030 renderSimpleErrorMessage (CannotGeneralizeRecursiveFunction ident ty) =
815 renderSimpleErrorMessage (CannotGeneralizeRecursiveFunction ident ty) =
1031− paras [ line $ "Unable to generalize the type of the recursive function " ++ showIdent ident ++ "."
816+ paras [ line $ "Unable to generalize the type of the recursive function " ++ markCode (showIdent ident) ++ "."
1032− , line $ "The inferred type of " ++ showIdent ident ++ " was:"
817+ , line $ "The inferred type of " ++ markCode (showIdent ident) ++ " was:"
1033− , indent $ typeAsBox ty
818+ , markCodeBox $ indent $ typeAsBox ty
1034 , line "Try adding a type signature."
819 , line "Try adding a type signature."
1035 ]
820 ]
1036
821
@@ -1038,42 +823,43 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1038 renderHint (ErrorUnifyingTypes t1 t2) detail =
823 renderHint (ErrorUnifyingTypes t1 t2) detail =
1039 paras [ detail
824 paras [ detail
1040 , Box.hsep 1 Box.top [ line "while trying to match type"
825 , Box.hsep 1 Box.top [ line "while trying to match type"
1041− , typeAsBox t1
826+ , markCodeBox $ typeAsBox t1
1042 ]
827 ]
1043 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "with type"
828 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "with type"
1044− , typeAsBox t2
829+ , markCodeBox $ typeAsBox t2
1045 ]
830 ]
1046 ]
831 ]
1047 renderHint (ErrorInExpression expr) detail =
832 renderHint (ErrorInExpression expr) detail =
1048 paras [ detail
833 paras [ detail
1049 , Box.hsep 1 Box.top [ Box.text "in the expression"
834 , Box.hsep 1 Box.top [ Box.text "in the expression"
1050− , prettyPrintValue valueDepth expr
835+ , markCodeBox $ markCodeBox $ prettyPrintValue valueDepth expr
1051 ]
836 ]
1052 ]
837 ]
1053 renderHint (ErrorInModule mn) detail =
838 renderHint (ErrorInModule mn) detail =
1054− paras [ line $ "in module " ++ runModuleName mn
839+ paras [ line $ "in module " ++ markCode (runModuleName mn)
1055 , detail
840 , detail
1056 ]
841 ]
1057 renderHint (ErrorInSubsumption t1 t2) detail =
842 renderHint (ErrorInSubsumption t1 t2) detail =
1058 paras [ detail
843 paras [ detail
1059 , Box.hsep 1 Box.top [ line "while checking that type"
844 , Box.hsep 1 Box.top [ line "while checking that type"
1060− , typeAsBox t1
845+ , markCodeBox $ typeAsBox t1
1061 ]
846 ]
1062 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "is at least as general as type"
847 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "is at least as general as type"
1063− , typeAsBox t2
848+ , markCodeBox $ typeAsBox t2
1064 ]
849 ]
1065 ]
850 ]
1066 renderHint (ErrorInInstance nm ts) detail =
851 renderHint (ErrorInInstance nm ts) detail =
1067 paras [ detail
852 paras [ detail
1068− , Box.hsep 1 Box.top [ line "in type class instance"
853+ , line "in type class instance"
854+ , markCodeBox $ indent $ Box.hsep 1 Box.top
1069− , line (showQualified runProperName nm)
855+ [ line $ showQualified runProperName nm
1070− , Box.vcat Box.left (map typeAtomAsBox ts)
856+ , Box.vcat Box.left (map typeAtomAsBox ts)
1071− ]
857+ ]
1072 ]
858 ]
1073 renderHint (ErrorCheckingKind ty) detail =
859 renderHint (ErrorCheckingKind ty) detail =
1074 paras [ detail
860 paras [ detail
1075 , Box.hsep 1 Box.top [ line "while checking the kind of"
861 , Box.hsep 1 Box.top [ line "while checking the kind of"
1076− , typeAsBox ty
862+ , markCodeBox $ typeAsBox ty
1077 ]
863 ]
1078 ]
864 ]
1079 renderHint ErrorCheckingGuard detail =
865 renderHint ErrorCheckingGuard detail =
@@ -1083,43 +869,43 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1083 renderHint (ErrorInferringType expr) detail =
869 renderHint (ErrorInferringType expr) detail =
1084 paras [ detail
870 paras [ detail
1085 , Box.hsep 1 Box.top [ line "while inferring the type of"
871 , Box.hsep 1 Box.top [ line "while inferring the type of"
1086− , prettyPrintValue valueDepth expr
872+ , markCodeBox $ prettyPrintValue valueDepth expr
1087 ]
873 ]
1088 ]
874 ]
1089 renderHint (ErrorCheckingType expr ty) detail =
875 renderHint (ErrorCheckingType expr ty) detail =
1090 paras [ detail
876 paras [ detail
1091 , Box.hsep 1 Box.top [ line "while checking that expression"
877 , Box.hsep 1 Box.top [ line "while checking that expression"
1092− , prettyPrintValue valueDepth expr
878+ , markCodeBox $ prettyPrintValue valueDepth expr
1093 ]
879 ]
1094 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "has type"
880 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "has type"
1095− , typeAsBox ty
881+ , markCodeBox $ typeAsBox ty
1096 ]
882 ]
1097 ]
883 ]
1098 renderHint (ErrorCheckingAccessor expr prop) detail =
884 renderHint (ErrorCheckingAccessor expr prop) detail =
1099 paras [ detail
885 paras [ detail
1100 , Box.hsep 1 Box.top [ line "while checking type of property accessor"
886 , Box.hsep 1 Box.top [ line "while checking type of property accessor"
1101− , prettyPrintValue valueDepth (Accessor prop expr)
887+ , markCodeBox $ prettyPrintValue valueDepth (Accessor prop expr)
1102 ]
888 ]
1103 ]
889 ]
1104 renderHint (ErrorInApplication f t a) detail =
890 renderHint (ErrorInApplication f t a) detail =
1105 paras [ detail
891 paras [ detail
1106 , Box.hsep 1 Box.top [ line "while applying a function"
892 , Box.hsep 1 Box.top [ line "while applying a function"
1107− , prettyPrintValue valueDepth f
893+ , markCodeBox $ prettyPrintValue valueDepth f
1108 ]
894 ]
1109 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "of type"
895 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "of type"
1110− , typeAsBox t
896+ , markCodeBox $ typeAsBox t
1111 ]
897 ]
1112 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "to argument"
898 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "to argument"
1113− , prettyPrintValue valueDepth a
899+ , markCodeBox $ prettyPrintValue valueDepth a
1114 ]
900 ]
1115 ]
901 ]
1116 renderHint (ErrorInDataConstructor nm) detail =
902 renderHint (ErrorInDataConstructor nm) detail =
1117 paras [ detail
903 paras [ detail
1118− , line $ "in data constructor " ++ runProperName nm
904+ , line $ "in data constructor " ++ markCode (runProperName nm)
1119 ]
905 ]
1120 renderHint (ErrorInTypeConstructor nm) detail =
906 renderHint (ErrorInTypeConstructor nm) detail =
1121 paras [ detail
907 paras [ detail
1122− , line $ "in type constructor " ++ runProperName nm
908+ , line $ "in type constructor " ++ markCode (runProperName nm)
1123 ]
909 ]
1124 renderHint (ErrorInBindingGroup nms) detail =
910 renderHint (ErrorInBindingGroup nms) detail =
1125 paras [ detail
911 paras [ detail
@@ -1131,25 +917,75 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1131 ]
917 ]
1132 renderHint (ErrorInTypeSynonym name) detail =
918 renderHint (ErrorInTypeSynonym name) detail =
1133 paras [ detail
919 paras [ detail
1134− , line $ "in type synonym " ++ runProperName name
920+ , line $ "in type synonym " ++ markCode (runProperName name)
1135 ]
921 ]
1136 renderHint (ErrorInValueDeclaration n) detail =
922 renderHint (ErrorInValueDeclaration n) detail =
1137 paras [ detail
923 paras [ detail
1138− , line $ "in value declaration " ++ showIdent n
924+ , line $ "in value declaration " ++ markCode (showIdent n)
1139 ]
925 ]
1140 renderHint (ErrorInTypeDeclaration n) detail =
926 renderHint (ErrorInTypeDeclaration n) detail =
1141 paras [ detail
927 paras [ detail
1142− , line $ "in type declaration for " ++ showIdent n
928+ , line $ "in type declaration for " ++ markCode (showIdent n)
1143 ]
929 ]
1144 renderHint (ErrorInForeignImport nm) detail =
930 renderHint (ErrorInForeignImport nm) detail =
1145 paras [ detail
931 paras [ detail
1146− , line $ "in foreign import " ++ showIdent nm
932+ , line $ "in foreign import " ++ markCode (showIdent nm)
933+ ]
934+ renderHint (ErrorSolvingConstraint (Constraint nm ts _)) detail =
935+ paras [ detail
936+ , line "while solving type class constriant"
937+ , markCodeBox $ indent $ Box.hsep 1 Box.left
938+ [ line (showQualified runProperName nm)
939+ , Box.vcat Box.left (map typeAtomAsBox ts)
940+ ]
1147 ]
941 ]
1148 renderHint (PositionedError srcSpan) detail =
942 renderHint (PositionedError srcSpan) detail =
1149 paras [ line $ "at " ++ displaySourceSpan srcSpan
943 paras [ line $ "at " ++ displaySourceSpan srcSpan
1150 , detail
944 , detail
1151 ]
945 ]
1152
946
947+ renderContext :: Context -> [Box.Box]
948+ renderContext [] = []
949+ renderContext ctx =
950+ [ line "in the following context:"
951+ , indent $ paras
952+ [ Box.hcat Box.left [ Box.text (showIdent ident <> " :: ")
953+ , markCodeBox $ typeAsBox ty'
954+ ]
955+ | (ident, ty') <- take 5 ctx
956+ ]
957+ ]
958+
959+ printName :: Qualified Name -> String
960+ printName qn = nameType (disqualify qn) ++ " " ++ markCode (runName qn)
961+
962+ nameType :: Name -> String
963+ nameType (IdentName _) = "value"
964+ nameType (ValOpName _) = "operator"
965+ nameType (TyName _) = "type"
966+ nameType (TyOpName _) = "type operator"
967+ nameType (DctorName _) = "data constructor"
968+ nameType (TyClassName _) = "type class"
969+ nameType (ModName _) = "module"
970+
971+ runName :: Qualified Name -> String
972+ runName (Qualified mn (IdentName name)) =
973+ showQualified showIdent (Qualified mn name)
974+ runName (Qualified mn (ValOpName op)) =
975+ showQualified showOp (Qualified mn op)
976+ runName (Qualified mn (TyName name)) =
977+ showQualified runProperName (Qualified mn name)
978+ runName (Qualified mn (TyOpName op)) =
979+ showQualified showOp (Qualified mn op)
980+ runName (Qualified mn (DctorName name)) =
981+ showQualified runProperName (Qualified mn name)
982+ runName (Qualified mn (TyClassName name)) =
983+ showQualified runProperName (Qualified mn name)
984+ runName (Qualified Nothing (ModName name)) =
985+ runModuleName name
986+ runName (Qualified _ ModName{}) =
987+ internalError "qualified ModName in runName"
988+
1153 valueDepth :: Int
989 valueDepth :: Int
1154 valueDepth | full = 1000
990 valueDepth | full = 1000
1155 | otherwise = 3
991 | otherwise = 3
@@ -1192,6 +1028,10 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1192 where
1028 where
1193 isUnifyHint ErrorUnifyingTypes{} = True
1029 isUnifyHint ErrorUnifyingTypes{} = True
1194 isUnifyHint _ = False
1030 isUnifyHint _ = False
1031+ stripRedudantHints NoInstanceFound{} = stripFirst isSolverHint
1032+ where
1033+ isSolverHint ErrorSolvingConstraint{} = True
1034+ isSolverHint _ = False
1195 stripRedudantHints _ = id
1035 stripRedudantHints _ = id
1196
1036
1197 stripFirst :: (ErrorMessageHint -> Bool) -> [ErrorMessageHint] -> [ErrorMessageHint]
1037 stripFirst :: (ErrorMessageHint -> Bool) -> [ErrorMessageHint] -> [ErrorMessageHint]
@@ -1203,70 +1043,86 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1203 stripFirst _ [] = []
1043 stripFirst _ [] = []
1204
1044
1205 hintCategory :: ErrorMessageHint -> HintCategory
1045 hintCategory :: ErrorMessageHint -> HintCategory
1206− hintCategory ErrorCheckingType{} = ExprHint
1046+ hintCategory ErrorCheckingType{} = ExprHint
1207− hintCategory ErrorInferringType{} = ExprHint
1047+ hintCategory ErrorInferringType{} = ExprHint
1208− hintCategory ErrorInExpression{} = ExprHint
1048+ hintCategory ErrorInExpression{} = ExprHint
1209− hintCategory ErrorUnifyingTypes{} = CheckHint
1049+ hintCategory ErrorUnifyingTypes{} = CheckHint
1210− hintCategory ErrorInSubsumption{} = CheckHint
1050+ hintCategory ErrorInSubsumption{} = CheckHint
1211− hintCategory ErrorInApplication{} = CheckHint
1051+ hintCategory ErrorInApplication{} = CheckHint
1212− hintCategory ErrorCheckingKind{} = CheckHint
1052+ hintCategory ErrorCheckingKind{} = CheckHint
1053+ hintCategory ErrorSolvingConstraint{} = SolverHint
1213− hintCategory PositionedError{} = PositionHint
1054+ hintCategory PositionedError{} = PositionHint
1214− hintCategory _ = OtherHint
1055+ hintCategory _ = OtherHint
1215
1056
1216-- Pretty print and export declaration
1057-- Pretty print and export declaration
1217prettyPrintExport :: DeclarationRef -> String
1058prettyPrintExport :: DeclarationRef -> String
1218prettyPrintExport (TypeRef pn _) = runProperName pn
1059prettyPrintExport (TypeRef pn _) = runProperName pn
1219−prettyPrintExport ref = prettyPrintRef ref
1060+prettyPrintExport ref =
1061+ fromMaybe
1062+ (internalError "prettyPrintRef returned Nothing in prettyPrintExport")
1063+ (prettyPrintRef ref)
1220
1064
1221prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
1065prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
1222prettyPrintImport mn idt qual =
1066prettyPrintImport mn idt qual =
1223 let i = case idt of
1067 let i = case idt of
1224 Implicit -> runModuleName mn
1068 Implicit -> runModuleName mn
1225− Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
1069+ Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (mapMaybe prettyPrintRef refs) ++ ")"
1226− Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (map prettyPrintRef refs) ++ ")"
1070+ Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (mapMaybe prettyPrintRef refs) ++ ")"
1227 in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
1071 in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
1228
1072
1229−prettyPrintRef :: DeclarationRef -> String
1073+prettyPrintRef :: DeclarationRef -> Maybe String
1230−prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
1074+prettyPrintRef (TypeRef pn Nothing) =
1075+ Just $ runProperName pn ++ "(..)"
1231−prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
1076+prettyPrintRef (TypeRef pn (Just [])) =
1077+ Just $ runProperName pn
1078+prettyPrintRef (TypeRef pn (Just dctors)) =
1232−prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1079+ Just $ runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1233−prettyPrintRef (TypeOpRef ident) = "type " ++ showIdent ident
1080+prettyPrintRef (TypeOpRef op) =
1081+ Just $ "type " ++ showOp op
1234−prettyPrintRef (ValueRef ident) = showIdent ident
1082+prettyPrintRef (ValueRef ident) =
1083+ Just $ showIdent ident
1084+prettyPrintRef (ValueOpRef op) =
1085+ Just $ showOp op
1086+prettyPrintRef (TypeClassRef pn) =
1235−prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1087+ Just $ "class " ++ runProperName pn
1236−prettyPrintRef (ProperRef name) = name
1237−prettyPrintRef (TypeInstanceRef ident) = showIdent ident
1088+prettyPrintRef (TypeInstanceRef ident) =
1089+ Just $ showIdent ident
1238−prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
1090+prettyPrintRef (ModuleRef name) =
1091+ Just $ "module " ++ runModuleName name
1092+prettyPrintRef (ReExportRef _ _) =
1093+ Nothing
1239−prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
1094+prettyPrintRef (PositionedDeclarationRef _ _ ref) =
1095+ prettyPrintRef ref
1240
1096
1241-- |
1097-- |
1242-- Pretty print multiple errors
1098-- Pretty print multiple errors
1243--
1099--
1244−prettyPrintMultipleErrors :: Bool -> MultipleErrors -> String
1100+prettyPrintMultipleErrors :: PPEOptions -> MultipleErrors -> String
1245−prettyPrintMultipleErrors full = unlines . map renderBox . prettyPrintMultipleErrorsBox full
1101+prettyPrintMultipleErrors ppeOptions = unlines . map renderBox . prettyPrintMultipleErrorsBox ppeOptions
1246
1102
1247-- |
1103-- |
1248-- Pretty print multiple warnings
1104-- Pretty print multiple warnings
1249--
1105--
1250−prettyPrintMultipleWarnings :: Bool -> MultipleErrors -> String
1106+prettyPrintMultipleWarnings :: PPEOptions -> MultipleErrors -> String
1251−prettyPrintMultipleWarnings full = unlines . map renderBox . prettyPrintMultipleWarningsBox full
1107+prettyPrintMultipleWarnings ppeOptions = unlines . map renderBox . prettyPrintMultipleWarningsBox ppeOptions
1252
1108
1253-- | Pretty print warnings as a Box
1109-- | Pretty print warnings as a Box
1254−prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> [Box.Box]
1110+prettyPrintMultipleWarningsBox :: PPEOptions -> MultipleErrors -> [Box.Box]
1255−prettyPrintMultipleWarningsBox = prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning"
1111+prettyPrintMultipleWarningsBox ppeOptions = prettyPrintMultipleErrorsWith (ppeOptions { ppeLevel = Warning }) "Warning found:" "Warning"
1256
1112
1257-- | Pretty print errors as a Box
1113-- | Pretty print errors as a Box
1258−prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> [Box.Box]
1114+prettyPrintMultipleErrorsBox :: PPEOptions -> MultipleErrors -> [Box.Box]
1259−prettyPrintMultipleErrorsBox = prettyPrintMultipleErrorsWith Error "Error found:" "Error"
1115+prettyPrintMultipleErrorsBox ppeOptions = prettyPrintMultipleErrorsWith (ppeOptions { ppeLevel = Error }) "Error found:" "Error"
1260
1116
1261−prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> [Box.Box]
1117+prettyPrintMultipleErrorsWith :: PPEOptions -> String -> String -> MultipleErrors -> [Box.Box]
1262−prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) =
1118+prettyPrintMultipleErrorsWith ppeOptions intro _ (MultipleErrors [e]) =
1263− let result = prettyPrintSingleError full level True e
1119+ let result = prettyPrintSingleError ppeOptions e
1264 in [ Box.vcat Box.left [ Box.text intro
1120 in [ Box.vcat Box.left [ Box.text intro
1265 , result
1121 , result
1266 ]
1122 ]
1267 ]
1123 ]
1268−prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) =
1124+prettyPrintMultipleErrorsWith ppeOptions _ intro (MultipleErrors es) =
1269− let result = map (prettyPrintSingleError full level True) es
1125+ let result = map (prettyPrintSingleError ppeOptions) es
1270 in concat $ zipWith withIntro [1 :: Int ..] result
1126 in concat $ zipWith withIntro [1 :: Int ..] result
1271 where
1127 where
1272 withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
1128 withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
src/Language/PureScript/Errors/JSON.hs+15−22
@@ -1,22 +1,7 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Errors.JSON
4−-- Copyright : (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess
5−-- License : MIT (http://opensource.org/licenses/MIT)
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−--
13−-----------------------------------------------------------------------------
14−
15{-# LANGUAGE TemplateHaskell #-}
1{-# LANGUAGE TemplateHaskell #-}
16
2
17module Language.PureScript.Errors.JSON where
3module Language.PureScript.Errors.JSON where
18
4
19−import Prelude ()
20import Prelude.Compat
5import Prelude.Compat
21
6
22import qualified Data.Aeson.TH as A
7import qualified Data.Aeson.TH as A
@@ -30,7 +15,10 @@ data ErrorPosition = ErrorPosition
30 , endColumn :: Int
15 , endColumn :: Int
31 } deriving (Show, Eq, Ord)
16 } deriving (Show, Eq, Ord)
32
17
33−data ErrorSuggestion = ErrorSuggestion { replacement :: String } deriving (Show, Eq)
18+data ErrorSuggestion = ErrorSuggestion
19+ { replacement :: String
20+ , replaceRange :: Maybe ErrorPosition
21+ } deriving (Show, Eq)
34
22
35data JSONError = JSONError
23data JSONError = JSONError
36 { position :: Maybe ErrorPosition
24 { position :: Maybe ErrorPosition
@@ -40,7 +28,7 @@ data JSONError = JSONError
40 , filename :: Maybe String
28 , filename :: Maybe String
41 , moduleName :: Maybe String
29 , moduleName :: Maybe String
42 , suggestion :: Maybe ErrorSuggestion
30 , suggestion :: Maybe ErrorSuggestion
43− } deriving (Show, Eq)
31+ } deriving (Show, Eq)
44
32
45data JSONResult = JSONResult
33data JSONResult = JSONResult
46 { warnings :: [JSONError]
34 { warnings :: [JSONError]
@@ -59,12 +47,12 @@ toJSONErrors verbose level = map (toJSONError verbose level) . P.runMultipleErro
59toJSONError :: Bool -> P.Level -> P.ErrorMessage -> JSONError
47toJSONError :: Bool -> P.Level -> P.ErrorMessage -> JSONError
60toJSONError verbose level e =
48toJSONError verbose level e =
61 JSONError (toErrorPosition <$> sspan)
49 JSONError (toErrorPosition <$> sspan)
62− (P.renderBox (P.prettyPrintSingleError verbose level False (P.stripModuleAndSpan e)))
50+ (P.renderBox (P.prettyPrintSingleError (P.PPEOptions Nothing verbose level False) (P.stripModuleAndSpan e)))
63 (P.errorCode e)
51 (P.errorCode e)
64 (P.wikiUri e)
52 (P.wikiUri e)
65 (P.spanName <$> sspan)
53 (P.spanName <$> sspan)
66 (P.runModuleName <$> P.errorModule e)
54 (P.runModuleName <$> P.errorModule e)
67− (toSuggestion <$> P.errorSuggestion (P.unwrapErrorMessage e))
55+ (toSuggestion e)
68 where
56 where
69 sspan :: Maybe P.SourceSpan
57 sspan :: Maybe P.SourceSpan
70 sspan = P.errorSpan e
58 sspan = P.errorSpan e
@@ -75,6 +63,11 @@ toJSONError verbose level e =
75 (P.sourcePosColumn (P.spanStart ss))
63 (P.sourcePosColumn (P.spanStart ss))
76 (P.sourcePosLine (P.spanEnd ss))
64 (P.sourcePosLine (P.spanEnd ss))
77 (P.sourcePosColumn (P.spanEnd ss))
65 (P.sourcePosColumn (P.spanEnd ss))
78− toSuggestion :: P.ErrorSuggestion -> ErrorSuggestion
66+ toSuggestion :: P.ErrorMessage -> Maybe ErrorSuggestion
67+ toSuggestion em =
68+ case P.errorSuggestion $ P.unwrapErrorMessage em of
69+ Nothing -> Nothing
70+ Just s -> Just $ ErrorSuggestion (suggestionText s) (toErrorPosition <$> P.suggestionSpan em)
71+
79−-- TODO: Adding a newline because source spans chomp everything up to the next character
72+ -- TODO: Adding a newline because source spans chomp everything up to the next character
80− toSuggestion (P.ErrorSuggestion s) = ErrorSuggestion $ if null s then s else s ++ "\n"
73+ suggestionText (P.ErrorSuggestion s) = if null s then s else s ++ "\n"
src/Language/PureScript/Externs.hs+45−27
@@ -1,37 +1,35 @@
1−{-# LANGUAGE RecordWildCards #-}
2−{-# LANGUAGE PatternGuards #-}
3{-# LANGUAGE TemplateHaskell #-}
1{-# LANGUAGE TemplateHaskell #-}
4
2
5-- |
3-- |
6−-- This module generates code for \"externs\" files, i.e. files containing only foreign import declarations.
4+-- This module generates code for \"externs\" files, i.e. files containing only
5+-- foreign import declarations.
7--
6--
8module Language.PureScript.Externs
7module Language.PureScript.Externs
9 ( ExternsFile(..)
8 ( ExternsFile(..)
10 , ExternsImport(..)
9 , ExternsImport(..)
11 , ExternsFixity(..)
10 , ExternsFixity(..)
11+ , ExternsTypeFixity(..)
12 , ExternsDeclaration(..)
12 , ExternsDeclaration(..)
13 , moduleToExternsFile
13 , moduleToExternsFile
14 , applyExternsFileToEnvironment
14 , applyExternsFileToEnvironment
15 ) where
15 ) where
16
16
17−import Prelude ()
18import Prelude.Compat
17import Prelude.Compat
19
18
19+import Data.Aeson.TH
20+import Data.Foldable (fold)
20import Data.List (find, foldl')
21import Data.List (find, foldl')
21import Data.Maybe (mapMaybe, maybeToList, fromMaybe)
22import Data.Maybe (mapMaybe, maybeToList, fromMaybe)
22−import Data.Foldable (fold)
23import Data.Version (showVersion)
23import Data.Version (showVersion)
24−import Data.Aeson.TH
25−
26import qualified Data.Map as M
24import qualified Data.Map as M
27
25
28−import Language.PureScript.Crash
29import Language.PureScript.AST
26import Language.PureScript.AST
27+import Language.PureScript.Crash
30import Language.PureScript.Environment
28import Language.PureScript.Environment
31−import Language.PureScript.Names
32−import Language.PureScript.Types
33import Language.PureScript.Kinds
29import Language.PureScript.Kinds
30+import Language.PureScript.Names
34import Language.PureScript.TypeClassDictionaries
31import Language.PureScript.TypeClassDictionaries
32+import Language.PureScript.Types
35
33
36import Paths_purescript as Paths
34import Paths_purescript as Paths
37
35
@@ -48,9 +46,11 @@ data ExternsFile = ExternsFile
48 , efImports :: [ExternsImport]
46 , efImports :: [ExternsImport]
49 -- | List of operators and their fixities
47 -- | List of operators and their fixities
50 , efFixities :: [ExternsFixity]
48 , efFixities :: [ExternsFixity]
49+ -- | List of type operators and their fixities
50+ , efTypeFixities :: [ExternsTypeFixity]
51 -- | List of type and value declaration
51 -- | List of type and value declaration
52 , efDeclarations :: [ExternsDeclaration]
52 , efDeclarations :: [ExternsDeclaration]
53− } deriving (Show, Read)
53+ } deriving (Show)
54
54
55-- | A module import in an externs file
55-- | A module import in an externs file
56data ExternsImport = ExternsImport
56data ExternsImport = ExternsImport
@@ -61,7 +61,7 @@ data ExternsImport = ExternsImport
61 , eiImportType :: ImportDeclarationType
61 , eiImportType :: ImportDeclarationType
62 -- | The imported-as name, for qualified imports
62 -- | The imported-as name, for qualified imports
63 , eiImportedAs :: Maybe ModuleName
63 , eiImportedAs :: Maybe ModuleName
64− } deriving (Show, Read)
64+ } deriving (Show)
65
65
66-- | A fixity declaration in an externs file
66-- | A fixity declaration in an externs file
67data ExternsFixity = ExternsFixity
67data ExternsFixity = ExternsFixity
@@ -71,10 +71,23 @@ data ExternsFixity = ExternsFixity
71 -- | The precedence level of the operator
71 -- | The precedence level of the operator
72 , efPrecedence :: Precedence
72 , efPrecedence :: Precedence
73 -- | The operator symbol
73 -- | The operator symbol
74− , efOperator :: String
74+ , efOperator :: OpName 'ValueOpName
75+ -- | The value the operator is an alias for
76+ , efAlias :: Qualified (Either Ident (ProperName 'ConstructorName))
77+ } deriving (Show)
78+
79+-- | A type fixity declaration in an externs file
80+data ExternsTypeFixity = ExternsTypeFixity
81+ {
82+ -- | The associativity of the operator
83+ efTypeAssociativity :: Associativity
84+ -- | The precedence level of the operator
85+ , efTypePrecedence :: Precedence
86+ -- | The operator symbol
87+ , efTypeOperator :: OpName 'TypeOpName
75 -- | The value the operator is an alias for
88 -- | The value the operator is an alias for
76− , efAlias :: Maybe (Qualified FixityAlias)
89+ , efTypeAlias :: Qualified (ProperName 'TypeName)
77− } deriving (Show, Read)
90+ } deriving (Show)
78
91
79-- | A type or value declaration appearing in an externs file
92-- | A type or value declaration appearing in an externs file
80data ExternsDeclaration =
93data ExternsDeclaration =
@@ -117,7 +130,7 @@ data ExternsDeclaration =
117 , edInstanceTypes :: [Type]
130 , edInstanceTypes :: [Type]
118 , edInstanceConstraints :: Maybe [Constraint]
131 , edInstanceConstraints :: Maybe [Constraint]
119 }
132 }
120− deriving (Show, Read)
133+ deriving (Show)
121
134
122-- | Convert an externs file back into a module
135-- | Convert an externs file back into a module
123applyExternsFileToEnvironment :: ExternsFile -> Environment -> Environment
136applyExternsFileToEnvironment :: ExternsFile -> Environment -> Environment
@@ -127,7 +140,7 @@ applyExternsFileToEnvironment ExternsFile{..} = flip (foldl' applyDecl) efDeclar
127 applyDecl env (EDType pn kind tyKind) = env { types = M.insert (qual pn) (kind, tyKind) (types env) }
140 applyDecl env (EDType pn kind tyKind) = env { types = M.insert (qual pn) (kind, tyKind) (types env) }
128 applyDecl env (EDTypeSynonym pn args ty) = env { typeSynonyms = M.insert (qual pn) (args, ty) (typeSynonyms env) }
141 applyDecl env (EDTypeSynonym pn args ty) = env { typeSynonyms = M.insert (qual pn) (args, ty) (typeSynonyms env) }
129 applyDecl env (EDDataConstructor pn dTy tNm ty nms) = env { dataConstructors = M.insert (qual pn) (dTy, tNm, ty, nms) (dataConstructors env) }
142 applyDecl env (EDDataConstructor pn dTy tNm ty nms) = env { dataConstructors = M.insert (qual pn) (dTy, tNm, ty, nms) (dataConstructors env) }
130− applyDecl env (EDValue ident ty) = env { names = M.insert (efModuleName, ident) (ty, External, Defined) (names env) }
143+ applyDecl env (EDValue ident ty) = env { names = M.insert (Qualified (Just efModuleName) ident) (ty, External, Defined) (names env) }
131 applyDecl env (EDClass pn args members cs) = env { typeClasses = M.insert (qual pn) (args, members, cs) (typeClasses env) }
144 applyDecl env (EDClass pn args members cs) = env { typeClasses = M.insert (qual pn) (args, members, cs) (typeClasses env) }
132 applyDecl env (EDInstance className ident tys cs) = env { typeClassDictionaries = updateMap (updateMap (M.insert (qual ident) dict) className) (Just efModuleName) (typeClassDictionaries env) }
145 applyDecl env (EDInstance className ident tys cs) = env { typeClassDictionaries = updateMap (updateMap (M.insert (qual ident) dict) className) (Just efModuleName) (typeClassDictionaries env) }
133 where
146 where
@@ -150,22 +163,26 @@ moduleToExternsFile (Module _ _ mn ds (Just exps)) env = ExternsFile{..}
150 efExports = exps
163 efExports = exps
151 efImports = mapMaybe importDecl ds
164 efImports = mapMaybe importDecl ds
152 efFixities = mapMaybe fixityDecl ds
165 efFixities = mapMaybe fixityDecl ds
166+ efTypeFixities = mapMaybe typeFixityDecl ds
153 efDeclarations = concatMap toExternsDeclaration efExports
167 efDeclarations = concatMap toExternsDeclaration efExports
154
168
155 fixityDecl :: Declaration -> Maybe ExternsFixity
169 fixityDecl :: Declaration -> Maybe ExternsFixity
156− fixityDecl (FixityDeclaration (Fixity assoc prec) op alias) =
170+ fixityDecl (ValueFixityDeclaration (Fixity assoc prec) name op) =
157− fmap (const (ExternsFixity assoc prec op alias)) (find exportsOp exps)
171+ fmap (const (ExternsFixity assoc prec op name)) (find (findOp getValueOpRef op) exps)
158− where
159− exportsOp :: DeclarationRef -> Bool
160− exportsOp (PositionedDeclarationRef _ _ r) = exportsOp r
161− exportsOp (ValueRef ident') = ident' == Op op
162− exportsOp (TypeOpRef ident') = ident' == Op op
163− exportsOp _ = False
164 fixityDecl (PositionedDeclaration _ _ d) = fixityDecl d
172 fixityDecl (PositionedDeclaration _ _ d) = fixityDecl d
165 fixityDecl _ = Nothing
173 fixityDecl _ = Nothing
166
174
175+ typeFixityDecl :: Declaration -> Maybe ExternsTypeFixity
176+ typeFixityDecl (TypeFixityDeclaration (Fixity assoc prec) name op) =
177+ fmap (const (ExternsTypeFixity assoc prec op name)) (find (findOp getTypeOpRef op) exps)
178+ typeFixityDecl (PositionedDeclaration _ _ d) = typeFixityDecl d
179+ typeFixityDecl _ = Nothing
180+
181+ findOp :: (DeclarationRef -> Maybe (OpName a)) -> OpName a -> DeclarationRef -> Bool
182+ findOp get op = maybe False (== op) . get
183+
167 importDecl :: Declaration -> Maybe ExternsImport
184 importDecl :: Declaration -> Maybe ExternsImport
168− importDecl (ImportDeclaration m mt qmn _) = Just (ExternsImport m mt qmn)
185+ importDecl (ImportDeclaration m mt qmn) = Just (ExternsImport m mt qmn)
169 importDecl (PositionedDeclaration _ _ d) = importDecl d
186 importDecl (PositionedDeclaration _ _ d) = importDecl d
170 importDecl _ = Nothing
187 importDecl _ = Nothing
171
188
@@ -184,7 +201,7 @@ moduleToExternsFile (Module _ _ mn ds (Just exps)) env = ExternsFile{..}
184 ]
201 ]
185 _ -> internalError "toExternsDeclaration: Invalid input"
202 _ -> internalError "toExternsDeclaration: Invalid input"
186 toExternsDeclaration (ValueRef ident)
203 toExternsDeclaration (ValueRef ident)
187− | Just (ty, _, _) <- (mn, ident) `M.lookup` names env
204+ | Just (ty, _, _) <- Qualified (Just mn) ident `M.lookup` names env
188 = [ EDValue ident ty ]
205 = [ EDValue ident ty ]
189 toExternsDeclaration (TypeClassRef className)
206 toExternsDeclaration (TypeClassRef className)
190 | Just (args, members, implies) <- Qualified (Just mn) className `M.lookup` typeClasses env
207 | Just (args, members, implies) <- Qualified (Just mn) className `M.lookup` typeClasses env
@@ -204,5 +221,6 @@ moduleToExternsFile (Module _ _ mn ds (Just exps)) env = ExternsFile{..}
204
221
205$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsImport)
222$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsImport)
206$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsFixity)
223$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsFixity)
224+$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsTypeFixity)
207$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsDeclaration)
225$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsDeclaration)
208$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsFile)
226$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsFile)
src/Language/PureScript/Ide.hs+134−183
@@ -12,34 +12,18 @@
12-- Interface for the psc-ide-server
12-- Interface for the psc-ide-server
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE MultiParamTypeClasses #-}
18{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
19{-# LANGUAGE PackageImports #-}
16{-# LANGUAGE PackageImports #-}
20{-# LANGUAGE TemplateHaskell #-}
17{-# LANGUAGE TemplateHaskell #-}
21−{-# LANGUAGE TupleSections #-}
22
18
23module Language.PureScript.Ide
19module Language.PureScript.Ide
24 ( handleCommand
20 ( handleCommand
25− -- for tests
26− , printModules
27 ) where
21 ) where
28
22
29−import Prelude ()
23+import Protolude
30−import Prelude.Compat
31
24
32−import Control.Monad (unless)
33−import Control.Monad.Error.Class
34−import Control.Monad.IO.Class
35import "monad-logger" Control.Monad.Logger
25import "monad-logger" Control.Monad.Logger
36−import Control.Monad.Reader.Class
26+import qualified Language.PureScript as P
37−import Data.Foldable
38−import qualified Data.Map.Lazy as M
39−import Data.Maybe (catMaybes, mapMaybe)
40−import Data.Monoid
41−import Data.Text (Text)
42−import qualified Data.Text as T
43import qualified Language.PureScript.Ide.CaseSplit as CS
27import qualified Language.PureScript.Ide.CaseSplit as CS
44import Language.PureScript.Ide.Command
28import Language.PureScript.Ide.Command
45import Language.PureScript.Ide.Completion
29import Language.PureScript.Ide.Completion
@@ -50,196 +34,163 @@ import Language.PureScript.Ide.Imports hiding (Import)
50import Language.PureScript.Ide.Matcher
34import Language.PureScript.Ide.Matcher
51import Language.PureScript.Ide.Pursuit
35import Language.PureScript.Ide.Pursuit
52import Language.PureScript.Ide.Rebuild
36import Language.PureScript.Ide.Rebuild
53−import Language.PureScript.Ide.Reexports
54import Language.PureScript.Ide.SourceFile
37import Language.PureScript.Ide.SourceFile
55import Language.PureScript.Ide.State
38import Language.PureScript.Ide.State
56import Language.PureScript.Ide.Types
39import Language.PureScript.Ide.Types
57import Language.PureScript.Ide.Util
40import Language.PureScript.Ide.Util
58import System.Directory
41import System.Directory
59−import System.Exit
60import System.FilePath
42import System.FilePath
43+import System.FilePath.Glob
61
44
45+-- | Accepts a Commmand and runs it against psc-ide's State. This is the main
46+-- entry point for the server.
62−handleCommand :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
47+handleCommand :: (Ide m, MonadLogger m, MonadError PscIdeError m) =>
63 Command -> m Success
48 Command -> m Success
64−handleCommand (Load [] []) = loadAllModules
49+handleCommand c = case c of
50+ Load [] ->
51+ findAvailableExterns >>= loadModules
65−handleCommand (Load modules deps) =
52+ Load modules ->
66− loadModulesAndDeps modules deps
53+ loadModules modules
67−handleCommand (Type search filters) =
54+ Type search filters currentModule ->
68− findType search filters
55+ findType search filters currentModule
69−handleCommand (Complete filters matcher) =
56+ Complete filters matcher currentModule ->
70− findCompletions filters matcher
57+ findCompletions filters matcher currentModule
71−handleCommand (Pursuit query Package) =
58+ Pursuit query Package ->
72− findPursuitPackages query
59+ findPursuitPackages query
73−handleCommand (Pursuit query Identifier) =
60+ Pursuit query Identifier ->
74− findPursuitCompletions query
61+ findPursuitCompletions query
75−handleCommand (List LoadedModules) =
62+ List LoadedModules ->
76− printModules
63+ printModules
77−handleCommand (List AvailableModules) =
64+ List AvailableModules ->
78− listAvailableModules
65+ listAvailableModules
79−handleCommand (List (Imports fp)) =
66+ List (Imports fp) ->
80− importsForFile fp
67+ ImportList <$> getImportsForFile fp
81−handleCommand (CaseSplit l b e wca t) =
68+ CaseSplit l b e wca t ->
82− caseSplit l b e wca t
69+ caseSplit l b e wca t
83−handleCommand (AddClause l wca) =
70+ AddClause l wca ->
84− pure $ addClause l wca
71+ MultilineTextResult <$> CS.addClause l wca
85−handleCommand (Import fp outfp _ (AddImplicitImport mn)) = do
72+ Import fp outfp _ (AddImplicitImport mn) -> do
86− rs <- addImplicitImport fp mn
73+ rs <- addImplicitImport fp mn
87− answerRequest outfp rs
74+ answerRequest outfp rs
88−handleCommand (Import fp outfp filters (AddImportForIdentifier ident)) = do
75+ Import fp outfp filters (AddImportForIdentifier ident) -> do
89− rs <- addImportForIdentifier fp ident filters
76+ rs <- addImportForIdentifier fp ident filters
90− case rs of
77+ case rs of
91− Right rs' -> answerRequest outfp rs'
78+ Right rs' -> answerRequest outfp rs'
79+ Left question ->
92− Left question -> pure $ CompletionResult (mapMaybe completionFromMatch question)
80+ pure (CompletionResult (map completionFromMatch question))
93−handleCommand (Rebuild file) =
81+ Rebuild file ->
94− rebuildFile file
82+ rebuildFile file
95−handleCommand Cwd =
83+ Cwd ->
96− TextResult . T.pack <$> liftIO getCurrentDirectory
84+ TextResult . toS <$> liftIO getCurrentDirectory
85+ Reset ->
86+ resetIdeState $> TextResult "State has been reset."
87+ Quit ->
97−handleCommand Quit = liftIO exitSuccess
88+ liftIO exitSuccess
98−
89+
99−findCompletions :: (PscIde m, MonadLogger m) =>
90+findCompletions :: Ide m =>
100− [Filter] -> Matcher -> m Success
91+ [Filter] -> Matcher IdeDeclaration -> Maybe P.ModuleName -> m Success
101−findCompletions filters matcher =
92+findCompletions filters matcher currentModule = do
93+ modules <- getAllModules currentModule
102− CompletionResult . mapMaybe completionFromMatch . getCompletions filters matcher <$> getAllModulesWithReexports
94+ pure . CompletionResult . map completionFromMatch . getCompletions filters matcher $ modules
103−
95+
104−findType :: (PscIde m, MonadLogger m) =>
96+findType :: Ide m =>
105− DeclIdent -> [Filter] -> m Success
97+ Text -> [Filter] -> Maybe P.ModuleName -> m Success
106−findType search filters =
98+findType search filters currentModule = do
107− CompletionResult . mapMaybe completionFromMatch . getExactMatches search filters <$> getAllModulesWithReexports
99+ modules <- getAllModules currentModule
108−
100+ pure . InfoResult . map infoFromMatch . getExactMatches search filters $ modules
101+
109−findPursuitCompletions :: (MonadIO m, MonadLogger m) =>
102+findPursuitCompletions :: MonadIO m =>
110 PursuitQuery -> m Success
103 PursuitQuery -> m Success
111findPursuitCompletions (PursuitQuery q) =
104findPursuitCompletions (PursuitQuery q) =
112 PursuitResult <$> liftIO (searchPursuitForDeclarations q)
105 PursuitResult <$> liftIO (searchPursuitForDeclarations q)
113
106
114−findPursuitPackages :: (MonadIO m, MonadLogger m) =>
107+findPursuitPackages :: MonadIO m =>
115 PursuitQuery -> m Success
108 PursuitQuery -> m Success
116findPursuitPackages (PursuitQuery q) =
109findPursuitPackages (PursuitQuery q) =
117 PursuitResult <$> liftIO (findPackagesForModuleIdent q)
110 PursuitResult <$> liftIO (findPackagesForModuleIdent q)
118
111
119−loadExtern ::(PscIde m, MonadLogger m, MonadError PscIdeError m) =>
112+printModules :: Ide m => m Success
120− FilePath -> m ()
113+printModules = ModuleList . map runModuleNameT <$> getLoadedModulenames
121−loadExtern fp = do
122− m <- readExternFile fp
123− insertModule m
124
114
125−printModules :: (PscIde m) => m Success
115+outputDirectory :: Ide m => m FilePath
126−printModules = printModules' <$> getPscIdeState
116+outputDirectory = do
127−
117+ outputPath <- confOutputPath . ideConfiguration <$> ask
128−printModules' :: M.Map ModuleIdent [ExternDecl] -> Success
118+ cwd <- liftIO getCurrentDirectory
129−printModules' = ModuleList . M.keys
119+ pure (cwd </> outputPath)
130
120
131−listAvailableModules :: PscIde m => m Success
121+listAvailableModules :: Ide m => m Success
132listAvailableModules = do
122listAvailableModules = do
133− outputPath <- confOutputPath . envConfiguration <$> ask
123+ oDir <- outputDirectory
134 liftIO $ do
124 liftIO $ do
135− cwd <- getCurrentDirectory
136− dirs <- getDirectoryContents (cwd </> outputPath)
125+ contents <- getDirectoryContents oDir
137− return (ModuleList (listAvailableModules' dirs))
138−
139−listAvailableModules' :: [FilePath] -> [Text]
140−listAvailableModules' dirs =
141− let cleanedModules = filter (`notElem` [".", ".."]) dirs
126+ let cleaned = filter (`notElem` [".", ".."]) contents
142− in map T.pack cleanedModules
127+ return (ModuleList (map toS cleaned))
143
128
144−caseSplit :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
129+caseSplit :: (Ide m, MonadError PscIdeError m) =>
145 Text -> Int -> Int -> CS.WildcardAnnotations -> Text -> m Success
130 Text -> Int -> Int -> CS.WildcardAnnotations -> Text -> m Success
146caseSplit l b e csa t = do
131caseSplit l b e csa t = do
147 patterns <- CS.makePattern l b e csa <$> CS.caseSplit t
132 patterns <- CS.makePattern l b e csa <$> CS.caseSplit t
148 pure (MultilineTextResult patterns)
133 pure (MultilineTextResult patterns)
149
134
150−addClause :: Text -> CS.WildcardAnnotations -> Success
135+-- | Finds all the externs.json files inside the output folder and returns the
151−addClause t wca = MultilineTextResult (CS.addClause t wca)
136+-- corresponding Modulenames
152−
153−importsForFile :: (MonadIO m, MonadLogger m, MonadError PscIdeError m) =>
154− FilePath -> m Success
155−importsForFile fp = do
156− imports <- getImportsForFile fp
157− pure (ImportList imports)
158−
159−-- | The first argument is a set of modules to load. The second argument
160−-- denotes modules for which to load dependencies
161−loadModulesAndDeps :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
162− [ModuleIdent] -> [ModuleIdent] -> m Success
163−loadModulesAndDeps mods deps = do
164− r1 <- mapM loadModule (mods ++ deps)
165− r2 <- mapM loadModuleDependencies deps
166− let moduleResults = T.concat r1
167− let dependencyResults = T.concat r2
168− pure (TextResult (moduleResults <> ", " <> dependencyResults))
169−
170−loadModuleDependencies ::(PscIde m, MonadLogger m, MonadError PscIdeError m) =>
171− ModuleIdent -> m Text
172−loadModuleDependencies moduleName = do
173− m <- getModule moduleName
174− case getDependenciesForModule <$> m of
175− Just deps -> do
176− mapM_ loadModule deps
177− -- We need to load the modules, that get reexported from the dependencies
178− depModules <- catMaybes <$> mapM getModule deps
179− -- What to do with errors here? This basically means a reexported dependency
180− -- doesn't exist in the output/ folder
181− traverse_ loadReexports depModules
182− pure ("Dependencies for " <> moduleName <> " loaded.")
183− Nothing -> throwError (ModuleNotFound moduleName)
184−
185−loadReexports :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
137+findAvailableExterns :: (Ide m, MonadError PscIdeError m) => m [P.ModuleName]
186− Module -> m [ModuleIdent]
138+findAvailableExterns = do
187−loadReexports m = case getReexports m of
139+ oDir <- outputDirectory
188− [] -> pure []
189− exportDeps -> do
190− -- I'm fine with this crashing on a failed pattern match.
191− -- If this ever fails I'll need to look at GADTs
192− let reexports = map (\(Export mn) -> mn) exportDeps
193− $(logDebug) ("Loading reexports for module: " <> fst m <>
194− " reexports: " <> T.intercalate ", " reexports)
195− traverse_ loadModule reexports
196− exportDepsModules <- catMaybes <$> traverse getModule reexports
197− exportDepDeps <- traverse loadReexports exportDepsModules
198− return $ concat exportDepDeps
199−
200−getDependenciesForModule :: Module -> [ModuleIdent]
201−getDependenciesForModule (_, decls) = mapMaybe getDependencyName decls
202− where getDependencyName (Dependency dependencyName _ _) = Just dependencyName
203− getDependencyName _ = Nothing
204−
205−loadModule :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
206− ModuleIdent -> m Text
207−loadModule "Prim" = pure "Prim won't be loaded"
208−loadModule mn = do
209− path <- filePathFromModule mn
210− loadExtern path
211− $(logDebug) ("Loaded extern file at: " <> T.pack path)
212− pure ("Loaded extern file at: " <> T.pack path)
213−
214−loadAllModules :: (PscIde m, MonadLogger m, MonadError PscIdeError m) => m Success
215−loadAllModules = do
216− outputPath <- confOutputPath . envConfiguration <$> ask
217− cwd <- liftIO getCurrentDirectory
218− let outputDirectory = cwd </> outputPath
219− liftIO (doesDirectoryExist outputDirectory)
140+ unlessM (liftIO (doesDirectoryExist oDir))
220− >>= flip unless (throwError (GeneralError "Couldn't locate your output directory"))
141+ (throwError (GeneralError "Couldn't locate your output directory."))
142+ liftIO $ do
221− liftIO (getDirectoryContents outputDirectory)
143+ directories <- getDirectoryContents oDir
222− >>= liftIO . traverse (getExternsPath outputDirectory)
144+ moduleNames <- filterM (containsExterns oDir) directories
223− >>= traverse_ loadExtern . catMaybes
145+ pure (P.moduleNameFromString <$> moduleNames)
224− pure (TextResult "All modules loaded.")
225 where
146 where
147+ -- Takes the output directory and a filepath like "Monad.Control.Eff" and
148+ -- looks up, whether that folder contains an externs.json
226− getExternsPath :: FilePath -> FilePath -> IO (Maybe FilePath)
149+ containsExterns :: FilePath -> FilePath -> IO Bool
227− getExternsPath outputDirectory d
150+ containsExterns oDir d
228− | d `elem` [".", ".."] = pure Nothing
151+ | d `elem` [".", ".."] = pure False
229 | otherwise = do
152 | otherwise = do
230− let file = outputDirectory </> d </> "externs.json"
153+ let file = oDir </> d </> "externs.json"
231− ex <- doesFileExist file
154+ doesFileExist file
232− if ex
155+
233− then pure (Just file)
156+-- | Finds all matches for the globs specified at the commandline
234− else pure Nothing
157+findAllSourceFiles :: Ide m => m [FilePath]
235−
158+findAllSourceFiles = do
159+ globs <- confGlobs . ideConfiguration <$> ask
160+ liftIO (concatMapM glob globs)
161+
162+-- | Looks up the ExternsFiles for the given Modulenames and loads them into the
163+-- server state. Then proceeds to parse all the specified sourcefiles and
164+-- inserts their ASTs into the state. Finally kicks off an async worker, which
165+-- populates Stage 2 and 3 of the state.
166+loadModules
236−filePathFromModule :: (PscIde m, MonadError PscIdeError m) =>
167+ :: (Ide m, MonadError PscIdeError m, MonadLogger m)
237− ModuleIdent -> m FilePath
168+ => [P.ModuleName]
238−filePathFromModule moduleName = do
169+ -> m Success
239− outputPath <- confOutputPath . envConfiguration <$> ask
170+loadModules moduleNames = do
240− cwd <- liftIO getCurrentDirectory
171+ -- We resolve all the modulenames to externs files and load these into memory.
241− let path = cwd </> outputPath </> T.unpack moduleName </> "externs.json"
172+ oDir <- outputDirectory
242− ex <- liftIO $ doesFileExist path
173+ let efPaths =
243− if ex
174+ map (\mn -> oDir </> P.runModuleName mn </> "externs.json") moduleNames
244− then pure path
175+ efiles <- traverse readExternFile efPaths
245− else throwError (ModuleFileNotFound moduleName)
176+ traverse_ insertExterns efiles
177+
178+ -- We parse all source files, log eventual parse failures if the debug flag
179+ -- was set and insert the succesful parses into the state.
180+ (failures, allModules) <-
181+ partitionEithers <$> (traverse parseModule =<< findAllSourceFiles)
182+ unless (null failures) $
183+ $(logDebug) ("Failed to parse: " <> show failures)
184+ traverse_ insertModule allModules
185+
186+ -- Finally we kick off the worker with @async@ and return the number of
187+ -- successfully parsed modules.
188+ env <- ask
189+ let runLogger =
190+ runStdoutLoggingT
191+ . filterLogger (\_ _ -> confDebug (ideConfiguration env))
192+ -- populateStage2 and 3 return Unit for now, so it's fine to discard this
193+ -- result. We might want to block on this in a benchmarking situation.
194+ _ <- liftIO (async (runLogger (runReaderT (populateStage2 *> populateStage3) env)))
195+ pure (TextResult ("Loaded " <> show (length efiles) <> " modules and "
196+ <> show (length allModules) <> " source files."))
src/Language/PureScript/Ide/CaseSplit.hs+24−36
@@ -12,14 +12,7 @@
12-- Casesplitting and adding function clauses
12-- Casesplitting and adding function clauses
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE DataKinds #-}
17−{-# LANGUAGE FlexibleContexts #-}
18−{-# LANGUAGE LambdaCase #-}
19−{-# LANGUAGE MultiParamTypeClasses #-}
20{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
21−{-# LANGUAGE PackageImports #-}
22−{-# LANGUAGE RecordWildCards #-}
23
16
24module Language.PureScript.Ide.CaseSplit
17module Language.PureScript.Ide.CaseSplit
25 ( WildcardAnnotations()
18 ( WildcardAnnotations()
@@ -30,26 +23,19 @@ module Language.PureScript.Ide.CaseSplit
30 , caseSplit
23 , caseSplit
31 ) where
24 ) where
32
25
33−import Prelude ()
26+import Protolude hiding (Constructor)
34−import Prelude.Compat hiding (lex)
35
27
36−import Control.Arrow (second)
37−import Control.Monad.Error.Class
38−import "monad-logger" Control.Monad.Logger
39−import Data.List (find)
40−import Data.Monoid
41−import Data.Text (Text)
42import qualified Data.Text as T
28import qualified Data.Text as T
43import qualified Language.PureScript as P
29import qualified Language.PureScript as P
44
30
45import Language.PureScript.Externs
31import Language.PureScript.Externs
46import Language.PureScript.Ide.Error
32import Language.PureScript.Ide.Error
47−import Language.PureScript.Ide.Externs (unwrapPositioned)
48import Language.PureScript.Ide.State
33import Language.PureScript.Ide.State
49import Language.PureScript.Ide.Types
34import Language.PureScript.Ide.Types
50import Language.PureScript.Ide.Util
35import Language.PureScript.Ide.Util
51
36
52import Text.Parsec as Parsec
37import Text.Parsec as Parsec
38+import qualified Text.PrettyPrint.Boxes as Box
53
39
54type Constructor = (P.ProperName 'P.ConstructorName, [P.Type])
40type Constructor = (P.ProperName 'P.ConstructorName, [P.Type])
55
41
@@ -61,17 +47,17 @@ explicitAnnotations = WildcardAnnotations True
61noAnnotations :: WildcardAnnotations
47noAnnotations :: WildcardAnnotations
62noAnnotations = WildcardAnnotations False
48noAnnotations = WildcardAnnotations False
63
49
64−caseSplit :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
50+caseSplit :: (Ide m, MonadError PscIdeError m) =>
65 Text -> m [Constructor]
51 Text -> m [Constructor]
66caseSplit q = do
52caseSplit q = do
67− type' <- parseType' (T.unpack q)
53+ type' <- parseType' q
68 (tc, args) <- splitTypeConstructor type'
54 (tc, args) <- splitTypeConstructor type'
69 (EDType _ _ (P.DataType typeVars ctors)) <- findTypeDeclaration tc
55 (EDType _ _ (P.DataType typeVars ctors)) <- findTypeDeclaration tc
70 let applyTypeVars = P.everywhereOnTypes (P.replaceAllTypeVars (zip (map fst typeVars) args))
56 let applyTypeVars = P.everywhereOnTypes (P.replaceAllTypeVars (zip (map fst typeVars) args))
71 let appliedCtors = map (second (map applyTypeVars)) ctors
57 let appliedCtors = map (second (map applyTypeVars)) ctors
72 pure appliedCtors
58 pure appliedCtors
73
59
74−findTypeDeclaration :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
60+findTypeDeclaration :: (Ide m, MonadError PscIdeError m) =>
75 P.ProperName 'P.TypeName -> m ExternsDeclaration
61 P.ProperName 'P.TypeName -> m ExternsDeclaration
76findTypeDeclaration q = do
62findTypeDeclaration q = do
77 efs <- getExternFiles
63 efs <- getExternFiles
@@ -121,39 +107,41 @@ makePattern t x y wsa = makePattern' (T.take x t) (T.drop y t)
121 where
107 where
122 makePattern' lhs rhs = map (\ctor -> lhs <> prettyCtor wsa ctor <> rhs)
108 makePattern' lhs rhs = map (\ctor -> lhs <> prettyCtor wsa ctor <> rhs)
123
109
124−addClause :: Text -> WildcardAnnotations -> [Text]
110+addClause :: (MonadError PscIdeError m) => Text -> WildcardAnnotations -> m [Text]
125−addClause s wca =
111+addClause s wca = do
126− let (fName, fType) = parseTypeDeclaration' (T.unpack s)
112+ (fName, fType) <- parseTypeDeclaration' s
127− (args, _) = splitFunctionType fType
113+ let args = splitFunctionType fType
128 template = runIdentT fName <> " " <>
114 template = runIdentT fName <> " " <>
129 T.unwords (map (prettyPrintWildcard wca) args) <>
115 T.unwords (map (prettyPrintWildcard wca) args) <>
130 " = ?" <> (T.strip . runIdentT $ fName)
116 " = ?" <> (T.strip . runIdentT $ fName)
131− in [s, template]
117+ pure [s, template]
132
118
133parseType' :: (MonadError PscIdeError m) =>
119parseType' :: (MonadError PscIdeError m) =>
134− String -> m P.Type
120+ Text -> m P.Type
135parseType' s =
121parseType' s =
136− case P.lex "<psc-ide>" s >>= P.runTokenParser "<psc-ide>" (P.parseType <* Parsec.eof) of
122+ case P.lex "<psc-ide>" (toS s) >>= P.runTokenParser "<psc-ide>" (P.parseType <* Parsec.eof) of
137 Right type' -> pure type'
123 Right type' -> pure type'
138 Left err ->
124 Left err ->
139 throwError (GeneralError ("Parsing the splittype failed with:"
125 throwError (GeneralError ("Parsing the splittype failed with:"
140− ++ show err))
126+ <> show err))
141
127
142−parseTypeDeclaration' :: String -> (P.Ident, P.Type)
128+parseTypeDeclaration' :: (MonadError PscIdeError m) => Text -> m (P.Ident, P.Type)
143parseTypeDeclaration' s =
129parseTypeDeclaration' s =
144 let x = do
130 let x = do
145− ts <- P.lex "" s
131+ ts <- P.lex "" (toS s)
146 P.runTokenParser "" (P.parseDeclaration <* Parsec.eof) ts
132 P.runTokenParser "" (P.parseDeclaration <* Parsec.eof) ts
147 in
133 in
148 case unwrapPositioned <$> x of
134 case unwrapPositioned <$> x of
149− Right (P.TypeDeclaration i t) -> (i, t)
135+ Right (P.TypeDeclaration i t) -> pure (i, t)
150− y -> error (show y)
136+ Right _ -> throwError (GeneralError "Found a non-type-declaration")
151−
137+ Left err ->
138+ throwError (GeneralError ("Parsing the type signature failed with: "
139+ <> toS (Box.render (P.prettyPrintParseError err))))
140+
152−splitFunctionType :: P.Type -> ([P.Type], P.Type)
141+splitFunctionType :: P.Type -> [P.Type]
153−splitFunctionType t = (arguments, returns)
142+splitFunctionType t = fromMaybe [] arguments
154 where
143 where
155− returns = last splitted
156− arguments = init splitted
144+ arguments = initMay splitted
157 splitted = splitType' t
145 splitted = splitType' t
158 splitType' (P.ForAll _ t' _) = splitType' t'
146 splitType' (P.ForAll _ t' _) = splitType' t'
159 splitType' (P.ConstrainedType _ t') = splitType' t'
147 splitType' (P.ConstrainedType _ t') = splitType' t'
src/Language/PureScript/Ide/Command.hs+62−72
@@ -12,38 +12,30 @@
12-- Datatypes for the commands psc-ide accepts
12-- Datatypes for the commands psc-ide accepts
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE MultiParamTypeClasses #-}
16{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
18
16
19module Language.PureScript.Ide.Command where
17module Language.PureScript.Ide.Command where
20
18
21−import Prelude ()
19+import Protolude
22−import Prelude.Compat
23
20
24−import Control.Monad
25import Data.Aeson
21import Data.Aeson
26−import Data.Maybe
27−import Data.Text (Text)
28−import Language.PureScript (ModuleName,
22+import qualified Language.PureScript as P
29− moduleNameFromString)
30import Language.PureScript.Ide.CaseSplit
23import Language.PureScript.Ide.CaseSplit
31import Language.PureScript.Ide.Filter
24import Language.PureScript.Ide.Filter
32import Language.PureScript.Ide.Matcher
25import Language.PureScript.Ide.Matcher
33import Language.PureScript.Ide.Types
26import Language.PureScript.Ide.Types
34
27
35data Command
28data Command
36− = Load
29+ = Load [P.ModuleName]
37− { loadModules :: [ModuleIdent]
38− , loadDependencies :: [ModuleIdent]
39− }
40 | Type
30 | Type
41− { typeSearch :: DeclIdent
31+ { typeSearch :: Text
42− , typeFilters :: [Filter]
32+ , typeFilters :: [Filter]
33+ , typeCurrentModule :: Maybe P.ModuleName
43 }
34 }
44 | Complete
35 | Complete
45− { completeFilters :: [Filter]
36+ { completeFilters :: [Filter]
46− , completeMatcher :: Matcher
37+ , completeMatcher :: Matcher IdeDeclaration
38+ , completeCurrentModule :: Maybe P.ModuleName
47 }
39 }
48 | Pursuit
40 | Pursuit
49 { pursuitQuery :: PursuitQuery
41 { pursuitQuery :: PursuitQuery
@@ -65,93 +57,91 @@ data Command
65 | List { listType :: ListType }
57 | List { listType :: ListType }
66 | Rebuild FilePath -- ^ Rebuild the specified file using the loaded externs
58 | Rebuild FilePath -- ^ Rebuild the specified file using the loaded externs
67 | Cwd
59 | Cwd
60+ | Reset
68 | Quit
61 | Quit
69
62
70data ImportCommand
63data ImportCommand
71− = AddImplicitImport ModuleName
64+ = AddImplicitImport P.ModuleName
72− | AddImportForIdentifier DeclIdent
65+ | AddImportForIdentifier Text
73 deriving (Show, Eq)
66 deriving (Show, Eq)
74
67
75instance FromJSON ImportCommand where
68instance FromJSON ImportCommand where
76 parseJSON = withObject "ImportCommand" $ \o -> do
69 parseJSON = withObject "ImportCommand" $ \o -> do
77− (command :: String) <- o .: "importCommand"
70+ (command :: Text) <- o .: "importCommand"
78 case command of
71 case command of
79− "addImplicitImport" -> do
72+ "addImplicitImport" ->
80− mn <- o .: "module"
81− pure (AddImplicitImport (moduleNameFromString mn))
73+ AddImplicitImport <$> (P.moduleNameFromString <$> o .: "module")
82− "addImport" -> do
74+ "addImport" ->
83− ident <- o .: "identifier"
84− pure (AddImportForIdentifier ident)
75+ AddImportForIdentifier <$> o .: "identifier"
85 _ -> mzero
76 _ -> mzero
86
77
87data ListType = LoadedModules | Imports FilePath | AvailableModules
78data ListType = LoadedModules | Imports FilePath | AvailableModules
88
79
89instance FromJSON ListType where
80instance FromJSON ListType where
90 parseJSON = withObject "ListType" $ \o -> do
81 parseJSON = withObject "ListType" $ \o -> do
91− (listType' :: String) <- o .: "type"
82+ (listType' :: Text) <- o .: "type"
92 case listType' of
83 case listType' of
93− "import" -> do
84+ "import" -> Imports <$> o .: "file"
94− fp <- o .: "file"
95− return (Imports fp)
96− "loadedModules" -> return LoadedModules
85+ "loadedModules" -> pure LoadedModules
97− "availableModules" -> return AvailableModules
86+ "availableModules" -> pure AvailableModules
98 _ -> mzero
87 _ -> mzero
99
88
100instance FromJSON Command where
89instance FromJSON Command where
101 parseJSON = withObject "command" $ \o -> do
90 parseJSON = withObject "command" $ \o -> do
102− (command :: String) <- o .: "command"
91+ (command :: Text) <- o .: "command"
103 case command of
92 case command of
104− "list" -> do
105− listType' <- o .:? "params"
106− return $ List (fromMaybe LoadedModules listType')
93+ "list" -> List <$> o .:? "params" .!= LoadedModules
107− "cwd" -> return Cwd
94+ "cwd" -> pure Cwd
108− "quit" -> return Quit
95+ "quit" -> pure Quit
96+ "reset" -> pure Reset
109− "load" ->
97+ "load" -> do
98+ params' <- o .:? "params"
99+ case params' of
110− maybe (pure (Load [] [])) (\params -> do
100+ Nothing -> pure (Load [])
101+ Just params ->
111− mods <- params .:? "modules"
102+ Load <$> (map P.moduleNameFromString <$> params .:? "modules" .!= [])
112− deps <- params .:? "dependencies"
113− pure $ Load (fromMaybe [] mods) (fromMaybe [] deps)) =<< o .:? "params"
114 "type" -> do
103 "type" -> do
115 params <- o .: "params"
104 params <- o .: "params"
116− search <- params .: "search"
105+ Type
117− filters <- params .: "filters"
106+ <$> params .: "search"
118− return $ Type search filters
107+ <*> params .: "filters"
108+ <*> (fmap P.moduleNameFromString <$> params .:? "currentModule")
119 "complete" -> do
109 "complete" -> do
120 params <- o .: "params"
110 params <- o .: "params"
121− filters <- params .:? "filters"
111+ Complete
122− matcher <- params .:? "matcher"
112+ <$> params .:? "filters" .!= []
123− return $ Complete (fromMaybe [] filters) (fromMaybe mempty matcher)
113+ <*> params .:? "matcher" .!= mempty
114+ <*> (fmap P.moduleNameFromString <$> params .:? "currentModule")
124 "pursuit" -> do
115 "pursuit" -> do
125 params <- o .: "params"
116 params <- o .: "params"
117+ Pursuit
126− query <- params .: "query"
118+ <$> params .: "query"
127− queryType <- params .: "type"
119+ <*> params .: "type"
128− return $ Pursuit query queryType
129 "caseSplit" -> do
120 "caseSplit" -> do
130 params <- o .: "params"
121 params <- o .: "params"
131− line <- params .: "line"
122+ CaseSplit
132− begin <- params .: "begin"
123+ <$> params .: "line"
133− end <- params .: "end"
124+ <*> params .: "begin"
134− annotations <- params .: "annotations"
125+ <*> params .: "end"
135− type' <- params .: "type"
126+ <*> (mkAnnotations <$> params .: "annotations")
136− return $ CaseSplit line begin end (if annotations
127+ <*> params .: "type"
137− then explicitAnnotations
138− else noAnnotations) type'
139 "addClause" -> do
128 "addClause" -> do
140 params <- o .: "params"
129 params <- o .: "params"
141− line <- params .: "line"
142− annotations <- params .: "annotations"
143− return $ AddClause line (if annotations
130+ AddClause
144− then explicitAnnotations
131+ <$> params .: "line"
145− else noAnnotations)
132+ <*> (mkAnnotations <$> params .: "annotations")
146 "import" -> do
133 "import" -> do
147 params <- o .: "params"
134 params <- o .: "params"
135+ Import
148− fp <- params .: "file"
136+ <$> params .: "file"
149− out <- params .:? "outfile"
137+ <*> params .:? "outfile"
150− filters <- params .:? "filters"
138+ <*> params .:? "filters" .!= []
151− importCommand <- params .: "importCommand"
152− pure $ Import fp out (fromMaybe [] filters) importCommand
139+ <*> params .: "importCommand"
153 "rebuild" -> do
140 "rebuild" -> do
154 params <- o .: "params"
141 params <- o .: "params"
142+ Rebuild
155− filePath <- params .: "file"
143+ <$> params .: "file"
156− return $ Rebuild filePath
157 _ -> mzero
144 _ -> mzero
145+ where
146+ mkAnnotations True = explicitAnnotations
147+ mkAnnotations False = noAnnotations
src/Language/PureScript/Ide/Completion.hs+17−17
@@ -1,32 +1,32 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2module Language.PureScript.Ide.Completion
2module Language.PureScript.Ide.Completion
3+ ( getCompletions
3− (getCompletions, getExactMatches)
4+ , getExactMatches
4− where
5+ ) where
5
6
6−import Prelude ()
7+import Protolude
7−import Prelude.Compat
8
8
9−import Data.Maybe (mapMaybe)
10import Language.PureScript.Ide.Filter
9import Language.PureScript.Ide.Filter
11import Language.PureScript.Ide.Matcher
10import Language.PureScript.Ide.Matcher
12import Language.PureScript.Ide.Types
11import Language.PureScript.Ide.Types
12+import Language.PureScript.Ide.Util
13
13
14-- | Applies the CompletionFilters and the Matcher to the given Modules
14-- | Applies the CompletionFilters and the Matcher to the given Modules
15-- and sorts the found Completions according to the Matching Score
15-- and sorts the found Completions according to the Matching Score
16−getCompletions :: [Filter] -> Matcher -> [Module] -> [Match]
16+getCompletions
17+ :: [Filter]
18+ -> Matcher IdeDeclaration
19+ -> [Module]
20+ -> [Match IdeDeclaration]
17getCompletions filters matcher modules =
21getCompletions filters matcher modules =
18− runMatcher matcher $ completionsFromModules (applyFilters filters modules)
22+ runMatcher matcher (completionsFromModules discardAnn (applyFilters filters modules))
19
23
20−getExactMatches :: DeclIdent -> [Filter] -> [Module] -> [Match]
24+getExactMatches :: Text -> [Filter] -> [Module] -> [Match IdeDeclarationAnn]
21getExactMatches search filters modules =
25getExactMatches search filters modules =
22− completionsFromModules $
23− applyFilters (equalityFilter search : filters) modules
26+ completionsFromModules identity (applyFilters (equalityFilter search : filters) modules)
24
27
25−completionsFromModules :: [Module] -> [Match]
28+completionsFromModules :: (IdeDeclarationAnn -> a) -> [Module] -> [Match a]
26−completionsFromModules = foldMap completionFromModule
29+completionsFromModules f = foldMap completionFromModule
27 where
30 where
28− completionFromModule :: Module -> [Match]
31+ completionFromModule (moduleName, decls) =
29− completionFromModule (moduleIdent, decls) = mapMaybe (matchFromDecl moduleIdent) decls
32+ map (\x -> Match (moduleName, f x)) decls
30−
31−matchFromDecl :: ModuleIdent -> ExternDecl -> Maybe Match
32−matchFromDecl mi = Just . Match mi
src/Language/PureScript/Ide/Conversions.hsnew file+35
@@ -0,0 +1,35 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.Ide.Conversions
4+-- Description : Conversions to Text for PureScript types
5+-- Copyright : Christoph Hegemann 2016
6+-- License : MIT (http://opensource.org/licenses/MIT)
7+--
8+-- Maintainer : Christoph Hegemann <christoph.hegemann1337@gmail.com>
9+-- Stability : experimental
10+--
11+-- |
12+-- Conversions to Text for PureScript types
13+-----------------------------------------------------------------------------
14+
15+module Language.PureScript.Ide.Conversions where
16+
17+import Protolude
18+import Data.Text (unwords, lines, strip)
19+import qualified Language.PureScript as P
20+
21+runProperNameT :: P.ProperName a -> Text
22+runProperNameT = toS . P.runProperName
23+
24+runIdentT :: P.Ident -> Text
25+runIdentT = toS . P.runIdent
26+
27+runOpNameT :: P.OpName a -> Text
28+runOpNameT = toS . P.runOpName
29+
30+runModuleNameT :: P.ModuleName -> Text
31+runModuleNameT = toS . P.runModuleName
32+
33+prettyTypeT :: P.Type -> Text
34+prettyTypeT = unwords . map strip . lines . toS . P.prettyPrintType
35+
src/Language/PureScript/Ide/Error.hs+8−11
@@ -14,24 +14,21 @@
14
14
15{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
16module Language.PureScript.Ide.Error
16module Language.PureScript.Ide.Error
17− (ErrorMsg, PscIdeError(..), textError)
17+ ( PscIdeError(..)
18− where
18+ ) where
19
19
20+import Protolude
20import Data.Aeson
21import Data.Aeson
21−import Data.Monoid
22−import Data.Text (Text, pack)
23import Language.PureScript.Errors.JSON
22import Language.PureScript.Errors.JSON
24import Language.PureScript.Ide.Types (ModuleIdent)
23import Language.PureScript.Ide.Types (ModuleIdent)
25import qualified Text.Parsec.Error as P
24import qualified Text.Parsec.Error as P
26
25
27−type ErrorMsg = String
28−
29data PscIdeError
26data PscIdeError
30− = GeneralError ErrorMsg
27+ = GeneralError Text
31 | NotFound Text
28 | NotFound Text
32 | ModuleNotFound ModuleIdent
29 | ModuleNotFound ModuleIdent
33 | ModuleFileNotFound ModuleIdent
30 | ModuleFileNotFound ModuleIdent
34− | ParseError P.ParseError ErrorMsg
31+ | ParseError P.ParseError Text
35 | RebuildError [JSONError]
32 | RebuildError [JSONError]
36
33
37instance ToJSON PscIdeError where
34instance ToJSON PscIdeError where
@@ -45,7 +42,7 @@ instance ToJSON PscIdeError where
45 ]
42 ]
46
43
47textError :: PscIdeError -> Text
44textError :: PscIdeError -> Text
48−textError (GeneralError msg) = pack msg
45+textError (GeneralError msg) = msg
49textError (NotFound ident) = "Symbol '" <> ident <> "' not found."
46textError (NotFound ident) = "Symbol '" <> ident <> "' not found."
50textError (ModuleNotFound ident) = "Module '" <> ident <> "' not found."
47textError (ModuleNotFound ident) = "Module '" <> ident <> "' not found."
51textError (ModuleFileNotFound ident) = "Extern file for module " <> ident <>" could not be found"
48textError (ModuleFileNotFound ident) = "Extern file for module " <> ident <>" could not be found"
@@ -53,5 +50,5 @@ textError (ParseError parseError msg) = let escape = show
53 -- escape newlines and other special
50 -- escape newlines and other special
54 -- chars so we can send the error
51 -- chars so we can send the error
55 -- over the socket as a single line
52 -- over the socket as a single line
56− in pack $ msg <> ": " <> show (escape parseError)
53+ in msg <> ": " <> escape parseError
57−textError (RebuildError err) = pack (show err)
54+textError (RebuildError err) = show err
src/Language/PureScript/Ide/Externs.hs+81−72
@@ -12,104 +12,113 @@
12-- Handles externs files for psc-ide
12-- Handles externs files for psc-ide
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE FlexibleContexts #-}
16−{-# LANGUAGE MultiParamTypeClasses #-}
17−{-# LANGUAGE OverloadedStrings #-}
15+{-# LANGUAGE OverloadedStrings #-}
18−{-# LANGUAGE RecordWildCards #-}
16+{-# LANGUAGE RecordWildCards #-}
19−{-# LANGUAGE ScopedTypeVariables #-}
17+{-# LANGUAGE FlexibleContexts #-}
20
18
21module Language.PureScript.Ide.Externs
19module Language.PureScript.Ide.Externs
22− ( ExternDecl(..),
23− ModuleIdent,
24− DeclIdent,
25− readExternFile,
20+ ( readExternFile,
26 convertExterns,
21 convertExterns,
27− unwrapPositioned,
22+ annotateLocations
28− unwrapPositionedRef
29 ) where
23 ) where
30
24
31−import Prelude ()
25+import Protolude
32−import Prelude.Compat
33
26
34−import Control.Monad.Error.Class
35−import Control.Monad.IO.Class
36import Data.Aeson (decodeStrict)
27import Data.Aeson (decodeStrict)
37import Data.List (nub)
28import Data.List (nub)
38−import Data.Maybe (mapMaybe)
39−import Data.Monoid
40−import Data.Text (Text)
41−import qualified Data.Text as T
29+import qualified Data.Map as Map
42import qualified Data.ByteString as BS
30import qualified Data.ByteString as BS
43import Language.PureScript.Ide.Error (PscIdeError (..))
31import Language.PureScript.Ide.Error (PscIdeError (..))
44import Language.PureScript.Ide.Types
32import Language.PureScript.Ide.Types
45import Language.PureScript.Ide.Util
33import Language.PureScript.Ide.Util
46
34
47import qualified Language.PureScript as P
35import qualified Language.PureScript as P
48−import qualified Language.PureScript.Externs as PE
49
36
50readExternFile :: (MonadIO m, MonadError PscIdeError m) =>
37readExternFile :: (MonadIO m, MonadError PscIdeError m) =>
51− FilePath -> m PE.ExternsFile
38+ FilePath -> m P.ExternsFile
52readExternFile fp = do
39readExternFile fp = do
53 parseResult <- liftIO (decodeStrict <$> BS.readFile fp)
40 parseResult <- liftIO (decodeStrict <$> BS.readFile fp)
54 case parseResult of
41 case parseResult of
55− Nothing -> throwError . GeneralError $ "Parsing the extern at: " ++ fp ++ " failed"
42+ Nothing -> throwError . GeneralError $ "Parsing the extern at: " <> toS fp <> " failed"
56 Just externs -> pure externs
43 Just externs -> pure externs
57
44
58−moduleNameToText :: P.ModuleName -> Text
45+convertExterns :: P.ExternsFile -> (Module, [(P.ModuleName, P.DeclarationRef)])
59−moduleNameToText = T.pack . P.runModuleName
60−
61−identToText :: P.Ident -> Text
62−identToText = T.pack . P.runIdent
63−
64−convertExterns :: PE.ExternsFile -> Module
65−convertExterns ef = (moduleName, exportDecls ++ importDecls ++ decls)
46+convertExterns ef =
47+ ((P.efModuleName ef, decls), exportDecls)
66 where
48 where
67− moduleName = moduleNameToText (PE.efModuleName ef)
49+ decls = map
68− importDecls = convertImport <$> PE.efImports ef
50+ (IdeDeclarationAnn emptyAnn)
51+ (cleanDeclarations ++ operatorDecls ++ tyOperatorDecls)
69− exportDecls = mapMaybe (convertExport . unwrapPositionedRef) (PE.efExports ef)
52+ exportDecls = mapMaybe (convertExport . unwrapPositionedRef) (P.efExports ef)
70− -- Ignoring operator fixities for now since we're not using them
71− -- operatorDecls = convertOperator <$> PE.efFixities ef
53+ operatorDecls = convertOperator <$> P.efFixities ef
54+ tyOperatorDecls = convertTypeOperator <$> P.efTypeFixities ef
72− otherDecls = mapMaybe convertDecl (PE.efDeclarations ef)
55+ declarations = mapMaybe convertDecl (P.efDeclarations ef)
73−
56+
74− typeClassFilter = foldMap removeTypeDeclarationsForClass (filter isTypeClassDeclaration otherDecls)
57+ typeClassFilter = foldMap removeTypeDeclarationsForClass (filter isTypeClassDeclaration declarations)
75− decls = nub $ appEndo typeClassFilter otherDecls
58+ cleanDeclarations = nub $ appEndo typeClassFilter declarations
76−
59+
77−removeTypeDeclarationsForClass :: ExternDecl -> Endo [ExternDecl]
60+removeTypeDeclarationsForClass :: IdeDeclaration -> Endo [IdeDeclaration]
78−removeTypeDeclarationsForClass (TypeClassDeclaration n) = Endo (filter notDuplicate)
61+removeTypeDeclarationsForClass (IdeTypeClass n) = Endo (filter notDuplicate)
79− where notDuplicate (TypeDeclaration n' _) = runProperNameT n /= runProperNameT n'
62+ where notDuplicate (IdeType n' _) = runProperNameT n /= runProperNameT n'
80− notDuplicate (TypeSynonymDeclaration n' _) = runProperNameT n /= runProperNameT n'
63+ notDuplicate (IdeTypeSynonym n' _) = runProperNameT n /= runProperNameT n'
81 notDuplicate _ = True
64 notDuplicate _ = True
82removeTypeDeclarationsForClass _ = mempty
65removeTypeDeclarationsForClass _ = mempty
83
66
84−isTypeClassDeclaration :: ExternDecl -> Bool
67+isTypeClassDeclaration :: IdeDeclaration -> Bool
85−isTypeClassDeclaration TypeClassDeclaration{} = True
68+isTypeClassDeclaration IdeTypeClass{} = True
86isTypeClassDeclaration _ = False
69isTypeClassDeclaration _ = False
87
70
88−convertImport :: PE.ExternsImport -> ExternDecl
89−convertImport ei = Dependency
90− (moduleNameToText (PE.eiModule ei))
91− []
92− (moduleNameToText <$> PE.eiImportedAs ei)
93−
94−convertExport :: P.DeclarationRef -> Maybe ExternDecl
71+convertExport :: P.DeclarationRef -> Maybe (P.ModuleName, P.DeclarationRef)
95−convertExport (P.ModuleRef mn) = Just (Export (moduleNameToText mn))
72+convertExport (P.ReExportRef m r) = Just (m, r)
96convertExport _ = Nothing
73convertExport _ = Nothing
97
74
98−convertDecl :: PE.ExternsDeclaration -> Maybe ExternDecl
75+convertDecl :: P.ExternsDeclaration -> Maybe IdeDeclaration
99−convertDecl PE.EDType{..} = Just $ TypeDeclaration edTypeName edTypeKind
76+convertDecl P.EDType{..} = Just (IdeType edTypeName edTypeKind)
100−convertDecl PE.EDTypeSynonym{..} = Just $
77+convertDecl P.EDTypeSynonym{..} =
101− TypeSynonymDeclaration edTypeSynonymName edTypeSynonymType
78+ Just (IdeTypeSynonym edTypeSynonymName edTypeSynonymType)
102−convertDecl PE.EDDataConstructor{..} = Just $
79+convertDecl P.EDDataConstructor{..} = Just $
103− DataConstructor (runProperNameT edDataCtorName) edDataCtorTypeCtor edDataCtorType
80+ IdeDataConstructor edDataCtorName edDataCtorTypeCtor edDataCtorType
104−convertDecl PE.EDValue{..} = Just $
81+convertDecl P.EDValue{..} = Just $
105− ValueDeclaration (identToText edValueName) edValueType
82+ IdeValue edValueName edValueType
106−convertDecl PE.EDClass{..} = Just $ TypeClassDeclaration edClassName
83+convertDecl P.EDClass{..} = Just (IdeTypeClass edClassName)
107−convertDecl PE.EDInstance{} = Nothing
84+convertDecl P.EDInstance{} = Nothing
108−
85+
109−unwrapPositioned :: P.Declaration -> P.Declaration
86+convertOperator :: P.ExternsFixity -> IdeDeclaration
110−unwrapPositioned (P.PositionedDeclaration _ _ x) = x
87+convertOperator P.ExternsFixity{..} =
111−unwrapPositioned x = x
88+ IdeValueOperator
112−
89+ efOperator
113−unwrapPositionedRef :: P.DeclarationRef -> P.DeclarationRef
90+ (toS (P.showQualified (either P.runIdent P.runProperName) efAlias))
114−unwrapPositionedRef (P.PositionedDeclarationRef _ _ x) = x
91+ efPrecedence
115−unwrapPositionedRef x = x
92+ efAssociativity
93+
94+convertTypeOperator :: P.ExternsTypeFixity -> IdeDeclaration
95+convertTypeOperator P.ExternsTypeFixity{..} =
96+ IdeTypeOperator
97+ efTypeOperator
98+ (toS (P.showQualified P.runProperName efTypeAlias))
99+ efTypePrecedence
100+ efTypeAssociativity
101+
102+annotateLocations :: Map (Either Text Text) P.SourceSpan -> Module -> Module
103+annotateLocations ast (moduleName, decls) =
104+ (moduleName, map convertDeclaration decls)
105+ where
106+ convertDeclaration :: IdeDeclarationAnn -> IdeDeclarationAnn
107+ convertDeclaration (IdeDeclarationAnn ann d) = case d of
108+ IdeValue i t ->
109+ annotateValue (runIdentT i) (IdeValue i t)
110+ IdeType i k ->
111+ annotateType (runProperNameT i) (IdeType i k)
112+ IdeTypeSynonym i t ->
113+ annotateType (runProperNameT i) (IdeTypeSynonym i t)
114+ IdeDataConstructor i tn t ->
115+ annotateValue (runProperNameT i) (IdeDataConstructor i tn t)
116+ IdeTypeClass i ->
117+ annotateType (runProperNameT i) (IdeTypeClass i)
118+ IdeValueOperator n i p a ->
119+ annotateValue i (IdeValueOperator n i p a)
120+ IdeTypeOperator n i p a ->
121+ annotateType i (IdeTypeOperator n i p a)
122+ where
123+ annotateValue x = IdeDeclarationAnn (ann {annLocation = Map.lookup (Left x) ast})
124+ annotateType x = IdeDeclarationAnn (ann {annLocation = Map.lookup (Right x) ast})
src/Language/PureScript/Ide/Filter.hs+17−51
@@ -14,29 +14,22 @@
14
14
15{-# LANGUAGE GeneralizedNewtypeDeriving #-}
15{-# LANGUAGE GeneralizedNewtypeDeriving #-}
16{-# LANGUAGE OverloadedStrings #-}
16{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
18
17
19module Language.PureScript.Ide.Filter
18module Language.PureScript.Ide.Filter
20 ( Filter
19 ( Filter
21 , moduleFilter
20 , moduleFilter
22 , prefixFilter
21 , prefixFilter
23 , equalityFilter
22 , equalityFilter
24− , dependencyFilter
25− , runFilter
26 , applyFilters
23 , applyFilters
27 ) where
24 ) where
28
25
29−import Prelude ()
26+import Protolude hiding (isPrefixOf)
30−import Prelude.Compat
31
27
32−import Control.Monad
33import Data.Aeson
28import Data.Aeson
34−import Data.Foldable
35−import Data.Maybe (listToMaybe, mapMaybe)
36−import Data.Monoid
37−import Data.Text (Text, isPrefixOf)
29+import Data.Text (isPrefixOf)
38import Language.PureScript.Ide.Types
30import Language.PureScript.Ide.Types
39import Language.PureScript.Ide.Util
31import Language.PureScript.Ide.Util
32+import qualified Language.PureScript as P
40
33
41newtype Filter = Filter (Endo [Module]) deriving(Monoid)
34newtype Filter = Filter (Endo [Module]) deriving(Monoid)
42
35
@@ -44,69 +37,46 @@ mkFilter :: ([Module] -> [Module]) -> Filter
44mkFilter = Filter . Endo
37mkFilter = Filter . Endo
45
38
46-- | Only keeps the given Modules
39-- | Only keeps the given Modules
47−moduleFilter :: [ModuleIdent] -> Filter
40+moduleFilter :: [P.ModuleName] -> Filter
48moduleFilter =
41moduleFilter =
49 mkFilter . moduleFilter'
42 mkFilter . moduleFilter'
50
43
51−moduleFilter' :: [ModuleIdent] -> [Module] -> [Module]
44+moduleFilter' :: [P.ModuleName] -> [Module] -> [Module]
52moduleFilter' moduleIdents = filter (flip elem moduleIdents . fst)
45moduleFilter' moduleIdents = filter (flip elem moduleIdents . fst)
53
46
54−-- | Only keeps the given Modules and all of their dependencies
55−dependencyFilter :: [ModuleIdent] -> Filter
56−dependencyFilter = mkFilter . dependencyFilter'
57−
58−dependencyFilter' :: [ModuleIdent] -> [Module] -> [Module]
59−dependencyFilter' moduleIdents mods =
60− moduleFilter' (concatMap (getDepForModule mods) moduleIdents) mods
61− where
62− getDepForModule :: [Module] -> ModuleIdent -> [ModuleIdent]
63− getDepForModule ms moduleIdent =
64− moduleIdent : maybe [] extractDeps (findModule moduleIdent ms)
65−
66− findModule :: ModuleIdent -> [Module] -> Maybe Module
67− findModule i ms = listToMaybe $ filter go ms
68− where go (mn, _) = i == mn
69−
70− extractDeps :: Module -> [ModuleIdent]
71− extractDeps = mapMaybe extractDep . snd
72− where extractDep (Dependency n _ _) = Just n
73− extractDep _ = Nothing
74−
75-- | Only keeps Identifiers that start with the given prefix
47-- | Only keeps Identifiers that start with the given prefix
76prefixFilter :: Text -> Filter
48prefixFilter :: Text -> Filter
77−prefixFilter "" = mkFilter id
49+prefixFilter "" = mkFilter identity
78prefixFilter t = mkFilter $ identFilter prefix t
50prefixFilter t = mkFilter $ identFilter prefix t
79 where
51 where
80− prefix :: ExternDecl -> Text -> Bool
52+ prefix :: IdeDeclaration -> Text -> Bool
81− prefix Export{} _ = False
82− prefix Dependency{} _ = False
83− prefix ed search = search `isPrefixOf` identifierFromExternDecl ed
53+ prefix ed search = search `isPrefixOf` identifierFromIdeDeclaration ed
84−
85
54
86-- | Only keeps Identifiers that are equal to the search string
55-- | Only keeps Identifiers that are equal to the search string
87equalityFilter :: Text -> Filter
56equalityFilter :: Text -> Filter
88equalityFilter = mkFilter . identFilter equality
57equalityFilter = mkFilter . identFilter equality
89 where
58 where
90− equality :: ExternDecl -> Text -> Bool
59+ equality :: IdeDeclaration -> Text -> Bool
91− equality ed search = identifierFromExternDecl ed == search
60+ equality ed search = identifierFromIdeDeclaration ed == search
92
61
93−identFilter :: (ExternDecl -> Text -> Bool ) -> Text -> [Module] -> [Module]
62+identFilter :: (IdeDeclaration -> Text -> Bool) -> Text -> [Module] -> [Module]
94identFilter predicate search =
63identFilter predicate search =
95 filter (not . null . snd) . fmap filterModuleDecls
64 filter (not . null . snd) . fmap filterModuleDecls
96 where
65 where
97 filterModuleDecls :: Module -> Module
66 filterModuleDecls :: Module -> Module
98− filterModuleDecls (moduleIdent,decls) =
67+ filterModuleDecls (moduleIdent, decls) =
99− (moduleIdent, filter (`predicate` search) decls)
68+ (moduleIdent, filter (flip predicate search . getDeclaration) decls)
69+ getDeclaration (IdeDeclarationAnn _ d) = d
100
70
101runFilter :: Filter -> [Module] -> [Module]
71runFilter :: Filter -> [Module] -> [Module]
102−runFilter (Filter f)= appEndo f
72+runFilter (Filter f) = appEndo f
103
73
104applyFilters :: [Filter] -> [Module] -> [Module]
74applyFilters :: [Filter] -> [Module] -> [Module]
105applyFilters = runFilter . fold
75applyFilters = runFilter . fold
106
76
107instance FromJSON Filter where
77instance FromJSON Filter where
108 parseJSON = withObject "filter" $ \o -> do
78 parseJSON = withObject "filter" $ \o -> do
109− (filter' :: String) <- o .: "filter"
79+ (filter' :: Text) <- o .: "filter"
110 case filter' of
80 case filter' of
111 "exact" -> do
81 "exact" -> do
112 params <- o .: "params"
82 params <- o .: "params"
@@ -118,10 +88,6 @@ instance FromJSON Filter where
118 return $ prefixFilter search
88 return $ prefixFilter search
119 "modules" -> do
89 "modules" -> do
120 params <- o .: "params"
90 params <- o .: "params"
121− modules <- params .: "modules"
91+ modules <- map P.moduleNameFromString <$> params .: "modules"
122 return $ moduleFilter modules
92 return $ moduleFilter modules
123− "dependencies" -> do
124− params <- o .: "params"
125− deps <- params .: "modules"
126− return $ dependencyFilter deps
127 _ -> mzero
93 _ -> mzero
src/Language/PureScript/Ide/Imports.hs+44−67
@@ -12,12 +12,7 @@
12-- Provides functionality to manage imports
12-- Provides functionality to manage imports
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE LambdaCase #-}
18−{-# LANGUAGE MultiParamTypeClasses #-}
19{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
20−{-# LANGUAGE PackageImports #-}
21
16
22module Language.PureScript.Ide.Imports
17module Language.PureScript.Ide.Imports
23 ( addImplicitImport
18 ( addImplicitImport
@@ -34,23 +29,13 @@ module Language.PureScript.Ide.Imports
34 )
29 )
35 where
30 where
36
31
37−import Control.Applicative ((<|>))
32+import Protolude
38−import Control.Monad.Error.Class
39−import Control.Monad.IO.Class
40−import "monad-logger" Control.Monad.Logger
41−import Data.Bifunctor (first, second)
42−import Data.Function (on)
43−import qualified Data.List as List
44−import Data.Maybe (isNothing)
45−import Data.Monoid ((<>))
46−import Data.Text (Text)
47import qualified Data.Text as T
33import qualified Data.Text as T
34+import Data.List (nubBy, findIndex)
48import qualified Data.Text.IO as TIO
35import qualified Data.Text.IO as TIO
49import qualified Language.PureScript as P
36import qualified Language.PureScript as P
50import Language.PureScript.Ide.Completion
37import Language.PureScript.Ide.Completion
51import Language.PureScript.Ide.Error
38import Language.PureScript.Ide.Error
52−import Language.PureScript.Ide.Externs (unwrapPositioned,
53− unwrapPositionedRef)
54import Language.PureScript.Ide.Filter
39import Language.PureScript.Ide.Filter
55import Language.PureScript.Ide.State
40import Language.PureScript.Ide.State
56import Language.PureScript.Ide.Types
41import Language.PureScript.Ide.Types
@@ -90,23 +75,23 @@ parseImportsFromFile fp = do
90 Right res -> pure res
75 Right res -> pure res
91 Left err -> throwError (GeneralError err)
76 Left err -> throwError (GeneralError err)
92
77
93−parseImportsWithModuleName :: [Text] -> Either String (P.ModuleName, [Import])
78+parseImportsWithModuleName :: [Text] -> Either Text (P.ModuleName, [Import])
94parseImportsWithModuleName ls = do
79parseImportsWithModuleName ls = do
95 (P.Module _ _ mn decls _) <- moduleParse ls
80 (P.Module _ _ mn decls _) <- moduleParse ls
96 pure (mn, concatMap mkImport (unwrapPositioned <$> decls))
81 pure (mn, concatMap mkImport (unwrapPositioned <$> decls))
97 where
82 where
98− mkImport (P.ImportDeclaration mn (P.Explicit refs) qual _) =
83+ mkImport (P.ImportDeclaration mn (P.Explicit refs) qual) =
99 [Import mn (P.Explicit (unwrapPositionedRef <$> refs)) qual]
84 [Import mn (P.Explicit (unwrapPositionedRef <$> refs)) qual]
100− mkImport (P.ImportDeclaration mn it qual _) = [Import mn it qual]
85+ mkImport (P.ImportDeclaration mn it qual) = [Import mn it qual]
101 mkImport _ = []
86 mkImport _ = []
102
87
103−sliceImportSection :: [Text] -> Either String (P.ModuleName, [Text], [Import], [Text])
88+sliceImportSection :: [Text] -> Either Text (P.ModuleName, [Text], [Import], [Text])
104sliceImportSection ts =
89sliceImportSection ts =
105 case foldl step (ModuleHeader 0) (zip [0..] ts) of
90 case foldl step (ModuleHeader 0) (zip [0..] ts) of
106 Res start end ->
91 Res start end ->
107 let
92 let
108 (moduleHeader, (importSection, remainingFile)) =
93 (moduleHeader, (importSection, remainingFile)) =
109− List.splitAt (succ (end - start)) `second` List.splitAt start ts
94+ splitAt (succ (end - start)) `second` splitAt start ts
110 in
95 in
111 (\(mn, is) -> (mn, moduleHeader, is, remainingFile)) <$>
96 (\(mn, is) -> (mn, moduleHeader, is, remainingFile)) <$>
112 parseImportsWithModuleName (moduleHeader <> importSection)
97 parseImportsWithModuleName (moduleHeader <> importSection)
@@ -114,7 +99,7 @@ sliceImportSection ts =
114 -- If we don't find any imports, we insert a newline after the module
99 -- If we don't find any imports, we insert a newline after the module
115 -- declaration and begin a new importsection
100 -- declaration and begin a new importsection
116 ModuleHeader ix ->
101 ModuleHeader ix ->
117− let (moduleHeader, remainingFile) = List.splitAt (succ ix) ts
102+ let (moduleHeader, remainingFile) = splitAt (succ ix) ts
118 in
103 in
119 (\(mn, is) -> (mn, moduleHeader ++ [""], is, remainingFile)) <$>
104 (\(mn, is) -> (mn, moduleHeader ++ [""], is, remainingFile)) <$>
120 parseImportsWithModuleName moduleHeader
105 parseImportsWithModuleName moduleHeader
@@ -156,7 +141,7 @@ step (ImportSection start lastImportLine) (ix, l)
156 | otherwise = Res start lastImportLine
141 | otherwise = Res start lastImportLine
157step (Res start end) _ = Res start end
142step (Res start end) _ = Res start end
158
143
159−moduleParse :: [Text] -> Either String P.Module
144+moduleParse :: [Text] -> Either Text P.Module
160moduleParse t = first show $ do
145moduleParse t = first show $ do
161 tokens <- (P.lex "" . T.unpack . T.unlines) t
146 tokens <- (P.lex "" . T.unpack . T.unlines) t
162 P.runTokenParser "<psc-ide>" P.parseModule tokens
147 P.runTokenParser "<psc-ide>" P.parseModule tokens
@@ -185,8 +170,8 @@ addImplicitImport' imports mn =
185-- So @addExplicitImport "/File.purs" "bind" "Prelude"@ with an already existing
170-- So @addExplicitImport "/File.purs" "bind" "Prelude"@ with an already existing
186-- @import Prelude (bind)@ in the file File.purs returns @["import Prelude
171-- @import Prelude (bind)@ in the file File.purs returns @["import Prelude
187-- (bind, unit)"]@
172-- (bind, unit)"]@
188−addExplicitImport :: (MonadIO m, MonadError PscIdeError m, MonadLogger m) =>
173+addExplicitImport :: (MonadIO m, MonadError PscIdeError m) =>
189− FilePath -> ExternDecl -> P.ModuleName -> m [Text]
174+ FilePath -> IdeDeclaration -> P.ModuleName -> m [Text]
190addExplicitImport fp decl moduleName = do
175addExplicitImport fp decl moduleName = do
191 (mn, pre, imports, post) <- parseImportsFromFile fp
176 (mn, pre, imports, post) <- parseImportsFromFile fp
192 let newImportSection =
177 let newImportSection =
@@ -197,7 +182,7 @@ addExplicitImport fp decl moduleName = do
197 else addExplicitImport' decl moduleName imports
182 else addExplicitImport' decl moduleName imports
198 pure (pre ++ prettyPrintImportSection newImportSection ++ post)
183 pure (pre ++ prettyPrintImportSection newImportSection ++ post)
199
184
200−addExplicitImport' :: ExternDecl -> P.ModuleName -> [Import] -> [Import]
185+addExplicitImport' :: IdeDeclaration -> P.ModuleName -> [Import] -> [Import]
201addExplicitImport' decl moduleName imports =
186addExplicitImport' decl moduleName imports =
202 let
187 let
203 isImplicitlyImported =
188 isImplicitlyImported =
@@ -212,56 +197,49 @@ addExplicitImport' decl moduleName imports =
212 then imports
197 then imports
213 else updateAtFirstOrPrepend matches (insertDeclIntoImport decl) freshImport imports
198 else updateAtFirstOrPrepend matches (insertDeclIntoImport decl) freshImport imports
214 where
199 where
215− refFromDeclaration (TypeClassDeclaration n) = P.TypeClassRef n
200+ refFromDeclaration (IdeTypeClass n) =
201+ P.TypeClassRef n
216− refFromDeclaration (DataConstructor n tn _) =
202+ refFromDeclaration (IdeDataConstructor n tn _) =
217− P.TypeRef tn (Just [P.ProperName (T.unpack n)])
203+ P.TypeRef tn (Just [n])
218− refFromDeclaration (TypeDeclaration n _) = P.TypeRef n (Just [])
204+ refFromDeclaration (IdeType n _) =
205+ P.TypeRef n (Just [])
206+ refFromDeclaration (IdeValueOperator op _ _ _) =
207+ P.ValueOpRef op
208+ refFromDeclaration (IdeTypeOperator op _ _ _) =
209+ P.TypeOpRef op
219 refFromDeclaration d =
210 refFromDeclaration d =
220− let
211+ P.ValueRef $ P.Ident $ T.unpack (identifierFromIdeDeclaration d)
221− ident = T.unpack (identifierFromExternDecl d)
222− in
223− P.ValueRef ((if all P.isSymbolChar ident then P.Op else P.Ident) ident)
224
212
225 -- | Adds a declaration to an import:
213 -- | Adds a declaration to an import:
226 -- TypeDeclaration "Maybe" + Data.Maybe (maybe) -> Data.Maybe(Maybe, maybe)
214 -- TypeDeclaration "Maybe" + Data.Maybe (maybe) -> Data.Maybe(Maybe, maybe)
227− insertDeclIntoImport :: ExternDecl -> Import -> Import
215+ insertDeclIntoImport :: IdeDeclaration -> Import -> Import
228 insertDeclIntoImport decl' (Import mn (P.Explicit refs) Nothing) =
216 insertDeclIntoImport decl' (Import mn (P.Explicit refs) Nothing) =
229 Import mn (P.Explicit (insertDeclIntoRefs decl' refs)) Nothing
217 Import mn (P.Explicit (insertDeclIntoRefs decl' refs)) Nothing
230 insertDeclIntoImport _ is = is
218 insertDeclIntoImport _ is = is
231
219
232− insertDeclIntoRefs :: ExternDecl -> [P.DeclarationRef] -> [P.DeclarationRef]
220+ insertDeclIntoRefs :: IdeDeclaration -> [P.DeclarationRef] -> [P.DeclarationRef]
233− insertDeclIntoRefs (DataConstructor dtor tn _) refs =
221+ insertDeclIntoRefs (IdeDataConstructor dtor tn _) refs =
234− let
235− dtor' = P.ProperName (T.unpack dtor)
236− -- TODO: Get rid of this once typeclasses can't be imported like types
237− refs' = properRefToTypeRef <$> refs
238− in
239− updateAtFirstOrPrepend (matchType tn) (insertDtor dtor') (P.TypeRef tn (Just [dtor'])) refs'
222+ updateAtFirstOrPrepend (matchType tn) (insertDtor dtor) (P.TypeRef tn (Just [dtor])) refs
240− insertDeclIntoRefs dr refs = List.nubBy ((==) `on` P.prettyPrintRef) (refFromDeclaration dr : refs)
223+ insertDeclIntoRefs dr refs = nubBy ((==) `on` P.prettyPrintRef) (refFromDeclaration dr : refs)
241
224
242 insertDtor dtor (P.TypeRef tn' dtors) =
225 insertDtor dtor (P.TypeRef tn' dtors) =
243 case dtors of
226 case dtors of
244− Just dtors' -> P.TypeRef tn' (Just (List.nub (dtor : dtors')))
227+ Just dtors' -> P.TypeRef tn' (Just (ordNub (dtor : dtors')))
245 -- This means the import was opened. We don't add anything in this case
228 -- This means the import was opened. We don't add anything in this case
246 -- import Data.Maybe (Maybe(..)) -> import Data.Maybe (Maybe(Just))
229 -- import Data.Maybe (Maybe(..)) -> import Data.Maybe (Maybe(Just))
247 Nothing -> P.TypeRef tn' Nothing
230 Nothing -> P.TypeRef tn' Nothing
248 insertDtor _ refs = refs
231 insertDtor _ refs = refs
249
232
250−
251− -- TODO: Get rid of this once typeclasses can't be imported like types
252− properRefToTypeRef (P.ProperRef n) = P.TypeRef (P.ProperName n) (Just [])
253− properRefToTypeRef r = r
254−
255 matchType :: P.ProperName 'P.TypeName -> P.DeclarationRef -> Bool
233 matchType :: P.ProperName 'P.TypeName -> P.DeclarationRef -> Bool
256 matchType tn (P.TypeRef n _) = tn == n
234 matchType tn (P.TypeRef n _) = tn == n
257 matchType _ _ = False
235 matchType _ _ = False
258
236
259updateAtFirstOrPrepend :: (a -> Bool) -> (a -> a) -> a -> [a] -> [a]
237updateAtFirstOrPrepend :: (a -> Bool) -> (a -> a) -> a -> [a] -> [a]
260updateAtFirstOrPrepend p t d l =
238updateAtFirstOrPrepend p t d l =
261− case List.findIndex p l of
239+ case findIndex p l of
262 Nothing -> d : l
240 Nothing -> d : l
263 Just ix ->
241 Just ix ->
264− let (x, a : y) = List.splitAt ix l
242+ let (x, a : y) = splitAt ix l
265 in x ++ [t a] ++ y
243 in x ++ [t a] ++ y
266
244
267-- | Looks up the given identifier in the currently loaded modules.
245-- | Looks up the given identifier in the currently loaded modules.
@@ -272,30 +250,30 @@ updateAtFirstOrPrepend p t d l =
272--
250--
273-- * If more than one possible imports are found, reports the possibilities as a
251-- * If more than one possible imports are found, reports the possibilities as a
274-- list of completions.
252-- list of completions.
275−addImportForIdentifier :: (PscIde m, MonadError PscIdeError m, MonadLogger m)
253+addImportForIdentifier :: (Ide m, MonadError PscIdeError m)
276 => FilePath -- ^ The Sourcefile to read from
254 => FilePath -- ^ The Sourcefile to read from
277 -> Text -- ^ The identifier to import
255 -> Text -- ^ The identifier to import
278 -> [Filter] -- ^ Filters to apply before searching for
256 -> [Filter] -- ^ Filters to apply before searching for
279 -- the identifier
257 -- the identifier
280− -> m (Either [Match] [Text])
258+ -> m (Either [Match IdeDeclaration] [Text])
281addImportForIdentifier fp ident filters = do
259addImportForIdentifier fp ident filters = do
282− modules <- getAllModulesWithReexports
260+ modules <- getAllModules Nothing
283− case getExactMatches ident filters modules of
261+ case map (fmap discardAnn) (getExactMatches ident filters modules) of
284 [] ->
262 [] ->
285 throwError (NotFound "Couldn't find the given identifier. \
263 throwError (NotFound "Couldn't find the given identifier. \
286 \Have you loaded the corresponding module?")
264 \Have you loaded the corresponding module?")
287
265
288 -- Only one match was found for the given identifier, so we can insert it
266 -- Only one match was found for the given identifier, so we can insert it
289 -- right away
267 -- right away
290− [Match m decl] ->
268+ [Match (m, decl)] ->
291− Right <$> addExplicitImport fp decl (P.moduleNameFromString (T.unpack m))
269+ Right <$> addExplicitImport fp decl m
292
270
293 -- This case comes up for newtypes and dataconstructors. Because values and
271 -- This case comes up for newtypes and dataconstructors. Because values and
294 -- types don't share a namespace we can get multiple matches from the same
272 -- types don't share a namespace we can get multiple matches from the same
295 -- module. This also happens for parameterized types, as these generate both
273 -- module. This also happens for parameterized types, as these generate both
296 -- a type aswell as a type synonym.
274 -- a type aswell as a type synonym.
297
275
298− ms@[Match m1 d1, Match m2 d2] ->
276+ ms@[Match (m1, d1), Match (m2, d2)] ->
299 if m1 /= m2
277 if m1 /= m2
300 -- If the modules don't line up we just ask the user to specify the
278 -- If the modules don't line up we just ask the user to specify the
301 -- module
279 -- module
@@ -305,7 +283,7 @@ addImportForIdentifier fp ident filters = do
305 -- dataconstructor as that will give us an unnecessary import warning at
283 -- dataconstructor as that will give us an unnecessary import warning at
306 -- worst
284 -- worst
307 Just decl ->
285 Just decl ->
308− Right <$> addExplicitImport fp decl (P.moduleNameFromString (T.unpack m1))
286+ Right <$> addExplicitImport fp decl m1
309 -- Here we need the user to specify whether he wanted a dataconstructor
287 -- Here we need the user to specify whether he wanted a dataconstructor
310 -- or a type
288 -- or a type
311 Nothing ->
289 Nothing ->
@@ -316,9 +294,9 @@ addImportForIdentifier fp ident filters = do
316 xs ->
294 xs ->
317 pure $ Left xs
295 pure $ Left xs
318 where
296 where
319− decideRedundantCase dtor@(DataConstructor _ t _) (TypeDeclaration t' _) =
297+ decideRedundantCase dtor@(IdeDataConstructor _ t _) (IdeType t' _) =
320 if t == t' then Just dtor else Nothing
298 if t == t' then Just dtor else Nothing
321− decideRedundantCase TypeDeclaration{} ts@TypeSynonymDeclaration{} =
299+ decideRedundantCase IdeType{} ts@IdeTypeSynonym{} =
322 Just ts
300 Just ts
323 decideRedundantCase _ _ = Nothing
301 decideRedundantCase _ _ = Nothing
324
302
@@ -330,7 +308,7 @@ prettyPrintImport' (Import mn idt qual) =
330 T.pack $ "import " ++ P.prettyPrintImport mn idt qual
308 T.pack $ "import " ++ P.prettyPrintImport mn idt qual
331
309
332prettyPrintImportSection :: [Import] -> [Text]
310prettyPrintImportSection :: [Import] -> [Text]
333−prettyPrintImportSection imports = map prettyPrintImport' (List.sort imports)
311+prettyPrintImportSection imports = map prettyPrintImport' (sort imports)
334
312
335-- | Writes a list of lines to @Just filepath@ and responds with a @TextResult@,
313-- | Writes a list of lines to @Just filepath@ and responds with a @TextResult@,
336-- or returns the lines as a @MultilineTextResult@ if @Nothing@ was given as the
314-- or returns the lines as a @MultilineTextResult@ if @Nothing@ was given as the
@@ -348,8 +326,7 @@ parseImport :: Text -> Maybe Import
348parseImport t =
326parseImport t =
349 case P.lex "<psc-ide>" (T.unpack t)
327 case P.lex "<psc-ide>" (T.unpack t)
350 >>= P.runTokenParser "<psc-ide>" P.parseImportDeclaration' of
328 >>= P.runTokenParser "<psc-ide>" P.parseImportDeclaration' of
351− Right (mn, P.Explicit refs, mmn, _) ->
329+ Right (mn, P.Explicit refs, mmn) ->
352 Just (Import mn (P.Explicit (unwrapPositionedRef <$> refs)) mmn)
330 Just (Import mn (P.Explicit (unwrapPositionedRef <$> refs)) mmn)
353− Right (mn, idt, mmn, _) -> Just (Import mn idt mmn)
331+ Right (mn, idt, mmn) -> Just (Import mn idt mmn)
354 Left _ -> Nothing
332 Left _ -> Nothing
355−
src/Language/PureScript/Ide/Matcher.hs+26−33
@@ -14,24 +14,18 @@
14
14
15{-# LANGUAGE GeneralizedNewtypeDeriving #-}
15{-# LANGUAGE GeneralizedNewtypeDeriving #-}
16{-# LANGUAGE OverloadedStrings #-}
16{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
17+{-# LANGUAGE FlexibleInstances #-}
18
18
19module Language.PureScript.Ide.Matcher
19module Language.PureScript.Ide.Matcher
20 ( Matcher
20 ( Matcher
21− , flexMatcher
22 , runMatcher
21 , runMatcher
22+ -- for tests
23+ , flexMatcher
23 ) where
24 ) where
24
25
25−import Prelude ()
26+import Protolude
26−import Prelude.Compat
27
27
28−import Control.Monad
29import Data.Aeson
28import Data.Aeson
30−import Data.Function (on)
31−import Data.List (sortBy)
32−import Data.Maybe (mapMaybe)
33−import Data.Monoid
34−import Data.Text (Text)
35import qualified Data.Text as T
29import qualified Data.Text as T
36import qualified Data.Text.Encoding as TE
30import qualified Data.Text.Encoding as TE
37import Language.PureScript.Ide.Types
31import Language.PureScript.Ide.Types
@@ -40,23 +34,22 @@ import Text.EditDistance
40import Text.Regex.TDFA ((=~))
34import Text.Regex.TDFA ((=~))
41
35
42
36
43−type ScoredMatch = (Match, Double)
37+type ScoredMatch a = (Match a, Double)
44
38
45−newtype Matcher = Matcher (Endo [Match]) deriving(Monoid)
39+newtype Matcher a = Matcher (Endo [Match a]) deriving (Monoid)
46
40
47−instance FromJSON Matcher where
41+instance FromJSON (Matcher IdeDeclaration) where
48 parseJSON = withObject "matcher" $ \o -> do
42 parseJSON = withObject "matcher" $ \o -> do
49− (matcher :: Maybe String) <- o .:? "matcher"
43+ (matcher :: Maybe Text) <- o .:? "matcher"
50 case matcher of
44 case matcher of
51 Just "flex" -> do
45 Just "flex" -> do
52 params <- o .: "params"
46 params <- o .: "params"
53− search <- params .: "search"
47+ flexMatcher <$> params .: "search"
54− pure $ flexMatcher search
55 Just "distance" -> do
48 Just "distance" -> do
56 params <- o .: "params"
49 params <- o .: "params"
50+ distanceMatcher
57− search <- params .: "search"
51+ <$> params .: "search"
58− maxDist <- params .: "maximumDistance"
52+ <*> params .: "maximumDistance"
59− pure $ distanceMatcher search maxDist
60 Just _ -> mzero
53 Just _ -> mzero
61 Nothing -> return mempty
54 Nothing -> return mempty
62
55
@@ -67,37 +60,37 @@ instance FromJSON Matcher where
67-- Examples:
60-- Examples:
68-- flMa matches flexMatcher. Score: 14.28
61-- flMa matches flexMatcher. Score: 14.28
69-- sons matches sortCompletions. Score: 6.25
62-- sons matches sortCompletions. Score: 6.25
70−flexMatcher :: Text -> Matcher
63+flexMatcher :: Text -> Matcher IdeDeclaration
71flexMatcher p = mkMatcher (flexMatch p)
64flexMatcher p = mkMatcher (flexMatch p)
72
65
73−distanceMatcher :: Text -> Int -> Matcher
66+distanceMatcher :: Text -> Int -> Matcher IdeDeclaration
74distanceMatcher q maxDist = mkMatcher (distanceMatcher' q maxDist)
67distanceMatcher q maxDist = mkMatcher (distanceMatcher' q maxDist)
75
68
76−distanceMatcher' :: Text -> Int -> [Match] -> [ScoredMatch]
69+distanceMatcher' :: Text -> Int -> [Match IdeDeclaration] -> [ScoredMatch IdeDeclaration]
77distanceMatcher' q maxDist = mapMaybe go
70distanceMatcher' q maxDist = mapMaybe go
78 where
71 where
79 go m = let d = dist (T.unpack y)
72 go m = let d = dist (T.unpack y)
80− y = identifierFromMatch m
73+ y = identifierFromIdeDeclaration (unwrapMatch m)
81 in if d <= maxDist
74 in if d <= maxDist
82 then Just (m, 1 / fromIntegral d)
75 then Just (m, 1 / fromIntegral d)
83 else Nothing
76 else Nothing
84 dist = levenshteinDistance defaultEditCosts (T.unpack q)
77 dist = levenshteinDistance defaultEditCosts (T.unpack q)
85
78
86−mkMatcher :: ([Match] -> [ScoredMatch]) -> Matcher
79+mkMatcher :: ([Match a] -> [ScoredMatch a]) -> Matcher a
87mkMatcher matcher = Matcher . Endo $ fmap fst . sortCompletions . matcher
80mkMatcher matcher = Matcher . Endo $ fmap fst . sortCompletions . matcher
88
81
89−runMatcher :: Matcher -> [Match] -> [Match]
82+runMatcher :: Matcher a -> [Match a] -> [Match a]
90runMatcher (Matcher m)= appEndo m
83runMatcher (Matcher m)= appEndo m
91
84
92−sortCompletions :: [ScoredMatch] -> [ScoredMatch]
85+sortCompletions :: [ScoredMatch a] -> [ScoredMatch a]
93sortCompletions = sortBy (flip compare `on` snd)
86sortCompletions = sortBy (flip compare `on` snd)
94
87
95−flexMatch :: Text -> [Match] -> [ScoredMatch]
88+flexMatch :: Text -> [Match IdeDeclaration] -> [ScoredMatch IdeDeclaration]
96flexMatch = mapMaybe . flexRate
89flexMatch = mapMaybe . flexRate
97
90
98−flexRate :: Text -> Match -> Maybe ScoredMatch
91+flexRate :: Text -> Match IdeDeclaration -> Maybe (ScoredMatch IdeDeclaration)
99flexRate p c = do
92flexRate p c = do
100− score <- flexScore p (identifierFromMatch c)
93+ score <- flexScore p (identifierFromIdeDeclaration (unwrapMatch c))
101 return (c, score)
94 return (c, score)
102
95
103-- FlexMatching ala Sublime.
96-- FlexMatching ala Sublime.
@@ -106,11 +99,11 @@ flexRate p c = do
106-- By string =~ pattern we'll get the start of the match and the length of
99-- By string =~ pattern we'll get the start of the match and the length of
107-- the matchas a (start, length) tuple if there's a match.
100-- the matchas a (start, length) tuple if there's a match.
108-- If match fails then it would be (-1,0)
101-- If match fails then it would be (-1,0)
109−flexScore :: Text -> DeclIdent -> Maybe Double
102+flexScore :: Text -> Text -> Maybe Double
110flexScore pat str =
103flexScore pat str =
111 case T.uncons pat of
104 case T.uncons pat of
112 Nothing -> Nothing
105 Nothing -> Nothing
113− Just (first, p) ->
106+ Just (first', p) ->
114 case TE.encodeUtf8 str =~ TE.encodeUtf8 pat' :: (Int, Int) of
107 case TE.encodeUtf8 str =~ TE.encodeUtf8 pat' :: (Int, Int) of
115 (-1,0) -> Nothing
108 (-1,0) -> Nothing
116 (start,len) -> Just $ calcScore start (start + len)
109 (start,len) -> Just $ calcScore start (start + len)
@@ -121,11 +114,11 @@ flexScore pat str =
121 -- escape prepends a backslash to "regexy" characters to prevent the
114 -- escape prepends a backslash to "regexy" characters to prevent the
122 -- matcher from crashing when trying to build the regex
115 -- matcher from crashing when trying to build the regex
123 escape :: Char -> Text
116 escape :: Char -> Text
124− escape c = if c `elem` ("[\\^$.|?*+(){}" :: String)
117+ escape c = if c `elem` T.unpack "[\\^$.|?*+(){}"
125 then T.pack ['\\', c]
118 then T.pack ['\\', c]
126 else T.singleton c
119 else T.singleton c
127 -- This just interleaves the search pattern with .*
120 -- This just interleaves the search pattern with .*
128 -- abcd[*] -> a.*b.*c.*d.*[*]
121 -- abcd[*] -> a.*b.*c.*d.*[*]
129− pat' = escape first <> foldMap (<> ".*") escapedPattern
122+ pat' = escape first' <> foldMap (<> ".*") escapedPattern
130 calcScore start end =
123 calcScore start end =
131 100.0 / fromIntegral ((1 + start) * (end - start + 1))
124 100.0 / fromIntegral ((1 + start) * (end - start + 1))
src/Language/PureScript/Ide/Pursuit.hs+10−14
@@ -13,22 +13,18 @@
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
16−{-# LANGUAGE ScopedTypeVariables #-}
17
16
18−module Language.PureScript.Ide.Pursuit where
17+module Language.PureScript.Ide.Pursuit
18+ ( searchPursuitForDeclarations
19+ , findPackagesForModuleIdent
20+ ) where
19
21
20−import Prelude ()
22+import Protolude hiding (fromStrict)
21−import Prelude.Compat
22
23
23import qualified Control.Exception as E
24import qualified Control.Exception as E
24import Data.Aeson
25import Data.Aeson
25−import Data.ByteString (ByteString)
26import Data.ByteString.Lazy (fromStrict)
26import Data.ByteString.Lazy (fromStrict)
27−import Data.Foldable (toList)
28−import Data.Maybe (mapMaybe)
29−import Data.Monoid ((<>))
30import Data.String
27import Data.String
31−import Data.Text (Text)
32import qualified Data.Text as T
28import qualified Data.Text as T
33import Language.PureScript.Ide.Types
29import Language.PureScript.Ide.Types
34import Network.HTTP.Types.Header (hAccept)
30import Network.HTTP.Types.Header (hAccept)
@@ -40,14 +36,14 @@ import qualified Pipes.Prelude as P
40queryPursuit :: Text -> IO ByteString
36queryPursuit :: Text -> IO ByteString
41queryPursuit q = do
37queryPursuit q = do
42 let qClean = T.dropWhileEnd (== '.') q
38 let qClean = T.dropWhileEnd (== '.') q
43− req' <- parseUrl "http://pursuit.purescript.org/search"
39+ req' <- parseRequest "http://pursuit.purescript.org/search"
44 let req = req'
40 let req = req'
45− { queryString=("q=" <> (fromString . T.unpack) qClean)
41+ { queryString= "q=" <> (fromString . T.unpack) qClean
46 , requestHeaders=[(hAccept, "application/json")]
42 , requestHeaders=[(hAccept, "application/json")]
47 }
43 }
48 m <- newManager tlsManagerSettings
44 m <- newManager tlsManagerSettings
49 withHTTP req m $ \resp ->
45 withHTTP req m $ \resp ->
50− P.fold (<>) "" id $ responseBody resp
46+ P.fold (<>) "" identity (responseBody resp)
51
47
52
48
53handler :: HttpException -> IO [a]
49handler :: HttpException -> IO [a]
@@ -60,7 +56,7 @@ searchPursuitForDeclarations query =
60 let results' = decode (fromStrict r) :: Maybe Array
56 let results' = decode (fromStrict r) :: Maybe Array
61 case results' of
57 case results' of
62 Nothing -> pure []
58 Nothing -> pure []
63− Just results -> pure (mapMaybe isDeclarationResponse (map fromJSON (toList results)))) `E.catch`
59+ Just results -> pure (mapMaybe (isDeclarationResponse . fromJSON) (toList results))) `E.catch`
64 handler
60 handler
65 where
61 where
66 isDeclarationResponse (Success a@DeclarationResponse{}) = Just a
62 isDeclarationResponse (Success a@DeclarationResponse{}) = Just a
@@ -72,7 +68,7 @@ findPackagesForModuleIdent query =
72 let results' = decode (fromStrict r) :: Maybe Array
68 let results' = decode (fromStrict r) :: Maybe Array
73 case results' of
69 case results' of
74 Nothing -> pure []
70 Nothing -> pure []
75− Just results -> pure (mapMaybe isModuleResponse (map fromJSON (toList results)))) `E.catch`
71+ Just results -> pure (mapMaybe (isModuleResponse . fromJSON) (toList results))) `E.catch`
76 handler
72 handler
77 where
73 where
78 isModuleResponse (Success a@ModuleResponse{}) = Just a
74 isModuleResponse (Success a@ModuleResponse{}) = Just a
src/Language/PureScript/Ide/Rebuild.hs+124−45
@@ -1,85 +1,164 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
4{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
5{-# LANGUAGE PackageImports #-}
2{-# LANGUAGE PackageImports #-}
6{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE RecordWildCards #-}
4+{-# LANGUAGE TemplateHaskell #-}
7{-# LANGUAGE TupleSections #-}
5{-# LANGUAGE TupleSections #-}
8
6
9−module Language.PureScript.Ide.Rebuild where
7+module Language.PureScript.Ide.Rebuild
8+ ( rebuildFile
9+ ) where
10
10
11−import Language.PureScript.Ide.Error
11+import Protolude
12−import Language.PureScript.Ide.State
13−import Language.PureScript.Ide.Types
14
12
15−import Control.Monad.Error.Class
16−import Control.Monad.IO.Class
17import "monad-logger" Control.Monad.Logger
13import "monad-logger" Control.Monad.Logger
18−import Control.Monad.Reader.Class
14+import qualified Data.List as List
19−import Control.Monad.Trans.Except
20import qualified Data.Map.Lazy as M
15import qualified Data.Map.Lazy as M
21−import Data.Maybe (fromJust, mapMaybe)
16+import Data.Maybe (fromJust)
22import qualified Data.Set as S
17import qualified Data.Set as S
23import qualified Language.PureScript as P
18import qualified Language.PureScript as P
24import Language.PureScript.Errors.JSON
19import Language.PureScript.Errors.JSON
25−import qualified Language.PureScript.Externs as P
20+import Language.PureScript.Ide.Error
26−import System.FilePath (replaceExtension)
21+import Language.PureScript.Ide.State
27−import System.Directory (doesFileExist)
22+import Language.PureScript.Ide.Types
23+import Language.PureScript.Ide.Util
28−import System.IO.UTF8 (readUTF8File)
24+import System.IO.UTF8 (readUTF8File)
29
25
26+-- | Given a filepath performs the following steps:
27+--
28+-- * Reads and parses a PureScript module from the filepath.
29+--
30+-- * Builds a dependency graph for the parsed module from the already loaded
31+-- ExternsFiles.
32+--
33+-- * Attempts to find an FFI definition file for the module by looking
34+-- for a file with the same filepath except for a .js extension.
35+--
36+-- * Passes all the created artifacts to @rebuildModule@.
37+--
38+-- * If the rebuilding succeeds, returns a @RebuildSuccess@ with the generated
39+-- warnings, and if rebuilding fails, returns a @RebuildError@ with the
40+-- generated errors.
30rebuildFile
41rebuildFile
31− :: (PscIde m, MonadLogger m, MonadError PscIdeError m)
42+ :: (Ide m, MonadLogger m, MonadError PscIdeError m)
32 => FilePath
43 => FilePath
33 -> m Success
44 -> m Success
34rebuildFile path = do
45rebuildFile path = do
35
46
36− input <- liftIO $ readUTF8File path
47+ input <- liftIO (readUTF8File path)
37
48
38− m <- case map snd <$> P.parseModulesFromFiles id [(path, input)] of
49+ m <- case snd <$> P.parseModuleFromFile identity (path, input) of
39− Left parseError ->
50+ Left parseError -> throwError
51+ . RebuildError
40− throwError . RebuildError . toJSONErrors False P.Error $ parseError
52+ . toJSONErrors False P.Error
53+ $ P.MultipleErrors [P.toPositionedError parseError]
41− Right [m] -> pure m
54+ Right m -> pure m
42− Right _ -> throwError . GeneralError $ "Please define exactly one module."
43
55
56+ -- Externs files must be sorted ahead of time, so that they get applied
57+ -- correctly to the 'Environment'.
44− externs <- sortExterns m . M.delete (P.getModuleName m) =<< getExternFiles
58+ externs <- sortExterns m =<< getExternFiles
45
59
46− outputDirectory <- confOutputPath . envConfiguration <$> ask
60+ outputDirectory <- confOutputPath . ideConfiguration <$> ask
47
61
48− let foreignModule = replaceExtension path "js"
62+ -- For rebuilding, we want to 'RebuildAlways', but for inferring foreign
49− foreignExists <- liftIO (doesFileExist foreignModule)
63+ -- modules using their file paths, we need to specify the path in the 'Map'.
64+ let filePathMap = M.singleton (P.getModuleName m) (Left P.RebuildAlways)
65+ foreigns <- P.inferForeignModules (M.singleton (P.getModuleName m) (Right path))
50
66
51− let ma = P.buildMakeActions outputDirectory
67+ let makeEnv = MakeActionsEnv outputDirectory filePathMap foreigns False
52− (M.singleton (P.getModuleName m) (Left P.RebuildAlways))
68+ -- Rebuild the single module using the cached externs
53− (if foreignExists
54− then M.singleton (P.getModuleName m) foreignModule
55− else M.empty)
56− False
57 (result, warnings) <- liftIO
69 (result, warnings) <- liftIO
58− . P.runMake P.defaultOptions
70+ . P.runMake P.defaultOptions
59− . P.rebuildModule (ma { P.progress = const (pure ()) }) externs
71+ . P.rebuildModule (buildMakeActions
60− $ P.addDefaultImport (P.ModuleName [P.ProperName "Prim"]) m
72+ >>= shushProgress $ makeEnv) externs $ m
61 case result of
73 case result of
62− Left errors -> throwError . RebuildError $ toJSONErrors False P.Error errors
74+ Left errors -> throwError (RebuildError (toJSONErrors False P.Error errors))
75+ Right _ -> do
76+ rebuildModuleOpen makeEnv externs m
63− Right _ -> pure . RebuildSuccess $ toJSONErrors False P.Warning warnings
77+ pure (RebuildSuccess (toJSONErrors False P.Warning warnings))
64
78
79+-- | Rebuilds a module but opens up its export list first and stores the result
80+-- inside the rebuild cache
81+rebuildModuleOpen
82+ :: (Ide m, MonadLogger m, MonadError PscIdeError m)
83+ => MakeActionsEnv
84+ -> [P.ExternsFile]
85+ -> P.Module
86+ -> m ()
87+rebuildModuleOpen makeEnv externs m = do
88+ (openResult, _) <- liftIO
89+ . P.runMake P.defaultOptions
90+ . P.rebuildModule (buildMakeActions
91+ >>= shushProgress
92+ >>= shushCodegen
93+ $ makeEnv) externs $ openModuleExports m
94+ case openResult of
95+ Left _ ->
96+ throwError (GeneralError "Failed when rebuilding with open exports")
97+ Right result -> do
98+ $(logDebug)
99+ ("Setting Rebuild cache: " <> runModuleNameT (P.efModuleName result))
100+ cacheRebuild result
101+
102+-- | Parameters we can access while building our @MakeActions@
103+data MakeActionsEnv =
104+ MakeActionsEnv
105+ { maeOutputDirectory :: FilePath
106+ , maeFilePathMap :: Map P.ModuleName (Either P.RebuildPolicy FilePath)
107+ , maeForeignPathMap :: Map P.ModuleName FilePath
108+ , maePrefixComment :: Bool
109+ }
110+
111+-- | Builds the default @MakeActions@ from a @MakeActionsEnv@
112+buildMakeActions :: MakeActionsEnv -> P.MakeActions P.Make
113+buildMakeActions MakeActionsEnv{..} =
114+ P.buildMakeActions
115+ maeOutputDirectory
116+ maeFilePathMap
117+ maeForeignPathMap
118+ maePrefixComment
119+
120+-- | Shuts the compiler up about progress messages
121+shushProgress :: P.MakeActions P.Make -> MakeActionsEnv -> P.MakeActions P.Make
122+shushProgress ma _ =
123+ ma { P.progress = \_ -> pure () }
124+
125+-- | Stops any kind of codegen (also silences errors about missing or unused FFI
126+-- files though)
127+shushCodegen :: P.MakeActions P.Make -> MakeActionsEnv -> P.MakeActions P.Make
128+shushCodegen ma MakeActionsEnv{..} =
129+ ma { P.codegen = \_ _ _ -> pure () }
130+
131+-- | Returns a topologically sorted list of dependent ExternsFiles for the given
132+-- module. Throws an error if there is a cyclic dependency within the
133+-- ExternsFiles
65sortExterns
134sortExterns
66− :: (PscIde m, MonadError PscIdeError m)
135+ :: (Ide m, MonadError PscIdeError m)
67 => P.Module
136 => P.Module
68− -> M.Map P.ModuleName P.ExternsFile
137+ -> Map P.ModuleName P.ExternsFile
69 -> m [P.ExternsFile]
138 -> m [P.ExternsFile]
70sortExterns m ex = do
139sortExterns m ex = do
140+ sorted' <- runExceptT
141+ . P.sortModules
142+ . (:) m
71− sorted' <- runExceptT . P.sortModules . (:) m . map mkShallowModule . M.elems $ ex
143+ . map mkShallowModule
144+ . M.elems
145+ . M.delete (P.getModuleName m) $ ex
72 case sorted' of
146 case sorted' of
73− Left _ -> throwError (GeneralError "There was a cycle in the dependencies")
147+ Left err ->
148+ throwError (RebuildError (toJSONErrors False P.Error err))
74 Right (sorted, graph) -> do
149 Right (sorted, graph) -> do
75− let deps = fromJust (lookup (P.getModuleName m) graph)
150+ let deps = fromJust (List.lookup (P.getModuleName m) graph)
76 pure $ mapMaybe getExtern (deps `inOrderOf` map P.getModuleName sorted)
151 pure $ mapMaybe getExtern (deps `inOrderOf` map P.getModuleName sorted)
77 where
152 where
78 mkShallowModule P.ExternsFile{..} =
153 mkShallowModule P.ExternsFile{..} =
79− P.Module undefined [] efModuleName (map mkImport efImports) Nothing
154+ P.Module (P.internalModuleSourceSpan "<rebuild>") [] efModuleName (map mkImport efImports) Nothing
80 mkImport (P.ExternsImport mn it iq) =
155 mkImport (P.ExternsImport mn it iq) =
81− P.ImportDeclaration mn it iq False
156+ P.ImportDeclaration mn it iq
82 getExtern mn = M.lookup mn ex
157 getExtern mn = M.lookup mn ex
83 -- Sort a list so its elements appear in the same order as in another list.
158 -- Sort a list so its elements appear in the same order as in another list.
84 inOrderOf :: (Ord a) => [a] -> [a] -> [a]
159 inOrderOf :: (Ord a) => [a] -> [a] -> [a]
85 inOrderOf xs ys = let s = S.fromList xs in filter (`S.member` s) ys
160 inOrderOf xs ys = let s = S.fromList xs in filter (`S.member` s) ys
161+
162+-- | Removes a modules export list.
163+openModuleExports :: P.Module -> P.Module
164+openModuleExports (P.Module ss cs mn decls _) = P.Module ss cs mn decls Nothing
src/Language/PureScript/Ide/Reexports.hs+93−66
@@ -14,78 +14,105 @@
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16{-# LANGUAGE OverloadedStrings #-}
16{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE PatternGuards #-}
17+{-# LANGUAGE PackageImports #-}
18−{-# LANGUAGE TupleSections #-}
18+{-# LANGUAGE TemplateHaskell #-}
19+{-# LANGUAGE RecordWildCards #-}
19
20
20−module Language.PureScript.Ide.Reexports where
21+module Language.PureScript.Ide.Reexports
22+ ( resolveReexports
23+ , prettyPrintReexportResult
24+ , reexportHasFailures
25+ , ReexportResult(..)
26+ ) where
21
27
28+import Protolude
22
29
23−import Prelude ()
24−import Prelude.Compat
25−
26−import Data.List (union)
27−import Data.Map (Map)
28import qualified Data.Map as Map
30import qualified Data.Map as Map
29−import Data.Maybe
30import Language.PureScript.Ide.Types
31import Language.PureScript.Ide.Types
31−
32+import Language.PureScript.Ide.Util
32−getReexports :: Module -> [ExternDecl]
33+import qualified Language.PureScript as P
33−getReexports (mn, decls)= concatMap getExport decls
34+
34− where getExport d
35+-- | Contains the module with resolved reexports, and eventual failures
35− | (Export mn') <- d
36+data ReexportResult a
36− , mn /= mn' = replaceExportWithAliases decls mn'
37+ = ReexportResult
37− | otherwise = []
38+ { reResolved :: a
38−
39+ , reFailed :: [(P.ModuleName, P.DeclarationRef)]
39−dependencyToExport :: ExternDecl -> ExternDecl
40+ } deriving (Show, Eq, Functor)
40−dependencyToExport (Dependency m _ _) = Export m
41+
41−dependencyToExport decl = decl
42+-- | Uses the passed formatter to format the resolved module, and adds eventual
42−
43+-- failures
43−replaceExportWithAliases :: [ExternDecl] -> ModuleIdent -> [ExternDecl]
44+prettyPrintReexportResult
44−replaceExportWithAliases decls ident =
45+ :: (a -> Text)
45− case filter isMatch decls of
46+ -- ^ Formatter for the resolved result
46− [] -> [Export ident]
47+ -> ReexportResult a
47− aliases -> map dependencyToExport aliases
48+ -- ^ The Result to be pretty printed
48− where isMatch d
49+ -> Text
49− | Dependency _ _ (Just alias) <- d
50+prettyPrintReexportResult f ReexportResult{..}
50− , alias == ident = True
51+ | null reFailed =
52+ "Successfully resolved reexports for " <> f reResolved
51− | otherwise = False
53+ | otherwise =
52−
54+ "Failed to resolve reexports for "
53−replaceReexport :: ExternDecl -> Module -> Module -> Module
55+ <> f reResolved
54−replaceReexport e@(Export _) (m, decls) (_, newDecls) =
56+ <> foldMap (\(mn, ref) -> runModuleNameT mn <> show ref) reFailed
55− (m, filter (/= e) decls `union` newDecls)
57+
56−replaceReexport _ _ _ = error "Should only get Exports here."
58+-- | Whether any Refs couldn't be resolved
57−
59+reexportHasFailures :: ReexportResult a -> Bool
58−emptyModule :: Module
60+reexportHasFailures = not . null . reFailed
59−emptyModule = ("Empty", [])
61+
60−
62+-- | Resolves Reexports for a given Module, by looking up the reexported values
61−isExport :: ExternDecl -> Bool
63+-- from the passed in Map
62−isExport (Export _) = True
64+resolveReexports
63−isExport _ = False
65+ :: Map P.ModuleName [IdeDeclarationAnn]
64−
66+ -- ^ Modules to search for the reexported declarations
65−removeExportDecls :: Module -> Module
67+ -> (Module, [(P.ModuleName, P.DeclarationRef)])
66−removeExportDecls = fmap (filter (not . isExport))
68+ -- ^ The module to resolve reexports for, aswell as the references to resolve
67−
69+ -> ReexportResult Module
68−replaceReexports :: Module -> Map ModuleIdent [ExternDecl] -> Module
70+resolveReexports modules ((moduleName, decls), refs) =
69−replaceReexports m db = result
71+ ReexportResult (moduleName, decls <> concat resolvedRefs) failedRefs
70 where
72 where
71− reexports = getReexports m
73+ (failedRefs, resolvedRefs) = partitionEithers (resolveRef' <$> refs)
72− result = foldl go (removeExportDecls m) reexports
74+ resolveRef' x@(mn, r) = case Map.lookup mn modules of
75+ Nothing -> Left x
76+ Just decls' -> first (mn,) (resolveRef decls' r)
77+
78+resolveRef
79+ :: [IdeDeclarationAnn]
80+ -> P.DeclarationRef
81+ -> Either P.DeclarationRef [IdeDeclarationAnn]
82+resolveRef decls ref = case ref of
83+ P.TypeRef tn mdtors ->
84+ case findRef (\case IdeType name _ -> name == tn; _ -> False) of
85+ Nothing -> Left ref
86+ Just d -> Right $ d : case mdtors of
87+ Nothing ->
88+ -- If the dataconstructor field inside the TypeRef is Nothing, that
89+ -- means that all data constructors are exported, so we need to look
90+ -- those up ourselfes
91+ findDtors tn
92+ Just dtors -> mapMaybe lookupDtor dtors
93+ P.ValueRef i ->
94+ findWrapped (\case IdeValue i' _ -> i' == i; _ -> False)
95+ P.TypeOpRef name ->
96+ findWrapped (\case IdeTypeOperator n _ _ _ -> n == name; _ -> False)
97+ P.ValueOpRef name ->
98+ findWrapped (\case IdeValueOperator n _ _ _ -> n == name; _ -> False)
99+ P.TypeClassRef name ->
100+ findWrapped (\case IdeTypeClass n -> n == name; _ -> False)
101+ _ ->
102+ Left ref
103+ where
104+ findWrapped = wrapSingle . findRef
105+ wrapSingle = maybe (Left ref) (Right . pure)
106+ findRef f = find (f . discardAnn) decls
73
107
74− go :: Module -> ExternDecl -> Module
108+ lookupDtor name =
75− go m' re@(Export name) = replaceReexport re m' (getModule name)
109+ findRef (\case IdeDataConstructor name' _ _ -> name == name'
76− go _ _ = error "partiality! woohoo"
110+ _ -> False)
77
111
78− getModule :: ModuleIdent -> Module
112+ findDtors tn = filter (f . discardAnn) decls
79− getModule name = clean res
80 where
113 where
81− res = fromMaybe emptyModule $ (name , ) <$> Map.lookup name db
114+ f :: IdeDeclaration -> Bool
82− -- we have to do this because keeping self exports in will result in
115+ f decl
83− -- infinite loops
116+ | (IdeDataConstructor _ tn' _) <- decl
84− clean (mn, decls) = (mn,) (filter (/= Export mn) decls)
117+ , tn == tn' = True
85−
118+ | otherwise = False
86−resolveReexports :: Map ModuleIdent [ExternDecl] -> Module -> Module
87−resolveReexports modules m =
88− let replaced = replaceReexports m modules
89− in if null (getReexports replaced)
90− then replaced
91− else resolveReexports modules replaced
src/Language/PureScript/Ide/SourceFile.hs+72−90
@@ -12,111 +12,93 @@
12-- Getting declarations from PureScript sourcefiles
12-- Getting declarations from PureScript sourcefiles
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE FlexibleContexts #-}
16−{-# LANGUAGE MultiParamTypeClasses #-}
17{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
18
16
19−module Language.PureScript.Ide.SourceFile where
17+module Language.PureScript.Ide.SourceFile
18+ ( parseModule
19+ , getImportsForFile
20+ , extractSpans
21+ ) where
20
22
21−import Prelude
23+import Protolude
22
24
23−import Control.Monad.Error.Class
24−import Control.Monad.IO.Class
25−import Control.Monad.Trans.Except
26−import Data.Maybe (mapMaybe)
27−import Data.Monoid
28−import qualified Data.Text as T
29−import qualified Language.PureScript.AST.Declarations as D
25+import qualified Language.PureScript as P
30−import qualified Language.PureScript.AST.SourcePos as SP
31import Language.PureScript.Ide.Error
26import Language.PureScript.Ide.Error
32−import Language.PureScript.Ide.Externs (unwrapPositioned,
27+import Language.PureScript.Ide.Util
33− unwrapPositionedRef)
34import Language.PureScript.Ide.Types
28import Language.PureScript.Ide.Types
35−import qualified Language.PureScript.Names as N
36−import qualified Language.PureScript.Parser as P
37−import System.Directory
38import System.IO.UTF8 (readUTF8File)
29import System.IO.UTF8 (readUTF8File)
39
30
40−parseModuleFromFile :: (MonadIO m, MonadError PscIdeError m) =>
31+parseModule
41− FilePath -> m D.Module
32+ :: (MonadIO m)
42−parseModuleFromFile fp = do
33+ => FilePath
43− exists <- liftIO (doesFileExist fp)
34+ -> m (Either FilePath (FilePath, P.Module) )
44− if exists
35+parseModule path = do
45− then do
46− content <- liftIO (readUTF8File fp)
36+ contents <- liftIO (readUTF8File path)
47− let m = do tokens <- P.lex fp content
37+ case P.parseModuleFromFile identity (path, contents) of
48− P.runTokenParser "" P.parseModule tokens
38+ Left _ -> pure (Left path)
49− either (throwError . (`ParseError` "File could not be parsed.")) pure m
39+ Right m -> pure (Right m)
50− else throwError (NotFound "File does not exist.")
51
40
52−-- data Module = Module SourceSpan [Comment] ModuleName [Declaration] (Maybe [DeclarationRef])
41+getImports :: P.Module -> [(P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)]
53−
54−getDeclarations :: D.Module -> [D.Declaration]
55−getDeclarations (D.Module _ _ _ declarations _) = declarations
56−
57−getImports :: D.Module -> [D.Declaration]
58−getImports (D.Module _ _ _ declarations _) =
42+getImports (P.Module _ _ _ declarations _) =
59 mapMaybe isImport declarations
43 mapMaybe isImport declarations
60 where
44 where
61− isImport (D.PositionedDeclaration _ _ (i@D.ImportDeclaration{})) = Just i
45+ isImport (P.PositionedDeclaration _ _ (P.ImportDeclaration a b c)) = Just (a, b, c)
62 isImport _ = Nothing
46 isImport _ = Nothing
63
47
64getImportsForFile :: (MonadIO m, MonadError PscIdeError m) =>
48getImportsForFile :: (MonadIO m, MonadError PscIdeError m) =>
65 FilePath -> m [ModuleImport]
49 FilePath -> m [ModuleImport]
66getImportsForFile fp = do
50getImportsForFile fp = do
67− module' <- parseModuleFromFile fp
51+ moduleE <- parseModule fp
68− let imports = getImports module'
52+ case moduleE of
53+ Left _ -> throwError (GeneralError "Failed to parse sourcefile.")
54+ Right (_, module') ->
69− pure (mkModuleImport . unwrapPositionedImport <$> imports)
55+ pure (mkModuleImport . unwrapPositionedImport <$> getImports module')
70− where
56+ where
71− mkModuleImport (D.ImportDeclaration mn importType' qualifier _) =
57+ mkModuleImport (mn, importType', qualifier) =
72− ModuleImport
58+ ModuleImport
73− (T.pack (N.runModuleName mn))
59+ (runModuleNameT mn)
74− importType'
60+ importType'
75− (T.pack . N.runModuleName <$> qualifier)
61+ (runModuleNameT <$> qualifier)
76− mkModuleImport _ = error "Shouldn't have gotten anything but Imports here"
77− unwrapPositionedImport (D.ImportDeclaration mn importType' qualifier b) =
62+ unwrapPositionedImport (mn, it, q) = (mn, unwrapImportType it, q)
78− D.ImportDeclaration mn (unwrapImportType importType') qualifier b
79− unwrapPositionedImport x = x
80− unwrapImportType (D.Explicit decls) = D.Explicit (map unwrapPositionedRef decls)
63+ unwrapImportType (P.Explicit decls) = P.Explicit (map unwrapPositionedRef decls)
81− unwrapImportType (D.Hiding decls) = D.Hiding (map unwrapPositionedRef decls)
64+ unwrapImportType (P.Hiding decls) = P.Hiding (map unwrapPositionedRef decls)
82− unwrapImportType D.Implicit = D.Implicit
65+ unwrapImportType P.Implicit = P.Implicit
83−
84−getPositionedImports :: D.Module -> [D.Declaration]
85−getPositionedImports (D.Module _ _ _ declarations _) =
86− mapMaybe isImport declarations
87− where
88− isImport i@(D.PositionedDeclaration _ _ D.ImportDeclaration{}) = Just i
89− isImport _ = Nothing
90
66
91−getDeclPosition :: D.Module -> String -> Maybe SP.SourceSpan
67+-- | Given a surrounding Sourcespan and a Declaration from the PS AST, extracts
92−getDeclPosition m ident = getFirst (foldMap (match ident) decls)
68+-- definition sites inside that Declaration.
69+extractSpans
70+ :: P.SourceSpan
71+ -- ^ The surrounding span
72+ -> P.Declaration
73+ -- ^ The declaration to extract spans from
74+ -> [(Either Text Text, P.SourceSpan)]
75+ -- ^ A @Right@ corresponds to a type level declaration, and a @Left@ to a
76+ -- value level one
77+extractSpans ss d = case d of
78+ P.PositionedDeclaration ss' _ d' ->
79+ extractSpans ss' d'
80+ P.ValueDeclaration i _ _ _ ->
81+ [(Left (runIdentT i), ss)]
82+ P.TypeSynonymDeclaration name _ _ ->
83+ [(Right (runProperNameT name), ss)]
84+ P.TypeClassDeclaration name _ _ members ->
85+ (Right (runProperNameT name), ss) : concatMap (extractSpans' ss) members
86+ P.DataDeclaration _ name _ ctors ->
87+ (Right (runProperNameT name), ss)
88+ : map (\(cname, _) -> (Left (runProperNameT cname), ss)) ctors
89+ P.ExternDeclaration ident _ ->
90+ [(Left (runIdentT ident), ss)]
91+ P.ExternDataDeclaration name _ ->
92+ [(Right (runProperNameT name), ss)]
93+ _ -> []
93 where
94 where
94− decls = getDeclarations m
95+ -- We need this special case to be able to also get the position info for
96+ -- typeclass member functions. Typedeclaratations would clash with value
97+ -- declarations for non-typeclass members, which is why we can't handle them
98+ -- in extractSpans.
99+ extractSpans' ssP dP = case dP of
95− match q (D.PositionedDeclaration ss _ decl) = First (if go q decl
100+ P.PositionedDeclaration ssP' _ dP' ->
96− then Just ss
101+ extractSpans' ssP' dP'
97− else Nothing)
98− match _ _ = First Nothing
99−
100− go q (D.DataDeclaration _ name _ constructors) =
101− properEqual name q || any (\(x,_) -> properEqual x q) constructors
102− go q (D.DataBindingGroupDeclaration decls') = any (go q) decls'
103− go q (D.TypeSynonymDeclaration name _ _) = properEqual name q
104− go q (D.TypeDeclaration ident' _) = identEqual ident' q
102+ P.TypeDeclaration ident _ ->
105− go q (D.ValueDeclaration ident' _ _ _) = identEqual ident' q
103+ [(Left (runIdentT ident), ssP)]
106− go q (D.ExternDeclaration ident' _) = identEqual ident' q
104+ _ -> []
107− go q (D.ExternDataDeclaration name _) = properEqual name q
108− go q (D.TypeClassDeclaration name _ _ members) =
109− properEqual name q || any (go q . unwrapPositioned) members
110− go q (D.TypeInstanceDeclaration ident' _ _ _ _) =
111− identEqual ident' q
112− go _ _ = False
113−
114− properEqual x q = N.runProperName x == q
115− identEqual x q = N.runIdent x == q
116−
117−goToDefinition :: String -> FilePath -> IO (Maybe SP.SourceSpan)
118−goToDefinition q fp = do
119− m <- runExceptT (parseModuleFromFile fp)
120− case m of
121− Right module' -> pure (getDeclPosition module' q)
122− Left _ -> pure Nothing
src/Language/PureScript/Ide/State.hs+186−71
@@ -12,87 +12,202 @@
12-- Functions to access psc-ide's state
12-- Functions to access psc-ide's state
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE MultiParamTypeClasses #-}
18{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
19{-# LANGUAGE PackageImports #-}
16{-# LANGUAGE PackageImports #-}
20{-# LANGUAGE TemplateHaskell #-}
17{-# LANGUAGE TemplateHaskell #-}
21−{-# LANGUAGE TupleSections #-}
22
18
23−module Language.PureScript.Ide.State where
19+module Language.PureScript.Ide.State
20+ ( getLoadedModulenames
21+ , getExternFiles
22+ , resetIdeState
23+ , cacheRebuild
24+ , insertExterns
25+ , insertModule
26+ , insertExternsSTM
27+ , getAllModules
28+ , populateStage2
29+ , populateStage3
30+ , populateStage3STM
31+ ) where
24
32
25−import Prelude ()
33+import Protolude
26−import Prelude.Compat
34+import qualified Prelude
27
35
28import Control.Concurrent.STM
36import Control.Concurrent.STM
29−import Control.Monad.IO.Class
30import "monad-logger" Control.Monad.Logger
37import "monad-logger" Control.Monad.Logger
31−import Control.Monad.Reader.Class
32import qualified Data.Map.Lazy as M
38import qualified Data.Map.Lazy as M
33−import Data.Maybe (catMaybes)
34−import Data.Monoid
35−import qualified Data.Text as T
36import Language.PureScript.Externs
39import Language.PureScript.Externs
37import Language.PureScript.Ide.Externs
40import Language.PureScript.Ide.Externs
38import Language.PureScript.Ide.Reexports
41import Language.PureScript.Ide.Reexports
42+import Language.PureScript.Ide.SourceFile
39import Language.PureScript.Ide.Types
43import Language.PureScript.Ide.Types
40−import Language.PureScript.Names
44+import Language.PureScript.Ide.Util
41−
45+import qualified Language.PureScript as P
42−getPscIdeState :: (PscIde m) =>
46+import System.Clock
43− m (M.Map ModuleIdent [ExternDecl])
47+
44−getPscIdeState = do
48+-- | Resets all State inside psc-ide
45− stateVar <- envStateVar <$> ask
49+resetIdeState :: Ide m => m ()
46− liftIO $ pscStateModules <$> readTVarIO stateVar
50+resetIdeState = do
47−
51+ ideVar <- ideStateVar <$> ask
48−getExternFiles :: (PscIde m) =>
52+ liftIO . atomically $ do
49− m (M.Map ModuleName ExternsFile)
53+ writeTVar ideVar emptyIdeState
50−getExternFiles = do
54+ setStage3STM ideVar emptyStage3
51− stateVar <- envStateVar <$> ask
55+
52− liftIO (externsFiles <$> readTVarIO stateVar)
56+-- | Gets the loaded Modulenames
53−
57+getLoadedModulenames :: Ide m => m [P.ModuleName]
54−getExternFile :: (PscIde m) =>
58+getLoadedModulenames = M.keys <$> getExternFiles
55− ModuleName -> m (Maybe ExternsFile)
59+
56−getExternFile mn = M.lookup mn <$> getExternFiles
60+-- | Gets all loaded ExternFiles
57−
61+getExternFiles :: Ide m => m (M.Map P.ModuleName ExternsFile)
58−getAllDecls :: (PscIde m) => m [ExternDecl]
62+getExternFiles = s1Externs <$> getStage1
59−getAllDecls = concat <$> getPscIdeState
63+
60−
64+-- | Insert a Module into Stage1 of the State
61−getAllModules :: (PscIde m) => m [Module]
65+insertModule :: Ide m => (FilePath, P.Module) -> m ()
62−getAllModules = M.toList <$> getPscIdeState
66+insertModule module' = do
63−
67+ stateVar <- ideStateVar <$> ask
64−getAllModulesWithReexports :: (PscIde m, MonadLogger m) =>
68+ liftIO . atomically $ insertModuleSTM stateVar module'
65− m [Module]
69+
66−getAllModulesWithReexports = do
70+-- | STM version of insertModule
67− mis <- M.keys <$> getPscIdeState
71+insertModuleSTM :: TVar IdeState -> (FilePath, P.Module) -> STM ()
68− ms <- traverse getModuleWithReexports mis
72+insertModuleSTM ref (fp, module') =
69− pure (catMaybes ms)
73+ modifyTVar ref $ \x ->
70−
74+ x { ideStage1 = (ideStage1 x) {
71−getModule :: (PscIde m, MonadLogger m) =>
75+ s1Modules = M.insert
72− ModuleIdent -> m (Maybe Module)
76+ (P.getModuleName module')
73−getModule m = do
77+ (module', fp)
74− modules <- getPscIdeState
78+ (s1Modules (ideStage1 x))}}
75− pure ((m,) <$> M.lookup m modules)
79+
76−
80+-- | Retrieves Stage1 from the State.
77−getModuleWithReexports :: (PscIde m, MonadLogger m) =>
81+-- This includes loaded Externfiles
78− ModuleIdent -> m (Maybe Module)
82+getStage1 :: Ide m => m Stage1
79−getModuleWithReexports mi = do
83+getStage1 = do
80− m <- getModule mi
84+ st <- ideStateVar <$> ask
81− modules <- getPscIdeState
85+ fmap ideStage1 . liftIO . readTVarIO $ st
82− pure $ resolveReexports modules <$> m
86+
83−
87+-- | STM version of getStage1
84−insertModule ::(PscIde m, MonadLogger m) =>
88+getStage1STM :: TVar IdeState -> STM Stage1
85− ExternsFile -> m ()
89+getStage1STM ref = ideStage1 <$> readTVar ref
86−insertModule externsFile = do
90+
87− env <- ask
91+-- | Retrieves Stage2 from the State.
88− let moduleName = efModuleName externsFile
92+getStage2 :: Ide m => m Stage2
89− $(logDebug) $ "Inserting Module: " <> T.pack (runModuleName moduleName)
93+getStage2 = do
90− liftIO . atomically $ insertModule' (envStateVar env) externsFile
94+ st <- ideStateVar <$> ask
91−
95+ liftIO (atomically (getStage2STM st))
92−insertModule' :: TVar PscIdeState -> ExternsFile -> STM ()
96+
93−insertModule' st ef =
97+getStage2STM :: TVar IdeState -> STM Stage2
94− modifyTVar st $ \x ->
98+getStage2STM ref = ideStage2 <$> readTVar ref
95− x { externsFiles = M.insert (efModuleName ef) ef (externsFiles x)
99+
96− , pscStateModules = let (mn, decls) = convertExterns ef
100+-- | STM version of setStage2
97− in M.insert mn decls (pscStateModules x)
101+setStage2STM :: TVar IdeState -> Stage2 -> STM ()
98− }
102+setStage2STM ref s2 = do
103+ modifyTVar ref $ \x ->
104+ x {ideStage2 = s2}
105+ pure ()
106+
107+-- | Retrieves Stage3 from the State.
108+-- This includes the denormalized Declarations and cached rebuilds
109+getStage3 :: Ide m => m Stage3
110+getStage3 = do
111+ st <- ideStateVar <$> ask
112+ fmap ideStage3 . liftIO . readTVarIO $ st
113+
114+-- | Sets Stage3 inside the compiler
115+setStage3STM :: TVar IdeState -> Stage3 -> STM ()
116+setStage3STM ref s3 = do
117+ modifyTVar ref $ \x ->
118+ x {ideStage3 = s3}
119+ pure ()
120+
121+-- | Checks if the given ModuleName matches the last rebuild cache and if it
122+-- does returns all loaded definitions + the definitions inside the rebuild
123+-- cache
124+getAllModules :: Ide m => Maybe P.ModuleName -> m [Module]
125+getAllModules mmoduleName = do
126+ declarations <- s3Declarations <$> getStage3
127+ rebuild <- cachedRebuild
128+ case mmoduleName of
129+ Nothing -> pure (M.toList declarations)
130+ Just moduleName ->
131+ case rebuild of
132+ Just (cachedModulename, ef)
133+ | cachedModulename == moduleName -> do
134+ (AstData asts) <- s2AstData <$> getStage2
135+ let ast = fromMaybe M.empty (M.lookup moduleName asts)
136+ pure . M.toList $
137+ M.insert moduleName
138+ (snd . annotateLocations ast . fst . convertExterns $ ef) declarations
139+ _ -> pure (M.toList declarations)
140+
141+-- | Adds an ExternsFile into psc-ide's State Stage1. This does not populate the
142+-- following Stages, which needs to be done after all the necessary Exterms have
143+-- been loaded.
144+insertExterns :: Ide m => ExternsFile -> m ()
145+insertExterns ef = do
146+ st <- ideStateVar <$> ask
147+ liftIO (atomically (insertExternsSTM st ef))
148+
149+-- | STM version of insertExterns
150+insertExternsSTM :: TVar IdeState -> ExternsFile -> STM ()
151+insertExternsSTM ref ef =
152+ modifyTVar ref $ \x ->
153+ x { ideStage1 = (ideStage1 x) {
154+ s1Externs = M.insert (efModuleName ef) ef (s1Externs (ideStage1 x))}}
155+
156+-- | Sets rebuild cache to the given ExternsFile
157+cacheRebuild :: Ide m => ExternsFile -> m ()
158+cacheRebuild ef = do
159+ st <- ideStateVar <$> ask
160+ liftIO . atomically . modifyTVar st $ \x ->
161+ x { ideStage3 = (ideStage3 x) {
162+ s3CachedRebuild = Just (efModuleName ef, ef)}}
163+
164+-- | Retrieves the rebuild cache
165+cachedRebuild :: Ide m => m (Maybe (P.ModuleName, ExternsFile))
166+cachedRebuild = s3CachedRebuild <$> getStage3
167+
168+-- | Extracts source spans from the parsed ASTs
169+populateStage2 :: (Ide m, MonadLogger m) => m ()
170+populateStage2 = do
171+ st <- ideStateVar <$> ask
172+ duration <- liftIO $ do
173+ start <- getTime Monotonic
174+ atomically (populateStage2STM st)
175+ end <- getTime Monotonic
176+ pure (Prelude.show (diffTimeSpec start end))
177+ $(logDebug) $ "Finished populating Stage2 in " <> toS duration
178+
179+-- | STM version of populateStage2
180+populateStage2STM :: TVar IdeState -> STM ()
181+populateStage2STM ref = do
182+ modules <- s1Modules <$> getStage1STM ref
183+ let spans = map (\((P.Module ss _ _ decls _), _) -> M.fromList (concatMap (extractSpans ss) decls)) modules
184+ setStage2STM ref (Stage2 (AstData spans))
185+
186+-- | Resolves reexports and populates Stage3 with data to be used in queries.
187+populateStage3 :: (Ide m, MonadLogger m) => m ()
188+populateStage3 = do
189+ st <- ideStateVar <$> ask
190+ (duration, results) <- liftIO $ do
191+ start <- getTime Monotonic
192+ results <- atomically (populateStage3STM st)
193+ end <- getTime Monotonic
194+ pure (Prelude.show (diffTimeSpec start end), results)
195+ traverse_
196+ (logWarnN . prettyPrintReexportResult (runModuleNameT . fst))
197+ (filter reexportHasFailures results)
198+ $(logDebug) $ "Finished populating Stage3 in " <> toS duration
199+
200+-- | STM version of populateStage3
201+populateStage3STM :: TVar IdeState -> STM [ReexportResult Module]
202+populateStage3STM ref = do
203+ externs <- s1Externs <$> getStage1STM ref
204+ (AstData asts) <- s2AstData <$> getStage2STM ref
205+ let modules = M.map convertExterns externs
206+ nModules :: Map P.ModuleName (Module, [(P.ModuleName, P.DeclarationRef)])
207+ nModules = M.mapWithKey
208+ (\moduleName (m, refs) ->
209+ (fromMaybe m $ annotateLocations <$> M.lookup moduleName asts <*> pure m, refs)) modules
210+ -- resolves reexports and discards load failures for now
211+ result = resolveReexports (M.map (snd . fst) nModules) <$> M.elems nModules
212+ setStage3STM ref (Stage3 (M.fromList (map reResolved result)) Nothing)
213+ pure result
src/Language/PureScript/Ide/Types.hs+98−76
@@ -12,102 +12,122 @@
12-- Type definitions for psc-ide
12-- Type definitions for psc-ide
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE ConstraintKinds #-}
15+{-# LANGUAGE OverloadedStrings #-}
16−{-# LANGUAGE FlexibleContexts #-}
16+{-# LANGUAGE DeriveFoldable #-}
17−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
18−{-# LANGUAGE OverloadedStrings #-}
19−{-# LANGUAGE ScopedTypeVariables #-}
20
17
21module Language.PureScript.Ide.Types where
18module Language.PureScript.Ide.Types where
22
19
23−import Prelude ()
20+import Protolude
24−import Prelude.Compat
25
21
26import Control.Concurrent.STM
22import Control.Concurrent.STM
27−import Control.Monad
28−import Control.Monad.Reader.Class
29−import Control.Monad.Trans
30import Data.Aeson
23import Data.Aeson
31import Data.Map.Lazy as M
24import Data.Map.Lazy as M
32−import Data.Maybe (maybeToList)
33−import Data.Text (Text (), pack, unpack)
34−import qualified Language.PureScript.AST.Declarations as D
35−import Language.PureScript.Externs
36import qualified Language.PureScript.Errors.JSON as P
25import qualified Language.PureScript.Errors.JSON as P
37−import qualified Language.PureScript.Names as N
38import qualified Language.PureScript as P
26import qualified Language.PureScript as P
39−
27+import Language.PureScript.Ide.Conversions
40−import Text.Parsec
28+import Text.Parsec as Parsec
41import Text.Parsec.Text
29import Text.Parsec.Text
42
30
43−type Ident = Text
44−type DeclIdent = Text
45type ModuleIdent = Text
31type ModuleIdent = Text
46
32
47−data ExternDecl
33+data IdeDeclaration
48− -- | A function/value declaration
34+ = IdeValue P.Ident P.Type
49− = ValueDeclaration Ident P.Type
35+ | IdeType (P.ProperName 'P.TypeName) P.Kind
50− | TypeDeclaration (P.ProperName 'P.TypeName) P.Kind
36+ | IdeTypeSynonym (P.ProperName 'P.TypeName) P.Type
51− | TypeSynonymDeclaration (P.ProperName 'P.TypeName) P.Type
37+ | IdeDataConstructor (P.ProperName 'P.ConstructorName) (P.ProperName 'P.TypeName) P.Type
52− -- | A Dependency onto another Module
38+ | IdeTypeClass (P.ProperName 'P.ClassName)
53− | Dependency
39+ | IdeValueOperator (P.OpName 'P.ValueOpName) Text P.Precedence P.Associativity
54− ModuleIdent -- name of the dependency
40+ | IdeTypeOperator (P.OpName 'P.TypeOpName) Text P.Precedence P.Associativity
55− [Text] -- explicit imports
41+ deriving (Show, Eq, Ord)
56− (Maybe Text) -- An eventual qualifier
42+
57− -- | A module declaration
43+data IdeDeclarationAnn = IdeDeclarationAnn Annotation IdeDeclaration
58− | ModuleDecl
44+ deriving (Show, Eq, Ord)
59− ModuleIdent -- The modules name
45+
60− [DeclIdent] -- The exported identifiers
46+data Annotation
61− -- | A data/newtype declaration
47+ = Annotation
62− | DataConstructor
48+ { annLocation :: Maybe P.SourceSpan
63− DeclIdent -- The type name
49+ , annExportedFrom :: Maybe P.ModuleName
64− (P.ProperName 'P.TypeName)
50+ } deriving (Show, Eq, Ord)
65− P.Type -- The "type"
51+
66− -- | An exported module
52+emptyAnn :: Annotation
67− | TypeClassDeclaration (P.ProperName 'P.ClassName)
53+emptyAnn = Annotation Nothing Nothing
68− | Export ModuleIdent -- The exported Modules name
54+
69− deriving (Show,Eq,Ord)
55+type Module = (P.ModuleName, [IdeDeclarationAnn])
70−
56+
71−type Module = (ModuleIdent, [ExternDecl])
57+newtype AstData a =
58+ AstData (Map P.ModuleName (Map (Either Text Text) a))
59+ deriving (Show, Eq, Ord, Functor, Foldable)
72
60
73data Configuration =
61data Configuration =
74 Configuration
62 Configuration
75 { confOutputPath :: FilePath
63 { confOutputPath :: FilePath
76 , confDebug :: Bool
64 , confDebug :: Bool
65+ , confGlobs :: [FilePath]
77 }
66 }
78
67
79−data PscIdeEnvironment =
68+data IdeEnvironment =
80− PscIdeEnvironment
69+ IdeEnvironment
81− { envStateVar :: TVar PscIdeState
70+ { ideStateVar :: TVar IdeState
82− , envConfiguration :: Configuration
71+ , ideConfiguration :: Configuration
83 }
72 }
84
73
85−type PscIde m = (MonadIO m, MonadReader PscIdeEnvironment m)
74+type Ide m = (MonadIO m, MonadReader IdeEnvironment m)
75+
76+data IdeState = IdeState
77+ { ideStage1 :: Stage1
78+ , ideStage2 :: Stage2
79+ , ideStage3 :: Stage3
80+ }
86
81
87−data PscIdeState =
82+emptyIdeState :: IdeState
88− PscIdeState
83+emptyIdeState = IdeState emptyStage1 emptyStage2 emptyStage3
89− { pscStateModules :: M.Map Text [ExternDecl]
90− , externsFiles :: M.Map P.ModuleName ExternsFile
91− } deriving Show
92
84
93−emptyPscIdeState :: PscIdeState
85+emptyStage1 :: Stage1
94−emptyPscIdeState = PscIdeState M.empty M.empty
86+emptyStage1 = Stage1 M.empty M.empty
95
87
96−data Match = Match ModuleIdent ExternDecl
88+emptyStage2 :: Stage2
97− deriving (Show, Eq)
89+emptyStage2 = Stage2 (AstData M.empty)
90+
91+emptyStage3 :: Stage3
92+emptyStage3 = Stage3 M.empty Nothing
93+
94+data Stage1 = Stage1
95+ { s1Externs :: M.Map P.ModuleName P.ExternsFile
96+ , s1Modules :: M.Map P.ModuleName (P.Module, FilePath)
97+ }
98+
99+data Stage2 = Stage2
100+ { s2AstData :: AstData P.SourceSpan
101+ }
102+
103+data Stage3 = Stage3
104+ { s3Declarations :: M.Map P.ModuleName [IdeDeclarationAnn]
105+ , s3CachedRebuild :: Maybe (P.ModuleName, P.ExternsFile)
106+ }
107+
108+newtype Match a = Match (P.ModuleName, a)
109+ deriving (Show, Eq, Functor)
98
110
99newtype Completion =
111newtype Completion =
100− Completion (ModuleIdent, DeclIdent, Text)
112+ Completion (Text, Text, Text)
113+ deriving (Show,Eq)
114+
115+newtype Info =
116+ Info (Text, Text, Text, Maybe P.SourceSpan)
101 deriving (Show,Eq)
117 deriving (Show,Eq)
102
118
119+instance ToJSON Info where
120+ toJSON (Info (m, d, t, sourceSpan)) =
121+ object ["module" .= m, "identifier" .= d, "type" .= t, "definedAt" .= sourceSpan]
122+
103instance ToJSON Completion where
123instance ToJSON Completion where
104− toJSON (Completion (m,d,t)) =
124+ toJSON (Completion (m, d, t)) =
105 object ["module" .= m, "identifier" .= d, "type" .= t]
125 object ["module" .= m, "identifier" .= d, "type" .= t]
106
126
107data ModuleImport =
127data ModuleImport =
108 ModuleImport
128 ModuleImport
109 { importModuleName :: ModuleIdent
129 { importModuleName :: ModuleIdent
110− , importType :: D.ImportDeclarationType
130+ , importType :: P.ImportDeclarationType
111 , importQualifier :: Maybe Text
131 , importQualifier :: Maybe Text
112 } deriving(Show)
132 } deriving(Show)
113
133
@@ -117,29 +137,30 @@ instance Eq ModuleImport where
117 && importQualifier mi1 == importQualifier mi2
137 && importQualifier mi1 == importQualifier mi2
118
138
119instance ToJSON ModuleImport where
139instance ToJSON ModuleImport where
120− toJSON (ModuleImport mn D.Implicit qualifier) =
140+ toJSON (ModuleImport mn P.Implicit qualifier) =
121 object $ [ "module" .= mn
141 object $ [ "module" .= mn
122 , "importType" .= ("implicit" :: Text)
142 , "importType" .= ("implicit" :: Text)
123 ] ++ fmap (\x -> "qualifier" .= x) (maybeToList qualifier)
143 ] ++ fmap (\x -> "qualifier" .= x) (maybeToList qualifier)
124− toJSON (ModuleImport mn (D.Explicit refs) _) =
144+ toJSON (ModuleImport mn (P.Explicit refs) _) =
125 object [ "module" .= mn
145 object [ "module" .= mn
126 , "importType" .= ("explicit" :: Text)
146 , "importType" .= ("explicit" :: Text)
127 , "identifiers" .= (identifierFromDeclarationRef <$> refs)
147 , "identifiers" .= (identifierFromDeclarationRef <$> refs)
128 ]
148 ]
129− toJSON (ModuleImport mn (D.Hiding refs) _) =
149+ toJSON (ModuleImport mn (P.Hiding refs) _) =
130 object [ "module" .= mn
150 object [ "module" .= mn
131 , "importType" .= ("hiding" :: Text)
151 , "importType" .= ("hiding" :: Text)
132 , "identifiers" .= (identifierFromDeclarationRef <$> refs)
152 , "identifiers" .= (identifierFromDeclarationRef <$> refs)
133 ]
153 ]
134
154
135−identifierFromDeclarationRef :: D.DeclarationRef -> String
155+identifierFromDeclarationRef :: P.DeclarationRef -> Text
136−identifierFromDeclarationRef (D.TypeRef name _) = N.runProperName name
156+identifierFromDeclarationRef (P.TypeRef name _) = runProperNameT name
137−identifierFromDeclarationRef (D.ValueRef ident) = N.runIdent ident
157+identifierFromDeclarationRef (P.ValueRef ident) = runIdentT ident
138−identifierFromDeclarationRef (D.TypeClassRef name) = N.runProperName name
158+identifierFromDeclarationRef (P.TypeClassRef name) = runProperNameT name
139identifierFromDeclarationRef _ = ""
159identifierFromDeclarationRef _ = ""
140
160
141data Success =
161data Success =
142 CompletionResult [Completion]
162 CompletionResult [Completion]
163+ | InfoResult [Info]
143 | TextResult Text
164 | TextResult Text
144 | MultilineTextResult [Text]
165 | MultilineTextResult [Text]
145 | PursuitResult [PursuitResponse]
166 | PursuitResult [PursuitResponse]
@@ -154,6 +175,7 @@ encodeSuccess res =
154
175
155instance ToJSON Success where
176instance ToJSON Success where
156 toJSON (CompletionResult cs) = encodeSuccess cs
177 toJSON (CompletionResult cs) = encodeSuccess cs
178+ toJSON (InfoResult i) = encodeSuccess i
157 toJSON (TextResult t) = encodeSuccess t
179 toJSON (TextResult t) = encodeSuccess t
158 toJSON (MultilineTextResult ts) = encodeSuccess ts
180 toJSON (MultilineTextResult ts) = encodeSuccess ts
159 toJSON (PursuitResult resp) = encodeSuccess resp
181 toJSON (PursuitResult resp) = encodeSuccess resp
@@ -183,14 +205,14 @@ data PursuitResponse =
183 ModuleResponse ModuleIdent Text
205 ModuleResponse ModuleIdent Text
184 -- | A Pursuit Response for a declaration. Consist of the declarations type,
206 -- | A Pursuit Response for a declaration. Consist of the declarations type,
185 -- module, name and package
207 -- module, name and package
186− | DeclarationResponse Text ModuleIdent DeclIdent Text
208+ | DeclarationResponse Text ModuleIdent Text Text
187 deriving (Show,Eq)
209 deriving (Show,Eq)
188
210
189instance FromJSON PursuitResponse where
211instance FromJSON PursuitResponse where
190 parseJSON (Object o) = do
212 parseJSON (Object o) = do
191 package <- o .: "package"
213 package <- o .: "package"
192 info <- o .: "info"
214 info <- o .: "info"
193− (type' :: String) <- info .: "type"
215+ (type' :: Text) <- info .: "type"
194 case type' of
216 case type' of
195 "module" -> do
217 "module" -> do
196 name <- info .: "module"
218 name <- info .: "module"
@@ -205,26 +227,26 @@ instance FromJSON PursuitResponse where
205
227
206typeParse :: Text -> Either Text (Text, Text)
228typeParse :: Text -> Either Text (Text, Text)
207typeParse t = case parse parseType "" t of
229typeParse t = case parse parseType "" t of
208− Right (x,y) -> Right (pack x, pack y)
230+ Right (x,y) -> Right (x, y)
209− Left err -> Left (pack (show err))
231+ Left err -> Left (show err)
210 where
232 where
211− parseType :: Parser (String, String)
233+ parseType :: Parser (Text, Text)
212 parseType = do
234 parseType = do
213 name <- identifier
235 name <- identifier
214 _ <- string "::"
236 _ <- string "::"
215 spaces
237 spaces
216 type' <- many1 anyChar
238 type' <- many1 anyChar
217− pure (unpack name, type')
239+ pure (name, toS type')
218
240
219 identifier :: Parser Text
241 identifier :: Parser Text
220 identifier = do
242 identifier = do
221 spaces
243 spaces
222 ident <-
244 ident <-
223 -- necessary for being able to parse the following ((++), concat)
245 -- necessary for being able to parse the following ((++), concat)
224− between (char '(') (char ')') (many1 (noneOf ", )")) <|>
246+ between (char '(') (char ')') (many1 (noneOf ", )")) Parsec.<|>
225 many1 (noneOf ", )")
247 many1 (noneOf ", )")
226 spaces
248 spaces
227− pure (pack ident)
249+ pure (toS ident)
228
250
229instance ToJSON PursuitResponse where
251instance ToJSON PursuitResponse where
230 toJSON (ModuleResponse name package) =
252 toJSON (ModuleResponse name package) =
src/Language/PureScript/Ide/Util.hs+64−34
@@ -9,57 +9,87 @@
9-- Stability : experimental
9-- Stability : experimental
10--
10--
11-- |
11-- |
12−-- Generally useful functions and conversions
12+-- Generally useful functions
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
16
16
17−module Language.PureScript.Ide.Util where
17+module Language.PureScript.Ide.Util
18+ ( identifierFromIdeDeclaration
19+ , unwrapMatch
20+ , unwrapPositioned
21+ , unwrapPositionedRef
22+ , completionFromMatch
23+ , infoFromMatch
24+ , encodeT
25+ , decodeT
26+ , discardAnn
27+ , module Language.PureScript.Ide.Conversions
28+ ) where
18
29
30+import Protolude hiding (decodeUtf8, encodeUtf8)
19import Data.Aeson
31import Data.Aeson
20−import Data.Text (Text)
21import qualified Data.Text as T
32import qualified Data.Text as T
22−import Data.Text.Lazy (fromStrict, toStrict)
23import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
33import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
24import qualified Language.PureScript as P
34import qualified Language.PureScript as P
25import Language.PureScript.Ide.Types
35import Language.PureScript.Ide.Types
36+import Language.PureScript.Ide.Conversions
26
37
27−runProperNameT :: P.ProperName a -> Text
38+identifierFromIdeDeclaration :: IdeDeclaration -> Text
28−runProperNameT = T.pack . P.runProperName
39+identifierFromIdeDeclaration d = case d of
40+ IdeValue name _ -> runIdentT name
41+ IdeType name _ -> runProperNameT name
42+ IdeTypeSynonym name _ -> runProperNameT name
43+ IdeDataConstructor name _ _ -> runProperNameT name
44+ IdeTypeClass name -> runProperNameT name
45+ IdeValueOperator op _ _ _ -> runOpNameT op
46+ IdeTypeOperator op _ _ _ -> runOpNameT op
29
47
30−runIdentT :: P.Ident -> Text
48+discardAnn :: IdeDeclarationAnn -> IdeDeclaration
31−runIdentT = T.pack . P.runIdent
49+discardAnn (IdeDeclarationAnn _ d) = d
32
50
33−prettyTypeT :: P.Type -> Text
51+unwrapMatch :: Match a -> a
34−prettyTypeT = T.unwords . fmap T.strip . T.lines . T.pack . P.prettyPrintType
52+unwrapMatch (Match (_, ed)) = ed
35
53
36−identifierFromExternDecl :: ExternDecl -> Text
54+completionFromMatch :: Match IdeDeclaration -> Completion
37−identifierFromExternDecl (ValueDeclaration name _) = name
55+completionFromMatch = Completion . completionFromMatch'
38−identifierFromExternDecl (TypeDeclaration name _) = runProperNameT name
39−identifierFromExternDecl (TypeSynonymDeclaration name _) = runProperNameT name
40−identifierFromExternDecl (DataConstructor name _ _) = name
41−identifierFromExternDecl (TypeClassDeclaration name) = runProperNameT name
42−identifierFromExternDecl (ModuleDecl name _) = name
43−identifierFromExternDecl Dependency{} = "~Dependency~"
44−identifierFromExternDecl Export{} = "~Export~"
45
56
46−identifierFromMatch :: Match -> Text
57+completionFromMatch' :: Match IdeDeclaration -> (Text, Text, Text)
47−identifierFromMatch (Match _ ed) = identifierFromExternDecl ed
58+completionFromMatch' (Match (m', d)) = case d of
59+ IdeValue name type' -> (m, runIdentT name, prettyTypeT type')
60+ IdeType name kind -> (m, runProperNameT name, toS (P.prettyPrintKind kind))
61+ IdeTypeSynonym name kind -> (m, runProperNameT name, prettyTypeT kind)
62+ IdeDataConstructor name _ type' -> (m, runProperNameT name, prettyTypeT type')
63+ IdeTypeClass name -> (m, runProperNameT name, "class")
64+ IdeValueOperator op ref precedence associativity ->
65+ (m, runOpNameT op, showFixity precedence associativity ref op)
66+ IdeTypeOperator op ref precedence associativity ->
67+ (m, runOpNameT op, showFixity precedence associativity ref op)
68+ where
69+ m = runModuleNameT m'
70+ showFixity p a r o =
71+ let asso = case a of
72+ P.Infix -> "infix"
73+ P.Infixl -> "infixl"
74+ P.Infixr -> "infixr"
75+ in T.unwords [asso, show p, r, "as", runOpNameT o]
48
76
49−completionFromMatch :: Match -> Maybe Completion
77+infoFromMatch :: Match IdeDeclarationAnn -> Info
50−completionFromMatch (Match _ Dependency{}) = Nothing
78+infoFromMatch (Match (m, (IdeDeclarationAnn ann d))) =
51−completionFromMatch (Match _ Export{}) = Nothing
79+ Info (a, b, c, annLocation ann)
52−completionFromMatch (Match m d) = Just $ case d of
80+ where
53− ValueDeclaration name type' -> Completion (m, name, prettyTypeT type')
81+ (a, b, c) = completionFromMatch' (Match (m, d))
54− TypeDeclaration name kind -> Completion (m, runProperNameT name, T.pack $ P.prettyPrintKind kind)
55− TypeSynonymDeclaration name kind -> Completion (m, runProperNameT name, prettyTypeT kind)
56− DataConstructor name _ type' -> Completion (m, name, prettyTypeT type')
57− TypeClassDeclaration name -> Completion (m, runProperNameT name, "class")
58− ModuleDecl name _ -> Completion ("module", name, "module")
59− _ -> error "the impossible happened in completionFromMatch"
60
82
61encodeT :: (ToJSON a) => a -> Text
83encodeT :: (ToJSON a) => a -> Text
62−encodeT = toStrict . decodeUtf8 . encode
84+encodeT = toS . decodeUtf8 . encode
63
85
64decodeT :: (FromJSON a) => Text -> Maybe a
86decodeT :: (FromJSON a) => Text -> Maybe a
65−decodeT = decode . encodeUtf8 . fromStrict
87+decodeT = decode . encodeUtf8 . toS
88+
89+unwrapPositioned :: P.Declaration -> P.Declaration
90+unwrapPositioned (P.PositionedDeclaration _ _ x) = x
91+unwrapPositioned x = x
92+
93+unwrapPositionedRef :: P.DeclarationRef -> P.DeclarationRef
94+unwrapPositionedRef (P.PositionedDeclarationRef _ _ x) = x
95+unwrapPositionedRef x = x
src/Language/PureScript/Ide/Watcher.hs+25−31
@@ -12,44 +12,38 @@
12-- File watcher for externs files
12-- File watcher for externs files
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE RecordWildCards #-}
15+module Language.PureScript.Ide.Watcher
16+ ( watcher
17+ ) where
16
18
17−module Language.PureScript.Ide.Watcher where
19+import Protolude
18
20
19−import Prelude ()
20−import Prelude.Compat
21−
22−import Control.Concurrent (threadDelay)
23import Control.Concurrent.STM
21import Control.Concurrent.STM
24−import Control.Monad
25−import Control.Monad.Trans.Except
26−import qualified Data.Map as M
27−import Data.Maybe (isJust)
28−import Language.PureScript.Externs
29import Language.PureScript.Ide.Externs
22import Language.PureScript.Ide.Externs
30import Language.PureScript.Ide.State
23import Language.PureScript.Ide.State
31import Language.PureScript.Ide.Types
24import Language.PureScript.Ide.Types
32import System.FilePath
25import System.FilePath
33import System.FSNotify
26import System.FSNotify
34
27
28+-- | Reloads an ExternsFile from Disc. If the Event indicates the ExternsFile
29+-- was deleted we don't do anything.
30+reloadFile :: TVar IdeState -> Event -> IO ()
31+reloadFile _ Removed{} = pure ()
32+reloadFile ref ev = do
33+ let fp = eventPath ev
34+ ef' <- runExceptT (readExternFile fp)
35+ case ef' of
36+ Left _ -> pure ()
37+ Right ef -> do
38+ void $ atomically (insertExternsSTM ref ef *> populateStage3STM ref)
39+ putStrLn ("Reloaded File at: " ++ fp)
35
40
36−reloadFile :: TVar PscIdeState -> FilePath -> IO ()
41+-- | Installs filewatchers for the given directory and reloads ExternsFiles when
37−reloadFile stateVar fp = do
42+-- they change on disc
38− (Right ef@ExternsFile{..}) <- runExceptT $ readExternFile fp
43+watcher :: TVar IdeState -> FilePath -> IO ()
39− reloaded <- atomically $ do
44+watcher stateVar fp =
40− st <- readTVar stateVar
45+ withManagerConf (defaultConfig { confDebounce = NoDebounce }) $ \mgr -> do
41− if isLoaded efModuleName st
46+ _ <- watchTree mgr fp
42− then
47+ (\ev -> takeFileName (eventPath ev) == "externs.json")
43− insertModule' stateVar ef *> pure True
48+ (reloadFile stateVar)
44− else
49+ forever (threadDelay 100000)
45− pure False
46− when reloaded $ putStrLn $ "Reloaded File at: " ++ fp
47− where
48− isLoaded name st = isJust (M.lookup name (externsFiles st))
49−
50−watcher :: TVar PscIdeState -> FilePath -> IO ()
51−watcher stateVar fp = withManager $ \mgr -> do
52− _ <- watchTree mgr fp
53− (\ev -> takeFileName (eventPath ev) == "externs.json")
54− (reloadFile stateVar . eventPath)
55− forever (threadDelay 10000)
src/Language/PureScript/Interactive.hsnew file+289
@@ -0,0 +1,289 @@
1+{-# LANGUAGE DoAndIfThenElse #-}
2+{-# LANGUAGE FlexibleContexts #-}
3+{-# LANGUAGE MultiParamTypeClasses #-}
4+{-# LANGUAGE TupleSections #-}
5+{-# LANGUAGE DataKinds #-}
6+
7+module Language.PureScript.Interactive
8+ ( handleCommand
9+ , module Interactive
10+
11+ -- TODO: remove these exports
12+ , make
13+ , runMake
14+ ) where
15+
16+import Prelude ()
17+import Prelude.Compat
18+
19+import Data.List (intercalate, nub, sort, find, foldl')
20+import Data.Maybe (mapMaybe)
21+import qualified Data.Map as M
22+
23+import Control.Monad.IO.Class (MonadIO, liftIO)
24+import Control.Monad.State.Class
25+import Control.Monad.Reader.Class
26+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
27+import Control.Monad.Trans.State.Strict (StateT, runStateT)
28+import Control.Monad.Writer.Strict (Writer(), runWriter)
29+
30+import qualified Language.PureScript as P
31+import qualified Language.PureScript.Names as N
32+
33+import Language.PureScript.Interactive.Completion as Interactive
34+import Language.PureScript.Interactive.IO as Interactive
35+import Language.PureScript.Interactive.Message as Interactive
36+import Language.PureScript.Interactive.Module as Interactive
37+import Language.PureScript.Interactive.Parser as Interactive
38+import Language.PureScript.Interactive.Printer as Interactive
39+import Language.PureScript.Interactive.Types as Interactive
40+
41+import System.FilePath ((</>))
42+
43+-- | Pretty-print errors
44+printErrors :: MonadIO m => P.MultipleErrors -> m ()
45+printErrors = liftIO . putStrLn . P.prettyPrintMultipleErrors P.defaultPPEOptions
46+
47+-- | This is different than the runMake in 'Language.PureScript.Make' in that it specifies the
48+-- options and ignores the warning messages.
49+runMake :: P.Make a -> IO (Either P.MultipleErrors a)
50+runMake mk = fst <$> P.runMake P.defaultOptions mk
51+
52+-- | Rebuild a module, using the cached externs data for dependencies.
53+rebuild
54+ :: [P.ExternsFile]
55+ -> P.Module
56+ -> P.Make (P.ExternsFile, P.Environment)
57+rebuild loadedExterns m = do
58+ externs <- P.rebuildModule buildActions loadedExterns m
59+ return (externs, foldl' (flip P.applyExternsFileToEnvironment) P.initEnvironment (loadedExterns ++ [externs]))
60+ where
61+ buildActions :: P.MakeActions P.Make
62+ buildActions =
63+ (P.buildMakeActions modulesDir
64+ filePathMap
65+ M.empty
66+ False) { P.progress = const (return ()) }
67+
68+ filePathMap :: M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
69+ filePathMap = M.singleton (P.getModuleName m) (Left P.RebuildAlways)
70+
71+-- | Build the collection of modules from scratch. This is usually done on startup.
72+make
73+ :: [(FilePath, P.Module)]
74+ -> P.Make ([P.ExternsFile], P.Environment)
75+make ms = do
76+ foreignFiles <- P.inferForeignModules filePathMap
77+ externs <- P.make (buildActions foreignFiles) (map snd ms)
78+ return (externs, foldl' (flip P.applyExternsFileToEnvironment) P.initEnvironment externs)
79+ where
80+ buildActions :: M.Map P.ModuleName FilePath -> P.MakeActions P.Make
81+ buildActions foreignFiles =
82+ P.buildMakeActions modulesDir
83+ filePathMap
84+ foreignFiles
85+ False
86+
87+ filePathMap :: M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
88+ filePathMap = M.fromList $ map (\(fp, m) -> (P.getModuleName m, Right fp)) ms
89+
90+-- | Performs a PSCi command
91+handleCommand
92+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
93+ => (String -> m ())
94+ -> m ()
95+ -> Command
96+ -> m ()
97+handleCommand _ _ ShowHelp = liftIO $ putStrLn helpMessage
98+handleCommand _ r ResetState = handleResetState r
99+handleCommand c _ (Expression val) = handleExpression c val
100+handleCommand _ _ (Import im) = handleImport im
101+handleCommand _ _ (Decls l) = handleDecls l
102+handleCommand _ _ (TypeOf val) = handleTypeOf val
103+handleCommand _ _ (KindOf typ) = handleKindOf typ
104+handleCommand _ _ (BrowseModule moduleName) = handleBrowse moduleName
105+handleCommand _ _ (ShowInfo QueryLoaded) = handleShowLoadedModules
106+handleCommand _ _ (ShowInfo QueryImport) = handleShowImportedModules
107+handleCommand _ _ QuitPSCi = P.internalError "`handleCommand QuitPSCi` was called. This is a bug."
108+
109+-- | Reset the application state
110+handleResetState
111+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
112+ => m ()
113+ -> m ()
114+handleResetState reload = do
115+ modify $ updateImportedModules (const [])
116+ . updateLets (const [])
117+ files <- asks psciLoadedFiles
118+ e <- runExceptT $ do
119+ modules <- ExceptT . liftIO $ loadAllModules files
120+ (externs, _) <- ExceptT . liftIO . runMake . make $ modules
121+ return (map snd modules, externs)
122+ case e of
123+ Left errs -> printErrors errs
124+ Right (modules, externs) -> do
125+ modify (updateLoadedExterns (const (zip modules externs)))
126+ reload
127+
128+-- | Takes a value expression and evaluates it with the current state.
129+handleExpression
130+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
131+ => (String -> m ())
132+ -> P.Expr
133+ -> m ()
134+handleExpression evaluate val = do
135+ st <- get
136+ let m = createTemporaryModule True st val
137+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
138+ case e of
139+ Left errs -> printErrors errs
140+ Right _ -> do
141+ js <- liftIO $ readFile (modulesDir </> "$PSCI" </> "index.js")
142+ evaluate js
143+
144+-- |
145+-- Takes a list of declarations and updates the environment, then run a make. If the declaration fails,
146+-- restore the original environment.
147+--
148+handleDecls
149+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
150+ => [P.Declaration]
151+ -> m ()
152+handleDecls ds = do
153+ st <- gets (updateLets (++ ds))
154+ let m = createTemporaryModule False st (P.Literal (P.ObjectLiteral []))
155+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
156+ case e of
157+ Left err -> printErrors err
158+ Right _ -> put st
159+
160+-- | Show actual loaded modules in psci.
161+handleShowLoadedModules
162+ :: (MonadState PSCiState m, MonadIO m)
163+ => m ()
164+handleShowLoadedModules = do
165+ loadedModules <- gets psciLoadedExterns
166+ liftIO $ putStrLn (readModules loadedModules)
167+ where
168+ readModules = unlines . sort . nub . map (P.runModuleName . P.getModuleName . fst)
169+
170+-- | Show the imported modules in psci.
171+handleShowImportedModules
172+ :: (MonadState PSCiState m, MonadIO m)
173+ => m ()
174+handleShowImportedModules = do
175+ PSCiState { psciImportedModules = importedModules } <- get
176+ liftIO $ showModules importedModules >>= putStrLn
177+ return ()
178+ where
179+ showModules = return . unlines . sort . map showModule
180+ showModule (mn, declType, asQ) =
181+ "import " ++ N.runModuleName mn ++ showDeclType declType ++
182+ foldMap (\mn' -> " as " ++ N.runModuleName mn') asQ
183+
184+ showDeclType P.Implicit = ""
185+ showDeclType (P.Explicit refs) = refsList refs
186+ showDeclType (P.Hiding refs) = " hiding " ++ refsList refs
187+ refsList refs = " (" ++ commaList (mapMaybe showRef refs) ++ ")"
188+
189+ showRef :: P.DeclarationRef -> Maybe String
190+ showRef (P.TypeRef pn dctors) =
191+ Just $ N.runProperName pn ++ "(" ++ maybe ".." (commaList . map N.runProperName) dctors ++ ")"
192+ showRef (P.TypeOpRef op) =
193+ Just $ "type " ++ N.showOp op
194+ showRef (P.ValueRef ident) =
195+ Just $ N.runIdent ident
196+ showRef (P.ValueOpRef op) =
197+ Just $ N.showOp op
198+ showRef (P.TypeClassRef pn) =
199+ Just $ "class " ++ N.runProperName pn
200+ showRef (P.TypeInstanceRef ident) =
201+ Just $ N.runIdent ident
202+ showRef (P.ModuleRef name) =
203+ Just $ "module " ++ N.runModuleName name
204+ showRef (P.ReExportRef _ _) =
205+ Nothing
206+ showRef (P.PositionedDeclarationRef _ _ ref) =
207+ showRef ref
208+
209+ commaList :: [String] -> String
210+ commaList = intercalate ", "
211+
212+-- | Imports a module, preserving the initial state on failure.
213+handleImport
214+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
215+ => ImportedModule
216+ -> m ()
217+handleImport im = do
218+ st <- gets (updateImportedModules (im :))
219+ let m = createTemporaryModuleForImports st
220+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
221+ case e of
222+ Left errs -> printErrors errs
223+ Right _ -> put st
224+
225+-- | Takes a value and prints its type
226+handleTypeOf
227+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
228+ => P.Expr
229+ -> m ()
230+handleTypeOf val = do
231+ st <- get
232+ let m = createTemporaryModule False st val
233+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
234+ case e of
235+ Left errs -> printErrors errs
236+ Right (_, env') ->
237+ case M.lookup (P.mkQualified (P.Ident "it") (P.ModuleName [P.ProperName "$PSCI"])) (P.names env') of
238+ Just (ty, _, _) -> liftIO . putStrLn . P.prettyPrintType $ ty
239+ Nothing -> liftIO $ putStrLn "Could not find type"
240+
241+-- | Takes a type and prints its kind
242+handleKindOf
243+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
244+ => P.Type
245+ -> m ()
246+handleKindOf typ = do
247+ st <- get
248+ let m = createTemporaryModuleForKind st typ
249+ mName = P.ModuleName [P.ProperName "$PSCI"]
250+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
251+ case e of
252+ Left errs -> printErrors errs
253+ Right (_, env') ->
254+ case M.lookup (P.Qualified (Just mName) $ P.ProperName "IT") (P.typeSynonyms env') of
255+ Just (_, typ') -> do
256+ let chk = (P.emptyCheckState env') { P.checkCurrentModule = Just mName }
257+ k = check (P.kindOf typ') chk
258+
259+ check :: StateT P.CheckState (ExceptT P.MultipleErrors (Writer P.MultipleErrors)) a -> P.CheckState -> Either P.MultipleErrors (a, P.CheckState)
260+ check sew = fst . runWriter . runExceptT . runStateT sew
261+ case k of
262+ Left err -> printErrors err
263+ Right (kind, _) -> liftIO . putStrLn . P.prettyPrintKind $ kind
264+ Nothing -> liftIO $ putStrLn "Could not find kind"
265+
266+-- | Browse a module and displays its signature
267+handleBrowse
268+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
269+ => P.ModuleName
270+ -> m ()
271+handleBrowse moduleName = do
272+ st <- get
273+ env <- asks psciEnvironment
274+ if isModInEnv moduleName st
275+ then liftIO . putStrLn $ printModuleSignatures moduleName env
276+ else case lookupUnQualifiedModName moduleName st of
277+ Just unQualifiedName ->
278+ if isModInEnv unQualifiedName st
279+ then liftIO . putStrLn $ printModuleSignatures unQualifiedName env
280+ else failNotInEnv moduleName
281+ Nothing ->
282+ failNotInEnv moduleName
283+ where
284+ isModInEnv modName =
285+ any ((== modName) . P.getModuleName . fst) . psciLoadedExterns
286+ failNotInEnv modName =
287+ liftIO $ putStrLn $ "Module '" ++ N.runModuleName modName ++ "' is not valid."
288+ lookupUnQualifiedModName quaModName st =
289+ (\(modName,_,_) -> modName) <$> find ( \(_, _, mayQuaName) -> mayQuaName == Just quaModName) (psciImportedModules st)
psci/PSCi/Completion.hs → src/Language/PureScript/Interactive/Completion.hsrenamed+77−81
@@ -1,36 +1,89 @@
1{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
2
2
3−module PSCi.Completion where
3+module Language.PureScript.Interactive.Completion
4+ ( CompletionM
5+ , liftCompletionM
6+ , completion
7+ , completion'
8+ ) where
4
9
5−import Prelude ()
6import Prelude.Compat
10import Prelude.Compat
7
11
8−import Data.Maybe (mapMaybe)
12+import Control.Arrow (second)
9−import Data.List (nub, nubBy, sortBy, isPrefixOf, stripPrefix)
13+import Control.Monad.IO.Class (MonadIO(..))
10−import Data.Char (isUpper)
14+import Control.Monad.State.Class (MonadState(..))
11−import Data.Function (on)
15+import Control.Monad.Trans.Reader (asks, runReaderT, ReaderT)
12−
16+import Data.Function (on)
13−import Control.Arrow (second)
17+import Data.List (nub, nubBy, isPrefixOf, sortBy, stripPrefix)
14−import Control.Monad.Trans.Reader (asks, runReaderT, ReaderT)
18+import Data.Maybe (mapMaybe)
15−import Control.Monad.Trans.State.Strict
16−
17−import System.Console.Haskeline
18−
19import qualified Language.PureScript as P
19import qualified Language.PureScript as P
20+import qualified Language.PureScript.Interactive.Directive as D
21+import Language.PureScript.Interactive.Types
20import qualified Language.PureScript.Names as N
22import qualified Language.PureScript.Names as N
21−
23+import System.Console.Haskeline
22−import qualified PSCi.Directive as D
23−import PSCi.Types
24
24
25-- Completions may read the state, but not modify it.
25-- Completions may read the state, but not modify it.
26type CompletionM = ReaderT PSCiState IO
26type CompletionM = ReaderT PSCiState IO
27
27
28−-- Lift a `CompletionM` action to a `StateT PSCiState IO` one.
28+-- Lift a `CompletionM` action into a state monad.
29−liftCompletionM :: CompletionM a -> StateT PSCiState IO a
29+liftCompletionM
30−liftCompletionM act = StateT (\s -> (\a -> (a, s)) <$> runReaderT act s)
30+ :: (MonadState PSCiState m, MonadIO m)
31+ => CompletionM a
32+ -> m a
33+liftCompletionM act = do
34+ st <- get
35+ liftIO $ runReaderT act st
31
36
32-- Haskeline completions
37-- Haskeline completions
33
38
39+-- | Loads module, function, and file completions.
40+completion
41+ :: (MonadState PSCiState m, MonadIO m)
42+ => CompletionFunc m
43+completion = liftCompletionM . completion'
44+
45+completion' :: CompletionFunc CompletionM
46+completion' = completeWordWithPrev Nothing " \t\n\r" findCompletions
47+
48+-- | Callback for Haskeline's `completeWordWithPrev`.
49+-- Expects:
50+-- * Line contents to the left of the word, reversed
51+-- * Word to be completed
52+findCompletions :: String -> String -> CompletionM [Completion]
53+findCompletions prev word = do
54+ let ctx = completionContext (words (reverse prev)) word
55+ completions <- concat <$> traverse getCompletions ctx
56+ return $ sortBy directivesFirst completions
57+ where
58+ getCompletions :: CompletionContext -> CompletionM [Completion]
59+ getCompletions = fmap (mapMaybe (either (prefixedBy word) Just)) . getCompletion
60+
61+ getCompletion :: CompletionContext -> CompletionM [Either String Completion]
62+ getCompletion ctx =
63+ case ctx of
64+ CtxFilePath f -> map Right <$> listFiles f
65+ CtxModule -> map Left <$> getModuleNames
66+ CtxIdentifier -> map Left <$> ((++) <$> getIdentNames <*> getDctorNames)
67+ CtxType -> map Left <$> getTypeNames
68+ CtxFixed str -> return [Left str]
69+ CtxDirective d -> return (map Left (completeDirectives d))
70+
71+ completeDirectives :: String -> [String]
72+ completeDirectives = map (':' :) . D.directiveStringsFor
73+
74+ prefixedBy :: String -> String -> Maybe Completion
75+ prefixedBy w cand = if w `isPrefixOf` cand
76+ then Just (simpleCompletion cand)
77+ else Nothing
78+
79+ directivesFirst :: Completion -> Completion -> Ordering
80+ directivesFirst (Completion _ d1 _) (Completion _ d2 _) = go d1 d2
81+ where
82+ go (':' : xs) (':' : ys) = compare xs ys
83+ go (':' : _) _ = LT
84+ go _ (':' : _) = GT
85+ go xs ys = compare xs ys
86+
34data CompletionContext
87data CompletionContext
35 = CtxDirective String
88 = CtxDirective String
36 | CtxFilePath String
89 | CtxFilePath String
@@ -38,16 +91,7 @@ data CompletionContext
38 | CtxIdentifier
91 | CtxIdentifier
39 | CtxType
92 | CtxType
40 | CtxFixed String
93 | CtxFixed String
41− deriving (Show, Read)
94+ deriving (Show)
42−
43−-- |
44−-- Loads module, function, and file completions.
45−--
46−completion :: CompletionFunc (StateT PSCiState IO)
47−completion = liftCompletionM . completion'
48−
49−completion' :: CompletionFunc CompletionM
50−completion' = completeWordWithPrev Nothing " \t\n\r" findCompletions
51
95
52-- |
96-- |
53-- Decide what kind of completion we need based on input. This function expects
97-- Decide what kind of completion we need based on input. This function expects
@@ -75,8 +119,6 @@ completeDirective ws w =
75
119
76directiveArg :: String -> Directive -> [CompletionContext]
120directiveArg :: String -> Directive -> [CompletionContext]
77directiveArg _ Browse = [CtxModule]
121directiveArg _ Browse = [CtxModule]
78−directiveArg w Load = [CtxFilePath w]
79−directiveArg w Foreign = [CtxFilePath w]
80directiveArg _ Quit = []
122directiveArg _ Quit = []
81directiveArg _ Reset = []
123directiveArg _ Reset = []
82directiveArg _ Help = []
124directiveArg _ Help = []
@@ -87,10 +129,8 @@ directiveArg _ Kind = [CtxType]
87completeImport :: [String] -> String -> [CompletionContext]
129completeImport :: [String] -> String -> [CompletionContext]
88completeImport ws w' =
130completeImport ws w' =
89 case (ws, w') of
131 case (ws, w') of
90− (["import"], w) | headSatisfies isUpper w -> [CtxModule]
132+ (["import"], _) -> [CtxModule]
91− (["import"], _) -> [CtxModule, CtxFixed "qualified"]
133+ _ -> []
92− (["import", "qualified"], _) -> [CtxModule]
93− _ -> []
94
134
95headSatisfies :: (a -> Bool) -> [a] -> Bool
135headSatisfies :: (a -> Bool) -> [a] -> Bool
96headSatisfies p str =
136headSatisfies p str =
@@ -98,44 +138,8 @@ headSatisfies p str =
98 (c:_) -> p c
138 (c:_) -> p c
99 _ -> False
139 _ -> False
100
140
101−-- | Callback for Haskeline's `completeWordWithPrev`.
102−-- Expects:
103−-- * Line contents to the left of the word, reversed
104−-- * Word to be completed
105−findCompletions :: String -> String -> CompletionM [Completion]
106−findCompletions prev word = do
107− let ctx = completionContext (words (reverse prev)) word
108− completions <- concat <$> traverse getCompletions ctx
109− return $ sortBy directivesFirst completions
110− where
111− getCompletions :: CompletionContext -> CompletionM [Completion]
112− getCompletions = fmap (mapMaybe (either (prefixedBy word) Just)) . getCompletion
113−
114− prefixedBy :: String -> String -> Maybe Completion
115− prefixedBy w cand = if w `isPrefixOf` cand
116− then Just (simpleCompletion cand)
117− else Nothing
118−
119−getCompletion :: CompletionContext -> CompletionM [Either String Completion]
120−getCompletion ctx =
121− case ctx of
122− CtxFilePath f -> map Right <$> listFiles f
123− CtxModule -> map Left <$> getModuleNames
124− CtxIdentifier -> map Left <$> ((++) <$> getIdentNames <*> getDctorNames)
125− CtxType -> map Left <$> getTypeNames
126− CtxFixed str -> return [Left str]
127− CtxDirective d -> return (map Left (completeDirectives d))
128−
129− where
130− completeDirectives :: String -> [String]
131− completeDirectives = map (':' :) . D.directiveStringsFor
132−
133−
134getLoadedModules :: CompletionM [P.Module]
141getLoadedModules :: CompletionM [P.Module]
135−getLoadedModules = asks (map snd . psciLoadedModules)
142+getLoadedModules = asks (map fst . psciLoadedExterns)
136−
137−getImportedModules :: CompletionM [ImportedModule]
138−getImportedModules = asks psciImportedModules
139
143
140getModuleNames :: CompletionM [String]
144getModuleNames :: CompletionM [String]
141getModuleNames = moduleNames <$> getLoadedModules
145getModuleNames = moduleNames <$> getLoadedModules
@@ -215,12 +219,4 @@ dctorNames = nubOnFst . concatMap go . P.exportedDeclarations
215 go _ = []
219 go _ = []
216
220
217moduleNames :: [P.Module] -> [String]
221moduleNames :: [P.Module] -> [String]
218−moduleNames ms = nub [P.runModuleName moduleName | P.Module _ _ moduleName _ _ <- ms]
222+moduleNames = nub . map (P.runModuleName . P.getModuleName)
219−
220−directivesFirst :: Completion -> Completion -> Ordering
221−directivesFirst (Completion _ d1 _) (Completion _ d2 _) = go d1 d2
222− where
223− go (':' : xs) (':' : ys) = compare xs ys
224− go (':' : _) _ = LT
225− go _ (':' : _) = GT
226− go xs ys = compare xs ys
psci/PSCi/Directive.hs → src/Language/PureScript/Interactive/Directive.hsrenamed+2−21
@@ -1,29 +1,15 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Directive
4−-- Copyright :
5−-- License : MIT
6−--
7−-- Maintainer :
8−-- Stability : experimental
9−-- Portability :
10−--
11-- |
1-- |
12-- Directives for PSCI.
2-- Directives for PSCI.
13--
3--
14−-----------------------------------------------------------------------------
4+module Language.PureScript.Interactive.Directive where
15
5
16−module PSCi.Directive where
17−
18−import Prelude ()
19import Prelude.Compat
6import Prelude.Compat
20
7
21−
22import Data.Maybe (fromJust, listToMaybe)
8import Data.Maybe (fromJust, listToMaybe)
23import Data.List (isPrefixOf)
9import Data.List (isPrefixOf)
24import Data.Tuple (swap)
10import Data.Tuple (swap)
25
11
26−import PSCi.Types
12+import Language.PureScript.Interactive.Types
27
13
28-- |
14-- |
29-- List of all avaliable directives.
15-- List of all avaliable directives.
@@ -41,8 +27,6 @@ directiveStrings =
41 , (Quit , ["quit"])
27 , (Quit , ["quit"])
42 , (Reset , ["reset"])
28 , (Reset , ["reset"])
43 , (Browse , ["browse"])
29 , (Browse , ["browse"])
44− , (Load , ["load", "module"])
45− , (Foreign, ["foreign"])
46 , (Type , ["type"])
30 , (Type , ["type"])
47 , (Kind , ["kind"])
31 , (Kind , ["kind"])
48 , (Show , ["show"])
32 , (Show , ["show"])
@@ -109,11 +93,8 @@ help =
109 , (Quit, "", "Quit PSCi")
93 , (Quit, "", "Quit PSCi")
110 , (Reset, "", "Discard all imported modules and declared bindings")
94 , (Reset, "", "Discard all imported modules and declared bindings")
111 , (Browse, "<module>", "See all functions in <module>")
95 , (Browse, "<module>", "See all functions in <module>")
112− , (Load, "<file>", "Load <file> for importing")
113− , (Foreign, "<file>", "Load foreign module <file>")
114 , (Type, "<expr>", "Show the type of <expr>")
96 , (Type, "<expr>", "Show the type of <expr>")
115 , (Kind, "<type>", "Show the kind of <type>")
97 , (Kind, "<type>", "Show the kind of <type>")
116 , (Show, "import", "Show all imported modules")
98 , (Show, "import", "Show all imported modules")
117 , (Show, "loaded", "Show all loaded modules")
99 , (Show, "loaded", "Show all loaded modules")
118 ]
100 ]
119−
psci/PSCi/IO.hs → src/Language/PureScript/Interactive/IO.hsrenamed+4−31
@@ -1,28 +1,11 @@
1−-----------------------------------------------------------------------------
1+module Language.PureScript.Interactive.IO where
2−--
3−-- Module : IO
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−--
13−-----------------------------------------------------------------------------
14−
15−module PSCi.IO where
16
2
17−import Prelude ()
18import Prelude.Compat
3import Prelude.Compat
19
4
20−import System.Directory (createDirectoryIfMissing, getHomeDirectory, findExecutable, doesFileExist)
21−import System.FilePath (takeDirectory, (</>), isPathSeparator)
22−import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
23import Control.Monad (msum)
5import Control.Monad (msum)
24−import Control.Monad.IO.Class (MonadIO, liftIO)
6+import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
25−import System.Console.Haskeline (outputStrLn, InputT)
7+import System.Directory (createDirectoryIfMissing, getHomeDirectory, findExecutable)
8+import System.FilePath (takeDirectory, (</>), isPathSeparator)
26
9
27mkdirp :: FilePath -> IO ()
10mkdirp :: FilePath -> IO ()
28mkdirp = createDirectoryIfMissing True . takeDirectory
11mkdirp = createDirectoryIfMissing True . takeDirectory
@@ -50,19 +33,9 @@ getHistoryFilename = do
50 mkdirp filename
33 mkdirp filename
51 return filename
34 return filename
52
35
53−
54-- |
36-- |
55-- Expands tilde in path.
37-- Expands tilde in path.
56--
38--
57expandTilde :: FilePath -> IO FilePath
39expandTilde :: FilePath -> IO FilePath
58expandTilde ('~':p:rest) | isPathSeparator p = (</> rest) <$> getHomeDirectory
40expandTilde ('~':p:rest) | isPathSeparator p = (</> rest) <$> getHomeDirectory
59expandTilde p = return p
41expandTilde p = return p
60−
61−
62−whenFileExists :: MonadIO m => FilePath -> (FilePath -> InputT m ()) -> InputT m ()
63−whenFileExists filePath f = do
64− absPath <- liftIO $ expandTilde filePath
65− exists <- liftIO $ doesFileExist absPath
66− if exists
67− then f absPath
68− else outputStrLn $ "Couldn't locate: " ++ filePath
src/Language/PureScript/Interactive/Message.hsnew file+52
@@ -0,0 +1,52 @@
1+module Language.PureScript.Interactive.Message where
2+
3+import Prelude.Compat
4+
5+import Data.List (intercalate)
6+import Data.Version (showVersion)
7+import qualified Paths_purescript as Paths
8+import qualified Language.PureScript.Interactive.Directive as D
9+import Language.PureScript.Interactive.Types
10+
11+-- Messages
12+
13+-- | The help message.
14+helpMessage :: String
15+helpMessage = "The following commands are available:\n\n " ++
16+ intercalate "\n " (map line D.help) ++
17+ "\n\n" ++ extraHelp
18+ where
19+ line :: (Directive, String, String) -> String
20+ line (dir, arg, desc) =
21+ let cmd = ':' : D.stringFor dir
22+ in unwords [ cmd
23+ , replicate (11 - length cmd) ' '
24+ , arg
25+ , replicate (11 - length arg) ' '
26+ , desc
27+ ]
28+
29+ extraHelp =
30+ "Further information is available on the PureScript wiki:\n" ++
31+ " --> https://github.com/purescript/purescript/wiki/psci"
32+
33+-- | The welcome prologue.
34+prologueMessage :: String
35+prologueMessage = unlines
36+ [ "PSCi, version " ++ showVersion Paths.version
37+ , "Type :? for help"
38+ ]
39+
40+supportModuleMessage :: String
41+supportModuleMessage = unlines
42+ [ "PSCi requires the purescript-psci-support package to be installed."
43+ , "You can install it using Bower as follows:"
44+ , ""
45+ , " bower i purescript-psci-support --save-dev"
46+ , ""
47+ , "For help getting started, visit http://wiki.purescript.org/PSCi"
48+ ]
49+
50+-- | The quit message.
51+quitMessage :: String
52+quitMessage = "See ya!"
src/Language/PureScript/Interactive/Module.hsnew file+99
@@ -0,0 +1,99 @@
1+module Language.PureScript.Interactive.Module where
2+
3+import Prelude.Compat
4+
5+import Control.Monad
6+import qualified Language.PureScript as P
7+import Language.PureScript.Interactive.Types
8+import System.FilePath (pathSeparator)
9+import System.IO.UTF8 (readUTF8File)
10+
11+-- * Support Module
12+
13+-- | The name of the PSCI support module
14+supportModuleName :: P.ModuleName
15+supportModuleName = P.moduleNameFromString "PSCI.Support"
16+
17+-- | Checks if the Console module is defined
18+supportModuleIsDefined :: [P.Module] -> Bool
19+supportModuleIsDefined = any ((== supportModuleName) . P.getModuleName)
20+
21+-- * Module Management
22+
23+-- |
24+-- Loads a file for use with imports.
25+--
26+loadModule :: FilePath -> IO (Either String [P.Module])
27+loadModule filename = do
28+ content <- readUTF8File filename
29+ return $ either (Left . P.prettyPrintMultipleErrors P.defaultPPEOptions) (Right . map snd) $ P.parseModulesFromFiles id [(filename, content)]
30+
31+-- |
32+-- Load all modules.
33+--
34+loadAllModules :: [FilePath] -> IO (Either P.MultipleErrors [(FilePath, P.Module)])
35+loadAllModules files = do
36+ filesAndContent <- forM files $ \filename -> do
37+ content <- readUTF8File filename
38+ return (filename, content)
39+ return $ P.parseModulesFromFiles id filesAndContent
40+
41+-- |
42+-- Makes a volatile module to execute the current expression.
43+--
44+createTemporaryModule :: Bool -> PSCiState -> P.Expr -> P.Module
45+createTemporaryModule exec PSCiState{psciImportedModules = imports, psciLetBindings = lets} val =
46+ let
47+ moduleName = P.ModuleName [P.ProperName "$PSCI"]
48+ effModuleName = P.moduleNameFromString "Control.Monad.Eff"
49+ effImport = (effModuleName, P.Implicit, Just (P.ModuleName [P.ProperName "$Eff"]))
50+ supportImport = (supportModuleName, P.Implicit, Just (P.ModuleName [P.ProperName "$Support"]))
51+ eval = P.Var (P.Qualified (Just (P.ModuleName [P.ProperName "$Support"])) (P.Ident "eval"))
52+ mainValue = P.App eval (P.Var (P.Qualified Nothing (P.Ident "it")))
53+ itDecl = P.ValueDeclaration (P.Ident "it") P.Public [] $ Right val
54+ typeDecl = P.TypeDeclaration (P.Ident "$main")
55+ (P.TypeApp
56+ (P.TypeApp
57+ (P.TypeConstructor
58+ (P.Qualified (Just (P.ModuleName [P.ProperName "$Eff"])) (P.ProperName "Eff")))
59+ (P.TypeWildcard internalSpan))
60+ (P.TypeWildcard internalSpan))
61+ mainDecl = P.ValueDeclaration (P.Ident "$main") P.Public [] $ Right mainValue
62+ decls = if exec then [itDecl, typeDecl, mainDecl] else [itDecl]
63+ internalSpan = P.internalModuleSourceSpan "<internal>"
64+ in
65+ P.Module internalSpan
66+ [] moduleName
67+ ((importDecl `map` (effImport : supportImport : imports)) ++ lets ++ decls)
68+ Nothing
69+
70+
71+-- |
72+-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
73+--
74+createTemporaryModuleForKind :: PSCiState -> P.Type -> P.Module
75+createTemporaryModuleForKind PSCiState{psciImportedModules = imports, psciLetBindings = lets} typ =
76+ let
77+ moduleName = P.ModuleName [P.ProperName "$PSCI"]
78+ itDecl = P.TypeSynonymDeclaration (P.ProperName "IT") [] typ
79+ in
80+ P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ [itDecl]) Nothing
81+
82+-- |
83+-- Makes a volatile module to execute the current imports.
84+--
85+createTemporaryModuleForImports :: PSCiState -> P.Module
86+createTemporaryModuleForImports PSCiState{psciImportedModules = imports} =
87+ let
88+ moduleName = P.ModuleName [P.ProperName "$PSCI"]
89+ in
90+ P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName (importDecl `map` imports) Nothing
91+
92+importDecl :: ImportedModule -> P.Declaration
93+importDecl (mn, declType, asQ) = P.ImportDeclaration mn declType asQ
94+
95+indexFile :: FilePath
96+indexFile = ".psci_modules" ++ pathSeparator : "index.js"
97+
98+modulesDir :: FilePath
99+modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
psci/PSCi/Parser.hs → src/Language/PureScript/Interactive/Parser.hsrenamed+9−27
@@ -1,35 +1,19 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Parser
4−-- Copyright : (c) Phil Freeman 2014
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11-- |
1-- |
12-- Parser for PSCI.
2-- Parser for PSCI.
13--
3--
14−-----------------------------------------------------------------------------
4+module Language.PureScript.Interactive.Parser
15−
16−module PSCi.Parser
17 ( parseCommand
5 ( parseCommand
18 ) where
6 ) where
19
7
20−import Prelude ()
8+import Prelude.Compat hiding (lex)
21−import Prelude.Compat hiding (lex)
22−
23−import Data.Char (isSpace)
24−import Data.List (intercalate)
25−
26−import Text.Parsec hiding ((<|>))
27
9
10+import Data.Char (isSpace)
11+import Data.List (intercalate)
12+import Text.Parsec hiding ((<|>))
28import qualified Language.PureScript as P
13import qualified Language.PureScript as P
29−import Language.PureScript.Parser.Common (mark, same)
14+import qualified Language.PureScript.Interactive.Directive as D
30−
15+import Language.PureScript.Interactive.Types
31−import qualified PSCi.Directive as D
16+import Language.PureScript.Parser.Common (mark, same)
32−import PSCi.Types
33
17
34-- |
18-- |
35-- Parses PSCI metacommands or expressions input from the user.
19-- Parses PSCI metacommands or expressions input from the user.
@@ -79,8 +63,6 @@ parseDirective cmd =
79 Quit -> return QuitPSCi
63 Quit -> return QuitPSCi
80 Reset -> return ResetState
64 Reset -> return ResetState
81 Browse -> BrowseModule <$> parseRest P.moduleName arg
65 Browse -> BrowseModule <$> parseRest P.moduleName arg
82− Load -> return $ LoadFile (trim arg)
83− Foreign -> return $ LoadForeign (trim arg)
84 Show -> ShowInfo <$> parseReplQuery' (trim arg)
66 Show -> ShowInfo <$> parseReplQuery' (trim arg)
85 Type -> TypeOf <$> parseRest P.parseValue arg
67 Type -> TypeOf <$> parseRest P.parseValue arg
86 Kind -> KindOf <$> parseRest P.parseType arg
68 Kind -> KindOf <$> parseRest P.parseType arg
@@ -107,7 +89,7 @@ psciLet = Decls <$> (P.reserved "let" *> P.indented *> manyDecls)
107-- :show import works, for example.
89-- :show import works, for example.
108psciImport :: P.TokenParser Command
90psciImport :: P.TokenParser Command
109psciImport = do
91psciImport = do
110− (mn, declType, asQ, _) <- P.parseImportDeclaration'
92+ (mn, declType, asQ) <- P.parseImportDeclaration'
111 return $ Import (mn, declType, asQ)
93 return $ Import (mn, declType, asQ)
112
94
113-- | Any other declaration that we don't need a 'special case' parser for
95-- | Any other declaration that we don't need a 'special case' parser for
psci/PSCi/Printer.hs → src/Language/PureScript/Interactive/Printer.hsrenamed+16−20
@@ -1,34 +1,32 @@
1{-# LANGUAGE RecordWildCards #-}
1{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
3
3
4−module PSCi.Printer where
4+module Language.PureScript.Interactive.Printer where
5
5
6−import Prelude ()
6+import Prelude.Compat
7−import Prelude.Compat
8
7
8+import Data.List (intersperse)
9+import qualified Data.Map as M
10+import Data.Maybe (mapMaybe)
9import qualified Language.PureScript as P
11import qualified Language.PureScript as P
10import qualified Text.PrettyPrint.Boxes as Box
12import qualified Text.PrettyPrint.Boxes as Box
11−import qualified Data.Map as M
12−import System.Console.Haskeline
13−import Data.Maybe (mapMaybe)
14−import Data.List (intersperse)
15−import Control.Monad.IO.Class (MonadIO)
16
13
17-- Printers
14-- Printers
18
15
19-- |
16-- |
20-- Pretty print a module's signatures
17-- Pretty print a module's signatures
21--
18--
22−printModuleSignatures :: MonadIO m => P.ModuleName -> P.Environment -> InputT m ()
19+printModuleSignatures :: P.ModuleName -> P.Environment -> String
23printModuleSignatures moduleName (P.Environment {..}) =
20printModuleSignatures moduleName (P.Environment {..}) =
24 -- get relevant components of a module from environment
21 -- get relevant components of a module from environment
25− let moduleNamesIdent = (filter ((== moduleName) . fst) . M.keys) names
22+ let moduleNamesIdent = byModuleName names
26− moduleTypeClasses = (filter (\(P.Qualified maybeName _) -> maybeName == Just moduleName) . M.keys) typeClasses
23+ moduleTypeClasses = byModuleName typeClasses
27− moduleTypes = (filter (\(P.Qualified maybeName _) -> maybeName == Just moduleName) . M.keys) types
24+ moduleTypes = byModuleName types
25+ byModuleName = filter ((== Just moduleName) . P.getQual) . M.keys
28
26
29 in
27 in
30 -- print each component
28 -- print each component
31− (outputStr . unlines . map trimEnd . lines . Box.render . Box.vsep 1 Box.left)
29+ (unlines . map trimEnd . lines . Box.render . Box.vsep 1 Box.left)
32 [ printModule's (mapMaybe (showTypeClass . findTypeClass typeClasses)) moduleTypeClasses -- typeClasses
30 [ printModule's (mapMaybe (showTypeClass . findTypeClass typeClasses)) moduleTypeClasses -- typeClasses
33 , printModule's (mapMaybe (showType typeClasses dataConstructors typeSynonyms . findType types)) moduleTypes -- types
31 , printModule's (mapMaybe (showType typeClasses dataConstructors typeSynonyms . findType types)) moduleTypes -- types
34 , printModule's (map (showNameType . findNameType names)) moduleNamesIdent -- functions
32 , printModule's (map (showNameType . findNameType names)) moduleNamesIdent -- functions
@@ -36,8 +34,10 @@ printModuleSignatures moduleName (P.Environment {..}) =
36
34
37 where printModule's showF = Box.vsep 1 Box.left . showF
35 where printModule's showF = Box.vsep 1 Box.left . showF
38
36
39− findNameType :: M.Map (P.ModuleName, P.Ident) (P.Type, P.NameKind, P.NameVisibility) -> (P.ModuleName, P.Ident) -> (P.Ident, Maybe (P.Type, P.NameKind, P.NameVisibility))
37+ findNameType :: M.Map (P.Qualified P.Ident) (P.Type, P.NameKind, P.NameVisibility)
40− findNameType envNames m@(_, mIdent) = (mIdent, M.lookup m envNames)
38+ -> P.Qualified P.Ident
39+ -> (P.Ident, Maybe (P.Type, P.NameKind, P.NameVisibility))
40+ findNameType envNames m = (P.disqualify m, M.lookup m envNames)
41
41
42 showNameType :: (P.Ident, Maybe (P.Type, P.NameKind, P.NameVisibility)) -> Box.Box
42 showNameType :: (P.Ident, Maybe (P.Type, P.NameKind, P.NameVisibility)) -> Box.Box
43 showNameType (mIdent, Just (mType, _, _)) = Box.text (P.showIdent mIdent ++ " :: ") Box.<> P.typeAsBox mType
43 showNameType (mIdent, Just (mType, _, _)) = Box.text (P.showIdent mIdent ++ " :: ") Box.<> P.typeAsBox mType
@@ -58,7 +58,7 @@ printModuleSignatures moduleName (P.Environment {..}) =
58 if null constrs
58 if null constrs
59 then Box.text ""
59 then Box.text ""
60 else Box.text "("
60 else Box.text "("
61− Box.<> Box.hcat Box.left (intersperse (Box.text ", ") $ map (\(P.Qualified _ pn, lt) -> Box.text (P.runProperName pn) Box.<+> Box.hcat Box.left (map P.typeAtomAsBox lt)) constrs)
61+ Box.<> Box.hcat Box.left (intersperse (Box.text ", ") $ map (\(P.Constraint (P.Qualified _ pn) lt _) -> Box.text (P.runProperName pn) Box.<+> Box.hcat Box.left (map P.typeAtomAsBox lt)) constrs)
62 Box.<> Box.text ") <= "
62 Box.<> Box.text ") <= "
63 className =
63 className =
64 Box.text (P.runProperName name)
64 Box.text (P.runProperName name)
@@ -125,7 +125,3 @@ printModuleSignatures moduleName (P.Environment {..}) =
125 mapFirstRest f g (x:xs) = f x : map g xs
125 mapFirstRest f g (x:xs) = f x : map g xs
126
126
127 trimEnd = reverse . dropWhile (== ' ') . reverse
127 trimEnd = reverse . dropWhile (== ' ') . reverse
128−
129−-- | Pretty-print errors
130−printErrors :: MonadIO m => P.MultipleErrors -> InputT m ()
131−printErrors = outputStrLn . P.prettyPrintMultipleErrors False
src/Language/PureScript/Interactive/Types.hsnew file+145
@@ -0,0 +1,145 @@
1+-- |
2+-- Type declarations and associated basic functions for PSCI.
3+--
4+module Language.PureScript.Interactive.Types where
5+
6+import Prelude.Compat
7+
8+import qualified Language.PureScript as P
9+
10+-- | The PSCI configuration.
11+--
12+-- These configuration values do not change during execution.
13+--
14+data PSCiConfig = PSCiConfig
15+ { psciLoadedFiles :: [FilePath]
16+ , psciEnvironment :: P.Environment
17+ } deriving Show
18+
19+-- | The PSCI state.
20+--
21+-- Holds a list of imported modules, loaded files, and partial let bindings.
22+-- The let bindings are partial,
23+-- because it makes more sense to apply the binding to the final evaluated expression.
24+data PSCiState = PSCiState
25+ { psciImportedModules :: [ImportedModule]
26+ , psciLetBindings :: [P.Declaration]
27+ , psciLoadedExterns :: [(P.Module, P.ExternsFile)]
28+ } deriving Show
29+
30+initialPSCiState :: PSCiState
31+initialPSCiState = PSCiState [] [] []
32+
33+-- | All of the data that is contained by an ImportDeclaration in the AST.
34+-- That is:
35+--
36+-- * A module name, the name of the module which is being imported
37+-- * An ImportDeclarationType which specifies whether there is an explicit
38+-- import list, a hiding list, or neither.
39+-- * If the module is imported qualified, its qualified name in the importing
40+-- module. Otherwise, Nothing.
41+--
42+type ImportedModule = (P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)
43+
44+psciImportedModuleNames :: PSCiState -> [P.ModuleName]
45+psciImportedModuleNames (PSCiState{psciImportedModules = is}) =
46+ map (\(mn, _, _) -> mn) is
47+
48+allImportsOf :: P.Module -> PSCiState -> [ImportedModule]
49+allImportsOf m (PSCiState{psciImportedModules = is}) =
50+ filter isImportOfThis is
51+ where
52+ name = P.getModuleName m
53+ isImportOfThis (name', _, _) = name == name'
54+
55+-- * State helpers
56+
57+-- | Updates the imported modules in the state record.
58+updateImportedModules :: ([ImportedModule] -> [ImportedModule]) -> PSCiState -> PSCiState
59+updateImportedModules f st = st { psciImportedModules = f (psciImportedModules st) }
60+
61+-- | Updates the loaded externs files in the state record.
62+updateLoadedExterns :: ([(P.Module, P.ExternsFile)] -> [(P.Module, P.ExternsFile)]) -> PSCiState -> PSCiState
63+updateLoadedExterns f st = st { psciLoadedExterns = f (psciLoadedExterns st) }
64+
65+-- | Updates the let bindings in the state record.
66+updateLets :: ([P.Declaration] -> [P.Declaration]) -> PSCiState -> PSCiState
67+updateLets f st = st { psciLetBindings = f (psciLetBindings st) }
68+
69+-- * Commands
70+
71+-- |
72+-- Valid Meta-commands for PSCI
73+--
74+data Command
75+ -- |
76+ -- A purescript expression
77+ --
78+ = Expression P.Expr
79+ -- |
80+ -- Show the help (ie, list of directives)
81+ --
82+ | ShowHelp
83+ -- |
84+ -- Import a module from a loaded file
85+ --
86+ | Import ImportedModule
87+ -- |
88+ -- Browse a module
89+ --
90+ | BrowseModule P.ModuleName
91+ -- |
92+ -- Exit PSCI
93+ --
94+ | QuitPSCi
95+ -- |
96+ -- Reset the state of the REPL
97+ --
98+ | ResetState
99+ -- |
100+ -- Add some declarations to the current evaluation context.
101+ --
102+ | Decls [P.Declaration]
103+ -- |
104+ -- Find the type of an expression
105+ --
106+ | TypeOf P.Expr
107+ -- |
108+ -- Find the kind of an expression
109+ --
110+ | KindOf P.Type
111+ -- |
112+ -- Shows information about the current state of the REPL
113+ --
114+ | ShowInfo ReplQuery
115+
116+data ReplQuery
117+ = QueryLoaded
118+ | QueryImport
119+ deriving (Eq, Show)
120+
121+-- | A list of all ReplQuery values.
122+replQueries :: [ReplQuery]
123+replQueries = [QueryLoaded, QueryImport]
124+
125+replQueryStrings :: [String]
126+replQueryStrings = map showReplQuery replQueries
127+
128+showReplQuery :: ReplQuery -> String
129+showReplQuery QueryLoaded = "loaded"
130+showReplQuery QueryImport = "import"
131+
132+parseReplQuery :: String -> Maybe ReplQuery
133+parseReplQuery "loaded" = Just QueryLoaded
134+parseReplQuery "import" = Just QueryImport
135+parseReplQuery _ = Nothing
136+
137+data Directive
138+ = Help
139+ | Quit
140+ | Reset
141+ | Browse
142+ | Type
143+ | Kind
144+ | Show
145+ deriving (Eq, Show)
src/Language/PureScript/Kinds.hs+9−20
@@ -2,36 +2,25 @@
2
2
3module Language.PureScript.Kinds where
3module Language.PureScript.Kinds where
4
4
5−import Prelude ()
6import Prelude.Compat
5import Prelude.Compat
7
6
8import qualified Data.Aeson.TH as A
7import qualified Data.Aeson.TH as A
9
8
10−-- |
9+-- | The data type of kinds
11−-- The data type of kinds
12−--
13data Kind
10data Kind
14− -- |
11+ -- | Unification variable of type Kind
15− -- Unification variable of type Kind
16− --
17 = KUnknown Int
12 = KUnknown Int
18− -- |
13+ -- | The kind of types
19− -- The kind of types
20− --
21 | Star
14 | Star
22− -- |
15+ -- | The kind of effects
23− -- The kind of effects
24− --
25 | Bang
16 | Bang
26− -- |
17+ -- | Kinds for labelled, unordered rows without duplicates
27− -- Kinds for labelled, unordered rows without duplicates
28− --
29 | Row Kind
18 | Row Kind
30− -- |
19+ -- | Function kinds
31− -- Function kinds
32− --
33 | FunKind Kind Kind
20 | FunKind Kind Kind
34− deriving (Show, Read, Eq, Ord)
21+ -- | Type-level strings
22+ | Symbol
23+ deriving (Show, Eq, Ord)
35
24
36$(A.deriveJSON A.defaultOptions ''Kind)
25$(A.deriveJSON A.defaultOptions ''Kind)
37
26
src/Language/PureScript/Linter.hs+6−23
@@ -1,30 +1,24 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE PatternGuards #-}
4−
5-- |
1-- |
6-- This module implements a simple linting pass on the PureScript AST.
2-- This module implements a simple linting pass on the PureScript AST.
7--
3--
8module Language.PureScript.Linter (lint, module L) where
4module Language.PureScript.Linter (lint, module L) where
9
5
10−import Prelude ()
11import Prelude.Compat
6import Prelude.Compat
12
7
8+import Control.Monad.Writer.Class
9+
13import Data.List (nub, (\\))
10import Data.List (nub, (\\))
14import Data.Maybe (mapMaybe)
11import Data.Maybe (mapMaybe)
15import Data.Monoid
12import Data.Monoid
16−
17import qualified Data.Set as S
13import qualified Data.Set as S
18
14
19−import Control.Monad.Writer.Class
20−
21−import Language.PureScript.Crash
22import Language.PureScript.AST
15import Language.PureScript.AST
23−import Language.PureScript.Names
16+import Language.PureScript.Crash
24import Language.PureScript.Errors
17import Language.PureScript.Errors
25−import Language.PureScript.Types
26import Language.PureScript.Linter.Exhaustive as L
18import Language.PureScript.Linter.Exhaustive as L
27import Language.PureScript.Linter.Imports as L
19import Language.PureScript.Linter.Imports as L
20+import Language.PureScript.Names
21+import Language.PureScript.Types
28
22
29-- | Lint the PureScript AST.
23-- | Lint the PureScript AST.
30-- |
24-- |
@@ -46,7 +40,7 @@ lint (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ mapM_ lintDecl
46 lintDeclaration :: Declaration -> m ()
40 lintDeclaration :: Declaration -> m ()
47 lintDeclaration = tell . f
41 lintDeclaration = tell . f
48 where
42 where
49− (warningsInDecl, _, _, _, _) = everythingWithScope stepD stepE stepB (\_ _ -> mempty) stepDo
43+ (warningsInDecl, _, _, _, _) = everythingWithScope (\_ _ -> mempty) stepE stepB (\_ _ -> mempty) stepDo
50
44
51 f :: Declaration -> MultipleErrors
45 f :: Declaration -> MultipleErrors
52 f (PositionedDeclaration pos _ dec) = addHint (PositionedError pos) (f dec)
46 f (PositionedDeclaration pos _ dec) = addHint (PositionedError pos) (f dec)
@@ -54,16 +48,6 @@ lint (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ mapM_ lintDecl
54 f (TypeDeclaration name ty) = addHint (ErrorInTypeDeclaration name) (checkTypeVars ty)
48 f (TypeDeclaration name ty) = addHint (ErrorInTypeDeclaration name) (checkTypeVars ty)
55 f dec = warningsInDecl moduleNames dec <> checkTypeVarsInDecl dec
49 f dec = warningsInDecl moduleNames dec <> checkTypeVarsInDecl dec
56
50
57− stepD :: S.Set Ident -> Declaration -> MultipleErrors
58− stepD _ (ValueDeclaration (Op name) _ _ _) = errorMessage (DeprecatedOperatorDecl name)
59− stepD _ (TypeClassDeclaration _ _ _ decls) = foldMap go decls
60− where
61− go :: Declaration -> MultipleErrors
62− go (PositionedDeclaration _ _ d') = go d'
63− go (TypeDeclaration (Op name) _) = errorMessage (DeprecatedOperatorDecl name)
64− go _ = mempty
65− stepD _ _ = mempty
66−
67 stepE :: S.Set Ident -> Expr -> MultipleErrors
51 stepE :: S.Set Ident -> Expr -> MultipleErrors
68 stepE s (Abs (Left name) _) | name `S.member` s = errorMessage (ShadowedName name)
52 stepE s (Abs (Left name) _) | name `S.member` s = errorMessage (ShadowedName name)
69 stepE s (Let ds' _) = foldMap go ds'
53 stepE s (Let ds' _) = foldMap go ds'
@@ -71,7 +55,6 @@ lint (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ mapM_ lintDecl
71 go d | Just i <- getDeclIdent d
55 go d | Just i <- getDeclIdent d
72 , i `S.member` s = errorMessage (ShadowedName i)
56 , i `S.member` s = errorMessage (ShadowedName i)
73 | otherwise = mempty
57 | otherwise = mempty
74− stepE _ (OperatorSection op val) = errorMessage $ DeprecatedOperatorSection op val
75 stepE _ _ = mempty
58 stepE _ _ = mempty
76
59
77 stepB :: S.Set Ident -> Binder -> MultipleErrors
60 stepB :: S.Set Ident -> Binder -> MultipleErrors
src/Language/PureScript/Linter/Exhaustive.hs+110−79
@@ -1,36 +1,38 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4-- |
1-- |
5-- Module for exhaustivity checking over pattern matching definitions
2-- Module for exhaustivity checking over pattern matching definitions
6-- The algorithm analyses the clauses of a definition one by one from top
3-- The algorithm analyses the clauses of a definition one by one from top
7-- to bottom, where in each step it has the cases already missing (uncovered),
4-- to bottom, where in each step it has the cases already missing (uncovered),
8-- and it generates the new set of missing cases.
5-- and it generates the new set of missing cases.
9--
6--
10−module Language.PureScript.Linter.Exhaustive (checkExhaustiveModule) where
7+module Language.PureScript.Linter.Exhaustive
8+ ( checkExhaustiveExpr
9+ ) where
11
10
12−import Prelude ()
13import Prelude.Compat
11import Prelude.Compat
14
12
15−import qualified Data.Map as M
16−import Data.Maybe (fromMaybe)
17−import Data.List (foldl', sortBy, nub)
18−import Data.Function (on)
19−
20−import Control.Monad (unless)
21import Control.Applicative
13import Control.Applicative
22import Control.Arrow (first, second)
14import Control.Arrow (first, second)
15+import Control.Monad (unless)
23import Control.Monad.Writer.Class
16import Control.Monad.Writer.Class
17+import Control.Monad.Supply.Class (MonadSupply, fresh, freshName)
18+
19+import Data.Function (on)
20+import Data.List (foldl', sortBy, nub)
21+import Data.Maybe (fromMaybe)
22+import qualified Data.Map as M
24
23
25−import Language.PureScript.Crash
26import Language.PureScript.AST.Binders
24import Language.PureScript.AST.Binders
27−import Language.PureScript.AST.Literals
28import Language.PureScript.AST.Declarations
25import Language.PureScript.AST.Declarations
26+import Language.PureScript.AST.Literals
27+import Language.PureScript.Crash
29import Language.PureScript.Environment
28import Language.PureScript.Environment
30−import Language.PureScript.Names as P
29+import Language.PureScript.Errors
31import Language.PureScript.Kinds
30import Language.PureScript.Kinds
31+import Language.PureScript.Names as P
32+import Language.PureScript.Pretty.Values (prettyPrintBinderAtom)
33+import Language.PureScript.Traversals
32import Language.PureScript.Types as P
34import Language.PureScript.Types as P
33−import Language.PureScript.Errors
35+import qualified Language.PureScript.Constants as C
34
36
35-- | There are two modes of failure for the redundancy check:
37-- | There are two modes of failure for the redundancy check:
36--
38--
@@ -44,7 +46,7 @@ data RedundancyError = Incomplete | Unknown
44-- Qualifies a propername from a given qualified propername and a default module name
46-- Qualifies a propername from a given qualified propername and a default module name
45--
47--
46qualifyName
48qualifyName
47− :: (ProperName a)
49+ :: ProperName a
48 -> ModuleName
50 -> ModuleName
49 -> Qualified (ProperName b)
51 -> Qualified (ProperName b)
50 -> Qualified (ProperName a)
52 -> Qualified (ProperName a)
@@ -138,7 +140,7 @@ missingCasesSingle env mn (LiteralBinder (ObjectLiteral bs)) (LiteralBinder (Obj
138 where
140 where
139 fm = fromMaybe e
141 fm = fromMaybe e
140
142
141− compBS :: Eq a => b -> a -> Maybe b -> Maybe b -> (a, (b, b))
143+ compBS :: b -> a -> Maybe b -> Maybe b -> (a, (b, b))
142 compBS e s b b' = (s, compB e b b')
144 compBS e s b b' = (s, compB e b b')
143
145
144 (sortedNames, binders) = unzip $ genericMerge (compBS NullBinder) sbs sbs'
146 (sortedNames, binders) = unzip $ genericMerge (compBS NullBinder) sbs sbs'
@@ -179,12 +181,11 @@ missingCasesSingle _ _ b _ = ([b], Left Unknown)
179missingCasesMultiple :: Environment -> ModuleName -> [Binder] -> [Binder] -> ([[Binder]], Either RedundancyError Bool)
181missingCasesMultiple :: Environment -> ModuleName -> [Binder] -> [Binder] -> ([[Binder]], Either RedundancyError Bool)
180missingCasesMultiple env mn = go
182missingCasesMultiple env mn = go
181 where
183 where
182− go [] [] = ([], pure True)
183 go (x:xs) (y:ys) = (map (: xs) miss1 ++ map (x :) miss2, liftA2 (&&) pr1 pr2)
184 go (x:xs) (y:ys) = (map (: xs) miss1 ++ map (x :) miss2, liftA2 (&&) pr1 pr2)
184 where
185 where
185 (miss1, pr1) = missingCasesSingle env mn x y
186 (miss1, pr1) = missingCasesSingle env mn x y
186 (miss2, pr2) = go xs ys
187 (miss2, pr2) = go xs ys
187− go _ _ = internalError "Argument lengths did not match in missingCasesMultiple."
188+ go _ _ = ([], pure True)
188
189
189-- |
190-- |
190-- Guard handling
191-- Guard handling
@@ -229,8 +230,16 @@ missingAlternative env mn ca uncovered
229-- it partitions that set with the new uncovered cases, until it consumes the whole set of clauses.
230-- it partitions that set with the new uncovered cases, until it consumes the whole set of clauses.
230-- Then, returns the uncovered set of case alternatives.
231-- Then, returns the uncovered set of case alternatives.
231--
232--
232−checkExhaustive :: forall m. (MonadWriter MultipleErrors m) => Bool -> Environment -> ModuleName -> Int -> [CaseAlternative] -> m ()
233+checkExhaustive
233−checkExhaustive hasConstraint env mn numArgs cas = makeResult . first nub $ foldl' step ([initialize numArgs], (pure True, [])) cas
234+ :: forall m
235+ . (MonadWriter MultipleErrors m, MonadSupply m)
236+ => Environment
237+ -> ModuleName
238+ -> Int
239+ -> [CaseAlternative]
240+ -> Expr
241+ -> m Expr
242+checkExhaustive env mn numArgs cas expr = makeResult . first nub $ foldl' step ([initialize numArgs], (pure True, [])) cas
234 where
243 where
235 step :: ([[Binder]], (Either RedundancyError Bool, [[Binder]])) -> CaseAlternative -> ([[Binder]], (Either RedundancyError Bool, [[Binder]]))
244 step :: ([[Binder]], (Either RedundancyError Bool, [[Binder]])) -> CaseAlternative -> ([[Binder]], (Either RedundancyError Bool, [[Binder]]))
236 step (uncovered, (nec, redundant)) ca =
245 step (uncovered, (nec, redundant)) ca =
@@ -246,69 +255,91 @@ checkExhaustive hasConstraint env mn numArgs cas = makeResult . first nub $ fold
246 )
255 )
247 )
256 )
248
257
249− makeResult :: ([[Binder]], (Either RedundancyError Bool, [[Binder]])) -> m ()
258+ makeResult :: ([[Binder]], (Either RedundancyError Bool, [[Binder]])) -> m Expr
250 makeResult (bss, (rr, bss')) =
259 makeResult (bss, (rr, bss')) =
251− do unless (hasConstraint || null bss) tellNonExhaustive
260+ do unless (null bss') tellRedundant
252− unless (null bss') tellRedundant
253 case rr of
261 case rr of
254− Left Incomplete -> unless hasConstraint tellIncomplete
262+ Left Incomplete -> tellIncomplete
255 _ -> return ()
263 _ -> return ()
264+ if null bss
265+ then return expr
266+ else addPartialConstraint (second null (splitAt 5 bss)) expr
256 where
267 where
257− tellNonExhaustive = tell . errorMessage . uncurry NotExhaustivePattern . second null . splitAt 5 $ bss
268+ tellRedundant = tell . errorMessage . uncurry OverlappingPattern . second null . splitAt 5 $ bss'
258− tellRedundant = tell . errorMessage . uncurry OverlappingPattern . second null . splitAt 5 $ bss'
269+ tellIncomplete = tell . errorMessage $ IncompleteExhaustivityCheck
259− tellIncomplete = tell . errorMessage $ IncompleteExhaustivityCheck
270+
260−
271+ -- | We add a Partial constraint by adding a call to the following identity function:
261−-- |
272+ --
262−-- Exhaustivity checking over a list of declarations
273+ -- partial :: forall a. Partial => a -> a
263−--
274+ --
264−checkExhaustiveDecls :: forall m. MonadWriter MultipleErrors m => Environment -> ModuleName -> [Declaration] -> m ()
275+ -- The binder information is provided so that it can be embedded in the constraint,
265−checkExhaustiveDecls env mn = mapM_ onDecl
276+ -- and then included in the error message.
266− where
277+ addPartialConstraint :: ([[Binder]], Bool) -> Expr -> m Expr
267− onDecl :: Declaration -> m ()
278+ addPartialConstraint (bss, complete) e = do
268− onDecl (BindingGroupDeclaration bs) = mapM_ (onDecl . convert) bs
279+ tyVar <- ("p" ++) . show <$> fresh
269− where
280+ var <- freshName
270− convert :: (Ident, NameKind, Expr) -> Declaration
281+ return $
271− convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
282+ Let
272− onDecl (ValueDeclaration name _ _ (Right e)) = censor (addHint (ErrorInValueDeclaration name)) (onExpr False e)
283+ [ partial var tyVar ]
273− onDecl (PositionedDeclaration pos _ dec) = censor (addHint (PositionedError pos)) (onDecl dec)
284+ $ App (Var (Qualified Nothing (Ident C.__unused))) e
274− onDecl _ = return ()
275−
276− onExpr :: Bool -> Expr -> m ()
277− onExpr isP (UnaryMinus e) = onExpr isP e
278− onExpr isP (Literal (ArrayLiteral es)) = mapM_ (onExpr isP) es
279− onExpr isP (Literal (ObjectLiteral es)) = mapM_ (onExpr isP . snd) es
280− onExpr isP (TypeClassDictionaryConstructorApp _ e) = onExpr isP e
281− onExpr isP (Accessor _ e) = onExpr isP e
282− onExpr isP (ObjectUpdate o es) = onExpr isP o >> mapM_ (onExpr isP . snd) es
283− onExpr isP (Abs _ e) = onExpr isP e
284− onExpr isP (App e1 e2) = onExpr isP e1 >> onExpr isP e2
285− onExpr isP (IfThenElse e1 e2 e3) = onExpr isP e1 >> onExpr isP e2 >> onExpr isP e3
286− onExpr isP (Case es cas) = checkExhaustive isP env mn (length es) cas >> mapM_ (onExpr isP) es >> mapM_ (onCaseAlternative isP) cas
287− onExpr isP (TypedValue _ e ty) = onExpr (isP || hasPartialConstraint ty) e
288− onExpr isP (Let ds e) = mapM_ onDecl ds >> onExpr isP e
289− onExpr isP (PositionedValue pos _ e) = censor (addHint (PositionedError pos)) (onExpr isP e)
290− onExpr _ _ = return ()
291−
292− onCaseAlternative :: Bool -> CaseAlternative -> m ()
293− onCaseAlternative isP (CaseAlternative _ (Left es)) = mapM_ (\(e, g) -> onExpr isP e >> onExpr isP g) es
294− onCaseAlternative isP (CaseAlternative _ (Right e)) = onExpr isP e
295−
296− hasPartialConstraint :: Type -> Bool
297− hasPartialConstraint (ConstrainedType cs _) = any (go . fst) cs
298 where
285 where
299− go :: Qualified (ProperName 'ClassName) -> Bool
286+ partial :: String -> String -> Declaration
300− go qname
287+ partial var tyVar =
301− | qname == partialClass = True
288+ ValueDeclaration (Ident C.__unused) Private [] $ Right $
302− | otherwise =
289+ TypedValue
303− case qname `M.lookup` typeClasses env of
290+ True
304− Just ([], _, cs') -> any (go . fst) cs'
291+ (Abs (Left (Ident var)) (Var (Qualified Nothing (Ident var))))
305− _ -> False
292+ (ty tyVar)
306− partialClass :: Qualified (ProperName 'ClassName)
293+
307− partialClass = primName "Partial"
294+ ty :: String -> Type
308− hasPartialConstraint _ = False
295+ ty tyVar =
296+ ForAll tyVar
297+ ( ConstrainedType
298+ [ Constraint C.Partial [] (Just constraintData) ]
299+ $ TypeApp (TypeApp tyFunction (TypeVar tyVar)) (TypeVar tyVar)
300+ )
301+ Nothing
302+
303+ constraintData :: ConstraintData
304+ constraintData =
305+ PartialConstraintData (map (map prettyPrintBinderAtom) bss) complete
309
306
310-- |
307-- |
311−-- Exhaustivity checking over a single module
308+-- Exhaustivity checking
312--
309--
313−checkExhaustiveModule :: forall m. MonadWriter MultipleErrors m => Environment -> Module -> m ()
310+checkExhaustiveExpr
314−checkExhaustiveModule env (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds
311+ :: forall m
312+ . (MonadWriter MultipleErrors m, MonadSupply m)
313+ => Environment
314+ -> ModuleName
315+ -> Expr
316+ -> m Expr
317+checkExhaustiveExpr env mn = onExpr
318+ where
319+ onDecl :: Declaration -> m Declaration
320+ onDecl (BindingGroupDeclaration bs) = BindingGroupDeclaration <$> mapM (thirdM onExpr) bs
321+ onDecl (ValueDeclaration name x y (Right e)) = ValueDeclaration name x y . Right <$> censor (addHint (ErrorInValueDeclaration name)) (onExpr e)
322+ onDecl (PositionedDeclaration pos x dec) = PositionedDeclaration pos x <$> censor (addHint (PositionedError pos)) (onDecl dec)
323+ onDecl decl = return decl
324+
325+ onExpr :: Expr -> m Expr
326+ onExpr (UnaryMinus e) = UnaryMinus <$> onExpr e
327+ onExpr (Literal (ArrayLiteral es)) = Literal . ArrayLiteral <$> mapM onExpr es
328+ onExpr (Literal (ObjectLiteral es)) = Literal . ObjectLiteral <$> mapM (sndM onExpr) es
329+ onExpr (TypeClassDictionaryConstructorApp x e) = TypeClassDictionaryConstructorApp x <$> onExpr e
330+ onExpr (Accessor x e) = Accessor x <$> onExpr e
331+ onExpr (ObjectUpdate o es) = ObjectUpdate <$> onExpr o <*> mapM (sndM onExpr) es
332+ onExpr (Abs x e) = Abs x <$> onExpr e
333+ onExpr (App e1 e2) = App <$> onExpr e1 <*> onExpr e2
334+ onExpr (IfThenElse e1 e2 e3) = IfThenElse <$> onExpr e1 <*> onExpr e2 <*> onExpr e3
335+ onExpr (Case es cas) = do
336+ case' <- Case <$> mapM onExpr es <*> mapM onCaseAlternative cas
337+ checkExhaustive env mn (length es) cas case'
338+ onExpr (TypedValue x e y) = TypedValue x <$> onExpr e <*> pure y
339+ onExpr (Let ds e) = Let <$> mapM onDecl ds <*> onExpr e
340+ onExpr (PositionedValue pos x e) = PositionedValue pos x <$> censor (addHint (PositionedError pos)) (onExpr e)
341+ onExpr expr = return expr
342+
343+ onCaseAlternative :: CaseAlternative -> m CaseAlternative
344+ onCaseAlternative (CaseAlternative x (Left es)) = CaseAlternative x . Left <$> mapM (\(e, g) -> (,) <$> onExpr e <*> onExpr g) es
345+ onCaseAlternative (CaseAlternative x (Right e)) = CaseAlternative x . Right <$> onExpr e
src/Language/PureScript/Linter/Imports.hs+172−152
@@ -1,63 +1,37 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−
4module Language.PureScript.Linter.Imports
1module Language.PureScript.Linter.Imports
5 ( lintImports
2 ( lintImports
6 , Name(..)
3 , Name(..)
7 , UsedImports()
4 , UsedImports()
8 ) where
5 ) where
9
6
10−import Prelude ()
11import Prelude.Compat
7import Prelude.Compat
12
8
13−import Control.Monad (unless, when)
9+import Control.Monad (join, unless, foldM, (<=<))
14−import Control.Monad.Error.Class (MonadError(..))
15import Control.Monad.Writer.Class
10import Control.Monad.Writer.Class
16
11
17−import Data.Foldable (forM_)
12+import Data.Function (on)
18−import Data.List ((\\), find, intersect, nub)
13+import Data.Foldable (for_)
19−import Data.Maybe (mapMaybe)
14+import Data.List (find, intersect, nub, groupBy, sortBy, (\\))
15+import Data.Maybe (mapMaybe, fromMaybe)
20import Data.Monoid (Sum(..))
16import Data.Monoid (Sum(..))
17+import Data.Traversable (forM)
21import qualified Data.Map as M
18import qualified Data.Map as M
22
19
23import Language.PureScript.AST.Declarations
20import Language.PureScript.AST.Declarations
24import Language.PureScript.AST.SourcePos
21import Language.PureScript.AST.SourcePos
25import Language.PureScript.Crash
22import Language.PureScript.Crash
26−import Language.PureScript.Names as P
27−
28import Language.PureScript.Errors
23import Language.PureScript.Errors
24+import Language.PureScript.Names
25+import Language.PureScript.Sugar.Names.Common (warnDuplicateRefs)
29import Language.PureScript.Sugar.Names.Env
26import Language.PureScript.Sugar.Names.Env
30import Language.PureScript.Sugar.Names.Imports
27import Language.PureScript.Sugar.Names.Imports
31−
32import qualified Language.PureScript.Constants as C
28import qualified Language.PureScript.Constants as C
33
29
34−-- | Imported name used in some type or expression.
30+-- |
35−data Name
31+-- Map of module name to list of imported names from that module which have
36− = IdentName (Qualified Ident)
32+-- been used.
37− | TyName (Qualified (ProperName 'TypeName))
33+--
38− | TyOpName (Qualified Ident)
34+type UsedImports = M.Map ModuleName [Qualified Name]
39− | DctorName (Qualified (ProperName 'ConstructorName))
40− | TyClassName (Qualified (ProperName 'ClassName))
41− deriving (Eq, Show)
42−
43−getIdentName :: Maybe ModuleName -> Name -> Maybe Ident
44−getIdentName q (IdentName (Qualified q' name)) | q == q' = Just name
45−getIdentName _ _ = Nothing
46−
47−getTypeOpName :: Maybe ModuleName -> Name -> Maybe Ident
48−getTypeOpName q (TyOpName (Qualified q' name)) | q == q' = Just name
49−getTypeOpName _ _ = Nothing
50−
51−getTypeName :: Maybe ModuleName -> Name -> Maybe (ProperName 'TypeName)
52−getTypeName q (TyName (Qualified q' name)) | q == q' = Just name
53−getTypeName _ _ = Nothing
54−
55−getClassName :: Maybe ModuleName -> Name -> Maybe (ProperName 'ClassName)
56−getClassName q (TyClassName (Qualified q' name)) | q == q' = Just name
57−getClassName _ _ = Nothing
58−
59−-- | Map of module name to list of imported names from that module which have been used.
60−type UsedImports = M.Map ModuleName [Name]
61
35
62-- |
36-- |
63-- Find and warn on:
37-- Find and warn on:
@@ -75,46 +49,79 @@ type UsedImports = M.Map ModuleName [Name]
75--
49--
76lintImports
50lintImports
77 :: forall m
51 :: forall m
78− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
52+ . MonadWriter MultipleErrors m
79 => Module
53 => Module
80 -> Env
54 -> Env
81 -> UsedImports
55 -> UsedImports
82 -> m ()
56 -> m ()
83−lintImports (Module _ _ mn mdecls mexports) env usedImps = do
57+lintImports (Module _ _ _ _ Nothing) _ _ =
58+ internalError "lintImports needs desugared exports"
59+lintImports (Module ss _ mn mdecls (Just mexports)) env usedImps = do
60+
61+ -- TODO: this needs some work to be easier to understand
84
62
85− let scope = maybe nullImports (\(_, imps, _) -> imps) (M.lookup mn env)
63+ let scope = maybe primImports (\(_, imps', _) -> imps') (M.lookup mn env)
86 usedImps' = foldr (elaborateUsed scope) usedImps exportedModules
64 usedImps' = foldr (elaborateUsed scope) usedImps exportedModules
87 numOpenImports = getSum $ foldMap (Sum . countOpenImports) mdecls
65 numOpenImports = getSum $ foldMap (Sum . countOpenImports) mdecls
88 allowImplicit = numOpenImports == 1
66 allowImplicit = numOpenImports == 1
67+ imports = M.toAscList (findImports mdecls)
89
68
90− imps <- M.toAscList <$> findImports mdecls
69+ for_ imports $ \(mni, decls) ->
91−
70+ unless (isPrim mni) $
92− forM_ imps $ \(mni, decls) ->
71+ for_ decls $ \(ss', declType, qualifierName) ->
93− unless (isPrim mni) $ do
72+ maybe id warnWithPosition ss' $ do
94− forM_ decls $ \(ss, declType, qualifierName) ->
95− censor (onErrorMessages $ addModuleLocError ss) $ do
96 let names = nub $ M.findWithDefault [] mni usedImps'
73 let names = nub $ M.findWithDefault [] mni usedImps'
97 lintImportDecl env mni qualifierName names declType allowImplicit
74 lintImportDecl env mni qualifierName names declType allowImplicit
98
75
99− forM_ (M.toAscList (byQual imps)) $ \(mnq, entries) -> do
76+ for_ (M.toAscList (byQual imports)) $ \(mnq, entries) -> do
100 let mnis = nub $ map (\(_, _, mni) -> mni) entries
77 let mnis = nub $ map (\(_, _, mni) -> mni) entries
101 unless (length mnis == 1) $ do
78 unless (length mnis == 1) $ do
102 let implicits = filter (\(_, declType, _) -> not $ isExplicit declType) entries
79 let implicits = filter (\(_, declType, _) -> not $ isExplicit declType) entries
103− forM_ implicits $ \(ss, _, mni) ->
80+ for_ implicits $ \(ss', _, mni) ->
104− censor (onErrorMessages $ addModuleLocError ss) $ do
81+ maybe id warnWithPosition ss' $ do
105 let names = nub $ M.findWithDefault [] mni usedImps'
82 let names = nub $ M.findWithDefault [] mni usedImps'
106 usedRefs = findUsedRefs env mni (Just mnq) names
83 usedRefs = findUsedRefs env mni (Just mnq) names
107 unless (null usedRefs) $
84 unless (null usedRefs) $
108 tell $ errorMessage $ ImplicitQualifiedImport mni mnq usedRefs
85 tell $ errorMessage $ ImplicitQualifiedImport mni mnq usedRefs
109
86
110− return ()
87+ for_ imports $ \(mnq, imps) -> do
88+
89+ warned <- foldM (checkDuplicateImports mnq) [] (selfCartesianSubset imps)
90+
91+ let unwarned = imps \\ warned
92+ duplicates
93+ = join
94+ . map tail
95+ . filter ((> 1) . length)
96+ . groupBy ((==) `on` defQual)
97+ . sortBy (compare `on` defQual)
98+ $ unwarned
99+
100+ for_ duplicates $ \(pos, _, _) ->
101+ maybe id warnWithPosition pos $
102+ tell $ errorMessage $ DuplicateSelectiveImport mnq
103+
104+ for_ (imps \\ (warned ++ duplicates)) $ \(pos, typ, _) ->
105+ warnDuplicateRefs (fromMaybe ss pos) DuplicateImportRef $ case typ of
106+ Explicit refs -> refs
107+ Hiding refs -> refs
108+ _ -> []
111
109
112 where
110 where
113
111
112+ defQual :: ImportDef -> Maybe ModuleName
113+ defQual (_, _, q) = q
114+
115+ selfCartesianSubset :: [a] -> [(a, a)]
116+ selfCartesianSubset (x : xs) = [(x, y) | y <- xs] ++ selfCartesianSubset xs
117+ selfCartesianSubset [] = []
118+
114 countOpenImports :: Declaration -> Int
119 countOpenImports :: Declaration -> Int
115− countOpenImports (ImportDeclaration mn' Implicit Nothing _) | not (isPrim mn') = 1
116− countOpenImports (ImportDeclaration mn' (Hiding _) Nothing _) | not (isPrim mn') = 1
117 countOpenImports (PositionedDeclaration _ _ d) = countOpenImports d
120 countOpenImports (PositionedDeclaration _ _ d) = countOpenImports d
121+ countOpenImports (ImportDeclaration mn' Implicit Nothing)
122+ | not (isPrim mn' || mn == mn') = 1
123+ countOpenImports (ImportDeclaration mn' (Hiding _) Nothing)
124+ | not (isPrim mn' || mn == mn') = 1
118 countOpenImports _ = 0
125 countOpenImports _ = 0
119
126
120 -- Checks whether a module is the Prim module - used to suppress any checks
127 -- Checks whether a module is the Prim module - used to suppress any checks
@@ -131,15 +138,15 @@ lintImports (Module _ _ mn mdecls mexports) env usedImps = do
131 byQual = foldr goImp M.empty
138 byQual = foldr goImp M.empty
132 where
139 where
133 goImp (mni, xs) acc = foldr (goDecl mni) acc xs
140 goImp (mni, xs) acc = foldr (goDecl mni) acc xs
134− goDecl mni (ss, declType, Just qmn) acc =
141+ goDecl mni (ss', declType, Just qmn) acc =
135− let entry = (ss, declType, mni)
142+ let entry = (ss', declType, mni)
136 in M.alter (Just . maybe [entry] (entry :)) qmn acc
143 in M.alter (Just . maybe [entry] (entry :)) qmn acc
137 goDecl _ _ acc = acc
144 goDecl _ _ acc = acc
138
145
139 -- The list of modules that are being re-exported by the current module. Any
146 -- The list of modules that are being re-exported by the current module. Any
140 -- module that appears in this list is always considered to be used.
147 -- module that appears in this list is always considered to be used.
141 exportedModules :: [ModuleName]
148 exportedModules :: [ModuleName]
142− exportedModules = nub $ maybe [] (mapMaybe extractModule) mexports
149+ exportedModules = nub $ mapMaybe extractModule mexports
143 where
150 where
144 extractModule (PositionedDeclarationRef _ _ r) = extractModule r
151 extractModule (PositionedDeclarationRef _ _ r) = extractModule r
145 extractModule (ModuleRef mne) = Just mne
152 extractModule (ModuleRef mne) = Just mne
@@ -150,52 +157,54 @@ lintImports (Module _ _ mn mdecls mexports) env usedImps = do
150 -- that are implicitly exported and then re-exported.
157 -- that are implicitly exported and then re-exported.
151 elaborateUsed :: Imports -> ModuleName -> UsedImports -> UsedImports
158 elaborateUsed :: Imports -> ModuleName -> UsedImports -> UsedImports
152 elaborateUsed scope mne used =
159 elaborateUsed scope mne used =
153− let classes = extractByQual mne (importedTypeClasses scope) TyClassName
160+ foldr go used
154− types = extractByQual mne (importedTypes scope) TyName
161+ $ extractByQual mne (importedTypeClasses scope) TyClassName
155− dctors = extractByQual mne (importedDataConstructors scope) DctorName
162+ ++ extractByQual mne (importedTypeOps scope) TyOpName
156− values = extractByQual mne (importedValues scope) IdentName
163+ ++ extractByQual mne (importedTypes scope) TyName
157− in foldr go used (classes ++ types ++ dctors ++ values)
164+ ++ extractByQual mne (importedDataConstructors scope) DctorName
165+ ++ extractByQual mne (importedValues scope) IdentName
166+ ++ extractByQual mne (importedValueOps scope) ValOpName
158 where
167 where
159− go :: (ModuleName, Name) -> UsedImports -> UsedImports
168+ go :: (ModuleName, Qualified Name) -> UsedImports -> UsedImports
160 go (q, name) = M.alter (Just . maybe [name] (name :)) q
169 go (q, name) = M.alter (Just . maybe [name] (name :)) q
161
170
162 extractByQual
171 extractByQual
163− :: (Eq a)
172+ :: ModuleName
164− => ModuleName
165 -> M.Map (Qualified a) [ImportRecord a]
173 -> M.Map (Qualified a) [ImportRecord a]
166− -> (Qualified a -> Name)
174+ -> (a -> Name)
167− -> [(ModuleName, Name)]
175+ -> [(ModuleName, Qualified Name)]
168 extractByQual k m toName = mapMaybe go (M.toList m)
176 extractByQual k m toName = mapMaybe go (M.toList m)
169 where
177 where
170 go (q@(Qualified mnq _), is)
178 go (q@(Qualified mnq _), is)
171 | isUnqualified q =
179 | isUnqualified q =
172 case find (isQualifiedWith k) (map importName is) of
180 case find (isQualifiedWith k) (map importName is) of
173− Just (Qualified _ name) -> Just (k, toName $ Qualified mnq name)
181+ Just (Qualified _ name) -> Just (k, Qualified mnq (toName name))
174 _ -> Nothing
182 _ -> Nothing
175 | isQualifiedWith k q =
183 | isQualifiedWith k q =
176− case importName (head is) of
184+ case importName (head is) of
177− Qualified (Just mn') name -> Just (mn', toName $ Qualified mnq name)
185+ Qualified (Just mn') name -> Just (mn', Qualified mnq (toName name))
178− _ -> internalError "unqualified name in extractByQual"
186+ _ -> internalError "unqualified name in extractByQual"
179 go _ = Nothing
187 go _ = Nothing
180
188
181lintImportDecl
189lintImportDecl
182 :: forall m
190 :: forall m
183− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
191+ . MonadWriter MultipleErrors m
184 => Env
192 => Env
185 -> ModuleName
193 -> ModuleName
186 -> Maybe ModuleName
194 -> Maybe ModuleName
187− -> [Name]
195+ -> [Qualified Name]
188 -> ImportDeclarationType
196 -> ImportDeclarationType
189 -> Bool
197 -> Bool
190− -> m ()
198+ -> m Bool
191lintImportDecl env mni qualifierName names declType allowImplicit =
199lintImportDecl env mni qualifierName names declType allowImplicit =
192 case declType of
200 case declType of
193 Implicit -> case qualifierName of
201 Implicit -> case qualifierName of
194− Nothing -> unless allowImplicit (checkImplicit ImplicitImport)
202+ Nothing ->
195− Just q ->
203+ if null allRefs
196− let usedModuleNames = mapMaybe extractQualName names
204+ then unused
197− in unless (q `elem` usedModuleNames) unused
205+ else unless' allowImplicit (checkImplicit ImplicitImport)
198− Hiding _ -> unless allowImplicit (checkImplicit HidingImport)
206+ Just q -> unless' (q `elem` mapMaybe getQual names) unused
207+ Hiding _ -> unless' allowImplicit (checkImplicit HidingImport)
199 Explicit [] -> unused
208 Explicit [] -> unused
200 Explicit declrefs -> checkExplicit declrefs
209 Explicit declrefs -> checkExplicit declrefs
201
210
@@ -203,82 +212,103 @@ lintImportDecl env mni qualifierName names declType allowImplicit =
203
212
204 checkImplicit
213 checkImplicit
205 :: (ModuleName -> [DeclarationRef] -> SimpleErrorMessage)
214 :: (ModuleName -> [DeclarationRef] -> SimpleErrorMessage)
206− -> m ()
215+ -> m Bool
207 checkImplicit warning =
216 checkImplicit warning =
208 if null allRefs
217 if null allRefs
209 then unused
218 then unused
210− else tell $ errorMessage $ warning mni allRefs
219+ else warn (warning mni (map simplifyTypeRef allRefs))
220+ where
221+ -- Replace explicit type refs with data constructor lists from listing the
222+ -- used constructors explicity `T(X, Y, [...])` to `T(..)` for suggestion
223+ -- message.
224+ simplifyTypeRef :: DeclarationRef -> DeclarationRef
225+ simplifyTypeRef (TypeRef name (Just dctors))
226+ | not (null dctors) = TypeRef name Nothing
227+ simplifyTypeRef other = other
211
228
212 checkExplicit
229 checkExplicit
213 :: [DeclarationRef]
230 :: [DeclarationRef]
214− -> m ()
231+ -> m Bool
215 checkExplicit declrefs = do
232 checkExplicit declrefs = do
216 let idents = nub (mapMaybe runDeclRef declrefs)
233 let idents = nub (mapMaybe runDeclRef declrefs)
217− dctors = mapMaybe (matchDctor qualifierName) names
234+ dctors = mapMaybe (getDctorName <=< disqualifyFor qualifierName) names
218− usedNames = mapMaybe (matchName (typeForDCtor mni) qualifierName) names
235+ usedNames = mapMaybe (matchName (typeForDCtor mni) <=< disqualifyFor qualifierName) names
219 diff = idents \\ usedNames
236 diff = idents \\ usedNames
220− case (length diff, length idents) of
237+
221− (0, _) -> return ()
238+ didWarn <- case (length diff, length idents) of
239+ (0, _) -> return False
222 (n, m) | n == m -> unused
240 (n, m) | n == m -> unused
223− _ -> tell $ errorMessage $ UnusedExplicitImport mni diff qualifierName allRefs
241+ _ -> warn (UnusedExplicitImport mni diff qualifierName allRefs)
224
242
225− -- If we've not already warned a type is unused, check its data constructors
243+ didWarn' <- forM (mapMaybe getTypeRef declrefs) $ \(tn, c) -> do
226− forM_ (mapMaybe getTypeRef declrefs) $ \(tn, c) -> do
227 let allCtors = dctorsForType mni tn
244 let allCtors = dctorsForType mni tn
228− when (runProperName tn `elem` usedNames) $ case (c, dctors `intersect` allCtors) of
245+ -- If we've not already warned a type is unused, check its data constructors
229− (_, []) | c /= Just [] ->
246+ unless' (runProperName tn `notElem` usedNames) $
230− tell $ errorMessage $ UnusedDctorImport tn
247+ case (c, dctors `intersect` allCtors) of
231− (Just ctors, dctors') ->
248+ (_, []) | c /= Just [] -> warn (UnusedDctorImport tn)
232− let ddiff = ctors \\ dctors'
249+ (Just ctors, dctors') ->
233− in unless (null ddiff) $ tell $ errorMessage $ UnusedDctorExplicitImport tn ddiff
250+ let ddiff = ctors \\ dctors'
234− _ -> return ()
251+ in unless' (null ddiff) $ warn $ UnusedDctorExplicitImport tn ddiff
235− return ()
252+ _ -> return False
236−
253+
237− unused :: m ()
254+ return (didWarn || or didWarn')
238− unused = tell $ errorMessage $ UnusedImport mni
255+
256+ unused :: m Bool
257+ unused = warn (UnusedImport mni)
258+
259+ warn :: SimpleErrorMessage -> m Bool
260+ warn err = tell (errorMessage err) >> return True
261+
262+ -- Unless the boolean is true, run the action. Return false when the action is
263+ -- not run, otherwise return whatever the action does.
264+ --
265+ -- The return value is intended for cases where we want to track whether some
266+ -- work was done, as there may be further conditions in the action that mean
267+ -- it ends up doing nothing.
268+ unless' :: Bool -> m Bool -> m Bool
269+ unless' False m = m
270+ unless' True _ = return False
239
271
240 allRefs :: [DeclarationRef]
272 allRefs :: [DeclarationRef]
241 allRefs = findUsedRefs env mni qualifierName names
273 allRefs = findUsedRefs env mni qualifierName names
242
274
243 dtys
275 dtys
244 :: ModuleName
276 :: ModuleName
245− -> [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
277+ -> M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName)
246− dtys mn = maybe [] exportedTypes $ envModuleExports <$> mn `M.lookup` env
278+ dtys mn = maybe M.empty exportedTypes $ envModuleExports <$> mn `M.lookup` env
247
279
248 dctorsForType
280 dctorsForType
249 :: ModuleName
281 :: ModuleName
250 -> ProperName 'TypeName
282 -> ProperName 'TypeName
251 -> [ProperName 'ConstructorName]
283 -> [ProperName 'ConstructorName]
252− dctorsForType mn tn =
284+ dctorsForType mn tn = maybe [] fst $ tn `M.lookup` dtys mn
253− maybe [] getDctors (find matches $ dtys mn)
254− where
255− matches ((ty, _),_) = ty == tn
256− getDctors ((_,ctors),_) = ctors
257
285
258 typeForDCtor
286 typeForDCtor
259 :: ModuleName
287 :: ModuleName
260 -> ProperName 'ConstructorName
288 -> ProperName 'ConstructorName
261 -> Maybe (ProperName 'TypeName)
289 -> Maybe (ProperName 'TypeName)
262− typeForDCtor mn pn =
290+ typeForDCtor mn pn = fst <$> find (elem pn . fst . snd) (M.toList (dtys mn))
263− getTy <$> find matches (dtys mn)
264− where
265− matches ((_, ctors), _) = pn `elem` ctors
266− getTy ((ty, _), _) = ty
267
291
268−findUsedRefs :: Env -> ModuleName -> Maybe ModuleName -> [Name] -> [DeclarationRef]
292+findUsedRefs
269−findUsedRefs env mni qualifierName names =
293+ :: Env
294+ -> ModuleName
295+ -> Maybe ModuleName
296+ -> [Qualified Name]
297+ -> [DeclarationRef]
298+findUsedRefs env mni qn names =
270 let
299 let
271− classRefs = TypeClassRef <$> mapMaybe (getClassName qualifierName) names
300+ classRefs = TypeClassRef <$> mapMaybe (getClassName <=< disqualifyFor qn) names
272− valueRefs = ValueRef <$> mapMaybe (getIdentName qualifierName) names
301+ valueRefs = ValueRef <$> mapMaybe (getIdentName <=< disqualifyFor qn) names
273− typeOpRefs = TypeOpRef <$> mapMaybe (getTypeOpName qualifierName) names
302+ valueOpRefs = ValueOpRef <$> mapMaybe (getValOpName <=< disqualifyFor qn) names
274− types = mapMaybe (getTypeName qualifierName) names
303+ typeOpRefs = TypeOpRef <$> mapMaybe (getTypeOpName <=< disqualifyFor qn) names
275− dctors = mapMaybe (matchDctor qualifierName) names
304+ types = mapMaybe (getTypeName <=< disqualifyFor qn) names
305+ dctors = mapMaybe (getDctorName <=< disqualifyFor qn) names
276 typesWithDctors = reconstructTypeRefs dctors
306 typesWithDctors = reconstructTypeRefs dctors
277 typesWithoutDctors = filter (`M.notMember` typesWithDctors) types
307 typesWithoutDctors = filter (`M.notMember` typesWithDctors) types
278 typesRefs
308 typesRefs
279 = map (flip TypeRef (Just [])) typesWithoutDctors
309 = map (flip TypeRef (Just [])) typesWithoutDctors
280 ++ map (\(ty, ds) -> TypeRef ty (Just ds)) (M.toList typesWithDctors)
310 ++ map (\(ty, ds) -> TypeRef ty (Just ds)) (M.toList typesWithDctors)
281− in classRefs ++ typeOpRefs ++ typesRefs ++ valueRefs
311+ in classRefs ++ typeOpRefs ++ typesRefs ++ valueRefs ++ valueOpRefs
282
312
283 where
313 where
284
314
@@ -287,7 +317,8 @@ findUsedRefs env mni qualifierName names =
287 -> M.Map (ProperName 'TypeName) [ProperName 'ConstructorName]
317 -> M.Map (ProperName 'TypeName) [ProperName 'ConstructorName]
288 reconstructTypeRefs = foldr accumDctors M.empty
318 reconstructTypeRefs = foldr accumDctors M.empty
289 where
319 where
290− accumDctors dctor = M.alter (Just . maybe [dctor] (dctor :)) (findTypeForDctor mni dctor)
320+ accumDctors dctor =
321+ M.alter (Just . maybe [dctor] (dctor :)) (findTypeForDctor mni dctor)
291
322
292 findTypeForDctor
323 findTypeForDctor
293 :: ModuleName
324 :: ModuleName
@@ -296,32 +327,20 @@ findUsedRefs env mni qualifierName names =
296 findTypeForDctor mn dctor =
327 findTypeForDctor mn dctor =
297 case mn `M.lookup` env of
328 case mn `M.lookup` env of
298 Just (_, _, exps) ->
329 Just (_, _, exps) ->
299− case find (elem dctor . snd . fst) (exportedTypes exps) of
330+ case find (elem dctor . fst . snd) (M.toList (exportedTypes exps)) of
300− Just ((ty, _), _) -> ty
331+ Just (ty, _) -> ty
301 Nothing -> internalError $ "missing type for data constructor " ++ runProperName dctor ++ " in findTypeForDctor"
332 Nothing -> internalError $ "missing type for data constructor " ++ runProperName dctor ++ " in findTypeForDctor"
302 Nothing -> internalError $ "missing module " ++ runModuleName mn ++ " in findTypeForDctor"
333 Nothing -> internalError $ "missing module " ++ runModuleName mn ++ " in findTypeForDctor"
303
334
304matchName
335matchName
305 :: (ProperName 'ConstructorName -> Maybe (ProperName 'TypeName))
336 :: (ProperName 'ConstructorName -> Maybe (ProperName 'TypeName))
306− -> Maybe ModuleName
307 -> Name
337 -> Name
308 -> Maybe String
338 -> Maybe String
309−matchName _ qual (IdentName (Qualified q x)) | q == qual = Just $ showIdent x
339+matchName _ (IdentName x) = Just $ showIdent x
310−matchName _ qual (TyName (Qualified q x)) | q == qual = Just $ runProperName x
340+matchName _ (TyName x) = Just $ runProperName x
311−matchName _ qual (TyClassName (Qualified q x)) | q == qual = Just $ runProperName x
341+matchName _ (TyClassName x) = Just $ runProperName x
312−matchName lookupDc qual (DctorName (Qualified q x)) | q == qual = runProperName <$> lookupDc x
342+matchName lookupDc (DctorName x) = runProperName <$> lookupDc x
313−matchName _ _ _ = Nothing
343+matchName _ _ = Nothing
314−
315−extractQualName :: Name -> Maybe ModuleName
316−extractQualName (IdentName (Qualified q _)) = q
317−extractQualName (TyName (Qualified q _)) = q
318−extractQualName (TyOpName (Qualified q _)) = q
319−extractQualName (TyClassName (Qualified q _)) = q
320−extractQualName (DctorName (Qualified q _)) = q
321−
322−matchDctor :: Maybe ModuleName -> Name -> Maybe (ProperName 'ConstructorName)
323−matchDctor qual (DctorName (Qualified q x)) | q == qual = Just x
324−matchDctor _ _ = Nothing
325
344
326runDeclRef :: DeclarationRef -> Maybe String
345runDeclRef :: DeclarationRef -> Maybe String
327runDeclRef (PositionedDeclarationRef _ _ ref) = runDeclRef ref
346runDeclRef (PositionedDeclarationRef _ _ ref) = runDeclRef ref
@@ -330,15 +349,16 @@ runDeclRef (TypeRef pn _) = Just $ runProperName pn
330runDeclRef (TypeClassRef pn) = Just $ runProperName pn
349runDeclRef (TypeClassRef pn) = Just $ runProperName pn
331runDeclRef _ = Nothing
350runDeclRef _ = Nothing
332
351
333−getTypeRef
352+checkDuplicateImports
334− :: DeclarationRef
353+ :: MonadWriter MultipleErrors m
335− -> Maybe (ProperName 'TypeName, Maybe [ProperName 'ConstructorName])
354+ => ModuleName
336−getTypeRef (PositionedDeclarationRef _ _ ref) = getTypeRef ref
355+ -> [ImportDef]
337−getTypeRef (TypeRef pn x) = Just (pn, x)
356+ -> (ImportDef, ImportDef)
338−getTypeRef _ = Nothing
357+ -> m [ImportDef]
339−
358+checkDuplicateImports mn xs ((_, t1, q1), (pos, t2, q2)) =
340−addModuleLocError :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
359+ if t1 == t2 && q1 == q2
341−addModuleLocError sp err =
360+ then do
342− case sp of
361+ maybe id warnWithPosition pos $
343− Just pos -> withPosition pos err
362+ tell $ errorMessage $ DuplicateImport mn t2 q2
344− _ -> err
363+ return $ (pos, t2, q2) : xs
364+ else return xs
src/Language/PureScript/Make.hs+79−84
@@ -1,10 +1,4 @@
1−{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3−{-# LANGUAGE TupleSections #-}
4−{-# LANGUAGE RankNTypes #-}
5−{-# LANGUAGE RecordWildCards #-}
6−{-# LANGUAGE ScopedTypeVariables #-}
7−{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE TypeFamilies #-}
9
3
10module Language.PureScript.Make
4module Language.PureScript.Make
@@ -20,59 +14,47 @@ module Language.PureScript.Make
20 -- * Implementation of Make API using files on disk
14 -- * Implementation of Make API using files on disk
21 , Make(..)
15 , Make(..)
22 , runMake
16 , runMake
17+ , makeIO
18+ , readTextFile
23 , buildMakeActions
19 , buildMakeActions
20+ , inferForeignModules
24 ) where
21 ) where
25
22
26−import Prelude ()
27import Prelude.Compat
23import Prelude.Compat
28
24
29−import Control.Applicative ((<|>))
25+import Control.Concurrent.Lifted as C
30import Control.Monad hiding (sequence)
26import Control.Monad hiding (sequence)
27+import Control.Monad.Base (MonadBase(..))
31import Control.Monad.Error.Class (MonadError(..))
28import Control.Monad.Error.Class (MonadError(..))
32−import Control.Monad.Writer.Class (MonadWriter(..))
33−import Control.Monad.Trans.Class (MonadTrans(..))
34−import Control.Monad.Trans.Except
35import Control.Monad.IO.Class
29import Control.Monad.IO.Class
36−import Control.Monad.Reader (MonadReader(..), ReaderT(..), asks)
37import Control.Monad.Logger
30import Control.Monad.Logger
31+import Control.Monad.Reader (MonadReader(..), ReaderT(..), asks)
38import Control.Monad.Supply
32import Control.Monad.Supply
39−import Control.Monad.Base (MonadBase(..))
33+import Control.Monad.Trans.Class (MonadTrans(..))
40import Control.Monad.Trans.Control (MonadBaseControl(..))
34import Control.Monad.Trans.Control (MonadBaseControl(..))
35+import Control.Monad.Trans.Except
36+import Control.Monad.Writer.Class (MonadWriter(..))
41
37
42−import Control.Concurrent.Lifted as C
38+import Data.Aeson (encode, decode)
43−
39+import Data.ByteString.Builder (toLazyByteString, stringUtf8)
44−import Data.List (foldl', sort)
45−import Data.Maybe (fromMaybe, catMaybes, isJust)
46import Data.Either (partitionEithers)
40import Data.Either (partitionEithers)
47−import Data.Time.Clock
48−import Data.String (fromString)
49import Data.Foldable (for_)
41import Data.Foldable (for_)
42+import Data.List (foldl', sort)
43+import Data.Maybe (fromMaybe, catMaybes)
44+import Data.String (fromString)
45+import Data.Time.Clock
50import Data.Traversable (for)
46import Data.Traversable (for)
51import Data.Version (showVersion)
47import Data.Version (showVersion)
52−import Data.Aeson (encode, decode)
53import qualified Data.ByteString.Lazy as B
48import qualified Data.ByteString.Lazy as B
54import qualified Data.ByteString.UTF8 as BU8
49import qualified Data.ByteString.UTF8 as BU8
55−import qualified Data.Set as S
56import qualified Data.Map as M
50import qualified Data.Map as M
51+import qualified Data.Set as S
57
52
58−import qualified Text.Parsec as Parsec
59−
60−import SourceMap.Types
61−import SourceMap
62−
63−import System.Directory
64− (doesFileExist, getModificationTime, createDirectoryIfMissing, getCurrentDirectory)
65−import System.FilePath ((</>), takeDirectory, makeRelative, splitPath, normalise)
66−import System.IO.Error (tryIOError)
67−import System.IO.UTF8 (readUTF8File, writeUTF8File)
68−
69−import qualified Language.JavaScript.Parser as JS
70−
71−import Language.PureScript.Crash
72import Language.PureScript.AST
53import Language.PureScript.AST
73−import Language.PureScript.Externs
54+import Language.PureScript.Crash
74import Language.PureScript.Environment
55import Language.PureScript.Environment
75import Language.PureScript.Errors
56import Language.PureScript.Errors
57+import Language.PureScript.Externs
76import Language.PureScript.Linter
58import Language.PureScript.Linter
77import Language.PureScript.ModuleDependencies
59import Language.PureScript.ModuleDependencies
78import Language.PureScript.Names
60import Language.PureScript.Names
@@ -82,18 +64,29 @@ import Language.PureScript.Pretty.Common(SMap(..))
82import Language.PureScript.Renamer
64import Language.PureScript.Renamer
83import Language.PureScript.Sugar
65import Language.PureScript.Sugar
84import Language.PureScript.TypeChecker
66import Language.PureScript.TypeChecker
85−import qualified Language.PureScript.Constants as C
67+import qualified Language.JavaScript.Parser as JS
86import qualified Language.PureScript.Bundle as Bundle
68import qualified Language.PureScript.Bundle as Bundle
87−import qualified Language.PureScript.Parser as PSParser
88−
89import qualified Language.PureScript.CodeGen.JS as J
69import qualified Language.PureScript.CodeGen.JS as J
70+import qualified Language.PureScript.Constants as C
90import qualified Language.PureScript.CoreFn as CF
71import qualified Language.PureScript.CoreFn as CF
72+import qualified Language.PureScript.Parser as PSParser
73+
91import qualified Paths_purescript as Paths
74import qualified Paths_purescript as Paths
92
75
76+import SourceMap
77+import SourceMap.Types
78+
79+import System.Directory (doesFileExist, getModificationTime, createDirectoryIfMissing, getCurrentDirectory)
80+import System.FilePath ((</>), takeDirectory, makeRelative, splitPath, normalise, replaceExtension)
81+import System.IO.Error (tryIOError)
82+import System.IO.UTF8 (readUTF8File, writeUTF8File)
83+
84+import qualified Text.Parsec as Parsec
85+
93-- | Progress messages from the make process
86-- | Progress messages from the make process
94data ProgressMessage
87data ProgressMessage
95 = CompilingModule ModuleName
88 = CompilingModule ModuleName
96− deriving (Show, Read, Eq, Ord)
89+ deriving (Show, Eq, Ord)
97
90
98-- | Render a progress message
91-- | Render a progress message
99renderProgressMessage :: ProgressMessage -> String
92renderProgressMessage :: ProgressMessage -> String
@@ -107,31 +100,22 @@ renderProgressMessage (CompilingModule mn) = "Compiling " ++ runModuleName mn
107--
100--
108-- * The details of how files are read/written etc.
101-- * The details of how files are read/written etc.
109--
102--
110−data MakeActions m = MakeActions {
103+data MakeActions m = MakeActions
111− -- |
104+ { getInputTimestamp :: ModuleName -> m (Either RebuildPolicy (Maybe UTCTime))
112− -- Get the timestamp for the input file(s) for a module. If there are multiple
105+ -- ^ Get the timestamp for the input file(s) for a module. If there are multiple
113− -- files (.purs and foreign files, for example) the timestamp should be for
106+ -- files (@.purs@ and foreign files, for example) the timestamp should be for
114 -- the most recently modified file.
107 -- the most recently modified file.
115− --
116− getInputTimestamp :: ModuleName -> m (Either RebuildPolicy (Maybe UTCTime))
117− -- |
118− -- Get the timestamp for the output files for a module. This should be the
119− -- timestamp for the oldest modified file, or Nothing if any of the required
120− -- output files are missing.
121− --
122 , getOutputTimestamp :: ModuleName -> m (Maybe UTCTime)
108 , getOutputTimestamp :: ModuleName -> m (Maybe UTCTime)
123− -- |
109+ -- ^ Get the timestamp for the output files for a module. This should be the
124− -- Read the externs file for a module as a string and also return the actual
110+ -- timestamp for the oldest modified file, or 'Nothing' if any of the required
125− -- path for the file.
111+ -- output files are missing.
126 , readExterns :: ModuleName -> m (FilePath, Externs)
112 , readExterns :: ModuleName -> m (FilePath, Externs)
127− -- |
113+ -- ^ Read the externs file for a module as a string and also return the actual
128− -- Run the code generator for the module and write any required output files.
114+ -- path for the file.
129− --
130 , codegen :: CF.Module CF.Ann -> Environment -> Externs -> SupplyT m ()
115 , codegen :: CF.Module CF.Ann -> Environment -> Externs -> SupplyT m ()
131− -- |
116+ -- ^ Run the code generator for the module and write any required output files.
132− -- Respond to a progress update.
133− --
134 , progress :: ProgressMessage -> m ()
117 , progress :: ProgressMessage -> m ()
118+ -- ^ Respond to a progress update.
135 }
119 }
136
120
137-- |
121-- |
@@ -146,10 +130,10 @@ data RebuildPolicy
146 -- | Never rebuild this module
130 -- | Never rebuild this module
147 = RebuildNever
131 = RebuildNever
148 -- | Always rebuild this module
132 -- | Always rebuild this module
149− | RebuildAlways deriving (Show, Read, Eq, Ord)
133+ | RebuildAlways deriving (Show, Eq, Ord)
150
134
151-- | Rebuild a single module
135-- | Rebuild a single module
152−rebuildModule :: forall m. (Monad m, MonadBaseControl IO m, MonadReader Options m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
136+rebuildModule :: forall m. (Monad m, MonadBaseControl IO m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
153 => MakeActions m
137 => MakeActions m
154 -> [ExternsFile]
138 -> [ExternsFile]
155 -> Module
139 -> Module
@@ -157,11 +141,11 @@ rebuildModule :: forall m. (Monad m, MonadBaseControl IO m, MonadReader Options
157rebuildModule MakeActions{..} externs m@(Module _ _ moduleName _ _) = do
141rebuildModule MakeActions{..} externs m@(Module _ _ moduleName _ _) = do
158 progress $ CompilingModule moduleName
142 progress $ CompilingModule moduleName
159 let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
143 let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
160− lint m
144+ withPrim = importPrim m
161− ((checked@(Module ss coms _ elaborated exps), env'), nextVar) <- runSupplyT 0 $ do
145+ lint withPrim
162− [desugared] <- desugar externs [m]
146+ ((Module ss coms _ elaborated exps, env'), nextVar) <- runSupplyT 0 $ do
147+ [desugared] <- desugar externs [withPrim]
163 runCheck' env $ typeCheckModule desugared
148 runCheck' env $ typeCheckModule desugared
164− checkExhaustiveModule env' checked
165 regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
149 regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
166 let mod' = Module ss coms moduleName regrouped exps
150 let mod' = Module ss coms moduleName regrouped exps
167 corefn = CF.moduleToCoreFn env' mod'
151 corefn = CF.moduleToCoreFn env' mod'
@@ -176,14 +160,11 @@ rebuildModule MakeActions{..} externs m@(Module _ _ moduleName _ _) = do
176-- If timestamps have not changed, the externs file can be used to provide the module's types without
160-- If timestamps have not changed, the externs file can be used to provide the module's types without
177-- having to typecheck the module again.
161-- having to typecheck the module again.
178--
162--
179−make :: forall m. (Monad m, MonadBaseControl IO m, MonadReader Options m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
163+make :: forall m. (Monad m, MonadBaseControl IO m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
180 => MakeActions m
164 => MakeActions m
181 -> [Module]
165 -> [Module]
182− -> m Environment
166+ -> m [ExternsFile]
183make ma@MakeActions{..} ms = do
167make ma@MakeActions{..} ms = do
184− requirePath <- asks optionsRequirePath
185− when (isJust requirePath) $ tell $ errorMessage DeprecatedRequirePath
186−
187 checkModuleNamesAreUnique
168 checkModuleNamesAreUnique
188
169
189 (sorted, graph) <- sortModules ms
170 (sorted, graph) <- sortModules ms
@@ -202,7 +183,7 @@ make ma@MakeActions{..} ms = do
202
183
203 -- Bundle up all the externs and return them as an Environment
184 -- Bundle up all the externs and return them as an Environment
204 (_, externs) <- unzip . fromMaybe (internalError "make: externs were missing but no errors reported.") . sequence <$> for barriers (takeMVar . fst . snd)
185 (_, externs) <- unzip . fromMaybe (internalError "make: externs were missing but no errors reported.") . sequence <$> for barriers (takeMVar . fst . snd)
205− return $ foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
186+ return externs
206
187
207 where
188 where
208 checkModuleNamesAreUnique :: m ()
189 checkModuleNamesAreUnique :: m ()
@@ -272,7 +253,7 @@ make ma@MakeActions{..} ms = do
272
253
273 decodeExterns :: Externs -> Maybe ExternsFile
254 decodeExterns :: Externs -> Maybe ExternsFile
274 decodeExterns bs = do
255 decodeExterns bs = do
275− externs <- decode (fromString bs)
256+ externs <- decode (toLazyByteString (stringUtf8 bs))
276 guard $ efVersion externs == showVersion Paths.version
257 guard $ efVersion externs == showVersion Paths.version
277 return externs
258 return externs
278
259
@@ -304,10 +285,28 @@ makeIO f io = do
304 e <- liftIO $ tryIOError io
285 e <- liftIO $ tryIOError io
305 either (throwError . singleError . f) return e
286 either (throwError . singleError . f) return e
306
287
307−-- Traverse (Either e) instance (base 4.7)
288+-- | Read a text file in the 'Make' monad, capturing any errors using the
308−traverseEither :: Applicative f => (a -> f b) -> Either e a -> f (Either e b)
289+-- 'MonadError' instance.
309−traverseEither _ (Left x) = pure (Left x)
290+readTextFile :: FilePath -> Make String
310−traverseEither f (Right y) = Right <$> f y
291+readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ readUTF8File path
292+
293+-- | Infer the module name for a module by looking for the same filename with
294+-- a .js extension.
295+inferForeignModules
296+ :: forall m
297+ . MonadIO m
298+ => M.Map ModuleName (Either RebuildPolicy FilePath)
299+ -> m (M.Map ModuleName FilePath)
300+inferForeignModules = fmap (M.mapMaybe id) . traverse inferForeignModule
301+ where
302+ inferForeignModule :: Either RebuildPolicy FilePath -> m (Maybe FilePath)
303+ inferForeignModule (Left _) = return Nothing
304+ inferForeignModule (Right path) = do
305+ let jsFile = replaceExtension path "js"
306+ exists <- liftIO $ doesFileExist jsFile
307+ if exists
308+ then return (Just jsFile)
309+ else return Nothing
311
310
312-- |
311-- |
313-- A set of make actions that read and write modules from the given directory.
312-- A set of make actions that read and write modules from the given directory.
@@ -324,7 +323,7 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
324 getInputTimestamp :: ModuleName -> Make (Either RebuildPolicy (Maybe UTCTime))
323 getInputTimestamp :: ModuleName -> Make (Either RebuildPolicy (Maybe UTCTime))
325 getInputTimestamp mn = do
324 getInputTimestamp mn = do
326 let path = fromMaybe (internalError "Module has no filename in 'make'") $ M.lookup mn filePathMap
325 let path = fromMaybe (internalError "Module has no filename in 'make'") $ M.lookup mn filePathMap
327− e1 <- traverseEither getTimestamp path
326+ e1 <- traverse getTimestamp path
328 fPath <- maybe (return Nothing) getTimestamp $ M.lookup mn foreigns
327 fPath <- maybe (return Nothing) getTimestamp $ M.lookup mn foreigns
329 return $ fmap (max fPath) e1
328 return $ fmap (max fPath) e1
330
329
@@ -375,7 +374,7 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
375 genSourceMap dir mapFile extraLines mappings = do
374 genSourceMap dir mapFile extraLines mappings = do
376 let pathToDir = iterate (".." </>) ".." !! length (splitPath $ normalise outputDir)
375 let pathToDir = iterate (".." </>) ".." !! length (splitPath $ normalise outputDir)
377 sourceFile = case mappings of
376 sourceFile = case mappings of
378− ((SMap file _ _):_) -> Just $ pathToDir </> makeRelative dir file
377+ (SMap file _ _ : _) -> Just $ pathToDir </> makeRelative dir file
379 _ -> Nothing
378 _ -> Nothing
380 let rawMapping = SourceMapping { smFile = "index.js", smSourceRoot = Nothing, smMappings =
379 let rawMapping = SourceMapping { smFile = "index.js", smSourceRoot = Nothing, smMappings =
381 map (\(SMap _ orig gen) -> Mapping {
380 map (\(SMap _ orig gen) -> Mapping {
@@ -414,9 +413,6 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
414 progress :: ProgressMessage -> Make ()
413 progress :: ProgressMessage -> Make ()
415 progress = liftIO . putStrLn . renderProgressMessage
414 progress = liftIO . putStrLn . renderProgressMessage
416
415
417−readTextFile :: FilePath -> Make String
418−readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ readUTF8File path
419−
420-- |
416-- |
421-- Check that the declarations in a given PureScript module match with those
417-- Check that the declarations in a given PureScript module match with those
422-- in its corresponding foreign module.
418-- in its corresponding foreign module.
@@ -464,11 +460,10 @@ checkForeignDecls m path = do
464 (errs, _) ->
460 (errs, _) ->
465 Left errs
461 Left errs
466
462
467− -- TODO: Handling for parenthesised operators should be removed after 0.9.
468 -- We ignore the error message here, just being told it's an invalid
463 -- We ignore the error message here, just being told it's an invalid
469 -- identifier should be enough.
464 -- identifier should be enough.
470 parseIdent :: String -> Either String Ident
465 parseIdent :: String -> Either String Ident
471− parseIdent str = try str <|> try ("(" ++ str ++ ")")
466+ parseIdent str = try str
472 where
467 where
473 try s = either (const (Left str)) Right $ do
468 try s = either (const (Left str)) Right $ do
474 ts <- PSParser.lex "" s
469 ts <- PSParser.lex "" s
src/Language/PureScript/ModuleDependencies.hs+16−12
@@ -1,12 +1,12 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−
3-- |
1-- |
4-- Provides the ability to sort modules based on module dependencies
2-- Provides the ability to sort modules based on module dependencies
5--
3--
6−module Language.PureScript.ModuleDependencies (
4+module Language.PureScript.ModuleDependencies
7− sortModules,
5+ ( sortModules
8− ModuleGraph
6+ , ModuleGraph
9−) where
7+ ) where
8+
9+import Prelude.Compat
10
10
11import Control.Monad.Error.Class (MonadError(..))
11import Control.Monad.Error.Class (MonadError(..))
12
12
@@ -14,11 +14,11 @@ import Data.Graph
14import Data.List (nub)
14import Data.List (nub)
15import Data.Maybe (fromMaybe)
15import Data.Maybe (fromMaybe)
16
16
17−import Language.PureScript.Crash
18import Language.PureScript.AST
17import Language.PureScript.AST
18+import Language.PureScript.Crash
19+import Language.PureScript.Errors
19import Language.PureScript.Names
20import Language.PureScript.Names
20import Language.PureScript.Types
21import Language.PureScript.Types
21−import Language.PureScript.Errors
22
22
23-- | A list of modules with their transitive dependencies
23-- | A list of modules with their transitive dependencies
24type ModuleGraph = [(ModuleName, [ModuleName])]
24type ModuleGraph = [(ModuleName, [ModuleName])]
@@ -47,7 +47,7 @@ sortModules ms = do
47 -- Extract module names that have been brought into scope by an `as` import.
47 -- Extract module names that have been brought into scope by an `as` import.
48 extractQualAs :: Declaration -> [ModuleName]
48 extractQualAs :: Declaration -> [ModuleName]
49 extractQualAs (PositionedDeclaration _ _ d) = extractQualAs d
49 extractQualAs (PositionedDeclaration _ _ d) = extractQualAs d
50− extractQualAs (ImportDeclaration _ _ (Just am) _) = [am]
50+ extractQualAs (ImportDeclaration _ _ (Just am)) = [am]
51 extractQualAs _ = []
51 extractQualAs _ = []
52
52
53-- |
53-- |
@@ -65,12 +65,12 @@ usedModules ams d =
65 where
65 where
66
66
67 forDecls :: Declaration -> [ModuleName]
67 forDecls :: Declaration -> [ModuleName]
68− forDecls (ImportDeclaration mn _ _ _) =
68+ forDecls (ImportDeclaration mn _ _) =
69 -- Regardless of whether an imported module is qualified we still need to
69 -- Regardless of whether an imported module is qualified we still need to
70 -- take into account its import to build an accurate list of dependencies.
70 -- take into account its import to build an accurate list of dependencies.
71 [mn]
71 [mn]
72− forDecls (FixityDeclaration _ _ (Just (Qualified (Just mn) _)))
72+ forDecls (FixityDeclaration fd)
73− | mn `notElem` ams = [mn]
73+ | Just mn <- extractQualFixity fd, mn `notElem` ams = [mn]
74 forDecls (TypeInstanceDeclaration _ _ (Qualified (Just mn) _) _ _)
74 forDecls (TypeInstanceDeclaration _ _ (Qualified (Just mn) _) _ _)
75 | mn `notElem` ams = [mn]
75 | mn `notElem` ams = [mn]
76 forDecls _ = []
76 forDecls _ = []
@@ -87,6 +87,10 @@ usedModules ams d =
87 | mn `notElem` ams = [mn]
87 | mn `notElem` ams = [mn]
88 forTypes _ = []
88 forTypes _ = []
89
89
90+ extractQualFixity :: Either ValueFixity TypeFixity -> Maybe ModuleName
91+ extractQualFixity (Left (ValueFixity _ (Qualified mn _) _)) = mn
92+ extractQualFixity (Right (TypeFixity _ (Qualified mn _) _)) = mn
93+
90-- |
94-- |
91-- Convert a strongly connected component of the module graph to a module
95-- Convert a strongly connected component of the module graph to a module
92--
96--
src/Language/PureScript/Names.hs+82−20
@@ -1,19 +1,56 @@
1−{-# LANGUAGE DeriveFunctor #-}
2{-# LANGUAGE TemplateHaskell #-}
1{-# LANGUAGE TemplateHaskell #-}
3−{-# LANGUAGE EmptyDataDecls #-}
4−{-# LANGUAGE KindSignatures #-}
5
2
6-- |
3-- |
7-- Data types for names
4-- Data types for names
8--
5--
9module Language.PureScript.Names where
6module Language.PureScript.Names where
10
7
11−import Control.Monad (liftM)
8+import Prelude.Compat
9+
12import Control.Monad.Supply.Class
10import Control.Monad.Supply.Class
13
11
14−import Data.List
15import Data.Aeson
12import Data.Aeson
16import Data.Aeson.TH
13import Data.Aeson.TH
14+import Data.List
15+
16+-- | A sum of the possible name types, useful for error and lint messages.
17+data Name
18+ = IdentName Ident
19+ | ValOpName (OpName 'ValueOpName)
20+ | TyName (ProperName 'TypeName)
21+ | TyOpName (OpName 'TypeOpName)
22+ | DctorName (ProperName 'ConstructorName)
23+ | TyClassName (ProperName 'ClassName)
24+ | ModName ModuleName
25+ deriving (Eq, Show)
26+
27+getIdentName :: Name -> Maybe Ident
28+getIdentName (IdentName name) = Just name
29+getIdentName _ = Nothing
30+
31+getValOpName :: Name -> Maybe (OpName 'ValueOpName)
32+getValOpName (ValOpName name) = Just name
33+getValOpName _ = Nothing
34+
35+getTypeName :: Name -> Maybe (ProperName 'TypeName)
36+getTypeName (TyName name) = Just name
37+getTypeName _ = Nothing
38+
39+getTypeOpName :: Name -> Maybe (OpName 'TypeOpName)
40+getTypeOpName (TyOpName name) = Just name
41+getTypeOpName _ = Nothing
42+
43+getDctorName :: Name -> Maybe (ProperName 'ConstructorName)
44+getDctorName (DctorName name) = Just name
45+getDctorName _ = Nothing
46+
47+getClassName :: Name -> Maybe (ProperName 'ClassName)
48+getClassName (TyClassName name) = Just name
49+getClassName _ = Nothing
50+
51+getModName :: Name -> Maybe ModuleName
52+getModName (ModName name) = Just name
53+getModName _ = Nothing
17
54
18-- |
55-- |
19-- Names for value identifiers
56-- Names for value identifiers
@@ -24,36 +61,50 @@ data Ident
24 --
61 --
25 = Ident String
62 = Ident String
26 -- |
63 -- |
27− -- A symbolic name for an infix operator
28− --
29− | Op String
30− -- |
31 -- A generated name for an identifier
64 -- A generated name for an identifier
32 --
65 --
33 | GenIdent (Maybe String) Integer
66 | GenIdent (Maybe String) Integer
34− deriving (Show, Read, Eq, Ord)
67+ deriving (Show, Eq, Ord)
35
68
36runIdent :: Ident -> String
69runIdent :: Ident -> String
37runIdent (Ident i) = i
70runIdent (Ident i) = i
38−runIdent (Op op) = op
39runIdent (GenIdent Nothing n) = "$" ++ show n
71runIdent (GenIdent Nothing n) = "$" ++ show n
40runIdent (GenIdent (Just name) n) = "$" ++ name ++ show n
72runIdent (GenIdent (Just name) n) = "$" ++ name ++ show n
41
73
42showIdent :: Ident -> String
74showIdent :: Ident -> String
43−showIdent (Op op) = '(' : op ++ ")"
75+showIdent = runIdent
44−showIdent i = runIdent i
45
76
46−freshIdent :: (MonadSupply m) => String -> m Ident
77+freshIdent :: MonadSupply m => String -> m Ident
47−freshIdent name = liftM (GenIdent (Just name)) fresh
78+freshIdent name = GenIdent (Just name) <$> fresh
48
79
49−freshIdent' :: (MonadSupply m) => m Ident
80+freshIdent' :: MonadSupply m => m Ident
50−freshIdent' = liftM (GenIdent Nothing) fresh
81+freshIdent' = GenIdent Nothing <$> fresh
82+
83+-- |
84+-- Operator alias names.
85+--
86+newtype OpName (a :: OpNameType) = OpName { runOpName :: String }
87+ deriving (Show, Eq, Ord)
88+
89+instance ToJSON (OpName a) where
90+ toJSON = toJSON . runOpName
91+
92+instance FromJSON (OpName a) where
93+ parseJSON = fmap OpName . parseJSON
94+
95+showOp :: OpName a -> String
96+showOp op = '(' : runOpName op ++ ")"
97+
98+-- |
99+-- The closed set of operator alias types.
100+--
101+data OpNameType = ValueOpName | TypeOpName
51
102
52-- |
103-- |
53-- Proper names, i.e. capitalized names for e.g. module names, type//data constructors.
104-- Proper names, i.e. capitalized names for e.g. module names, type//data constructors.
54--
105--
55newtype ProperName (a :: ProperNameType) = ProperName { runProperName :: String }
106newtype ProperName (a :: ProperNameType) = ProperName { runProperName :: String }
56− deriving (Show, Read, Eq, Ord)
107+ deriving (Show, Eq, Ord)
57
108
58instance ToJSON (ProperName a) where
109instance ToJSON (ProperName a) where
59 toJSON = toJSON . runProperName
110 toJSON = toJSON . runProperName
@@ -78,7 +129,7 @@ coerceProperName = ProperName . runProperName
78-- Module names
129-- Module names
79--
130--
80newtype ModuleName = ModuleName [ProperName 'Namespace]
131newtype ModuleName = ModuleName [ProperName 'Namespace]
81− deriving (Show, Read, Eq, Ord)
132+ deriving (Show, Eq, Ord)
82
133
83runModuleName :: ModuleName -> String
134runModuleName :: ModuleName -> String
84runModuleName (ModuleName pns) = intercalate "." (runProperName `map` pns)
135runModuleName (ModuleName pns) = intercalate "." (runProperName `map` pns)
@@ -95,12 +146,15 @@ moduleNameFromString = ModuleName . splitProperNames
95-- A qualified name, i.e. a name with an optional module name
146-- A qualified name, i.e. a name with an optional module name
96--
147--
97data Qualified a = Qualified (Maybe ModuleName) a
148data Qualified a = Qualified (Maybe ModuleName) a
98− deriving (Show, Read, Eq, Ord, Functor)
149+ deriving (Show, Eq, Ord, Functor)
99
150
100showQualified :: (a -> String) -> Qualified a -> String
151showQualified :: (a -> String) -> Qualified a -> String
101showQualified f (Qualified Nothing a) = f a
152showQualified f (Qualified Nothing a) = f a
102showQualified f (Qualified (Just name) a) = runModuleName name ++ "." ++ f a
153showQualified f (Qualified (Just name) a) = runModuleName name ++ "." ++ f a
103
154
155+getQual :: Qualified a -> Maybe ModuleName
156+getQual (Qualified mn _) = mn
157+
104-- |
158-- |
105-- Provide a default module name, if a name is unqualified
159-- Provide a default module name, if a name is unqualified
106--
160--
@@ -118,6 +172,14 @@ mkQualified name mn = Qualified (Just mn) name
118disqualify :: Qualified a -> a
172disqualify :: Qualified a -> a
119disqualify (Qualified _ a) = a
173disqualify (Qualified _ a) = a
120
174
175+-- |
176+-- Remove the qualification from a value when it is qualified with a particular
177+-- module name.
178+--
179+disqualifyFor :: Maybe ModuleName -> Qualified a -> Maybe a
180+disqualifyFor mn (Qualified mn' a) | mn == mn' = Just a
181+disqualifyFor _ _ = Nothing
182+
121-- |
183-- |
122-- Checks whether a qualified value is actually qualified with a module reference
184-- Checks whether a qualified value is actually qualified with a module reference
123--
185--
src/Language/PureScript/Options.hs+3−16
@@ -1,20 +1,10 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Options
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11-- |
1-- |
12-- The data type of compiler options
2-- The data type of compiler options
13--
3--
14−-----------------------------------------------------------------------------
15−
16module Language.PureScript.Options where
4module Language.PureScript.Options where
17
5
6+import Prelude.Compat
7+
18-- |
8-- |
19-- The data type of compiler options
9-- The data type of compiler options
20--
10--
@@ -38,9 +28,6 @@ data Options = Options {
38 -- |
28 -- |
39 -- Remove the comments from the generated js
29 -- Remove the comments from the generated js
40 , optionsNoComments :: Bool
30 , optionsNoComments :: Bool
41− -- |
42− -- The path to prepend to require statements
43− , optionsRequirePath :: Maybe FilePath
44 -- |
31 -- |
45 -- Generate soure maps
32 -- Generate soure maps
46 , optionsSourceMaps :: Bool
33 , optionsSourceMaps :: Bool
@@ -49,4 +36,4 @@ data Options = Options {
49-- |
36-- |
50-- Default make options
37-- Default make options
51defaultOptions :: Options
38defaultOptions :: Options
52−defaultOptions = Options False False Nothing False False False Nothing False
39+defaultOptions = Options False False Nothing False False False False
src/Language/PureScript/Parser.hs+23−36

This diff is too big to show here.

src/Language/PureScript/Parser/Common.hs+29−7

This diff is too big to show here.

src/Language/PureScript/Parser/Declarations.hs+116−112

This diff is too big to show here.

src/Language/PureScript/Parser/JS.hsdeleted−60

This diff is too big to show here.

src/Language/PureScript/Parser/Kinds.hs+6−16

This diff is too big to show here.

src/Language/PureScript/Parser/Lexer.hs+42−36

This diff is too big to show here.

src/Language/PureScript/Parser/State.hs+2−14

This diff is too big to show here.

src/Language/PureScript/Parser/Types.hs+25−15

This diff is too big to show here.

src/Language/PureScript/Pretty.hs+2−14

This diff is too big to show here.

src/Language/PureScript/Pretty/Common.hs+9−17

This diff is too big to show here.

src/Language/PureScript/Pretty/Cpp.hs+22−18

This diff is too big to show here.

src/Language/PureScript/Pretty/JS.hs+10−25

This diff is too big to show here.

src/Language/PureScript/Pretty/Kinds.hs+11−18

This diff is too big to show here.

src/Language/PureScript/Pretty/Types.hs+22−13

This diff is too big to show here.

src/Language/PureScript/Pretty/Values.hs+13−14

This diff is too big to show here.

src/Language/PureScript/Publish.hs+28−26

This diff is too big to show here.

src/Language/PureScript/Publish/BoxesHelpers.hs+3

This diff is too big to show here.

src/Language/PureScript/Publish/ErrorsWarnings.hs+31−27

This diff is too big to show here.

src/Language/PureScript/Publish/Utils.hs+41−38

This diff is too big to show here.

src/Language/PureScript/Renamer.hs−6

This diff is too big to show here.

src/Language/PureScript/Sugar.hs+16−27

This diff is too big to show here.

src/Language/PureScript/Sugar/BindingGroups.hs+19−25

This diff is too big to show here.

src/Language/PureScript/Sugar/CaseDeclarations.hs+18−21

This diff is too big to show here.

src/Language/PureScript/Sugar/DoNotation.hs+14−16

This diff is too big to show here.

src/Language/PureScript/Sugar/Names.hs+115−190

This diff is too big to show here.

src/Language/PureScript/Sugar/Names/Common.hsnew file+68

This diff is too big to show here.

src/Language/PureScript/Sugar/Names/Env.hs+209−88

This diff is too big to show here.

src/Language/PureScript/Sugar/Names/Exports.hs+157−156

This diff is too big to show here.

src/Language/PureScript/Sugar/Names/Imports.hs+91−180

This diff is too big to show here.

src/Language/PureScript/Sugar/ObjectWildcards.hs+7−10

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators.hs+211−128

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators/Binders.hs+4−5

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators/Common.hs+11−16

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators/Expr.hs+6−10

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators/Types.hs+4−5

This diff is too big to show here.

src/Language/PureScript/Sugar/TypeClasses.hs+12−17

This diff is too big to show here.

src/Language/PureScript/Sugar/TypeClasses/Deriving.hs+38−35

This diff is too big to show here.

src/Language/PureScript/Sugar/TypeDeclarations.hs+28−38

This diff is too big to show here.

src/Language/PureScript/Traversals.hs+27−42

This diff is too big to show here.

src/Language/PureScript/TypeChecker.hs+67−116

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Entailment.hs+38−37

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Kinds.hs+10−14

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Monad.hs+72−35

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Rows.hs+8−27

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Skolems.hs+15−30

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Subsumption.hs+12−27

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Synonyms.hs+8−24

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Types.hs+90−96

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Unify.hs+38−50

This diff is too big to show here.

src/Language/PureScript/TypeClassDictionaries.hs+4−2

This diff is too big to show here.

src/Language/PureScript/Types.hs+63−76

This diff is too big to show here.

src/System/IO/UTF8.hs+2−2

This diff is too big to show here.

stack-ghc-8.0.yamlnew file+7

This diff is too big to show here.

stack-lts-5.yamldeleted−7

This diff is too big to show here.

stack-nightly.yamldeleted−6

This diff is too big to show here.

stack.yamlmode 120000 → 100644+9−1

This diff is too big to show here.

tests/Language/PureScript/Ide/FilterSpec.hs+21−32

This diff is too big to show here.

tests/Language/PureScript/Ide/Imports/IntegrationSpec.hs+17−35

This diff is too big to show here.

tests/Language/PureScript/Ide/ImportsSpec.hs+13−8

This diff is too big to show here.

tests/Language/PureScript/Ide/Integration.hs+113−80

This diff is too big to show here.

tests/Language/PureScript/Ide/MatcherSpec.hs+18−27

This diff is too big to show here.

tests/Language/PureScript/Ide/RebuildSpec.hs+18−23

This diff is too big to show here.

tests/Language/PureScript/Ide/ReexportsSpec.hs+54−68

This diff is too big to show here.

tests/Language/PureScript/Ide/SourceFile/IntegrationSpec.hsnew file+36

This diff is too big to show here.

tests/Language/PureScript/Ide/SourceFileSpec.hsnew file+46

This diff is too big to show here.

tests/Language/PureScript/IdeSpec.hsdeleted−35

This diff is too big to show here.

tests/Main.hs+4−1

This diff is too big to show here.

tests/TestCompiler.hs+187−95

This diff is too big to show here.

tests/TestDocs.hs+3−8

This diff is too big to show here.

tests/TestPscIde.hs+9−2

This diff is too big to show here.

tests/TestPscPublish.hs+2−2

This diff is too big to show here.

tests/TestPsci.hs+24−46

This diff is too big to show here.

tests/TestUtils.hs+53−19

This diff is too big to show here.

tests/support/bower.json+7−6

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Class.pursdeleted−24

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Console.jsdeleted−18

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Console.pursdeleted−18

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Unsafe.jsdeleted−8

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Unsafe.pursdeleted−10

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff.jsdeleted−62

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff.pursdeleted−67

This diff is too big to show here.

tests/support/flattened/Control-Monad-ST.jsdeleted−38

This diff is too big to show here.

tests/support/flattened/Control-Monad-ST.pursdeleted−42

This diff is too big to show here.

tests/support/flattened/Data-Function.jsdeleted−233

This diff is too big to show here.

tests/support/flattened/Data-Function.pursdeleted−113

This diff is too big to show here.

tests/support/flattened/Prelude.jsdeleted−228

This diff is too big to show here.

tests/support/flattened/Prelude.pursdeleted−872

This diff is too big to show here.

tests/support/flattened/Test-Assert.jsdeleted−27

This diff is too big to show here.

tests/support/flattened/Test-Assert.pursdeleted−46

This diff is too big to show here.

tests/support/package.json+2−1

This diff is too big to show here.

tests/support/preludedeleted−1

This diff is too big to show here.

tests/support/pscide/src/ImportsSpec.purs+1−3

This diff is too big to show here.

tests/support/pscide/src/Main.purs → tests/support/pscide/src/MatcherSpec.pursrenamed+1−1

This diff is too big to show here.

tests/support/pscide/src/RebuildSpecSingleModule.purs+1−1

This diff is too big to show here.

tests/support/pscide/src/RebuildSpecWithForeign.js−2

This diff is too big to show here.

tests/support/pscide/src/RebuildSpecWithHiddenIdent.pursnew file+6

This diff is too big to show here.

tests/support/pscide/src/SourceFileSpec.pursnew file+10

This diff is too big to show here.

tests/support/setup.jsdeleted−22

This diff is too big to show here.

travis/after.shdeleted−13

This diff is too big to show here.

travis/build.shnew file+59

This diff is too big to show here.

travis/configure.shdeleted−17

This diff is too big to show here.

travis/convert-os-name.shnew file+14

This diff is too big to show here.

travis/test-install.shdeleted−18

This diff is too big to show here.