@@ -26,7 +26,7 @@ import qualified Data.Text as T
2626
2727import Language.PureScript.AST.SourcePos
2828import Language.PureScript.CodeGen.JS.Common as Common
29- import Language.PureScript.CoreImp.AST (AST , everywhereTopDownM , withSourceSpan )
29+ import Language.PureScript.CoreImp.AST (AST , PurityAnnotation ( .. ), everywhereTopDownM , withSourceSpan )
3030import qualified Language.PureScript.CoreImp.AST as AST
3131import Language.PureScript.CoreImp.Optimizer
3232import Language.PureScript.CoreFn
@@ -56,7 +56,7 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
5656 let mnLookup = renameImports usedNames imps
5757 let decls' = renameModules mnLookup decls
5858 jsDecls <- mapM bindToJs decls'
59- optimized <- traverse ( traverse optimize ) jsDecls
59+ optimized <- optimize ( map identToJs exps ) jsDecls
6060 let mnReverseLookup = M. fromList $ map (\ (origName, (_, safeName)) -> (moduleNameToJs safeName, origName)) $ M. toList mnLookup
6161 let usedModuleNames = foldMap (foldMap (findModules mnReverseLookup)) optimized
6262 `S.union` M. keysSet reExps
@@ -67,7 +67,7 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
6767 comments <- not <$> asks optionsNoComments
6868 let strict = AST. StringLiteral Nothing " use strict"
6969 let header = if comments && not (null coms) then AST. Comment Nothing coms strict else strict
70- let foreign' = [AST. VariableIntroduction Nothing " $foreign" foreign_ | not $ null foreigns || isNothing foreign_]
70+ let foreign' = [AST. VariableIntroduction Nothing " $foreign" ( fmap ( UnknownPurity ,) foreign_) | not $ null foreigns || isNothing foreign_]
7171 let moduleBody = header : foreign' ++ jsImports ++ concat optimized
7272 let foreignExps = exps `intersect` foreigns
7373 let standardExps = exps \\ foreignExps
@@ -127,7 +127,7 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
127127 let ((ss, _, _, _), mnSafe) = fromMaybe (internalError " Missing value in mnLookup" ) $ M. lookup mn' mnLookup
128128 let moduleBody = AST. App Nothing (AST. Var Nothing " require" )
129129 [AST. StringLiteral Nothing (fromString (" .." </> T. unpack (runModuleName mn') </> " index.js" ))]
130- withPos ss $ AST. VariableIntroduction Nothing (moduleNameToJs mnSafe) (Just moduleBody)
130+ withPos ss $ AST. VariableIntroduction Nothing (moduleNameToJs mnSafe) (Just ( UnknownPurity , moduleBody) )
131131
132132 -- | Replaces the `ModuleName`s in the AST so that the generated code refers to
133133 -- the collision-avoiding renamed module imports.
@@ -180,7 +180,13 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
180180 else AST. Comment Nothing com <$> nonRecToJS a i (modifyAnn removeComments e)
181181 nonRecToJS (ss, _, _, _) ident val = do
182182 js <- valueToJs val
183- withPos ss $ AST. VariableIntroduction Nothing (identToJs ident) (Just js)
183+ withPos ss $ AST. VariableIntroduction Nothing (identToJs ident) (Just (guessPurity val, js))
184+
185+ guessPurity :: Expr Ann -> AST. PurityAnnotation
186+ guessPurity = \ case
187+ Var _ (Qualified Nothing _) -> IsPure
188+ App (_, _, _, Just IsSyntheticApp ) _ _ -> IsPure
189+ _ -> UnknownPurity
184190
185191 withPos :: SourceSpan -> AST -> m AST
186192 withPos ss js = do
@@ -257,7 +263,7 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
257263 ret <- valueToJs val
258264 return $ AST. App Nothing (AST. Function Nothing Nothing [] (AST. Block Nothing (ds' ++ [AST. Return Nothing ret]))) []
259265 valueToJs' (Constructor (_, _, _, Just IsNewtype ) _ ctor _) =
260- return $ AST. VariableIntroduction Nothing (properToJs ctor) (Just $
266+ return $ AST. VariableIntroduction Nothing (properToJs ctor) (Just . ( UnknownPurity ,) $
261267 AST. ObjectLiteral Nothing [(" create" ,
262268 AST. Function Nothing Nothing [" value" ]
263269 (AST. Block Nothing [AST. Return Nothing $ AST. Var Nothing " value" ]))])
@@ -299,8 +305,8 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
299305 jsNewObj = AST. Var Nothing newObj
300306 jsEvaluatedObj = AST. Var Nothing evaluatedObj
301307 block = AST. Block Nothing (evaluate: objAssign: copy: extend ++ [AST. Return Nothing jsNewObj])
302- evaluate = AST. VariableIntroduction Nothing evaluatedObj (Just obj)
303- objAssign = AST. VariableIntroduction Nothing newObj (Just $ AST. ObjectLiteral Nothing [] )
308+ evaluate = AST. VariableIntroduction Nothing evaluatedObj (Just ( UnknownPurity , obj) )
309+ objAssign = AST. VariableIntroduction Nothing newObj (Just ( IsPure , AST. ObjectLiteral Nothing [] ) )
304310 copy = AST. ForIn Nothing key jsEvaluatedObj $ AST. Block Nothing [AST. IfElse Nothing cond assign Nothing ]
305311 cond = AST. App Nothing (accessorString " call" (accessorString " hasOwnProperty" (AST. ObjectLiteral Nothing [] ))) [jsEvaluatedObj, jsKey]
306312 assign = AST. Block Nothing [AST. Assignment Nothing (AST. Indexer Nothing jsKey jsNewObj) (AST. Indexer Nothing jsKey jsEvaluatedObj)]
@@ -329,7 +335,7 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
329335 bindersToJs :: SourceSpan -> [CaseAlternative Ann ] -> [AST ] -> m AST
330336 bindersToJs ss binders vals = do
331337 valNames <- replicateM (length vals) freshName
332- let assignments = zipWith (AST. VariableIntroduction Nothing ) valNames (map Just vals)
338+ let assignments = zipWith (AST. VariableIntroduction Nothing ) valNames (map ( Just . ( UnknownPurity ,)) vals)
333339 jss <- forM binders $ \ (CaseAlternative bs result) -> do
334340 ret <- guardsToJs result
335341 go valNames ret bs
@@ -378,7 +384,7 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
378384 binderToJs' varName done (LiteralBinder _ l) =
379385 literalToBinderJS varName done l
380386 binderToJs' varName done (VarBinder _ ident) =
381- return (AST. VariableIntroduction Nothing (identToJs ident) (Just (AST. Var Nothing varName)) : done)
387+ return (AST. VariableIntroduction Nothing (identToJs ident) (Just (IsPure , AST. Var Nothing varName)) : done)
382388 binderToJs' varName done (ConstructorBinder (_, _, _, Just IsNewtype ) _ _ [b]) =
383389 binderToJs varName done b
384390 binderToJs' varName done (ConstructorBinder (_, _, _, Just (IsConstructor ctorType fields)) _ ctor bs) = do
@@ -396,12 +402,12 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
396402 argVar <- freshName
397403 done'' <- go remain done'
398404 js <- binderToJs argVar done'' binder
399- return (AST. VariableIntroduction Nothing argVar (Just $ accessorString (mkString $ identToJs field) $ AST. Var Nothing varName) : js)
405+ return (AST. VariableIntroduction Nothing argVar (Just ( UnknownPurity , accessorString (mkString $ identToJs field) $ AST. Var Nothing varName) ) : js)
400406 binderToJs' _ _ ConstructorBinder {} =
401407 internalError " binderToJs: Invalid ConstructorBinder in binderToJs"
402408 binderToJs' varName done (NamedBinder _ ident binder) = do
403409 js <- binderToJs varName done binder
404- return (AST. VariableIntroduction Nothing (identToJs ident) (Just (AST. Var Nothing varName)) : js)
410+ return (AST. VariableIntroduction Nothing (identToJs ident) (Just (IsPure , AST. Var Nothing varName)) : js)
405411
406412 literalToBinderJS :: Text -> [AST ] -> Literal (Binder Ann ) -> m [AST ]
407413 literalToBinderJS varName done (NumericLiteral num) =
@@ -422,7 +428,7 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
422428 propVar <- freshName
423429 done'' <- go done' bs'
424430 js <- binderToJs propVar done'' binder
425- return (AST. VariableIntroduction Nothing propVar (Just (accessorString prop (AST. Var Nothing varName))) : js)
431+ return (AST. VariableIntroduction Nothing propVar (Just (UnknownPurity , accessorString prop (AST. Var Nothing varName))) : js)
426432 literalToBinderJS varName done (ArrayLiteral bs) = do
427433 js <- go done 0 bs
428434 return [AST. IfElse Nothing (AST. Binary Nothing AST. EqualTo (accessorString " length" (AST. Var Nothing varName)) (AST. NumericLiteral Nothing (Left (fromIntegral $ length bs)))) (AST. Block Nothing js) Nothing ]
@@ -433,7 +439,7 @@ moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreign_ =
433439 elVar <- freshName
434440 done'' <- go done' (index + 1 ) bs'
435441 js <- binderToJs elVar done'' binder
436- return (AST. VariableIntroduction Nothing elVar (Just (AST. Indexer Nothing (AST. NumericLiteral Nothing (Left index)) (AST. Var Nothing varName))) : js)
442+ return (AST. VariableIntroduction Nothing elVar (Just (UnknownPurity , AST. Indexer Nothing (AST. NumericLiteral Nothing (Left index)) (AST. Var Nothing varName))) : js)
437443
438444 -- Check that all integers fall within the valid int range for JavaScript.
439445 checkIntegers :: AST -> m ()
0 commit comments