diff --git a/packages/babel-generator/src/generators/expressions.js b/packages/babel-generator/src/generators/expressions.js index 0c2ca52cbd..a6cc4548d0 100644 --- a/packages/babel-generator/src/generators/expressions.js +++ b/packages/babel-generator/src/generators/expressions.js @@ -1,13 +1,9 @@ /* eslint max-len: 0 */ -import isInteger from "lodash/isInteger"; import isNumber from "lodash/isNumber"; import * as t from "babel-types"; import * as n from "../node"; -const SCIENTIFIC_NOTATION = /e/i; -const ZERO_DECIMAL_INTEGER = /\.0+$/; -const NON_DECIMAL_LITERAL = /^0[box]/; export function UnaryExpression(node: Object) { if (node.operator === "void" || node.operator === "delete" || node.operator === "typeof") { @@ -209,17 +205,6 @@ export function MemberExpression(node: Object) { this.print(node.property, node); this.token("]"); } else { - if (t.isNumericLiteral(node.object)) { - let val = this.getPossibleRaw(node.object) || node.object.value; - if (isInteger(+val) && - !NON_DECIMAL_LITERAL.test(val) && - !SCIENTIFIC_NOTATION.test(val) && - !ZERO_DECIMAL_INTEGER.test(val) && - !this.endsWith(".")) { - this.token("."); - } - } - this.token("."); this.print(node.property, node); } diff --git a/packages/babel-generator/src/generators/types.js b/packages/babel-generator/src/generators/types.js index c1497250b3..9d7ecde738 100644 --- a/packages/babel-generator/src/generators/types.js +++ b/packages/babel-generator/src/generators/types.js @@ -124,12 +124,8 @@ export function NullLiteral() { export function NumericLiteral(node: Object) { let raw = this.getPossibleRaw(node); - if (raw != null) { - this.word(raw); - return; - } - this.word(node.value + ""); + this.number(raw == null ? node.value + "" : raw); } export function StringLiteral(node: Object, parent: Object) { diff --git a/packages/babel-generator/src/printer.js b/packages/babel-generator/src/printer.js index ad3884e617..45aa2be442 100644 --- a/packages/babel-generator/src/printer.js +++ b/packages/babel-generator/src/printer.js @@ -2,12 +2,17 @@ import find from "lodash/find"; import findLast from "lodash/findLast"; +import isInteger from "lodash/isInteger"; import repeat from "lodash/repeat"; import Buffer from "./buffer"; import * as n from "./node"; import Whitespace from "./whitespace"; import * as t from "babel-types"; +const SCIENTIFIC_NOTATION = /e/i; +const ZERO_DECIMAL_INTEGER = /\.0+$/; +const NON_DECIMAL_LITERAL = /^0[box]/; + export type Format = { shouldPrintComment: (comment: string) => boolean; retainLines: boolean; @@ -44,6 +49,8 @@ export default class Printer { _parenPushNewlineState: ?Object = null; _printAuxAfterOnNextUserNode: boolean = false; _printedComments: WeakSet = new WeakSet(); + _endsWithInteger = false; + _endsWithWord = false; generate(ast) { this.print(ast); @@ -126,6 +133,23 @@ export default class Printer { this._endsWithWord = true; } + /** + * Writes a number token so that we can validate if it is an integer. + */ + + number(str: string): void { + this.word(str); + + // Integer tokens need special handling because they cannot have '.'s inserted + // immediately after them. + this._endsWithInteger = + isInteger(+str) && + !NON_DECIMAL_LITERAL.test(str) && + !SCIENTIFIC_NOTATION.test(str) && + !ZERO_DECIMAL_INTEGER.test(str) && + str[str.length - 1] !== "."; + } + /** * Writes a simple token. */ @@ -137,7 +161,10 @@ export default class Printer { // Need spaces for operators of the same kind to avoid: `a+++b` (str[0] === "+" && this.endsWith("+")) || - (str[0] === "-" && this.endsWith("-"))) { + (str[0] === "-" && this.endsWith("-")) || + + // Needs spaces to avoid changing '34' to '34.', which would still be a valid number. + (str[0] === "." && this._endsWithInteger)) { this._space(); } @@ -207,6 +234,7 @@ export default class Printer { else this._buf.append(str); this._endsWithWord = false; + this._endsWithInteger = false; } _maybeIndent(str: string): void {