feat: more flexible squared property read expression, fixes #643 (#646)

* fix: more flexible squared property read expression, fixes #643

* fix: unecessary error wrapping in browser bundles

* style: update code style and types

* perf: use token.value when evalToken
This commit is contained in:
Jun Yang
2023-08-23 00:45:49 +08:00
committed by GitHub
parent dc6a301387
commit 660d9be55f
22 changed files with 261 additions and 167 deletions
+9
View File
@@ -2,6 +2,11 @@ import * as _ from './underscore'
import { Token } from '../tokens/token'
import { Template } from '../template/template'
/**
* targeting ES5, extends Error won't create a proper prototype chain, need a trait to kee track of classes
*/
const TRAIT = '__liquidClass__'
export abstract class LiquidError extends Error {
private token!: Token
public context = ''
@@ -14,6 +19,7 @@ export abstract class LiquidError extends Error {
super(typeof err === 'string' ? err : err.message)
if (typeof err !== 'string') Object.defineProperty(this, 'originalError', { value: err, enumerable: false })
Object.defineProperty(this, 'token', { value: token, enumerable: false })
Object.defineProperty(this, TRAIT, { value: 'LiquidError', enumerable: false })
}
protected update () {
Object.defineProperty(this, 'context', { value: mkContext(this.token), enumerable: false })
@@ -22,6 +28,9 @@ export abstract class LiquidError extends Error {
'\n' + this.stack
if (this.originalError) this.stack += '\nFrom ' + this.originalError.stack
}
static is (obj: unknown): obj is LiquidError {
return obj?.[TRAIT] === 'LiquidError'
}
}
export class TokenizationError extends LiquidError {
+3
View File
@@ -9,3 +9,6 @@ export const literalValues = {
'empty': new EmptyDrop(),
'blank': new BlankDrop()
}
export type LiteralKey = keyof typeof literalValues
export type LiteralValue = typeof literalValues[LiteralKey]
+14 -11
View File
@@ -1,22 +1,25 @@
import { Operators, OperatorHandler } from '../render/operator'
import { IDENTIFIER, TYPES } from '../util/character'
interface TrieLeafNode {
handler: OperatorHandler;
interface TrieInput<T> {
[key: string]: T
}
interface TrieLeafNode<T> {
data: T;
end: true;
needBoundary?: true;
}
export interface Trie {
[key: string]: Trie | TrieLeafNode;
export interface Trie<T> {
[key: string]: Trie<T> | TrieLeafNode<T>;
}
export type TrieNode = Trie | TrieLeafNode
export type TrieNode<T> = Trie<T> | TrieLeafNode<T>
export function createTrie (operators: Operators): Trie {
const trie: Trie = {}
for (const [name, handler] of Object.entries(operators)) {
let node: Trie | TrieLeafNode = trie
export function createTrie<T = any> (input: TrieInput<T>): Trie<T> {
const trie: Trie<T> = {}
for (const [name, data] of Object.entries(input)) {
let node: Trie<T> | TrieLeafNode<T> = trie
for (let i = 0; i < name.length; i++) {
const c = name[i]
@@ -29,7 +32,7 @@ export function createTrie (operators: Operators): Trie {
node = node[c]
}
node.handler = handler
node.data = data
node.end = true
}
return trie