Remove whitespace generation (#5833)
* Remove whitespace generation and rely on default printing Changes to printing: * Add newline after last empty SwitchCase * Add newlines around block comments if they are non-flow comments or contain newlines * Fix a few more fixtures
This commit is contained in:
committed by
Brian Ng
parent
bc29145465
commit
b3372a572d
@@ -329,7 +329,11 @@ export function ObjectTypeAnnotation(node: Object) {
|
||||
this.token("{");
|
||||
}
|
||||
|
||||
const props = node.properties.concat(node.callProperties, node.indexers);
|
||||
// TODO: remove the array fallbacks and instead enforce the types to require an array
|
||||
const props = node.properties.concat(
|
||||
node.callProperties || [],
|
||||
node.indexers || [],
|
||||
);
|
||||
|
||||
if (props.length) {
|
||||
this.space();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import SourceMap from "./source-map";
|
||||
import * as messages from "babel-messages";
|
||||
import Printer from "./printer";
|
||||
import type { Format } from "./printer";
|
||||
import Printer, { type Format } from "./printer";
|
||||
|
||||
/**
|
||||
* Babel's code generator, turns an ast into code, maintaining sourcemaps,
|
||||
@@ -10,10 +9,9 @@ import type { Format } from "./printer";
|
||||
|
||||
class Generator extends Printer {
|
||||
constructor(ast, opts = {}, code) {
|
||||
const tokens = ast.tokens || [];
|
||||
const format = normalizeOptions(code, opts);
|
||||
const map = opts.sourceMaps ? new SourceMap(opts, code) : null;
|
||||
super(format, map, tokens);
|
||||
super(format, map);
|
||||
|
||||
this.ast = ast;
|
||||
}
|
||||
|
||||
@@ -86,9 +86,12 @@ export const nodes = {
|
||||
* Test if SwitchCase needs whitespace.
|
||||
*/
|
||||
|
||||
SwitchCase(node: Object, parent: Object): ?WhitespaceObject {
|
||||
SwitchCase(node: Object, parent: Object): WhitespaceObject {
|
||||
return {
|
||||
before: node.consequent.length || parent.cases[0] === node,
|
||||
after:
|
||||
!node.consequent.length &&
|
||||
parent.cases[parent.cases.length - 1] === node,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -181,6 +184,32 @@ nodes.ObjectProperty = nodes.ObjectTypeProperty = nodes.ObjectMethod = function(
|
||||
}
|
||||
};
|
||||
|
||||
nodes.ObjectTypeCallProperty = function(
|
||||
node: Object,
|
||||
parent,
|
||||
): ?WhitespaceObject {
|
||||
if (
|
||||
parent.callProperties[0] === node &&
|
||||
(!parent.properties || !parent.properties.length)
|
||||
) {
|
||||
return {
|
||||
before: true,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
nodes.ObjectTypeIndexer = function(node: Object, parent): ?WhitespaceObject {
|
||||
if (
|
||||
parent.indexers[0] === node &&
|
||||
(!parent.properties || !parent.properties.length) &&
|
||||
(!parent.callProperties || !parent.callProperties.length)
|
||||
) {
|
||||
return {
|
||||
before: true,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns lists from node types that need whitespace.
|
||||
*/
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
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";
|
||||
|
||||
import * as generatorFunctions from "./generators";
|
||||
@@ -32,17 +29,15 @@ export type Format = {
|
||||
};
|
||||
|
||||
export default class Printer {
|
||||
constructor(format, map, tokens) {
|
||||
constructor(format, map) {
|
||||
this.format = format || {};
|
||||
this._buf = new Buffer(map);
|
||||
this._whitespace = tokens.length > 0 ? new Whitespace(tokens) : null;
|
||||
}
|
||||
|
||||
format: Format;
|
||||
inForStatementInitCounter: number = 0;
|
||||
|
||||
_buf: Buffer;
|
||||
_whitespace: Whitespace;
|
||||
_printStack: Array<Node> = [];
|
||||
_indent: number = 0;
|
||||
_insideAux: boolean = false;
|
||||
@@ -498,43 +493,13 @@ export default class Printer {
|
||||
}
|
||||
|
||||
let lines = 0;
|
||||
|
||||
if (node.start != null && !node._ignoreUserWhitespace && this._whitespace) {
|
||||
// user node
|
||||
if (leading) {
|
||||
const comments = node.leadingComments;
|
||||
const comment =
|
||||
comments &&
|
||||
find(
|
||||
comments,
|
||||
comment =>
|
||||
!!comment.loc && this.format.shouldPrintComment(comment.value),
|
||||
);
|
||||
|
||||
lines = this._whitespace.getNewlinesBefore(comment || node);
|
||||
} else {
|
||||
const comments = node.trailingComments;
|
||||
const comment =
|
||||
comments &&
|
||||
findLast(
|
||||
comments,
|
||||
comment =>
|
||||
!!comment.loc && this.format.shouldPrintComment(comment.value),
|
||||
);
|
||||
|
||||
lines = this._whitespace.getNewlinesAfter(comment || node);
|
||||
}
|
||||
} else {
|
||||
// generated node
|
||||
// don't add newlines at the beginning of the file
|
||||
if (this._buf.hasContent()) {
|
||||
if (!leading) lines++; // always include at least a single line after
|
||||
if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0;
|
||||
|
||||
let needs = n.needsWhitespaceAfter;
|
||||
if (leading) needs = n.needsWhitespaceBefore;
|
||||
const needs = leading ? n.needsWhitespaceBefore : n.needsWhitespaceAfter;
|
||||
if (needs(node, parent)) lines++;
|
||||
|
||||
// generated nodes can't add starting file whitespace
|
||||
if (!this._buf.hasContent()) lines = 0;
|
||||
}
|
||||
|
||||
this.newline(lines);
|
||||
@@ -563,23 +528,17 @@ export default class Printer {
|
||||
this._printedCommentStarts[comment.start] = true;
|
||||
}
|
||||
|
||||
// whitespace before
|
||||
this.newline(
|
||||
this._whitespace ? this._whitespace.getNewlinesBefore(comment) : 0,
|
||||
);
|
||||
const isBlockComment = comment.type === "CommentBlock";
|
||||
|
||||
// Always add a newline before a block comment
|
||||
this.newline(this._buf.hasContent() && isBlockComment ? 1 : 0);
|
||||
|
||||
if (!this.endsWith("[") && !this.endsWith("{")) this.space();
|
||||
|
||||
let val =
|
||||
comment.type === "CommentLine"
|
||||
? `//${comment.value}\n`
|
||||
: `/*${comment.value}*/`;
|
||||
let val = !isBlockComment ? `//${comment.value}\n` : `/*${comment.value}*/`;
|
||||
|
||||
//
|
||||
if (
|
||||
comment.type === "CommentBlock" &&
|
||||
this.format.indent.adjustMultilineComment
|
||||
) {
|
||||
if (isBlockComment && this.format.indent.adjustMultilineComment) {
|
||||
const offset = comment.loc && comment.loc.start.column;
|
||||
if (offset) {
|
||||
const newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
|
||||
@@ -600,12 +559,8 @@ export default class Printer {
|
||||
this._append(val);
|
||||
});
|
||||
|
||||
// whitespace after
|
||||
this.newline(
|
||||
(this._whitespace ? this._whitespace.getNewlinesAfter(comment) : 0) +
|
||||
// Subtract one to account for the line force-added above.
|
||||
(comment.type === "CommentLine" ? -1 : 0),
|
||||
);
|
||||
// Always add a newline after a block comment
|
||||
this.newline(isBlockComment ? 1 : 0);
|
||||
}
|
||||
|
||||
_printComments(comments?: Array<Object>) {
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/**
|
||||
* Get whitespace around tokens.
|
||||
*/
|
||||
|
||||
export default class Whitespace {
|
||||
constructor(tokens) {
|
||||
this.tokens = tokens;
|
||||
this.used = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all the newlines before a node.
|
||||
*/
|
||||
|
||||
getNewlinesBefore(node) {
|
||||
let startToken;
|
||||
let endToken;
|
||||
const tokens = this.tokens;
|
||||
|
||||
let index = this._findToken(
|
||||
token => token.start - node.start,
|
||||
0,
|
||||
tokens.length,
|
||||
);
|
||||
if (index >= 0) {
|
||||
while (index && node.start === tokens[index - 1].start) --index;
|
||||
startToken = tokens[index - 1];
|
||||
endToken = tokens[index];
|
||||
}
|
||||
|
||||
return this._getNewlinesBetween(startToken, endToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all the newlines after a node.
|
||||
*/
|
||||
|
||||
getNewlinesAfter(node) {
|
||||
let startToken;
|
||||
let endToken;
|
||||
const tokens = this.tokens;
|
||||
|
||||
let index = this._findToken(
|
||||
token => token.end - node.end,
|
||||
0,
|
||||
tokens.length,
|
||||
);
|
||||
if (index >= 0) {
|
||||
while (index && node.end === tokens[index - 1].end) --index;
|
||||
startToken = tokens[index];
|
||||
endToken = tokens[index + 1];
|
||||
if (endToken.type.label === ",") endToken = tokens[index + 2];
|
||||
}
|
||||
|
||||
if (endToken && endToken.type.label === "eof") {
|
||||
return 1;
|
||||
} else {
|
||||
return this._getNewlinesBetween(startToken, endToken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all the newlines between two tokens.
|
||||
*/
|
||||
|
||||
_getNewlinesBetween(startToken, endToken) {
|
||||
if (!endToken || !endToken.loc) return 0;
|
||||
|
||||
const start = startToken ? startToken.loc.end.line : 1;
|
||||
const end = endToken.loc.start.line;
|
||||
let lines = 0;
|
||||
|
||||
for (let line = start; line < end; line++) {
|
||||
if (typeof this.used[line] === "undefined") {
|
||||
this.used[line] = true;
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a token between start and end.
|
||||
*/
|
||||
|
||||
_findToken(test: Function, start: number, end: number): number {
|
||||
if (start >= end) return -1;
|
||||
const middle = (start + end) >>> 1;
|
||||
const match: number = test(this.tokens[middle]);
|
||||
if (match < 0) {
|
||||
return this._findToken(test, middle + 1, end);
|
||||
} else if (match > 0) {
|
||||
return this._findToken(test, start, middle);
|
||||
} else if (match === 0) {
|
||||
return middle;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user