the parser says what was in parens: the four scans back through the source for a ( go

goodbye-acorn
Nic 2 days ago
parent 394fa2c588
commit 6632b93c8b

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

@ -604,14 +604,10 @@ function special(parser) {
parser.eat('=', true);
parser.allow_whitespace();
const expression_start = parser.index;
const init = read_expression(parser);
// parser is past wrapping parens, but `init.end` is not — use the parser position
const declarator_end = parser.index;
if (
init.type === 'SequenceExpression' &&
!parser.template.substring(expression_start, init.start).includes('(')
) {
if (init.type === 'SequenceExpression' && !init.parenthesized) {
// const a = (b, c) is allowed but a = b, c = d is not;
e.const_tag_invalid_expression(init);
}

@ -135,23 +135,9 @@ export function BindDirective(node, context) {
e.bind_group_invalid_expression(node);
}
let i = /** @type {number} */ (node.expression.start);
let leading_comments_start = /**@type {any}*/ (node.expression.leadingComments?.at(0))?.start;
let leading_comments_end = /**@type {any}*/ (node.expression.leadingComments?.at(-1))?.end;
while (context.state.analysis.source[--i] !== '{') {
if (
context.state.analysis.source[i] === '(' &&
// if the parenthesis is in a leading comment we don't need to throw the error
!(
leading_comments_start &&
leading_comments_end &&
i <= leading_comments_end &&
i >= leading_comments_start
)
) {
if (node.expression.parenthesized) {
e.bind_invalid_parens(node, node.name);
}
}
if (node.expression.expressions.length !== 2) {
e.bind_invalid_expression(node);

@ -93,10 +93,7 @@ export function visit_component(node, context) {
validate_attribute(attribute, node);
if (is_expression_attribute(attribute)) {
disallow_unparenthesized_sequences(
get_attribute_expression(attribute),
context.state.analysis.source
);
disallow_unparenthesized_sequences(get_attribute_expression(attribute));
}
}
@ -112,7 +109,7 @@ export function visit_component(node, context) {
}
if (attribute.type === 'AttachTag') {
disallow_unparenthesized_sequences(attribute.expression, context.state.analysis.source);
disallow_unparenthesized_sequences(attribute.expression);
}
}
@ -163,15 +160,9 @@ export function visit_component(node, context) {
/**
* @param {Expression} expression
* @param {string} source
*/
function disallow_unparenthesized_sequences(expression, source) {
if (expression.type === 'SequenceExpression') {
let i = /** @type {number} */ (expression.start);
while (--i > 0) {
const char = source[i];
if (char === '(') break; // parenthesized sequence expressions are ok
if (char === '{') e.attribute_invalid_sequence_expression(expression);
}
function disallow_unparenthesized_sequences(expression) {
if (expression.type === 'SequenceExpression' && !expression.parenthesized) {
e.attribute_invalid_sequence_expression(expression);
}
}

@ -45,13 +45,8 @@ export function validate_element(node, context) {
if (is_expression) {
const expression = get_attribute_expression(attribute);
if (expression.type === 'SequenceExpression') {
let i = /** @type {number} */ (expression.start);
while (--i > 0) {
const char = context.state.analysis.source[i];
if (char === '(') break; // parenthesized sequence expressions are ok
if (char === '{') e.attribute_invalid_sequence_expression(expression);
}
if (expression.type === 'SequenceExpression' && !expression.parenthesized) {
e.attribute_invalid_sequence_expression(expression);
}
}
}

@ -665,5 +665,7 @@ declare module 'estree' {
end?: number;
/** Added by acorn-typescript */
typeAnnotation?: any;
/** The source wraps the node in parens, from the parser; absent otherwise */
parenthesized?: true;
}
}

@ -79,6 +79,7 @@
"column": 24
}
},
"parenthesized": true,
"object": {
"type": "Identifier",
"start": 36,
@ -171,6 +172,7 @@
"column": 24
}
},
"parenthesized": true,
"operator": "=",
"left": {
"type": "Identifier",
@ -295,6 +297,7 @@
"column": 27
}
},
"parenthesized": true,
"properties": [
{
"type": "Property",
@ -523,5 +526,6 @@
}
]
},
"options": null
"options": null,
"comments": []
}

@ -1005,6 +1005,7 @@
"column": 60
}
},
"parenthesized": true,
"id": null,
"expression": false,
"generator": false,

@ -25,6 +25,7 @@
"column": 9
}
},
"parenthesized": true,
"leadingComments": [
{
"type": "Block",

@ -76,6 +76,9 @@ function clean(ast: AST.SvelteNode) {
delete node.leadingComments;
// @ts-ignore
delete node.trailingComments;
// the printer drops parens it does not need
// @ts-ignore
delete node.parenthesized;
context.next();
},

Loading…
Cancel
Save