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:
Daniel Tschinder 2017-06-27 19:57:02 -07:00 committed by Brian Ng
parent bc29145465
commit b3372a572d
379 changed files with 1974 additions and 1109 deletions

View File

@ -3,9 +3,6 @@
/*
Test comment
*/
arr.map(function (x) {
return x * MULTIPLIER;
});
// END OF FILE
}); // END OF FILE

View File

@ -480,7 +480,7 @@ describe("api", function() {
}).then(function(result) {
assert.equal(
result.code,
"/*before*/start;\n/*after*/class Foo {}\n/*before*/end;\n/*after*/",
"/*before*/\nstart;\n\n/*after*/\nclass Foo {}\n\n/*before*/\nend;\n\n/*after*/",
);
});
});

View File

@ -1,3 +1,2 @@
export function foo() {}
export function bar() {}
export function bar() {}

View File

@ -3,13 +3,14 @@ var Foo = function (_Bar) {
function Foo(options) {
babelHelpers.classCallCheck(this, Foo);
var parentOptions = {};
parentOptions.init = function () {
this;
};
return babelHelpers.possibleConstructorReturn(this, (Foo.__proto__ || Object.getPrototypeOf(Foo)).call(this, parentOptions));
}
return Foo;
}(Bar);
}(Bar);

View File

@ -1,5 +1,4 @@
function test() {
var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "hi";
return x;
}

View File

@ -9,4 +9,4 @@ function foo() {
}
return output;
}
}

View File

@ -10,7 +10,9 @@ function f() {
return _ref.apply(this, arguments);
};
}();
};
}
;
class Class {
m() {
@ -28,4 +30,5 @@ class Class {
}();
})();
}
}
}

View File

@ -3,5 +3,4 @@
var _values = values;
value = _values[fieldName];
rest = babelHelpers.objectWithoutProperties(_values, [fieldName]);
var error = void 0;

View File

@ -1,4 +1,2 @@
#!/usr/bin/env node
foobar();
foobar();

View File

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

View File

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

View File

@ -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.
*/

View File

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

View File

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

View File

@ -1,5 +1,6 @@
function foo() {
bar();
if (foo) {
bar();
}

View File

@ -1,6 +1,7 @@
function foo() {
bar();
if (foo) {
bar();
}
}
}

View File

@ -1,5 +1,6 @@
function foo() {
bar();
if (foo) {
bar();
}

View File

@ -1,9 +1,9 @@
var single = 'quotes';
var outnumber = 'double';
var moreSingleQuotesThanDouble = '!';
React.createClass({
render() {
return <View multiple="attributes" attribute="If parent is JSX keep double quote" />;
}
});
});

View File

@ -1,8 +1,6 @@
function test() {
/*
* this is comment
*/
var i = 20;
}
}

View File

@ -1,7 +1,6 @@
// from #23
/**/
/*
*/
*/

View File

@ -1,4 +1,6 @@
// from #23
/**/
/*
*/
*/

View File

@ -3,9 +3,10 @@ var test = {
* Before bracket init
*/
["a"]: "1",
[/*
* Inside bracket init
*/
[
/*
* Inside bracket init
*/
"b"]: "2"
},
ok = 42;
ok = 42;

View File

@ -3,25 +3,20 @@ var test = {
* Before bracket init
*/
["a"]: "1",
[/*
* Inside bracket init
*/
[
/*
* Inside bracket init
*/
"b"]: "2",
["c"
/*
* After bracket key
*/]: "3",
*/
]: "3",
// Before bracket, line comment
["d"]: "4",
[
// Inside bracket, line comment
[// Inside bracket, line comment
"e"]: "5",
["f"
// After bracket, line comment
["f" // After bracket, line comment
]: "6"
};
};

View File

@ -1,6 +1,11 @@
!function () {} //
, 42;
!{ get 42() {} //
, foo: 42 };
!{
get 42() {} //
,
foo: 42
};
(function () {} //
);
);

View File

@ -1,5 +1,4 @@
if (cond)
// Leading to if-block
if (cond) // Leading to if-block
{
print("hello");
} // Trailing to if-block
} // Trailing to if-block

View File

@ -1,3 +1,2 @@
if (cond)
// Leading to EmptyStatement
; // Trailing to EmptyStatement
if (cond) // Leading to EmptyStatement
; // Trailing to EmptyStatement

View File

@ -2,6 +2,6 @@ function test() {
// Leading if statement
if (cond) {
print("hello");
}
// Trailing if-block statement
}
} // Trailing if-block statement
}

View File

@ -3,10 +3,11 @@ var test = {
* Test 2
*/
a: "1",
/*
* Test 1
*/
b: "2",
// Test 3
c: "3"
};
};

View File

