summaryrefslogtreecommitdiff
path: root/src/compiler/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/utils')
-rw-r--r--src/compiler/utils/error.ts69
-rw-r--r--src/compiler/utils/full_char_code_at.ts8
-rw-r--r--src/compiler/utils/fuzzymatch.ts402
-rw-r--r--src/compiler/utils/get_code_frame.ts40
-rw-r--r--src/compiler/utils/link.ts4
-rw-r--r--src/compiler/utils/list.ts6
-rw-r--r--src/compiler/utils/names.ts234
-rw-r--r--src/compiler/utils/namespaces.ts17
-rw-r--r--src/compiler/utils/nodes_match.ts44
-rw-r--r--src/compiler/utils/trim.ts12
10 files changed, 404 insertions, 432 deletions
diff --git a/src/compiler/utils/error.ts b/src/compiler/utils/error.ts
index 438d8c500..3c1b23e4c 100644
--- a/src/compiler/utils/error.ts
+++ b/src/compiler/utils/error.ts
@@ -4,39 +4,42 @@ import { locate } from 'locate-character';
import get_code_frame from './get_code_frame.js';
export class CompileError extends Error {
- code: string;
- start: { line: number; column: number };
- end: { line: number; column: number };
- pos: number;
- filename: string;
- frame: string;
-
- toString() {
- return `${this.message} (${this.start.line}:${this.start.column})\n${this.frame}`;
- }
+ code: string;
+ start: { line: number; column: number };
+ end: { line: number; column: number };
+ pos: number;
+ filename: string;
+ frame: string;
+
+ toString() {
+ return `${this.message} (${this.start.line}:${this.start.column})\n${this.frame}`;
+ }
}
-export default function error(message: string, props: {
- name: string;
- code: string;
- source: string;
- filename: string;
- start: number;
- end?: number;
-}): never {
- const error = new CompileError(message);
- error.name = props.name;
-
- const start = locate(props.source, props.start, { offsetLine: 1 });
- const end = locate(props.source, props.end || props.start, { offsetLine: 1 });
-
- error.code = props.code;
- error.start = start;
- error.end = end;
- error.pos = props.start;
- error.filename = props.filename;
-
- error.frame = get_code_frame(props.source, start.line - 1, start.column);
-
- throw error;
+export default function error(
+ message: string,
+ props: {
+ name: string;
+ code: string;
+ source: string;
+ filename: string;
+ start: number;
+ end?: number;
+ }
+): never {
+ const error = new CompileError(message);
+ error.name = props.name;
+
+ const start = locate(props.source, props.start, { offsetLine: 1 });
+ const end = locate(props.source, props.end || props.start, { offsetLine: 1 });
+
+ error.code = props.code;
+ error.start = start;
+ error.end = end;
+ error.pos = props.start;
+ error.filename = props.filename;
+
+ error.frame = get_code_frame(props.source, start.line - 1, start.column);
+
+ throw error;
}
diff --git a/src/compiler/utils/full_char_code_at.ts b/src/compiler/utils/full_char_code_at.ts
index 0469b537f..fea5151b6 100644
--- a/src/compiler/utils/full_char_code_at.ts
+++ b/src/compiler/utils/full_char_code_at.ts
@@ -2,9 +2,9 @@
// Reproduced under MIT License https://github.com/acornjs/acorn/blob/master/LICENSE
export default function full_char_code_at(str: string, i: number): number {
- const code = str.charCodeAt(i);
- if (code <= 0xd7ff || code >= 0xe000) return code;
+ const code = str.charCodeAt(i);
+ if (code <= 0xd7ff || code >= 0xe000) return code;
- const next = str.charCodeAt(i + 1);
- return (code << 10) + next - 0x35fdc00;
+ const next = str.charCodeAt(i + 1);
+ return (code << 10) + next - 0x35fdc00;
}
diff --git a/src/compiler/utils/fuzzymatch.ts b/src/compiler/utils/fuzzymatch.ts
index 22e6c2363..d24d0fd0a 100644
--- a/src/compiler/utils/fuzzymatch.ts
+++ b/src/compiler/utils/fuzzymatch.ts
@@ -1,10 +1,10 @@
// @ts-nocheck
export default function fuzzymatch(name: string, names: string[]) {
- const set = new FuzzySet(names);
- const matches = set.get(name);
+ const set = new FuzzySet(names);
+ const matches = set.get(name);
- return matches && matches[0] && matches[0][0] > 0.7 ? matches[0][1] : null;
+ return matches && matches[0] && matches[0][0] > 0.7 ? matches[0][1] : null;
}
// adapted from https://github.com/Glench/fuzzyset.js/blob/master/lib/fuzzyset.js
@@ -15,225 +15,215 @@ const GRAM_SIZE_UPPER = 3;
// return an edit distance from 0 to 1
function _distance(str1: string, str2: string) {
- if (str1 === null && str2 === null) {
- throw 'Trying to compare two null values';
- }
- if (str1 === null || str2 === null) return 0;
- str1 = String(str1);
- str2 = String(str2);
-
- const distance = levenshtein(str1, str2);
- if (str1.length > str2.length) {
- return 1 - distance / str1.length;
- } else {
- return 1 - distance / str2.length;
- }
+ if (str1 === null && str2 === null) {
+ throw 'Trying to compare two null values';
+ }
+ if (str1 === null || str2 === null) return 0;
+ str1 = String(str1);
+ str2 = String(str2);
+
+ const distance = levenshtein(str1, str2);
+ if (str1.length > str2.length) {
+ return 1 - distance / str1.length;
+ } else {
+ return 1 - distance / str2.length;
+ }
}
// helper functions
function levenshtein(str1: string, str2: string) {
- const current: number[] = [];
- let prev;
- let value;
-
- for (let i = 0; i <= str2.length; i++) {
- for (let j = 0; j <= str1.length; j++) {
- if (i && j) {
- if (str1.charAt(j - 1) === str2.charAt(i - 1)) {
- value = prev;
- } else {
- value = Math.min(current[j], current[j - 1], prev) + 1;
- }
- } else {
- value = i + j;
- }
-
- prev = current[j];
- current[j] = value;
- }
- }
-
- return current.pop();
+ const current: number[] = [];
+ let prev;
+ let value;
+
+ for (let i = 0; i <= str2.length; i++) {
+ for (let j = 0; j <= str1.length; j++) {
+ if (i && j) {
+ if (str1.charAt(j - 1) === str2.charAt(i - 1)) {
+ value = prev;
+ } else {
+ value = Math.min(current[j], current[j - 1], prev) + 1;
+ }
+ } else {
+ value = i + j;
+ }
+
+ prev = current[j];
+ current[j] = value;
+ }
+ }
+
+ return current.pop();
}
const non_word_regex = /[^\w, ]+/;
function iterate_grams(value: string, gram_size = 2) {
- const simplified = '-' + value.toLowerCase().replace(non_word_regex, '') + '-';
- const len_diff = gram_size - simplified.length;
- const results = [];
-
- if (len_diff > 0) {
- for (let i = 0; i < len_diff; ++i) {
- value += '-';
- }
- }
- for (let i = 0; i < simplified.length - gram_size + 1; ++i) {
- results.push(simplified.slice(i, i + gram_size));
- }
- return results;
+ const simplified = '-' + value.toLowerCase().replace(non_word_regex, '') + '-';
+ const len_diff = gram_size - simplified.length;
+ const results = [];
+
+ if (len_diff > 0) {
+ for (let i = 0; i < len_diff; ++i) {
+ value += '-';
+ }
+ }
+ for (let i = 0; i < simplified.length - gram_size + 1; ++i) {
+ results.push(simplified.slice(i, i + gram_size));
+ }
+ return results;
}
function gram_counter(value: string, gram_size = 2) {
- // return an object where key=gram, value=number of occurrences
- const result = {};
- const grams = iterate_grams(value, gram_size);
- let i = 0;
-
- for (i; i < grams.length; ++i) {
- if (grams[i] in result) {
- result[grams[i]] += 1;
- } else {
- result[grams[i]] = 1;
- }
- }
- return result;
+ // return an object where key=gram, value=number of occurrences
+ const result = {};
+ const grams = iterate_grams(value, gram_size);
+ let i = 0;
+
+ for (i; i < grams.length; ++i) {
+ if (grams[i] in result) {
+ result[grams[i]] += 1;
+ } else {
+ result[grams[i]] = 1;
+ }
+ }
+ return result;
}
function sort_descending(a, b) {
- return b[0] - a[0];
+ return b[0] - a[0];
}
class FuzzySet {
- exact_set = {};
- match_dict = {};
- items = {};
-
- constructor(arr: string[]) {
- // initialization
- for (let i = GRAM_SIZE_LOWER; i < GRAM_SIZE_UPPER + 1; ++i) {
- this.items[i] = [];
- }
-
- // add all the items to the set
- for (let i = 0; i < arr.length; ++i) {
- this.add(arr[i]);
- }
- }
-
- add(value: string) {
- const normalized_value = value.toLowerCase();
- if (normalized_value in this.exact_set) {
- return false;
- }
-
- let i = GRAM_SIZE_LOWER;
- for (i; i < GRAM_SIZE_UPPER + 1; ++i) {
- this._add(value, i);
- }
- }
-
- _add(value: string, gram_size: number) {
- const normalized_value = value.toLowerCase();
- const items = this.items[gram_size] || [];
- const index = items.length;
-
- items.push(0);
- const gram_counts = gram_counter(normalized_value, gram_size);
- let sum_of_square_gram_counts = 0;
- let gram;
- let gram_count;
-
- for (gram in gram_counts) {
- gram_count = gram_counts[gram];
- sum_of_square_gram_counts += Math.pow(gram_count, 2);
- if (gram in this.match_dict) {
- this.match_dict[gram].push([index, gram_count]);
- } else {
- this.match_dict[gram] = [[index, gram_count]];
- }
- }
- const vector_normal = Math.sqrt(sum_of_square_gram_counts);
- items[index] = [vector_normal, normalized_value];
- this.items[gram_size] = items;
- this.exact_set[normalized_value] = value;
- }
-
- get(value: string) {
- const normalized_value = value.toLowerCase();
- const result = this.exact_set[normalized_value];
-
- if (result) {
- return [[1, result]];
- }
-
- let results = [];
- // start with high gram size and if there are no results, go to lower gram sizes
- for (
- let gram_size = GRAM_SIZE_UPPER;
- gram_size >= GRAM_SIZE_LOWER;
- --gram_size
- ) {
- results = this.__get(value, gram_size);
- if (results) {
- return results;
- }
- }
- return null;
- }
-
- __get(value: string, gram_size: number) {
- const normalized_value = value.toLowerCase();
- const matches = {};
- const gram_counts = gram_counter(normalized_value, gram_size);
- const items = this.items[gram_size];
- let sum_of_square_gram_counts = 0;
- let gram;
- let gram_count;
- let i;
- let index;
- let other_gram_count;
-
- for (gram in gram_counts) {
- gram_count = gram_counts[gram];
- sum_of_square_gram_counts += Math.pow(gram_count, 2);
- if (gram in this.match_dict) {
- for (i = 0; i < this.match_dict[gram].length; ++i) {
- index = this.match_dict[gram][i][0];
- other_gram_count = this.match_dict[gram][i][1];
- if (index in matches) {
- matches[index] += gram_count * other_gram_count;
- } else {
- matches[index] = gram_count * other_gram_count;
- }
- }
- }
- }
-
- const vector_normal = Math.sqrt(sum_of_square_gram_counts);
- let results = [];
- let match_score;
-
- // build a results list of [score, str]
- for (const match_index in matches) {
- match_score = matches[match_index];
- results.push([
- match_score / (vector_normal * items[match_index][0]),
- items[match_index][1]
- ]);
- }
-
- results.sort(sort_descending);
-
- let new_results = [];
- const end_index = Math.min(50, results.length);
- // truncate somewhat arbitrarily to 50
- for (let i = 0; i < end_index; ++i) {
- new_results.push([
- _distance(results[i][1], normalized_value),
- results[i][1]
- ]);
- }
- results = new_results;
- results.sort(sort_descending);
-
- new_results = [];
- for (let i = 0; i < results.length; ++i) {
- if (results[i][0] == results[0][0]) {
- new_results.push([results[i][0], this.exact_set[results[i][1]]]);
- }
- }
-
- return new_results;
- }
+ exact_set = {};
+ match_dict = {};
+ items = {};
+
+ constructor(arr: string[]) {
+ // initialization
+ for (let i = GRAM_SIZE_LOWER; i < GRAM_SIZE_UPPER + 1; ++i) {
+ this.items[i] = [];
+ }
+
+ // add all the items to the set
+ for (let i = 0; i < arr.length; ++i) {
+ this.add(arr[i]);
+ }
+ }
+
+ add(value: string) {
+ const normalized_value = value.toLowerCase();
+ if (normalized_value in this.exact_set) {
+ return false;
+ }
+
+ let i = GRAM_SIZE_LOWER;
+ for (i; i < GRAM_SIZE_UPPER + 1; ++i) {
+ this._add(value, i);
+ }
+ }
+
+ _add(value: string, gram_size: number) {
+ const normalized_value = value.toLowerCase();
+ const items = this.items[gram_size] || [];
+ const index = items.length;
+
+ items.push(0);
+ const gram_counts = gram_counter(normalized_value, gram_size);
+ let sum_of_square_gram_counts = 0;
+ let gram;
+ let gram_count;
+
+ for (gram in gram_counts) {
+ gram_count = gram_counts[gram];
+ sum_of_square_gram_counts += Math.pow(gram_count, 2);
+ if (gram in this.match_dict) {
+ this.match_dict[gram].push([index, gram_count]);
+ } else {
+ this.match_dict[gram] = [[index, gram_count]];
+ }
+ }
+ const vector_normal = Math.sqrt(sum_of_square_gram_counts);
+ items[index] = [vector_normal, normalized_value];
+ this.items[gram_size] = items;
+ this.exact_set[normalized_value] = value;
+ }
+
+ get(value: string) {
+ const normalized_value = value.toLowerCase();
+ const result = this.exact_set[normalized_value];
+
+ if (result) {
+ return [[1, result]];
+ }
+
+ let results = [];
+ // start with high gram size and if there are no results, go to lower gram sizes
+ for (let gram_size = GRAM_SIZE_UPPER; gram_size >= GRAM_SIZE_LOWER; --gram_size) {
+ results = this.__get(value, gram_size);
+ if (results) {
+ return results;
+ }
+ }
+ return null;
+ }
+
+ __get(value: string, gram_size: number) {
+ const normalized_value = value.toLowerCase();
+ const matches = {};
+ const gram_counts = gram_counter(normalized_value, gram_size);
+ const items = this.items[gram_size];
+ let sum_of_square_gram_counts = 0;
+ let gram;
+ let gram_count;
+ let i;
+ let index;
+ let other_gram_count;
+
+ for (gram in gram_counts) {
+ gram_count = gram_counts[gram];
+ sum_of_square_gram_counts += Math.pow(gram_count, 2);
+ if (gram in this.match_dict) {
+ for (i = 0; i < this.match_dict[gram].length; ++i) {
+ index = this.match_dict[gram][i][0];
+ other_gram_count = this.match_dict[gram][i][1];
+ if (index in matches) {
+ matches[index] += gram_count * other_gram_count;
+ } else {
+ matches[index] = gram_count * other_gram_count;
+ }
+ }
+ }
+ }
+
+ const vector_normal = Math.sqrt(sum_of_square_gram_counts);
+ let results = [];
+ let match_score;
+
+ // build a results list of [score, str]
+ for (const match_index in matches) {
+ match_score = matches[match_index];
+ results.push([match_score / (vector_normal * items[match_index][0]), items[match_index][1]]);
+ }
+
+ results.sort(sort_descending);
+
+ let new_results = [];
+ const end_index = Math.min(50, results.length);
+ // truncate somewhat arbitrarily to 50
+ for (let i = 0; i < end_index; ++i) {
+ new_results.push([_distance(results[i][1], normalized_value), results[i][1]]);
+ }
+ results = new_results;
+ results.sort(sort_descending);
+
+ new_results = [];
+ for (let i = 0; i < results.length; ++i) {
+ if (results[i][0] == results[0][0]) {
+ new_results.push([results[i][0], this.exact_set[results[i][1]]]);
+ }
+ }
+
+ return new_results;
+ }
}
diff --git a/src/compiler/utils/get_code_frame.ts b/src/compiler/utils/get_code_frame.ts
index 1097f5b3d..a0c296672 100644
--- a/src/compiler/utils/get_code_frame.ts
+++ b/src/compiler/utils/get_code_frame.ts
@@ -1,31 +1,27 @@
function tabs_to_spaces(str: string) {
- return str.replace(/^\t+/, match => match.split('\t').join(' '));
+ return str.replace(/^\t+/, (match) => match.split('\t').join(' '));
}
-export default function get_code_frame(
- source: string,
- line: number,
- column: number
-) {
- const lines = source.split('\n');
+export default function get_code_frame(source: string, line: number, column: number) {
+ const lines = source.split('\n');
- const frame_start = Math.max(0, line - 2);
- const frame_end = Math.min(line + 3, lines.length);
+ const frame_start = Math.max(0, line - 2);
+ const frame_end = Math.min(line + 3, lines.length);
- const digits = String(frame_end + 1).length;
+ const digits = String(frame_end + 1).length;
- return lines
- .slice(frame_start, frame_end)
- .map((str, i) => {
- const isErrorLine = frame_start + i === line;
- const line_num = String(i + frame_start + 1).padStart(digits, ' ');
+ return lines
+ .slice(frame_start, frame_end)
+ .map((str, i) => {
+ const isErrorLine = frame_start + i === line;
+ const line_num = String(i + frame_start + 1).padStart(digits, ' ');
- if (isErrorLine) {
- const indicator = ' '.repeat(digits + 2 + tabs_to_spaces(str.slice(0, column)).length) + '^';
- return `${line_num}: ${tabs_to_spaces(str)}\n${indicator}`;
- }
+ if (isErrorLine) {
+ const indicator = ' '.repeat(digits + 2 + tabs_to_spaces(str.slice(0, column)).length) + '^';
+ return `${line_num}: ${tabs_to_spaces(str)}\n${indicator}`;
+ }
- return `${line_num}: ${tabs_to_spaces(str)}`;
- })
- .join('\n');
+ return `${line_num}: ${tabs_to_spaces(str)}`;
+ })
+ .join('\n');
}
diff --git a/src/compiler/utils/link.ts b/src/compiler/utils/link.ts
index 7cdef75d9..0dc5af1b7 100644
--- a/src/compiler/utils/link.ts
+++ b/src/compiler/utils/link.ts
@@ -1,4 +1,4 @@
export function link<T extends { next?: T; prev?: T }>(next: T, prev: T) {
- prev.next = next;
- if (next) next.prev = prev;
+ prev.next = next;
+ if (next) next.prev = prev;
}
diff --git a/src/compiler/utils/list.ts b/src/compiler/utils/list.ts
index 785f006d1..ba1ef9f4c 100644
--- a/src/compiler/utils/list.ts
+++ b/src/compiler/utils/list.ts
@@ -1,6 +1,4 @@
export default function list(items: string[], conjunction = 'or') {
- if (items.length === 1) return items[0];
- return `${items.slice(0, -1).join(', ')} ${conjunction} ${items[
- items.length - 1
- ]}`;
+ if (items.length === 1) return items[0];
+ return `${items.slice(0, -1).join(', ')} ${conjunction} ${items[items.length - 1]}`;
}
diff --git a/src/compiler/utils/names.ts b/src/compiler/utils/names.ts
index c386541a2..f2e1dfc8e 100644
--- a/src/compiler/utils/names.ts
+++ b/src/compiler/utils/names.ts
@@ -2,138 +2,138 @@ import { isIdentifierStart, isIdentifierChar } from 'acorn';
import full_char_code_at from './full_char_code_at.js';
export const globals = new Set([
- 'alert',
- 'Array',
- 'Boolean',
- 'clearInterval',
- 'clearTimeout',
- 'confirm',
- 'console',
- 'Date',
- 'decodeURI',
- 'decodeURIComponent',
- 'document',
- 'Element',
- 'encodeURI',
- 'encodeURIComponent',
- 'Error',
- 'EvalError',
- 'Event',
- 'EventSource',
- 'fetch',
- 'global',
- 'globalThis',
- 'history',
- 'Infinity',
- 'InternalError',
- 'Intl',
- 'isFinite',
- 'isNaN',
- 'JSON',
- 'localStorage',
- 'location',
- 'Map',
- 'Math',
- 'NaN',
- 'navigator',
- 'Number',
- 'Node',
- 'Object',
- 'parseFloat',
- 'parseInt',
- 'process',
- 'Promise',
- 'prompt',
- 'RangeError',
- 'ReferenceError',
- 'RegExp',
- 'sessionStorage',
- 'Set',
- 'setInterval',
- 'setTimeout',
- 'String',
- 'SyntaxError',
- 'TypeError',
- 'undefined',
- 'URIError',
- 'URL',
- 'window'
+ 'alert',
+ 'Array',
+ 'Boolean',
+ 'clearInterval',
+ 'clearTimeout',
+ 'confirm',
+ 'console',
+ 'Date',
+ 'decodeURI',
+ 'decodeURIComponent',
+ 'document',
+ 'Element',
+ 'encodeURI',
+ 'encodeURIComponent',
+ 'Error',
+ 'EvalError',
+ 'Event',
+ 'EventSource',
+ 'fetch',
+ 'global',
+ 'globalThis',
+ 'history',
+ 'Infinity',
+ 'InternalError',
+ 'Intl',
+ 'isFinite',
+ 'isNaN',
+ 'JSON',
+ 'localStorage',
+ 'location',
+ 'Map',
+ 'Math',
+ 'NaN',
+ 'navigator',
+ 'Number',
+ 'Node',
+ 'Object',
+ 'parseFloat',
+ 'parseInt',
+ 'process',
+ 'Promise',
+ 'prompt',
+ 'RangeError',
+ 'ReferenceError',
+ 'RegExp',
+ 'sessionStorage',
+ 'Set',
+ 'setInterval',
+ 'setTimeout',
+ 'String',
+ 'SyntaxError',
+ 'TypeError',
+ 'undefined',
+ 'URIError',
+ 'URL',
+ 'window',
]);
export const reserved = new Set([
- 'arguments',
- 'await',
- 'break',
- 'case',
- 'catch',
- 'class',
- 'const',
- 'continue',
- 'debugger',
- 'default',
- 'delete',
- 'do',
- 'else',
- 'enum',
- 'eval',
- 'export',
- 'extends',
- 'false',
- 'finally',
- 'for',
- 'function',
- 'if',
- 'implements',
- 'import',
- 'in',
- 'instanceof',
- 'interface',
- 'let',
- 'new',
- 'null',
- 'package',
- 'private',
- 'protected',
- 'public',
- 'return',
- 'static',
- 'super',
- 'switch',
- 'this',
- 'throw',
- 'true',
- 'try',
- 'typeof',
- 'var',
- 'void',
- 'while',
- 'with',
- 'yield'
+ 'arguments',
+ 'await',
+ 'break',
+ 'case',
+ 'catch',
+ 'class',
+ 'const',
+ 'continue',
+ 'debugger',
+ 'default',
+ 'delete',
+ 'do',
+ 'else',
+ 'enum',
+ 'eval',
+ 'export',
+ 'extends',
+ 'false',
+ 'finally',
+ 'for',
+ 'function',
+ 'if',
+ 'implements',
+ 'import',
+ 'in',
+ 'instanceof',
+ 'interface',
+ 'let',
+ 'new',
+ 'null',
+ 'package',
+ 'private',
+ 'protected',
+ 'public',
+ 'return',
+ 'static',
+ 'super',
+ 'switch',
+ 'this',
+ 'throw',
+ 'true',
+ 'try',
+ 'typeof',
+ 'var',
+ 'void',
+ 'while',
+ 'with',
+ 'yield',
]);
const void_element_names = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/;
export function is_void(name: string) {
- return void_element_names.test(name) || name.toLowerCase() === '!doctype';
+ return void_element_names.test(name) || name.toLowerCase() === '!doctype';
}
export function is_valid(str: string): boolean {
- let i = 0;
+ let i = 0;
- while (i < str.length) {
- const code = full_char_code_at(str, i);
- if (!(i === 0 ? isIdentifierStart : isIdentifierChar)(code, true)) return false;
+ while (i < str.length) {
+ const code = full_char_code_at(str, i);
+ if (!(i === 0 ? isIdentifierStart : isIdentifierChar)(code, true)) return false;
- i += code <= 0xffff ? 1 : 2;
- }
+ i += code <= 0xffff ? 1 : 2;
+ }
- return true;
+ return true;
}
export function sanitize(name: string) {
- return name
- .replace(/[^a-zA-Z0-9_]+/g, '_')
- .replace(/^_/, '')
- .replace(/_$/, '')
- .replace(/^[0-9]/, '_$&');
+ return name
+ .replace(/[^a-zA-Z0-9_]+/g, '_')
+ .replace(/^_/, '')
+ .replace(/_$/, '')
+ .replace(/^[0-9]/, '_$&');
}
diff --git a/src/compiler/utils/namespaces.ts b/src/compiler/utils/namespaces.ts
index 01d9bd60b..5f61beff9 100644
--- a/src/compiler/utils/namespaces.ts
+++ b/src/compiler/utils/namespaces.ts
@@ -8,21 +8,6 @@ export const xlink = 'http://www.w3.org/1999/xlink';
export const xml = 'http://www.w3.org/XML/1998/namespace';
export const xmlns = 'http://www.w3.org/2000/xmlns';
-export const valid_namespaces = [
- 'foreign',
- 'html',
- 'mathml',
- 'svg',
- 'xlink',
- 'xml',
- 'xmlns',
- foreign,
- html,
- mathml,
- svg,
- xlink,
- xml,
- xmlns
-];
+export const valid_namespaces = ['foreign', 'html', 'mathml', 'svg', 'xlink', 'xml', 'xmlns', foreign, html, mathml, svg, xlink, xml, xmlns];
export const namespaces: Record<string, string> = { foreign, html, mathml, svg, xlink, xml, xmlns };
diff --git a/src/compiler/utils/nodes_match.ts b/src/compiler/utils/nodes_match.ts
index 9c8e1fb48..563742635 100644
--- a/src/compiler/utils/nodes_match.ts
+++ b/src/compiler/utils/nodes_match.ts
@@ -1,34 +1,34 @@
// @ts-nocheck
export function nodes_match(a, b) {
- if (!!a !== !!b) return false;
- if (Array.isArray(a) !== Array.isArray(b)) return false;
+ if (!!a !== !!b) return false;
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
- if (a && typeof a === 'object') {
- if (Array.isArray(a)) {
- if (a.length !== b.length) return false;
- return a.every((child, i) => nodes_match(child, b[i]));
- }
+ if (a && typeof a === 'object') {
+ if (Array.isArray(a)) {
+ if (a.length !== b.length) return false;
+ return a.every((child, i) => nodes_match(child, b[i]));
+ }
- const a_keys = Object.keys(a).sort();
- const b_keys = Object.keys(b).sort();
+ const a_keys = Object.keys(a).sort();
+ const b_keys = Object.keys(b).sort();
- if (a_keys.length !== b_keys.length) return false;
+ if (a_keys.length !== b_keys.length) return false;
- let i = a_keys.length;
- while (i--) {
- const key = a_keys[i];
- if (b_keys[i] !== key) return false;
+ let i = a_keys.length;
+ while (i--) {
+ const key = a_keys[i];
+ if (b_keys[i] !== key) return false;
- if (key === 'start' || key === 'end') continue;
+ if (key === 'start' || key === 'end') continue;
- if (!nodes_match(a[key], b[key])) {
- return false;
- }
- }
+ if (!nodes_match(a[key], b[key])) {
+ return false;
+ }
+ }
- return true;
- }
+ return true;
+ }
- return a === b;
+ return a === b;
}
diff --git a/src/compiler/utils/trim.ts b/src/compiler/utils/trim.ts
index 1c7388c2c..406a8c97f 100644
--- a/src/compiler/utils/trim.ts
+++ b/src/compiler/utils/trim.ts
@@ -1,15 +1,15 @@
import { whitespace } from './patterns.js';
export function trim_start(str: string) {
- let i = 0;
- while (whitespace.test(str[i])) i += 1;
+ let i = 0;
+ while (whitespace.test(str[i])) i += 1;
- return str.slice(i);
+ return str.slice(i);
}
export function trim_end(str: string) {
- let i = str.length;
- while (whitespace.test(str[i - 1])) i -= 1;
+ let i = str.length;
+ while (whitespace.test(str[i - 1])) i -= 1;
- return str.slice(0, i);
+ return str.slice(0, i);
}