perf: introduce AST to avoid reparse

This commit is contained in:
harttle
2020-03-15 02:51:25 +08:00
committed by Jun Yang
parent 3b58f1c3f6
commit d2d6a38235
96 changed files with 1553 additions and 1168 deletions
+11 -10
View File
@@ -1,20 +1,21 @@
import { Token } from '../parser/token'
import { Token } from '../tokens/token'
import { Template } from '../template/template'
import { TagToken } from './tag-token'
import { isTagToken } from '../util/type-guards'
import { TopLevelToken } from '../tokens/toplevel-token'
type ParseToken = ((token: Token, remainTokens: Token[]) => Template)
type ParseToken<T extends Token> = ((token: T, remainTokens: T[]) => Template)
export class ParseStream {
private tokens: Token[]
export class ParseStream<T extends Token = TopLevelToken> {
private tokens: T[]
private handlers: {[key: string]: (arg: any) => void} = {}
private stopRequested = false
private parseToken: ParseToken
private parseToken: ParseToken<T>
public constructor (tokens: Token[], parseToken: ParseToken) {
public constructor (tokens: T[], parseToken: ParseToken<T>) {
this.tokens = tokens
this.parseToken = parseToken
}
public on<T extends Template | Token | undefined> (name: string, cb: (arg: T) => void): ParseStream {
public on<T2 extends Template | T | undefined> (name: string, cb: (arg: T2) => void): ParseStream<T> {
this.handlers[name] = cb
return this
}
@@ -24,10 +25,10 @@ export class ParseStream {
}
public start () {
this.trigger('start')
let token: Token | undefined
let token: T | undefined
while (!this.stopRequested && (token = this.tokens.shift())) {
if (this.trigger('token', token)) continue
if (TagToken.is(token) && this.trigger(`tag:${token.name}`, token)) {
if (isTagToken(token) && this.trigger(`tag:${token.name}`, token)) {
continue
}
const template = this.parseToken(token, this.tokens)