do a bunch of easy ones by hand

pull/8569/head
Simon Holthausen 3 years ago
parent 4b3cacf3b9
commit 561ecf28ff

@ -1,5 +1,6 @@
// 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.js'; import list from '../utils/list.js';
/** /**
* @internal * @internal
*/ */

@ -6,7 +6,7 @@ import full_char_code_at from '../utils/full_char_code_at';
import error from '../utils/error'; import error from '../utils/error';
import parser_errors from './errors'; import parser_errors from './errors';
const regex_position_indicator = / \(\d+:\d+\)$/; const regex_position_indicator = / \(\d+:\d+\)$/;
/** */
export class Parser { export class Parser {
/** /**
* @readonly * @readonly
@ -32,39 +32,39 @@ export class Parser {
*/ */
css_mode = undefined; css_mode = undefined;
/**
* @default 0 */
index = 0; index = 0;
/** /**
* @default [] * @type {import('../interfaces.js').TemplateNode[]}
* @type {TemplateNode[]}
*/ */
stack = []; stack = [];
/** /**
* @type {Fragment} */ * @type {import('../interfaces.js').Fragment}
*/
html = undefined; html = undefined;
/** /**
* @default [] * @type {import('../interfaces.js').Style[]}
* @type {Style[]}
*/ */
css = []; css = [];
/** /**
* @default [] * @type {import('../interfaces.js').Script[]}
* @type {Script[]}
*/ */
js = []; js = [];
/**
* @default {} */
meta_tags = {}; meta_tags = {};
/** /**
* @type {LastAutoClosedTag} */ * @type {LastAutoClosedTag}
*/
last_auto_closed_tag = undefined; last_auto_closed_tag = undefined;
/**
* @param {string} template
* @param {import('../interfaces.js').ParserOptions} options
*/
constructor(template, options) { constructor(template, options) {
if (typeof template !== 'string') { if (typeof template !== 'string') {
throw new TypeError('Template must be a string'); throw new TypeError('Template must be a string');
@ -80,6 +80,7 @@ export class Parser {
children: [] children: []
}; };
this.stack.push(this.html); this.stack.push(this.html);
/** @type {ParserState} */
let state = fragment; let state = fragment;
while (this.index < this.template.length) { while (this.index < this.template.length) {
state = state(this) || fragment; state = state(this) || fragment;
@ -118,7 +119,8 @@ export class Parser {
} }
/** /**
* @param {any} err */ * @param {any} err
*/
acorn_error(err) { acorn_error(err) {
this.error( this.error(
{ {
@ -130,7 +132,8 @@ export class Parser {
} }
/** /**
* @param {{ code: string; message: string }} */ * @param {{ code: string; message: string }} err
*/
error({ code, message }, index = this.index) { error({ code, message }, index = this.index) {
error(message, { error(message, {
name: 'ParseError', name: 'ParseError',
@ -143,8 +146,8 @@ export class Parser {
/** /**
* @param {string} str * @param {string} str
* @param {boolean} required * @param {boolean} [required]
* @param {{ code: string; message: string }} error * @param {{ code: string; message: string }} [error]
*/ */
eat(str, required, error) { eat(str, required, error) {
if (this.match(str)) { if (this.match(str)) {
@ -163,7 +166,8 @@ export class Parser {
} }
/** /**
* @param {string} str */ * @param {string} str
*/
match(str) { match(str) {
return this.template.slice(this.index, this.index + str.length) === str; return this.template.slice(this.index, this.index + str.length) === str;
} }
@ -216,7 +220,7 @@ export class Parser {
/** /**
* @param {RegExp} pattern * @param {RegExp} pattern
* @param {Parameters<Parser['error']>[0]} error_message * @param {Parameters<Parser['error']>[0]} [error_message]
*/ */
read_until(pattern, error_message) { read_until(pattern, error_message) {
if (this.index >= this.template.length) { if (this.index >= this.template.length) {
@ -249,8 +253,8 @@ export class Parser {
/** /**
* @param {string} template * @param {string} template
* @param {ParserOptions} options * @param {import('../interfaces.js').ParserOptions} options
* @returns {Ast} * @returns {import('../interfaces.js').Ast}
*/ */
export default function parse(template, options = {}) { export default function parse(template, options = {}) {
const parser = new Parser(template, options); const parser = new Parser(template, options);
@ -275,9 +279,14 @@ export default function parse(template, options = {}) {
}; };
} }
/** @typedef {(parser: Parser) => ParserState | void} ParserState */ /**
* @internal
* @typedef {(parser: Parser) => ParserState | void} ParserState
*/
/** @typedef {Object} LastAutoClosedTag /**
* @internal
* @typedef {Object} LastAutoClosedTag
* @property {string} tag * @property {string} tag
* @property {string} reason * @property {string} reason
* @property {number} depth * @property {number} depth

@ -1,18 +1,20 @@
import { Parser } from '../index';
import { isIdentifierStart } from 'acorn'; import { isIdentifierStart } from 'acorn';
import full_char_code_at from '../../utils/full_char_code_at'; import full_char_code_at from '../../utils/full_char_code_at.js';
import { import {
is_bracket_open, is_bracket_open,
is_bracket_close, is_bracket_close,
is_bracket_pair, is_bracket_pair,
get_bracket_close get_bracket_close
} from '../utils/bracket'; } from '../utils/bracket.js';
import { parse_expression_at } from '../acorn'; import { parse_expression_at } from '../acorn.js';
import { Pattern } from 'estree'; import parser_errors from '../errors.js';
import parser_errors from '../errors'; import { regex_not_newline_characters } from '../../utils/patterns.js';
import { regex_not_newline_characters } from '../../utils/patterns';
export default function read_context(parser: Parser): Pattern & { start: number; end: number } { /**
* @param {import('../index.js').Parser} parser
* @returns {Pattern & { start: number; end: number }}
*/
export default function read_context(parser) {
const start = parser.index; const start = parser.index;
let i = parser.index; let i = parser.index;

@ -1,10 +1,12 @@
import { parse_expression_at } from '../acorn'; import { parse_expression_at } from '../acorn.js';
import { Parser } from '../index'; import { regex_whitespace } from '../../utils/patterns.js';
import { Node } from 'estree'; import parser_errors from '../errors.js';
import { regex_whitespace } from '../../utils/patterns';
import parser_errors from '../errors'; /**
* @param {import('../index.js').Parser} parser
export default function read_expression(parser: Parser): Node { * @returns {import('estree').Node | undefined}
*/
export default function read_expression(parser) {
try { try {
const node = parse_expression_at(parser.template, parser.index); const node = parse_expression_at(parser.template, parser.index);
@ -29,7 +31,7 @@ export default function read_expression(parser: Parser): Node {
parser.index = index; parser.index = index;
return node as Node; return node;
} catch (err) { } catch (err) {
parser.acorn_error(err); parser.acorn_error(err);
} }

@ -0,0 +1,18 @@
import tag from './tag.js';
import mustache from './mustache.js';
import text from './text.js';
/**
* @param {import('../index.js').Parser} parser
*/
export default function fragment(parser) {
if (parser.match('<')) {
return tag;
}
if (parser.match('{')) {
return mustache;
}
return text;
}

@ -1,16 +0,0 @@
import tag from './tag';
import mustache from './mustache';
import text from './text';
import { Parser } from '../index';
export default function fragment(parser: Parser) {
if (parser.match('<')) {
return tag;
}
if (parser.match('{')) {
return mustache;
}
return text;
}

@ -1,7 +1,9 @@
import { decode_character_references } from '../utils/html'; import { decode_character_references } from '../utils/html.js';
import { Parser } from '../index';
export default function text(parser: Parser) { /**
* @param {import('../index.js').Parser} parser
*/
export default function text(parser) {
const start = parser.index; const start = parser.index;
let data = ''; let data = '';

@ -1,6 +1,7 @@
import { TemplateNode } from '../../interfaces'; /**
* @param {import("../../interfaces.js").TemplateNode} node
export function to_string(node: TemplateNode) { */
export function to_string(node) {
switch (node.type) { switch (node.type) {
case 'IfBlock': case 'IfBlock':
return '{#if} block'; return '{#if} block';
Loading…
Cancel
Save