error on rest prop and duplicate props

props-bindable
Simon Holthausen 6 months ago
parent 695a309567
commit a472ccf828

@ -180,6 +180,9 @@ const runes = {
'invalid-props-id': () => `$props() can only be used with an object destructuring pattern`,
'invalid-props-pattern': () =>
`$props() assignment must not contain nested properties or computed keys`,
'duplicate-prop-name': () =>
`Cannot use the same prop name more than once across $props() and $props.bindable()`,
'invalid-props-rest-element': () => `Cannot use ...rest parameter with $props.bindable()`,
'invalid-props-location': () =>
`$props() can only be used at the top level of components as a variable declaration initializer`,
/** @param {string} rune */

@ -422,6 +422,7 @@ export function analyze_component(root, options) {
options,
ast_type: ast === instance.ast ? 'instance' : ast === template.ast ? 'template' : 'module',
parent_element: null,
all_prop_names: new Set(),
has_props_rune: [false, false],
component_slots: new Set(),
expression: null,
@ -446,6 +447,7 @@ export function analyze_component(root, options) {
analysis,
options,
parent_element: null,
all_prop_names: new Set(),
has_props_rune: [false, false],
ast_type: ast === instance.ast ? 'instance' : ast === template.ast ? 'template' : 'module',
instance_scope: instance.scope,
@ -525,6 +527,16 @@ export function analyze_component(root, options) {
}
}
if (analysis.runes) {
const props = new Set();
for (const [name, binding] of instance.scope.declarations) {
if (binding.kind === 'prop' || binding.kind === 'bindable_prop') {
if (props.has(binding)) {
}
}
}
}
if (analysis.css.ast) {
analyze_css(analysis.css.ast, analysis);

@ -15,6 +15,8 @@ export interface AnalysisState {
options: ValidatedCompileOptions;
ast_type: 'instance' | 'template' | 'module';
parent_element: string | null;
/** Names of $props() and $props.bindable() */
all_prop_names: Set<string>;
has_props_rune: [props: boolean, bindings: boolean];
/** Which slots the current parent component has */
component_slots: Set<string>;

@ -1092,9 +1092,17 @@ export const validation_runes = merge(validation, a11y_validators, {
const value =
property.value.type === 'AssignmentPattern' ? property.value.left : property.value;
if (value.type !== 'Identifier') {
if (value.type !== 'Identifier' || property.key.type !== 'Identifier') {
error(property, 'invalid-props-pattern');
}
if (state.all_prop_names.has(property.key.name)) {
error(property, 'duplicate-prop-name');
}
state.all_prop_names.add(property.key.name);
} else if (rune === '$props.bindable') {
error(property, 'invalid-props-rest-element');
}
}
}

@ -0,0 +1,9 @@
import { test } from '../../test';
export default test({
error: {
code: 'invalid-props-rest-element',
message: 'Cannot use ...rest parameter with $props.bindable()',
position: [53, 62]
}
});

@ -0,0 +1,4 @@
<script>
let { foo, ...ok } = $props();
let { bar, ...not_ok } = $props.bindable();
</script>

@ -0,0 +1,9 @@
import { test } from '../../test';
export default test({
error: {
code: 'duplicate-prop-name',
message: 'Cannot use the same prop name more than once across $props() and $props.bindable()',
position: [44, 50]
}
});

@ -0,0 +1,4 @@
<script>
let { foo: a } = $props();
let { foo: b } = $props.bindable();
</script>
Loading…
Cancel
Save