Skip to content

Commit

Permalink
fix: move validation from parsing to validation
Browse files Browse the repository at this point in the history
  • Loading branch information
paoloricciuti committed May 23, 2024
1 parent 5454abb commit f320272
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 22 deletions.
19 changes: 0 additions & 19 deletions packages/svelte/src/compiler/phases/1-parse/state/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -680,15 +680,6 @@ function read_attribute_value(parser) {
];
}

/**
* we need this because if we are not inside a mustache we treat
* the whole thing as a string
* eg.
*
* <input foo=cool{variable} /> it's equal to <input foo="cool{variable}" />
*/
const mustached = !quote_mark && parser.match('{');

let value;
try {
value = read_sequence(
Expand All @@ -700,16 +691,6 @@ function read_attribute_value(parser) {
},
'in attribute value'
);

/**
* if we are in a mustache tag and the value returned is more than one
* expression there's a mismatch in the expression
*
* <input foo={true}} /> or even <input foo={true}something />
*/
if (mustached && value.length > 1) {
e.attribute_invalid_expression(parser.index);
}
} catch (/** @type {any} */ error) {
if (error.code === 'js_parse_error') {
// if the attribute value didn't close + self-closing tag
Expand Down
20 changes: 19 additions & 1 deletion packages/svelte/src/compiler/phases/2-analyze/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import * as e from '../../errors.js';
import {
extract_identifiers,
get_parent,
is_event_attribute,
is_expression_attribute,
is_quoted_attribute,
is_text_attribute,
object,
unwrap_optional
Expand Down Expand Up @@ -58,6 +58,15 @@ function validate_component(node, context) {
}

if (attribute.type === 'Attribute') {
if (
context.state.analysis.runes &&
!is_quoted_attribute(attribute) &&
Array.isArray(attribute.value) &&
attribute.value.length > 1
) {
e.attribute_invalid_expression(attribute);
}

if (context.state.analysis.runes && is_expression_attribute(attribute)) {
const expression = attribute.value[0].expression;
if (expression.type === 'SequenceExpression') {
Expand Down Expand Up @@ -107,6 +116,15 @@ function validate_element(node, context) {
if (attribute.type === 'Attribute') {
const is_expression = is_expression_attribute(attribute);

if (
context.state.analysis.runes &&
!is_quoted_attribute(attribute) &&
Array.isArray(attribute.value) &&
attribute.value.length > 1
) {
e.attribute_invalid_expression(attribute);
}

if (context.state.analysis.runes && is_expression) {
const expression = attribute.value[0].expression;
if (expression.type === 'SequenceExpression') {
Expand Down
10 changes: 10 additions & 0 deletions packages/svelte/src/compiler/utils/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ export function is_expression_attribute(attribute) {
);
}

/**
* Returns true if the attribute is quoted.
* @param {import('#compiler').Attribute} attribute
* @returns {attribute is import('#compiler').Attribute & { value: [import('#compiler').ExpressionTag] }}
*/
export function is_quoted_attribute(attribute) {
if (attribute.value === true) return false;
return attribute.value.at(-1)?.end !== attribute.end;
}

/**
* Returns true if the attribute starts with `on` and contains a single expression node.
* @param {import('#compiler').Attribute} attribute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ export default test({
error: {
code: 'attribute_invalid_expression',
message: 'Invalid attribute expression',
position: [91, 91]
position: [101, 116]
}
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<svelte:options runes />
<script>
import Component from "./Component.svelte";
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ export default test({
error: {
code: 'attribute_invalid_expression',
message: 'Invalid attribute expression',
position: [46, 46]
position: [34, 71]
}
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<svelte:options runes />
<button
onclick={() => console.log('hello')}}
>
Expand Down

0 comments on commit f320272

Please sign in to comment.