cleaning up

pull/6519/head
tanhauhau 5 years ago
parent 903d27e1ed
commit 77310c320b

@ -1,178 +1,192 @@
// All parser errors should be listed and accessed from here // All parser errors should be listed and accessed from here
import list from '../utils/list';
/** /**
* @internal * @internal
*/ */
export default { export default {
unexpected_eof: { css_syntax_error: (message) => ({
code: 'unexpected-eof', code: 'css-syntax-error',
message: 'Unexpected end of input' message
}, }),
attribute_duplicate: { duplicate_attribute: {
code: 'duplicate-attribute', code: 'duplicate-attribute',
message: 'Attributes need to be unique' message: 'Attributes need to be unique'
}, },
expected_token_equal: { duplicate_element: (slug: string, name: string) => ({
code: 'unexpected-token', code: `duplicate-${slug}`,
message: 'Expected =' message: `A component can only have one <${name}> tag`
}, }),
directive_value_invalid: {
code: 'invalid-directive-value',
message: 'Directive value must be a JavaScript expression enclosed in curly braces'
},
duplicate_style: { duplicate_style: {
code: 'duplicate-style', code: 'duplicate-style',
message: 'You can only have one top-level <style> tag per component' message: 'You can only have one top-level <style> tag per component'
}, },
duplicate_instance_script: () => ({ empty_attribute_shorthand: {
code: 'invalid-script', code: 'empty-attribute-shorthand',
message: 'A component can only have one instance-level <script> element' message: 'Attribute shorthand cannot be empty'
},
empty_directive_name: (type: string) => ({
code: 'empty-directive-name',
message: `${type} name cannot be empty`
}), }),
duplicate_module_script: () => ({ empty_global_selector: {
code: 'invalid-script', code: 'css-syntax-error',
message: 'A component can only have one <script context="module"> element' message: ':global() must contain a selector'
},
expected_block_type: {
code: 'expected-block-type',
message: 'Expected if, each or await'
},
expected_name: {
code: 'expected-name',
message: 'Expected name'
},
invalid_catch_placement_unclosed_block: (block) => ({
code: 'invalid-catch-placement',
message: `Expected to close ${block} before seeing {:catch} block`
}), }),
dynamic_context_attribute: () => ({ invalid_catch_placement_without_await: {
code: 'invalid-script', code: 'invalid-catch-placement',
message: 'context attribute must be static' message: 'Cannot have an {:catch} block outside an {#await ...} block'
},
invalid_component_definition: {
code: 'invalid-component-definition',
message: 'invalid component definition'
},
invalid_closing_tag_unopened: (name: string) => ({
code: 'invalid-closing-tag',
message: `</${name}> attempted to close an element that was not open`
}), }),
fixed_context_attribute: () => ({ invalid_closing_tag_autoclosed: (name: string, reason: string) => ({
code: 'invalid-script', code: 'invalid-closing-tag',
message: 'If the context attribute is supplied, its value must be "module"' message: `</${name}> attempted to close <${name}> that was already automatically closed by <${reason}>`
}), }),
invalid_debug_args: {
code: 'invalid-debug-args',
message:
'{@debug ...} arguments must be identifiers, not arbitrary expressions'
},
invalid_declaration: {
code: 'invalid-declaration',
message: 'Declaration cannot be empty'
},
invalid_directive_value: {
code: 'invalid-directive-value',
message: 'Directive value must be a JavaScript expression enclosed in curly braces'
},
invalid_elseif: { invalid_elseif: {
code: 'invalid-elseif', code: 'invalid-elseif',
message: '\'elseif\' should be \'else if\'' message: '\'elseif\' should be \'else if\''
}, },
else_if_without_if: { invalid_elseif_placement_outside_if: {
code: 'invalid-elseif-placement', code: 'invalid-elseif-placement',
message: 'Cannot have an {:else if ...} block outside an {#if ...} block' message: 'Cannot have an {:else if ...} block outside an {#if ...} block'
}, },
else_if_before_block_close: (block) => ({ invalid_elseif_placement_unclosed_block: (block) => ({
code: 'invalid-elseif-placement', code: 'invalid-elseif-placement',
message: `Expected to close ${block} before seeing {:else if ...} block` message: `Expected to close ${block} before seeing {:else if ...} block`
}), }),
else_without_if_each: () => ({ invalid_else_placement_outside_if: {
code: 'invalid-else-placement', code: 'invalid-else-placement',
message: 'Cannot have an {:else} block outside an {#if ...} or {#each ...} block' message: 'Cannot have an {:else} block outside an {#if ...} or {#each ...} block'
}), },
else_before_block_close: (block) => ({ invalid_else_placement_unclosed_block: (block) => ({
code: 'invalid-else-placement', code: 'invalid-else-placement',
message: `Expected to close ${block} before seeing {:else} block` message: `Expected to close ${block} before seeing {:else} block`
}), }),
then_before_close_block: (block) => ({ invalid_element_content: (slug: string, name: string) => ({
code: 'invalid-then-placement', code: `invalid-${slug}-content`,
message: `Expected to close ${block} before seeing {:then} block` message: `<${name}> cannot have children`
}), }),
then_without_await: { invalid_element_placement: (slug: string, name: string) => ({
code: 'invalid-then-placement', code: `invalid-${slug}-placement`,
message: 'Cannot have an {:then} block outside an {#await ...} block' message: `<${name}> tags cannot be inside elements or blocks`
},
catch_before_close_block: (block) => ({
code: 'invalid-catch-placement',
message: `Expected to close ${block} before seeing {:catch} block`
}), }),
catch_without_await: { invalid_ref_directive: (name: string) => ({
code: 'invalid-catch-placement', code: 'invalid-ref-directive',
message: 'Cannot have an {:catch} block outside an {#await ...} block' message: `The ref directive is no longer supported — use \`bind:this={${name}}\` instead`
}),
invalid_ref_selector: {
code: 'invalid-ref-selector',
message: 'ref selectors are no longer supported'
}, },
component_definition_invalid: { invalid_self_placement: {
code: 'invalid-component-definition', code: 'invalid-self-placement',
message: 'invalid component definition' message: '<svelte:self> components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components'
}, },
component_definition_missing: { invalid_script_instance: {
code: 'missing-component-definition', code: 'invalid-script',
message: '<svelte:component> must have a \'this\' attribute' message: 'A component can only have one instance-level <script> element'
}, },
expected_block_type: { invalid_script_module: {
code: 'expected-block-type', code: 'invalid-script',
message: 'Expected if, each or await' message: 'A component can only have one <script context="module"> element'
}, },
expected_name: { invalid_script_context_attribute: {
code: 'expected-name', code: 'invalid-script',
message: 'Expected name' message: 'context attribute must be static'
}, },
unexpected_block_close: { invalid_script_context_value: {
code: 'unexpected-block-close', code: 'invalid-script',
message: 'Unexpected block closing tag' message: 'If the context attribute is supplied, its value must be "module"'
}, },
debug_args: () => ({ invalid_tag_name: {
code: 'invalid-debug-args',
message:
'{@debug ...} arguments must be identifiers, not arbitrary expressions'
}),
element_unopened: (name) => ({
code: 'invalid-closing-tag',
message: `</${name}> attempted to close an element that was not open`
}),
element_autoclosed: (name, reason) => ({
code: 'invalid-closing-tag',
message: `</${name}> attempted to close <${name}> that was already automatically closed by <${reason}>`
}),
element_tag_name_invalid: {
code: 'invalid-tag-name', code: 'invalid-tag-name',
message: 'Expected valid tag name' message: 'Expected valid tag name'
}, },
meta_no_children: (slug, name) => ({ invalid_tag_name_svelte_element: (tags: string[], match: string) => ({
code: `invalid-${slug}-content`,
message: `<${name}> cannot have children`
}),
meta_duplicate: (slug, name) => ({
code: `duplicate-${slug}`,
message: `A component can only have one <${name}> tag`
}),
meta_top_level: (slug, name) => ({
code: `invalid-${slug}-placement`,
message: `<${name}> tags cannot be inside elements or blocks`
}),
self_placement_invalid: {
code: 'invalid-self-placement',
message: '<svelte:self> components can only exist inside {#if} blocks, {#each} blocks, or slots passed to components'
},
meta_tag_name_invalid: (tags, match) => ({
code: 'invalid-tag-name', code: 'invalid-tag-name',
message: `Valid <svelte:...> tag names are ${tags}${ message: `Valid <svelte:...> tag names are ${list(tags)}${
match ? ' (did you mean ' + match + '?)' : '' match ? ' (did you mean ' + match + '?)' : ''
}` }`
}), }),
ref_directive_invalid: (name) => ({ invalid_then_placement_unclosed_block: (block) => ({
code: 'invalid-ref-directive', code: 'invalid-then-placement',
message: `The ref directive is no longer supported — use \`bind:this={${name}}\` instead` message: `Expected to close ${block} before seeing {:then} block`
}), }),
void_no_children: (name) => ({ invalid_then_placement_without_await: {
code: 'invalid-then-placement',
message: 'Cannot have an {:then} block outside an {#await ...} block'
},
invalid_void_content: (name: string) => ({
code: 'invalid-void-content', code: 'invalid-void-content',
message: `<${name}> is a void element and cannot have children, or a closing tag` message: `<${name}> is a void element and cannot have children, or a closing tag`
}), }),
unclosed_script: () => ({ missing_component_definition: {
code: 'missing-component-definition',
message: '<svelte:component> must have a \'this\' attribute'
},
unclosed_script: {
code: 'unclosed-script', code: 'unclosed-script',
message: '<script> must have a closing tag' message: '<script> must have a closing tag'
}), },
unclosed_style: () => ({ unclosed_style: {
code: 'unclosed-style', code: 'unclosed-style',
message: '<style> must have a closing tag' message: '<style> must have a closing tag'
}), },
unclosed_comment: () => ({ unclosed_comment: {
code: 'unclosed-comment', code: 'unclosed-comment',
message: 'comment was left open, expected -->' message: 'comment was left open, expected -->'
},
unexpected_block_close: {
code: 'unexpected-block-close',
message: 'Unexpected block closing tag'
},
unexpected_eof: {
code: 'unexpected-eof',
message: 'Unexpected end of input'
},
unexpected_eof_token: (token: string) => ({
code: 'unexpected-eof',
message: `Unexpected ${token}`
}), }),
unexpected_token: () => ({ unexpected_token: (token: string) => ({
code: 'unexpected-token', code: 'unexpected-token',
message: 'Expected )' message: `Expected ${token}`
}),
invalid_ref_selector: () => ({
code: 'invalid-ref-selector',
message: 'ref selectors are no longer supported'
}), }),
invalid_declaration: () => ({ unexpected_token_destructure: {
code: 'invalid-declaration', code: 'unexpected-token',
message: 'Declaration cannot be empty' message: 'Expected identifier or destructure pattern'
}), }
empty_global_selector: () => ({
code: 'css-syntax-error',
message: ':global() must contain a selector'
}),
syntax_error: (message) => ({
code: 'css-syntax-error',
message
})
}; };

