Skip to content

Commit 6f6b61c

Browse files
authored
Merge pull request #2132 from DanielXMoore/claude/issue-2131-20260530-1726
Fix postfix if/unless followed by ; emitting invalid JS
2 parents 9a263a2 + c32cccd commit 6f6b61c

3 files changed

Lines changed: 55 additions & 7 deletions

File tree

source/parser.hera

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6206,8 +6206,8 @@ MaybeNestedExpression ::unknown
62066206
# (e.g. for `return` or `yield`)
62076207
# This also doesn't allow initial __ (whereas MaybeNestedExpression does)
62086208
MaybeParenNestedExpression
6209-
# Skip if there's a postfix if/etc.
6210-
&( _? PostfixStatement NoBlock ) -> ""
6209+
# Skip if there's a postfix if/etc., possibly followed by `;` (see #2131).
6210+
&( _? PostfixStatement ( NoBlock / ( _? Semicolon ) ) ) -> ""
62116211
# Not nested case
62126212
!EOS Expression -> $2
62136213
# Avoid double wrapping nested array/object return value in parentheses.

source/parser/function.civet

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,11 +1343,19 @@ function skipImplicitArguments(args: ASTNode[]): boolean
13431343
if arg0!.type is "StatementExpression"
13441344
arg0 = arg0.statement
13451345

1346-
return (and)
1347-
arg0!.type is "IterationExpression"
1348-
arg0!.subtype !== "DoStatement"
1349-
!arg0!.async
1350-
isEmptyBareBlock arg0.block
1346+
if arg0!.type is "IterationExpression"
1347+
return (and)
1348+
arg0!.subtype !== "DoStatement"
1349+
!arg0!.async
1350+
isEmptyBareBlock arg0.block
1351+
1352+
// Postfix `if`/`unless` followed by `;` (empty body) should be treated
1353+
// as a postfix modifier, not as an implicit-call argument with an empty
1354+
// consequent. See #2131.
1355+
if arg0!.type is "IfStatement"
1356+
return (and)
1357+
!arg0!.else
1358+
isEmptyBareBlock arg0.then
13511359

13521360
return false
13531361

test/if.civet

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,46 @@ describe "if", ->
636636
let x = 2
637637
"""
638638

639+
testCase """
640+
postfix if followed by semicolon (#2131)
641+
---
642+
foo() if x;
643+
---
644+
if (x) { foo() };
645+
"""
646+
647+
testCase """
648+
postfix unless followed by semicolon (#2131)
649+
---
650+
foo() unless x;
651+
---
652+
if (!x) { foo() };
653+
"""
654+
655+
testCase """
656+
return postfix unless followed by semicolon (#2131)
657+
---
658+
return unless x;
659+
---
660+
if (!x) { return };
661+
"""
662+
663+
testCase """
664+
return postfix if followed by semicolon (#2131)
665+
---
666+
return if x;
667+
---
668+
if (x) { return };
669+
"""
670+
671+
testCase """
672+
throw postfix unless followed by semicolon (#2131)
673+
---
674+
throw err unless x;
675+
---
676+
if (!x) { throw err };
677+
"""
678+
639679
testCase """
640680
postfix if with indented condition
641681
---

0 commit comments

Comments
 (0)