summaryrefslogtreecommitdiffstats
path: root/js/src/frontend/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend/Parser.cpp')
-rw-r--r--js/src/frontend/Parser.cpp88
1 files changed, 49 insertions, 39 deletions
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index cf9f1e27c..810d589be 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -6901,57 +6901,67 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
/*
* Legal catch forms are:
* catch (lhs)
- * catch (lhs if <boolean_expression>)
+ * catch (lhs if <boolean_expression>) ** non-standard **
+ * catch ** ES2019 **
* where lhs is a name or a destructuring left-hand side.
- * (the latter is legal only #ifdef JS_HAS_CATCH_GUARD)
+ * The second is legal only #ifdef JS_HAS_CATCH_GUARD
*/
- MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);
-
- if (!tokenStream.getToken(&tt))
+ bool omittedBinding;
+ if (!tokenStream.matchToken(&omittedBinding, TOK_LC))
return null();
+
Node catchName;
- switch (tt) {
- case TOK_LB:
- case TOK_LC:
- catchName = destructuringDeclaration(DeclarationKind::CatchParameter,
- yieldHandling, tt);
- if (!catchName)
- return null();
- break;
+ Node catchGuard = null();
- default: {
- if (!TokenKindIsPossibleIdentifierName(tt)) {
- error(JSMSG_CATCH_IDENTIFIER);
- return null();
- }
+ if (omittedBinding) {
+ catchName = null();
+ } else {
+ MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);
- catchName = bindingIdentifier(DeclarationKind::SimpleCatchParameter,
- yieldHandling);
- if (!catchName)
+ if (!tokenStream.getToken(&tt))
return null();
- break;
- }
- }
+ switch (tt) {
+ case TOK_LB:
+ case TOK_LC:
+ catchName = destructuringDeclaration(DeclarationKind::CatchParameter,
+ yieldHandling, tt);
+ if (!catchName)
+ return null();
+ break;
+
+ default: {
+ if (!TokenKindIsPossibleIdentifierName(tt)) {
+ error(JSMSG_CATCH_IDENTIFIER);
+ return null();
+ }
+
+ catchName = bindingIdentifier(DeclarationKind::SimpleCatchParameter,
+ yieldHandling);
+ if (!catchName)
+ return null();
+ break;
+ }
+ }
- Node catchGuard = null();
#if JS_HAS_CATCH_GUARD
- /*
- * We use 'catch (x if x === 5)' (not 'catch (x : x === 5)')
- * to avoid conflicting with the JS2/ECMAv4 type annotation
- * catchguard syntax.
- */
- bool matched;
- if (!tokenStream.matchToken(&matched, TOK_IF))
- return null();
- if (matched) {
- catchGuard = expr(InAllowed, yieldHandling, TripledotProhibited);
- if (!catchGuard)
+ /*
+ * We use 'catch (x if x === 5)' (not 'catch (x : x === 5)')
+ * to avoid conflicting with the JS2/ECMAv4 type annotation
+ * catchguard syntax.
+ */
+ bool matched;
+ if (!tokenStream.matchToken(&matched, TOK_IF))
return null();
- }
+ if (matched) {
+ catchGuard = expr(InAllowed, yieldHandling, TripledotProhibited);
+ if (!catchGuard)
+ return null();
+ }
#endif
- MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH);
+ MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH);
- MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);
+ MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);
+ }
Node catchBody = catchBlockStatement(yieldHandling, scope);
if (!catchBody)