From 69dc0b1e23ce6de43a3762a27017f7b5a1ca6aad Mon Sep 17 00:00:00 2001 From: Andrew Peters Date: Mon, 25 Mar 2024 16:09:40 +0200 Subject: [PATCH] fix: support member exp after template and tagged template fixes: #259 --- packages/template/src/index.js | 17 ++++++-- packages/template/test/index.test.js | 65 ++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/packages/template/src/index.js b/packages/template/src/index.js index d054a04..756978e 100644 --- a/packages/template/src/index.js +++ b/packages/template/src/index.js @@ -8,7 +8,7 @@ export default { name: 'jsepTemplateLiteral', init(jsep) { - function gobbleTemplateLiteral(env) { + function gobbleTemplateLiteral(env, gobbleMember = true) { if (this.code === BTICK_CODE) { const node = { type: TEMPLATE_LITERAL, @@ -37,7 +37,13 @@ export default { pushQuasi(); env.node = node; - return node; + + if (gobbleMember) { + // allow . [] and () after template: `foo`.length + env.node = this.gobbleTokenProperty(env.node); + } + + return env.node; } else if (ch === '$' && this.expr.charAt(this.index + 1) === '{') { this.index += 2; @@ -81,8 +87,13 @@ export default { env.node = { type: TAGGED_TEMPLATE_EXPRESSION, tag: env.node, - quasi: gobbleTemplateLiteral.bind(this)(env), + quasi: gobbleTemplateLiteral.bind(this)(env, false), }; + + // allow . [] and () after tagged template: bar`foo`.length + env.node = this.gobbleTokenProperty(env.node); + + return env.node; } }); } diff --git a/packages/template/test/index.test.js b/packages/template/test/index.test.js index b37fc67..847ab4d 100644 --- a/packages/template/test/index.test.js +++ b/packages/template/test/index.test.js @@ -39,6 +39,71 @@ const { test } = QUnit; }, assert); }); + test('should parse template literal member access', (assert) => { + testParser('`foo`.bar', { + type: 'MemberExpression', + computed: false, + object: { + type: 'TemplateLiteral', + quasis: [ + { + type: 'TemplateElement', + value: { + raw: 'foo', + cooked: 'foo', + }, + tail: true, + } + ], + expressions: [] + }, + property: { + type: 'Identifier', + name: 'bar' + } + }, assert); + }); + + test('should parse tagged template literal member access', (assert) => { + testParser('String.raw`foo`.bar', { + type: "MemberExpression", + computed: false, + object: { + type: "TaggedTemplateExpression", + tag: { + type: "MemberExpression", + computed: false, + object: { + type: "Identifier", + name: "String" + }, + property: { + type: "Identifier", + name: "raw" + } + }, + quasi: { + type: "TemplateLiteral", + quasis: [ + { + type: "TemplateElement", + value: { + raw: "foo", + cooked: "foo" + }, + tail: true + } + ], + expressions: [] + } + }, + property: { + type: "Identifier", + name: "bar" + } + }, assert); + }); + test('should parse tagged, nested template literal expression', (assert) => { testParser('abc`token ${`nested ${`deeply` + "str"} blah`}`', { type: 'TaggedTemplateExpression',