@ -19,11 +19,7 @@
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function test() {}
// Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
function test() {} // Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@ -43,4 +39,4 @@ function test() {}
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -21,9 +21,7 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
function test() {}
/*
Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
@ -46,4 +44,4 @@ function test() {}
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/

View File

@ -1,3 +1,2 @@
// Leading
var i = 20;
// Trailing
var i = 20; // Trailing

View File

@ -8,7 +8,6 @@ function test() {
* Leading comment 2
*
*/
var i = 20;
/*
* Trailing comment
@ -19,4 +18,4 @@ function test() {
* Trailing comment 2
*
*/
}
}

View File

@ -1,10 +1,8 @@
function test() {
var
// Leading to VariableDeclarator
var // Leading to VariableDeclarator
// Leading to VariableDeclarator
i = 20,
// Leading to VariableDeclarator
// Leading to VariableDeclarator
// Leading to VariableDeclarator
j = 20;
}
}

View File

@ -1,18 +1,20 @@
{
var t = 20; /*
* This is trailing comment
*/
var t = 20;
/*
* This is trailing comment
*/
}
{
var tt = 20; /*
* This is trailing comment
*/
var tt = 20;
/*
* This is trailing comment
*/
}
{
{
var t = 20; /*
* This is trailing comment
*/
var t = 20;
/*
* This is trailing comment
*/
}
}
}

View File

@ -5,8 +5,13 @@
//for (var i = 10 + (10 in []) in []);
//for (var i = 10 + 10 in [] in []);
for (var i = (1 in []);;);
for ((1 in []);;);
for (1 * (1 in []);;);
for (1 * (1 + 1 in []);;);
for (1 * (1 + 1 in []);;);
for (1 * (1 + (1 in []));;);
for (1 * (1 + (1 in []));;);

View File

@ -1,4 +1,5 @@
for ((a in b) ? a : b; i;);
for (function () {
for (;;);
} && (a in b);;);
} && (a in b);;);

View File

@ -1,7 +1,13 @@
const bar1 = (x: number): string => {};
const bar2 = (x?) => {};
const bar3 = (x?: string) => {};
const bar4 = x => {};
const bar5 = (x): string => {};
const bar6 = (x: number) => {};
const bar7 = <T>(x) => {};
const bar7 = <T>(x) => {};

View File

@ -1,5 +1,18 @@
var a: { (): number };
var a: { (): number };
var a: { y: string, (): number, (x: string): string, };
var a: { <T>(x: T): number };
interface A { (): number };
var a: {
(): number
};
var a: {
(): number
};
var a: {
y: string,
(): number,
(x: string): string,
};
var a: {
<T>(x: T): number
};
interface A {
(): number
}
;

View File

@ -5,10 +5,19 @@ declare export function foo(): void;
declare export function foo<T>(): void;
declare export function foo(x: number, y: string): void;
declare export class A {}
declare export class A<T> extends B<T> { x: number }
declare export class A { static foo: () => number, static x: string, }
declare export class A { static [indexer: number]: string }
declare export class A { static (): number }
declare export class A<T> extends B<T> {
x: number
}
declare export class A {
static foo: () => number,
static x: string,
}
declare export class A {
static [indexer: number]: string
}
declare export class A {
static (): number
}
declare export class A mixins B<T>, C {}
declare export default class A {}
declare export default function foo(): void;
@ -17,8 +26,7 @@ declare export * from 'asd';
declare export { a, b };
declare export {};
declare export { c, d } from 'bar';
declare module B {
declare export type B = {};
declare export interface Moon {}
}
}

View File

@ -7,8 +7,12 @@ declare module A {
declare function foo(): number;
}
declare module A {
declare class B { foo: () => number }
declare class B {
foo: () => number
}
}
declare module A {
declare module.exports: { foo: () => number }
}
declare module.exports: {
foo: () => number
}
}

View File

@ -5,17 +5,36 @@ declare function foo(): void;
declare function foo<T>(): void;
declare function foo(x: number, y: string): void;
declare class A {}
declare class A<T> extends B<T> { x: number }
declare class A { static foo: () => number, static x: string, }
declare class A { static [indexer: number]: string }
declare class A { static (): number }
declare class B { (): number }
declare class A<T> extends B<T> {
x: number
}
declare class A {
static foo: () => number,
static x: string,
}
declare class A {
static [indexer: number]: string
}
declare class A {
static (): number
}
declare class B {
(): number
}
declare class A mixins B<T>, C {}
declare type A = string;
declare type T<U> = { [k: string]: U };
declare type T<U> = {
[k: string]: U
};
declare type B = {
fn?: (foo: string) => void
};
declare interface I { foo: string }
declare interface I<T> { foo: T }
declare module.exports: { foo: string }
declare interface I {
foo: string
}
declare interface I<T> {
foo: T
}
declare module.exports: {
foo: string
}

View File

