Perform number decimal checks at the token level.

This commit is contained in:
Logan Smyth 2016-07-17 11:31:47 -07:00
parent 9f49c99774
commit 1b527eb23c
3 changed files with 30 additions and 21 deletions

View File

@ -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);
}

View File

@ -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) {

View File

@ -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 {