From 63075603f3bc62dd0e09b79c90ffade585df2da8 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sun, 17 Mar 2019 21:46:37 -0400 Subject: [PATCH] more tidying up --- src/compile/nodes/EachBlock.ts | 23 ++- src/compile/render-dom/wrappers/Fragment.ts | 6 +- src/interfaces.ts | 2 +- src/parse/acorn.ts | 2 +- src/parse/index.ts | 23 ++- src/parse/read/context.ts | 28 ++-- src/parse/read/expression.ts | 10 +- src/parse/read/script.ts | 18 +-- src/parse/read/style.ts | 18 +-- src/parse/state/mustache.ts | 140 ++++++++-------- src/parse/state/tag.ts | 167 +++++++++----------- src/parse/state/text.ts | 4 +- src/parse/utils/html.ts | 21 +-- src/preprocess/index.ts | 10 +- src/utils/trim.ts | 4 +- src/utils/unpackDestructuring.ts | 22 --- 16 files changed, 235 insertions(+), 263 deletions(-) delete mode 100644 src/utils/unpackDestructuring.ts diff --git a/src/compile/nodes/EachBlock.ts b/src/compile/nodes/EachBlock.ts index 5ea1d5e033..fa095031a3 100644 --- a/src/compile/nodes/EachBlock.ts +++ b/src/compile/nodes/EachBlock.ts @@ -4,7 +4,26 @@ import Block from '../render-dom/Block'; import Expression from './shared/Expression'; import mapChildren from './shared/mapChildren'; import TemplateScope from './shared/TemplateScope'; -import unpackDestructuring from '../../utils/unpackDestructuring'; +import { Node as INode } from '../../interfaces'; + +function unpack_destructuring(contexts: Array<{ name: string, tail: string }>, node: INode, tail: string) { + if (!node) return; + + if (node.type === 'Identifier') { + contexts.push({ + key: node, + tail + }); + } else if (node.type === 'ArrayPattern') { + node.elements.forEach((element, i) => { + unpack_destructuring(contexts, element, `${tail}[${i}]`); + }); + } else if (node.type === 'ObjectPattern') { + node.properties.forEach((property) => { + unpack_destructuring(contexts, property.value, `${tail}.${property.key.name}`); + }); + } +} export default class EachBlock extends Node { type: 'EachBlock'; @@ -36,7 +55,7 @@ export default class EachBlock extends Node { this.scope = scope.child(); this.contexts = []; - unpackDestructuring(this.contexts, info.context, ''); + unpack_destructuring(this.contexts, info.context, ''); this.contexts.forEach(context => { this.scope.add(context.key.name, this.expression.dependencies, this); diff --git a/src/compile/render-dom/wrappers/Fragment.ts b/src/compile/render-dom/wrappers/Fragment.ts index ef16d4e2aa..dc39eeeb41 100644 --- a/src/compile/render-dom/wrappers/Fragment.ts +++ b/src/compile/render-dom/wrappers/Fragment.ts @@ -14,7 +14,7 @@ import Text from './Text'; import Title from './Title'; import Window from './Window'; import Node from '../../nodes/shared/Node'; -import { trimStart, trimEnd } from '../../../utils/trim'; +import { trim_start, trim_end } from '../../../utils/trim'; import TextWrapper from './Text'; import Renderer from '../Renderer'; import Block from '../Block'; @@ -89,7 +89,7 @@ export default class FragmentWrapper { ); if (shouldTrim) { - data = trimEnd(data); + data = trim_end(data); if (!data) continue; } } @@ -121,7 +121,7 @@ export default class FragmentWrapper { const first = this.nodes[0] as TextWrapper; if (first && first.node.type === 'Text') { - first.data = trimStart(first.data); + first.data = trim_start(first.data); if (!first.data) { first.var = null; this.nodes.shift(); diff --git a/src/interfaces.ts b/src/interfaces.ts index 1fe7673fc6..7480792e09 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -15,7 +15,7 @@ export interface Parser { html: Node; css: Node; js: Node; - metaTags: {}; + meta_tags: {}; } export interface Ast { diff --git a/src/parse/acorn.ts b/src/parse/acorn.ts index cfb3cdbfbd..a93418f4cb 100644 --- a/src/parse/acorn.ts +++ b/src/parse/acorn.ts @@ -9,7 +9,7 @@ export const parse = (source: string) => Parser.parse(source, { preserveParens: true }); -export const parseExpressionAt = (source: string, index: number) => Parser.parseExpressionAt(source, index, { +export const parse_expression_at = (source: string, index: number) => Parser.parseExpressionAt(source, index, { ecmaVersion: 9, preserveParens: true }); \ No newline at end of file diff --git a/src/parse/index.ts b/src/parse/index.ts index 8419b41e31..39c6972213 100644 --- a/src/parse/index.ts +++ b/src/parse/index.ts @@ -8,7 +8,6 @@ import error from '../utils/error'; interface ParserOptions { filename?: string; - bind?: boolean; customElement?: boolean; } @@ -25,9 +24,7 @@ export class Parser { html: Node; css: Node[] = []; js: Node[] = []; - metaTags = {}; - - allowBindings: boolean; + meta_tags = {}; constructor(template: string, options: ParserOptions) { if (typeof template !== 'string') { @@ -38,8 +35,6 @@ export class Parser { this.filename = options.filename; this.customElement = options.customElement; - this.allowBindings = options.bind !== false; - this.html = { start: null, end: null, @@ -92,7 +87,7 @@ export class Parser { return this.stack[this.stack.length - 1]; } - acornError(err: any) { + acorn_error(err: any) { this.error({ code: `parse-error`, message: err.message.replace(/ \(\d+:\d+\)$/, '') @@ -129,14 +124,14 @@ export class Parser { return this.template.slice(this.index, this.index + str.length) === str; } - matchRegex(pattern: RegExp) { + match_regex(pattern: RegExp) { const match = pattern.exec(this.template.slice(this.index)); if (!match || match.index !== 0) return null; return match[0]; } - allowWhitespace() { + allow_whitespace() { while ( this.index < this.template.length && whitespace.test(this.template[this.index]) @@ -146,12 +141,12 @@ export class Parser { } read(pattern: RegExp) { - const result = this.matchRegex(pattern); + const result = this.match_regex(pattern); if (result) this.index += result.length; return result; } - readIdentifier() { + read_identifier() { const start = this.index; let i = this.index; @@ -180,7 +175,7 @@ export class Parser { return identifier; } - readUntil(pattern: RegExp) { + read_until(pattern: RegExp) { if (this.index >= this.template.length) this.error({ code: `unexpected-eof`, @@ -199,7 +194,7 @@ export class Parser { return this.template.slice(start); } - requireWhitespace() { + require_whitespace() { if (!whitespace.test(this.template[this.index])) { this.error({ code: `missing-whitespace`, @@ -207,7 +202,7 @@ export class Parser { }); } - this.allowWhitespace(); + this.allow_whitespace(); } } diff --git a/src/parse/read/context.ts b/src/parse/read/context.ts index e5e1f1ee6c..cece1c42d6 100644 --- a/src/parse/read/context.ts +++ b/src/parse/read/context.ts @@ -26,7 +26,7 @@ type Context = { properties?: Property[]; } -function errorOnAssignmentPattern(parser: Parser) { +function error_on_assignment_pattern(parser: Parser) { if (parser.eat('=')) { parser.error({ code: 'invalid-assignment-pattern', @@ -35,7 +35,7 @@ function errorOnAssignmentPattern(parser: Parser) { } } -export default function readContext(parser: Parser) { +export default function read_context(parser: Parser) { const context: Context = { start: parser.index, end: null, @@ -47,17 +47,17 @@ export default function readContext(parser: Parser) { context.elements = []; do { - parser.allowWhitespace(); + parser.allow_whitespace(); if (parser.template[parser.index] === ',') { context.elements.push(null); } else { - context.elements.push(readContext(parser)); - parser.allowWhitespace(); + context.elements.push(read_context(parser)); + parser.allow_whitespace(); } } while (parser.eat(',')); - errorOnAssignmentPattern(parser); + error_on_assignment_pattern(parser); parser.eat(']', true); context.end = parser.index; } @@ -67,20 +67,20 @@ export default function readContext(parser: Parser) { context.properties = []; do { - parser.allowWhitespace(); + parser.allow_whitespace(); const start = parser.index; - const name = parser.readIdentifier(); + const name = parser.read_identifier(); const key: Identifier = { start, end: parser.index, type: 'Identifier', name }; - parser.allowWhitespace(); + parser.allow_whitespace(); const value = parser.eat(':') - ? (parser.allowWhitespace(), readContext(parser)) + ? (parser.allow_whitespace(), read_context(parser)) : key; const property: Property = { @@ -95,16 +95,16 @@ export default function readContext(parser: Parser) { context.properties.push(property); - parser.allowWhitespace(); + parser.allow_whitespace(); } while (parser.eat(',')); - errorOnAssignmentPattern(parser); + error_on_assignment_pattern(parser); parser.eat('}', true); context.end = parser.index; } else { - const name = parser.readIdentifier(); + const name = parser.read_identifier(); if (name) { context.type = 'Identifier'; context.end = parser.index; @@ -118,7 +118,7 @@ export default function readContext(parser: Parser) { }); } - errorOnAssignmentPattern(parser); + error_on_assignment_pattern(parser); } return context; diff --git a/src/parse/read/expression.ts b/src/parse/read/expression.ts index 3bfad75e6a..4d1de89fe7 100644 --- a/src/parse/read/expression.ts +++ b/src/parse/read/expression.ts @@ -1,12 +1,12 @@ -import { parseExpressionAt } from '../acorn'; +import { parse_expression_at } from '../acorn'; import { Parser } from '../index'; const literals = new Map([['true', true], ['false', false], ['null', null]]); -export default function readExpression(parser: Parser) { +export default function read_expression(parser: Parser) { const start = parser.index; - const name = parser.readUntil(/\s*}/); + const name = parser.read_until(/\s*}/); if (name && /^[a-z]+$/.test(name)) { const end = start + name.length; @@ -31,11 +31,11 @@ export default function readExpression(parser: Parser) { parser.index = start; try { - const node = parseExpressionAt(parser.template, parser.index); + const node = parse_expression_at(parser.template, parser.index); parser.index = node.end; return node; } catch (err) { - parser.acornError(err); + parser.acorn_error(err); } } diff --git a/src/parse/read/script.ts b/src/parse/read/script.ts index 172e1a832b..59e4451dca 100644 --- a/src/parse/read/script.ts +++ b/src/parse/read/script.ts @@ -3,7 +3,7 @@ import repeat from '../../utils/repeat'; import { Parser } from '../index'; import { Node } from '../../interfaces'; -const scriptClosingTag = ''; +const script_closing_tag = ''; function get_context(parser: Parser, attributes: Node[], start: number) { const context = attributes.find(attribute => attribute.name === 'context'); @@ -28,28 +28,28 @@ function get_context(parser: Parser, attributes: Node[], start: number) { return value; } -export default function readScript(parser: Parser, start: number, attributes: Node[]) { - const scriptStart = parser.index; - const scriptEnd = parser.template.indexOf(scriptClosingTag, scriptStart); +export default function read_script(parser: Parser, start: number, attributes: Node[]) { + const script_start = parser.index; + const script_end = parser.template.indexOf(script_closing_tag, script_start); - if (scriptEnd === -1) parser.error({ + if (script_end === -1) parser.error({ code: `unclosed-script`, message: `', true); @@ -271,7 +250,7 @@ export default function tag(parser: Parser) { } else if (name === 'style') { // special case const start = parser.index; - const data = parser.readUntil(/<\/style>/); + const data = parser.read_until(/<\/style>/); const end = parser.index; element.children.push({ start, end, type: 'Text', data }); parser.eat('', true); @@ -280,7 +259,7 @@ export default function tag(parser: Parser) { } } -function readTagName(parser: Parser) { +function read_tag_name(parser: Parser) { const start = parser.index; if (parser.read(SELF)) { @@ -309,9 +288,9 @@ function readTagName(parser: Parser) { if (parser.read(COMPONENT)) return 'svelte:component'; - const name = parser.readUntil(/(\s|\/|>)/); + const name = parser.read_until(/(\s|\/|>)/); - if (metaTags.has(name)) return name; + if (meta_tags.has(name)) return name; if (name.startsWith('svelte:')) { const match = fuzzymatch(name.slice(7), valid_meta_tags); @@ -325,7 +304,7 @@ function readTagName(parser: Parser) { }, start); } - if (!validTagName.test(name)) { + if (!valid_tag_name.test(name)) { parser.error({ code: `invalid-tag-name`, message: `Expected valid tag name` @@ -335,16 +314,16 @@ function readTagName(parser: Parser) { return name; } -function readAttribute(parser: Parser, uniqueNames: Set) { +function readAttribute(parser: Parser, unique_names: Set) { const start = parser.index; if (parser.eat('{')) { - parser.allowWhitespace(); + parser.allow_whitespace(); if (parser.eat('...')) { - const expression = readExpression(parser); + const expression = read_expression(parser); - parser.allowWhitespace(); + parser.allow_whitespace(); parser.eat('}', true); return { @@ -354,10 +333,10 @@ function readAttribute(parser: Parser, uniqueNames: Set) { expression }; } else { - const valueStart = parser.index; + const value_start = parser.index; - const name = parser.readIdentifier(); - parser.allowWhitespace(); + const name = parser.read_identifier(); + parser.allow_whitespace(); parser.eat('}', true); return { @@ -366,12 +345,12 @@ function readAttribute(parser: Parser, uniqueNames: Set) { type: 'Attribute', name, value: [{ - start: valueStart, - end: valueStart + name.length, + start: value_start, + end: value_start + name.length, type: 'AttributeShorthand', expression: { - start: valueStart, - end: valueStart + name.length, + start: value_start, + end: value_start + name.length, type: 'Identifier', name } @@ -380,27 +359,27 @@ function readAttribute(parser: Parser, uniqueNames: Set) { } } - let name = parser.readUntil(/(\s|=|\/|>)/); + let name = parser.read_until(/(\s|=|\/|>)/); if (!name) return null; - if (uniqueNames.has(name)) { + if (unique_names.has(name)) { parser.error({ code: `duplicate-attribute`, message: 'Attributes need to be unique' }, start); } - uniqueNames.add(name); + unique_names.add(name); let end = parser.index; - parser.allowWhitespace(); + parser.allow_whitespace(); const colon_index = name.indexOf(':'); const type = colon_index !== -1 && get_directive_type(name.slice(0, colon_index)); let value: any[] | true = true; if (parser.eat('=')) { - value = readAttributeValue(parser); + value = read_attribute_value(parser); end = parser.index; } @@ -470,23 +449,23 @@ function get_directive_type(name) { if (name === 'in' || name === 'out' || name === 'transition') return 'Transition'; } -function readAttributeValue(parser: Parser) { - const quoteMark = parser.eat(`'`) ? `'` : parser.eat(`"`) ? `"` : null; +function read_attribute_value(parser: Parser) { + const quote_mark = parser.eat(`'`) ? `'` : parser.eat(`"`) ? `"` : null; const regex = ( - quoteMark === `'` ? /'/ : - quoteMark === `"` ? /"/ : + quote_mark === `'` ? /'/ : + quote_mark === `"` ? /"/ : /(\/>|[\s"'=<>`])/ ); - const value = readSequence(parser, () => !!parser.matchRegex(regex)); + const value = read_sequence(parser, () => !!parser.match_regex(regex)); - if (quoteMark) parser.index += 1; + if (quote_mark) parser.index += 1; return value; } -function readSequence(parser: Parser, done: () => boolean) { - let currentChunk: Node = { +function read_sequence(parser: Parser, done: () => boolean) { + let current_chunk: Node = { start: parser.index, end: null, type: 'Text', @@ -499,25 +478,25 @@ function readSequence(parser: Parser, done: () => boolean) { const index = parser.index; if (done()) { - currentChunk.end = parser.index; + current_chunk.end = parser.index; - if (currentChunk.data) chunks.push(currentChunk); + if (current_chunk.data) chunks.push(current_chunk); chunks.forEach(chunk => { if (chunk.type === 'Text') - chunk.data = decodeCharacterReferences(chunk.data); + chunk.data = decode_character_references(chunk.data); }); return chunks; } else if (parser.eat('{')) { - if (currentChunk.data) { - currentChunk.end = index; - chunks.push(currentChunk); + if (current_chunk.data) { + current_chunk.end = index; + chunks.push(current_chunk); } - parser.allowWhitespace(); - const expression = readExpression(parser); - parser.allowWhitespace(); + parser.allow_whitespace(); + const expression = read_expression(parser); + parser.allow_whitespace(); parser.eat('}', true); chunks.push({ @@ -527,14 +506,14 @@ function readSequence(parser: Parser, done: () => boolean) { expression, }); - currentChunk = { + current_chunk = { start: parser.index, end: null, type: 'Text', data: '', }; } else { - currentChunk.data += parser.template[parser.index++]; + current_chunk.data += parser.template[parser.index++]; } } diff --git a/src/parse/state/text.ts b/src/parse/state/text.ts index 72fea496ce..f739c8cc9e 100644 --- a/src/parse/state/text.ts +++ b/src/parse/state/text.ts @@ -1,4 +1,4 @@ -import { decodeCharacterReferences } from '../utils/html'; +import { decode_character_references } from '../utils/html'; import { Parser } from '../index'; export default function text(parser: Parser) { @@ -18,6 +18,6 @@ export default function text(parser: Parser) { start, end: parser.index, type: 'Text', - data: decodeCharacterReferences(data), + data: decode_character_references(data), }); } diff --git a/src/parse/utils/html.ts b/src/parse/utils/html.ts index dd4296a8d0..b49989eacd 100644 --- a/src/parse/utils/html.ts +++ b/src/parse/utils/html.ts @@ -1,6 +1,6 @@ -import htmlEntities from './entities'; +import entities from './entities'; -const windows1252 = [ +const windows_1252 = [ 8364, 129, 8218, @@ -34,18 +34,19 @@ const windows1252 = [ 382, 376, ]; -const entityPattern = new RegExp( - `&(#?(?:x[\\w\\d]+|\\d+|${Object.keys(htmlEntities).join('|')}));?`, + +const entity_pattern = new RegExp( + `&(#?(?:x[\\w\\d]+|\\d+|${Object.keys(entities).join('|')}));?`, 'g' ); -export function decodeCharacterReferences(html: string) { - return html.replace(entityPattern, (match, entity) => { +export function decode_character_references(html: string) { + return html.replace(entity_pattern, (match, entity) => { let code; // Handle named entities if (entity[0] !== '#') { - code = htmlEntities[entity]; + code = entities[entity]; } else if (entity[1] === 'x') { code = parseInt(entity.substring(2), 16); } else { @@ -56,7 +57,7 @@ export function decodeCharacterReferences(html: string) { return match; } - return String.fromCodePoint(validateCode(code)); + return String.fromCodePoint(validate_code(code)); }); } @@ -67,7 +68,7 @@ const NUL = 0; // to replace them ourselves // // Source: http://en.wikipedia.org/wiki/Character_encodings_in_HTML#Illegal_characters -function validateCode(code: number) { +function validate_code(code: number) { // line feed becomes generic whitespace if (code === 10) { return 32; @@ -81,7 +82,7 @@ function validateCode(code: number) { // code points 128-159 are dealt with leniently by browsers, but they're incorrect. We need // to correct the mistake or we'll end up with missing € signs and so on if (code <= 159) { - return windows1252[code - 128]; + return windows_1252[code - 128]; } // basic multilingual plane diff --git a/src/preprocess/index.ts b/src/preprocess/index.ts index 9472bf57fb..1f8207bec6 100644 --- a/src/preprocess/index.ts +++ b/src/preprocess/index.ts @@ -21,17 +21,17 @@ interface Processed { dependencies?: string[]; } -function parseAttributeValue(value: string) { +function parse_attribute_value(value: string) { return /^['"]/.test(value) ? value.slice(1, -1) : value; } -function parseAttributes(str: string) { +function parse_attributes(str: string) { const attrs = {}; str.split(/\s+/).filter(Boolean).forEach(attr => { const [name, value] = attr.split('='); - attrs[name] = value ? parseAttributeValue(value) : true; + attrs[name] = value ? parse_attribute_value(value) : true; }); return attrs; } @@ -99,7 +99,7 @@ export default async function preprocess( async (match, attributes, content) => { const processed: Processed = await fn({ content, - attributes: parseAttributes(attributes), + attributes: parse_attributes(attributes), filename }); if (processed && processed.dependencies) dependencies.push(...processed.dependencies); @@ -115,7 +115,7 @@ export default async function preprocess( async (match, attributes, content) => { const processed: Processed = await fn({ content, - attributes: parseAttributes(attributes), + attributes: parse_attributes(attributes), filename }); if (processed && processed.dependencies) dependencies.push(...processed.dependencies); diff --git a/src/utils/trim.ts b/src/utils/trim.ts index 387b368826..43f413bb1d 100644 --- a/src/utils/trim.ts +++ b/src/utils/trim.ts @@ -1,13 +1,13 @@ import { whitespace } from './patterns'; -export function trimStart(str: string) { +export function trim_start(str: string) { let i = 0; while (whitespace.test(str[i])) i += 1; return str.slice(i); } -export function trimEnd(str: string) { +export function trim_end(str: string) { let i = str.length; while (whitespace.test(str[i - 1])) i -= 1; diff --git a/src/utils/unpackDestructuring.ts b/src/utils/unpackDestructuring.ts deleted file mode 100644 index 749d26b34b..0000000000 --- a/src/utils/unpackDestructuring.ts +++ /dev/null @@ -1,22 +0,0 @@ -export default function unpackDestructuring( - contexts: Array<{ name: string, tail: string }>, - node: Node, - tail: string -) { - if (!node) return; - - if (node.type === 'Identifier') { - contexts.push({ - key: node, - tail - }); - } else if (node.type === 'ArrayPattern') { - node.elements.forEach((element, i) => { - unpackDestructuring(contexts, element, `${tail}[${i}]`); - }); - } else if (node.type === 'ObjectPattern') { - node.properties.forEach((property) => { - unpackDestructuring(contexts, property.value, `${tail}.${property.key.name}`); - }); - } -} \ No newline at end of file