@ -1,21 +1,61 @@
class C1<+T, -U> {}
function f<+T, -U>() {}
type T<+T, -U> = {};
type T = { +p: T };
type T = { -p: T };
type T = { +[k: K]: V };
type T = { -[k: K]: V };
interface I { +p: T };
interface I { -p: T };
interface I { +[k: K]: V };
interface I { -[k: K]: V };
declare class I { +p: T };
declare class I { -p: T };
declare class I { +[k: K]: V };
declare class I { -[k: K]: V };
type T = {
+p: T
};
type T = {
-p: T
};
type T = {
+[k: K]: V
};
type T = {
-[k: K]: V
};
interface I {
+p: T
}
;
interface I {
-p: T
}
;
interface I {
+[k: K]: V
}
;
interface I {
-[k: K]: V
}
;
declare class I {
+p: T
}
;
declare class I {
-p: T
}
;
declare class I {
+[k: K]: V
}
;
declare class I {
-[k: K]: V
}
;
class C2 {
+p: T = e;
};
}
;
class C3 {
-p: T = e;
};
}
;

View File

@ -1,9 +1,23 @@
interface A {};
interface A extends B {};
interface A<T> extends B<T>, C<T> {};
interface A { foo: () => number };
interface Dictionary { length: number, [index: string]: string, };
interface A {}
;
interface A extends B {}
;
interface A<T> extends B<T>, C<T> {}
;
interface A {
foo: () => number
}
;
interface Dictionary {
length: number,
[index: string]: string,
}
;
class Foo implements Bar {}
class Foo extends Bar implements Bat, Man<number> {}
class Foo extends class Bar implements Bat {} {}
class Foo extends class Bar implements Bat {} implements Man {}
class Foo extends class Bar implements Bat {} implements Man {}

View File

@ -1,7 +1,18 @@
type U = {};
type V = {};
type T = { ...U };
type T = { ...U, ...V, };
type T = { p: V, ...U, };
type T = { ...U, p: V, };
type T = { ...{} | { p: V } };
type T = { ...U
};
type T = { ...U,
...V,
};
type T = {
p: V,
...U,
};
type T = { ...U,
p: V,
};
type T = { ...{} | {
p: V
}
};

View File

@ -1,2 +1,3 @@
function createElement(tagName: "div"): HTMLDivElement {}
function createElement(tagName: 'div'): HTMLDivElement {}
function createElement(tagName: 'div'): HTMLDivElement {}

View File

@ -2,4 +2,5 @@ class Foo {
bar(): this {
return this;
}
}
}

View File

@ -2,7 +2,9 @@ type FBID = number;
type Foo<T> = Bar<T>;
type Maybe<T> = _Maybe<T, *>;
export type Foo = number;
type union = { type: "A" } | { type: "B" };
type overloads = (x: string) => number & (x: number) => string;
type union = {
type: "A"
} | {
type: "B"
};
type overloads = (x: string) => number & (x: number) => string;

View File

