refactor: strictly typed

This commit is contained in:
harttle
2019-02-23 00:49:54 +08:00
parent 51f7e66f60
commit 5b6100d12b
86 changed files with 2630 additions and 2590 deletions
+4 -3
View File
@@ -1,12 +1,13 @@
import Token from './token'
import { last } from 'src/util/underscore'
export default class DelimitedToken extends Token {
trimLeft: boolean
trimRight: boolean
constructor (raw, value, pos, input, file, line) {
super(raw, pos, input, file, line)
constructor (raw: string, value: string, input: string, line: number, pos: number, file?: string) {
super(raw, input, line, pos, file)
this.trimLeft = value[0] === '-'
this.trimRight = value[value.length - 1] === '-'
this.trimRight = last(value) === '-'
this.value = value
.slice(
this.trimLeft ? 1 : 0,
+2 -2
View File
@@ -1,8 +1,8 @@
import Token from './token'
export default class HTMLToken extends Token {
constructor (str, begin, input, file, line) {
super(str, begin, input, file, line)
constructor (str: string, input: string, line: number, col: number, file?: string) {
super(str, input, line, col, file)
this.type = 'html'
this.value = str
}
+6 -6
View File
@@ -49,27 +49,27 @@ export const operators = [
/==|!=|<=|>=|<|>|\s+contains\s+/
]
export function isInteger (str) {
export function isInteger (str: string) {
return integerLine.test(str)
}
export function isLiteral (str) {
export function isLiteral (str: string) {
return literalLine.test(str)
}
export function isRange (str) {
export function isRange (str: string) {
return rangeLine.test(str)
}
export function isVariable (str) {
export function isVariable (str: string) {
return variableLine.test(str)
}
export function matchValue (str) {
export function matchValue (str: string) {
return value.exec(str)
}
export function parseLiteral (str) {
export function parseLiteral (str: string) {
let res = str.match(numberLine)
if (res) {
return Number(str)
+2 -2
View File
@@ -1,8 +1,8 @@
import DelimitedToken from './delimited-token'
export default class OutputToken extends DelimitedToken {
constructor (raw, value, pos, input, file, line) {
super(raw, value, pos, input, file, line)
constructor (raw: string, value: string, input: string, line: number, pos: number, file?: string) {
super(raw, value, input, line, pos, file)
this.type = 'output'
}
}
+11 -11
View File
@@ -1,37 +1,37 @@
import Token from 'src/parser/token'
import ITemplate from 'src/template/itemplate'
import TagToken from './tag-token';
type parseToken = (token: Token, remainTokens: Array<Token>) => ITemplate
type eventHandler = ((arg?: Token | ITemplate) => void)
type ParseToken = ((token: Token, remainTokens: Array<Token>) => ITemplate)
export default class ParseStream {
private tokens: Array<Token>
private handlers: {[key: string]: eventHandler} = {}
private stopRequested: boolean
private parseToken: parseToken
private handlers: {[key: string]: (arg: any) => void} = {}
private stopRequested: boolean = false
private parseToken: ParseToken
constructor (tokens: Array<Token>, parseToken: parseToken) {
constructor (tokens: Array<Token>, parseToken: ParseToken) {
this.tokens = tokens
this.parseToken = parseToken
}
on (name: string, cb: eventHandler) {
on<T extends ITemplate | Token | undefined> (name: string, cb: (arg: T) => void): ParseStream {
this.handlers[name] = cb
return this
}
trigger (event: string, arg?: Token | ITemplate) {
trigger <T extends Token | ITemplate>(event: string, arg?: T) {
const h = this.handlers[event]
if (typeof h === 'function') {
h(arg)
return true
}
return false
}
start () {
this.trigger('start')
let token
let token: Token | undefined
while (!this.stopRequested && (token = this.tokens.shift())) {
if (this.trigger('token', token)) continue
if (token.type === 'tag' &&
this.trigger(`tag:${token.name}`, token)) {
if (token.type === 'tag' && this.trigger(`tag:${(<TagToken>token).name}`, token)) {
continue
}
const template = this.parseToken(token, this.tokens)
+2 -1
View File
@@ -7,6 +7,7 @@ import OutputToken from './output-token'
import Tag from 'src/template/tag/tag'
import Output from 'src/template/output'
import HTML from 'src/template/html'
import ITemplate from 'src/template/itemplate'
export default class Parser {
liquid: Liquid
@@ -16,7 +17,7 @@ export default class Parser {
}
parse (tokens: Array<Token>) {
let token
const templates = []
const templates: ITemplate[] = []
while ((token = tokens.shift())) {
templates.push(this.parseToken(token, tokens))
}
+2 -2
View File
@@ -5,8 +5,8 @@ import * as lexical from './lexical'
export default class TagToken extends DelimitedToken {
name: string
args: string
constructor (raw, value, pos, input, file, line) {
super(raw, value, pos, input, file, line)
constructor (raw: string, value: string, input: string, line: number, pos: number, file?: string) {
super(raw, value, input, line, pos, file)
this.type = 'tag'
const match = this.value.match(lexical.tagLine)
if (!match) {
+4 -3
View File
@@ -1,15 +1,16 @@
export default class Token {
type: string
type: string = 'notset'
line: number
col: number
raw: string
input: string
file: string
file?: string
value: string
constructor (raw, col, input, file, line) {
constructor (raw: string, input: string, line: number, col: number, file?: string) {
this.col = col
this.line = line
this.raw = raw
this.value = raw
this.input = input
this.file = file
}
+8 -8
View File
@@ -14,7 +14,7 @@ export default class Tokenizer {
this.options = applyDefault(options)
}
tokenize (input: string, file?: string) {
const tokens = []
const tokens: Token[] = []
const tagL = this.options.tag_delimiter_left
const tagR = this.options.tag_delimiter_right
const outputL = this.options.output_delimiter_left
@@ -34,7 +34,7 @@ export default class Tokenizer {
}
if (state === ParseState.HTML) {
if (input.substr(p, outputL.length) === outputL) {
if (buffer) tokens.push(new HTMLToken(buffer, col, input, file, line))
if (buffer) tokens.push(new HTMLToken(buffer, input, line, col, file))
buffer = outputL
line = curLine
col = p - lineBegin + 1
@@ -42,7 +42,7 @@ export default class Tokenizer {
state = ParseState.OUTPUT
continue
} else if (input.substr(p, tagL.length) === tagL) {
if (buffer) tokens.push(new HTMLToken(buffer, col, input, file, line))
if (buffer) tokens.push(new HTMLToken(buffer, input, line, col, file))
buffer = tagL
line = curLine
col = p - lineBegin + 1
@@ -52,7 +52,7 @@ export default class Tokenizer {
}
} else if (state === ParseState.OUTPUT && input.substr(p, outputR.length) === outputR) {
buffer += outputR
tokens.push(new OutputToken(buffer, buffer.slice(outputL.length, -outputR.length), col, input, file, line))
tokens.push(new OutputToken(buffer, buffer.slice(outputL.length, -outputR.length), input, line, col, file))
p += outputR.length
buffer = ''
line = curLine
@@ -61,7 +61,7 @@ export default class Tokenizer {
continue
} else if (input.substr(p, tagR.length) === tagR) {
buffer += tagR
tokens.push(new TagToken(buffer, buffer.slice(tagL.length, -tagR.length), col, input, file, line))
tokens.push(new TagToken(buffer, buffer.slice(tagL.length, -tagR.length), input, line, col, file))
p += tagR.length
buffer = ''
line = curLine
@@ -75,11 +75,11 @@ export default class Tokenizer {
const t = state === ParseState.OUTPUT ? 'output' : 'tag'
const str = buffer.length > 16 ? buffer.slice(0, 13) + '...' : buffer
throw new TokenizationError(
new Error(`${t} "${str}" not closed`),
new Token(buffer, col, input, file, line)
`${t} "${str}" not closed`,
new Token(buffer, input, line, col, file)
)
}
if (buffer) tokens.push(new HTMLToken(buffer, col, input, file, line))
if (buffer) tokens.push(new HTMLToken(buffer, input, line, col, file))
whiteSpaceCtrl(tokens, this.options)
return tokens
+2 -2
View File
@@ -21,13 +21,13 @@ export default function whiteSpaceCtrl (tokens: Token[], options: NormalizedFull
})
}
function shouldTrimLeft (token: DelimitedToken, inRaw: boolean, options) {
function shouldTrimLeft (token: DelimitedToken, inRaw: boolean, options: NormalizedFullOptions) {
if (inRaw) return false
if (token.type === 'tag') return token.trimLeft || options.trim_tag_left
if (token.type === 'output') return token.trimLeft || options.trim_output_left
}
function shouldTrimRight (token: DelimitedToken, inRaw: boolean, options) {
function shouldTrimRight (token: DelimitedToken, inRaw: boolean, options: NormalizedFullOptions) {
if (inRaw) return false
if (token.type === 'tag') return token.trimRight || options.trim_tag_right
if (token.type === 'output') return token.trimRight || options.trim_output_right