loose mode asks the parser to recover: the bracket scanner, the synthetic declaration and the paren lookahead go, a placeholder spans what could not be read

goodbye-acorn
Nic 2 days ago
parent 76c64bd0ce
commit 3ee5cc64af

@ -97,6 +97,7 @@ export class Parser {
comments: true, comments: true,
locations: true, locations: true,
scopes: true, scopes: true,
errorRecovery: loose,
// a script may export what the component declares elsewhere // a script may export what the component declares elsewhere
allowUndeclaredExports: true allowUndeclaredExports: true
}); });

@ -3,7 +3,6 @@
/** @import { Parser } from './index.js' */ /** @import { Parser } from './index.js' */
import * as teasel from '@teasel/parser'; import * as teasel from '@teasel/parser';
import * as e from '../../errors.js'; import * as e from '../../errors.js';
import { find_matching_bracket } from './utils/bracket.js';
import { keep_tables } from '../../utils/ast.js'; import { keep_tables } from '../../utils/ast.js';
/** /**
@ -67,6 +66,7 @@ export function parse_script(parser, start, end) {
/** @type {teasel.Comment[]} */ (ast.comments) /** @type {teasel.Comment[]} */ (ast.comments)
); );
delete ast.comments; delete ast.comments;
delete ast.errors;
keep_tables(ast, tables(ast)); keep_tables(ast, tables(ast));
unsupported(ast.typescript); unsupported(ast.typescript);
delete ast.typescript; delete ast.typescript;
@ -105,29 +105,19 @@ function read(parser, run) {
/** /**
* @param {Parser} parser * @param {Parser} parser
* @param {string[]} [stop_at] the template's own tokens after the expression, which end it * @param {string[]} [stop_at] the template's own tokens after the expression, which end it
* @param {string} [opening_token] the bracket the expression sits in, for loose mode
* @returns {Expression} * @returns {Expression}
*/ */
export function read_expression(parser, stop_at, opening_token = '{') { export function read_expression(parser, stop_at) {
const start = parser.index; const start = parser.index;
try {
const answer = read(parser, (js) => js.parseExpressionAt(start, stop_at)); const answer = read(parser, (js) => js.parseExpressionAt(start, stop_at));
keep_tables(answer.node, tables(answer)); keep_tables(answer.node, tables(answer));
return answer.node; const node = answer.node;
} catch (err) { // the language tools copy an expression's text by its node's range, so the placeholder standing for one that could not be read spans what was read
if (parser.loose) { if (node.type === 'Identifier' && node.name === '' && node.start === node.end) {
// Find the next } and treat it as the end of the expression node.start = start;
const end = find_matching_bracket(parser.template, start, opening_token); node.end = answer.end;
if (end !== undefined) {
parser.index = end;
// We don't know what the expression is and signal this by returning an empty identifier
return { type: 'Identifier', start, end, name: '' };
}
}
throw err;
} }
return node;
} }
/** /**

@ -4,7 +4,7 @@
import * as e from '../../../errors.js'; import * as e from '../../../errors.js';
import { create_fragment, ExpressionMetadata } from '../../nodes.js'; import { create_fragment, ExpressionMetadata } from '../../nodes.js';
import { read_expression, read_params, read_pattern, read_statement } from '../js.js'; import { read_expression, read_params, read_pattern, read_statement } from '../js.js';
import { find_matching_bracket, match_bracket } from '../utils/bracket.js'; import { match_bracket } from '../utils/bracket.js';
const regex_whitespace_with_closing_curly_brace = /\s*}/y; const regex_whitespace_with_closing_curly_brace = /\s*}/y;
const regex_supported_declaration = /(?:let|const)\b/y; const regex_supported_declaration = /(?:let|const)\b/y;
@ -84,40 +84,7 @@ function read_declaration(parser) {
const initial_comment_count = parser.root.comments.length; const initial_comment_count = parser.root.comments.length;
/** @type {import('estree').Statement | import('estree').VariableDeclaration} */ const declaration = read_statement(parser);
let declaration;
try {
declaration = read_statement(parser);
} catch (error) {
if (!parser.loose) throw error;
const end = find_matching_bracket(parser.template, start, '{');
if (end === undefined) throw error;
parser.index = end;
const kind = parser.template.startsWith('const', start) ? 'const' : 'let';
declaration = {
type: 'VariableDeclaration',
kind,
declarations: [
{
type: 'VariableDeclarator',
id: {
type: 'Identifier',
name: '',
start: parser.index,
end: parser.index
},
init: null,
start: parser.index,
end: parser.index
}
],
start,
end
};
}
if (declaration.type !== 'VariableDeclaration') { if (declaration.type !== 'VariableDeclaration') {
if (declaration.type === 'ExpressionStatement') { if (declaration.type === 'ExpressionStatement') {
@ -348,10 +315,6 @@ function open(parser) {
let parameters = []; let parameters = [];
if (parser.match('(')) { if (parser.match('(')) {
if (find_matching_bracket(parser.template, parser.index + 1, '(') === undefined) {
e.expected_token(parser.template.length, ')');
}
parameters = read_params(parser); parameters = read_params(parser);
} else if (!parser.loose) { } else if (!parser.loose) {
e.expected_token(parser.index, '('); e.expected_token(parser.index, '(');

@ -1,150 +1,6 @@
/** @import { Parser } from '../index.js' */ /** @import { Parser } from '../index.js' */
import * as e from '../../../errors.js'; import * as e from '../../../errors.js';
/**
* @param {number} num
* @returns {number} Infinity if {@link num} is negative, else {@link num}.
*/
function infinity_if_negative(num) {
if (num < 0) {
return Infinity;
}
return num;
}
/**
* @param {string} string The string to search.
* @param {number} search_start_index The index to start searching at.
* @param {"'" | '"' | '`'} string_start_char The character that started this string.
* @returns {number} The index of the end of this string expression, or `Infinity` if not found.
*/
function find_string_end(string, search_start_index, string_start_char) {
let string_to_search;
if (string_start_char === '`') {
string_to_search = string;
} else {
// we could slice at the search start index, but this way the index remains valid
string_to_search = string.slice(
0,
infinity_if_negative(string.indexOf('\n', search_start_index))
);
}
return find_unescaped_char(string_to_search, search_start_index, string_start_char);
}
/**
* @param {string} string The string to search.
* @param {number} search_start_index The index to start searching at.
* @returns {number} The index of the end of this regex expression, or `Infinity` if not found.
*/
function find_regex_end(string, search_start_index) {
const slash = find_unescaped_char(string, search_start_index, '/');
const eol = find_unescaped_char(string, search_start_index, '\n');
return slash < eol ? slash : Infinity;
}
/**
*
* @param {string} string The string to search.
* @param {number} search_start_index The index to begin the search at.
* @param {string} char The character to search for.
* @returns {number} The index of the first unescaped instance of {@link char}, or `Infinity` if not found.
*/
function find_unescaped_char(string, search_start_index, char) {
let i = search_start_index;
while (true) {
const found_index = string.indexOf(char, i);
if (found_index === -1) {
return Infinity;
}
if (count_leading_backslashes(string, found_index - 1) % 2 === 0) {
return found_index;
}
i = found_index + 1;
}
}
/**
* Count consecutive leading backslashes before {@link search_start_index}.
*
* @example
* ```js
* count_leading_backslashes('\\\\\\foo', 2); // 3 (the backslashes have to be escaped in the string literal, there are three in reality)
* ```
*
* @param {string} string The string to search.
* @param {number} search_start_index The index to begin the search at.
*/
function count_leading_backslashes(string, search_start_index) {
let i = search_start_index;
let count = 0;
while (string[i] === '\\') {
count++;
i--;
}
return count;
}
/**
* Finds the corresponding closing bracket, ignoring brackets found inside comments, strings, or regex expressions.
* @param {string} template The string to search.
* @param {number} index The index to begin the search at.
* @param {string} open The opening bracket (ex: `'{'` will search for `'}'`).
* @returns {number | undefined} The index of the closing bracket, or undefined if not found.
*/
export function find_matching_bracket(template, index, open) {
const close = default_brackets[open];
let brackets = 1;
let i = index;
while (brackets > 0 && i < template.length) {
const char = template[i];
switch (char) {
case "'":
case '"':
case '`':
i = find_string_end(template, i + 1, char) + 1;
continue;
case '/': {
const next_char = template[i + 1];
if (!next_char) {
// `/` is the last character; advance past it so we don't loop forever
i++;
continue;
}
if (next_char === '/') {
i = infinity_if_negative(template.indexOf('\n', i + 1)) + '\n'.length;
continue;
}
if (next_char === '*') {
i = infinity_if_negative(template.indexOf('*/', i + 1)) + '*/'.length;
continue;
}
const end = find_regex_end(template, i + 1) + '/'.length;
if (end === Infinity) {
i++;
} else {
i = end;
}
continue;
}
default: {
const char = template[i];
if (char === open) {
brackets++;
} else if (char === close) {
brackets--;
}
if (brackets === 0) {
return i;
}
i++;
}
}
}
return undefined;
}
/** @type {Record<string, string>} */ /** @type {Record<string, string>} */
const default_brackets = { const default_brackets = {
'{': '}', '{': '}',

@ -2,8 +2,8 @@ import { test } from '../../test';
export default test({ export default test({
error: { error: {
code: 'expected_token', code: 'js_parse_error',
message: 'Expected token )', message: 'Unexpected token',
position: [31, 31] position: [21, 21]
} }
}); });

@ -12,6 +12,16 @@
"type": "Identifier", "type": "Identifier",
"start": 5, "start": 5,
"end": 5, "end": 5,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 5
}
},
"name": "" "name": ""
}, },
"children": [], "children": [],
@ -28,6 +38,16 @@
"type": "Identifier", "type": "Identifier",
"start": 17, "start": 17,
"end": 17, "end": 17,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 10
}
},
"name": "" "name": ""
}, },
"children": [], "children": [],
@ -59,6 +79,16 @@
"type": "Identifier", "type": "Identifier",
"start": 42, "start": 42,
"end": 42, "end": 42,
"loc": {
"start": {
"line": 6,
"column": 7
},
"end": {
"line": 6,
"column": 7
}
},
"name": "" "name": ""
} }
}, },

