|
|
|
@ -17,7 +17,12 @@ const meta_tags = new Map([
|
|
|
|
['svelte:document', 'Document'],
|
|
|
|
['svelte:document', 'Document'],
|
|
|
|
['svelte:body', 'Body']
|
|
|
|
['svelte:body', 'Body']
|
|
|
|
]);
|
|
|
|
]);
|
|
|
|
const valid_meta_tags = Array.from(meta_tags.keys()).concat('svelte:self', 'svelte:component', 'svelte:fragment', 'svelte:element');
|
|
|
|
const valid_meta_tags = Array.from(meta_tags.keys()).concat(
|
|
|
|
|
|
|
|
'svelte:self',
|
|
|
|
|
|
|
|
'svelte:component',
|
|
|
|
|
|
|
|
'svelte:fragment',
|
|
|
|
|
|
|
|
'svelte:element'
|
|
|
|
|
|
|
|
);
|
|
|
|
const specials = new Map([
|
|
|
|
const specials = new Map([
|
|
|
|
[
|
|
|
|
[
|
|
|
|
'script',
|
|
|
|
'script',
|
|
|
|
@ -42,10 +47,8 @@ function parent_is_head(stack) {
|
|
|
|
let i = stack.length;
|
|
|
|
let i = stack.length;
|
|
|
|
while (i--) {
|
|
|
|
while (i--) {
|
|
|
|
const { type } = stack[i];
|
|
|
|
const { type } = stack[i];
|
|
|
|
if (type === 'Head')
|
|
|
|
if (type === 'Head') return true;
|
|
|
|
return true;
|
|
|
|
if (type === 'Element' || type === 'InlineComponent') return false;
|
|
|
|
if (type === 'Element' || type === 'InlineComponent')
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -76,12 +79,16 @@ export default function tag(parser) {
|
|
|
|
if (meta_tags.has(name)) {
|
|
|
|
if (meta_tags.has(name)) {
|
|
|
|
const slug = meta_tags.get(name).toLowerCase();
|
|
|
|
const slug = meta_tags.get(name).toLowerCase();
|
|
|
|
if (is_closing_tag) {
|
|
|
|
if (is_closing_tag) {
|
|
|
|
if ((name === 'svelte:window' || name === 'svelte:body') &&
|
|
|
|
if (
|
|
|
|
parser.current().children.length) {
|
|
|
|
(name === 'svelte:window' || name === 'svelte:body') &&
|
|
|
|
parser.error(parser_errors.invalid_element_content(slug, name), parser.current().children[0].start);
|
|
|
|
parser.current().children.length
|
|
|
|
}
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
parser.error(
|
|
|
|
else {
|
|
|
|
parser_errors.invalid_element_content(slug, name),
|
|
|
|
|
|
|
|
parser.current().children[0].start
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (name in parser.meta_tags) {
|
|
|
|
if (name in parser.meta_tags) {
|
|
|
|
parser.error(parser_errors.duplicate_element(slug, name), start);
|
|
|
|
parser.error(parser_errors.duplicate_element(slug, name), start);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -123,7 +130,8 @@ export default function tag(parser) {
|
|
|
|
// close any elements that don't have their own closing tags, e.g. <div><p></div>
|
|
|
|
// close any elements that don't have their own closing tags, e.g. <div><p></div>
|
|
|
|
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.invalid_closing_tag_autoclosed(name, parser.last_auto_closed_tag.reason)
|
|
|
|
? parser_errors.invalid_closing_tag_autoclosed(name, parser.last_auto_closed_tag.reason)
|
|
|
|
: parser_errors.invalid_closing_tag_unopened(name);
|
|
|
|
: parser_errors.invalid_closing_tag_unopened(name);
|
|
|
|
parser.error(error, start);
|
|
|
|
parser.error(error, start);
|
|
|
|
@ -138,8 +146,7 @@ export default function tag(parser) {
|
|
|
|
parser.last_auto_closed_tag = null;
|
|
|
|
parser.last_auto_closed_tag = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (closing_tag_omitted(parent.name, name)) {
|
|
|
|
else if (closing_tag_omitted(parent.name, name)) {
|
|
|
|
|
|
|
|
parent.end = start;
|
|
|
|
parent.end = start;
|
|
|
|
parser.stack.pop();
|
|
|
|
parser.stack.pop();
|
|
|
|
parser.last_auto_closed_tag = {
|
|
|
|
parser.last_auto_closed_tag = {
|
|
|
|
@ -159,20 +166,26 @@ export default function tag(parser) {
|
|
|
|
parser.allow_whitespace();
|
|
|
|
parser.allow_whitespace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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 === -1) {
|
|
|
|
if (index === -1) {
|
|
|
|
parser.error(parser_errors.missing_component_definition, 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 ||
|
|
|
|
if (
|
|
|
|
|
|
|
|
definition.value === true ||
|
|
|
|
definition.value.length !== 1 ||
|
|
|
|
definition.value.length !== 1 ||
|
|
|
|
definition.value[0].type === 'Text') {
|
|
|
|
definition.value[0].type === 'Text'
|
|
|
|
|
|
|
|
) {
|
|
|
|
parser.error(parser_errors.invalid_component_definition, definition.start);
|
|
|
|
parser.error(parser_errors.invalid_component_definition, definition.start);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
element.expression = definition.value[0].expression;
|
|
|
|
element.expression = definition.value[0].expression;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (name === 'svelte:element') {
|
|
|
|
if (name === 'svelte:element') {
|
|
|
|
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 === -1) {
|
|
|
|
if (index === -1) {
|
|
|
|
parser.error(parser_errors.missing_element_definition, start);
|
|
|
|
parser.error(parser_errors.missing_element_definition, start);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -187,8 +200,7 @@ export default function tag(parser) {
|
|
|
|
const special = specials.get(name);
|
|
|
|
const special = specials.get(name);
|
|
|
|
parser.eat('>', true);
|
|
|
|
parser.eat('>', true);
|
|
|
|
const content = special.read(parser, start, element.attributes);
|
|
|
|
const content = special.read(parser, start, element.attributes);
|
|
|
|
if (content)
|
|
|
|
if (content) parser[special.property].push(content);
|
|
|
|
parser[special.property].push(content);
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parser.current().children.push(element);
|
|
|
|
parser.current().children.push(element);
|
|
|
|
@ -197,14 +209,16 @@ export default function tag(parser) {
|
|
|
|
if (self_closing) {
|
|
|
|
if (self_closing) {
|
|
|
|
// don't push self-closing elements onto the stack
|
|
|
|
// don't push self-closing elements onto the stack
|
|
|
|
element.end = parser.index;
|
|
|
|
element.end = parser.index;
|
|
|
|
}
|
|
|
|
} else if (name === 'textarea') {
|
|
|
|
else if (name === 'textarea') {
|
|
|
|
|
|
|
|
// special case
|
|
|
|
// special case
|
|
|
|
element.children = read_sequence(parser, () => regex_closing_textarea_tag.test(parser.template.slice(parser.index)), 'inside <textarea>');
|
|
|
|
element.children = read_sequence(
|
|
|
|
|
|
|
|
parser,
|
|
|
|
|
|
|
|
() => regex_closing_textarea_tag.test(parser.template.slice(parser.index)),
|
|
|
|
|
|
|
|
'inside <textarea>'
|
|
|
|
|
|
|
|
);
|
|
|
|
parser.read(regex_closing_textarea_tag);
|
|
|
|
parser.read(regex_closing_textarea_tag);
|
|
|
|
element.end = parser.index;
|
|
|
|
element.end = parser.index;
|
|
|
|
}
|
|
|
|
} else if (name === 'script' || name === 'style') {
|
|
|
|
else if (name === 'script' || name === 'style') {
|
|
|
|
|
|
|
|
// special case
|
|
|
|
// special case
|
|
|
|
const start = parser.index;
|
|
|
|
const start = parser.index;
|
|
|
|
const data = parser.read_until(new RegExp(`</${name}>`));
|
|
|
|
const data = parser.read_until(new RegExp(`</${name}>`));
|
|
|
|
@ -212,8 +226,7 @@ export default function tag(parser) {
|
|
|
|
element.children.push({ start, end, type: 'Text', data });
|
|
|
|
element.children.push({ start, end, type: 'Text', data });
|
|
|
|
parser.eat(`</${name}>`, true);
|
|
|
|
parser.eat(`</${name}>`, true);
|
|
|
|
element.end = parser.index;
|
|
|
|
element.end = parser.index;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
else {
|
|
|
|
|
|
|
|
parser.stack.push(element);
|
|
|
|
parser.stack.push(element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -231,9 +244,11 @@ function read_tag_name(parser) {
|
|
|
|
let legal = false;
|
|
|
|
let legal = false;
|
|
|
|
while (i--) {
|
|
|
|
while (i--) {
|
|
|
|
const fragment = parser.stack[i];
|
|
|
|
const fragment = parser.stack[i];
|
|
|
|
if (fragment.type === 'IfBlock' ||
|
|
|
|
if (
|
|
|
|
|
|
|
|
fragment.type === 'IfBlock' ||
|
|
|
|
fragment.type === 'EachBlock' ||
|
|
|
|
fragment.type === 'EachBlock' ||
|
|
|
|
fragment.type === 'InlineComponent') {
|
|
|
|
fragment.type === 'InlineComponent'
|
|
|
|
|
|
|
|
) {
|
|
|
|
legal = true;
|
|
|
|
legal = true;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -243,15 +258,11 @@ function read_tag_name(parser) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 'svelte:self';
|
|
|
|
return 'svelte:self';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (parser.read(COMPONENT))
|
|
|
|
if (parser.read(COMPONENT)) return 'svelte:component';
|
|
|
|
return 'svelte:component';
|
|
|
|
if (parser.read(ELEMENT)) return 'svelte:element';
|
|
|
|
if (parser.read(ELEMENT))
|
|
|
|
if (parser.read(SLOT)) return 'svelte:fragment';
|
|
|
|
return 'svelte:element';
|
|
|
|
|
|
|
|
if (parser.read(SLOT))
|
|
|
|
|
|
|
|
return 'svelte:fragment';
|
|
|
|
|
|
|
|
const name = parser.read_until(regex_whitespace_or_slash_or_closing_tag);
|
|
|
|
const name = parser.read_until(regex_whitespace_or_slash_or_closing_tag);
|
|
|
|
if (meta_tags.has(name))
|
|
|
|
if (meta_tags.has(name)) return name;
|
|
|
|
return name;
|
|
|
|
|
|
|
|
if (name.startsWith('svelte:')) {
|
|
|
|
if (name.startsWith('svelte:')) {
|
|
|
|
const match = fuzzymatch(name.slice(7), valid_meta_tags);
|
|
|
|
const match = fuzzymatch(name.slice(7), valid_meta_tags);
|
|
|
|
parser.error(parser_errors.invalid_tag_name_svelte_element(valid_meta_tags, match), start);
|
|
|
|
parser.error(parser_errors.invalid_tag_name_svelte_element(valid_meta_tags, match), start);
|
|
|
|
@ -293,8 +304,7 @@ function read_attribute(parser, unique_names) {
|
|
|
|
type: 'Spread',
|
|
|
|
type: 'Spread',
|
|
|
|
expression
|
|
|
|
expression
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
else {
|
|
|
|
|
|
|
|
const value_start = parser.index;
|
|
|
|
const value_start = parser.index;
|
|
|
|
const name = parser.read_identifier();
|
|
|
|
const name = parser.read_identifier();
|
|
|
|
parser.allow_whitespace();
|
|
|
|
parser.allow_whitespace();
|
|
|
|
@ -325,8 +335,7 @@ function read_attribute(parser, unique_names) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const name = parser.read_until(regex_token_ending_character);
|
|
|
|
const name = parser.read_until(regex_token_ending_character);
|
|
|
|
if (!name)
|
|
|
|
if (!name) return null;
|
|
|
|
return null;
|
|
|
|
|
|
|
|
let end = parser.index;
|
|
|
|
let end = parser.index;
|
|
|
|
parser.allow_whitespace();
|
|
|
|
parser.allow_whitespace();
|
|
|
|
const colon_index = name.indexOf(':');
|
|
|
|
const colon_index = name.indexOf(':');
|
|
|
|
@ -340,8 +349,7 @@ function read_attribute(parser, unique_names) {
|
|
|
|
parser.allow_whitespace();
|
|
|
|
parser.allow_whitespace();
|
|
|
|
value = read_attribute_value(parser);
|
|
|
|
value = read_attribute_value(parser);
|
|
|
|
end = parser.index;
|
|
|
|
end = parser.index;
|
|
|
|
}
|
|
|
|
} else if (parser.match_regex(regex_starts_with_quote_characters)) {
|
|
|
|
else if (parser.match_regex(regex_starts_with_quote_characters)) {
|
|
|
|
|
|
|
|
parser.error(parser_errors.unexpected_token('='), parser.index);
|
|
|
|
parser.error(parser_errors.unexpected_token('='), parser.index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (type) {
|
|
|
|
if (type) {
|
|
|
|
@ -351,8 +359,7 @@ function read_attribute(parser, unique_names) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (type === 'Binding' && directive_name !== 'this') {
|
|
|
|
if (type === 'Binding' && directive_name !== 'this') {
|
|
|
|
check_unique(directive_name);
|
|
|
|
check_unique(directive_name);
|
|
|
|
}
|
|
|
|
} else if (type !== 'EventHandler' && type !== 'Action') {
|
|
|
|
else if (type !== 'EventHandler' && type !== 'Action') {
|
|
|
|
|
|
|
|
check_unique(name);
|
|
|
|
check_unique(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (type === 'Ref') {
|
|
|
|
if (type === 'Ref') {
|
|
|
|
@ -374,8 +381,7 @@ function read_attribute(parser, unique_names) {
|
|
|
|
const attribute_contains_text = value.length > 1 || first_value.type === 'Text';
|
|
|
|
const attribute_contains_text = value.length > 1 || first_value.type === 'Text';
|
|
|
|
if (attribute_contains_text) {
|
|
|
|
if (attribute_contains_text) {
|
|
|
|
parser.error(parser_errors.invalid_directive_value, first_value.start);
|
|
|
|
parser.error(parser_errors.invalid_directive_value, first_value.start);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
else {
|
|
|
|
|
|
|
|
expression = first_value.expression;
|
|
|
|
expression = first_value.expression;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -418,24 +424,15 @@ function read_attribute(parser, unique_names) {
|
|
|
|
* @returns {DirectiveType}
|
|
|
|
* @returns {DirectiveType}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
function get_directive_type(name) {
|
|
|
|
function get_directive_type(name) {
|
|
|
|
if (name === 'use')
|
|
|
|
if (name === 'use') return 'Action';
|
|
|
|
return 'Action';
|
|
|
|
if (name === 'animate') return 'Animation';
|
|
|
|
if (name === 'animate')
|
|
|
|
if (name === 'bind') return 'Binding';
|
|
|
|
return 'Animation';
|
|
|
|
if (name === 'class') return 'Class';
|
|
|
|
if (name === 'bind')
|
|
|
|
if (name === 'style') return 'StyleDirective';
|
|
|
|
return 'Binding';
|
|
|
|
if (name === 'on') return 'EventHandler';
|
|
|
|
if (name === 'class')
|
|
|
|
if (name === 'let') return 'Let';
|
|
|
|
return 'Class';
|
|
|
|
if (name === 'ref') return 'Ref';
|
|
|
|
if (name === 'style')
|
|
|
|
if (name === 'in' || name === 'out' || name === 'transition') return 'Transition';
|
|
|
|
return 'StyleDirective';
|
|
|
|
|
|
|
|
if (name === 'on')
|
|
|
|
|
|
|
|
return 'EventHandler';
|
|
|
|
|
|
|
|
if (name === 'let')
|
|
|
|
|
|
|
|
return 'Let';
|
|
|
|
|
|
|
|
if (name === 'ref')
|
|
|
|
|
|
|
|
return 'Ref';
|
|
|
|
|
|
|
|
if (name === 'in' || name === 'out' || name === 'transition')
|
|
|
|
|
|
|
|
return 'Transition';
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
@ -456,14 +453,16 @@ function read_attribute_value(parser) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let value;
|
|
|
|
let value;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
value = read_sequence(parser, () => {
|
|
|
|
value = read_sequence(
|
|
|
|
|
|
|
|
parser,
|
|
|
|
|
|
|
|
() => {
|
|
|
|
// handle common case of quote marks existing outside of regex for performance reasons
|
|
|
|
// handle common case of quote marks existing outside of regex for performance reasons
|
|
|
|
if (quote_mark)
|
|
|
|
if (quote_mark) return parser.match(quote_mark);
|
|
|
|
return parser.match(quote_mark);
|
|
|
|
|
|
|
|
return !!parser.match_regex(regex_starts_with_invalid_attr_value);
|
|
|
|
return !!parser.match_regex(regex_starts_with_invalid_attr_value);
|
|
|
|
}, 'in attribute value');
|
|
|
|
},
|
|
|
|
}
|
|
|
|
'in attribute value'
|
|
|
|
catch (error) {
|
|
|
|
);
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
if (error.code === 'parse-error') {
|
|
|
|
if (error.code === 'parse-error') {
|
|
|
|
// if the attribute value didn't close + self-closing tag
|
|
|
|
// if the attribute value didn't close + self-closing tag
|
|
|
|
// eg: `<Component test={{a:1} />`
|
|
|
|
// eg: `<Component test={{a:1} />`
|
|
|
|
@ -478,8 +477,7 @@ function read_attribute_value(parser) {
|
|
|
|
if (value.length === 0 && !quote_mark) {
|
|
|
|
if (value.length === 0 && !quote_mark) {
|
|
|
|
parser.error(parser_errors.missing_attribute_value);
|
|
|
|
parser.error(parser_errors.missing_attribute_value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (quote_mark)
|
|
|
|
if (quote_mark) parser.index += 1;
|
|
|
|
parser.index += 1;
|
|
|
|
|
|
|
|
return value;
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -490,7 +488,6 @@ function read_attribute_value(parser) {
|
|
|
|
* @returns {TemplateNode[]}
|
|
|
|
* @returns {TemplateNode[]}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
function read_sequence(parser, done, location) {
|
|
|
|
function read_sequence(parser, done, location) {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @type {Text}
|
|
|
|
* @type {Text}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
@ -522,15 +519,13 @@ function read_sequence(parser, done, location) {
|
|
|
|
if (done()) {
|
|
|
|
if (done()) {
|
|
|
|
flush(parser.index);
|
|
|
|
flush(parser.index);
|
|
|
|
return chunks;
|
|
|
|
return chunks;
|
|
|
|
}
|
|
|
|
} else if (parser.eat('{')) {
|
|
|
|
else if (parser.eat('{')) {
|
|
|
|
|
|
|
|
if (parser.match('#')) {
|
|
|
|
if (parser.match('#')) {
|
|
|
|
const index = parser.index - 1;
|
|
|
|
const index = parser.index - 1;
|
|
|
|
parser.eat('#');
|
|
|
|
parser.eat('#');
|
|
|
|
const name = parser.read_until(/[^a-z]/);
|
|
|
|
const name = parser.read_until(/[^a-z]/);
|
|
|
|
parser.error(parser_errors.invalid_logic_block_placement(location, name), index);
|
|
|
|
parser.error(parser_errors.invalid_logic_block_placement(location, name), index);
|
|
|
|
}
|
|
|
|
} else if (parser.match('@')) {
|
|
|
|
else if (parser.match('@')) {
|
|
|
|
|
|
|
|
const index = parser.index - 1;
|
|
|
|
const index = parser.index - 1;
|
|
|
|
parser.eat('@');
|
|
|
|
parser.eat('@');
|
|
|
|
const name = parser.read_until(/[^a-z]/);
|
|
|
|
const name = parser.read_until(/[^a-z]/);
|
|
|
|
@ -554,14 +549,9 @@ function read_sequence(parser, done, location) {
|
|
|
|
raw: '',
|
|
|
|
raw: '',
|
|
|
|
data: null
|
|
|
|
data: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
else {
|
|
|
|
|
|
|
|
current_chunk.raw += parser.template[parser.index++];
|
|
|
|
current_chunk.raw += parser.template[parser.index++];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parser.error(parser_errors.unexpected_eof);
|
|
|
|
parser.error(parser_errors.unexpected_eof);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|