@ -1,94 +1,213 @@
function foo(numVal: any) {}
function foo(numVal: number) {}
function foo(numVal: number, strVal: string) {}
function foo(numVal: number, untypedVal) {}
function foo(untypedVal, numVal: number) {}
function foo(nullableNum: ?number) {}
function foo(callback: () => void) {}
function foo(callback: () => number) {}
function foo(callback: (_: boolean) => number) {}
function foo(callback: (_1: boolean, _2: string) => number) {}
function foo(callback: (_1: boolean, ...foo: Array<number>) => number) {}
function foo(): number {}
function foo(): () => void {}
function foo(): (_: boolean) => number {}
function foo(): (_?: boolean) => number {}
function foo(): {} {}
function foo<T>() {}
function foo<T, S>() {}
function foo<T: F>() {}
a = function <T, S>() {};
a = { set fooProp(value: number) {} };
a = { set fooProp(value: number): void {} };
a = { get fooProp(): number {} };
a = { id<T>(x: T): T {} };
a = { *id<T>(x: T): T {} };
a = { async id<T>(x: T): T {} };
a = { 123<T>(x: T): T {} };
a = {
set fooProp(value: number) {}
};
a = {
set fooProp(value: number): void {}
};
a = {
get fooProp(): number {}
};
a = {
id<T>(x: T): T {}
};
a = {
*id<T>(x: T): T {}
};
a = {
async id<T>(x: T): T {}
};
a = {
123<T>(x: T): T {}
};
class Foo {
set fooProp(value: number) {}
}
class Foo {
set fooProp(value: number): void {}
}
class Foo {
get fooProp(): number {}
}
var numVal: number;
var numVal: empty;
var numVal: mixed;
var numVal: number = otherNumVal;
var a: { numVal: number };
var a: { numVal: number };
var a: { numVal: number, [indexer: string]: number, };
var a: ?{ numVal: number };
var a: { numVal: number, strVal: string, };
var a: { subObj: { strVal: string } };
var a: { subObj: ?{ strVal: string } };
var a: { param1: number, param2: string, };
var a: { param1: number, param2?: string, };
var a: { [a: number]: string, [b: number]: string, };
var a: { add: (x: number, ...y: Array<string>) => void };
var a: { subtract: (x: number, ...y: Array<string>) => void };
var a: { id: <T>(x: T) => T };
var a: {
numVal: number
};
var a: {
numVal: number
};
var a: {
numVal: number,
[indexer: string]: number,
};
var a: ?{
numVal: number
};
var a: {
numVal: number,
strVal: string,
};
var a: {
subObj: {
strVal: string
}
};
var a: {
subObj: ?{
strVal: string
}
};
var a: {
param1: number,
param2: string,
};
var a: {
param1: number,
param2?: string,
};
var a: {
[a: number]: string,
[b: number]: string,
};
var a: {
add: (x: number, ...y: Array<string>) => void
};
var a: {
subtract: (x: number, ...y: Array<string>) => void
};
var a: {
id: <T>(x: T) => T
};
var a: Array<number> = [1, 2, 3];
a = class Foo<T> {};
a = class Foo<T> extends Bar<T> {};
class Foo<T> {}
class Foo<T> extends Bar<T> {}
class Foo<T> extends mixin(Bar) {}
class Foo<T> {
bar<U>(): number {
return 42;
}
}
class Foo {
"bar"<T>() {}
}
function foo(requiredParam, optParam?) {}
class Foo {
prop1: string;
prop2: number;
}
class Foo {
static prop1: string;
prop2: number;
}
var x: number | string = 4;
class Array {
concat(items: number | string) {}
}
var x: () => number | () => string = fn;
var x: typeof Y = Y;
var x: typeof Y | number = Y;
var { x }: { x: string } = { x: "hello" };
var { x }: { x: string } = { x: "hello" };
var {
x
}: {
x: string
} = {
x: "hello"
};
var {
x
}: {
x: string
} = {
x: "hello"
};
var [x]: Array<string> = ["hello"];
function foo({ x }: { x: string }) {}
function foo({
x
}: {
x: string
}) {}
function foo([x]: Array<string>) {}
function foo(...rest: Array<number>) {}
(function (...rest: Array<number>) {});
(...rest: Array<number>) => rest;
var a: Map<string, Array<string>>;
var a: Map<string, Array<string>>;
var a: number[];
@ -109,21 +228,64 @@ import { type Foo as Bar } from "bar";
import { typeof Foo as Bar } from "bar";
export type { foo };
export type { bar } from "bar";
export interface baz { p: number };
export interface qux<T> { p: T };
export interface baz {
p: number
}
;
export interface qux<T> {
p: T
}
;
var a: ?Array<?string>;
var a: {| numVal: number |};
var a: {| numVal: number |};
var a: {| numVal: number, [indexer: string]: number, |};
var a: ?{| numVal: number |};
var a: {| numVal: number, strVal: string, |};
var a: {| subObj: { strVal: string } |};
var a: {| subObj: ?{ strVal: string } |};
var a: {| param1: number, param2: string, |};
var a: {| param1: number, param2?: string, |};
var a: {| [a: number]: string, [b: number]: string, |};
var a: {| add: (x: number, ...y: Array<string>) => void |};
var a: {| subtract: (x: number, ...y: Array<string>) => void |};
var a: {| id: <T>(x: T) => T |};
var a: {|
numVal: number
|};
var a: {|
numVal: number
|};
var a: {|
numVal: number,
[indexer: string]: number,
|};
var a: ?{|
numVal: number
|};
var a: {|
numVal: number,
strVal: string,
|};
var a: {|
subObj: {
strVal: string
}
|};
var a: {|
subObj: ?{
strVal: string
}
|};
var a: {|
param1: number,
param2: string,
|};
var a: {|
param1: number,
param2?: string,
|};
var a: {|
[a: number]: string,
[b: number]: string,
|};
var a: {|
add: (x: number, ...y: Array<string>) => void
|};
var a: {|
subtract: (x: number, ...y: Array<string>) => void
|};
var a: {|
id: <T>(x: T) => T
|};
function foo(numVal: number = 2) {}
function foo(numVal?: number = 2) {}

View File

@ -3,19 +3,44 @@ type A<T = *> = T;
type A<T: ?string = string> = T;
type A<S, T: ?string = string> = T;
type A<S = number, T: ?string = string> = T;
class A<T = string> {};
class A<T: ?string = string> {};
class A<S, T: ?string = string> {};
class A<S = number, T: ?string = string> {};
class A<T = string> {}
;
class A<T: ?string = string> {}
;
class A<S, T: ?string = string> {}
;
class A<S = number, T: ?string = string> {}
;
(class A<T = string> {});
(class A<T: ?string = string> {});
(class A<S, T: ?string = string> {});
(class A<S = number, T: ?string = string> {});
declare class A<T = string> {};
declare class A<T: ?string = string> {};
declare class A<S, T: ?string = string> {};
declare class A<S = number, T: ?string = string> {};
interface A<T = string> {};
interface A<T: ?string = string> {};
interface A<S, T: ?string = string> {};
interface A<S = number, T: ?string = string> {};
declare class A<T = string> {}
;
declare class A<T: ?string = string> {}
;
declare class A<S, T: ?string = string> {}
;
declare class A<S = number, T: ?string = string> {}
;
interface A<T = string> {}
;
interface A<T: ?string = string> {}
;
interface A<S, T: ?string = string> {}
;
interface A<S = number, T: ?string = string> {}
;

