git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge remote-tracking branch 'upstream/master' into pure11-0.8
commita4673586b1b1599bbad5c3e2dc0ecc9df985176d authorAndy Arvanitis <andyarvanitis@gmail.com> dateSun 24 Jan 2016, 17:47 (11 years ago) parent2650e50f4d109c
13 files changed+459−279
CONTRIBUTORS.md+1 examples/docs/src/ImportedTwice.purs+27 psci/PSCi.hs+17−4 src/Language/PureScript/CodeGen/JS/Optimizer.hs+5−17 src/Language/PureScript/CodeGen/JS/Optimizer/Common.hs+15−12 src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+188−136 src/Language/PureScript/CodeGen/JS/Optimizer/MagicDo.hs+11−42 src/Language/PureScript/Constants.hs+101−23 src/Language/PureScript/CoreFn/Traversals.hs+1 src/Language/PureScript/Docs/Convert/ReExports.hs+78−36 src/Language/PureScript/Linter/Exhaustive.hs+1 src/Language/PureScript/ModuleDependencies.hs+6−4 src/Language/PureScript/Sugar/TypeClasses/Deriving.hs+8−5
CONTRIBUTORS.md+1
@@ -51,6 +51,7 @@ This file lists the contributors to the PureScript compiler project, and the ter
5151- [@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).
5252- [@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).
5353- [@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.
54+- [@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).
5455- [@sztupi](https://github.com/sztupi) (Attila Sztupak) My existing contributions and all future contributions until further notice are Copyright Attila Sztupak, 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).
5556- [@taku0](https://github.com/taku0) - My existing contributions and all future contributions until further notice are Copyright taku0, 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).
5657- [@trofi](https://github.com/trofi) (Sergei Trofimovich) My existing contributions and all future contributions until further notice are Copyright Sergei Trofimovich, 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).
examples/docs/src/ImportedTwice.pursnew file+27
@@ -0,0 +1,27 @@
1+-- See also an example in the wild: purescript-transformers v0.8.4.
2+-- Control.Monad.RWS.Trans re-exports `lift` from both Control.Monad.Trans
3+-- (where it is originally defined) and Control.Monad.RWS.Class (which
4+-- re-exports it from Control.Monad.Trans).
5+
6+module ImportedTwice
7+ ( module A
8+ , module B
9+ )
10+ where
11+
12+import A
13+import B
14+
15+module A
16+ ( module B )
17+ where
18+
19+import B
20+
21+bar :: Int
22+bar = 1
23+
24+module B where
25+
26+foo :: Int
27+foo = 0
psci/PSCi.hs+17−4
@@ -14,7 +14,7 @@ import Prelude.Compat
1414
1515import Data.Foldable (traverse_)
1616import Data.Maybe (mapMaybe)
17−import Data.List (intersperse, intercalate, nub, sort)
17+import Data.List (intersperse, intercalate, nub, sort, find)
1818import Data.Tuple (swap)
1919import Data.Version (showVersion)
2020import qualified Data.Map as M
@@ -486,9 +486,22 @@ handleBrowse moduleName = do
486486 case env of
487487 Left errs -> printErrors errs
488488 Right env' ->
489− if moduleName `notElem` (nub . map ((\ (P.Module _ _ modName _ _ ) -> modName) . snd)) (psciLoadedModules st)
490− then PSCI $ outputStrLn $ "Module '" ++ N.runModuleName moduleName ++ "' is not valid."
491− else printModuleSignatures moduleName env'
489+ if isModInEnv moduleName st
490+ then printModuleSignatures moduleName env'
491+ else case lookupUnQualifiedModName moduleName st of
492+ Just unQualifiedName ->
493+ if isModInEnv unQualifiedName st
494+ then printModuleSignatures unQualifiedName env'
495+ else failNotInEnv moduleName
496+ Nothing ->
497+ failNotInEnv moduleName
498+ where
499+ isModInEnv modName =
500+ any ((== modName) . P.getModuleName . snd) . psciLoadedModules
501+ failNotInEnv modName =
502+ PSCI $ outputStrLn $ "Module '" ++ N.runModuleName modName ++ "' is not valid."
503+ lookupUnQualifiedModName quaModName st =
504+ (\(modName,_,_) -> modName) <$> find ( \(_, _, mayQuaName) -> mayQuaName == Just quaModName) (psciImportedModules st)
492505
493506-- | Pretty-print errors
494507printErrors :: P.MultipleErrors -> PSCI ()
src/Language/PureScript/CodeGen/JS/Optimizer.hs+5−17
@@ -1,13 +1,5 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
1+{-# LANGUAGE FlexibleContexts #-}
2+
113-- |
124-- This module optimizes code in the simplified-Javascript intermediate representation.
135--
@@ -29,13 +21,7 @@
2921--
3022-- * Inlining primitive Javascript operators
3123--
32−-----------------------------------------------------------------------------
33−
34−{-# LANGUAGE FlexibleContexts #-}
35−
36−module Language.PureScript.CodeGen.JS.Optimizer (
37− optimize
38−) where
24+module Language.PureScript.CodeGen.JS.Optimizer (optimize) where
3925
4026import Prelude ()
4127import Prelude.Compat
@@ -79,7 +65,9 @@ optimize' js = do
7965 , inlineVariables
8066 , inlineValues
8167 , inlineOperator (C.prelude, (C.$)) $ \f x -> JSApp f [x]
68+ , inlineOperator (C.dataFunction, C.apply) $ \f x -> JSApp f [x]
8269 , inlineOperator (C.prelude, (C.#)) $ \x f -> JSApp f [x]
70+ , inlineOperator (C.dataFunction, C.applyFlipped) $ \x f -> JSApp f [x]
8371 , inlineOperator (C.dataArrayUnsafe, C.unsafeIndex) $ flip JSIndexer
8472 , inlineCommonOperators ]) js
8573
src/Language/PureScript/CodeGen/JS/Optimizer/Common.hs+15−12
@@ -1,18 +1,6 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.Common
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- Common functions used by the various optimizer phases
133--
14−-----------------------------------------------------------------------------
15−
164module Language.PureScript.CodeGen.JS.Optimizer.Common where
175
186import Data.Maybe (fromMaybe)
@@ -76,3 +64,18 @@ isUpdated var1 = everythingOnJS (||) check
7664removeFromBlock :: ([JS] -> [JS]) -> JS -> JS
7765removeFromBlock go (JSBlock sts) = JSBlock (go sts)
7866removeFromBlock _ js = js
67+
68+isFn :: (String, String) -> JS -> Bool
69+isFn (moduleName, fnName) (JSAccessor x (JSVar y)) = x == fnName && y == moduleName
70+isFn (moduleName, fnName) (JSIndexer (JSStringLiteral x) (JSVar y)) = x == fnName && y == moduleName
71+isFn _ _ = False
72+
73+isFn' :: [(String, String)] -> JS -> Bool
74+isFn' xs js = any (`isFn` js) xs
75+
76+isDict :: (String, String) -> JS -> Bool
77+isDict (moduleName, dictName) (JSAccessor x (JSVar y)) = x == dictName && y == moduleName
78+isDict _ _ = False
79+
80+isDict' :: [(String, String)] -> JS -> Bool
81+isDict' xs js = any (`isDict` js) xs
src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+188−136
@@ -1,28 +1,16 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.Inliner
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- This module provides basic inlining capabilities
133--
14−-----------------------------------------------------------------------------
15−
16−module Language.PureScript.CodeGen.JS.Optimizer.Inliner (
17− inlineVariables,
18− inlineValues,
19− inlineOperator,
20− inlineCommonOperators,
21− inlineFnComposition,
22− etaConvert,
23− unThunk,
24− evaluateIifes
25−) where
4+module Language.PureScript.CodeGen.JS.Optimizer.Inliner
5+ ( inlineVariables
6+ , inlineValues
7+ , inlineOperator
8+ , inlineCommonOperators
9+ , inlineFnComposition
10+ , etaConvert
11+ , unThunk
12+ , evaluateIifes
13+ ) where
2614
2715import Prelude ()
2816import Prelude.Compat
@@ -93,26 +81,26 @@ inlineValues :: JS -> JS
9381inlineValues = everywhereOnJS convert
9482 where
9583 convert :: JS -> JS
96− convert (JSApp fn [dict]) | isDict semiringNumber dict && isFn fnZero fn = JSNumericLiteral (Left 0)
97− | isDict semiringNumber dict && isFn fnOne fn = JSNumericLiteral (Left 1)
98− | isDict semiringInt dict && isFn fnZero fn = JSNumericLiteral (Left 0)
99− | isDict semiringInt dict && isFn fnOne fn = JSNumericLiteral (Left 1)
100− | isDict boundedBoolean dict && isFn fnBottom fn = JSBooleanLiteral False
101− | isDict boundedBoolean dict && isFn fnTop fn = JSBooleanLiteral True
84+ convert (JSApp fn [dict])
85+ | isDict' (semiringNumber ++ semiringInt) dict && isFn' fnZero fn = JSNumericLiteral (Left 0)
86+ | isDict' (semiringNumber ++ semiringInt) dict && isFn' fnOne fn = JSNumericLiteral (Left 1)
87+ | isDict' boundedBoolean dict && isFn' fnBottom fn = JSBooleanLiteral False
88+ | isDict' boundedBoolean dict && isFn' fnTop fn = JSBooleanLiteral True
10289 convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y])
103− | isDict semiringInt dict && isFn fnAdd fn = JSBinary BitwiseOr (JSBinary Add x y) (JSNumericLiteral (Left 0))
104− | isDict semiringInt dict && isFn fnMultiply fn = JSBinary BitwiseOr (JSBinary Multiply x y) (JSNumericLiteral (Left 0))
105− | isDict moduloSemiringInt dict && isFn fnDivide fn = JSBinary BitwiseOr (JSBinary Divide x y) (JSNumericLiteral (Left 0))
106− | isDict ringInt dict && isFn fnSubtract fn = JSBinary BitwiseOr (JSBinary Subtract x y) (JSNumericLiteral (Left 0))
90+ | isDict' semiringInt dict && isFn' fnAdd fn = intOp Add x y
91+ | isDict' semiringInt dict && isFn' fnMultiply fn = intOp Multiply x y
92+ | isDict' moduloSemiringInt dict && isFn' fnDivide fn = intOp Divide x y
93+ | isDict' ringInt dict && isFn' fnSubtract fn = intOp Subtract x y
10794 convert other = other
108− fnZero = (C.prelude, C.zero)
109− fnOne = (C.prelude, C.one)
110− fnBottom = (C.prelude, C.bottom)
111− fnTop = (C.prelude, C.top)
112− fnAdd = (C.prelude, (C.+))
113− fnDivide = (C.prelude, (C./))
114− fnMultiply = (C.prelude, (C.*))
115− fnSubtract = (C.prelude, (C.-))
95+ fnZero = [(C.prelude, C.zero), (C.dataSemiring, C.zero)]
96+ fnOne = [(C.prelude, C.one), (C.dataSemiring, C.one)]
97+ fnBottom = [(C.prelude, C.bottom), (C.dataBounded, C.bottom)]
98+ fnTop = [(C.prelude, C.top), (C.dataBounded, C.top)]
99+ fnAdd = [(C.prelude, (C.+)), (C.prelude, (C.add)), (C.dataSemiring, (C.+)), (C.dataSemiring, (C.add))]
100+ fnDivide = [(C.prelude, (C./)), (C.prelude, (C.div)), (C.dataModuloSemiring, C.div)]
101+ fnMultiply = [(C.prelude, (C.*)), (C.prelude, (C.mul)), (C.dataSemiring, (C.*)), (C.dataSemiring, (C.mul))]
102+ fnSubtract = [(C.prelude, (C.-)), (C.prelude, C.sub), (C.dataRing, C.sub)]
103+ intOp op x y = JSBinary BitwiseOr (JSBinary op x y) (JSNumericLiteral (Left 0))
116104
117105inlineOperator :: (String, String) -> (JS -> JS -> JS) -> JS -> JS
118106inlineOperator (m, op) f = everywhereOnJS convert
@@ -126,43 +114,54 @@ inlineOperator (m, op) f = everywhereOnJS convert
126114
127115inlineCommonOperators :: JS -> JS
128116inlineCommonOperators = applyAll $
129− [ binary semiringNumber (C.+) Add
130− , binary semiringNumber (C.*) Multiply
131−
132− , binary ringNumber (C.-) Subtract
133− , unary ringNumber C.negate Negate
134− , binary ringInt (C.-) Subtract
135− , unary ringInt C.negate Negate
136−
137− , binary moduloSemiringNumber (C./) Divide
138− , binary moduloSemiringInt C.mod Modulus
139−
140− , binary eqNumber (C.==) EqualTo
141− , binary eqNumber (C./=) NotEqualTo
142− , binary eqInt (C.==) EqualTo
143− , binary eqInt (C./=) NotEqualTo
144− , binary eqString (C.==) EqualTo
145− , binary eqString (C./=) NotEqualTo
146− , binary eqBoolean (C.==) EqualTo
147− , binary eqBoolean (C./=) NotEqualTo
148−
149− , binary ordNumber (C.<) LessThan
150− , binary ordNumber (C.>) GreaterThan
151− , binary ordNumber (C.<=) LessThanOrEqualTo
152− , binary ordNumber (C.>=) GreaterThanOrEqualTo
153− , binary ordInt (C.<) LessThan
154− , binary ordInt (C.>) GreaterThan
155− , binary ordInt (C.<=) LessThanOrEqualTo
156− , binary ordInt (C.>=) GreaterThanOrEqualTo
157−
158− , binary semigroupString (C.<>) Add
159− , binary semigroupString (C.++) Add
160−
161− , binary booleanAlgebraBoolean (C.&&) And
162− , binary booleanAlgebraBoolean (C.||) Or
163− , binaryFunction booleanAlgebraBoolean C.conj And
164− , binaryFunction booleanAlgebraBoolean C.disj Or
165− , unary booleanAlgebraBoolean C.not Not
117+ [ binary semiringNumber opAdd Add
118+ , binary semiringNumber opMul Multiply
119+
120+ , binary ringNumber opSub Subtract
121+ , unary ringNumber opNegate Negate
122+ , binary ringInt opSub Subtract
123+ , unary ringInt opNegate Negate
124+
125+ , binary moduloSemiringNumber opDiv Divide
126+ , binary moduloSemiringInt opMod Modulus
127+
128+ , binary eqNumber opEq EqualTo
129+ , binary eqNumber opNotEq NotEqualTo
130+ , binary eqInt opEq EqualTo
131+ , binary eqInt opNotEq NotEqualTo
132+ , binary eqString opEq EqualTo
133+ , binary eqString opNotEq NotEqualTo
134+ , binary eqChar opEq EqualTo
135+ , binary eqChar opNotEq NotEqualTo
136+ , binary eqBoolean opEq EqualTo
137+ , binary eqBoolean opNotEq NotEqualTo
138+
139+ , binary ordBoolean opLessThan LessThan
140+ , binary ordBoolean opLessThanOrEq LessThanOrEqualTo
141+ , binary ordBoolean opGreaterThan GreaterThan
142+ , binary ordBoolean opGreaterThanOrEq GreaterThanOrEqualTo
143+ , binary ordChar opLessThan LessThan
144+ , binary ordChar opLessThanOrEq LessThanOrEqualTo
145+ , binary ordChar opGreaterThan GreaterThan
146+ , binary ordChar opGreaterThanOrEq GreaterThanOrEqualTo
147+ , binary ordInt opLessThan LessThan
148+ , binary ordInt opLessThanOrEq LessThanOrEqualTo
149+ , binary ordInt opGreaterThan GreaterThan
150+ , binary ordInt opGreaterThanOrEq GreaterThanOrEqualTo
151+ , binary ordNumber opLessThan LessThan
152+ , binary ordNumber opLessThanOrEq LessThanOrEqualTo
153+ , binary ordNumber opGreaterThan GreaterThan
154+ , binary ordNumber opGreaterThanOrEq GreaterThanOrEqualTo
155+ , binary ordString opLessThan LessThan
156+ , binary ordString opLessThanOrEq LessThanOrEqualTo
157+ , binary ordString opGreaterThan GreaterThan
158+ , binary ordString opGreaterThanOrEq GreaterThanOrEqualTo
159+
160+ , binary semigroupString opAppend Add
161+
162+ , binary booleanAlgebraBoolean opConj And
163+ , binary booleanAlgebraBoolean opDisj Or
164+ , unary booleanAlgebraBoolean opNot Not
166165
167166 , binary' C.dataIntBits (C..|.) BitwiseOr
168167 , binary' C.dataIntBits (C..&.) BitwiseAnd
@@ -174,11 +173,11 @@ inlineCommonOperators = applyAll $
174173 ] ++
175174 [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
176175 where
177− binary :: (String, String) -> String -> BinaryOperator -> JS -> JS
178− binary dict opString op = everywhereOnJS convert
176+ binary :: [(String, String)] -> [(String, String)] -> BinaryOperator -> JS -> JS
177+ binary dict fns op = everywhereOnJS convert
179178 where
180179 convert :: JS -> JS
181− convert (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) | isDict dict dict' && isPreludeFn opString fn = JSBinary op x y
180+ convert (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) | isDict' dict dict' && isFn' fns fn = JSBinary op x y
182181 convert other = other
183182 binary' :: String -> String -> BinaryOperator -> JS -> JS
184183 binary' moduleName opString op = everywhereOnJS convert
@@ -186,17 +185,11 @@ inlineCommonOperators = applyAll $
186185 convert :: JS -> JS
187186 convert (JSApp (JSApp fn [x]) [y]) | isFn (moduleName, opString) fn = JSBinary op x y
188187 convert other = other
189− binaryFunction :: (String, String) -> String -> BinaryOperator -> JS -> JS
190− binaryFunction dict fnName op = everywhereOnJS convert
191− where
192− convert :: JS -> JS
193− convert (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) | isPreludeFn fnName fn && isDict dict dict' = JSBinary op x y
194− convert other = other
195− unary :: (String, String) -> String -> UnaryOperator -> JS -> JS
196− unary dict fnName op = everywhereOnJS convert
188+ unary :: [(String, String)] -> [(String, String)] -> UnaryOperator -> JS -> JS
189+ unary dicts fns op = everywhereOnJS convert
197190 where
198191 convert :: JS -> JS
199− convert (JSApp (JSApp fn [dict']) [x]) | isPreludeFn fnName fn && isDict dict dict' = JSUnary op x
192+ convert (JSApp (JSApp fn [dict']) [x]) | isDict' dicts dict' && isFn' fns fn = JSUnary op x
200193 convert other = other
201194 unary' :: String -> String -> UnaryOperator -> JS -> JS
202195 unary' moduleName fnName op = everywhereOnJS convert
@@ -246,71 +239,130 @@ inlineFnComposition :: (Applicative m, MonadSupply m) => JS -> m JS
246239inlineFnComposition = everywhereOnJSTopDownM convert
247240 where
248241 convert :: (MonadSupply m) => JS -> m JS
249− convert (JSApp (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) [z]) | isFnCompose dict' fn =
250− return $ JSApp x [JSApp y [z]]
251− convert (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) | isFnCompose dict' fn = do
252− arg <- freshName
253− return $ JSFunction Nothing [arg] (JSBlock [JSReturn $ JSApp x [JSApp y [JSVar arg]]])
242+ convert (JSApp (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) [z])
243+ | isFnCompose dict' fn = return $ JSApp x [JSApp y [z]]
244+ | isFnComposeFlipped dict' fn = return $ JSApp y [JSApp x [z]]
245+ convert (JSApp (JSApp (JSApp fn [dict']) [x]) [y])
246+ | isFnCompose dict' fn = do
247+ arg <- freshName
248+ return $ JSFunction Nothing [arg] (JSBlock [JSReturn $ JSApp x [JSApp y [JSVar arg]]])
249+ | isFnComposeFlipped dict' fn = do
250+ arg <- freshName
251+ return $ JSFunction Nothing [arg] (JSBlock [JSReturn $ JSApp y [JSApp x [JSVar arg]]])
254252 convert other = return other
255253 isFnCompose :: JS -> JS -> Bool
256− isFnCompose dict' fn = isDict semigroupoidFn dict' && (isPreludeFn (C.<<<) fn || isPreludeFn C.compose fn)
254+ isFnCompose dict' fn = isDict' semigroupoidFn dict' && isFn' fnCompose fn
255+ isFnComposeFlipped :: JS -> JS -> Bool
256+ isFnComposeFlipped dict' fn = isDict' semigroupoidFn dict' && isFn' fnComposeFlipped fn
257+ fnCompose :: [(String, String)]
258+ fnCompose = [(C.prelude, C.compose), (C.prelude, (C.<<<)), (C.controlSemigroupoid, C.compose)]
259+ fnComposeFlipped :: [(String, String)]
260+ fnComposeFlipped = [(C.prelude, (C.>>>)), (C.controlSemigroupoid, C.composeFlipped)]
261+
262+semiringNumber :: [(String, String)]
263+semiringNumber = [(C.prelude, C.semiringNumber), (C.dataSemiring, C.semiringNumber)]
264+
265+semiringInt :: [(String, String)]
266+semiringInt = [(C.prelude, C.semiringInt), (C.dataSemiring, C.semiringInt)]
267+
268+ringNumber :: [(String, String)]
269+ringNumber = [(C.prelude, C.ringNumber), (C.dataRing, C.ringNumber)]
270+
271+ringInt :: [(String, String)]
272+ringInt = [(C.prelude, C.ringInt), (C.dataRing, C.ringInt)]
273+
274+moduloSemiringNumber :: [(String, String)]
275+moduloSemiringNumber = [(C.prelude, C.moduloSemiringNumber), (C.dataModuloSemiring, C.moduloSemiringNumber)]
276+
277+moduloSemiringInt :: [(String, String)]
278+moduloSemiringInt = [(C.prelude, C.moduloSemiringInt), (C.dataModuloSemiring, C.moduloSemiringInt)]
279+
280+eqNumber :: [(String, String)]
281+eqNumber = [(C.prelude, C.eqNumber), (C.dataEq, C.eqNumber)]
282+
283+eqInt :: [(String, String)]
284+eqInt = [(C.prelude, C.eqInt), (C.dataEq, C.eqInt)]
285+
286+eqString :: [(String, String)]
287+eqString = [(C.prelude, C.eqString), (C.dataEq, C.eqString)]
288+
289+eqChar :: [(String, String)]
290+eqChar = [(C.prelude, C.eqChar), (C.dataEq, C.eqChar)]
291+
292+eqBoolean :: [(String, String)]
293+eqBoolean = [(C.prelude, C.eqBoolean), (C.dataEq, C.eqBoolean)]
294+
295+ordBoolean :: [(String, String)]
296+ordBoolean = [(C.prelude, C.ordBoolean), (C.dataOrd, C.ordBoolean)]
297+
298+ordNumber :: [(String, String)]
299+ordNumber = [(C.prelude, C.ordNumber), (C.dataOrd, C.ordNumber)]
300+
301+ordInt :: [(String, String)]
302+ordInt = [(C.prelude, C.ordInt), (C.dataOrd, C.ordInt)]
303+
304+ordString :: [(String, String)]
305+ordString = [(C.prelude, C.ordString), (C.dataOrd, C.ordString)]
306+
307+ordChar :: [(String, String)]
308+ordChar = [(C.prelude, C.ordChar), (C.dataOrd, C.ordChar)]
309+
310+semigroupString :: [(String, String)]
311+semigroupString = [(C.prelude, C.semigroupString), (C.dataSemigroup, C.semigroupString)]
257312
258−isDict :: (String, String) -> JS -> Bool
259−isDict (moduleName, dictName) (JSAccessor x (JSVar y)) = x == dictName && y == moduleName
260−isDict _ _ = False
313+boundedBoolean :: [(String, String)]
314+boundedBoolean = [(C.prelude, C.boundedBoolean), (C.dataBounded, C.boundedBoolean)]
261315
262−isFn :: (String, String) -> JS -> Bool
263−isFn (moduleName, fnName) (JSAccessor x (JSVar y)) = x == fnName && y == moduleName
264−isFn (moduleName, fnName) (JSIndexer (JSStringLiteral x) (JSVar y)) = x == fnName && y == moduleName
265−isFn _ _ = False
316+booleanAlgebraBoolean :: [(String, String)]
317+booleanAlgebraBoolean = [(C.prelude, C.booleanAlgebraBoolean), (C.dataBooleanAlgebra, C.booleanAlgebraBoolean)]
266318
267−isPreludeFn :: String -> JS -> Bool
268−isPreludeFn fnName = isFn (C.prelude, fnName)
319+semigroupoidFn :: [(String, String)]
320+semigroupoidFn = [(C.prelude, C.semigroupoidFn), (C.controlSemigroupoid, C.semigroupoidFn)]
269321
270−semiringNumber :: (String, String)
271−semiringNumber = (C.prelude, C.semiringNumber)
322+opAdd :: [(String, String)]
323+opAdd = [(C.prelude, (C.+)), (C.prelude, C.add), (C.dataSemiring, C.add)]
272324
273−semiringInt :: (String, String)
274−semiringInt = (C.prelude, C.semiringInt)
325+opMul :: [(String, String)]
326+opMul = [(C.prelude, (C.*)), (C.prelude, C.mul), (C.dataSemiring, C.mul)]
275327
276−ringNumber :: (String, String)
277−ringNumber = (C.prelude, C.ringNumber)
328+opEq :: [(String, String)]
329+opEq = [(C.prelude, (C.==)), (C.prelude, C.eq), (C.dataEq, C.eq)]
278330
279−ringInt :: (String, String)
280−ringInt = (C.prelude, C.ringInt)
331+opNotEq :: [(String, String)]
332+opNotEq = [(C.prelude, (C./=)), (C.dataEq, C.notEq)]
281333
282−moduloSemiringNumber :: (String, String)
283−moduloSemiringNumber = (C.prelude, C.moduloSemiringNumber)
334+opLessThan :: [(String, String)]
335+opLessThan = [(C.prelude, (C.<)), (C.dataOrd, C.lessThan)]
284336
285−moduloSemiringInt :: (String, String)
286−moduloSemiringInt = (C.prelude, C.moduloSemiringInt)
337+opLessThanOrEq :: [(String, String)]
338+opLessThanOrEq = [(C.prelude, (C.<=)), (C.dataOrd, C.lessThanOrEq)]
287339
288−eqNumber :: (String, String)
289−eqNumber = (C.prelude, C.eqNumber)
340+opGreaterThan :: [(String, String)]
341+opGreaterThan = [(C.prelude, (C.>)), (C.dataOrd, C.greaterThan)]
290342
291−eqInt :: (String, String)
292−eqInt = (C.prelude, C.eqInt)
343+opGreaterThanOrEq :: [(String, String)]
344+opGreaterThanOrEq = [(C.prelude, (C.>=)), (C.dataOrd, C.greaterThanOrEq)]
293345
294−eqString :: (String, String)
295−eqString = (C.prelude, C.eqNumber)
346+opAppend :: [(String, String)]
347+opAppend = [(C.prelude, (C.<>)), (C.prelude, (C.++)), (C.prelude, C.append), (C.dataSemigroup, C.append)]
296348
297−eqBoolean :: (String, String)
298−eqBoolean = (C.prelude, C.eqNumber)
349+opSub :: [(String, String)]
350+opSub = [(C.prelude, (C.-)), (C.prelude, C.sub), (C.dataRing, C.sub)]
299351
300−ordNumber :: (String, String)
301−ordNumber = (C.prelude, C.ordNumber)
352+opNegate :: [(String, String)]
353+opNegate = [(C.prelude, C.negate), (C.dataRing, C.negate)]
302354
303−ordInt :: (String, String)
304−ordInt = (C.prelude, C.ordInt)
355+opDiv :: [(String, String)]
356+opDiv = [(C.prelude, (C./)), (C.prelude, C.div), (C.dataModuloSemiring, C.div)]
305357
306−semigroupString :: (String, String)
307−semigroupString = (C.prelude, C.semigroupString)
358+opMod :: [(String, String)]
359+opMod = [(C.prelude, C.mod), (C.dataModuloSemiring, C.mod)]
308360
309−boundedBoolean :: (String, String)
310−boundedBoolean = (C.prelude, C.boundedBoolean)
361+opConj :: [(String, String)]
362+opConj = [(C.prelude, (C.&&)), (C.prelude, C.conj), (C.dataBooleanAlgebra, C.conj)]
311363
312−booleanAlgebraBoolean :: (String, String)
313−booleanAlgebraBoolean = (C.prelude, C.booleanAlgebraBoolean)
364+opDisj :: [(String, String)]
365+opDisj = [(C.prelude, (C.||)), (C.prelude, C.disj), (C.dataBooleanAlgebra, C.disj)]
314366
315−semigroupoidFn :: (String, String)
316−semigroupoidFn = (C.prelude, C.semigroupoidFn)
367+opNot :: [(String, String)]
368+opNot = [(C.prelude, C.not), (C.dataBooleanAlgebra, C.not)]
src/Language/PureScript/CodeGen/JS/Optimizer/MagicDo.hs+11−42
@@ -1,29 +1,14 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.MagicDo
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- This module implements the "Magic Do" optimization, which inlines calls to return
133-- and bind for the Eff monad, as well as some of its actions.
144--
15−-----------------------------------------------------------------------------
16−
17−module Language.PureScript.CodeGen.JS.Optimizer.MagicDo (
18− magicDo
19−) where
5+module Language.PureScript.CodeGen.JS.Optimizer.MagicDo (magicDo) where
206
217import Data.List (nub)
228import Data.Maybe (fromJust, isJust)
239
2410import Language.PureScript.CodeGen.JS.AST
25−import Language.PureScript.CodeGen.JS.Common
26−import Language.PureScript.Names
11+import Language.PureScript.CodeGen.JS.Optimizer.Common
2712import Language.PureScript.Options
2813import qualified Language.PureScript.Constants as C
2914
@@ -54,9 +39,7 @@ magicDo' = everywhereOnJS undo . everywhereOnJSTopDown convert
5439 fnName = "__do"
5540 -- Desugar monomorphic calls to >>= and return for the Eff monad
5641 convert :: JS -> JS
57− -- Desugar return
58− convert (JSApp (JSApp ret [val]) []) | isReturn ret = val
59− -- Desugar pure
42+ -- Desugar pure & return
6043 convert (JSApp (JSApp pure' [val]) []) | isPure pure' = val
6144 -- Desugar >>
6245 convert (JSApp (JSApp bind [m]) [JSFunction Nothing [] (JSBlock js)]) | isBind bind =
@@ -72,33 +55,19 @@ magicDo' = everywhereOnJS undo . everywhereOnJSTopDown convert
7255 JSApp (JSFunction Nothing [] (JSBlock [ JSWhile (JSApp arg1 []) (JSBlock [ JSApp arg2 [] ]), JSReturn $ JSObjectLiteral []])) []
7356 convert other = other
7457 -- Check if an expression represents a monomorphic call to >>= for the Eff monad
75− isBind (JSApp bindPoly [effDict]) | isBindPoly bindPoly && isEffDict C.bindEffDictionary effDict = True
58+ isBind (JSApp fn [dict]) | isDict (C.eff, C.bindEffDictionary) dict && isBindPoly fn = True
7659 isBind _ = False
77− -- Check if an expression represents a monomorphic call to return for the Eff monad
78− isReturn (JSApp retPoly [effDict]) | isRetPoly retPoly && isEffDict C.monadEffDictionary effDict = True
79− isReturn _ = False
80− -- Check if an expression represents a monomorphic call to pure for the Eff applicative
81− isPure (JSApp purePoly [effDict]) | isPurePoly purePoly && isEffDict C.applicativeEffDictionary effDict = True
60+ -- Check if an expression represents a monomorphic call to pure or return for the Eff applicative
61+ isPure (JSApp fn [dict]) | isDict (C.eff, C.applicativeEffDictionary) dict && isPurePoly fn = True
8262 isPure _ = False
8363 -- Check if an expression represents the polymorphic >>= function
84− isBindPoly (JSAccessor prop (JSVar prelude)) = prelude == C.prelude && (prop `elem` map identToJs [Ident C.bind, Op (C.>>=)])
85− isBindPoly (JSIndexer (JSStringLiteral bind) (JSVar prelude)) = prelude == C.prelude && (bind `elem` [C.bind, (C.>>=)])
86− isBindPoly _ = False
87− -- Check if an expression represents the polymorphic return function
88− isRetPoly (JSAccessor returnEscaped (JSVar prelude)) = prelude == C.prelude && returnEscaped == C.returnEscaped
89− isRetPoly (JSIndexer (JSStringLiteral return') (JSVar prelude)) = prelude == C.prelude && return' == C.return
90− isRetPoly _ = False
91− -- Check if an expression represents the polymorphic pure function
92− isPurePoly (JSAccessor pure' (JSVar prelude)) = prelude == C.prelude && pure' == C.pure'
93− isPurePoly (JSIndexer (JSStringLiteral pure') (JSVar prelude)) = prelude == C.prelude && pure' == C.pure'
94− isPurePoly _ = False
95− -- Check if an expression represents a function in the Ef module
64+ isBindPoly = isFn' [(C.prelude, C.bind), (C.prelude, (C.>>=)), (C.controlBind, C.bind)]
65+ -- 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')]
67+ -- Check if an expression represents a function in the Eff module
9668 isEffFunc name (JSAccessor name' (JSVar eff)) = eff == C.eff && name == name'
9769 isEffFunc _ _ = False
98− -- Check if an expression represents the Monad Eff dictionary
99− isEffDict name (JSVar ident) | ident == name = True
100− isEffDict name (JSAccessor prop (JSVar eff)) = eff == C.eff && prop == name
101− isEffDict _ _ = False
70+
10271 -- Remove __do function applications which remain after desugaring
10372 undo :: JS -> JS
10473 undo (JSReturn (JSApp (JSFunction (Just ident) [] body) [])) | ident == fnName = body
src/Language/PureScript/Constants.hs+101−23
@@ -1,18 +1,6 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Constants
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- Various constants which refer to things in the Prelude
133--
14−-----------------------------------------------------------------------------
15−
164module Language.PureScript.Constants where
175
186-- Operators
@@ -20,59 +8,107 @@ module Language.PureScript.Constants where
208($) :: String
219($) = "$"
2210
11+apply :: String
12+apply = "apply"
13+
2314(#) :: String
2415(#) = "#"
2516
17+applyFlipped :: String
18+applyFlipped = "applyFlipped"
19+
2620(<>) :: String
2721(<>) = "<>"
2822
2923(++) :: String
3024(++) = "++"
3125
26+append :: String
27+append = "append"
28+
3229(>>=) :: String
3330(>>=) = ">>="
3431
32+bind :: String
33+bind = "bind"
34+
3535(+) :: String
3636(+) = "+"
3737
38+add :: String
39+add = "add"
40+
3841(-) :: String
3942(-) = "-"
4043
44+sub :: String
45+sub = "sub"
46+
4147(*) :: String
4248(*) = "*"
4349
50+mul :: String
51+mul = "mul"
52+
4453(/) :: String
4554(/) = "/"
4655
56+div :: String
57+div = "div"
58+
4759(%) :: String
4860(%) = "%"
4961
62+mod :: String
63+mod = "mod"
64+
5065(<) :: String
5166(<) = "<"
5267
68+lessThan :: String
69+lessThan = "lessThan"
70+
5371(>) :: String
5472(>) = ">"
5573
74+greaterThan :: String
75+greaterThan = "greaterThan"
76+
5677(<=) :: String
5778(<=) = "<="
5879
80+lessThanOrEq :: String
81+lessThanOrEq = "lessThanOrEq"
82+
5983(>=) :: String
6084(>=) = ">="
6185
86+greaterThanOrEq :: String
87+greaterThanOrEq = "greaterThanOrEq"
88+
6289(==) :: String
6390(==) = "=="
6491
92+eq :: String
93+eq = "eq"
94+
6595(/=) :: String
6696(/=) = "/="
6797
98+notEq :: String
99+notEq = "notEq"
100+
68101(&&) :: String
69102(&&) = "&&"
70103
104+conj :: String
105+conj = "conj"
106+
71107(||) :: String
72108(||) = "||"
73109
74−bind :: String
75−bind = "bind"
110+disj :: String
111+disj = "disj"
76112
77113unsafeIndex :: String
78114unsafeIndex = "unsafeIndex"
@@ -92,6 +128,12 @@ unsafeIndex = "unsafeIndex"
92128compose :: String
93129compose = "compose"
94130
131+(>>>) :: String
132+(>>>) = ">>>"
133+
134+composeFlipped :: String
135+composeFlipped = "composeFlipped"
136+
95137-- Functions
96138
97139negate :: String
@@ -100,15 +142,6 @@ negate = "negate"
100142not :: String
101143not = "not"
102144
103−conj :: String
104−conj = "conj"
105−
106−disj :: String
107−disj = "disj"
108−
109−mod :: String
110−mod = "mod"
111−
112145shl :: String
113146shl = "shl"
114147
@@ -211,12 +244,21 @@ moduloSemiringNumber = "moduloSemiringNumber"
211244moduloSemiringInt :: String
212245moduloSemiringInt = "moduloSemiringInt"
213246
247+ordBoolean :: String
248+ordBoolean = "ordBoolean"
249+
214250ordNumber :: String
215251ordNumber = "ordNumber"
216252
217253ordInt :: String
218254ordInt = "ordInt"
219255
256+ordString :: String
257+ordString = "ordString"
258+
259+ordChar :: String
260+ordChar = "ordChar"
261+
220262eqNumber :: String
221263eqNumber = "eqNumber"
222264
@@ -226,6 +268,9 @@ eqInt = "eqInt"
226268eqString :: String
227269eqString = "eqString"
228270
271+eqChar :: String
272+eqChar = "eqChar"
273+
229274eqBoolean :: String
230275eqBoolean = "eqBoolean"
231276
@@ -285,6 +330,39 @@ eff = "Control_Monad_Eff"
285330st :: String
286331st = "Control_Monad_ST"
287332
333+controlApplicative :: String
334+controlApplicative = "Control_Applicative"
335+
336+controlSemigroupoid :: String
337+controlSemigroupoid = "Control_Semigroupoid"
338+
339+controlBind :: String
340+controlBind = "Control_Bind"
341+
342+dataBounded :: String
343+dataBounded = "Data_Bounded"
344+
345+dataSemigroup :: String
346+dataSemigroup = "Data_Semigroup"
347+
348+dataModuloSemiring :: String
349+dataModuloSemiring = "Data_ModuloSemiring"
350+
351+dataBooleanAlgebra :: String
352+dataBooleanAlgebra = "Data_BooleanAlgebra"
353+
354+dataEq :: String
355+dataEq = "Data_Eq"
356+
357+dataOrd :: String
358+dataOrd = "Data_Ord"
359+
360+dataSemiring :: String
361+dataSemiring = "Data_Semiring"
362+
363+dataRing :: String
364+dataRing = "Data_Ring"
365+
288366dataFunction :: String
289367dataFunction = "Data_Function"
290368
src/Language/PureScript/CoreFn/Traversals.hs+1
@@ -40,6 +40,7 @@ everywhereOnValues f g h = (f', g', h')
4040
4141 h' (LiteralBinder a b) = h (LiteralBinder a (handleLiteral h' b))
4242 h' (NamedBinder a name b) = h (NamedBinder a name (h' b))
43+ h' (ConstructorBinder a q1 q2 bs) = h (ConstructorBinder a q1 q2 (map h' bs))
4344 h' b = h b
4445
4546 handleCaseAlternative ca =
src/Language/PureScript/Docs/Convert/ReExports.hs+78−36
@@ -13,6 +13,8 @@ import Prelude.Compat
1313import Control.Monad
1414import Control.Monad.Trans.State.Strict (execState)
1515import Control.Monad.State.Class (MonadState, gets, modify)
16+import Control.Monad.Trans.Reader (runReaderT)
17+import Control.Monad.Reader.Class (MonadReader, ask)
1618import Control.Arrow ((&&&), first, second)
1719import Data.Either
1820import Data.Maybe (mapMaybe)
@@ -76,9 +78,12 @@ getReExports env mn =
7678 case Map.lookup mn env of
7779 Nothing ->
7880 internalError ("Module missing: " ++ P.runModuleName mn)
79− Just (_, imports, exports) ->
80− let notLocal = (/= mn) . fst
81− in filter notLocal <$> collectDeclarations imports exports
81+ Just (_, imports, exports) -> do
82+ allExports <- runReaderT (collectDeclarations imports exports) mn
83+ pure (filter notLocal allExports)
84+
85+ where
86+ notLocal = (/= mn) . fst
8287
8388-- |
8489-- Assemble a list of declarations re-exported from a particular module, based
@@ -100,7 +105,9 @@ getReExports env mn =
100105-- class members are listed.
101106--
102107collectDeclarations ::
103− (Functor m, Applicative m, MonadState (Map P.ModuleName Module) m) =>
108+ (Functor m, Applicative m,
109+ MonadState (Map P.ModuleName Module) m,
110+ MonadReader P.ModuleName m) =>
104111 P.Imports ->
105112 P.Exports ->
106113 m [(P.ModuleName, [Declaration])]
@@ -109,7 +116,7 @@ collectDeclarations imports exports = do
109116 typeClasses <- collect lookupTypeClassDeclaration impTCs expTCs
110117 types <- collect lookupTypeDeclaration impTypes expTypes
111118
112− let (vals, classes) = handleTypeClassMembers valsAndMembers typeClasses
119+ (vals, classes) <- handleTypeClassMembers valsAndMembers typeClasses
113120
114121 let filteredTypes = filterDataConstructors expCtors types
115122 let filteredClasses = filterTypeClassMembers (map fst expVals) classes
@@ -117,9 +124,9 @@ collectDeclarations imports exports = do
117124 pure (Map.toList (Map.unionsWith (<>) [filteredTypes, filteredClasses, vals]))
118125
119126 where
120− collect lookup' imps exps =
121− Map.fromListWith (<>) <$> traverse (uncurry lookup')
122− (map (findImport imps) exps)
127+ collect lookup' imps exps = do
128+ imps' <- traverse (findImport imps) exps
129+ Map.fromListWith (<>) <$> traverse (uncurry lookup') imps'
123130
124131 expVals = P.exportedValues exports
125132 impVals = concat (Map.elems (P.importedValues imports))
@@ -147,19 +154,29 @@ collectDeclarations imports exports = do
147154-- instantiate @name@ as both 'P.Ident' and 'P.ProperName'.
148155--
149156findImport ::
150− (Show name, Eq name) =>
157+ (Show name, Eq name, Applicative m, MonadReader P.ModuleName m) =>
151158 [(P.Qualified name, P.ModuleName)] ->
152159 (name, P.ModuleName) ->
153− (P.ModuleName, name)
160+ m (P.ModuleName, name)
154161findImport imps (name, orig) =
155− case filter (\(qual, mn) -> P.disqualify qual == name && mn == orig) imps of
156− [(P.Qualified (Just importedFrom) _, _)] ->
157− (importedFrom, name)
158− other ->
159− internalError ("findImport: unexpected result: " ++ show other)
162+ let
163+ matches (qual, mn) = P.disqualify qual == name && mn == orig
164+ matching = filter matches imps
165+ getQualified (P.Qualified mname _) = mname
166+ in
167+ case mapMaybe (getQualified . fst) matching of
168+ -- A value can occur more than once if it is imported twice (eg, if it is
169+ -- exported by A, re-exported from A by B, and C imports it from both A
170+ -- and B). In this case, we just take its first appearance.
171+ (importedFrom:_) ->
172+ pure (importedFrom, name)
173+ [] ->
174+ internalErrorInModule ("findImport: not found: " ++ show (name, orig))
160175
161176lookupValueDeclaration ::
162− (MonadState (Map P.ModuleName Module) m, Applicative m) =>
177+ (Applicative m,
178+ MonadState (Map P.ModuleName Module) m,
179+ MonadReader P.ModuleName m) =>
163180 P.ModuleName ->
164181 P.Ident ->
165182 m (P.ModuleName, [Either (String, P.Constraint, ChildDeclaration) Declaration])
@@ -170,7 +187,7 @@ lookupValueDeclaration importedFrom ident = do
170187 filter (\d -> declTitle d == P.showIdent ident
171188 && (isValue d || isAlias d)) decls
172189 errOther other =
173− internalError
190+ internalErrorInModule
174191 ("lookupValueDeclaration: unexpected result:\n" ++
175192 "other: " ++ show other ++ "\n" ++
176193 "ident: " ++ show ident ++ "\n" ++
@@ -216,7 +233,9 @@ lookupValueDeclaration importedFrom ident = do
216233-- are only included in the output if they are listed in the arguments.
217234--
218235lookupTypeDeclaration ::
219− (MonadState (Map P.ModuleName Module) m, Applicative m) =>
236+ (Applicative m,
237+ MonadState (Map P.ModuleName Module) m,
238+ MonadReader P.ModuleName m) =>
220239 P.ModuleName ->
221240 P.ProperName 'P.TypeName ->
222241 m (P.ModuleName, [Declaration])
@@ -228,11 +247,13 @@ lookupTypeDeclaration importedFrom ty = do
228247 [d] ->
229248 pure (importedFrom, [d])
230249 other ->
231− internalError
250+ internalErrorInModule
232251 ("lookupTypeDeclaration: unexpected result: " ++ show other)
233252
234253lookupTypeClassDeclaration ::
235− (MonadState (Map P.ModuleName Module) m, Applicative m) =>
254+ (Applicative m,
255+ MonadState (Map P.ModuleName Module) m,
256+ MonadReader P.ModuleName m) =>
236257 P.ModuleName ->
237258 P.ProperName 'P.ClassName ->
238259 m (P.ModuleName, [Declaration])
@@ -246,15 +267,18 @@ lookupTypeClassDeclaration importedFrom tyClass = do
246267 [d] ->
247268 pure (importedFrom, [d])
248269 other ->
249− internalError ("lookupTypeClassDeclaration: unexpected result: "
250− ++ (unlines . map show) other)
270+ internalErrorInModule
271+ ("lookupTypeClassDeclaration: unexpected result: "
272+ ++ (unlines . map show) other)
251273
252274-- |
253275-- Get the full list of declarations for a particular module out of the
254276-- state, or raise an internal error if it is not there.
255277--
256278lookupModuleDeclarations ::
257− (Applicative m, MonadState (Map P.ModuleName Module) m) =>
279+ (Applicative m,
280+ MonadState (Map P.ModuleName Module) m,
281+ MonadReader P.ModuleName m) =>
258282 String ->
259283 P.ModuleName ->
260284 m [Declaration]
@@ -262,15 +286,18 @@ lookupModuleDeclarations definedIn moduleName = do
262286 mmdl <- gets (Map.lookup moduleName)
263287 case mmdl of
264288 Nothing ->
265− internalError (definedIn ++ ": module missing: "
266− ++ P.runModuleName moduleName)
289+ internalErrorInModule
290+ (definedIn ++ ": module missing: "
291+ ++ P.runModuleName moduleName)
267292 Just mdl ->
268293 pure (allDeclarations mdl)
269294
270295handleTypeClassMembers ::
296+ (Functor m, Applicative m,
297+ MonadReader P.ModuleName m) =>
271298 Map P.ModuleName [Either (String, P.Constraint, ChildDeclaration) Declaration] ->
272299 Map P.ModuleName [Declaration] ->
273− (Map P.ModuleName [Declaration], Map P.ModuleName [Declaration])
300+ m (Map P.ModuleName [Declaration], Map P.ModuleName [Declaration])
274301handleTypeClassMembers valsAndMembers typeClasses =
275302 let
276303 moduleEnvs =
@@ -279,8 +306,8 @@ handleTypeClassMembers valsAndMembers typeClasses =
279306 (fmap typeClassesToEnv typeClasses)
280307 in
281308 moduleEnvs
282− |> fmap handleEnv
283− |> splitMap
309+ |> traverse handleEnv
310+ |> fmap splitMap
284311
285312valsAndMembersToEnv ::
286313 [Either (String, P.Constraint, ChildDeclaration) Declaration] -> TypeClassEnv
@@ -336,11 +363,15 @@ instance Monoid TypeClassEnv where
336363--
337364-- Returns a tuple of (values, type classes).
338365--
339−handleEnv :: TypeClassEnv -> ([Declaration], [Declaration])
366+handleEnv ::
367+ (Functor m, Applicative m,
368+ MonadReader P.ModuleName m) =>
369+ TypeClassEnv ->
370+ m ([Declaration], [Declaration])
340371handleEnv TypeClassEnv{..} =
341372 envUnhandledMembers
342− |> foldl go (envValues, mkMap envTypeClasses)
343− |> second Map.elems
373+ |> foldM go (envValues, mkMap envTypeClasses)
374+ |> fmap (second Map.elems)
344375
345376 where
346377 mkMap =
@@ -351,14 +382,15 @@ handleEnv TypeClassEnv{..} =
351382 Just _ ->
352383 -- Leave the state unchanged; if the type class is there, the child
353384 -- will be too.
354− (values, tcs)
355− Nothing ->
356− (promoteChild constraint childDecl : values, tcs)
385+ pure (values, tcs)
386+ Nothing -> do
387+ c <- promoteChild constraint childDecl
388+ pure (c : values, tcs)
357389
358390 promoteChild constraint ChildDeclaration{..} =
359391 case cdeclInfo of
360392 ChildTypeClassMember typ ->
361− Declaration
393+ pure $ Declaration
362394 { declTitle = cdeclTitle
363395 , declComments = cdeclComments
364396 , declSourceSpan = cdeclSourceSpan
@@ -367,7 +399,7 @@ handleEnv TypeClassEnv{..} =
367399 , declInfo = ValueDeclaration (addConstraint constraint typ)
368400 }
369401 _ ->
370− internalError
402+ internalErrorInModule
371403 ("handleEnv: Bad child declaration passed to promoteChild: "
372404 ++ cdeclTitle)
373405
@@ -429,6 +461,16 @@ x |> f = f x
429461internalError :: String -> a
430462internalError = P.internalError . ("Docs.Convert.ReExports: " ++)
431463
464+internalErrorInModule ::
465+ (MonadReader P.ModuleName m) =>
466+ String ->
467+ m a
468+internalErrorInModule msg = do
469+ mn <- ask
470+ internalError
471+ ("while collecting re-exports for module: " ++ P.runModuleName mn ++
472+ ", " ++ msg)
473+
432474-- |
433475-- If the provided Declaration is a TypeClassDeclaration, construct an
434476-- appropriate Constraint for use with the types of its members.
src/Language/PureScript/Linter/Exhaustive.hs+1
@@ -203,6 +203,7 @@ isExhaustiveGuard (Left gs) = not . null $ filter (\(g, _) -> isOtherwise g) gs
203203 isOtherwise :: Expr -> Bool
204204 isOtherwise (TypedValue _ (BooleanLiteral True) _) = True
205205 isOtherwise (TypedValue _ (Var (Qualified (Just (ModuleName [ProperName "Prelude"])) (Ident "otherwise"))) _) = True
206+ isOtherwise (TypedValue _ (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "Boolean"])) (Ident "otherwise"))) _) = True
206207 isOtherwise _ = False
207208isExhaustiveGuard (Right _) = True
208209
src/Language/PureScript/ModuleDependencies.hs+6−4
@@ -23,7 +23,7 @@ import Control.Monad.Error.Class (MonadError(..))
2323
2424import Data.Graph
2525import Data.List (nub)
26−import Data.Maybe (fromMaybe, mapMaybe)
26+import Data.Maybe (fromMaybe)
2727
2828import Language.PureScript.Crash
2929import Language.PureScript.AST
@@ -54,22 +54,24 @@ sortModules ms = do
5454-- Calculate a list of used modules based on explicit imports and qualified names
5555--
5656usedModules :: Declaration -> [ModuleName]
57−usedModules = let (f, _, _, _, _) = everythingOnValues (++) forDecls forValues (const []) (const []) (const []) in nub . f
57+usedModules d =
58+ let (f, _, _, _, _) = everythingOnValues (++) forDecls forValues (const []) (const []) (const [])
59+ (g, _, _, _, _) = accumTypes (everythingOnTypes (++) forTypes)
60+ in nub (f d ++ g d)
5861 where
5962 forDecls :: Declaration -> [ModuleName]
6063 forDecls (ImportDeclaration mn _ _ _) = [mn]
6164 forDecls (FixityDeclaration _ _ (Just (Qualified (Just mn) _))) = [mn]
65+ forDecls (TypeInstanceDeclaration _ _ (Qualified (Just mn) _) _ _) = [mn]
6266 forDecls _ = []
6367
6468 forValues :: Expr -> [ModuleName]
6569 forValues (Var (Qualified (Just mn) _)) = [mn]
6670 forValues (Constructor (Qualified (Just mn) _)) = [mn]
67− forValues (TypedValue _ _ ty) = forTypes ty
6871 forValues _ = []
6972
7073 forTypes :: Type -> [ModuleName]
7174 forTypes (TypeConstructor (Qualified (Just mn) _)) = [mn]
72− forTypes (ConstrainedType cs _) = mapMaybe (\(Qualified mn _, _) -> mn) cs
7375 forTypes _ = []
7476
7577-- |
src/Language/PureScript/Sugar/TypeClasses/Deriving.hs+8−5
@@ -17,6 +17,7 @@ import Data.List (foldl', find, sortBy)
1717import Data.Maybe (fromMaybe)
1818import Data.Ord (comparing)
1919
20+import Control.Arrow (second)
2021import Control.Monad (replicateM)
2122import Control.Monad.Supply.Class (MonadSupply)
2223import Control.Monad.Error.Class (MonadError(..))
@@ -55,11 +56,13 @@ deriveInstance mn ds (PositionedDeclaration pos com d) = PositionedDeclaration p
5556deriveInstance _ _ e = return e
5657
5758unwrapTypeConstructor :: Type -> Maybe (Qualified (ProperName 'TypeName), [Type])
58−unwrapTypeConstructor (TypeConstructor tyCon) = Just (tyCon, [])
59−unwrapTypeConstructor (TypeApp ty arg) = do
60− (tyCon, args) <- unwrapTypeConstructor ty
61− return (tyCon, arg : args)
62−unwrapTypeConstructor _ = Nothing
59+unwrapTypeConstructor = fmap (second reverse) . go
60+ where
61+ go (TypeConstructor tyCon) = Just (tyCon, [])
62+ go (TypeApp ty arg) = do
63+ (tyCon, args) <- go ty
64+ return (tyCon, arg : args)
65+ go _ = Nothing
6366
6467dataGeneric :: ModuleName
6568dataGeneric = ModuleName [ ProperName "Data", ProperName "Generic" ]