git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Add psc-bundle
commitc92c7a602729a2beea034b20d630da6f9b33533b authorPhil Freeman <paf31@cantab.net> dateSun 28 Jun 2015, 15:09 (11 years ago) parent087f15b
7 files changed+848−90
LICENSE+218−89 bundle/build.sh+2 bundle/winbuild.sh+2 license-generator/generate+1−1 psc-bundle/Main.hs+589 psc-bundle/README.md+18 purescript.cabal+18
LICENSE+218−89
@@ -22,6 +22,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2222
2323PureScript uses the following Haskell library packages. Their license files follow.
2424
25+ Glob
26+ HUnit
2527 aeson
2628 aeson-better-errors
2729 ansi-terminal
@@ -29,6 +31,7 @@ PureScript uses the following Haskell library packages. Their license files foll
2931 array
3032 attoparsec
3133 base
34+ blaze-builder
3235 bower-json
3336 boxes
3437 bytestring
@@ -38,10 +41,10 @@ PureScript uses the following Haskell library packages. Their license files foll
3841 dlist
3942 filepath
4043 ghc-prim
41− Glob
4244 hashable
4345 haskeline
4446 integer-gmp
47+ language-javascript
4548 mtl
4649 nats
4750 old-locale
@@ -69,6 +72,69 @@ PureScript uses the following Haskell library packages. Their license files foll
6972 vector
7073 void
7174
75+Glob LICENSE file:
76+
77+ The code in Glob is released under the license below. Copyrights to parts of
78+ the code are held by whoever wrote the code in question: see CREDITS.txt for a
79+ list of authors.
80+
81+ Copyright (c) 2008-2012 <authors>
82+ All rights reserved.
83+
84+ Redistribution and use in source and binary forms, with or without
85+ modification, are permitted provided that the following conditions are met:
86+ * Redistributions of source code must retain the above copyright
87+ notice, this list of conditions and the following disclaimer.
88+ * Redistributions in binary form must reproduce the above copyright
89+ notice, this list of conditions and the following disclaimer in the
90+ documentation and/or other materials provided with the distribution.
91+ * Neither the name of the project nor the names of its contributors may be
92+ used to endorse or promote products derived from this software without
93+ specific prior written permission.
94+
95+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
96+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
97+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
98+ EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
99+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
100+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
101+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
102+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
103+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
104+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105+
106+HUnit LICENSE file:
107+
108+ HUnit is Copyright (c) Dean Herington, 2002, all rights reserved,
109+ and is distributed as free software under the following license.
110+
111+ Redistribution and use in source and binary forms, with or without
112+ modification, are permitted provided that the following conditions
113+ are met:
114+
115+ - Redistributions of source code must retain the above copyright
116+ notice, this list of conditions, and the following disclaimer.
117+
118+ - Redistributions in binary form must reproduce the above copyright
119+ notice, this list of conditions, and the following disclaimer in the
120+ documentation and/or other materials provided with the distribution.
121+
122+ - The names of the copyright holders may not be used to endorse or
123+ promote products derived from this software without specific prior
124+ written permission.
125+
126+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY
127+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
128+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
129+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE
130+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
131+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
132+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
133+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
134+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
135+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
136+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
137+
72138aeson LICENSE file:
73139
74140 Copyright (c) 2011, MailRank, Inc.
@@ -149,6 +215,7 @@ ansi-terminal LICENSE file:
149215 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
150216 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
151217 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
218+
152219ansi-wl-pprint LICENSE file:
153220
154221 Copyright 2008, Daan Leijen and Max Bolingbroke. All rights reserved.
@@ -382,6 +449,39 @@ base LICENSE file:
382449
383450 -----------------------------------------------------------------------------
384451
452+blaze-builder LICENSE file:
453+
454+ Copyright Jasper Van der Jeugt 2010, Simon Meier 2010 & 2011
455+
456+ All rights reserved.
457+
458+ Redistribution and use in source and binary forms, with or without
459+ modification, are permitted provided that the following conditions are met:
460+
461+ * Redistributions of source code must retain the above copyright
462+ notice, this list of conditions and the following disclaimer.
463+
464+ * Redistributions in binary form must reproduce the above
465+ copyright notice, this list of conditions and the following
466+ disclaimer in the documentation and/or other materials provided
467+ with the distribution.
468+
469+ * Neither the name of Jasper Van der Jeugt nor the names of other
470+ contributors may be used to endorse or promote products derived
471+ from this software without specific prior written permission.
472+
473+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
474+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
475+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
476+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
477+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
478+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
479+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
480+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
481+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
482+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
483+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
484+
385485bower-json LICENSE file:
386486
387487 Copyright (c) 2015 Harry Garrood
@@ -742,10 +842,6 @@ ghc-prim LICENSE file:
742842 be a definition of the Haskell 98 Language.
743843
744844
745−Glob LICENSE file:
746−
747− Page not found: Sorry, it's just not here.
748−
749845hashable LICENSE file:
750846
751847 Copyright Milan Straka 2010
@@ -838,6 +934,39 @@ integer-gmp LICENSE file:
838934 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
839935 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
840936
937+language-javascript LICENSE file:
938+
939+ Copyright (c)2010, Alan Zimmerman
940+
941+ All rights reserved.
942+
943+ Redistribution and use in source and binary forms, with or without
944+ modification, are permitted provided that the following conditions are met:
945+
946+ * Redistributions of source code must retain the above copyright
947+ notice, this list of conditions and the following disclaimer.
948+
949+ * Redistributions in binary form must reproduce the above
950+ copyright notice, this list of conditions and the following
951+ disclaimer in the documentation and/or other materials provided
952+ with the distribution.
953+
954+ * Neither the name of Alan Zimmerman nor the names of other
955+ contributors may be used to endorse or promote products derived
956+ from this software without specific prior written permission.
957+
958+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
959+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
960+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
961+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
962+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
963+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
964+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
965+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
966+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
967+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
968+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
969+
841970mtl LICENSE file:
842971
843972 The Glasgow Haskell Compiler License
@@ -1198,7 +1327,7 @@ rts LICENSE file:
11981327
11991328safe LICENSE file:
12001329
1201− Copyright Neil Mitchell 2007-2014.
1330+ Copyright Neil Mitchell 2007-2015.
12021331 All rights reserved.
12031332
12041333 Redistribution and use in source and binary forms, with or without
@@ -1323,89 +1452,89 @@ split LICENSE file:
13231452
13241453syb LICENSE file:
13251454
1326− This library (libraries/syb) is derived from code from several
1327− sources:
1328−
1329− * Code from the GHC project which is largely (c) The University of
1330− Glasgow, and distributable under a BSD-style license (see below),
1331−
1332− * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
1333− and freely redistributable (but see the full license for
1334− restrictions).
1335−
1336− * Code from the Haskell Foreign Function Interface specification,
1337− which is (c) Manuel M. T. Chakravarty and freely redistributable
1338− (but see the full license for restrictions).
1339−
1340− The full text of these licenses is reproduced below. All of the
1341− licenses are BSD-style or compatible.
1342−
1343− -----------------------------------------------------------------------------
1344−
1345− The Glasgow Haskell Compiler License
1346−
1347− Copyright 2004, The University Court of the University of Glasgow.
1348− All rights reserved.
1349−
1350− Redistribution and use in source and binary forms, with or without
1351− modification, are permitted provided that the following conditions are met:
1352−
1353− - Redistributions of source code must retain the above copyright notice,
1354− this list of conditions and the following disclaimer.
1355−
1356− - Redistributions in binary form must reproduce the above copyright notice,
1357− this list of conditions and the following disclaimer in the documentation
1358− and/or other materials provided with the distribution.
1359−
1360− - Neither name of the University nor the names of its contributors may be
1361− used to endorse or promote products derived from this software without
1362− specific prior written permission.
1363−
1364− THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
1365− GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
1366− INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1367− FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1368− UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
1369− FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1370− DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1371− SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1372− CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1373− LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1374− OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1375− DAMAGE.
1376−
1377− -----------------------------------------------------------------------------
1378−
1379− Code derived from the document "Report on the Programming Language
1380− Haskell 98", is distributed under the following license:
1381−
1382− Copyright (c) 2002 Simon Peyton Jones
1383−
1384− The authors intend this Report to belong to the entire Haskell
1385− community, and so we grant permission to copy and distribute it for
1386− any purpose, provided that it is reproduced in its entirety,
1387− including this Notice. Modified versions of this Report may also be
1388− copied and distributed for any purpose, provided that the modified
1389− version is clearly presented as such, and that it does not claim to
1390− be a definition of the Haskell 98 Language.
1391−
1392− -----------------------------------------------------------------------------
1393−
1394− Code derived from the document "The Haskell 98 Foreign Function
1395− Interface, An Addendum to the Haskell 98 Report" is distributed under
1396− the following license:
1397−
1398− Copyright (c) 2002 Manuel M. T. Chakravarty
1399−
1400− The authors intend this Report to belong to the entire Haskell
1401− community, and so we grant permission to copy and distribute it for
1402− any purpose, provided that it is reproduced in its entirety,
1403− including this Notice. Modified versions of this Report may also be
1404− copied and distributed for any purpose, provided that the modified
1405− version is clearly presented as such, and that it does not claim to
1406− be a definition of the Haskell 98 Foreign Function Interface.
1407−
1408− -----------------------------------------------------------------------------
1455+ This library (libraries/syb) is derived from code from several
1456+ sources:
1457+
1458+ * Code from the GHC project which is largely (c) The University of
1459+ Glasgow, and distributable under a BSD-style license (see below),
1460+
1461+ * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
1462+ and freely redistributable (but see the full license for
1463+ restrictions).
1464+
1465+ * Code from the Haskell Foreign Function Interface specification,
1466+ which is (c) Manuel M. T. Chakravarty and freely redistributable
1467+ (but see the full license for restrictions).
1468+
1469+ The full text of these licenses is reproduced below. All of the
1470+ licenses are BSD-style or compatible.
1471+
1472+ -----------------------------------------------------------------------------
1473+
1474+ The Glasgow Haskell Compiler License
1475+
1476+ Copyright 2004, The University Court of the University of Glasgow.
1477+ All rights reserved.
1478+
1479+ Redistribution and use in source and binary forms, with or without
1480+ modification, are permitted provided that the following conditions are met:
1481+
1482+ - Redistributions of source code must retain the above copyright notice,
1483+ this list of conditions and the following disclaimer.
1484+
1485+ - Redistributions in binary form must reproduce the above copyright notice,
1486+ this list of conditions and the following disclaimer in the documentation
1487+ and/or other materials provided with the distribution.
1488+
1489+ - Neither name of the University nor the names of its contributors may be
1490+ used to endorse or promote products derived from this software without
1491+ specific prior written permission.
1492+
1493+ THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
1494+ GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
1495+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1496+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1497+ UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
1498+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1499+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1500+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1501+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1502+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1503+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1504+ DAMAGE.
1505+
1506+ -----------------------------------------------------------------------------
1507+
1508+ Code derived from the document "Report on the Programming Language
1509+ Haskell 98", is distributed under the following license:
1510+
1511+ Copyright (c) 2002 Simon Peyton Jones
1512+
1513+ The authors intend this Report to belong to the entire Haskell
1514+ community, and so we grant permission to copy and distribute it for
1515+ any purpose, provided that it is reproduced in its entirety,
1516+ including this Notice. Modified versions of this Report may also be
1517+ copied and distributed for any purpose, provided that the modified
1518+ version is clearly presented as such, and that it does not claim to
1519+ be a definition of the Haskell 98 Language.
1520+
1521+ -----------------------------------------------------------------------------
1522+
1523+ Code derived from the document "The Haskell 98 Foreign Function
1524+ Interface, An Addendum to the Haskell 98 Report" is distributed under
1525+ the following license:
1526+
1527+ Copyright (c) 2002 Manuel M. T. Chakravarty
1528+
1529+ The authors intend this Report to belong to the entire Haskell
1530+ community, and so we grant permission to copy and distribute it for
1531+ any purpose, provided that it is reproduced in its entirety,
1532+ including this Notice. Modified versions of this Report may also be
1533+ copied and distributed for any purpose, provided that the modified
1534+ version is clearly presented as such, and that it does not claim to
1535+ be a definition of the Haskell 98 Foreign Function Interface.
1536+
1537+ -----------------------------------------------------------------------------
14091538
14101539template-haskell LICENSE file:
14111540
bundle/build.sh+2
@@ -20,12 +20,14 @@ strip ../dist/build/psc/psc
2020strip ../dist/build/psci/psci
2121strip ../dist/build/psc-docs/psc-docs
2222strip ../dist/build/psc-publish/psc-publish
23+strip ../dist/build/psc-bundle/psc-bundle
2324
2425# Copy files to staging directory
2526cp ../dist/build/psc/psc build/purescript/
2627cp ../dist/build/psci/psci build/purescript/
2728cp ../dist/build/psc-docs/psc-docs build/purescript/
2829cp ../dist/build/psc-publish/psc-publish build/purescript/
30+cp ../dist/build/psc-bundle/psc-bundle build/purescript/
2931cp README build/purescript/
3032cp ../LICENSE build/purescript/
3133
bundle/winbuild.sh+2
@@ -16,12 +16,14 @@ strip ../dist/build/psc/psc.exe
1616strip ../dist/build/psci/psci.exe
1717strip ../dist/build/psc-docs/psc-docs.exe
1818strip ../dist/build/psc-publish/psc-publish.exe
19+strip ../dist/build/psc-bundle/psc-bundle.exe
1920
2021# Copy files to staging directory
2122cp ../dist/build/psc/psc.exe build/purescript/
2223cp ../dist/build/psci/psci.exe build/purescript/
2324cp ../dist/build/psc-docs/psc-docs.exe build/purescript/
2425cp ../dist/build/psc-publish/psc-publish.exe build/purescript/
26+cp ../dist/build/psc-bundle/psc-bundle.exe build/purescript/
2527cp README build/purescript/
2628cp ../LICENSE build/purescript/
2729
license-generator/generate+1−1
@@ -21,7 +21,7 @@ echo_header() {
2121
2222echo_deps_names() {
2323 cabal-dependency-licenses \
24− | grep '^- ' | sed 's/^..//' | sort -h
24+ | grep '^- ' | sed 's/^..//' | gsort -h
2525}
2626
2727echo_deps_licenses() {
psc-bundle/Main.hsnew file+589
@@ -0,0 +1,589 @@
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.
12+--
13+-----------------------------------------------------------------------------
14+
15+{-# LANGUAGE PatternGuards #-}
16+{-# LANGUAGE FlexibleContexts #-}
17+{-# LANGUAGE ScopedTypeVariables #-}
18+{-# LANGUAGE TupleSections #-}
19+{-# LANGUAGE RecordWildCards #-}
20+
21+module Main (main) where
22+
23+import Data.List (nub)
24+import Data.Maybe (mapMaybe, catMaybes)
25+import Data.Traversable (for)
26+import Data.Generics (everything, everywhere, mkQ, mkT)
27+import Data.Graph
28+import Data.Version (showVersion)
29+
30+import qualified Data.Set as S
31+
32+import Control.Applicative
33+import Control.Monad.Except
34+
35+import System.FilePath (takeFileName, takeDirectory)
36+import System.Exit (exitFailure)
37+import System.IO (stderr, hPutStrLn)
38+
39+import Language.JavaScript.Parser
40+
41+import Options.Applicative as Opts
42+
43+import qualified Paths_purescript as Paths
44+
45+-- | The type of error messages. We separate generation and rendering of errors using a data
46+-- type, in case we need to match on error types later.
47+data ErrorMessage
48+ = UnsupportedModulePath String
49+ | InvalidTopLevel
50+ | UnableToParseModule
51+ | UnsupportedExport
52+ | ErrorInFile FilePath ErrorMessage
53+ deriving Show
54+
55+-- | Modules are either "regular modules" (i.e. those generated by psc-make) or foreign modules.
56+data ModuleType
57+ = Regular
58+ | Foreign
59+ deriving (Show, Eq, Ord)
60+
61+-- | A module is identified by its module name and its type.
62+data ModuleIdentifier = ModuleIdentifier String ModuleType deriving (Show, Eq, Ord)
63+
64+moduleName :: ModuleIdentifier -> String
65+moduleName (ModuleIdentifier name _) = name
66+
67+-- | A piece of code is identified by its module and its name. These keys are used to label vertices
68+-- in the dependency graph.
69+type Key = (ModuleIdentifier, String)
70+
71+-- | An export is either a "regular export", which exports a name from the regular module we are in,
72+-- or a reexport of a declaration in the corresponding foreign module.
73+--
74+-- Regular exports are labelled, since they might re-export an operator with another name.
75+data ExportType
76+ = RegularExport String
77+ | ForeignReexport
78+ deriving (Show, Eq, Ord)
79+
80+-- | There are four types of module element we are interested in:
81+--
82+-- 1) Require statements
83+-- 2) Member declarations
84+-- 3) Export lists
85+-- 4) Everything else
86+--
87+-- Each is labelled with the original AST node which generated it, so that we can dump it back
88+-- into the output during codegen.
89+data ModuleElement
90+ = Require JSNode String ModuleIdentifier
91+ | Member JSNode Bool String [JSNode] [Key]
92+ | ExportsList [(ExportType, String, JSNode, [Key])]
93+ | Other JSNode
94+ deriving Show
95+
96+-- | A module is just a list of elements of the types listed above.
97+data Module = Module ModuleIdentifier [ModuleElement] deriving Show
98+
99+-- | Command line options.
100+data Options = Options
101+ { optionsInputFiles :: [FilePath]
102+ , optionsEntryPoints :: [String]
103+ , optionsMainModule :: Maybe String
104+ , optionsNamespace :: String
105+ } deriving Show
106+
107+-- | Prepare an error message for consumption by humans.
108+printErrorMessage :: ErrorMessage -> [String]
109+printErrorMessage (UnsupportedModulePath s) =
110+ [ "A CommonJS module has an unsupported name (" ++ show s ++ ")."
111+ , "The following file names are supported:"
112+ , " 1) index.js (psc-make native modules)"
113+ , " 2) foreign.js (psc-make foreign modules)"
114+ ]
115+printErrorMessage InvalidTopLevel =
116+ [ "Expected a list of source elements at the top level." ]
117+printErrorMessage UnableToParseModule =
118+ [ "The module could not be parsed." ]
119+printErrorMessage UnsupportedExport =
120+ [ "An export was unsupported. Exports can be defined in one of two ways: "
121+ , " 1) exports.name = ..."
122+ , " 2) exports = { ... }"
123+ ]
124+printErrorMessage (ErrorInFile filename e) =
125+ ("Error in file " ++ show filename ++ ":")
126+ : ""
127+ : map (" " ++) (printErrorMessage e)
128+
129+-- | Unpack the node inside a JSNode. This is useful when pattern matching.
130+node :: JSNode -> Node
131+node (NN n) = n
132+node (NT n _ _) = n
133+
134+-- | Given a filename, assuming it is in the correct place on disk, infer a ModuleIdentifier.
135+guessModuleIdentifier :: (Applicative m, MonadError ErrorMessage m) => FilePath -> m ModuleIdentifier
136+guessModuleIdentifier filename = ModuleIdentifier (takeFileName (takeDirectory filename)) <$> (guessModuleType (takeFileName filename))
137+ where
138+ guessModuleType "index.js" = pure Regular
139+ guessModuleType "foreign.js" = pure Foreign
140+ guessModuleType name = throwError $ UnsupportedModulePath name
141+
142+-- | Calculate the ModuleIdentifier which a require(...) statement imports.
143+checkImportPath :: String -> ModuleIdentifier -> S.Set String -> Maybe ModuleIdentifier
144+checkImportPath "./foreign" m _ =
145+ Just (ModuleIdentifier (moduleName m) Foreign)
146+checkImportPath name _ names
147+ | name `S.member` names = Just (ModuleIdentifier name Regular)
148+checkImportPath _ _ _ = Nothing
149+
150+-- | Compute the dependencies of all elements in a module, and add them to the tree.
151+--
152+-- Members and exports can have dependencies. A dependency is of one of the following forms:
153+--
154+-- 1) module.name or member["name"]
155+--
156+-- where module was imported using
157+--
158+-- var module = require("Module.Name");
159+--
160+-- 2) name
161+--
162+-- where name is the name of a member defined in the current module.
163+withDeps :: Module -> Module
164+withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
165+ where
166+ -- | Collects all modules which are imported, so that we can identify dependencies of the first type.
167+ imports :: [(String, ModuleIdentifier)]
168+ imports = mapMaybe toImport es
169+ where
170+ toImport :: ModuleElement -> Maybe (String, ModuleIdentifier)
171+ toImport (Require _ nm mid) = Just (nm, mid)
172+ toImport _ = Nothing
173+
174+ -- | Collects all member names in scope, so that we can identify dependencies of the second type.
175+ boundNames :: [String]
176+ boundNames = mapMaybe toBoundName es
177+ where
178+ toBoundName :: ModuleElement -> Maybe String
179+ toBoundName (Member _ _ nm _ _) = Just nm
180+ toBoundName _ = Nothing
181+
182+ -- | Calculate dependencies and add them to the current element.
183+ expandDeps :: ModuleElement -> ModuleElement
184+ expandDeps (Member n f nm decl _) = Member n f nm decl (nub (concatMap (dependencies modulePath) decl))
185+ expandDeps (ExportsList exps) = ExportsList (map expand exps)
186+ where
187+ expand (ty, nm, n1, _) = (ty, nm, n1, nub (dependencies modulePath n1))
188+ expandDeps other = other
189+
190+ dependencies :: ModuleIdentifier -> JSNode -> [(ModuleIdentifier, String)]
191+ dependencies m = everything (++) (mkQ [] toReference)
192+ where
193+ toReference :: Node -> [(ModuleIdentifier, String)]
194+ toReference (JSMemberDot [ mn ] _ nm)
195+ | JSIdentifier mn' <- node mn
196+ , JSIdentifier nm' <- node nm
197+ , Just mid <- lookup mn' imports
198+ = [(mid, nm')]
199+ toReference (JSMemberSquare [ mn ] _ nm _)
200+ | JSIdentifier mn' <- node mn
201+ , JSExpression [ s ] <- node nm
202+ , JSStringLiteral _ nm' <- node s
203+ , Just mid <- lookup mn' imports
204+ = [(mid, nm')]
205+ toReference (JSIdentifier nm)
206+ | nm `elem` boundNames
207+ = [(m, nm)]
208+ toReference _ = []
209+
210+-- | Attempt to create a Module from a Javascript AST.
211+--
212+-- Each type of module element is matched using pattern guards, and everything else is bundled into the
213+-- Other constructor.
214+toModule :: forall m. (Applicative m, MonadError ErrorMessage m) => S.Set String -> ModuleIdentifier -> JSNode -> m Module
215+toModule mids mid top
216+ | JSSourceElementsTop ns <- node top = Module mid <$> mapM toModuleElement ns
217+ | otherwise = throwError InvalidTopLevel
218+ where
219+ toModuleElement :: JSNode -> m ModuleElement
220+ toModuleElement n
221+ | JSVariables var [ varIntro ] _ <- node n
222+ , JSLiteral "var" <- node var
223+ , JSVarDecl impN [ eq, req, impP ] <- node varIntro
224+ , JSIdentifier importName <- node impN
225+ , JSLiteral "=" <- node eq
226+ , JSIdentifier "require" <- node req
227+ , JSArguments _ [ impS ] _ <- node impP
228+ , JSStringLiteral _ importPath <- node impS
229+ , Just importPath' <- checkImportPath importPath mid mids
230+ = pure (Require n importName importPath')
231+ toModuleElement n
232+ | JSVariables var [ varIntro ] _ <- node n
233+ , JSLiteral "var" <- node var
234+ , JSVarDecl declN (eq : decl) <- node varIntro
235+ , JSIdentifier name <- node declN
236+ , JSLiteral "=" <- node eq
237+ = pure (Member n False name decl [])
238+ toModuleElement n
239+ | JSExpression (e : op : decl) <- node n
240+ , JSMemberDot [ exports ] _ nm <- node e
241+ , JSIdentifier "exports" <- node exports
242+ , JSOperator eq <- node op
243+ , JSLiteral "=" <- node eq
244+ , JSIdentifier name <- node nm
245+ = pure (Member n True name decl [])
246+ toModuleElement n
247+ | JSExpression (mnExp : op : obj: _) <- node n
248+ , JSMemberDot [ mn ] _ e <- node mnExp
249+ , JSIdentifier "module" <- node mn
250+ , JSIdentifier "exports" <- node e
251+ , JSOperator eq <- node op
252+ , JSLiteral "=" <- node eq
253+ , JSObjectLiteral _ props _ <- node obj
254+ = ExportsList <$> mapM toExport (filter (not . isSeparator) (map node props))
255+ where
256+ toExport :: Node -> m (ExportType, String, JSNode, [Key])
257+ toExport (JSPropertyNameandValue name _ [val] ) =
258+ (,,val,[]) <$> exportType (node val)
259+ <*> extractLabel (node name)
260+ toExport _ = throwError UnsupportedExport
261+
262+ exportType :: Node -> m ExportType
263+ exportType (JSMemberDot [f] _ _)
264+ | JSIdentifier "$foreign" <- node f
265+ = pure ForeignReexport
266+ exportType (JSMemberSquare [f] _ _ _)
267+ | JSIdentifier "$foreign" <- node f
268+ = pure ForeignReexport
269+ exportType (JSIdentifier s) = pure (RegularExport s)
270+ exportType _ = throwError UnsupportedExport
271+
272+ extractLabel :: Node -> m String
273+ extractLabel (JSStringLiteral _ nm) = pure nm
274+ extractLabel (JSIdentifier nm) = pure nm
275+ extractLabel _ = throwError UnsupportedExport
276+
277+ isSeparator :: Node -> Bool
278+ isSeparator (JSLiteral ",") = True
279+ isSeparator _ = False
280+ toModuleElement other = pure (Other other)
281+
282+-- | Eliminate unused code based on the specified entry point set.
283+compile :: [Module] -> [ModuleIdentifier] -> [Module]
284+compile modules entryPoints = filteredModules
285+ where
286+ (graph, _, vertexFor) = graphFromEdges verts
287+
288+ -- | The vertex set
289+ verts :: [(ModuleElement, Key, [Key])]
290+ verts = do
291+ Module mid els <- modules
292+ concatMap (toVertices mid) els
293+ where
294+ -- | Create a set of vertices for a module element.
295+ --
296+ -- Some special cases worth commenting on:
297+ --
298+ -- 1) Regular exports which simply export their own name do not count as dependencies.
299+ -- Regular exports which rename and reexport an operator do count, however.
300+ --
301+ -- 2) Require statements don't contribute towards dependencies, since they effectively get
302+ -- inlined wherever they are used inside other module elements.
303+ toVertices :: ModuleIdentifier -> ModuleElement -> [(ModuleElement, Key, [Key])]
304+ toVertices p m@(Member _ _ nm _ deps) = [(m, (p, nm), deps)]
305+ toVertices p m@(ExportsList exps) = mapMaybe toVertex exps
306+ where
307+ toVertex (ForeignReexport, nm, _, ks) = Just (m, (p, nm), ks)
308+ toVertex (RegularExport nm, nm1, _, ks) | nm /= nm1 = Just (m, (p, nm1), ks)
309+ toVertex _ = Nothing
310+ toVertices _ _ = []
311+
312+ -- | The set of vertices whose connected components we are interested in keeping.
313+ entryPointVertices :: [Vertex]
314+ entryPointVertices = catMaybes $ do
315+ (_, k@(mid, _), _) <- verts
316+ guard $ mid `elem` entryPoints
317+ return (vertexFor k)
318+
319+ -- | The set of vertices reachable from an entry point
320+ reachableSet :: S.Set Vertex
321+ reachableSet = S.fromList (concatMap (reachable graph) entryPointVertices)
322+
323+ filteredModules :: [Module]
324+ filteredModules = map filterUsed modules
325+ where
326+ filterUsed :: Module -> Module
327+ filterUsed (Module mid ds) = Module mid (map filterExports (go ds))
328+ where
329+ go :: [ModuleElement] -> [ModuleElement]
330+ go [] = []
331+ go (d : Other semi : rest)
332+ | JSLiteral ";" <- node semi
333+ , not (isDeclUsed d)
334+ = go rest
335+ go (d : rest)
336+ | not (isDeclUsed d) = go rest
337+ | otherwise = d : go rest
338+
339+ -- | Filter out the exports for members which aren't used.
340+ filterExports :: ModuleElement -> ModuleElement
341+ filterExports (ExportsList exps) = ExportsList (filter (\(_, nm, _, _) -> isKeyUsed (mid, nm)) exps)
342+ filterExports me = me
343+
344+ isDeclUsed :: ModuleElement -> Bool
345+ isDeclUsed (Member _ _ nm _ _) = isKeyUsed (mid, nm)
346+ isDeclUsed _ = True
347+
348+ isKeyUsed :: Key -> Bool
349+ isKeyUsed k
350+ | Just me <- vertexFor k = me `S.member` reachableSet
351+ | otherwise = False
352+
353+-- | Topologically sort the module dependency graph, so that when we generate code, modules can be
354+-- defined in the right order.
355+sortModules :: [Module] -> [Module]
356+sortModules modules = map (\v -> case nodeFor v of (n, _, _) -> n) (reverse (topSort graph))
357+ where
358+ (graph, nodeFor, _) = graphFromEdges $ do
359+ m@(Module mid els) <- modules
360+ return (m, mid, mapMaybe getKey els)
361+
362+ getKey :: ModuleElement -> Maybe ModuleIdentifier
363+ getKey (Require _ _ mi) = Just mi
364+ getKey _ = Nothing
365+
366+-- | A module is empty if it contains no exported members (in other words,
367+-- if the only things left after dead code elimination are module imports and
368+-- "other" foreign code).
369+--
370+-- If a module is empty, we don't want to generate code for it.
371+isModuleEmpty :: Module -> Bool
372+isModuleEmpty (Module _ els) = all isElementEmpty els
373+ where
374+ isElementEmpty :: ModuleElement -> Bool
375+ isElementEmpty (ExportsList exps) = null exps
376+ isElementEmpty (Require _ _ _) = True
377+ isElementEmpty (Other _) = True
378+ isElementEmpty _ = False
379+
380+-- | Generate code for a set of modules, including a call to main().
381+--
382+-- Modules get defined on the global PS object, as follows:
383+--
384+-- var PS = { };
385+-- (function(exports) {
386+-- ...
387+-- })(PS["Module.Name"] = PS["Module.Name"] || {});
388+--
389+-- In particular, a module and its foreign imports share the same namespace inside PS.
390+-- This saves us from having to generate unique names for a module and its foreign imports,
391+-- and is safe since a module shares a namespace with its foreign imports in PureScript as well
392+-- (so there is no way to have overlaps in code generated by psc-make).
393+codeGen :: Options -> [Module] -> String
394+codeGen Options{..} ms = renderToString (NN (JSSourceElementsTop (prelude ++ concatMap moduleToJS ms ++ maybe [] runMain optionsMainModule)))
395+ where
396+ moduleToJS :: Module -> [JSNode]
397+ moduleToJS (Module mn ds) = wrap (moduleName mn) (indent (concatMap declToJS ds))
398+ where
399+ declToJS :: ModuleElement -> [JSNode]
400+ declToJS (Member n _ _ _ _) = [n]
401+ declToJS (Other n) = [n]
402+ declToJS (Require _ nm req) =
403+ [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ])
404+ [ NN (JSVarDecl (sp (JSIdentifier nm))
405+ [ sp (JSLiteral "=")
406+ , moduleReference sp (moduleName req)
407+ ])
408+ ]
409+ (nt (JSLiteral ";"))) ]
410+ declToJS (ExportsList exps) = map toExport exps
411+
412+ where
413+ toExport :: (ExportType, String, JSNode, [Key]) -> JSNode
414+ toExport (_, nm, val, _) =
415+ NN (JSExpression [ NN (JSMemberSquare [ NT (JSIdentifier "exports") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ] ]
416+ (nt (JSLiteral "["))
417+ (NN (JSExpression [ nt (JSStringLiteral '"' nm) ]))
418+ (nt (JSLiteral "]")))
419+ , NN (JSOperator (sp (JSLiteral "=")))
420+ , reindent val
421+ , nt (JSLiteral ";")
422+ ])
423+
424+ reindent :: JSNode -> JSNode
425+ reindent (NT n _ _) = sp n
426+ reindent nn = nn
427+
428+ indent :: [JSNode] -> [JSNode]
429+ indent = everywhere (mkT squash)
430+ where
431+ squash (NT n pos ann) = NT n (keepCol pos) (map splat ann)
432+ squash nn = nn
433+
434+ splat (CommentA pos s) = CommentA (keepCol pos) s
435+ splat (WhiteSpace pos w) = WhiteSpace (keepCol pos) w
436+ splat ann = ann
437+
438+ keepCol (TokenPn _ _ c) = TokenPn 0 0 (c + 2)
439+
440+ prelude :: [JSNode]
441+ prelude =
442+ [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ CommentA tokenPosnEmpty "// Generated by psc-bundle"
443+ , WhiteSpace tokenPosnEmpty "\n"
444+ ])
445+ [ NN (JSVarDecl (sp (JSIdentifier optionsNamespace))
446+ [ sp (JSLiteral "=")
447+ , NN (JSObjectLiteral (sp (JSLiteral "{"))
448+ []
449+ (sp (JSLiteral "}")))
450+ ])
451+ ]
452+ (nt (JSLiteral ";")))
453+ , lf
454+ ]
455+
456+ moduleReference :: (Node -> JSNode) -> String -> JSNode
457+ moduleReference f mn =
458+ NN (JSMemberSquare [ f (JSIdentifier optionsNamespace) ]
459+ (nt (JSLiteral "["))
460+ (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
461+ (nt (JSLiteral "]")))
462+
463+ wrap :: String -> [JSNode] -> [JSNode]
464+ wrap mn ds =
465+ [ NN (JSExpression [ NN (JSExpressionParen (nt (JSLiteral "("))
466+ (NN (JSExpression [ NN (JSFunctionExpression (nt (JSLiteral "function"))
467+ []
468+ (nt (JSLiteral "(") ) [nt (JSIdentifier "exports")] (nt (JSLiteral ")"))
469+ (NN (JSBlock [sp (JSLiteral "{")]
470+ (lf : ds)
471+ [nl (JSLiteral "}")])))]))
472+ (nt (JSLiteral ")")))
473+ , NN (JSArguments (nt (JSLiteral "("))
474+ [ NN (JSExpression [ moduleReference nt mn
475+ , NN (JSOperator (sp (JSLiteral "=")))
476+ , NN (JSExpressionBinary "||"
477+ [ moduleReference sp mn ]
478+ (sp (JSLiteral "||"))
479+ [ emptyObj ])
480+ ])
481+ ]
482+ (nt (JSLiteral ")")))
483+ ])
484+ , nt (JSLiteral ";")
485+ , lf
486+ ]
487+ where
488+ emptyObj = NN (JSObjectLiteral (sp (JSLiteral "{")) [] (nt (JSLiteral "}")))
489+
490+ runMain :: String -> [JSNode]
491+ runMain mn =
492+ [ NN (JSExpression [ NN (JSMemberDot [ NN (JSMemberSquare [ nl (JSIdentifier optionsNamespace) ]
493+ (nt (JSLiteral "["))
494+ (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
495+ (nt (JSLiteral "]")))
496+ ]
497+ (nt (JSLiteral "."))
498+ (nt (JSIdentifier "main")))
499+ , NN (JSArguments (nt (JSLiteral "(")) [] (nt (JSLiteral ")")))
500+ ])
501+ , nt (JSLiteral ";")
502+ ]
503+
504+ nt :: Node -> JSNode
505+ nt n = NT n tokenPosnEmpty []
506+
507+ lf :: JSNode
508+ lf = NT (JSLiteral "") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
509+
510+ sp :: Node -> JSNode
511+ sp n = NT n tokenPosnEmpty [ WhiteSpace tokenPosnEmpty " " ]
512+
513+ nl :: Node -> JSNode
514+ nl n = NT n tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
515+
516+-- | The main application function.
517+-- This function parses the input files, performs dead code elimination, filters empty modules
518+-- and generates and prints the final Javascript bundle.
519+app :: forall m. (Applicative m, MonadError ErrorMessage m, MonadIO m) => Options -> m String
520+app opts@Options{..} = do
521+ input <- for optionsInputFiles $ \filename -> do
522+ js <- liftIO (readFile filename)
523+ ast <- fromRight (parse js filename)
524+ mid <- guessModuleIdentifier filename
525+ return (mid, ast)
526+
527+ let mids = S.fromList (map (moduleName . fst) input)
528+
529+ modules <- mapM (fmap withDeps . uncurry (toModule mids)) input
530+
531+ let compiled = compile modules (map (`ModuleIdentifier` Regular) optionsEntryPoints)
532+ sorted = sortModules (filter (not . isModuleEmpty) compiled)
533+
534+ return (codeGen opts sorted)
535+
536+ where
537+ fromRight :: Either a b -> m b
538+ fromRight (Right b) = pure b
539+ fromRight (Left _) = throwError UnableToParseModule
540+
541+-- | Command line options parser.
542+options :: Parser Options
543+options = Options <$> some inputFile
544+ <*> some entryPoint
545+ <*> optional mainModule
546+ <*> namespace
547+ where
548+ inputFile :: Parser FilePath
549+ inputFile = strArgument $
550+ metavar "FILE"
551+ <> help "The input .js file(s)"
552+
553+ entryPoint :: Parser String
554+ entryPoint = strOption $
555+ short 'm'
556+ <> long "module"
557+ <> help "Entry point module name(s). All code which is not a transitive dependency of an entry point module will be removed."
558+
559+ mainModule :: Parser String
560+ mainModule = strOption $
561+ long "main"
562+ <> help "Generate code to run the main method in the specified module."
563+
564+ namespace :: Parser String
565+ namespace = strOption $
566+ short 'n'
567+ <> long "namespace"
568+ <> Opts.value "PS"
569+ <> showDefault
570+ <> help "Specify the namespace that PureScript modules will be exported to when running in the browser."
571+
572+-- | Make it go.
573+main :: IO ()
574+main = do
575+ opts <- execParser (info (version <*> helper <*> options) infoModList)
576+ output <- runExceptT (app opts)
577+ case output of
578+ Left err -> do
579+ hPutStrLn stderr (unlines (printErrorMessage err))
580+ exitFailure
581+ Right js ->
582+ putStrLn js
583+ where
584+ infoModList = fullDesc <> headerInfo <> footerInfo
585+ headerInfo = header "psc-bundle - Bundles compiled PureScript modules for the browser"
586+ footerInfo = footer $ "psc-bundle " ++ showVersion Paths.version
587+
588+ version :: Parser (a -> a)
589+ version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psc-bundle/README.mdnew file+18
@@ -0,0 +1,18 @@
1+# psc-bundle
2+
3+A dead code elimination tool for PureScript-style CommonJS modules. This can be used as an alternative to Browserify.
4+
5+## Usage
6+
7+ psc-bundle FILE (-m|--module ARG) [--main ARG] [--namespace ARG]
8+
9+Options:
10+
11+- The input .js file(s)
12+- Entry point module name(s) are specified with `-m` or `--module`. All code which is not a transitive dependency of an entry point module will be removed.
13+- The main module is (optionally) specified using `--main`. If specified, this will generate code to run the main method in the specified module.
14+- The browser namespace defaults to `PS`, and can be overridden with `--namespace`.
15+
16+For example, to bundle the modules in the `output` directory, with main module `Main`:
17+
18+ psc-bundle output/**/*.js -m Main --main Main
purescript.cabal+18
@@ -211,6 +211,24 @@ executable psc-hierarchy
211211 other-modules:
212212 ghc-options: -Wall -O2
213213
214+executable psc-bundle
215+ main-is: Main.hs
216+ other-modules:
217+ other-extensions:
218+ build-depends: base >=4 && <5,
219+ language-javascript == 0.5.*,
220+ syb -any,
221+ containers -any,
222+ filepath -any,
223+ directory -any,
224+ mtl -any,
225+ transformers -any,
226+ transformers-compat -any,
227+ optparse-applicative >= 0.10.0
228+ ghc-options: -Wall -O2
229+ hs-source-dirs: psc-bundle
230+ default-language: Haskell2010
231+
214232test-suite tests
215233 build-depends: base >=4 && <5, containers -any, directory -any,
216234 filepath -any, mtl -any, parsec -any, purescript -any,