View File

@ -1,4 +1,10 @@
(xxx: number);
({ xxx: 0, yyy: "hey" }: { xxx: number, yyy: string, });
({
xxx: 0,
yyy: "hey"
}: {
xxx: number,
yyy: string,
});
(xxx => xxx + 1: (xxx: number) => number);
(xxx: number), (yyy: string);
(xxx: number), (yyy: string);

View File

@ -1,10 +1,39 @@
var a: { numVal: number };
var a: { numVal: number };
var a: { numVal: number, [indexer: string]: number, };
var a: ?{ numVal: number };
var a: { numVal: number, strVal: string, };
var a: { subObj: { strVal: string } };
var a: { subObj: ?{ strVal: string } };
var a: { param1: number, param2: string, };
var a: { param1: number, param2?: string, };
var a: { [a: number]: string, [b: number]: string, };
var a: {
numVal: number
};
var a: {
numVal: number
};
var a: {
numVal: number,
[indexer: string]: number,
};
var a: ?{
numVal: number
};
var a: {
numVal: number,
strVal: string,
};
var a: {
subObj: {
strVal: string
}
};
var a: {
subObj: ?{
strVal: string
}
};
var a: {
param1: number,
param2: string,
};
var a: {
param1: number,
param2?: string,
};
var a: {
[a: number]: string,
[b: number]: string,
};

View File

@ -1,10 +1,15 @@
e => {
print("hello world");
};
(e1, e2, e3) => {
print("hello world");
};
e => e;
(e1, e2, e3) => e;
e => {};
e => 20 + 20;
e => 20 + 20;

View File

@ -1,5 +1,7 @@
class Test {}
class Derived extends Super {}
class StaticMethods {
static n1() {}
@ -8,7 +10,9 @@ class StaticMethods {
static set set1(value) {}
static *gen1() {}
}
class Methods {
n2() {}
@ -17,7 +21,9 @@ class Methods {
set set2(value) {}
*gen1() {}
}
class ComputedStaticMethods {
static [n1]() {}
@ -26,7 +32,9 @@ class ComputedStaticMethods {
static set [set1](value) {}
static *[gen1]() {}
}
class ComputedMethods {
[n2]() {}
@ -35,4 +43,5 @@ class ComputedMethods {
set [set2](value) {}
*[gen1]() {}
}
}

View File

@ -1,5 +1,7 @@
(class Test {});
(class Derived extends Super {});
(class StaticMethods {
static n1() {}
@ -8,7 +10,9 @@
static set set1(value) {}
static *gen1() {}
});
(class Methods {
n2() {}
@ -17,7 +21,9 @@
set set2(value) {}
*gen1() {}
});
(class ComputedStaticMethods {
static [n1]() {}
@ -26,7 +32,9 @@
static set [set1](value) {}
static *[gen1]() {}
});
(class ComputedMethods {
[n2]() {}
@ -35,5 +43,7 @@
set [set2](value) {}
*[gen1]() {}
});
(class {});
(class {});

View File

@ -1,14 +1,18 @@
var object1 = {
get [Symbol.create]() {},
set [set()](value) {}
};
var object2 = {
*[generator()]() {}
};
var object3 = {
*[generator()]() {}
};
var object4 = {
[Symbol.xxx]: "hello",
[ok()]: 42
};
};

View File

@ -5,4 +5,5 @@ function b(p, q = 30) {}
function c(p, q = 30, ...r) {}
(p = 20) => {};
(p = 20, ...q) => {};
(p = 20, ...q) => {};

View File

@ -1,15 +1,32 @@
function t1({ responseText: responseText }) {}
function t2({ responseText }) {}
function t1({
responseText: responseText
}) {}
function t2({
responseText
}) {}
function t3([a, b]) {}
var [i, j, k] = array;
var {
i,
j,
k
} = obj;
let { i, j, k } = obj;
const { i, j, k } = obj;
var { value } = obj;
let {
i,
j,
k
} = obj;
const {
i,
j,
k
} = obj;
var {
value
} = obj;
var {
value
} = obj;

View File

@ -1,4 +1,6 @@
var [a, b, ...rest] = array;
const [a, b, ...rest] = array;
function a([a, b, ...rest]) {}
([a, b, ...rest]) => {};
([a, b, ...rest]) => {};

View File

@ -2,11 +2,10 @@ var escaped = `
\u2028
\u2029
`;
var escaped = `
\v
\b
\t
\n
\r
`;
`;

View File

@ -7,9 +7,7 @@ ${'the energy motron'}
{
const foo = `spam
and eggs!`;
const bar = `${4 + 2}`;
const hello = `Hello
${'world'}`;
}
}

View File

@ -1,31 +1,25 @@
var hello = `hello`;
var hello = `
line
terminators`;
var tagged = tagged`hello`;
var tagged = member.call`hello`;
var tagged = new call`hello`();
var tagged = new (call`hello`())();
var tageed = member[call`hello`];
var middles = `
Is the order a rabbit?
`;
var middles = `
Is the order ${order}?
`;
var middles = `
Is the order ${order}?
`;
var middles = `
1. ${cocoa}
2. ${chino}
3. ${rize}
4. ${syaro}
5. ${chiya}
`;
`;

View File

@ -2,4 +2,5 @@ var foo = arr.map(v => ({
x: v.bar,
y: v.bar * 2
}));
var fn = () => ({}).key;
var fn = () => ({}).key;

View File

@ -9,5 +9,7 @@ async function asdf() {
}
async function a(b) {
(await xhr({ url: "views/test.html" })).data;
}
(await xhr({
url: "views/test.html"
})).data;
}

View File

@ -1,2 +1,4 @@
a && a.b && a.b.c() && function () {}() && { a: 1 }.a;
!function () {}();
a && a.b && a.b.c() && function () {}() && {
a: 1
}.a;
!function () {}();

View File

@ -3,7 +3,6 @@ function foo() {
}
if (a, b, c) d();
throw a, b, c;
switch (a, b, c) {}
@ -12,4 +11,4 @@ for (a in b, c);
while (a, b, c);
!function () {}(), a();
!function () {}(), a();

View File

@ -5,8 +5,7 @@ function foo() {
}
function foo() {
return (
// foobar
return (// foobar
"bar"
);
}
}

View File

@ -8,5 +8,7 @@ function* asdf() {
}
function* a(b) {
(yield xhr({ url: "views/test.html" })).data;
}
(yield xhr({
url: "views/test.html"
})).data;
}