@ -107,17 +107,18 @@ export class Parser {
}); });
} }
eat(str: string, required?: boolean, message?: string) { eat(str: string, required?: boolean, error?: { code: string, message: string }) {
if (this.match(str)) { if (this.match(str)) {
this.index += str.length; this.index += str.length;
return true; return true;
} }
if (required) { if (required) {
this.error({ this.error(error ||
code: `unexpected-${this.index === this.template.length ? 'eof' : 'token'}`, (this.index === this.template.length
message: message || `Expected ${str}` ? parser_errors.unexpected_eof_token(str)
}); : parser_errors.unexpected_token(str))
);
} }
return false; return false;
@ -226,11 +227,11 @@ export default function parse(
const module_scripts = parser.js.filter(script => script.context === 'module'); const module_scripts = parser.js.filter(script => script.context === 'module');
if (instance_scripts.length > 1) { if (instance_scripts.length > 1) {
parser.error(parser_errors.duplicate_instance_script(), instance_scripts[1].start); parser.error(parser_errors.invalid_script_instance, instance_scripts[1].start);
} }
if (module_scripts.length > 1) { if (module_scripts.length > 1) {
parser.error(parser_errors.duplicate_module_script(), module_scripts[1].start); parser.error(parser_errors.invalid_script_module, module_scripts[1].start);
} }
return { return {

@ -9,6 +9,7 @@ import {
} from '../utils/bracket'; } from '../utils/bracket';
import { parse_expression_at } from '../acorn'; import { parse_expression_at } from '../acorn';
import { Pattern } from 'estree'; import { Pattern } from 'estree';
import parser_errors from '../errors';
export default function read_context( export default function read_context(
parser: Parser parser: Parser
@ -27,10 +28,7 @@ export default function read_context(
} }
if (!is_bracket_open(code)) { if (!is_bracket_open(code)) {
parser.error({ parser.error(parser_errors.unexpected_token_destructure);
code: 'unexpected-token',
message: 'Expected identifier or destructure pattern'
});
} }
const bracket_stack = [code]; const bracket_stack = [code];
@ -42,12 +40,11 @@ export default function read_context(
bracket_stack.push(code); bracket_stack.push(code);
} else if (is_bracket_close(code)) { } else if (is_bracket_close(code)) {
if (!is_bracket_pair(bracket_stack[bracket_stack.length - 1], code)) { if (!is_bracket_pair(bracket_stack[bracket_stack.length - 1], code)) {
parser.error({ parser.error(
code: 'unexpected-token', parser_errors.unexpected_token(
message: `Expected ${String.fromCharCode( String.fromCharCode(get_bracket_close(bracket_stack[bracket_stack.length - 1]))
get_bracket_close(bracket_stack[bracket_stack.length - 1]) )
)}` );
});
} }
bracket_stack.pop(); bracket_stack.pop();
if (bracket_stack.length === 0) { if (bracket_stack.length === 0) {

@ -2,6 +2,7 @@ import { parse_expression_at } from '../acorn';
import { Parser } from '../index'; import { Parser } from '../index';
import { Node } from 'estree'; import { Node } from 'estree';
import { whitespace } from '../../utils/patterns'; import { whitespace } from '../../utils/patterns';
import parser_errors from '../errors';
export default function read_expression(parser: Parser): Node { export default function read_expression(parser: Parser): Node {
try { try {
@ -20,10 +21,7 @@ export default function read_expression(parser: Parser): Node {
if (char === ')') { if (char === ')') {
num_parens -= 1; num_parens -= 1;
} else if (!whitespace.test(char)) { } else if (!whitespace.test(char)) {
parser.error({ parser.error(parser_errors.unexpected_token(')'), index);
code: 'unexpected-token',
message: 'Expected )'
}, index);
} }
index += 1; index += 1;

@ -9,13 +9,13 @@ function get_context(parser: Parser, attributes: any[], start: number): string {
if (!context) return 'default'; if (!context) return 'default';
if (context.value.length !== 1 || context.value[0].type !== 'Text') { if (context.value.length !== 1 || context.value[0].type !== 'Text') {
parser.error(parser_errors.dynamic_context_attribute(), start); parser.error(parser_errors.invalid_script_context_attribute, start);
} }
const value = context.value[0].data; const value = context.value[0].data;
if (value !== 'module') { if (value !== 'module') {
parser.error(parser_errors.fixed_context_attribute(), context.start); parser.error(parser_errors.invalid_script_context_value, context.start);
} }
return value; return value;
@ -23,10 +23,9 @@ function get_context(parser: Parser, attributes: any[], start: number): string {
export default function read_script(parser: Parser, start: number, attributes: Node[]): Script { export default function read_script(parser: Parser, start: number, attributes: Node[]): Script {
const script_start = parser.index; const script_start = parser.index;
const error_message = parser_errors.unclosed_script(); const data = parser.read_until(/<\/script\s*>/, parser_errors.unclosed_script);
const data = parser.read_until(/<\/script\s*>/, error_message);
if (parser.index >= parser.template.length) { if (parser.index >= parser.template.length) {
parser.error(error_message); parser.error(parser_errors.unclosed_script);
} }
const source = parser.template.slice(0, script_start).replace(/[^\n]/g, ' ') + data; const source = parser.template.slice(0, script_start).replace(/[^\n]/g, ' ') + data;

@ -7,12 +7,11 @@ import parser_errors from '../errors';
export default function read_style(parser: Parser, start: number, attributes: Node[]): Style { export default function read_style(parser: Parser, start: number, attributes: Node[]): Style {
const content_start = parser.index; const content_start = parser.index;
const error_message = parser_errors.unclosed_style();
const styles = parser.read_until(/<\/style\s*>/, error_message); const styles = parser.read_until(/<\/style\s*>/, parser_errors.unclosed_style);
if (parser.index >= parser.template.length) { if (parser.index >= parser.template.length) {
parser.error(error_message); parser.error(parser_errors.unclosed_style);
} }
const content_end = parser.index; const content_end = parser.index;
@ -29,7 +28,7 @@ export default function read_style(parser: Parser, start: number, attributes: No
}); });
} catch (err) { } catch (err) {
if (err.name === 'SyntaxError') { if (err.name === 'SyntaxError') {
parser.error(parser_errors.syntax_error(err.message), err.offset); parser.error(parser_errors.css_syntax_error(err.message), err.offset);
} else { } else {
throw err; throw err;
} }
@ -47,17 +46,17 @@ export default function read_style(parser: Parser, start: number, attributes: No
const b = node.children[i + 1]; const b = node.children[i + 1];
if (is_ref_selector(a, b)) { if (is_ref_selector(a, b)) {
parser.error(parser_errors.invalid_ref_selector(), a.loc.start.offset); parser.error(parser_errors.invalid_ref_selector, a.loc.start.offset);
} }
} }
} }
if (node.type === 'Declaration' && node.value.type === 'Value' && node.value.children.length === 0) { if (node.type === 'Declaration' && node.value.type === 'Value' && node.value.children.length === 0) {
parser.error(parser_errors.invalid_declaration(), node.start); parser.error(parser_errors.invalid_declaration, node.start);
} }
if (node.type === 'PseudoClassSelector' && node.name === 'global' && node.children === null) { if (node.type === 'PseudoClassSelector' && node.name === 'global' && node.children === null) {
parser.error(parser_errors.empty_global_selector(), node.loc.start.offset); parser.error(parser_errors.empty_global_selector, node.loc.start.offset);
} }
if (node.loc) { if (node.loc) {

@ -107,8 +107,8 @@ export default function mustache(parser: Parser) {
if (block.type !== 'IfBlock') { if (block.type !== 'IfBlock') {
parser.error( parser.error(
parser.stack.some(block => block.type === 'IfBlock') parser.stack.some(block => block.type === 'IfBlock')
? parser_errors.else_if_before_block_close(to_string(block)) ? parser_errors.invalid_elseif_placement_unclosed_block(to_string(block))
: parser_errors.else_if_without_if : parser_errors.invalid_elseif_placement_outside_if
); );
} }
@ -142,8 +142,8 @@ export default function mustache(parser: Parser) {
if (block.type !== 'IfBlock' && block.type !== 'EachBlock') { if (block.type !== 'IfBlock' && block.type !== 'EachBlock') {
parser.error( parser.error(
parser.stack.some(block => block.type === 'IfBlock' || block.type === 'EachBlock') parser.stack.some(block => block.type === 'IfBlock' || block.type === 'EachBlock')
? parser_errors.else_before_block_close(to_string(block)) ? parser_errors.invalid_else_placement_unclosed_block(to_string(block))
: parser_errors.else_without_if_each() : parser_errors.invalid_else_placement_outside_if
); );
} }
@ -167,15 +167,15 @@ export default function mustache(parser: Parser) {
if (block.type !== 'PendingBlock') { if (block.type !== 'PendingBlock') {
parser.error( parser.error(
parser.stack.some(block => block.type === 'PendingBlock') parser.stack.some(block => block.type === 'PendingBlock')
? parser_errors.then_before_close_block(to_string(block)) ? parser_errors.invalid_then_placement_unclosed_block(to_string(block))
: parser_errors.then_without_await : parser_errors.invalid_then_placement_without_await
); );
} }
} else { } else {
if (block.type !== 'ThenBlock' && block.type !== 'PendingBlock') { if (block.type !== 'ThenBlock' && block.type !== 'PendingBlock') {
parser.error(parser.stack.some(block => block.type === 'ThenBlock' || block.type === 'PendingBlock') parser.error(parser.stack.some(block => block.type === 'ThenBlock' || block.type === 'PendingBlock')
? parser_errors.catch_before_close_block(to_string(block)) ? parser_errors.invalid_catch_placement_unclosed_block(to_string(block))
: parser_errors.catch_without_await : parser_errors.invalid_catch_placement_without_await
); );
} }
} }
@ -353,7 +353,7 @@ export default function mustache(parser: Parser) {
identifiers.forEach(node => { identifiers.forEach(node => {
if (node.type !== 'Identifier') { if (node.type !== 'Identifier') {
parser.error(parser_errors.debug_args(), node.start); parser.error(parser_errors.invalid_debug_args, node.start);
} }
}); });

@ -6,7 +6,6 @@ import { is_void } from '../../utils/names';
import { Parser } from '../index'; import { Parser } from '../index';
import { Directive, DirectiveType, TemplateNode, Text } from '../../interfaces'; import { Directive, DirectiveType, TemplateNode, Text } from '../../interfaces';
import fuzzymatch from '../../utils/fuzzymatch'; import fuzzymatch from '../../utils/fuzzymatch';
import list from '../../utils/list';
import parser_errors from '../errors'; import parser_errors from '../errors';
// eslint-disable-next-line no-useless-escape // eslint-disable-next-line no-useless-escape
@ -59,7 +58,7 @@ export default function tag(parser: Parser) {
if (parser.eat('!--')) { if (parser.eat('!--')) {
const data = parser.read_until(/-->/); const data = parser.read_until(/-->/);
parser.eat('-->', true, 'comment was left open, expected -->'); parser.eat('-->', true, parser_errors.unclosed_comment);
parser.current().children.push({ parser.current().children.push({
start, start,
@ -83,17 +82,17 @@ export default function tag(parser: Parser) {
parser.current().children.length parser.current().children.length
) { ) {
parser.error( parser.error(
parser_errors.meta_no_children(slug, name), parser_errors.invalid_element_content(slug, name),
parser.current().children[0].start parser.current().children[0].start
); );
} }
} else { } else {
if (name in parser.meta_tags) { if (name in parser.meta_tags) {
parser.error(parser_errors.meta_duplicate(slug, name), start); parser.error(parser_errors.duplicate_element(slug, name), start);
} }
if (parser.stack.length > 1) { if (parser.stack.length > 1) {
parser.error(parser_errors.meta_top_level(slug, name), start); parser.error(parser_errors.invalid_element_placement(slug, name), start);
} }
parser.meta_tags[name] = true; parser.meta_tags[name] = true;
@ -120,7 +119,7 @@ export default function tag(parser: Parser) {
if (is_closing_tag) { if (is_closing_tag) {
if (is_void(name)) { if (is_void(name)) {
parser.error(parser_errors.void_no_children(name), start); parser.error(parser_errors.invalid_void_content(name), start);
} }
parser.eat('>', true); parser.eat('>', true);
@ -129,8 +128,8 @@ export default function tag(parser: Parser) {
while (parent.name !== name) { while (parent.name !== name) {
if (parent.type !== 'Element') { if (parent.type !== 'Element') {
const error = parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name const error = parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name
? parser_errors.element_autoclosed(name, parser.last_auto_closed_tag.reason) ? parser_errors.invalid_closing_tag_autoclosed(name, parser.last_auto_closed_tag.reason)
: parser_errors.element_unopened(name); : parser_errors.invalid_closing_tag_unopened(name);
parser.error(error, start); parser.error(error, start);
} }
@ -169,12 +168,12 @@ export default function tag(parser: Parser) {
if (name === 'svelte:component') { if (name === 'svelte:component') {
const index = element.attributes.findIndex(attr => attr.type === 'Attribute' && attr.name === 'this'); const index = element.attributes.findIndex(attr => attr.type === 'Attribute' && attr.name === 'this');
if (!~index) { if (!~index) {
parser.error(parser_errors.component_definition_missing, start); parser.error(parser_errors.missing_component_definition, start);
} }
const definition = element.attributes.splice(index, 1)[0]; const definition = element.attributes.splice(index, 1)[0];
if (definition.value === true || definition.value.length !== 1 || definition.value[0].type === 'Text') { if (definition.value === true || definition.value.length !== 1 || definition.value[0].type === 'Text') {
parser.error(parser_errors.component_definition_invalid, definition.start); parser.error(parser_errors.invalid_component_definition, definition.start);
} }
element.expression = definition.value[0].expression; element.expression = definition.value[0].expression;
@ -239,7 +238,7 @@ function read_tag_name(parser: Parser) {
} }
if (!legal) { if (!legal) {
parser.error(parser_errors.self_placement_invalid, start); parser.error(parser_errors.invalid_self_placement, start);
} }
return 'svelte:self'; return 'svelte:self';
@ -257,13 +256,13 @@ function read_tag_name(parser: Parser) {
const match = fuzzymatch(name.slice(7), valid_meta_tags); const match = fuzzymatch(name.slice(7), valid_meta_tags);
parser.error( parser.error(
parser_errors.meta_tag_name_invalid(list(valid_meta_tags), match), parser_errors.invalid_tag_name_svelte_element(valid_meta_tags, match),
start start
); );
} }
if (!valid_tag_name.test(name)) { if (!valid_tag_name.test(name)) {
parser.error(parser_errors.element_tag_name_invalid, start); parser.error(parser_errors.invalid_tag_name, start);
} }
return name; return name;
@ -274,7 +273,7 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
function check_unique(name: string) { function check_unique(name: string) {
if (unique_names.has(name)) { if (unique_names.has(name)) {
parser.error(parser_errors.attribute_duplicate, start); parser.error(parser_errors.duplicate_attribute, start);
} }
unique_names.add(name); unique_names.add(name);
} }
@ -302,10 +301,7 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
parser.eat('}', true); parser.eat('}', true);
if (name === null) { if (name === null) {
parser.error({ parser.error(parser_errors.empty_attribute_shorthand, start);
code: 'empty-attribute-shorthand',
message: 'Attribute shorthand cannot be empty'
}, start);
} }
check_unique(name); check_unique(name);
@ -347,17 +343,14 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
value = read_attribute_value(parser); value = read_attribute_value(parser);
end = parser.index; end = parser.index;
} else if (parser.match_regex(/["']/)) { } else if (parser.match_regex(/["']/)) {
parser.error(parser_errors.expected_token_equal, parser.index); parser.error(parser_errors.unexpected_token('='), parser.index);
} }
if (type) { if (type) {
const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|'); const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|');
if (directive_name === '') { if (directive_name === '') {
parser.error({ parser.error(parser_errors.empty_directive_name(type), start + colon_index + 1);
code: 'empty-directive-name',
message: `${type} name cannot be empty`
}, start + colon_index + 1);
} }
if (type === 'Binding' && directive_name !== 'this') { if (type === 'Binding' && directive_name !== 'this') {
@ -367,12 +360,12 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
} }
if (type === 'Ref') { if (type === 'Ref') {
parser.error(parser_errors.ref_directive_invalid(directive_name), start); parser.error(parser_errors.invalid_ref_directive(directive_name), start);
} }
if (value[0]) { if (value[0]) {
if ((value as any[]).length > 1 || value[0].type === 'Text') { if ((value as any[]).length > 1 || value[0].type === 'Text') {
parser.error(parser_errors.directive_value_invalid, value[0].start); parser.error(parser_errors.invalid_directive_value, value[0].start);
} }
} }

@ -1,5 +1,5 @@
{ {
"code": "unexpected-eof", "code": "unclosed-comment",
"message": "comment was left open, expected -->", "message": "comment was left open, expected -->",
"start": { "start": {
"line": 1, "line": 1,

Loading…
Cancel
Save