diff --git a/.changeset/clean-planets-rush.md b/.changeset/clean-planets-rush.md new file mode 100644 index 000000000000..d8500d431524 --- /dev/null +++ b/.changeset/clean-planets-rush.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: handle default values in object destructuring within "each" blocks when using characters like "}" and "]" diff --git a/documentation/docs/98-reference/.generated/compile-errors.md b/documentation/docs/98-reference/.generated/compile-errors.md index 3bd162d8d74d..05304d747f43 100644 --- a/documentation/docs/98-reference/.generated/compile-errors.md +++ b/documentation/docs/98-reference/.generated/compile-errors.md @@ -988,6 +988,12 @@ Unexpected end of input '%word%' is a reserved word in JavaScript and cannot be used here ``` +### unterminated_string_constant + +``` +Unterminated string constant +``` + ### void_element_invalid_content ``` diff --git a/packages/svelte/messages/compile-errors/template.md b/packages/svelte/messages/compile-errors/template.md index 9621a6457ba9..599a1d77a57f 100644 --- a/packages/svelte/messages/compile-errors/template.md +++ b/packages/svelte/messages/compile-errors/template.md @@ -410,6 +410,10 @@ See https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-ele > '%word%' is a reserved word in JavaScript and cannot be used here +## unterminated_string_constant + +> Unterminated string constant + ## void_element_invalid_content > Void elements cannot have children or closing tags diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index 901ea1983ea7..4c51a6422e67 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -1537,6 +1537,15 @@ export function unexpected_reserved_word(node, word) { e(node, "unexpected_reserved_word", `'${word}' is a reserved word in JavaScript and cannot be used here`); } +/** + * Unterminated string constant + * @param {null | number | NodeLike} node + * @returns {never} + */ +export function unterminated_string_constant(node) { + e(node, "unterminated_string_constant", "Unterminated string constant"); +} + /** * Void elements cannot have children or closing tags * @param {null | number | NodeLike} node diff --git a/packages/svelte/src/compiler/phases/1-parse/read/context.js b/packages/svelte/src/compiler/phases/1-parse/read/context.js index e408b5024fa3..08a0cc482295 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/context.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/context.js @@ -14,6 +14,8 @@ import { parse_expression_at } from '../acorn.js'; import { regex_not_newline_characters } from '../../patterns.js'; import * as e from '../../../errors.js'; import { locator } from '../../../state.js'; +import read_expression from './expression.js'; +import { is_back_quote, is_quote } from '../utils/quote.js'; /** * @param {Parser} parser @@ -41,33 +43,11 @@ export default function read_pattern(parser) { }; } - if (!is_bracket_open(code)) { - e.expected_pattern(i); - } - - const bracket_stack = [code]; - i += code <= 0xffff ? 1 : 2; - - while (i < parser.template.length) { - const code = full_char_code_at(parser.template, i); - if (is_bracket_open(code)) { - bracket_stack.push(code); - } else if (is_bracket_close(code)) { - const popped = /** @type {number} */ (bracket_stack.pop()); - if (!is_bracket_pair(popped, code)) { - e.expected_token(i, String.fromCharCode(/** @type {number} */ (get_bracket_close(popped)))); - } - if (bracket_stack.length === 0) { - i += code <= 0xffff ? 1 : 2; - break; - } - } - i += code <= 0xffff ? 1 : 2; - } - + i = read_expression_length(parser, start); parser.index = i; const pattern_string = parser.template.slice(start, i); + try { // the length of the `space_with_newline` has to be start - 1 // because we added a `(` in front of the pattern_string, @@ -97,6 +77,95 @@ export default function read_pattern(parser) { } } +/** + * @param {Parser} parser + * @param {number} start + */ +function read_expression_length(parser, start) { + let i = start; + const code = full_char_code_at(parser.template, i); + + if (!is_bracket_open(code)) { + e.expected_pattern(i); + } + + const bracket_stack = [code]; + i += code <= 0xffff ? 1 : 2; + + while (i < parser.template.length) { + let code = full_char_code_at(parser.template, i); + if (is_quote(code)) { + i = read_string_length(parser, i, code); + } else { + if (is_bracket_open(code)) { + bracket_stack.push(code); + } else if (is_bracket_close(code)) { + const popped = /** @type {number} */ (bracket_stack.pop()); + if (!is_bracket_pair(popped, code)) { + e.expected_token( + i, + String.fromCharCode(/** @type {number} */ (get_bracket_close(popped))) + ); + } + if (bracket_stack.length === 0) { + i += code <= 0xffff ? 1 : 2; + break; + } + } + i += code <= 0xffff ? 1 : 2; + } + } + + return i; +} + +/** + * @param {Parser} parser + * @param {number} start + * @param {number} quote + */ +function read_string_length(parser, start, quote) { + let i = start; + i += quote <= 0xffff ? 1 : 2; + + const BACKSLASH = '\\'.charCodeAt(0); + const DOLAR = '$'.charCodeAt(0); + const LEFT_BRACKET = '{'.charCodeAt(0); + + let is_escaped = false; + while (i < parser.template.length) { + const code = full_char_code_at(parser.template, i); + if (!is_escaped && code === quote) { + break; + } + + if (!is_escaped && code === BACKSLASH) { + is_escaped = true; + } else if (is_escaped) { + is_escaped = false; + } + + if ( + i < parser.template.length - 1 && + is_back_quote(quote) && + code === DOLAR && + full_char_code_at(parser.template, i + 1) === LEFT_BRACKET + ) { + i++; + i = read_expression_length(parser, i); + } else { + i += code <= 0xffff ? 1 : 2; + } + } + + const code = full_char_code_at(parser.template, i); + if (code !== quote) { + e.unterminated_string_constant(start); + } + + return i + (code <= 0xffff ? 1 : 2); +} + /** * @param {Parser} parser * @returns {any} diff --git a/packages/svelte/src/compiler/phases/1-parse/utils/quote.js b/packages/svelte/src/compiler/phases/1-parse/utils/quote.js new file mode 100644 index 000000000000..517e7b3a55da --- /dev/null +++ b/packages/svelte/src/compiler/phases/1-parse/utils/quote.js @@ -0,0 +1,13 @@ +const SINGLE_QUOTE = "'".charCodeAt(0); +const DOUBLE_QUOTE = '"'.charCodeAt(0); +const BACK_QUOTE = '`'.charCodeAt(0); + +/** @param {number} code */ +export function is_quote(code) { + return code === SINGLE_QUOTE || code === DOUBLE_QUOTE || code === BACK_QUOTE; +} + +/** @param {number} code */ +export function is_back_quote(code) { + return code === BACK_QUOTE; +} diff --git a/packages/svelte/tests/parser-modern/samples/each-block-object-pattern-special-characters/input.svelte b/packages/svelte/tests/parser-modern/samples/each-block-object-pattern-special-characters/input.svelte new file mode 100644 index 000000000000..bc83f8e57fa8 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/each-block-object-pattern-special-characters/input.svelte @@ -0,0 +1,9 @@ +{#each x as { y = 'z' }}{/each} + +{#each x as { y = '{' }}{/each} + +{#each x as { y = ']' }}{/each} + +{#each x as { y = `${`"`}` }}{/each} + +{#each x as { y = `${`John`}` }}{/each} diff --git a/packages/svelte/tests/parser-modern/samples/each-block-object-pattern-special-characters/output.json b/packages/svelte/tests/parser-modern/samples/each-block-object-pattern-special-characters/output.json new file mode 100644 index 000000000000..b962db322640 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/each-block-object-pattern-special-characters/output.json @@ -0,0 +1,826 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 176, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "EachBlock", + "start": 0, + "end": 31, + "expression": { + "type": "Identifier", + "start": 7, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "name": "x" + }, + "body": { + "type": "Fragment", + "nodes": [] + }, + "context": { + "type": "ObjectPattern", + "start": 12, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 23 + } + }, + "properties": [ + { + "type": "Property", + "start": 14, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 21 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "name": "y" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 14, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 21 + } + }, + "left": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "name": "y" + }, + "right": { + "type": "Literal", + "start": 18, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 21 + } + }, + "value": "z", + "raw": "'z'" + } + } + } + ] + } + }, + { + "type": "Text", + "start": 31, + "end": 33, + "raw": "\n\n", + "data": "\n\n" + }, + { + "type": "EachBlock", + "start": 33, + "end": 64, + "expression": { + "type": "Identifier", + "start": 40, + "end": 41, + "loc": { + "start": { + "line": 3, + "column": 7 + }, + "end": { + "line": 3, + "column": 8 + } + }, + "name": "x" + }, + "body": { + "type": "Fragment", + "nodes": [] + }, + "context": { + "type": "ObjectPattern", + "start": 45, + "end": 56, + "loc": { + "start": { + "line": 3, + "column": 13 + }, + "end": { + "line": 3, + "column": 24 + } + }, + "properties": [ + { + "type": "Property", + "start": 47, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 15 + }, + "end": { + "line": 3, + "column": 22 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 47, + "end": 48, + "loc": { + "start": { + "line": 3, + "column": 15 + }, + "end": { + "line": 3, + "column": 16 + } + }, + "name": "y" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 47, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 15 + }, + "end": { + "line": 3, + "column": 22 + } + }, + "left": { + "type": "Identifier", + "start": 47, + "end": 48, + "loc": { + "start": { + "line": 3, + "column": 15 + }, + "end": { + "line": 3, + "column": 16 + } + }, + "name": "y" + }, + "right": { + "type": "Literal", + "start": 51, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 19 + }, + "end": { + "line": 3, + "column": 22 + } + }, + "value": "{", + "raw": "'{'" + } + } + } + ] + } + }, + { + "type": "Text", + "start": 64, + "end": 66, + "raw": "\n\n", + "data": "\n\n" + }, + { + "type": "EachBlock", + "start": 66, + "end": 97, + "expression": { + "type": "Identifier", + "start": 73, + "end": 74, + "loc": { + "start": { + "line": 5, + "column": 7 + }, + "end": { + "line": 5, + "column": 8 + } + }, + "name": "x" + }, + "body": { + "type": "Fragment", + "nodes": [] + }, + "context": { + "type": "ObjectPattern", + "start": 78, + "end": 89, + "loc": { + "start": { + "line": 5, + "column": 13 + }, + "end": { + "line": 5, + "column": 24 + } + }, + "properties": [ + { + "type": "Property", + "start": 80, + "end": 87, + "loc": { + "start": { + "line": 5, + "column": 15 + }, + "end": { + "line": 5, + "column": 22 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 80, + "end": 81, + "loc": { + "start": { + "line": 5, + "column": 15 + }, + "end": { + "line": 5, + "column": 16 + } + }, + "name": "y" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 80, + "end": 87, + "loc": { + "start": { + "line": 5, + "column": 15 + }, + "end": { + "line": 5, + "column": 22 + } + }, + "left": { + "type": "Identifier", + "start": 80, + "end": 81, + "loc": { + "start": { + "line": 5, + "column": 15 + }, + "end": { + "line": 5, + "column": 16 + } + }, + "name": "y" + }, + "right": { + "type": "Literal", + "start": 84, + "end": 87, + "loc": { + "start": { + "line": 5, + "column": 19 + }, + "end": { + "line": 5, + "column": 22 + } + }, + "value": "]", + "raw": "']'" + } + } + } + ] + } + }, + { + "type": "Text", + "start": 97, + "end": 99, + "raw": "\n\n", + "data": "\n\n" + }, + { + "type": "EachBlock", + "start": 99, + "end": 135, + "expression": { + "type": "Identifier", + "start": 106, + "end": 107, + "loc": { + "start": { + "line": 7, + "column": 7 + }, + "end": { + "line": 7, + "column": 8 + } + }, + "name": "x" + }, + "body": { + "type": "Fragment", + "nodes": [] + }, + "context": { + "type": "ObjectPattern", + "start": 111, + "end": 127, + "loc": { + "start": { + "line": 7, + "column": 13 + }, + "end": { + "line": 7, + "column": 29 + } + }, + "properties": [ + { + "type": "Property", + "start": 113, + "end": 125, + "loc": { + "start": { + "line": 7, + "column": 15 + }, + "end": { + "line": 7, + "column": 27 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 113, + "end": 114, + "loc": { + "start": { + "line": 7, + "column": 15 + }, + "end": { + "line": 7, + "column": 16 + } + }, + "name": "y" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 113, + "end": 125, + "loc": { + "start": { + "line": 7, + "column": 15 + }, + "end": { + "line": 7, + "column": 27 + } + }, + "left": { + "type": "Identifier", + "start": 113, + "end": 114, + "loc": { + "start": { + "line": 7, + "column": 15 + }, + "end": { + "line": 7, + "column": 16 + } + }, + "name": "y" + }, + "right": { + "type": "TemplateLiteral", + "start": 117, + "end": 125, + "loc": { + "start": { + "line": 7, + "column": 19 + }, + "end": { + "line": 7, + "column": 27 + } + }, + "expressions": [ + { + "type": "TemplateLiteral", + "start": 120, + "end": 123, + "loc": { + "start": { + "line": 7, + "column": 22 + }, + "end": { + "line": 7, + "column": 25 + } + }, + "expressions": [], + "quasis": [ + { + "type": "TemplateElement", + "start": 121, + "end": 122, + "loc": { + "start": { + "line": 7, + "column": 23 + }, + "end": { + "line": 7, + "column": 24 + } + }, + "value": { + "raw": "\"", + "cooked": "\"" + }, + "tail": true + } + ] + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 118, + "end": 118, + "loc": { + "start": { + "line": 7, + "column": 20 + }, + "end": { + "line": 7, + "column": 20 + } + }, + "value": { + "raw": "", + "cooked": "" + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 124, + "end": 124, + "loc": { + "start": { + "line": 7, + "column": 26 + }, + "end": { + "line": 7, + "column": 26 + } + }, + "value": { + "raw": "", + "cooked": "" + }, + "tail": true + } + ] + } + } + } + ] + } + }, + { + "type": "Text", + "start": 135, + "end": 137, + "raw": "\n\n", + "data": "\n\n" + }, + { + "type": "EachBlock", + "start": 137, + "end": 176, + "expression": { + "type": "Identifier", + "start": 144, + "end": 145, + "loc": { + "start": { + "line": 9, + "column": 7 + }, + "end": { + "line": 9, + "column": 8 + } + }, + "name": "x" + }, + "body": { + "type": "Fragment", + "nodes": [] + }, + "context": { + "type": "ObjectPattern", + "start": 149, + "end": 168, + "loc": { + "start": { + "line": 9, + "column": 13 + }, + "end": { + "line": 9, + "column": 32 + } + }, + "properties": [ + { + "type": "Property", + "start": 151, + "end": 166, + "loc": { + "start": { + "line": 9, + "column": 15 + }, + "end": { + "line": 9, + "column": 30 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 151, + "end": 152, + "loc": { + "start": { + "line": 9, + "column": 15 + }, + "end": { + "line": 9, + "column": 16 + } + }, + "name": "y" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 151, + "end": 166, + "loc": { + "start": { + "line": 9, + "column": 15 + }, + "end": { + "line": 9, + "column": 30 + } + }, + "left": { + "type": "Identifier", + "start": 151, + "end": 152, + "loc": { + "start": { + "line": 9, + "column": 15 + }, + "end": { + "line": 9, + "column": 16 + } + }, + "name": "y" + }, + "right": { + "type": "TemplateLiteral", + "start": 155, + "end": 166, + "loc": { + "start": { + "line": 9, + "column": 19 + }, + "end": { + "line": 9, + "column": 30 + } + }, + "expressions": [ + { + "type": "TemplateLiteral", + "start": 158, + "end": 164, + "loc": { + "start": { + "line": 9, + "column": 22 + }, + "end": { + "line": 9, + "column": 28 + } + }, + "expressions": [], + "quasis": [ + { + "type": "TemplateElement", + "start": 159, + "end": 163, + "loc": { + "start": { + "line": 9, + "column": 23 + }, + "end": { + "line": 9, + "column": 27 + } + }, + "value": { + "raw": "John", + "cooked": "John" + }, + "tail": true + } + ] + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 156, + "end": 156, + "loc": { + "start": { + "line": 9, + "column": 20 + }, + "end": { + "line": 9, + "column": 20 + } + }, + "value": { + "raw": "", + "cooked": "" + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 165, + "end": 165, + "loc": { + "start": { + "line": 9, + "column": 29 + }, + "end": { + "line": 9, + "column": 29 + } + }, + "value": { + "raw": "", + "cooked": "" + }, + "tail": true + } + ] + } + } + } + ] + } + } + ] + }, + "options": null +} diff --git a/packages/svelte/tests/parser-modern/samples/each-block-object-pattern/input.svelte b/packages/svelte/tests/parser-modern/samples/each-block-object-pattern/input.svelte index 8ffe8a7287a5..c3bfdb46a6f3 100644 --- a/packages/svelte/tests/parser-modern/samples/each-block-object-pattern/input.svelte +++ b/packages/svelte/tests/parser-modern/samples/each-block-object-pattern/input.svelte @@ -1,3 +1,11 @@ {#each people as { name, cool = true }}
{name} is {cool ? 'cool' : 'not cool'}
{/each} + +{#each people as { name = `Jane ${"Doe"}`, cool = true }} +{name} is {cool ? 'cool' : 'not cool'}
+{/each} + +{#each people as { name = (() => { return `Jane ${"Doe"}`; })(), cool = true }} +{name} is {cool ? 'cool' : 'not cool'}
+{/each} diff --git a/packages/svelte/tests/parser-modern/samples/each-block-object-pattern/output.json b/packages/svelte/tests/parser-modern/samples/each-block-object-pattern/output.json index 8fc3feb91664..144016417b84 100644 --- a/packages/svelte/tests/parser-modern/samples/each-block-object-pattern/output.json +++ b/packages/svelte/tests/parser-modern/samples/each-block-object-pattern/output.json @@ -2,7 +2,7 @@ "css": null, "js": [], "start": 0, - "end": 94, + "end": 344, "type": "Root", "fragment": { "type": "Fragment", @@ -307,6 +307,873 @@ } ] } + }, + { + "type": "Text", + "start": 94, + "end": 96, + "raw": "\n\n", + "data": "\n\n" + }, + { + "type": "EachBlock", + "start": 96, + "end": 208, + "expression": { + "type": "Identifier", + "start": 103, + "end": 109, + "loc": { + "start": { + "line": 5, + "column": 7 + }, + "end": { + "line": 5, + "column": 13 + } + }, + "name": "people" + }, + "body": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 153, + "end": 155, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "RegularElement", + "start": 155, + "end": 200, + "name": "p", + "attributes": [], + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "ExpressionTag", + "start": 158, + "end": 164, + "expression": { + "type": "Identifier", + "start": 159, + "end": 163, + "loc": { + "start": { + "line": 6, + "column": 5 + }, + "end": { + "line": 6, + "column": 9 + } + }, + "name": "name" + } + }, + { + "type": "Text", + "start": 164, + "end": 168, + "raw": " is ", + "data": " is " + }, + { + "type": "ExpressionTag", + "start": 168, + "end": 196, + "expression": { + "type": "ConditionalExpression", + "start": 169, + "end": 195, + "loc": { + "start": { + "line": 6, + "column": 15 + }, + "end": { + "line": 6, + "column": 41 + } + }, + "test": { + "type": "Identifier", + "start": 169, + "end": 173, + "loc": { + "start": { + "line": 6, + "column": 15 + }, + "end": { + "line": 6, + "column": 19 + } + }, + "name": "cool" + }, + "consequent": { + "type": "Literal", + "start": 176, + "end": 182, + "loc": { + "start": { + "line": 6, + "column": 22 + }, + "end": { + "line": 6, + "column": 28 + } + }, + "value": "cool", + "raw": "'cool'" + }, + "alternate": { + "type": "Literal", + "start": 185, + "end": 195, + "loc": { + "start": { + "line": 6, + "column": 31 + }, + "end": { + "line": 6, + "column": 41 + } + }, + "value": "not cool", + "raw": "'not cool'" + } + } + } + ] + } + }, + { + "type": "Text", + "start": 200, + "end": 201, + "raw": "\n", + "data": "\n" + } + ] + }, + "context": { + "type": "ObjectPattern", + "start": 113, + "end": 152, + "loc": { + "start": { + "line": 5, + "column": 18 + }, + "end": { + "line": 5, + "column": 57 + } + }, + "properties": [ + { + "type": "Property", + "start": 115, + "end": 137, + "loc": { + "start": { + "line": 5, + "column": 20 + }, + "end": { + "line": 5, + "column": 42 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 115, + "end": 119, + "loc": { + "start": { + "line": 5, + "column": 20 + }, + "end": { + "line": 5, + "column": 24 + } + }, + "name": "name" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 115, + "end": 137, + "loc": { + "start": { + "line": 5, + "column": 20 + }, + "end": { + "line": 5, + "column": 42 + } + }, + "left": { + "type": "Identifier", + "start": 115, + "end": 119, + "loc": { + "start": { + "line": 5, + "column": 20 + }, + "end": { + "line": 5, + "column": 24 + } + }, + "name": "name" + }, + "right": { + "type": "TemplateLiteral", + "start": 122, + "end": 137, + "loc": { + "start": { + "line": 5, + "column": 27 + }, + "end": { + "line": 5, + "column": 42 + } + }, + "expressions": [ + { + "type": "Literal", + "start": 130, + "end": 135, + "loc": { + "start": { + "line": 5, + "column": 35 + }, + "end": { + "line": 5, + "column": 40 + } + }, + "value": "Doe", + "raw": "\"Doe\"" + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 123, + "end": 128, + "loc": { + "start": { + "line": 5, + "column": 28 + }, + "end": { + "line": 5, + "column": 33 + } + }, + "value": { + "raw": "Jane ", + "cooked": "Jane " + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 136, + "end": 136, + "loc": { + "start": { + "line": 5, + "column": 41 + }, + "end": { + "line": 5, + "column": 41 + } + }, + "value": { + "raw": "", + "cooked": "" + }, + "tail": true + } + ] + } + } + }, + { + "type": "Property", + "start": 139, + "end": 150, + "loc": { + "start": { + "line": 5, + "column": 44 + }, + "end": { + "line": 5, + "column": 55 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 139, + "end": 143, + "loc": { + "start": { + "line": 5, + "column": 44 + }, + "end": { + "line": 5, + "column": 48 + } + }, + "name": "cool" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 139, + "end": 150, + "loc": { + "start": { + "line": 5, + "column": 44 + }, + "end": { + "line": 5, + "column": 55 + } + }, + "left": { + "type": "Identifier", + "start": 139, + "end": 143, + "loc": { + "start": { + "line": 5, + "column": 44 + }, + "end": { + "line": 5, + "column": 48 + } + }, + "name": "cool" + }, + "right": { + "type": "Literal", + "start": 146, + "end": 150, + "loc": { + "start": { + "line": 5, + "column": 51 + }, + "end": { + "line": 5, + "column": 55 + } + }, + "value": true, + "raw": "true" + } + } + } + ] + } + }, + { + "type": "Text", + "start": 208, + "end": 210, + "raw": "\n\n", + "data": "\n\n" + }, + { + "type": "EachBlock", + "start": 210, + "end": 344, + "expression": { + "type": "Identifier", + "start": 217, + "end": 223, + "loc": { + "start": { + "line": 9, + "column": 7 + }, + "end": { + "line": 9, + "column": 13 + } + }, + "name": "people" + }, + "body": { + "type": "Fragment", + "nodes": [ + { + "type": "Text", + "start": 289, + "end": 291, + "raw": "\n\t", + "data": "\n\t" + }, + { + "type": "RegularElement", + "start": 291, + "end": 336, + "name": "p", + "attributes": [], + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "ExpressionTag", + "start": 294, + "end": 300, + "expression": { + "type": "Identifier", + "start": 295, + "end": 299, + "loc": { + "start": { + "line": 10, + "column": 5 + }, + "end": { + "line": 10, + "column": 9 + } + }, + "name": "name" + } + }, + { + "type": "Text", + "start": 300, + "end": 304, + "raw": " is ", + "data": " is " + }, + { + "type": "ExpressionTag", + "start": 304, + "end": 332, + "expression": { + "type": "ConditionalExpression", + "start": 305, + "end": 331, + "loc": { + "start": { + "line": 10, + "column": 15 + }, + "end": { + "line": 10, + "column": 41 + } + }, + "test": { + "type": "Identifier", + "start": 305, + "end": 309, + "loc": { + "start": { + "line": 10, + "column": 15 + }, + "end": { + "line": 10, + "column": 19 + } + }, + "name": "cool" + }, + "consequent": { + "type": "Literal", + "start": 312, + "end": 318, + "loc": { + "start": { + "line": 10, + "column": 22 + }, + "end": { + "line": 10, + "column": 28 + } + }, + "value": "cool", + "raw": "'cool'" + }, + "alternate": { + "type": "Literal", + "start": 321, + "end": 331, + "loc": { + "start": { + "line": 10, + "column": 31 + }, + "end": { + "line": 10, + "column": 41 + } + }, + "value": "not cool", + "raw": "'not cool'" + } + } + } + ] + } + }, + { + "type": "Text", + "start": 336, + "end": 337, + "raw": "\n", + "data": "\n" + } + ] + }, + "context": { + "type": "ObjectPattern", + "start": 227, + "end": 288, + "loc": { + "start": { + "line": 9, + "column": 18 + }, + "end": { + "line": 9, + "column": 79 + } + }, + "properties": [ + { + "type": "Property", + "start": 229, + "end": 273, + "loc": { + "start": { + "line": 9, + "column": 20 + }, + "end": { + "line": 9, + "column": 64 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 229, + "end": 233, + "loc": { + "start": { + "line": 9, + "column": 20 + }, + "end": { + "line": 9, + "column": 24 + } + }, + "name": "name" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 229, + "end": 273, + "loc": { + "start": { + "line": 9, + "column": 20 + }, + "end": { + "line": 9, + "column": 64 + } + }, + "left": { + "type": "Identifier", + "start": 229, + "end": 233, + "loc": { + "start": { + "line": 9, + "column": 20 + }, + "end": { + "line": 9, + "column": 24 + } + }, + "name": "name" + }, + "right": { + "type": "CallExpression", + "start": 236, + "end": 273, + "loc": { + "start": { + "line": 9, + "column": 27 + }, + "end": { + "line": 9, + "column": 64 + } + }, + "callee": { + "type": "ArrowFunctionExpression", + "start": 237, + "end": 270, + "loc": { + "start": { + "line": 9, + "column": 28 + }, + "end": { + "line": 9, + "column": 61 + } + }, + "id": null, + "expression": false, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 243, + "end": 270, + "loc": { + "start": { + "line": 9, + "column": 34 + }, + "end": { + "line": 9, + "column": 61 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 245, + "end": 268, + "loc": { + "start": { + "line": 9, + "column": 36 + }, + "end": { + "line": 9, + "column": 59 + } + }, + "argument": { + "type": "TemplateLiteral", + "start": 252, + "end": 267, + "loc": { + "start": { + "line": 9, + "column": 43 + }, + "end": { + "line": 9, + "column": 58 + } + }, + "expressions": [ + { + "type": "Literal", + "start": 260, + "end": 265, + "loc": { + "start": { + "line": 9, + "column": 51 + }, + "end": { + "line": 9, + "column": 56 + } + }, + "value": "Doe", + "raw": "\"Doe\"" + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 253, + "end": 258, + "loc": { + "start": { + "line": 9, + "column": 44 + }, + "end": { + "line": 9, + "column": 49 + } + }, + "value": { + "raw": "Jane ", + "cooked": "Jane " + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 266, + "end": 266, + "loc": { + "start": { + "line": 9, + "column": 57 + }, + "end": { + "line": 9, + "column": 57 + } + }, + "value": { + "raw": "", + "cooked": "" + }, + "tail": true + } + ] + } + } + ] + } + }, + "arguments": [], + "optional": false + } + } + }, + { + "type": "Property", + "start": 275, + "end": 286, + "loc": { + "start": { + "line": 9, + "column": 66 + }, + "end": { + "line": 9, + "column": 77 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 275, + "end": 279, + "loc": { + "start": { + "line": 9, + "column": 66 + }, + "end": { + "line": 9, + "column": 70 + } + }, + "name": "cool" + }, + "kind": "init", + "value": { + "type": "AssignmentPattern", + "start": 275, + "end": 286, + "loc": { + "start": { + "line": 9, + "column": 66 + }, + "end": { + "line": 9, + "column": 77 + } + }, + "left": { + "type": "Identifier", + "start": 275, + "end": 279, + "loc": { + "start": { + "line": 9, + "column": 66 + }, + "end": { + "line": 9, + "column": 70 + } + }, + "name": "cool" + }, + "right": { + "type": "Literal", + "start": 282, + "end": 286, + "loc": { + "start": { + "line": 9, + "column": 73 + }, + "end": { + "line": 9, + "column": 77 + } + }, + "value": true, + "raw": "true" + } + } + } + ] + } } ] },