@ -95,6 +95,16 @@
"type": "Identifier", "type": "Identifier",
"start": 25, "start": 25,
"end": 25, "end": 25,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 10
}
},
"name": "" "name": ""
} }
} }
@ -139,10 +149,53 @@
"start": 44, "start": 44,
"end": 48, "end": 48,
"expression": { "expression": {
"type": "MemberExpression",
"start": 45,
"end": 47,
"loc": {
"start": {
"line": 4,
"column": 10
},
"end": {
"line": 4,
"column": 12
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 45, "start": 45,
"end": 46,
"loc": {
"start": {
"line": 4,
"column": 10
},
"end": {
"line": 4,
"column": 11
}
},
"name": "a"
},
"property": {
"type": "Identifier",
"start": 47,
"end": 47, "end": 47,
"loc": {
"start": {
"line": 4,
"column": 12
},
"end": {
"line": 4,
"column": 12
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
} }
] ]
@ -186,10 +239,54 @@
"start": 65, "start": 65,
"end": 73, "end": 73,
"expression": { "expression": {
"type": "Identifier", "type": "MemberExpression",
"start": 66, "start": 66,
"end": 72, "end": 72,
"loc": {
"start": {
"line": 5,
"column": 10
},
"end": {
"line": 5,
"column": 16
}
},
"object": {
"type": "Literal",
"start": 66,
"end": 71,
"loc": {
"start": {
"line": 5,
"column": 10
},
"end": {
"line": 5,
"column": 15
}
},
"value": "hi}",
"raw": "'hi}'"
},
"property": {
"type": "Identifier",
"start": 72,
"end": 72,
"loc": {
"start": {
"line": 5,
"column": 16
},
"end": {
"line": 5,
"column": 16
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
} }
] ]
@ -233,10 +330,73 @@
"start": 100, "start": 100,
"end": 110, "end": 110,
"expression": { "expression": {
"type": "Identifier", "type": "ArrowFunctionExpression",
"start": 101, "start": 101,
"end": 109, "end": 109,
"loc": {
"start": {
"line": 6,
"column": 20
},
"end": {
"line": 6,
"column": 28
}
},
"id": null,
"expression": true,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "MemberExpression",
"start": 107,
"end": 109,
"loc": {
"start": {
"line": 6,
"column": 26
},
"end": {
"line": 6,
"column": 28
}
},
"object": {
"type": "Identifier",
"start": 107,
"end": 108,
"loc": {
"start": {
"line": 6,
"column": 26
},
"end": {
"line": 6,
"column": 27
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 109,
"end": 109,
"loc": {
"start": {
"line": 6,
"column": 28
},
"end": {
"line": 6,
"column": 28
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
}
} }
} }
] ]
@ -275,11 +435,54 @@
} }
}, },
"expression": { "expression": {
"type": "MemberExpression",
"start": 134,
"end": 136,
"loc": {
"start": {
"line": 8,
"column": 19
},
"end": {
"line": 8,
"column": 21
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 134, "start": 134,
"end": 135,
"loc": {
"start": {
"line": 8,
"column": 19
},
"end": {
"line": 8,
"column": 20
}
},
"name": "a"
},
"property": {
"type": "Identifier",
"start": 136,
"end": 136, "end": 136,
"loc": {
"start": {
"line": 8,
"column": 21
},
"end": {
"line": 8,
"column": 21
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"modifiers": [] "modifiers": []
} }
], ],
@ -297,10 +500,53 @@
"start": 145, "start": 145,
"end": 149, "end": 149,
"expression": { "expression": {
"type": "MemberExpression",
"start": 146,
"end": 148,
"loc": {
"start": {
"line": 10,
"column": 4
},
"end": {
"line": 10,
"column": 6
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 146, "start": 146,
"end": 147,
"loc": {
"start": {
"line": 10,
"column": 4
},
"end": {
"line": 10,
"column": 5
}
},
"name": "a"
},
"property": {
"type": "Identifier",
"start": 148,
"end": 148, "end": 148,
"loc": {
"start": {
"line": 10,
"column": 6
},
"end": {
"line": 10,
"column": 6
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
}, },
{ {
@ -315,10 +561,86 @@
"start": 153, "start": 153,
"end": 164, "end": 164,
"expression": { "expression": {
"type": "Identifier", "type": "MemberExpression",
"start": 154, "start": 154,
"end": 163, "end": 163,
"loc": {
"start": {
"line": 11,
"column": 1
},
"end": {
"line": 11,
"column": 10
}
},
"object": {
"type": "Identifier",
"start": 154,
"end": 157,
"loc": {
"start": {
"line": 11,
"column": 1
},
"end": {
"line": 11,
"column": 4
}
},
"name": "foo"
},
"property": {
"type": "MemberExpression",
"start": 158,
"end": 162,
"loc": {
"start": {
"line": 11,
"column": 5
},
"end": {
"line": 11,
"column": 9
}
},
"object": {
"type": "Identifier",
"start": 158,
"end": 161,
"loc": {
"start": {
"line": 11,
"column": 5
},
"end": {
"line": 11,
"column": 8
}
},
"name": "bar"
},
"property": {
"type": "Identifier",
"start": 162,
"end": 162,
"loc": {
"start": {
"line": 11,
"column": 9
},
"end": {
"line": 11,
"column": 9
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
},
"computed": true,
"optional": false
} }
}, },
{ {
@ -333,11 +655,54 @@
"start": 166, "start": 166,
"end": 179, "end": 179,
"expression": { "expression": {
"type": "MemberExpression",
"start": 171,
"end": 173,
"loc": {
"start": {
"line": 13,
"column": 5
},
"end": {
"line": 13,
"column": 7
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 171, "start": 171,
"end": 172,
"loc": {
"start": {
"line": 13,
"column": 5
},
"end": {
"line": 13,
"column": 6
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 173,
"end": 173, "end": 173,
"loc": {
"start": {
"line": 13,
"column": 7
},
"end": {
"line": 13,
"column": 7
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"children": [] "children": []
}, },
{ {
@ -387,10 +752,53 @@
"name": "array" "name": "array"
}, },
"key": { "key": {
"type": "MemberExpression",
"start": 203,
"end": 208,
"loc": {
"start": {
"line": 15,
"column": 22
},
"end": {
"line": 15,
"column": 27
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 203, "start": 203,
"end": 207,
"loc": {
"start": {
"line": 15,
"column": 22
},
"end": {
"line": 15,
"column": 26
}
},
"name": "item"
},
"property": {
"type": "Identifier",
"start": 208,
"end": 208, "end": 208,
"loc": {
"start": {
"line": 15,
"column": 27
},
"end": {
"line": 15,
"column": 27
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
}, },
{ {
@ -405,12 +813,72 @@
"start": 219, "start": 219,
"end": 246, "end": 246,
"children": [], "children": [],
"context": null, "context": {
"type": "Identifier",
"name": "item",
"start": 234,
"end": 238,
"loc": {
"start": {
"line": 17,
"column": 15,
"character": 234
},
"end": {
"line": 17,
"column": 19,
"character": 238
}
}
},
"expression": { "expression": {
"type": "MemberExpression",
"start": 226,
"end": 231,
"loc": {
"start": {
"line": 17,
"column": 7
},
"end": {
"line": 17,
"column": 12
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 226, "start": 226,
"end": 238, "end": 229,
"loc": {
"start": {
"line": 17,
"column": 7
},
"end": {
"line": 17,
"column": 10
}
},
"name": "obj"
},
"property": {
"type": "Identifier",
"start": 231,
"end": 231,
"loc": {
"start": {
"line": 17,
"column": 12
},
"end": {
"line": 17,
"column": 12
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
}, },
{ {
@ -425,11 +893,54 @@
"start": 248, "start": 248,
"end": 267, "end": 267,
"expression": { "expression": {
"type": "MemberExpression",
"start": 256,
"end": 258,
"loc": {
"start": {
"line": 19,
"column": 8
},
"end": {
"line": 19,
"column": 10
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 256, "start": 256,
"end": 257,
"loc": {
"start": {
"line": 19,
"column": 8
},
"end": {
"line": 19,
"column": 9
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 258,
"end": 258, "end": 258,
"loc": {
"start": {
"line": 19,
"column": 10
},
"end": {
"line": 19,
"column": 10
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"value": null, "value": null,
"error": null, "error": null,
"pending": { "pending": {
@ -466,26 +977,86 @@
"start": 269, "start": 269,
"end": 295, "end": 295,
"expression": { "expression": {
"type": "MemberExpression",
"start": 277,
"end": 280,
"loc": {
"start": {
"line": 21,
"column": 8
},
"end": {
"line": 21,
"column": 11
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 277, "start": 277,
"end": 286, "end": 278,
"loc": {
"start": {
"line": 21,
"column": 8
},
"end": {
"line": 21,
"column": 9
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 280,
"end": 280,
"loc": {
"start": {
"line": 21,
"column": 11
},
"end": {
"line": 21,
"column": 11
}
},
"name": "" "name": ""
}, },
"value": null, "computed": false,
"optional": false
},
"value": {
"type": "Identifier",
"name": "y",
"start": 285,
"end": 286,
"loc": {
"start": {
"line": 21,
"column": 16,
"character": 285
},
"end": {
"line": 21,
"column": 17,
"character": 286
}
}
},
"error": null, "error": null,
"pending": { "pending": {
"type": "PendingBlock", "type": "PendingBlock",
"start": 287, "start": null,
"end": 287, "end": null,
"children": [], "children": [],
"skip": false "skip": true
}, },
"then": { "then": {
"type": "ThenBlock", "type": "ThenBlock",
"start": null, "start": 287,
"end": null, "end": 267,
"children": [], "children": [],
"skip": true "skip": false
}, },
"catch": { "catch": {
"type": "CatchBlock", "type": "CatchBlock",
@ -507,19 +1078,79 @@
"start": 297, "start": 297,
"end": 324, "end": 324,
"expression": { "expression": {
"type": "MemberExpression",
"start": 305,
"end": 308,
"loc": {
"start": {
"line": 23,
"column": 8
},
"end": {
"line": 23,
"column": 11
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 305, "start": 305,
"end": 315, "end": 306,
"loc": {
"start": {
"line": 23,
"column": 8
},
"end": {
"line": 23,
"column": 9
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 308,
"end": 308,
"loc": {
"start": {
"line": 23,
"column": 11
},
"end": {
"line": 23,
"column": 11
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"value": null, "value": null,
"error": null, "error": {
"type": "Identifier",
"name": "y",
"start": 314,
"end": 315,
"loc": {
"start": {
"line": 23,
"column": 17,
"character": 314
},
"end": {
"line": 23,
"column": 18,
"character": 315
}
}
},
"pending": { "pending": {
"type": "PendingBlock", "type": "PendingBlock",
"start": 316, "start": null,
"end": 316, "end": null,
"children": [], "children": [],
"skip": false "skip": true
}, },
"then": { "then": {
"type": "ThenBlock", "type": "ThenBlock",
@ -530,10 +1161,10 @@
}, },
"catch": { "catch": {
"type": "CatchBlock", "type": "CatchBlock",
"start": null, "start": 316,
"end": null, "end": 295,
"children": [], "children": [],
"skip": true "skip": false
} }
} }
] ]

@ -45,23 +45,53 @@
"end": 18, "end": 18,
"declaration": { "declaration": {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"kind": "let", "start": 13,
"end": 17,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 6
}
},
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 17,
"end": 17,
"loc": {
"start": {
"line": 2,
"column": 6
},
"end": {
"line": 2,
"column": 6
}
},
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"name": "",
"start": 17, "start": 17,
"end": 17 "end": 17,
"loc": {
"start": {
"line": 2,
"column": 6
}, },
"init": null, "end": {
"start": 17, "line": 2,
"end": 17 "column": 6
}
},
"name": ""
},
"init": null
} }
], ],
"start": 13, "kind": "let"
"end": 17
} }
}, },
{ {
@ -77,23 +107,68 @@
"end": 32, "end": 32,
"declaration": { "declaration": {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"kind": "const", "start": 21,
"end": 31,
"loc": {
"start": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 12
}
},
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 27,
"end": 31,
"loc": {
"start": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 12
}
},
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"name": "", "start": 27,
"start": 31, "end": 28,
"end": 31 "loc": {
"start": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 9
}
}, },
"init": null, "name": "x"
},
"init": {
"type": "Identifier",
"start": 31, "start": 31,
"end": 31 "end": 31,
"loc": {
"start": {
"line": 3,
"column": 12
},
"end": {
"line": 3,
"column": 12
}
},
"name": ""
}
} }
], ],
"start": 21, "kind": "const"
"end": 31
} }
}, },
{ {
@ -109,23 +184,100 @@
"end": 48, "end": 48,
"declaration": { "declaration": {
"type": "VariableDeclaration", "type": "VariableDeclaration",
"kind": "let", "start": 35,
"end": 47,
"loc": {
"start": {
"line": 4,
"column": 2
},
"end": {
"line": 4,
"column": 14
}
},
"declarations": [ "declarations": [
{ {
"type": "VariableDeclarator", "type": "VariableDeclarator",
"start": 39,
"end": 47,
"loc": {
"start": {
"line": 4,
"column": 6
},
"end": {
"line": 4,
"column": 14
}
},
"id": { "id": {
"type": "Identifier", "type": "Identifier",
"name": "", "start": 39,
"start": 47, "end": 40,
"end": 47 "loc": {
"start": {
"line": 4,
"column": 6
},
"end": {
"line": 4,
"column": 7
}
},
"name": "x"
}, },
"init": null, "init": {
"type": "BinaryExpression",
"start": 43,
"end": 47,
"loc": {
"start": {
"line": 4,
"column": 10
},
"end": {
"line": 4,
"column": 14
}
},
"left": {
"type": "Identifier",
"start": 43,
"end": 44,
"loc": {
"start": {
"line": 4,
"column": 10
},
"end": {
"line": 4,
"column": 11
}
},
"name": "a"
},
"operator": "/",
"right": {
"type": "Identifier",
"start": 47, "start": 47,
"end": 47 "end": 47,
"loc": {
"start": {
"line": 4,
"column": 14
},
"end": {
"line": 4,
"column": 14
}
},
"name": ""
}
}
} }
], ],
"start": 35, "kind": "let"
"end": 47
} }
}, },
{ {
@ -141,5 +293,6 @@
} }
] ]
}, },
"options": null "options": null,
"comments": []
} }

@ -16,6 +16,16 @@
"type": "Identifier", "type": "Identifier",
"start": 5, "start": 5,
"end": 5, "end": 5,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 5
}
},
"name": "" "name": ""
}, },
"consequent": { "consequent": {
@ -42,6 +52,16 @@
"type": "Identifier", "type": "Identifier",
"start": 17, "start": 17,
"end": 17, "end": 17,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 10
}
},
"name": "" "name": ""
}, },
"consequent": { "consequent": {
@ -87,6 +107,16 @@
"type": "Identifier", "type": "Identifier",
"start": 42, "start": 42,
"end": 42, "end": 42,
"loc": {
"start": {
"line": 6,
"column": 7
},
"end": {
"line": 6,
"column": 7
}
},
"name": "" "name": ""
}, },
"body": { "body": {
@ -191,5 +221,6 @@
} }
] ]
}, },
"options": null "options": null,
"comments": []
} }

@ -122,6 +122,16 @@
"type": "Identifier", "type": "Identifier",
"start": 25, "start": 25,
"end": 25, "end": 25,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 10
}
},
"name": "" "name": ""
} }
} }
@ -179,10 +189,53 @@
"start": 44, "start": 44,
"end": 48, "end": 48,
"expression": { "expression": {
"type": "MemberExpression",
"start": 45,
"end": 47,
"loc": {
"start": {
"line": 4,
"column": 10
},
"end": {
"line": 4,
"column": 12
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 45, "start": 45,
"end": 46,
"loc": {
"start": {
"line": 4,
"column": 10
},
"end": {
"line": 4,
"column": 11
}
},
"name": "a"
},
"property": {
"type": "Identifier",
"start": 47,
"end": 47, "end": 47,
"loc": {
"start": {
"line": 4,
"column": 12
},
"end": {
"line": 4,
"column": 12
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
} }
} }
@ -239,10 +292,54 @@
"start": 65, "start": 65,
"end": 73, "end": 73,
"expression": { "expression": {
"type": "Identifier", "type": "MemberExpression",
"start": 66,
"end": 72,
"loc": {
"start": {
"line": 5,
"column": 10
},
"end": {
"line": 5,
"column": 16
}
},
"object": {
"type": "Literal",
"start": 66, "start": 66,
"end": 71,
"loc": {
"start": {
"line": 5,
"column": 10
},
"end": {
"line": 5,
"column": 15
}
},
"value": "hi}",
"raw": "'hi}'"
},
"property": {
"type": "Identifier",
"start": 72,
"end": 72, "end": 72,
"loc": {
"start": {
"line": 5,
"column": 16
},
"end": {
"line": 5,
"column": 16
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
} }
} }
@ -299,10 +396,73 @@
"start": 100, "start": 100,
"end": 110, "end": 110,
"expression": { "expression": {
"type": "Identifier", "type": "ArrowFunctionExpression",
"start": 101, "start": 101,
"end": 109, "end": 109,
"loc": {
"start": {
"line": 6,
"column": 20
},
"end": {
"line": 6,
"column": 28
}
},
"id": null,
"expression": true,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "MemberExpression",
"start": 107,
"end": 109,
"loc": {
"start": {
"line": 6,
"column": 26
},
"end": {
"line": 6,
"column": 28
}
},
"object": {
"type": "Identifier",
"start": 107,
"end": 108,
"loc": {
"start": {
"line": 6,
"column": 26
},
"end": {
"line": 6,
"column": 27
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 109,
"end": 109,
"loc": {
"start": {
"line": 6,
"column": 28
},
"end": {
"line": 6,
"column": 28
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
}
} }
} }
} }
@ -355,11 +515,54 @@
} }
}, },
"expression": { "expression": {
"type": "MemberExpression",
"start": 134,
"end": 136,
"loc": {
"start": {
"line": 8,
"column": 19
},
"end": {
"line": 8,
"column": 21
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 134, "start": 134,
"end": 135,
"loc": {
"start": {
"line": 8,
"column": 19
},
"end": {
"line": 8,
"column": 20
}
},
"name": "a"
},
"property": {
"type": "Identifier",
"start": 136,
"end": 136, "end": 136,
"loc": {
"start": {
"line": 8,
"column": 21
},
"end": {
"line": 8,
"column": 21
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"modifiers": [] "modifiers": []
} }
], ],
@ -380,10 +583,53 @@
"start": 145, "start": 145,
"end": 149, "end": 149,
"expression": { "expression": {
"type": "MemberExpression",
"start": 146,
"end": 148,
"loc": {
"start": {
"line": 10,
"column": 4
},
"end": {
"line": 10,
"column": 6
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 146, "start": 146,
"end": 147,
"loc": {
"start": {
"line": 10,
"column": 4
},
"end": {
"line": 10,
"column": 5
}
},
"name": "a"
},
"property": {
"type": "Identifier",
"start": 148,
"end": 148, "end": 148,
"loc": {
"start": {
"line": 10,
"column": 6
},
"end": {
"line": 10,
"column": 6
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
}, },
{ {
@ -398,10 +644,86 @@
"start": 153, "start": 153,
"end": 164, "end": 164,
"expression": { "expression": {
"type": "Identifier", "type": "MemberExpression",
"start": 154, "start": 154,
"end": 163, "end": 163,
"loc": {
"start": {
"line": 11,
"column": 1
},
"end": {
"line": 11,
"column": 10
}
},
"object": {
"type": "Identifier",
"start": 154,
"end": 157,
"loc": {
"start": {
"line": 11,
"column": 1
},
"end": {
"line": 11,
"column": 4
}
},
"name": "foo"
},
"property": {
"type": "MemberExpression",
"start": 158,
"end": 162,
"loc": {
"start": {
"line": 11,
"column": 5
},
"end": {
"line": 11,
"column": 9
}
},
"object": {
"type": "Identifier",
"start": 158,
"end": 161,
"loc": {
"start": {
"line": 11,
"column": 5
},
"end": {
"line": 11,
"column": 8
}
},
"name": "bar"
},
"property": {
"type": "Identifier",
"start": 162,
"end": 162,
"loc": {
"start": {
"line": 11,
"column": 9
},
"end": {
"line": 11,
"column": 9
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
},
"computed": true,
"optional": false
} }
}, },
{ {
@ -417,11 +739,54 @@
"start": 166, "start": 166,
"end": 179, "end": 179,
"test": { "test": {
"type": "MemberExpression",
"start": 171,
"end": 173,
"loc": {
"start": {
"line": 13,
"column": 5
},
"end": {
"line": 13,
"column": 7
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 171, "start": 171,
"end": 172,
"loc": {
"start": {
"line": 13,
"column": 5
},
"end": {
"line": 13,
"column": 6
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 173,
"end": 173, "end": 173,
"loc": {
"start": {
"line": 13,
"column": 7
},
"end": {
"line": 13,
"column": 7
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"consequent": { "consequent": {
"type": "Fragment", "type": "Fragment",
"nodes": [] "nodes": []
@ -478,10 +843,53 @@
} }
}, },
"key": { "key": {
"type": "MemberExpression",
"start": 203,
"end": 208,
"loc": {
"start": {
"line": 15,
"column": 22
},
"end": {
"line": 15,
"column": 27
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 203, "start": 203,
"end": 207,
"loc": {
"start": {
"line": 15,
"column": 22
},
"end": {
"line": 15,
"column": 26
}
},
"name": "item"
},
"property": {
"type": "Identifier",
"start": 208,
"end": 208, "end": 208,
"loc": {
"start": {
"line": 15,
"column": 27
},
"end": {
"line": 15,
"column": 27
}
},
"name": "" "name": ""
},
"computed": false,
"optional": false
} }
}, },
{ {
@ -496,16 +904,76 @@
"start": 219, "start": 219,
"end": 246, "end": 246,
"expression": { "expression": {
"type": "MemberExpression",
"start": 226,
"end": 231,
"loc": {
"start": {
"line": 17,
"column": 7
},
"end": {
"line": 17,
"column": 12
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 226, "start": 226,
"end": 238, "end": 229,
"loc": {
"start": {
"line": 17,
"column": 7
},
"end": {
"line": 17,
"column": 10
}
},
"name": "obj"
},
"property": {
"type": "Identifier",
"start": 231,
"end": 231,
"loc": {
"start": {
"line": 17,
"column": 12
},
"end": {
"line": 17,
"column": 12
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"body": { "body": {
"type": "Fragment", "type": "Fragment",
"nodes": [] "nodes": []
}, },
"context": null "context": {
"type": "Identifier",
"name": "item",
"start": 234,
"end": 238,
"loc": {
"start": {
"line": 17,
"column": 15,
"character": 234
},
"end": {
"line": 17,
"column": 19,
"character": 238
}
}
}
}, },
{ {
"type": "Text", "type": "Text",
@ -519,11 +987,54 @@
"start": 248, "start": 248,
"end": 267, "end": 267,
"expression": { "expression": {
"type": "MemberExpression",
"start": 256,
"end": 258,
"loc": {
"start": {
"line": 19,
"column": 8
},
"end": {
"line": 19,
"column": 10
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 256, "start": 256,
"end": 257,
"loc": {
"start": {
"line": 19,
"column": 8
},
"end": {
"line": 19,
"column": 9
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 258,
"end": 258, "end": 258,
"loc": {
"start": {
"line": 19,
"column": 10
},
"end": {
"line": 19,
"column": 10
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"value": null, "value": null,
"error": null, "error": null,
"pending": { "pending": {
@ -545,18 +1056,78 @@
"start": 269, "start": 269,
"end": 295, "end": 295,
"expression": { "expression": {
"type": "MemberExpression",
"start": 277,
"end": 280,
"loc": {
"start": {
"line": 21,
"column": 8
},
"end": {
"line": 21,
"column": 11
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 277, "start": 277,
"end": 286, "end": 278,
"loc": {
"start": {
"line": 21,
"column": 8
},
"end": {
"line": 21,
"column": 9
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 280,
"end": 280,
"loc": {
"start": {
"line": 21,
"column": 11
},
"end": {
"line": 21,
"column": 11
}
},
"name": "" "name": ""
}, },
"value": null, "computed": false,
"optional": false
},
"value": {
"type": "Identifier",
"name": "y",
"start": 285,
"end": 286,
"loc": {
"start": {
"line": 21,
"column": 16,
"character": 285
},
"end": {
"line": 21,
"column": 17,
"character": 286
}
}
},
"error": null, "error": null,
"pending": { "pending": null,
"then": {
"type": "Fragment", "type": "Fragment",
"nodes": [] "nodes": []
}, },
"then": null,
"catch": null "catch": null
}, },
{ {
@ -571,19 +1142,79 @@
"start": 297, "start": 297,
"end": 324, "end": 324,
"expression": { "expression": {
"type": "MemberExpression",
"start": 305,
"end": 308,
"loc": {
"start": {
"line": 23,
"column": 8
},
"end": {
"line": 23,
"column": 11
}
},
"object": {
"type": "Identifier", "type": "Identifier",
"start": 305, "start": 305,
"end": 315, "end": 306,
"loc": {
"start": {
"line": 23,
"column": 8
},
"end": {
"line": 23,
"column": 9
}
},
"name": "x"
},
"property": {
"type": "Identifier",
"start": 308,
"end": 308,
"loc": {
"start": {
"line": 23,
"column": 11
},
"end": {
"line": 23,
"column": 11
}
},
"name": "" "name": ""
}, },
"computed": false,
"optional": false
},
"value": null, "value": null,
"error": null, "error": {
"pending": { "type": "Identifier",
"type": "Fragment", "name": "y",
"nodes": [] "start": 314,
"end": 315,
"loc": {
"start": {
"line": 23,
"column": 17,
"character": 314
},
"end": {
"line": 23,
"column": 18,
"character": 315
}
}
}, },
"pending": null,
"then": null, "then": null,
"catch": null "catch": {
"type": "Fragment",
"nodes": []
}
} }
] ]
}, },

Loading…
Cancel
Save