@@ -43,6 +43,7 @@ import qualified Data.Set as S
43import Control.Monad
43import Control.Monad
44import Control.Monad.Error.Class
44import Control.Monad.Error.Class
45import Language.JavaScript.Parser
45import Language.JavaScript.Parser
46+import Language.JavaScript.Parser.AST
47import qualified Paths_purescript as Paths
48import qualified Paths_purescript as Paths
@@ -83,7 +84,7 @@ type Key = (ModuleIdentifier, String)
83data ExportType
84data ExportType
84 = RegularExport String
85 = RegularExport String
85 | ForeignReexport
86 | ForeignReexport
86− deriving (Show, Read, Eq, Ord)
87+ deriving (Show, Eq, Ord)
88-- | There are four types of module element we are interested in:
89-- | There are four types of module element we are interested in:
@@ -95,14 +96,14 @@ data ExportType
95-- Each is labelled with the original AST node which generated it, so that we can dump it back
96-- Each is labelled with the original AST node which generated it, so that we can dump it back
96-- into the output during codegen.
97-- into the output during codegen.
97data ModuleElement
98data ModuleElement
98− = Require JSNode String (Either String ModuleIdentifier)
99+ = Require JSStatement String (Either String ModuleIdentifier)
99− | Member JSNode Bool String [JSNode] [Key]
100+ | Member JSStatement Bool String JSExpression [Key]
100− | ExportsList [(ExportType, String, JSNode, [Key])]
101+ | ExportsList [(ExportType, String, JSExpression, [Key])]
101− | Other JSNode
102+ | Other JSStatement
102− deriving (Show, Read)
103+ deriving (Show)
104-- | A module is just a list of elements of the types listed above.
105-- | A module is just a list of elements of the types listed above.
105−data Module = Module ModuleIdentifier [ModuleElement] deriving (Show, Read)
106+data Module = Module ModuleIdentifier [ModuleElement] deriving (Show)
107-- | Prepare an error message for consumption by humans.
108-- | Prepare an error message for consumption by humans.
108printErrorMessage :: ErrorMessage -> [String]
109printErrorMessage :: ErrorMessage -> [String]
@@ -131,11 +132,6 @@ printErrorMessage (ErrorInModule mid e) =
131 displayIdentifier (ModuleIdentifier name ty) =
132 displayIdentifier (ModuleIdentifier name ty) =
132 name ++ " (" ++ showModuleType ty ++ ")"
133 name ++ " (" ++ showModuleType ty ++ ")"
134−-- | Unpack the node inside a JSNode. This is useful when pattern matching.
135−node :: JSNode -> Node
139-- | Calculate the ModuleIdentifier which a require(...) statement imports.
135-- | Calculate the ModuleIdentifier which a require(...) statement imports.
140checkImportPath :: Maybe FilePath -> String -> ModuleIdentifier -> S.Set String -> Either String ModuleIdentifier
136checkImportPath :: Maybe FilePath -> String -> ModuleIdentifier -> S.Set String -> Either String ModuleIdentifier
141checkImportPath _ "./foreign" m _ =
137checkImportPath _ "./foreign" m _ =
@@ -179,114 +175,124 @@ withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
180 -- | Calculate dependencies and add them to the current element.
176 -- | Calculate dependencies and add them to the current element.
181 expandDeps :: ModuleElement -> ModuleElement
177 expandDeps :: ModuleElement -> ModuleElement
182− expandDeps (Member n f nm decl _) = Member n f nm decl (nub (concatMap (dependencies modulePath) decl))
178+ expandDeps (Member n f nm decl _) = Member n f nm decl (nub $ dependencies modulePath decl)
183 expandDeps (ExportsList exps) = ExportsList (map expand exps)
179 expandDeps (ExportsList exps) = ExportsList (map expand exps)
185 expand (ty, nm, n1, _) = (ty, nm, n1, nub (dependencies modulePath n1))
181 expand (ty, nm, n1, _) = (ty, nm, n1, nub (dependencies modulePath n1))
186 expandDeps other = other
182 expandDeps other = other
188− dependencies :: ModuleIdentifier -> JSNode -> [(ModuleIdentifier, String)]
184+ dependencies :: ModuleIdentifier -> JSExpression -> [(ModuleIdentifier, String)]
189 dependencies m = everything (++) (mkQ [] toReference)
185 dependencies m = everything (++) (mkQ [] toReference)
191− toReference :: Node -> [(ModuleIdentifier, String)]
187+ toReference :: JSExpression -> [(ModuleIdentifier, String)]
192− toReference (JSMemberDot [ mn ] _ nm)
188+ toReference (JSMemberDot mn _ nm)
193− | JSIdentifier mn' <- node mn
189+ | JSIdentifier _ mn' <- mn
194− , JSIdentifier nm' <- node nm
190+ , JSIdentifier _ nm' <- nm
195 , Just mid <- lookup mn' imports
191 , Just mid <- lookup mn' imports
196 = [(mid, nm')]
192 = [(mid, nm')]
197− toReference (JSMemberSquare [ mn ] _ nm _)
193+ toReference (JSMemberSquare mn _ nm _)
198− | JSIdentifier mn' <- node mn
194+ | JSIdentifier _ mn' <- mn
199− , JSExpression [ s ] <- node nm
195+ , Just nm' <- fromStringLiteral nm
200− , JSStringLiteral _ nm' <- node s
201 , Just mid <- lookup mn' imports
196 , Just mid <- lookup mn' imports
202 = [(mid, nm')]
197 = [(mid, nm')]
203− toReference (JSIdentifier nm)
198+ toReference (JSIdentifier _ nm)
204 | nm `elem` boundNames
199 | nm `elem` boundNames
205 = [(m, nm)]
200 = [(m, nm)]
206 toReference _ = []
201 toReference _ = []
203+-- String literals include the quote chars
204+fromStringLiteral :: JSExpression -> Maybe String
205+fromStringLiteral (JSStringLiteral _ str) = Just $ trimStringQuotes str
206+fromStringLiteral _ = Nothing
208+trimStringQuotes :: String -> String
209+trimStringQuotes str = reverse $ drop 1 $ reverse $ drop 1 $ str
211+commaList :: JSCommaList a -> [a]
212+commaList JSLNil = []
213+commaList (JSLOne x) = [x]
214+commaList (JSLCons l _ x) = commaList l ++ [x]
216+trailingCommaList :: JSCommaTrailingList a -> [a]
217+trailingCommaList (JSCTLComma l _) = commaList l
218+trailingCommaList (JSCTLNone l) = commaList l
208-- | Attempt to create a Module from a Javascript AST.
220-- | Attempt to create a Module from a Javascript AST.
210-- Each type of module element is matched using pattern guards, and everything else is bundled into the
222-- Each type of module element is matched using pattern guards, and everything else is bundled into the
211-- Other constructor.
223-- Other constructor.
212−toModule :: forall m. (MonadError ErrorMessage m) => Maybe FilePath -> S.Set String -> ModuleIdentifier -> JSNode -> m Module
224+toModule :: forall m. (MonadError ErrorMessage m) => Maybe FilePath -> S.Set String -> ModuleIdentifier -> JSAST -> m Module
213toModule requirePath mids mid top
225toModule requirePath mids mid top
214− | JSSourceElementsTop ns <- node top = Module mid <$> traverse toModuleElement ns
226+ | JSAstProgram smts _ <- top = Module mid <$> traverse toModuleElement smts
215 | otherwise = err InvalidTopLevel
227 | otherwise = err InvalidTopLevel
217 err = throwError . ErrorInModule mid
229 err = throwError . ErrorInModule mid
219− toModuleElement :: JSNode -> m ModuleElement
231+ toModuleElement :: JSStatement -> m ModuleElement
232+ -- var ModuleName = require("file");
220− toModuleElement n
233+ toModuleElement stmt
221− | JSVariables var [ varIntro ] _ <- node n
234+ | JSVariable _ jsInit _ <- stmt
222− , JSLiteral "var" <- node var
235+ , [JSVarInitExpression var varInit] <- commaList jsInit
223− , JSVarDecl impN [ eq, req, impP ] <- node varIntro
224− , JSIdentifier importName <- node impN
236+ , JSIdentifier _ importName <- var
225− , JSLiteral "=" <- node eq
237+ , JSVarInit _ jsInitEx <- varInit
226− , JSIdentifier "require" <- node req
238+ , JSMemberExpression req _ argsE _ <- jsInitEx
227− , JSArguments _ [ impS ] _ <- node impP
239+ , JSIdentifier _ "require" <- req
228− , JSStringLiteral _ importPath <- node impS
240+ , [ Just importPath ] <- map fromStringLiteral (commaList argsE)
229 , importPath' <- checkImportPath requirePath importPath mid mids
241 , importPath' <- checkImportPath requirePath importPath mid mids
230− = pure (Require n importName importPath')
242+ = pure (Require stmt importName importPath')
231− toModuleElement n
244+ toModuleElement stmt
232− | JSVariables var [ varIntro ] _ <- node n
245+ | JSVariable _ jsInit _ <- stmt
233− , JSLiteral "var" <- node var
246+ , [JSVarInitExpression var varInit] <- commaList jsInit
234− , JSVarDecl declN (eq : decl) <- node varIntro
235− , JSIdentifier name <- node declN
247+ , JSIdentifier _ name <- var
236− , JSLiteral "=" <- node eq
248+ , JSVarInit _ decl <- varInit
237− = pure (Member n False name decl [])
249+ = pure (Member stmt False name decl [])
250+ -- exports.foo = expr; exports["foo"] = expr;
238− toModuleElement n
251+ toModuleElement stmt
239− | JSExpression (e : op : decl) <- node n
252+ | JSAssignStatement e (JSAssign _) decl _ <- stmt
240− , Just name <- accessor (node e)
253+ , Just name <- accessor e
241− , JSOperator eq <- node op
242− , JSLiteral "=" <- node eq
243− = pure (Member n True name decl [])
254+ = pure (Member stmt True name decl [])
245− accessor :: Node -> Maybe String
256+ accessor :: JSExpression -> Maybe String
246− accessor (JSMemberDot [ exports ] _ nm)
257+ accessor (JSMemberDot exports _ nm)
247− | JSIdentifier "exports" <- node exports
258+ | JSIdentifier _ "exports" <- exports
248− , JSIdentifier name <- node nm
259+ , JSIdentifier _ name <- nm
249 = Just name
260 = Just name
250− accessor (JSMemberSquare [ exports ] _ nm _)
261+ accessor (JSMemberSquare exports _ nm _)
251− | JSIdentifier "exports" <- node exports
262+ | JSIdentifier _ "exports" <- exports
252− , JSExpression [e] <- node nm
263+ , Just name <- fromStringLiteral nm
253− , JSStringLiteral _ name <- node e
254 = Just name
264 = Just name
255 accessor _ = Nothing
265 accessor _ = Nothing
266+ -- module.exports = { ... }
256− toModuleElement n
267+ toModuleElement stmt
257− | JSExpression (mnExp : op : obj: _) <- node n
268+ | JSAssignStatement e (JSAssign _) decl _ <- stmt
258− , JSMemberDot [ mn ] _ e <- node mnExp
269+ , JSMemberDot module' _ exports <- e
259− , JSIdentifier "module" <- node mn
270+ , JSIdentifier _ "module" <- module'
260− , JSIdentifier "exports" <- node e
271+ , JSIdentifier _ "exports" <- exports
261− , JSOperator eq <- node op
262− , JSLiteral "=" <- node eq
263− , JSObjectLiteral _ props _ <- node obj
272+ , JSObjectLiteral _ props _ <- decl
264− = ExportsList <$> traverse toExport (filter (not . isSeparator) (map node props))
273+ = (ExportsList <$> traverse toExport (trailingCommaList props))
266− toExport :: Node -> m (ExportType, String, JSNode, [Key])
275+ toExport :: JSObjectProperty -> m (ExportType, String, JSExpression, [Key])
267− toExport (JSPropertyNameandValue name _ [val] ) =
276+ toExport (JSPropertyNameandValue name _ [val]) =
268− (,,val,[]) <$> exportType (node val)
277+ (,,val,[]) <$> exportType val
269− <*> extractLabel (node name)
278+ <*> extractLabel name
270− toExport _ = err UnsupportedExport
279+ toExport _ = err UnsupportedExport
272− exportType :: Node -> m ExportType
281+ exportType :: JSExpression -> m ExportType
273− exportType (JSMemberDot [f] _ _)
282+ exportType (JSMemberDot f _ _)
274− | JSIdentifier "$foreign" <- node f
283+ | JSIdentifier _ "$foreign" <- f
275− = pure ForeignReexport
284+ = pure ForeignReexport
276− exportType (JSMemberSquare [f] _ _ _)
285+ exportType (JSMemberSquare f _ _ _)
277− | JSIdentifier "$foreign" <- node f
286+ | JSIdentifier _ "$foreign" <- f
278− = pure ForeignReexport
287+ = pure ForeignReexport
279− exportType (JSIdentifier s) = pure (RegularExport s)
288+ exportType (JSIdentifier _ s) = pure (RegularExport s)
280− exportType _ = err UnsupportedExport
289+ exportType _ = err UnsupportedExport
282− extractLabel :: Node -> m String
291+ extractLabel :: JSPropertyName -> m String
283− extractLabel (JSStringLiteral _ nm) = pure nm
292+ extractLabel (JSPropertyString _ nm) = pure (trimStringQuotes nm)
284− extractLabel (JSIdentifier nm) = pure nm
293+ extractLabel (JSPropertyIdent _ nm) = pure nm
285− extractLabel _ = err UnsupportedExport
294+ extractLabel _ = err UnsupportedExport
287− isSeparator :: Node -> Bool
288− isSeparator (JSLiteral ",") = True
289− isSeparator _ = False
290 toModuleElement other = pure (Other other)
296 toModuleElement other = pure (Other other)
292-- | Eliminate unused code based on the specified entry point set.
298-- | Eliminate unused code based on the specified entry point set.
@@ -339,10 +345,6 @@ compile modules entryPoints = filteredModules
340 go :: [ModuleElement] -> [ModuleElement]
346 go :: [ModuleElement] -> [ModuleElement]
341 go [] = []
347 go [] = []
342− go (d : Other semi : rest)
343− | JSLiteral ";" <- node semi
344− , not (isDeclUsed d)
346 go (d : rest)
348 go (d : rest)
347 | not (isDeclUsed d) = go rest
349 | not (isDeclUsed d) = go rest
348 | otherwise = d : go rest
350 | otherwise = d : go rest
@@ -405,130 +407,121 @@ codeGen :: Maybe String -- ^ main module
405 -> String -- ^ namespace
407 -> String -- ^ namespace
406 -> [Module] -- ^ input modules
408 -> [Module] -- ^ input modules
407 -> String
409 -> String
408−codeGen optionsMainModule optionsNamespace ms = renderToString (NN (JSSourceElementsTop (prelude ++ concatMap moduleToJS ms ++ maybe [] runMain optionsMainModule)))
410+codeGen optionsMainModule optionsNamespace ms = renderToString (JSAstProgram (prelude : concatMap moduleToJS ms ++ maybe [] runMain optionsMainModule) JSNoAnnot)
410− moduleToJS :: Module -> [JSNode]
412+ moduleToJS :: Module -> [JSStatement]
411 moduleToJS (Module mn ds) = wrap (moduleName mn) (indent (concatMap declToJS ds))
413 moduleToJS (Module mn ds) = wrap (moduleName mn) (indent (concatMap declToJS ds))
413− declToJS :: ModuleElement -> [JSNode]
415+ declToJS :: ModuleElement -> [JSStatement]
414 declToJS (Member n _ _ _ _) = [n]
416 declToJS (Member n _ _ _ _) = [n]
415 declToJS (Other n) = [n]
417 declToJS (Other n) = [n]
416 declToJS (Require _ nm req) =
418 declToJS (Require _ nm req) =
417− [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ])
419+ [
418− [ NN (JSVarDecl (sp (JSIdentifier nm))
422+ JSVarInitExpression (JSIdentifier sp nm)
419− (sp (JSLiteral "=") : either require (return . moduleReference sp . moduleName) req))
423+ (JSVarInit sp $ either require (moduleReference sp . moduleName) req )
420− ]
424+ ]) (JSSemi JSNoAnnot)
421− (nt (JSLiteral ";"))) ]
425+ ]
422 declToJS (ExportsList exps) = map toExport exps
426 declToJS (ExportsList exps) = map toExport exps
425− toExport :: (ExportType, String, JSNode, [Key]) -> JSNode
429+ toExport :: (ExportType, String, JSExpression, [Key]) -> JSStatement
426 toExport (_, nm, val, _) =
430 toExport (_, nm, val, _) =
427− NN (JSExpression [ NN (JSMemberSquare [ NT (JSIdentifier "exports") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ] ]
432+ (JSMemberSquare (JSIdentifier lfsp "exports") JSNoAnnot
428− (nt (JSLiteral "["))
433+ (str nm) JSNoAnnot)
429− (NN (JSExpression [ nt (JSStringLiteral '"' nm) ]))
434+ (JSAssign sp)
430− (nt (JSLiteral "]")))
431− , NN (JSOperator (sp (JSLiteral "=")))
432− , reindent val
435+ val
433− , nt (JSLiteral ";")
436+ (JSSemi JSNoAnnot)
435−
438+ -- comma lists are reverse-consed
436− reindent :: JSNode -> JSNode
439+ cList :: [a] -> JSCommaList a
437− reindent (NT n _ _) = sp n
440+ cList [] = JSLNil
438− reindent nn = nn
441+ cList [x] = JSLOne x
439−
442+ cList l = go $ reverse l
440− indent :: [JSNode] -> [JSNode]
443+ where
445+ go (h:t)= JSLCons (go t) JSNoAnnot h
446+ go [] = error "Invalid case in comma-list"
448+ indent :: [JSStatement] -> [JSStatement]
441 indent = everywhere (mkT squash)
449 indent = everywhere (mkT squash)
451+ squash JSNoAnnot = (JSAnnot (TokenPn 0 0 2) [])
443− squash (NT n pos ann) = NT n (keepCol pos) (map splat ann)
452+ squash (JSAnnot pos ann) = JSAnnot (keepCol pos) (map splat ann)
446 splat (CommentA pos s) = CommentA (keepCol pos) s
454 splat (CommentA pos s) = CommentA (keepCol pos) s
447 splat (WhiteSpace pos w) = WhiteSpace (keepCol pos) w
455 splat (WhiteSpace pos w) = WhiteSpace (keepCol pos) w
448 splat ann = ann
456 splat ann = ann
450− keepCol (TokenPn _ _ c) = TokenPn 0 0 (c + 2)
458+ keepCol (TokenPn _ _ c) = TokenPn 0 0 (if c >= 0 then c + 2 else 2)
452− prelude :: [JSNode]
460+ prelude :: JSStatement
454− [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ CommentA tokenPosnEmpty ("// Generated by psc-bundle " ++ showVersion Paths.version)
461+ prelude = JSVariable (JSAnnot tokenPosnEmpty [ CommentA tokenPosnEmpty $ "// Generated by psc-bundle " ++ showVersion Paths.version
455− , WhiteSpace tokenPosnEmpty "\n"
462+ , WhiteSpace tokenPosnEmpty "\n" ])
457− [ NN (JSVarDecl (sp (JSIdentifier optionsNamespace))
464+ JSVarInitExpression (JSIdentifier sp optionsNamespace)
458− [ sp (JSLiteral "=")
465+ (JSVarInit sp (emptyObj sp))
459− , NN (JSObjectLiteral (sp (JSLiteral "{"))
466+ ]) (JSSemi JSNoAnnot)
461− (sp (JSLiteral "}")))
468+ require :: String -> JSExpression
463− ]
470+ JSMemberExpression (JSIdentifier JSNoAnnot "require") JSNoAnnot (cList [ str mn ]) JSNoAnnot
464− (nt (JSLiteral ";")))
471+
465− , lf
472+ moduleReference :: JSAnnot -> String -> JSExpression
466− ]
473+ moduleReference a mn =
474+ JSMemberSquare (JSIdentifier a optionsNamespace) JSNoAnnot
468− require :: String -> [JSNode]
477+ str :: String -> JSExpression
469− require mn = [ sp (JSIdentifier "require")
478+ str s = JSStringLiteral JSNoAnnot $ "\"" ++ s ++ "\""
470− , NN (JSArguments (nt (JSLiteral "(")) [ nt (JSStringLiteral '"' mn) ] (nt (JSLiteral ")")))
473− moduleReference :: (Node -> JSNode) -> String -> JSNode
474− moduleReference f mn =
475− NN (JSMemberSquare [ f (JSIdentifier optionsNamespace) ]
476− (nt (JSLiteral "["))
477− (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
478− (nt (JSLiteral "]")))
480− wrap :: String -> [JSNode] -> [JSNode]
481+ emptyObj :: JSAnnot -> JSExpression
482+ emptyObj a = JSObjectLiteral a (JSCTLNone JSLNil) JSNoAnnot
484+ wrap :: String -> [JSStatement] -> [JSStatement]
481 wrap mn ds =
485 wrap mn ds =
482− [ NN (JSExpression [ NN (JSExpressionParen (nt (JSLiteral "("))
486+ [
483− (NN (JSExpression [ NN (JSFunctionExpression (nt (JSLiteral "function"))
487+ JSMethodCall (JSExpressionParen lf (JSFunctionExpression JSNoAnnot JSIdentNone JSNoAnnot
484− []
488+ (JSLOne (JSIdentName JSNoAnnot "exports")) JSNoAnnot
485− (nt (JSLiteral "(") ) [nt (JSIdentifier "exports")] (nt (JSLiteral ")"))
489+ (JSBlock sp (lfHead ds) lf)) -- \n not quite in right place
486− (NN (JSBlock [sp (JSLiteral "{")]
490+ JSNoAnnot)
487− (lf : ds)
491+ JSNoAnnot
488− [nl (JSLiteral "}")])))]))
492+ (JSLOne (JSAssignExpression (moduleReference JSNoAnnot mn) (JSAssign sp)
489− (nt (JSLiteral ")")))
490− , NN (JSArguments (nt (JSLiteral "("))
491− [ NN (JSExpression [ moduleReference nt mn
492− , NN (JSOperator (sp (JSLiteral "=")))
493− , NN (JSExpressionBinary "||"
494− [ moduleReference sp mn ]
493+ (JSExpressionBinary (moduleReference sp mn) (JSBinOpOr sp) (emptyObj sp))))
495− (sp (JSLiteral "||"))
494+ JSNoAnnot
496− [ emptyObj ])
495+ (JSSemi JSNoAnnot)
499− (nt (JSLiteral ")")))
501− , nt (JSLiteral ";")
505− emptyObj = NN (JSObjectLiteral (sp (JSLiteral "{")) [] (nt (JSLiteral "}")))
498+ lfHead (h:t) = (addAnn (WhiteSpace tokenPosnEmpty "\n ") h) : t
501+ addAnn :: CommentAnnotation -> JSStatement -> JSStatement
502+ addAnn a (JSExpressionStatement (JSStringLiteral ann s) _) =
503+ (JSExpressionStatement (JSStringLiteral (appendAnn a ann) s) (JSSemi JSNoAnnot))
506+ appendAnn a JSNoAnnot = (JSAnnot tokenPosnEmpty [a])
507+ appendAnn a (JSAnnot _ anns) = JSAnnot tokenPosnEmpty (a:anns ++ [WhiteSpace tokenPosnEmpty " "])
507− runMain :: String -> [JSNode]
509+ runMain :: String -> [JSStatement]
508 runMain mn =
510 runMain mn =
509− [ NN (JSExpression [ NN (JSMemberDot [ NN (JSMemberSquare [ nl (JSIdentifier optionsNamespace) ]
511+ [JSMethodCall
510− (nt (JSLiteral "["))
512+ (JSMemberDot (moduleReference lf mn) JSNoAnnot
511− (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
512− (nt (JSLiteral "]")))
514− (nt (JSLiteral "."))
515− (nt (JSIdentifier "main")))
513+ (JSIdentifier JSNoAnnot "main"))
516− , NN (JSArguments (nt (JSLiteral "(")) [] (nt (JSLiteral ")")))
514+ JSNoAnnot (cList []) JSNoAnnot (JSSemi JSNoAnnot)]
518− , nt (JSLiteral ";")
521− nt :: Node -> JSNode
516+ lf :: JSAnnot
522− nt n = NT n tokenPosnEmpty []
517+ lf = JSAnnot tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
525− lf = NT (JSLiteral "") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
527− sp :: Node -> JSNode
520+ lfsp :: JSAnnot
528− sp n = NT n tokenPosnEmpty [ WhiteSpace tokenPosnEmpty " " ]
521+ lfsp = JSAnnot tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ]
530− nl :: Node -> JSNode
523+ sp :: JSAnnot
531− nl n = NT n tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
524+ sp = JSAnnot tokenPosnEmpty [ WhiteSpace tokenPosnEmpty " " ]
533-- | The bundling function.
526-- | The bundling function.
534-- This function performs dead code elimination, filters empty modules
527-- This function performs dead code elimination, filters empty modules