@@ -56,11 +56,11 @@ data ErrorMessage
5656 deriving Show
5757
5858-- | Modules are either "regular modules" (i.e. those generated by psc-make) or foreign modules.
59−data ModuleType
60− = Regular
61− | Foreign
59+data ModuleType
60+ = Regular
61+ | Foreign
6262 deriving (Show, Eq, Ord)
63−
63+
6464-- | A module is identified by its module name and its type.
6565data ModuleIdentifier = ModuleIdentifier String ModuleType deriving (Show, Eq, Ord)
6666
@@ -73,11 +73,11 @@ type Key = (ModuleIdentifier, String)
7373
7474-- | An export is either a "regular export", which exports a name from the regular module we are in,
7575-- or a reexport of a declaration in the corresponding foreign module.
76−--
77−-- Regular exports are labelled, since they might re-export an operator with another name.
78−data ExportType
79− = RegularExport String
80− | ForeignReexport
76+--
77+-- Regular exports are labelled, since they might re-export an operator with another name.
78+data ExportType
79+ = RegularExport String
80+ | ForeignReexport
8181 deriving (Show, Eq, Ord)
8282
8383-- | There are four types of module element we are interested in:
@@ -89,16 +89,16 @@ data ExportType
8989--
9090-- Each is labelled with the original AST node which generated it, so that we can dump it back
9191-- into the output during codegen.
92−data ModuleElement
92+data ModuleElement
9393 = Require JSNode String ModuleIdentifier
9494 | Member JSNode Bool String [JSNode] [Key]
9595 | ExportsList [(ExportType, String, JSNode, [Key])]
9696 | Other JSNode
9797 deriving Show
9898
99−-- | A module is just a list of elements of the types listed above.
99+-- | A module is just a list of elements of the types listed above.
100100data Module = Module ModuleIdentifier [ModuleElement] deriving Show
101−
101+
102102-- | Prepare an error message for consumption by humans.
103103printErrorMessage :: ErrorMessage -> [String]
104104printErrorMessage (UnsupportedModulePath s) =
@@ -108,7 +108,7 @@ printErrorMessage (UnsupportedModulePath s) =
108108 , " 2) foreign.js (psc-make foreign modules)"
109109 ]
110110printErrorMessage InvalidTopLevel =
111− [ "Expected a list of source elements at the top level." ]
111+ [ "Expected a list of source elements at the top level." ]
112112printErrorMessage UnableToParseModule =
113113 [ "The module could not be parsed." ]
114114printErrorMessage UnsupportedExport =
@@ -128,18 +128,18 @@ node (NT n _ _) = n
128128
129129-- | Calculate the ModuleIdentifier which a require(...) statement imports.
130130checkImportPath :: String -> ModuleIdentifier -> S.Set String -> Maybe ModuleIdentifier
131−checkImportPath "./foreign" m _ =
131+checkImportPath "./foreign" m _ =
132132 Just (ModuleIdentifier (moduleName m) Foreign)
133−checkImportPath name _ names
133+checkImportPath name _ names
134134 | name `S.member` names = Just (ModuleIdentifier name Regular)
135135checkImportPath _ _ _ = Nothing
136136
137137-- | Compute the dependencies of all elements in a module, and add them to the tree.
138−--
138+--
139139-- Members and exports can have dependencies. A dependency is of one of the following forms:
140140--
141141-- 1) module.name or member["name"]
142−--
142+--
143143-- where module was imported using
144144--
145145-- var module = require("Module.Name");
@@ -149,7 +149,7 @@ checkImportPath _ _ _ = Nothing
149149-- where name is the name of a member defined in the current module.
150150withDeps :: Module -> Module
151151withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
152− where
152+ where
153153 -- | Collects all modules which are imported, so that we can identify dependencies of the first type.
154154 imports :: [(String, ModuleIdentifier)]
155155 imports = mapMaybe toImport es
@@ -157,7 +157,7 @@ withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
157157 toImport :: ModuleElement -> Maybe (String, ModuleIdentifier)
158158 toImport (Require _ nm mid) = Just (nm, mid)
159159 toImport _ = Nothing
160−
160+
161161 -- | Collects all member names in scope, so that we can identify dependencies of the second type.
162162 boundNames :: [String]
163163 boundNames = mapMaybe toBoundName es
@@ -173,7 +173,7 @@ withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
173173 where
174174 expand (ty, nm, n1, _) = (ty, nm, n1, nub (dependencies modulePath n1))
175175 expandDeps other = other
176−
176+
177177 dependencies :: ModuleIdentifier -> JSNode -> [(ModuleIdentifier, String)]
178178 dependencies m = everything (++) (mkQ [] toReference)
179179 where
@@ -195,29 +195,29 @@ withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
195195 toReference _ = []
196196
197197-- | Attempt to create a Module from a Javascript AST.
198−--
199−-- Each type of module element is matched using pattern guards, and everything else is bundled into the
198+--
199+-- Each type of module element is matched using pattern guards, and everything else is bundled into the
200200-- Other constructor.
201201toModule :: forall m. (Applicative m, MonadError ErrorMessage m) => S.Set String -> ModuleIdentifier -> JSNode -> m Module
202−toModule mids mid top
202+toModule mids mid top
203203 | JSSourceElementsTop ns <- node top = Module mid <$> mapM toModuleElement ns
204204 | otherwise = throwError InvalidTopLevel
205− where
205+ where
206206 toModuleElement :: JSNode -> m ModuleElement
207207 toModuleElement n
208208 | JSVariables var [ varIntro ] _ <- node n
209− , JSLiteral "var" <- node var
209+ , JSLiteral "var" <- node var
210210 , JSVarDecl impN [ eq, req, impP ] <- node varIntro
211211 , JSIdentifier importName <- node impN
212212 , JSLiteral "=" <- node eq
213213 , JSIdentifier "require" <- node req
214− , JSArguments _ [ impS ] _ <- node impP
214+ , JSArguments _ [ impS ] _ <- node impP
215215 , JSStringLiteral _ importPath <- node impS
216216 , Just importPath' <- checkImportPath importPath mid mids
217217 = pure (Require n importName importPath')
218218 toModuleElement n
219219 | JSVariables var [ varIntro ] _ <- node n
220− , JSLiteral "var" <- node var
220+ , JSLiteral "var" <- node var
221221 , JSVarDecl declN (eq : decl) <- node varIntro
222222 , JSIdentifier name <- node declN
223223 , JSLiteral "=" <- node eq
@@ -251,11 +251,11 @@ toModule mids mid top
251251 = ExportsList <$> mapM toExport (filter (not . isSeparator) (map node props))
252252 where
253253 toExport :: Node -> m (ExportType, String, JSNode, [Key])
254− toExport (JSPropertyNameandValue name _ [val] ) =
255− (,,val,[]) <$> exportType (node val)
254+ toExport (JSPropertyNameandValue name _ [val] ) =
255+ (,,val,[]) <$> exportType (node val)
256256 <*> extractLabel (node name)
257257 toExport _ = throwError UnsupportedExport
258−
258+
259259 exportType :: Node -> m ExportType
260260 exportType (JSMemberDot [f] _ _)
261261 | JSIdentifier "$foreign" <- node f
@@ -265,12 +265,12 @@ toModule mids mid top
265265 = pure ForeignReexport
266266 exportType (JSIdentifier s) = pure (RegularExport s)
267267 exportType _ = throwError UnsupportedExport
268−
268+
269269 extractLabel :: Node -> m String
270270 extractLabel (JSStringLiteral _ nm) = pure nm
271271 extractLabel (JSIdentifier nm) = pure nm
272272 extractLabel _ = throwError UnsupportedExport
273−
273+
274274 isSeparator :: Node -> Bool
275275 isSeparator (JSLiteral ",") = True
276276 isSeparator _ = False
@@ -280,9 +280,9 @@ toModule mids mid top
280280compile :: [Module] -> [ModuleIdentifier] -> [Module]
281281compile modules [] = modules
282282compile modules entryPoints = filteredModules
283− where
283+ where
284284 (graph, _, vertexFor) = graphFromEdges verts
285−
285+
286286 -- | The vertex set
287287 verts :: [(ModuleElement, Key, [Key])]
288288 verts = do
@@ -290,12 +290,12 @@ compile modules entryPoints = filteredModules
290290 concatMap (toVertices mid) els
291291 where
292292 -- | Create a set of vertices for a module element.
293− --
293+ --
294294 -- Some special cases worth commenting on:
295295 --
296296 -- 1) Regular exports which simply export their own name do not count as dependencies.
297297 -- Regular exports which rename and reexport an operator do count, however.
298− --
298+ --
299299 -- 2) Require statements don't contribute towards dependencies, since they effectively get
300300 -- inlined wherever they are used inside other module elements.
301301 toVertices :: ModuleIdentifier -> ModuleElement -> [(ModuleElement, Key, [Key])]
@@ -306,18 +306,18 @@ compile modules entryPoints = filteredModules
306306 toVertex (RegularExport nm, nm1, _, ks) | nm /= nm1 = Just (m, (p, nm1), ks)
307307 toVertex _ = Nothing
308308 toVertices _ _ = []
309−
309+
310310 -- | The set of vertices whose connected components we are interested in keeping.
311311 entryPointVertices :: [Vertex]
312312 entryPointVertices = catMaybes $ do
313313 (_, k@(mid, _), _) <- verts
314314 guard $ mid `elem` entryPoints
315315 return (vertexFor k)
316−
316+
317317 -- | The set of vertices reachable from an entry point
318318 reachableSet :: S.Set Vertex
319319 reachableSet = S.fromList (concatMap (reachable graph) entryPointVertices)
320−
320+
321321 filteredModules :: [Module]
322322 filteredModules = map filterUsed modules
323323 where
@@ -326,29 +326,29 @@ compile modules entryPoints = filteredModules
326326 where
327327 go :: [ModuleElement] -> [ModuleElement]
328328 go [] = []
329− go (d : Other semi : rest)
329+ go (d : Other semi : rest)
330330 | JSLiteral ";" <- node semi
331331 , not (isDeclUsed d)
332332 = go rest
333− go (d : rest)
333+ go (d : rest)
334334 | not (isDeclUsed d) = go rest
335335 | otherwise = d : go rest
336−
336+
337337 -- | Filter out the exports for members which aren't used.
338338 filterExports :: ModuleElement -> ModuleElement
339339 filterExports (ExportsList exps) = ExportsList (filter (\(_, nm, _, _) -> isKeyUsed (mid, nm)) exps)
340340 filterExports me = me
341−
341+
342342 isDeclUsed :: ModuleElement -> Bool
343343 isDeclUsed (Member _ _ nm _ _) = isKeyUsed (mid, nm)
344344 isDeclUsed _ = True
345−
345+
346346 isKeyUsed :: Key -> Bool
347− isKeyUsed k
347+ isKeyUsed k
348348 | Just me <- vertexFor k = me `S.member` reachableSet
349349 | otherwise = False
350−
351−-- | Topologically sort the module dependency graph, so that when we generate code, modules can be
350+
351+-- | Topologically sort the module dependency graph, so that when we generate code, modules can be
352352-- defined in the right order.
353353sortModules :: [Module] -> [Module]
354354sortModules modules = map (\v -> case nodeFor v of (n, _, _) -> n) (reverse (topSort graph))
@@ -356,11 +356,11 @@ sortModules modules = map (\v -> case nodeFor v of (n, _, _) -> n) (reverse (top
356356 (graph, nodeFor, _) = graphFromEdges $ do
357357 m@(Module mid els) <- modules
358358 return (m, mid, mapMaybe getKey els)
359−
359+
360360 getKey :: ModuleElement -> Maybe ModuleIdentifier
361− getKey (Require _ _ mi) = Just mi
361+ getKey (Require _ _ mi) = Just mi
362362 getKey _ = Nothing
363−
363+
364364-- | A module is empty if it contains no exported members (in other words,
365365-- if the only things left after dead code elimination are module imports and
366366-- "other" foreign code).
@@ -374,7 +374,7 @@ isModuleEmpty (Module _ els) = all isElementEmpty els
374374 isElementEmpty (Require _ _ _) = True
375375 isElementEmpty (Other _) = True
376376 isElementEmpty _ = False
377−
377+
378378-- | Generate code for a set of modules, including a call to main().
379379--
380380-- Modules get defined on the global PS object, as follows:
@@ -384,7 +384,7 @@ isModuleEmpty (Module _ els) = all isElementEmpty els
384384-- ...
385385-- })(PS["Module.Name"] = PS["Module.Name"] || {});
386386--
387−-- In particular, a module and its foreign imports share the same namespace inside PS.
387+-- In particular, a module and its foreign imports share the same namespace inside PS.
388388-- This saves us from having to generate unique names for a module and its foreign imports,
389389-- and is safe since a module shares a namespace with its foreign imports in PureScript as well
390390-- (so there is no way to have overlaps in code generated by psc-make).
@@ -399,85 +399,85 @@ codeGen optionsMainModule optionsNamespace ms = renderToString (NN (JSSourceElem
399399 where
400400 declToJS :: ModuleElement -> [JSNode]
401401 declToJS (Member n _ _ _ _) = [n]
402− declToJS (Other n) = [n]
403− declToJS (Require _ nm req) =
404− [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ])
405− [ NN (JSVarDecl (sp (JSIdentifier nm))
402+ declToJS (Other n) = [n]
403+ declToJS (Require _ nm req) =
404+ [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ])
405+ [ NN (JSVarDecl (sp (JSIdentifier nm))
406406 [ sp (JSLiteral "=")
407407 , moduleReference sp (moduleName req)
408408 ])
409409 ]
410410 (nt (JSLiteral ";"))) ]
411411 declToJS (ExportsList exps) = map toExport exps
412−
413− where
412+
413+ where
414414 toExport :: (ExportType, String, JSNode, [Key]) -> JSNode
415415 toExport (_, nm, val, _) =
416− NN (JSExpression [ NN (JSMemberSquare [ NT (JSIdentifier "exports") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ] ]
417− (nt (JSLiteral "["))
416+ NN (JSExpression [ NN (JSMemberSquare [ NT (JSIdentifier "exports") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ] ]
417+ (nt (JSLiteral "["))
418418 (NN (JSExpression [ nt (JSStringLiteral '"' nm) ]))
419419 (nt (JSLiteral "]")))
420420 , NN (JSOperator (sp (JSLiteral "=")))
421421 , reindent val
422422 , nt (JSLiteral ";")
423423 ])
424−
424+
425425 reindent :: JSNode -> JSNode
426426 reindent (NT n _ _) = sp n
427427 reindent nn = nn
428−
428+
429429 indent :: [JSNode] -> [JSNode]
430430 indent = everywhere (mkT squash)
431431 where
432432 squash (NT n pos ann) = NT n (keepCol pos) (map splat ann)
433433 squash nn = nn
434−
434+
435435 splat (CommentA pos s) = CommentA (keepCol pos) s
436436 splat (WhiteSpace pos w) = WhiteSpace (keepCol pos) w
437437 splat ann = ann
438−
438+
439439 keepCol (TokenPn _ _ c) = TokenPn 0 0 (c + 2)
440−
440+
441441 prelude :: [JSNode]
442− prelude =
442+ prelude =
443443 [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ CommentA tokenPosnEmpty ("// Generated by psc-bundle " ++ showVersion Paths.version)
444444 , WhiteSpace tokenPosnEmpty "\n"
445− ])
446− [ NN (JSVarDecl (sp (JSIdentifier optionsNamespace))
445+ ])
446+ [ NN (JSVarDecl (sp (JSIdentifier optionsNamespace))
447447 [ sp (JSLiteral "=")
448− , NN (JSObjectLiteral (sp (JSLiteral "{"))
448+ , NN (JSObjectLiteral (sp (JSLiteral "{"))
449449 []
450450 (sp (JSLiteral "}")))
451451 ])
452− ]
452+ ]
453453 (nt (JSLiteral ";")))
454454 , lf
455455 ]
456−
456+
457457 moduleReference :: (Node -> JSNode) -> String -> JSNode
458− moduleReference f mn =
459− NN (JSMemberSquare [ f (JSIdentifier optionsNamespace) ]
460− (nt (JSLiteral "["))
458+ moduleReference f mn =
459+ NN (JSMemberSquare [ f (JSIdentifier optionsNamespace) ]
460+ (nt (JSLiteral "["))
461461 (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
462462 (nt (JSLiteral "]")))
463−
463+
464464 wrap :: String -> [JSNode] -> [JSNode]
465− wrap mn ds =
466− [ NN (JSExpression [ NN (JSExpressionParen (nt (JSLiteral "("))
467− (NN (JSExpression [ NN (JSFunctionExpression (nt (JSLiteral "function"))
468− []
469− (nt (JSLiteral "(") ) [nt (JSIdentifier "exports")] (nt (JSLiteral ")"))
470− (NN (JSBlock [sp (JSLiteral "{")]
465+ wrap mn ds =
466+ [ NN (JSExpression [ NN (JSExpressionParen (nt (JSLiteral "("))
467+ (NN (JSExpression [ NN (JSFunctionExpression (nt (JSLiteral "function"))
468+ []
469+ (nt (JSLiteral "(") ) [nt (JSIdentifier "exports")] (nt (JSLiteral ")"))
470+ (NN (JSBlock [sp (JSLiteral "{")]
471471 (lf : ds)
472472 [nl (JSLiteral "}")])))]))
473473 (nt (JSLiteral ")")))
474− , NN (JSArguments (nt (JSLiteral "("))
474+ , NN (JSArguments (nt (JSLiteral "("))
475475 [ NN (JSExpression [ moduleReference nt mn
476476 , NN (JSOperator (sp (JSLiteral "=")))
477477 , NN (JSExpressionBinary "||"
478− [ moduleReference sp mn ]
479− (sp (JSLiteral "||"))
480− [ emptyObj ])
478+ [ moduleReference sp mn ]
479+ (sp (JSLiteral "||"))
480+ [ emptyObj ])
481481 ])
482482 ]
483483 (nt (JSLiteral ")")))
@@ -487,30 +487,30 @@ codeGen optionsMainModule optionsNamespace ms = renderToString (NN (JSSourceElem
487487 ]
488488 where
489489 emptyObj = NN (JSObjectLiteral (sp (JSLiteral "{")) [] (nt (JSLiteral "}")))
490−
490+
491491 runMain :: String -> [JSNode]
492− runMain mn =
493− [ NN (JSExpression [ NN (JSMemberDot [ NN (JSMemberSquare [ nl (JSIdentifier optionsNamespace) ]
494− (nt (JSLiteral "["))
495− (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
492+ runMain mn =
493+ [ NN (JSExpression [ NN (JSMemberDot [ NN (JSMemberSquare [ nl (JSIdentifier optionsNamespace) ]
494+ (nt (JSLiteral "["))
495+ (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
496496 (nt (JSLiteral "]")))
497− ]
498− (nt (JSLiteral "."))
497+ ]
498+ (nt (JSLiteral "."))
499499 (nt (JSIdentifier "main")))
500500 , NN (JSArguments (nt (JSLiteral "(")) [] (nt (JSLiteral ")")))
501501 ])
502502 , nt (JSLiteral ";")
503503 ]
504−
504+
505505 nt :: Node -> JSNode
506506 nt n = NT n tokenPosnEmpty []
507−
507+
508508 lf :: JSNode
509509 lf = NT (JSLiteral "") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
510−
510+
511511 sp :: Node -> JSNode
512512 sp n = NT n tokenPosnEmpty [ WhiteSpace tokenPosnEmpty " " ]
513−
513+
514514 nl :: Node -> JSNode
515515 nl n = NT n tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
516516
@@ -529,10 +529,10 @@ bundle inputStrs entryPoints mainModule namespace = do
529529 return (ident, ast)
530530
531531 let mids = S.fromList (map (moduleName . fst) input)
532−
532+
533533 modules <- mapM (fmap withDeps . uncurry (toModule mids)) input
534−
534+
535535 let compiled = compile modules entryPoints
536536 sorted = sortModules (filter (not . isModuleEmpty) compiled)
537−
537+
538538 return (codeGen mainModule namespace sorted)