@@ -44,7 +44,6 @@ import Data.Newtype (class Newtype)
4444import Data.Set (Set)
4545import Data.Set as Set
4646import Data.String as String
47−import Data.Traversable (traverse)
4847import Data.Tuple (Tuple(..), fst, snd)
4948import Dodo as Dodo
5049import Dodo.Common as Dodo.Common
@@ -277,42 +276,39 @@ build syn = case syn of
277276 EsCall (EsExpr _ (EsArrowFunction [] bs)) []
278277 | Just expr <- inlineCallBlock bs ->
279278 expr
280− EsReturn (Just b)
281− | Just expr' <- inlineLoopBlockStatement b ->
282− expr'
283279 EsReturn (Just (EsExpr _ EsUndefined)) ->
284280 build $ EsReturn Nothing
285− EsArrowFunction as bs
286− | Just (EsExpr _ (EsReturn Nothing)) <- Array.last bs ->
287− esArrowFunction as $ Array.dropEnd 1 bs
288281 EsArrowFunction as [ block ]
289282 | Just bs <- inlineReturnBlock block ->
290283 esArrowFunction as bs
291284 EsArrowFunction as bs -> do
292− let Tuple s bs' = buildStatements bs
293− EsExpr (alwaysPure (bumpSize s)) $ EsArrowFunction as bs'
294− EsIfElse a [ block ] cs
295− | Just bs <- inlineReturnBlock block ->
296− build $ EsIfElse a bs cs
285+ let bs' = buildStatements bs
286+ case removeTrailingReturn bs' of
287+ Just bs'' ->
288+ build $ EsArrowFunction as bs''
289+ Nothing ->
290+ EsExpr (alwaysPure (bumpSize (foldMap esAnalysisOf bs'))) $ EsArrowFunction as bs'
297291 EsIfElse a bs [ block ]
298292 | Just cs <- inlineReturnBlock block ->
299293 build $ EsIfElse a bs cs
300294 EsIfElse a bs cs -> do
301− let Tuple s1 bs' = buildStatements bs
302− let Tuple s2 cs' = buildStatements cs
303− EsExpr (bumpSize (esAnalysisOf a <> s1 <> s2)) $ EsIfElse a bs' cs'
304− EsWhile a bs
305− | Just bs' <- removeTrailingContinue bs ->
306− build $ EsWhile a bs'
307− | otherwise -> do
308− let Tuple s bs' = buildStatements bs
309− EsExpr (bumpSize (esAnalysisOf a <> s)) $ EsWhile a bs'
310− EsForOf a b cs
311− | Just cs' <- removeTrailingContinue cs ->
312− build $ EsForOf a b cs'
313− | otherwise -> do
314− let Tuple s cs' = buildStatements cs
315− EsExpr (bumpSize (esAnalysisOf b <> s)) $ EsForOf a b cs'
295+ let bs' = buildStatements bs
296+ let cs' = buildStatements cs
297+ EsExpr (bumpSize (esAnalysisOf a <> foldMap esAnalysisOf bs' <> foldMap esAnalysisOf cs')) $ EsIfElse a bs' cs'
298+ EsWhile a bs -> do
299+ let bs' = buildStatements bs
300+ case removeTrailingContinue bs' of
301+ Just bs'' ->
302+ build $ EsWhile a bs''
303+ Nothing ->
304+ EsExpr (bumpSize (esAnalysisOf a <> foldMap esAnalysisOf bs')) $ EsWhile a bs'
305+ EsForOf a b cs -> do
306+ let cs' = buildStatements cs
307+ case removeTrailingContinue cs' of
308+ Just cs'' ->
309+ build $ EsForOf a b cs''
310+ Nothing ->
311+ EsExpr (bumpSize (esAnalysisOf b <> foldMap esAnalysisOf cs')) $ EsForOf a b cs'
316312 EsUnary EsNot (EsExpr _ (EsBinary EsEquals a b)) ->
317313 build $ EsBinary EsNotEquals a b
318314 _ ->
@@ -327,14 +323,18 @@ build syn = case syn of
327323 EsArrowFunction _ _ -> alwaysPure
328324 _ -> identity
329325
330−buildStatements :: Array EsExpr -> Tuple EsAnalysis (Array EsExpr)
331−buildStatements = traverse go <<< mergeBranchTails
326+buildStatements :: Array EsExpr -> Array EsExpr
327+buildStatements = (go =<< _) <<< mergeBranchTails
332328 where
333− go expr = case expr of
334− _ | Just expr' <- inlineLoopBlockStatement expr ->
335− go expr'
336− _ ->
337− Tuple (esAnalysisOf expr) expr
329+ go = case _ of
330+ EsExpr _ (EsReturn (Just expr'))
331+ | Just expr'' <- inlineLoopBlockStatement expr' ->
332+ Array.snoc (go expr'') $ build $ EsReturn Nothing
333+ expr
334+ | Just expr' <- inlineLoopBlockStatement expr ->
335+ go expr'
336+ expr ->
337+ [ expr ]
338338
339339 -- For nested if/else blocks, merges a duplicate tail of alternatives
340340 -- via fallthrough. If an inner branch has a tail that matches the
@@ -391,11 +391,24 @@ inlineLoopBlockStatement (EsExpr _ expr) = case expr of
391391 _ ->
392392 Nothing
393393
394+removeTrailingReturn :: Array EsExpr -> Maybe (Array EsExpr)
395+removeTrailingReturn stmts = case Array.last stmts of
396+ Just (EsExpr _ (EsIfElse a bs []))
397+ | Just cs <- removeTrailingReturn bs ->
398+ Just $ Array.snoc (Array.dropEnd 1 stmts) $ build $ EsIfElse a cs []
399+ Just (EsExpr _ (EsReturn Nothing)) ->
400+ Just (Array.dropEnd 1 stmts)
401+ Just expr
402+ | Just stmts' <- inlineReturnBlock expr ->
403+ Just (Array.dropEnd 1 stmts <> stmts')
404+ _ ->
405+ Nothing
406+
394407removeTrailingContinue :: Array EsExpr -> Maybe (Array EsExpr)
395408removeTrailingContinue stmts = case Array.last stmts of
396− Just (EsExpr s (EsIfElse a bs []))
409+ Just (EsExpr _ (EsIfElse a bs []))
397410 | Just cs <- removeTrailingContinue bs ->
398− Just $ Array.snoc (Array.dropEnd 1 stmts) $ EsExpr s $ EsIfElse a cs []
411+ Just $ Array.snoc (Array.dropEnd 1 stmts) $ build $ EsIfElse a cs []
399412 Just (EsExpr _ EsContinue) ->
400413 Just (Array.dropEnd 1 stmts)
401414 _ ->