diff --git a/packages/babylon/package.json b/packages/babylon/package.json index b4e82c7dec..07856635c1 100644 --- a/packages/babylon/package.json +++ b/packages/babylon/package.json @@ -25,6 +25,8 @@ "devDependencies": { "@babel/helper-fixtures": "7.0.0-beta.32", "babel-plugin-transform-for-of-as-array": "1.0.4", + "babel-plugin-transform-charcodes": "0.0.10", + "charcodes": "0.0.10", "rollup": "^0.50.0", "rollup-plugin-babel": "^4.0.0-beta.0", "rollup-plugin-node-resolve": "^3.0.0", diff --git a/packages/babylon/rollup.config.js b/packages/babylon/rollup.config.js index 7ed7a136b4..f627c6a860 100644 --- a/packages/babylon/rollup.config.js +++ b/packages/babylon/rollup.config.js @@ -24,7 +24,7 @@ export default { ], "@babel/flow", ], - plugins: ["transform-for-of-as-array"], + plugins: ["transform-charcodes", "transform-for-of-as-array"], }), nodeResolve(), ], diff --git a/packages/babylon/src/plugins/jsx/index.js b/packages/babylon/src/plugins/jsx/index.js index 9478bec17c..15444d8738 100644 --- a/packages/babylon/src/plugins/jsx/index.js +++ b/packages/babylon/src/plugins/jsx/index.js @@ -1,5 +1,7 @@ // @flow +import * as charCodes from "charcodes"; + import XHTMLEntities from "./xhtml"; import type Parser from "../../parser"; import { TokenType, types as tt } from "../../tokenizer/types"; @@ -84,10 +86,10 @@ export default (superClass: Class): Class => const ch = this.input.charCodeAt(this.state.pos); switch (ch) { - case 60: // "<" - case 123: // "{" + case charCodes.lessThan: + case charCodes.leftCurlyBrace: if (this.state.pos === this.state.start) { - if (ch === 60 && this.state.exprAllowed) { + if (ch === charCodes.lessThan && this.state.exprAllowed) { ++this.state.pos; return this.finishToken(tt.jsxTagStart); } @@ -96,7 +98,7 @@ export default (superClass: Class): Class => out += this.input.slice(chunkStart, this.state.pos); return this.finishToken(tt.jsxText, out); - case 38: // "&" + case charCodes.ampersand: out += this.input.slice(chunkStart, this.state.pos); out += this.jsxReadEntity(); chunkStart = this.state.pos; @@ -118,7 +120,10 @@ export default (superClass: Class): Class => const ch = this.input.charCodeAt(this.state.pos); let out; ++this.state.pos; - if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) { + if ( + ch === charCodes.carriageReturn && + this.input.charCodeAt(this.state.pos) === charCodes.lineFeed + ) { ++this.state.pos; out = normalizeCRLF ? "\n" : "\r\n"; } else { @@ -140,8 +145,7 @@ export default (superClass: Class): Class => const ch = this.input.charCodeAt(this.state.pos); if (ch === quote) break; - if (ch === 38) { - // "&" + if (ch === charCodes.ampersand) { out += this.input.slice(chunkStart, this.state.pos); out += this.jsxReadEntity(); chunkStart = this.state.pos; @@ -205,7 +209,7 @@ export default (superClass: Class): Class => const start = this.state.pos; do { ch = this.input.charCodeAt(++this.state.pos); - } while (isIdentifierChar(ch) || ch === 45); // "-" + } while (isIdentifierChar(ch) || ch === charCodes.dash); return this.finishToken( tt.jsxName, this.input.slice(start, this.state.pos), @@ -513,17 +517,20 @@ export default (superClass: Class): Class => return this.jsxReadWord(); } - if (code === 62) { + if (code === charCodes.greaterThan) { ++this.state.pos; return this.finishToken(tt.jsxTagEnd); } - if ((code === 34 || code === 39) && context === tc.j_oTag) { + if ( + (code === charCodes.quotationMark || code === charCodes.apostrophe) && + context === tc.j_oTag + ) { return this.jsxReadString(code); } } - if (code === 60 && this.state.exprAllowed) { + if (code === charCodes.lessThan && this.state.exprAllowed) { ++this.state.pos; return this.finishToken(tt.jsxTagStart); } diff --git a/packages/babylon/src/tokenizer/index.js b/packages/babylon/src/tokenizer/index.js index b08448f7f6..608a85bf79 100644 --- a/packages/babylon/src/tokenizer/index.js +++ b/packages/babylon/src/tokenizer/index.js @@ -4,6 +4,7 @@ import type { Options } from "../options"; import type { Position } from "../util/location"; +import * as charCodes from "charcodes"; import { isIdentifierStart, isIdentifierChar, @@ -26,63 +27,65 @@ import State from "./state"; const forbiddenNumericSeparatorSiblings = { decBinOct: [ - 46, // . - 66, // B - 69, // E - 79, // O - 95, // _ (multiple separators are not allowed) - 98, // b - 101, // e - 111, // o + charCodes.dot, + charCodes.uppercaseB, + charCodes.uppercaseE, + charCodes.uppercaseO, + charCodes.underscore, // multiple separators are not allowed + charCodes.lowercaseB, + charCodes.lowercaseE, + charCodes.lowercaseO, ], hex: [ - 46, // . - 88, // X - 95, // _ (multiple separators are not allowed) - 120, // x + charCodes.dot, + charCodes.uppercaseX, + charCodes.underscore, // multiple separators are not allowed + charCodes.lowercaseX, ], }; const allowedNumericSeparatorSiblings = {}; allowedNumericSeparatorSiblings.bin = [ // 0 - 1 - 48, - 49, + charCodes.digit0, + charCodes.digit1, ]; allowedNumericSeparatorSiblings.oct = [ // 0 - 7 ...allowedNumericSeparatorSiblings.bin, - 50, - 51, - 52, - 53, - 54, - 55, + + charCodes.digit2, + charCodes.digit3, + charCodes.digit4, + charCodes.digit5, + charCodes.digit6, + charCodes.digit7, ]; allowedNumericSeparatorSiblings.dec = [ // 0 - 9 ...allowedNumericSeparatorSiblings.oct, - 56, - 57, + + charCodes.digit8, + charCodes.digit9, ]; allowedNumericSeparatorSiblings.hex = [ // 0 - 9, A - F, a - f, ...allowedNumericSeparatorSiblings.dec, - // A - F - 65, - 66, - 67, - 68, - 69, - 70, - // a - f - 97, - 98, - 99, - 100, - 101, - 102, + + charCodes.uppercaseA, + charCodes.uppercaseB, + charCodes.uppercaseC, + charCodes.uppercaseD, + charCodes.uppercaseE, + charCodes.uppercaseF, + + charCodes.lowercaseA, + charCodes.lowercaseB, + charCodes.lowercaseC, + charCodes.lowercaseD, + charCodes.lowercaseE, + charCodes.lowercaseF, ]; // Object type used to represent tokens. Note that normally, tokens @@ -230,7 +233,7 @@ export default class Tokenizer extends LocationParser { readToken(code: number): void { // Identifier or keyword. '\uXXXX' sequences are allowed in // identifiers, so '\' also dispatches to that. - if (isIdentifierStart(code) || code === 92 /* '\' */) { + if (isIdentifierStart(code) || code === charCodes.backslash) { this.readWord(); } else { this.getTokenFromCode(code); @@ -301,10 +304,10 @@ export default class Tokenizer extends LocationParser { let ch = this.input.charCodeAt((this.state.pos += startSkip)); if (this.state.pos < this.input.length) { while ( - ch !== 10 && - ch !== 13 && - ch !== 8232 && - ch !== 8233 && + ch !== charCodes.lineFeed && + ch !== charCodes.carriageReturn && + ch !== charCodes.lineSeparator && + ch !== charCodes.paragraphSeparator && ++this.state.pos < this.input.length ) { ch = this.input.charCodeAt(this.state.pos); @@ -328,31 +331,33 @@ export default class Tokenizer extends LocationParser { loop: while (this.state.pos < this.input.length) { const ch = this.input.charCodeAt(this.state.pos); switch (ch) { - case 32: // space - case 160: // non-breaking space + case charCodes.space: + case charCodes.nonBreakingSpace: ++this.state.pos; break; - case 13: // '\r' carriage return - if (this.input.charCodeAt(this.state.pos + 1) === 10) { + case charCodes.carriageReturn: + if ( + this.input.charCodeAt(this.state.pos + 1) === charCodes.lineFeed + ) { ++this.state.pos; } - case 10: // '\n' line feed - case 8232: // line separator - case 8233: // paragraph separator + case charCodes.lineFeed: + case charCodes.lineSeparator: + case charCodes.paragraphSeparator: ++this.state.pos; ++this.state.curLine; this.state.lineStart = this.state.pos; break; - case 47: // '/' + case charCodes.slash: switch (this.input.charCodeAt(this.state.pos + 1)) { - case 42: // '*' + case charCodes.asterisk: this.skipBlockComment(); break; - case 47: + case charCodes.slash: this.skipLineComment(2); break; @@ -363,8 +368,9 @@ export default class Tokenizer extends LocationParser { default: if ( - (ch > 8 && ch < 14) || - (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) + (ch > charCodes.backSpace && ch < charCodes.shiftOut) || + (ch >= charCodes.oghamSpaceMark && + nonASCIIwhitespace.test(String.fromCharCode(ch))) ) { ++this.state.pos; } else { @@ -400,14 +406,13 @@ export default class Tokenizer extends LocationParser { // readToken_dot(): void { const next = this.input.charCodeAt(this.state.pos + 1); - if (next >= 48 && next <= 57) { + if (next >= charCodes.digit0 && next <= charCodes.digit9) { this.readNumber(true); return; } const next2 = this.input.charCodeAt(this.state.pos + 2); - if (next === 46 && next2 === 46) { - // 46 = dot '.' + if (next === charCodes.dot && next2 === charCodes.dot) { this.state.pos += 3; this.finishToken(tt.ellipsis); } else { @@ -425,7 +430,7 @@ export default class Tokenizer extends LocationParser { } const next = this.input.charCodeAt(this.state.pos + 1); - if (next === 61) { + if (next === charCodes.equalsTo) { this.finishOp(tt.assign, 2); } else { this.finishOp(tt.slash, 1); @@ -434,19 +439,19 @@ export default class Tokenizer extends LocationParser { readToken_mult_modulo(code: number): void { // '%*' - let type = code === 42 ? tt.star : tt.modulo; + let type = code === charCodes.asterisk ? tt.star : tt.modulo; let width = 1; let next = this.input.charCodeAt(this.state.pos + 1); const exprAllowed = this.state.exprAllowed; // Exponentiation operator ** - if (code === 42 && next === 42) { + if (code === charCodes.asterisk && next === charCodes.asterisk) { width++; next = this.input.charCodeAt(this.state.pos + 2); type = tt.exponent; } - if (next === 61 && !exprAllowed) { + if (next === charCodes.equalsTo && !exprAllowed) { width++; type = tt.assign; } @@ -459,34 +464,40 @@ export default class Tokenizer extends LocationParser { const next = this.input.charCodeAt(this.state.pos + 1); if (next === code) { - this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2); + this.finishOp( + code === charCodes.verticalBar ? tt.logicalOR : tt.logicalAND, + 2, + ); return; } - if (code === 124) { + if (code === charCodes.verticalBar) { // '|>' - if (next === 62) { + if (next === charCodes.greaterThan) { this.finishOp(tt.pipeline, 2); return; - } else if (next === 125 && this.hasPlugin("flow")) { + } else if (next === charCodes.rightCurlyBrace && this.hasPlugin("flow")) { // '|}' this.finishOp(tt.braceBarR, 2); return; } } - if (next === 61) { + if (next === charCodes.equalsTo) { this.finishOp(tt.assign, 2); return; } - this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1); + this.finishOp( + code === charCodes.verticalBar ? tt.bitwiseOR : tt.bitwiseAND, + 1, + ); } readToken_caret(): void { // '^' const next = this.input.charCodeAt(this.state.pos + 1); - if (next === 61) { + if (next === charCodes.equalsTo) { this.finishOp(tt.assign, 2); } else { this.finishOp(tt.bitwiseXOR, 1); @@ -499,9 +510,9 @@ export default class Tokenizer extends LocationParser { if (next === code) { if ( - next === 45 && + next === charCodes.dash && !this.inModule && - this.input.charCodeAt(this.state.pos + 2) === 62 && + this.input.charCodeAt(this.state.pos + 2) === charCodes.greaterThan && lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.pos)) ) { // A `-->` line comment @@ -514,7 +525,7 @@ export default class Tokenizer extends LocationParser { return; } - if (next === 61) { + if (next === charCodes.equalsTo) { this.finishOp(tt.assign, 2); } else { this.finishOp(tt.plusMin, 1); @@ -528,8 +539,11 @@ export default class Tokenizer extends LocationParser { if (next === code) { size = - code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2; - if (this.input.charCodeAt(this.state.pos + size) === 61) { + code === charCodes.greaterThan && + this.input.charCodeAt(this.state.pos + 2) === charCodes.greaterThan + ? 3 + : 2; + if (this.input.charCodeAt(this.state.pos + size) === charCodes.equalsTo) { this.finishOp(tt.assign, size + 1); return; } @@ -538,11 +552,11 @@ export default class Tokenizer extends LocationParser { } if ( - next === 33 && - code === 60 && + next === charCodes.exclamationMark && + code === charCodes.lessThan && !this.inModule && - this.input.charCodeAt(this.state.pos + 2) === 45 && - this.input.charCodeAt(this.state.pos + 3) === 45 + this.input.charCodeAt(this.state.pos + 2) === charCodes.dash && + this.input.charCodeAt(this.state.pos + 3) === charCodes.dash ) { // `