From 07f644c39223e016aceedd2cd71b5941579b5659 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth <456802+GeoffreyBooth@users.noreply.github.com> Date: Tue, 2 Jun 2020 21:00:40 -0700 Subject: [PATCH] Fix call MetaProperty (#5324) --- lib/coffeescript/grammar.js | 9 +++++---- lib/coffeescript/rewriter.js | 2 +- src/grammar.coffee | 9 +++++---- src/rewriter.coffee | 1 + test/classes.coffee | 4 ++++ test/modules.coffee | 14 ++++++++++++++ 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/coffeescript/grammar.js b/lib/coffeescript/grammar.js index e1e0528c..f35e1639 100644 --- a/lib/coffeescript/grammar.js +++ b/lib/coffeescript/grammar.js @@ -126,7 +126,7 @@ }), o('Body TERMINATOR') ], - // Block and statements, which make up a line in a body. YieldReturn is a + // Block and statements, which make up a line in a body. FuncDirective is a // statement, but not included in Statement because that results in an ambiguous // grammar. Line: [o('Expression'), o('ExpressionLine'), o('Statement'), o('FuncDirective')], @@ -525,7 +525,7 @@ }); }) ], - // The **Code** node is the function literal. It's defined by an indented block + // The **Code** node is the function literal. It’s defined by an indented block // of **Block** preceded by a function arrow, with an optional parameter list. Code: [ o('PARAM_START ParamList PARAM_END FuncGlyph Block', @@ -722,7 +722,8 @@ LOC(1)(new Literal($1))); }) ], - // A "meta-property" access e.g. `new.target` + // A “meta-property” access e.g. `new.target` or `import.meta`, where + // something that looks like a property is referenced on a keyword. MetaProperty: [ o('NEW_TARGET . Property', function() { @@ -1689,7 +1690,7 @@ }) ], // The source of a comprehension is an array or object with an optional guard - // clause. If it's an array comprehension, you can also choose to step through + // clause. If it’s an array comprehension, you can also choose to step through // in fixed-size increments. ForSource: [ o('FORIN Expression', diff --git a/lib/coffeescript/rewriter.js b/lib/coffeescript/rewriter.js index 3d819d88..a2816f0b 100644 --- a/lib/coffeescript/rewriter.js +++ b/lib/coffeescript/rewriter.js @@ -1100,7 +1100,7 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'PROPERTY', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; // If preceded by an `IMPLICIT_FUNC`, indicates a function invocation. - IMPLICIT_CALL = ['IDENTIFIER', 'JSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'UNDEFINED', 'NULL', 'BOOL', 'UNARY', 'DO', 'DO_IIFE', 'YIELD', 'AWAIT', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++']; + IMPLICIT_CALL = ['IDENTIFIER', 'JSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'DYNAMIC_IMPORT', 'IMPORT_META', 'NEW_TARGET', 'UNDEFINED', 'NULL', 'BOOL', 'UNARY', 'DO', 'DO_IIFE', 'YIELD', 'AWAIT', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++']; IMPLICIT_UNSPACED_CALL = ['+', '-']; diff --git a/src/grammar.coffee b/src/grammar.coffee index ac4747f6..354475c6 100644 --- a/src/grammar.coffee +++ b/src/grammar.coffee @@ -113,7 +113,7 @@ grammar = o 'Body TERMINATOR' ] - # Block and statements, which make up a line in a body. YieldReturn is a + # Block and statements, which make up a line in a body. FuncDirective is a # statement, but not included in Statement because that results in an ambiguous # grammar. Line: [ @@ -325,7 +325,7 @@ grammar = o 'AWAIT RETURN', -> new AwaitReturn null, returnKeyword: LOC(2)(new Literal $2) ] - # The **Code** node is the function literal. It's defined by an indented block + # The **Code** node is the function literal. It’s defined by an indented block # of **Block** preceded by a function arrow, with an optional parameter list. Code: [ o 'PARAM_START ParamList PARAM_END FuncGlyph Block', -> new Code $2, $5, $4, LOC(1)(new Literal $1) @@ -421,7 +421,8 @@ grammar = o 'SUPER INDEX_START INDENT Expression OUTDENT INDEX_END', -> new Super LOC(4)(new Index $4), LOC(1)(new Literal $1) ] - # A "meta-property" access e.g. `new.target` + # A “meta-property” access e.g. `new.target` or `import.meta`, where + # something that looks like a property is referenced on a keyword. MetaProperty: [ o 'NEW_TARGET . Property', -> new MetaProperty LOC(1)(new IdentifierLiteral $1), LOC(3)(new Access $3) o 'IMPORT_META . Property', -> new MetaProperty LOC(1)(new IdentifierLiteral $1), LOC(3)(new Access $3) @@ -774,7 +775,7 @@ grammar = ] # The source of a comprehension is an array or object with an optional guard - # clause. If it's an array comprehension, you can also choose to step through + # clause. If it’s an array comprehension, you can also choose to step through # in fixed-size increments. ForSource: [ o 'FORIN Expression', -> source: $2 diff --git a/src/rewriter.coffee b/src/rewriter.coffee index 152d2669..fea70d01 100644 --- a/src/rewriter.coffee +++ b/src/rewriter.coffee @@ -814,6 +814,7 @@ IMPLICIT_CALL = [ 'IDENTIFIER', 'JSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN' 'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS' 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS' + 'DYNAMIC_IMPORT', 'IMPORT_META', 'NEW_TARGET' 'UNDEFINED', 'NULL', 'BOOL' 'UNARY', 'DO', 'DO_IIFE', 'YIELD', 'AWAIT', 'UNARY_MATH', 'SUPER', 'THROW' '@', '->', '=>', '[', '(', '{', '--', '++' diff --git a/test/classes.coffee b/test/classes.coffee index 8b9e2d3b..fa653e4e 100644 --- a/test/classes.coffee +++ b/test/classes.coffee @@ -1917,6 +1917,10 @@ test "#4609: Support new.target", -> new Foo() eq newTarget, yes +test "#5323: new.target can be the argument of a function", -> + fn = (arg) -> arg + fn new.target + test "#5085: Bug: @ reference to class not maintained in do block", -> thisFoo = 'initial foo' thisBar = 'initial bar' diff --git a/test/modules.coffee b/test/modules.coffee index 5b4fbe68..be1ad291 100644 --- a/test/modules.coffee +++ b/test/modules.coffee @@ -942,6 +942,13 @@ test "#4834: dynamic import", -> }; """ + eqJS """ + console.log import('foo') + """, + """ + console.log(import('foo')); + """ + test "#5317: Support import.meta", -> eqJS """ foo = import.meta @@ -991,3 +998,10 @@ test "#5317: Support import.meta", -> foo = import.meta.bar; """ + + eqJS """ + console.log import.meta.url + """, + """ + console.log(import.meta.url); + """