| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| const Token = { |
| Boolean: "Boolean", |
| EOF: "<end>", |
| Identifier: "Identifier", |
| PrivateIdentifier: "PrivateIdentifier", |
| Keyword: "Keyword", |
| Null: "Null", |
| Numeric: "Numeric", |
| Punctuator: "Punctuator", |
| String: "String", |
| RegularExpression: "RegularExpression", |
| Template: "Template", |
| JSXIdentifier: "JSXIdentifier", |
| JSXText: "JSXText", |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| function convertTemplatePart(tokens, code) { |
| const firstToken = tokens[0], |
| lastTemplateToken = |
| ( |
| tokens.at(-1) |
| ); |
|
|
| |
| const token = { |
| type: Token.Template, |
| value: code.slice(firstToken.start, lastTemplateToken.end), |
| }; |
|
|
| if (firstToken.loc) { |
| token.loc = { |
| start: firstToken.loc.start, |
| end: lastTemplateToken.loc.end, |
| }; |
| } |
|
|
| if (firstToken.range) { |
| token.start = firstToken.range[0]; |
| token.end = lastTemplateToken.range[1]; |
| token.range = [token.start, token.end]; |
| } |
|
|
| return token; |
| } |
|
|
| |
| |
| |
| |
| class TokenTranslator { |
| |
| |
| |
| |
| |
| |
| constructor(acornTokTypes, code) { |
| |
|
|
| |
| this._acornTokTypes = acornTokTypes; |
|
|
| |
| |
| this._tokens = []; |
|
|
| |
| this._curlyBrace = null; |
|
|
| |
| this._code = code; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| translate(token, extra) { |
| const type = token.type, |
| tt = this._acornTokTypes, |
| |
| |
| |
| |
| unknownTokenType = (token), |
| newToken = (unknownTokenType); |
|
|
| if (type === tt.name) { |
| newToken.type = Token.Identifier; |
|
|
| |
| if ("value" in token && token.value === "static") { |
| newToken.type = Token.Keyword; |
| } |
|
|
| if ( |
| extra.ecmaVersion > 5 && |
| "value" in token && |
| (token.value === "yield" || token.value === "let") |
| ) { |
| newToken.type = Token.Keyword; |
| } |
| } else if (type === tt.privateId) { |
| newToken.type = Token.PrivateIdentifier; |
| } else if ( |
| type === tt.semi || |
| type === tt.comma || |
| type === tt.parenL || |
| type === tt.parenR || |
| type === tt.braceL || |
| type === tt.braceR || |
| type === tt.dot || |
| type === tt.bracketL || |
| type === tt.colon || |
| type === tt.question || |
| type === tt.bracketR || |
| type === tt.ellipsis || |
| type === tt.arrow || |
| type === tt.jsxTagStart || |
| type === tt.incDec || |
| type === tt.starstar || |
| type === tt.jsxTagEnd || |
| type === tt.prefix || |
| type === tt.questionDot || |
| ("binop" in type && type.binop && !type.keyword) || |
| ("isAssign" in type && type.isAssign) |
| ) { |
| newToken.type = Token.Punctuator; |
| newToken.value = this._code.slice(token.start, token.end); |
| } else if (type === tt.jsxName) { |
| newToken.type = Token.JSXIdentifier; |
| } else if (type.label === "jsxText" || type === tt.jsxAttrValueToken) { |
| newToken.type = Token.JSXText; |
| } else if (type.keyword) { |
| if (type.keyword === "true" || type.keyword === "false") { |
| newToken.type = Token.Boolean; |
| } else if (type.keyword === "null") { |
| newToken.type = Token.Null; |
| } else { |
| newToken.type = Token.Keyword; |
| } |
| } else if (type === tt.num) { |
| newToken.type = Token.Numeric; |
| newToken.value = this._code.slice(token.start, token.end); |
| } else if (type === tt.string) { |
| if (extra.jsxAttrValueToken) { |
| extra.jsxAttrValueToken = false; |
| newToken.type = Token.JSXText; |
| } else { |
| newToken.type = Token.String; |
| } |
|
|
| newToken.value = this._code.slice(token.start, token.end); |
| } else if (type === tt.regexp) { |
| newToken.type = Token.RegularExpression; |
| const value = ( |
| "value" in token && token.value |
| ); |
|
|
| newToken.regex = { |
| flags: value.flags, |
| pattern: value.pattern, |
| }; |
| newToken.value = `/${value.pattern}/${value.flags}`; |
| } |
|
|
| return newToken; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| onToken(token, extra) { |
| const tt = this._acornTokTypes, |
| tokens = extra.tokens, |
| templateTokens = this._tokens; |
|
|
| |
| |
| |
| |
| |
| |
| const translateTemplateTokens = () => { |
| tokens.push(convertTemplatePart(this._tokens, this._code)); |
| this._tokens = []; |
| }; |
|
|
| if (token.type === tt.eof) { |
| |
| if (this._curlyBrace) { |
| tokens.push(this.translate(this._curlyBrace, extra)); |
| } |
|
|
| return; |
| } |
|
|
| if (token.type === tt.backQuote) { |
| |
| if (this._curlyBrace) { |
| tokens.push(this.translate(this._curlyBrace, extra)); |
| this._curlyBrace = null; |
| } |
|
|
| templateTokens.push(token); |
|
|
| |
| if (templateTokens.length > 1) { |
| translateTemplateTokens(); |
| } |
|
|
| return; |
| } |
| if (token.type === tt.dollarBraceL) { |
| templateTokens.push(token); |
| translateTemplateTokens(); |
| return; |
| } |
| if (token.type === tt.braceR) { |
| |
| if (this._curlyBrace) { |
| tokens.push(this.translate(this._curlyBrace, extra)); |
| } |
|
|
| |
| this._curlyBrace = token; |
| return; |
| } |
| if (token.type === tt.template || token.type === tt.invalidTemplate) { |
| if (this._curlyBrace) { |
| templateTokens.push(this._curlyBrace); |
| this._curlyBrace = null; |
| } |
|
|
| templateTokens.push(token); |
| return; |
| } |
|
|
| if (this._curlyBrace) { |
| tokens.push(this.translate(this._curlyBrace, extra)); |
| this._curlyBrace = null; |
| } |
|
|
| tokens.push(this.translate(token, extra)); |
| } |
| } |
|
|
| |
| |
| |
|
|
| export default TokenTranslator; |
|
|