View File

@ -1 +1,3 @@
({ set = {} }) => set;
({
set = {}
}) => set;

View File

@ -1,4 +1,7 @@
var foo = x => x * x;
var foo = (a, b) => a * b;
var foo = async x => x * x;
var foo = async (a, b) => a * b;
var foo = async (a, b) => a * b;

View File

@ -1,5 +1,4 @@
::foo.bar.foo;
::foo.bar["foo"];
ctx::foo.bar.foo;
ctx::foo.bar["foo"];
ctx::foo.bar["foo"];

View File

@ -1,5 +1,4 @@
{}
{
foo();
}
}

View File

@ -8,7 +8,6 @@ class Foo {
["foo"] = 1;
["f" + "oo"];
["f" + "oo"] = 1;
static foo;
static foo = 1;
static "foo";
@ -18,14 +17,15 @@ class Foo {
static ["foo"] = 1;
static ["f" + "oo"];
static ["f" + "oo"] = 1;
get;
set;
static;
static = 1;
async;
foo;bar;
foo = 0;bar = 1;
foo;
bar;
foo = 0;
bar = 1;
}
class A1 {
@ -35,16 +35,21 @@ class A1 {
class A2 {
get;
*a() {}
}
class A3 {
static *a() {}
}
class A4 {
async;
a() {}
}
class A5 {
@ -54,8 +59,10 @@ class A5 {
class A6 {
get ['a']() {}
}
class A7 {
static get static() {}
}
}

View File

@ -1,15 +1,24 @@
class Foo {
async foo() {}
foo() {}
["foo"]() {}
get foo() {}
set foo(bar) {}
static async foo() {}
static foo() {}
static ["foo"]() {}
static get foo() {}
static set foo(bar) {}
static static() {}
get() {}
@ -33,4 +42,5 @@ class Foo {
get async() {}
static get static() {}
}
}

View File

@ -1,2 +1,3 @@
class Foo {}
class Foo extends Bar {}
class Foo extends Bar {}

View File

@ -12,6 +12,7 @@ var obj = {
@bar
set bar(foo) {}
};
class Foo {
@ -28,6 +29,7 @@ class Foo {
@bar
set bar(foo) {}
}
@foo
@ -35,11 +37,12 @@ export default class Foo {
bar() {
class Baz {}
}
}
}
@foo
export class Foo {
bar() {
class Baz {}
}
}

View File

@ -1,9 +1,8 @@
(do {});
let a = do {
if (x > 10) {
'big';
} else {
'small';
}
};
};

View File

@ -1,3 +1,5 @@
for (var i = 0;;) {}
for (var i = 0; i < 5;) {}
for (var i = 0; i < 5; i++) {}
for (var i = 0; i < 5; i++) {}

View File

@ -1,13 +1,10 @@
foo["bar"];
foo.bar;
foo.bar.foo;
foo.bar["foo"];
foo["foo"]["bar"];
foo[test()][bar()];
0..toString();
0.5.toString();
1.0.toString();
1.000.toString();
1.000.toString();

View File

@ -1,20 +1,29 @@
var foo = {};
var foo = { x, y };
var foo = { x: x, y: y };
var foo = {
x,
y
};
var foo = {
x: x,
y: y
};
var foo = {
x: x,
y: y
};
var foo = {
["bar"]: "foo",
["foo"]() {},
foo() {},
async foo() {},
*foo() {},
get foo() {},
set foo(foo) {}
};
};

View File

@ -5,7 +5,6 @@ foo?.(bar());
foo?.(bar("test"));
foo(bar?.());
foo(bar?.("test"));
a.foo?.();
a.foo?.("foo");
a.foo?.("foo", "bar");
@ -13,7 +12,6 @@ a.foo?.(bar());
a.foo?.(bar("test"));
a.foo(bar?.());
a.foo(bar?.("test"));
a?.foo?.();
a?.foo?.("foo");
a?.foo?.("foo", "bar");
@ -21,7 +19,6 @@ a?.foo?.(bar());
a?.foo?.(bar("test"));
a?.foo(bar?.());
a?.foo(bar?.("test"));
a.foo?.().baz;
a.foo?.("foo").baz;
a.foo?.("foo", "bar").baz;
@ -29,7 +26,6 @@ a.foo?.(bar()).baz;
a.foo?.(bar("test")).baz;
a.foo(bar?.()).baz;
a.foo(bar?.("test")).baz;
a.foo?.()?.baz;
a.foo?.("foo")?.baz;
a.foo?.("foo", "bar")?.baz;

View File

@ -5,7 +5,6 @@ foo?.(bar());
foo?.(bar("test"));
foo(bar?.());
foo(bar?.("test"));
a.foo?.();
a.foo?.("foo");
a.foo?.("foo", "bar");
@ -13,7 +12,6 @@ a.foo?.(bar());
a.foo?.(bar("test"));
a.foo(bar?.());
a.foo(bar?.("test"));
a?.foo?.();
a?.foo?.("foo");
a?.foo?.("foo", "bar");
@ -21,7 +19,6 @@ a?.foo?.(bar());
a?.foo?.(bar("test"));
a?.foo(bar?.());
a?.foo(bar?.("test"));
a.foo?.().baz;
a.foo?.("foo").baz;
a.foo?.("foo", "bar").baz;
@ -29,7 +26,6 @@ a.foo?.(bar()).baz;
a.foo?.(bar("test")).baz;
a.foo(bar?.()).baz;
a.foo(bar?.("test")).baz;
a.foo?.()?.baz;
a.foo?.("foo")?.baz;
a.foo?.("foo", "bar")?.baz;

View File

@ -1,6 +1,5 @@
foo?.["bar"];
foo?.bar;
foo.bar?.foo;
foo?.bar.foo;
foo?.bar?.foo;
@ -10,7 +9,6 @@ foo?.bar?.["foo"];
foo["bar"]?.foo;
foo?.["bar"].foo;
foo?.["bar"]?.foo;
0.?.toString();
0.5?.toString();
1.000?.toString();

View File

@ -5,7 +5,6 @@ new foo?.(bar());
new foo?.(bar("test"));
foo(new bar?.());
foo(new bar?.("test"));
new a.foo?.();
new a.foo?.("foo");
new a.foo?.("foo", "bar");
@ -13,7 +12,6 @@ new a.foo?.(bar());
new a.foo?.(bar("test"));
a.foo(new bar?.());
a.foo(new bar?.("test"));
new a?.foo?.();
new a?.foo?.("foo");
new a?.foo?.("foo", "bar");
@ -21,7 +19,6 @@ new a?.foo?.(bar());
new a?.foo?.(bar("test"));
a?.foo(new bar?.());
a?.foo(new bar?.("test"));
new a.foo?.().baz;
new a.foo?.("foo").baz;
new a.foo?.("foo", "bar").baz;
@ -29,7 +26,6 @@ new a.foo?.(bar()).baz;
new a.foo?.(bar("test")).baz;
a.foo(new bar?.()).baz;
a.foo(new bar?.("test")).baz;
new a.foo?.()?.baz;
new a.foo?.("foo")?.baz;
new a.foo?.("foo", "bar")?.baz;

View File

@ -1,3 +1,19 @@
var { ...{ z } } = { z: 1 };
var { ...{ x = 5 } } = { x: 1 };
({ x, ...{ y, z } } = o);
var { ...{
z
}
} = {
z: 1
};
var { ...{
x = 5
}
} = {
x: 1
};
({
x,
...{
y,
z
}
} = o);

View File

@ -1,3 +1,2 @@
foo, bar;
foo, bar;
foo, bar;

View File

@ -35,8 +35,10 @@ switch (foo) {
switch (foo) {
case "foo":
foo();
case "bar":
bar();
default:
yay();
}
}

View File

@ -1,20 +1,16 @@
html`<b></b>`;
`multi
lines`;
`test ${interpolation} test`;
`foob
asdf
awer
erqer`;
tag`\unicode and \u{55}`;
tag`\01`;
tag`\xg${0}right`;
tag`left${0}\xg`;
tag`left${0}\xg${1}right`;
tag`left${0}\u000g${1}right`;
tag`left${0}\u{-0}${1}right`;
tag`left${0}\u{-0}${1}right`;

View File

@ -1,18 +1,15 @@
let foo;
var foo;
let foo = "foo";
var foo = "bar";
const foo = "foo";
let foo,
bar = "bar";
var foo,
bar = "bar";
let foo = "foo",
bar = "bar";
var foo = "foo",
bar = "bar";
const foo = "foo",
bar = "bar";
bar = "bar";

View File

@ -1,5 +1,4 @@
with (foo) {}
with (foo) {
bar();
}
}

View File

@ -1,11 +1,7 @@
<div id="wow"></div>;
<div id="wow">text</div>;
<div id="wow" disabled></div>;
<div id="wow" disabled>text</div>;
<div id="wôw" />;
<div id="\w" />;
<div id="w &lt; w" />;
<div id="w &lt; w" />;

View File

@ -1,5 +1,3 @@
<div></div>;
<div />;
<div>text</div>;
<div>text</div>;

View File

@ -1,12 +1,9 @@
<div>wow</div>;
<div>wôw</div>;
<div>w & w</div>;
<div>w &amp; w</div>;
<div>w &nbsp; w</div>;
<div>this should not parse as unicode: \u00a0</div>;
<div>this should parse as nbsp:   </div>;
<div>this should parse as unicode: {'\u00a0 '}</div>;
<div>w &lt; w</div>;
<div>w &lt; w</div>;

View File

@ -1,4 +1,3 @@
import Whitespace from "../lib/whitespace";
import Printer from "../lib/printer";
import generate from "../lib";
import assert from "assert";
@ -305,7 +304,12 @@ describe("programmatic generation", function() {
);
const output = generate(blockStatement).code;
assert.equal(output, ["{", ' "use strict";', "}"].join("\n"));
assert.equal(
output,
`{
"use strict";
}`,
);
});
it("flow object indentation", function() {
@ -316,7 +320,12 @@ describe("programmatic generation", function() {
);
const output = generate(objectStatement).code;
assert.equal(output, ["{", " bar: string,", "}"].join("\n"));
assert.equal(
output,
`{
bar: string
}`,
);
});
it("flow object indentation with empty leading ObjectTypeProperty", function() {
@ -333,14 +342,12 @@ describe("programmatic generation", function() {
const output = generate(objectStatement).code;
assert.equal(output, ["{", " [key: any]: Test,", "}"].join("\n"));
});
});
describe("whitespace", function() {
it("empty token list", function() {
const w = new Whitespace([]);
assert.equal(w.getNewlinesBefore(t.stringLiteral("1")), 0);
assert.equal(
output,
`{
[key: any]: Test
}`,
);
});
});

View File

@ -2,9 +2,15 @@ var a = 1,
b = 2;
var c = 3,
d = 4;
var _e$f = { e: 5, f: 6 },
var _e$f = {
e: 5,
f: 6
},
e = _e$f.e,
f = _e$f.f;
var _a$b = { a: 7, b: 8 },
var _a$b = {
a: 7,
b: 8
},
g = _a$b.a,
h = _a$b.b;
h = _a$b.b;

View File

@ -6,7 +6,6 @@ babelHelpers.asyncToGenerator(function* () {
try {
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
let x = _value;
f(x);
}
} catch (err) {
@ -23,4 +22,4 @@ babelHelpers.asyncToGenerator(function* () {
}
}
}
});
});

View File

@ -7,7 +7,6 @@ let f = (() => {
try {
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield _iterator.next(), _iteratorNormalCompletion = _step.done, _value = yield _step.value, !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
let x = _value;
g(x);
}
} catch (err) {
@ -29,4 +28,4 @@ let f = (() => {
return function f() {
return _ref.apply(this, arguments);
};
})();
})();

View File

@ -7,7 +7,6 @@ let g = (() => {
try {
for (var _iterator = babelHelpers.asyncIterator(y), _step, _value; _step = yield babelHelpers.asyncGenerator.await(_iterator.next()), _iteratorNormalCompletion = _step.done, _value = yield babelHelpers.asyncGenerator.await(_step.value), !_iteratorNormalCompletion; _iteratorNormalCompletion = true) {
let x = _value;
f(x);
}
} catch (err) {
@ -29,4 +28,4 @@ let g = (() => {
return function g() {
return _ref.apply(this, arguments);
};
})();
})();

Some files were not shown because too many files have changed in this diff Show More