|
|
@ -134,7 +134,6 @@ function validate_element(node, context) {
|
|
|
|
warn(
|
|
|
|
warn(
|
|
|
|
context.state.analysis.warnings,
|
|
|
|
context.state.analysis.warnings,
|
|
|
|
attribute,
|
|
|
|
attribute,
|
|
|
|
context.path,
|
|
|
|
|
|
|
|
'global-event-reference',
|
|
|
|
'global-event-reference',
|
|
|
|
attribute.name
|
|
|
|
attribute.name
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -147,7 +146,7 @@ function validate_element(node, context) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (attribute.name === 'is' && context.state.options.namespace !== 'foreign') {
|
|
|
|
if (attribute.name === 'is' && context.state.options.namespace !== 'foreign') {
|
|
|
|
warn(context.state.analysis.warnings, attribute, context.path, 'avoid-is');
|
|
|
|
warn(context.state.analysis.warnings, attribute, 'avoid-is');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const correct_name = react_attributes.get(attribute.name);
|
|
|
|
const correct_name = react_attributes.get(attribute.name);
|
|
|
@ -155,7 +154,6 @@ function validate_element(node, context) {
|
|
|
|
warn(
|
|
|
|
warn(
|
|
|
|
context.state.analysis.warnings,
|
|
|
|
context.state.analysis.warnings,
|
|
|
|
attribute,
|
|
|
|
attribute,
|
|
|
|
context.path,
|
|
|
|
|
|
|
|
'invalid-html-attribute',
|
|
|
|
'invalid-html-attribute',
|
|
|
|
attribute.name,
|
|
|
|
attribute.name,
|
|
|
|
correct_name
|
|
|
|
correct_name
|
|
|
@ -235,7 +233,7 @@ function validate_attribute_name(attribute, context) {
|
|
|
|
!attribute.name.startsWith('xlink:') &&
|
|
|
|
!attribute.name.startsWith('xlink:') &&
|
|
|
|
!attribute.name.startsWith('xml:')
|
|
|
|
!attribute.name.startsWith('xml:')
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
warn(context.state.analysis.warnings, attribute, context.path, 'illegal-attribute-character');
|
|
|
|
warn(context.state.analysis.warnings, attribute, 'illegal-attribute-character');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -313,7 +311,7 @@ function validate_block_not_empty(node, context) {
|
|
|
|
// Assumption: If the block has zero elements, someone's in the middle of typing it out,
|
|
|
|
// Assumption: If the block has zero elements, someone's in the middle of typing it out,
|
|
|
|
// so don't warn in that case because it would be distracting.
|
|
|
|
// so don't warn in that case because it would be distracting.
|
|
|
|
if (node.nodes.length === 1 && node.nodes[0].type === 'Text' && !node.nodes[0].raw.trim()) {
|
|
|
|
if (node.nodes.length === 1 && node.nodes[0].type === 'Text' && !node.nodes[0].raw.trim()) {
|
|
|
|
warn(context.state.analysis.warnings, node.nodes[0], context.path, 'empty-block');
|
|
|
|
warn(context.state.analysis.warnings, node.nodes[0], 'empty-block');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -377,7 +375,6 @@ const validation = {
|
|
|
|
warn(
|
|
|
|
warn(
|
|
|
|
context.state.analysis.warnings,
|
|
|
|
context.state.analysis.warnings,
|
|
|
|
binding.node,
|
|
|
|
binding.node,
|
|
|
|
context.path,
|
|
|
|
|
|
|
|
'invalid-rest-eachblock-binding',
|
|
|
|
'invalid-rest-eachblock-binding',
|
|
|
|
binding.node.name
|
|
|
|
binding.node.name
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -534,13 +531,7 @@ const validation = {
|
|
|
|
binding.declaration_kind === 'import' &&
|
|
|
|
binding.declaration_kind === 'import' &&
|
|
|
|
binding.references.length === 0
|
|
|
|
binding.references.length === 0
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
warn(
|
|
|
|
warn(context.state.analysis.warnings, node, 'component-name-lowercase', node.name);
|
|
|
|
context.state.analysis.warnings,
|
|
|
|
|
|
|
|
node,
|
|
|
|
|
|
|
|
context.path,
|
|
|
|
|
|
|
|
'component-name-lowercase',
|
|
|
|
|
|
|
|
node.name
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
validate_element(node, context);
|
|
|
|
validate_element(node, context);
|
|
|
@ -579,13 +570,7 @@ const validation = {
|
|
|
|
!VoidElements.includes(node.name) &&
|
|
|
|
!VoidElements.includes(node.name) &&
|
|
|
|
!SVGElements.includes(node.name)
|
|
|
|
!SVGElements.includes(node.name)
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
warn(
|
|
|
|
warn(context.state.analysis.warnings, node, 'invalid-self-closing-tag', node.name);
|
|
|
|
context.state.analysis.warnings,
|
|
|
|
|
|
|
|
node,
|
|
|
|
|
|
|
|
context.path,
|
|
|
|
|
|
|
|
'invalid-self-closing-tag',
|
|
|
|
|
|
|
|
node.name
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.next({
|
|
|
|
context.next({
|
|
|
@ -781,7 +766,7 @@ export const validation_legacy = merge(validation, a11y_validators, {
|
|
|
|
(state.ast_type !== 'instance' ||
|
|
|
|
(state.ast_type !== 'instance' ||
|
|
|
|
/** @type {import('#compiler').SvelteNode} */ (path.at(-1)).type !== 'Program')
|
|
|
|
/** @type {import('#compiler').SvelteNode} */ (path.at(-1)).type !== 'Program')
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
warn(state.analysis.warnings, node, path, 'no-reactive-declaration');
|
|
|
|
warn(state.analysis.warnings, node, 'no-reactive-declaration');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
UpdateExpression(node, { state }) {
|
|
|
|
UpdateExpression(node, { state }) {
|
|
|
@ -984,12 +969,12 @@ export const validation_runes_js = {
|
|
|
|
const allowed_depth = context.state.ast_type === 'module' ? 0 : 1;
|
|
|
|
const allowed_depth = context.state.ast_type === 'module' ? 0 : 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (context.state.scope.function_depth > allowed_depth) {
|
|
|
|
if (context.state.scope.function_depth > allowed_depth) {
|
|
|
|
warn(context.state.analysis.warnings, node, context.path, 'avoid-nested-class');
|
|
|
|
warn(context.state.analysis.warnings, node, 'avoid-nested-class');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
NewExpression(node, context) {
|
|
|
|
NewExpression(node, context) {
|
|
|
|
if (node.callee.type === 'ClassExpression' && context.state.scope.function_depth > 0) {
|
|
|
|
if (node.callee.type === 'ClassExpression' && context.state.scope.function_depth > 0) {
|
|
|
|
warn(context.state.analysis.warnings, node, context.path, 'avoid-inline-class');
|
|
|
|
warn(context.state.analysis.warnings, node, 'avoid-inline-class');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -1134,7 +1119,7 @@ export const validation_runes = merge(validation, a11y_validators, {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
next({ ...state });
|
|
|
|
next({ ...state });
|
|
|
|
},
|
|
|
|
},
|
|
|
|
VariableDeclarator(node, { state, path }) {
|
|
|
|
VariableDeclarator(node, { state }) {
|
|
|
|
ensure_no_module_import_conflict(node, state);
|
|
|
|
ensure_no_module_import_conflict(node, state);
|
|
|
|
|
|
|
|
|
|
|
|
const init = node.init;
|
|
|
|
const init = node.init;
|
|
|
@ -1142,7 +1127,7 @@ export const validation_runes = merge(validation, a11y_validators, {
|
|
|
|
|
|
|
|
|
|
|
|
if (rune === null) {
|
|
|
|
if (rune === null) {
|
|
|
|
if (init?.type === 'Identifier' && init.name === '$props' && !state.scope.get('props')) {
|
|
|
|
if (init?.type === 'Identifier' && init.name === '$props' && !state.scope.get('props')) {
|
|
|
|
warn(state.analysis.warnings, node, path, 'invalid-props-declaration');
|
|
|
|
warn(state.analysis.warnings, node, 'invalid-props-declaration');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1195,29 +1180,29 @@ export const validation_runes = merge(validation, a11y_validators, {
|
|
|
|
arg.type === 'CallExpression' &&
|
|
|
|
arg.type === 'CallExpression' &&
|
|
|
|
(arg.callee.type === 'ArrowFunctionExpression' || arg.callee.type === 'FunctionExpression')
|
|
|
|
(arg.callee.type === 'ArrowFunctionExpression' || arg.callee.type === 'FunctionExpression')
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
warn(state.analysis.warnings, node, path, 'derived-iife');
|
|
|
|
warn(state.analysis.warnings, node, 'derived-iife');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
AssignmentPattern(node, { state, path }) {
|
|
|
|
AssignmentPattern(node, { state }) {
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
node.right.type === 'Identifier' &&
|
|
|
|
node.right.type === 'Identifier' &&
|
|
|
|
node.right.name === '$bindable' &&
|
|
|
|
node.right.name === '$bindable' &&
|
|
|
|
!state.scope.get('bindable')
|
|
|
|
!state.scope.get('bindable')
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
warn(state.analysis.warnings, node, path, 'invalid-bindable-declaration');
|
|
|
|
warn(state.analysis.warnings, node, 'invalid-bindable-declaration');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
SlotElement(node, { state, path }) {
|
|
|
|
SlotElement(node, { state }) {
|
|
|
|
if (!state.analysis.custom_element) {
|
|
|
|
if (!state.analysis.custom_element) {
|
|
|
|
warn(state.analysis.warnings, node, path, 'deprecated-slot-element');
|
|
|
|
warn(state.analysis.warnings, node, 'deprecated-slot-element');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
OnDirective(node, { state, path }) {
|
|
|
|
OnDirective(node, { state, path }) {
|
|
|
|
const parent_type = path.at(-1)?.type;
|
|
|
|
const parent_type = path.at(-1)?.type;
|
|
|
|
// Don't warn on component events; these might not be under the author's control so the warning would be unactionable
|
|
|
|
// Don't warn on component events; these might not be under the author's control so the warning would be unactionable
|
|
|
|
if (parent_type === 'RegularElement' || parent_type === 'SvelteElement') {
|
|
|
|
if (parent_type === 'RegularElement' || parent_type === 'SvelteElement') {
|
|
|
|
warn(state.analysis.warnings, node, path, 'deprecated-event-handler', node.name);
|
|
|
|
warn(state.analysis.warnings, node, 'deprecated-event-handler', node.name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// TODO this is a code smell. need to refactor this stuff
|
|
|
|
// TODO this is a code smell. need to refactor this stuff
|
|
|
|