Add `conditionalGroup` to allow manually specifying multiple representations of a document; use it to support expanding last parameter of functions

master
James Long 2017-01-04 15:24:10 -05:00
parent fa16988401
commit 588c8ce7cd
30 changed files with 567 additions and 730 deletions

View File

@ -23,15 +23,27 @@ function indent(n, contents) {
return { type: 'indent', contents, n };
}
function group(contents) {
function group(contents, opts) {
opts = opts || {};
assertDoc(contents);
return { type: 'group', contents };
return {
type: 'group',
contents: contents,
break: !!opts.shouldBreak,
expandedStates: opts.expandedStates
};
}
function multilineGroup(doc) {
assertDoc(doc);
const shouldBreak = hasHardLine(doc);
return { type: 'group', contents: doc, break: shouldBreak };
function multilineGroup(contents, opts) {
return group(contents, Object.assign(opts || {}, {
shouldBreak: hasHardLine(contents)
}));
}
function conditionalGroup(states, opts) {
return group(states[0], Object.assign(opts || {}, {
expandedStates: states
}));
}
function iterDoc(topDoc, func) {
@ -70,10 +82,6 @@ const softline = { type: 'line', soft: true };
const hardline = { type: 'line', hard: true };
const literalline = { type: 'line', hard: true, literal: true };
function indentedLine(n) {
return { type: 'line', indent: n };
}
function isEmpty(n) {
return typeof n === "string" && n.length === 0;
}
@ -183,6 +191,7 @@ function print(w, doc) {
// cmds to the array instead of recursively calling `print`.
let cmds = [[0, MODE_BREAK, doc]];
let out = [];
let shouldRemeasure = false;
while(cmds.length !== 0) {
const [ind, mode, doc] = cmds.pop();
@ -204,16 +213,53 @@ function print(w, doc) {
case "group":
switch(mode) {
case MODE_FLAT:
cmds.push([ind, doc.break ? MODE_BREAK : MODE_FLAT, doc.contents]);
break;
if(!shouldRemeasure) {
cmds.push([ind, doc.break ? MODE_BREAK : MODE_FLAT, doc.contents]);
break;
}
// fallthrough
case MODE_BREAK:
shouldRemeasure = false;
const next = [ind, MODE_FLAT, doc.contents];
let rem = w - pos;
if(!doc.break && fits(next, cmds, rem)) {
cmds.push(next);
}
else {
cmds.push([ind, MODE_BREAK, doc.contents]);
// Expanded states are a rare case where a document
// can manually provide mutliple representations of
// itself. It provides an array of documents
// going from the least expanded (most flattened)
// representation first to the most expanded. If a
// group has these, we need to manually go through
// these states and find the first one that fits.
if(doc.expandedStates) {
const mostExpanded = doc.expandedStates[doc.expandedStates.length - 1];
if(doc.break) {
cmds.push([ind, MODE_BREAK, mostExpanded]);
break;
}
else {
for(var i=1; i<doc.expandedStates.length + 1; i++) {
if(i >= doc.expandedStates.length) {
cmds.push([ind, MODE_BREAK, mostExpanded]);
break;
}
else {
const state = doc.expandedStates[i];
const cmd = [ind, MODE_FLAT, state];
if(fits(cmd, cmds, rem)) {
cmds.push(cmd);
break;
}
}
}
}
}
else {
cmds.push([ind, MODE_BREAK, doc.contents]);
}
}
break;
}
@ -229,13 +275,13 @@ function print(w, doc) {
break;
}
else {
// We need to switch everything back into
// the breaking mode because this is
// forcing a newline and everything needs
// to be re-measured.
cmds.forEach(cmd => {
cmd[1] = MODE_BREAK;
});
// This line was forced into the output even if we
// were in flattened mode, so we need to tell the next
// group that no matter what, it needs to remeasure
// because the previous measurement didn't accurately
// capture the entire expression (this is necessary
// for nested groups)
shouldRemeasure = true;
}
// fallthrough
case MODE_BREAK:
@ -268,5 +314,5 @@ function print(w, doc) {
module.exports = {
fromString, concat, isEmpty, join,
line, softline, hardline, literalline, group, multilineGroup,
hasHardLine, indent, print, getFirstString
conditionalGroup, hasHardLine, indent, print, getFirstString
};

View File

@ -15,6 +15,7 @@ var multilineGroup = pp.multilineGroup;
var indent = pp.indent;
var getFirstString = pp.getFirstString;
var hasHardLine = pp.hasHardLine;
var conditionalGroup = pp.conditionalGroup;
var normalizeOptions = require("./options").normalize;
var types = require("ast-types");
var namedTypes = types.namedTypes;
@ -1175,13 +1176,12 @@ else
);
var mostChildren = children.slice(0, -1);
var lastChild = children[children.length - 1];
var closingLines = path.call(print, "closingElement");
return concat(
[
openingLines,
indent(options.tabWidth, concat(mostChildren)),
lastChild || "",
util.getLast(children) || "",
closingLines
]
);
@ -1746,25 +1746,65 @@ function printArgumentsList(path, options, print) {
var args;
if (printed.length === 0) {
args = "";
} else
if (printed.length === 1 && getFirstString(printed[0]) === "{") {
// If the only argument is an object, don't force it to be on
// newline and keep the braces on the same line as the parens
args = printed[0];
} else {
args = concat(
[
indent(
options.tabWidth,
concat([ softline, join(concat([ ",", line ]), printed) ])
),
softline
]
);
}
return "()";
}
return multilineGroup(concat([ "(", args, ")" ]));
const shouldBreak = printed.slice(0, -1).some(hasHardLine);
const lastArg = util.getLast(path.getValue().arguments);
// This is just an optimization; I think we could return the
// conditional group for all function calls, but it's more expensive
// so only do it for specific forms.
const groupLastArg = lastArg.type === "ObjectExpression" ||
lastArg.type === "ArrayExpression" ||
lastArg.type === "FunctionExpression" ||
lastArg.type === "ArrowFunctionExpression";
if (groupLastArg) {
return conditionalGroup(
[
concat([
"(",
join(concat([ ", " ]), printed),
")"
]),
concat([
"(",
join(concat([ ",", line ]), printed.slice(0, -1)),
", ",
group(util.getLast(printed), { shouldBreak: true }),
")"
]),
group(
concat([
"(",
indent(
options.tabWidth,
concat([ line, join(concat([ ",", line ]), printed) ])
),
line,
")"
]),
{ shouldBreak: true }
),
],
shouldBreak
);
}
return group(
concat([
"(",
indent(
options.tabWidth,
concat([ softline, join(concat([ ",", line ]), printed) ])
),
softline,
")"
]),
shouldBreak
);
}
function printFunctionParams(path, print) {

View File

@ -304,3 +304,10 @@ util.isTrailingCommaEnabled = function(options, context) {
}
return !!trailingComma;
};
util.getLast = function(arr) {
if(arr.length > 0) {
return arr[arr.length - 1];
}
return null;
}

View File

@ -102,15 +102,13 @@ function param_anno(n: number): void {
function param_anno2(
batchRequests: Array<{ method: string; path: string; params: ?Object }>
): void {
batchRequests = batchRequests.map(
request => {
return {
method: request.method,
params: request.params,
relative_url: request.path
};
}
);
batchRequests = batchRequests.map(request => {
return {
method: request.method,
params: request.params,
relative_url: request.path
};
});
}
var toz: null = 3;

View File

@ -39,15 +39,13 @@ console.log(filteredItems);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
function filterItems(items: Array<string | number>): Array<string | number> {
return items.map(
item => {
if (typeof item === \"string\") {
return (item.length > 2 ? item : null);
} else {
return item * 10;
}
return items.map(item => {
if (typeof item === \"string\") {
return (item.length > 2 ? item : null);
} else {
return item * 10;
}
).filter(Boolean);
}).filter(Boolean);
}
const filteredItems = filterItems([ \"foo\", \"b\", 1, 2 ]);

View File

@ -69,22 +69,18 @@ function from_test() {
function foo(x: string) {}
var a = [ 0 ];
var b = a.map(
function(x) {
foo(x);
var b = a.map(function(x) {
foo(x);
return \"\" + x;
}
);
return \"\" + x;
});
var c: number = a[0];
var d: number = b[0];
var e: Array<string> = a.reverse();
var f = [ \"\" ];
var g: number = f.map(
function() {
return 0;
}
)[0];
var g: number = f.map(function() {
return 0;
})[0];
var h: Array<number> = [ 1, 2, 3 ];
var i: Array<string> = [ \"a\", \"b\", \"c\" ];
var j: Array<number | string> = h.concat(i);
@ -94,29 +90,20 @@ var m: Array<number | string> = h.concat(\"a\", \"b\", \"c\");
var n: Array<number> = h.concat(\"a\", \"b\", \"c\");
function reduce_test() {
[ 0, 1, 2, 3, 4 ].reduce(
function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
}
);
[ 0, 1, 2, 3, 4 ].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
});
[ 0, 1, 2, 3, 4 ].reduce(
function(previousValue, currentValue, index, array) {
[ 0, 1, 2, 3, 4 ].reduce(function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
},
10
);
}, 10);
var total = [ 0, 1, 2, 3 ].reduce(
function(a, b) {
return a + b;
}
);
var flattened = [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ] ].reduce(
function(a, b) {
return a.concat(b);
}
);
var total = [ 0, 1, 2, 3 ].reduce(function(a, b) {
return a + b;
});
var flattened = [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ] ].reduce(function(a, b) {
return a.concat(b);
});
[ \"\" ].reduce((acc, str) => acc * str.length);
@ -124,18 +111,12 @@ function reduce_test() {
}
function from_test() {
var a: Array<string> = Array.from(
[ 1, 2, 3 ],
function(val, index) {
return (index % 2 ? \"foo\" : String(val));
}
);
var b: Array<string> = Array.from(
[ 1, 2, 3 ],
function(val) {
return String(val);
}
);
var a: Array<string> = Array.from([ 1, 2, 3 ], function(val, index) {
return (index % 2 ? \"foo\" : String(val));
});
var b: Array<string> = Array.from([ 1, 2, 3 ], function(val) {
return String(val);
});
}
"
`;

View File

@ -131,11 +131,9 @@ async function foo() {
// am not clear on whether it should. In any case it\'s a strange corner case
// that is probably not important to support.
class C {}
var P: Promise<Class<C>> = new Promise(
function(resolve, reject) {
resolve(C);
}
);
var P: Promise<Class<C>> = new Promise(function(resolve, reject) {
resolve(C);
});
async function foo() {
class Bar extends (await P) {}

View File

@ -145,11 +145,9 @@ refuse_return().return(\"string\").then(result => {
// error: number | void ~> string
declare var gen: AsyncGenerator<void, string, void>;
gen.return(0).then(
result => {
(result.value: void);
}
);
gen.return(0).then(result => {
(result.value: void);
});
async function* refuse_return() {
try {
@ -159,13 +157,11 @@ async function* refuse_return() {
}
}
refuse_return().return(\"string\").then(
result => {
if (result.done) {
(result.value: string);
}
refuse_return().return(\"string\").then(result => {
if (result.done) {
(result.value: string);
}
);
});
"
`;
@ -214,13 +210,11 @@ async function* catch_return() {
}
async () => {
catch_return().throw(\"\").then(
({ value }) => {
if (value !== undefined) {
(value: void);
}
catch_return().throw(\"\").then(({ value }) => {
if (value !== undefined) {
(value: void);
}
);
});
};
async function* yield_return() {
@ -234,13 +228,11 @@ async function* yield_return() {
}
async () => {
yield_return().throw(\"\").then(
({ value }) => {
if (value !== undefined) {
(value: void);
}
yield_return().throw(\"\").then(({ value }) => {
if (value !== undefined) {
(value: void);
}
);
});
};
"
`;

View File

@ -21,20 +21,16 @@ function g() {
// error: string !~> number
// error: string !~> number
var a = [ \"...\" ];
var b = a.map(
function(x) {
return 0;
}
);
var b = a.map(function(x) {
return 0;
});
var c: string = b[0];
var array = [];
function f() {
array = array.map(
function() {
return \"...\";
}
);
array = array.map(function() {
return \"...\";
});
var x: number = array[0];
}
@ -43,11 +39,9 @@ var Foo = require(\"./genericfoo\");
var foo = new Foo();
function g() {
var foo1 = foo.map(
function() {
return \"...\";
}
);
var foo1 = foo.map(function() {
return \"...\";
});
var x: number = foo1.get();
foo = foo1;

View File

@ -447,59 +447,44 @@ let tests = [
// Error: This might be null
let tests = [
function() {
document.registerElement(
\"custom-element\",
{
prototype: Object.create(
HTMLElement.prototype,
{
createdCallback: { value: function createdCallback() {} },
attachedCallback: { value: function attachedCallback() {} },
detachedCallback: { value: function detachedCallback() {} },
attributeChangedCallback: {
value: function attributeChangedCallback(
attributeLocalName,
oldAttributeValue,
newAttributeValue,
attributeNamespace
) {}
}
}
)
}
);
},
function() {
document.registerElement(
\"custom-element\",
{
prototype: Object.assign(
Object.create(HTMLElement.prototype),
{
createdCallback() {},
attachedCallback() {},
detachedCallback() {},
attributeChangedCallback(attributeLocalName,
document.registerElement(\"custom-element\", {
prototype: Object.create(HTMLElement.prototype, {
createdCallback: { value: function createdCallback() {} },
attachedCallback: { value: function attachedCallback() {} },
detachedCallback: { value: function detachedCallback() {} },
attributeChangedCallback: {
value: function attributeChangedCallback(
attributeLocalName,
oldAttributeValue,
newAttributeValue,
attributeNamespace) {}
}
)
}
);
attributeNamespace
) {}
}
})
});
},
function() {
document.registerElement(
\"custom-element\",
{
prototype: {
attributeChangedCallback(localName: string,
oldVal: string,
newVal: string,
namespace: string) {}
}
document.registerElement(\"custom-element\", {
prototype: Object.assign(Object.create(HTMLElement.prototype), {
createdCallback() {},
attachedCallback() {},
detachedCallback() {},
attributeChangedCallback(attributeLocalName,
oldAttributeValue,
newAttributeValue,
attributeNamespace) {}
})
});
},
function() {
document.registerElement(\"custom-element\", {
prototype: {
attributeChangedCallback(localName: string,
oldVal: string,
newVal: string,
namespace: string) {}
}
);
});
}
];
"
@ -907,17 +892,13 @@ let tests = [
document.createNodeIterator(document.body, -1, node => \"accept\");
document.createNodeIterator(
document.body,
-1,
{ accept: node => NodeFilter.FILTER_ACCEPT }
);
document.createNodeIterator(document.body, -1, {
accept: node => NodeFilter.FILTER_ACCEPT
});
document.createNodeIterator(
document.body,
-1,
{ accept: node => \"accept\" }
);
document.createNodeIterator(document.body, -1, {
accept: node => \"accept\"
});
document.createNodeIterator(document.body, -1, {});
},
@ -930,11 +911,9 @@ let tests = [
document.createTreeWalker(document.body, -1, node => \"accept\");
document.createTreeWalker(
document.body,
-1,
{ accept: node => NodeFilter.FILTER_ACCEPT }
);
document.createTreeWalker(document.body, -1, {
accept: node => NodeFilter.FILTER_ACCEPT
});
document.createTreeWalker(document.body, -1, { accept: node => \"accept\" });

View File

@ -66,11 +66,9 @@ let tests = [
result.baz = false;
(copyProperties(result, { foo: \"a\" }, { bar: 123 }): {
foo: string;
bar: number;
baz: boolean
});
(copyProperties(result, { foo: \"a\" }, {
bar: 123
}): { foo: string; bar: number; baz: boolean });
},
function() {
const copyProperties = require(\"copyProperties\");

View File

@ -203,43 +203,31 @@ const d: Request = new Request(c.clone());
const e: Request = new Request(b, c);
const f: Request = new Request({});
const g: Request = new Request(\"http://example.org\", {});
const h: Request = new Request(
\"http://example.org\",
{
method: \"GET\",
headers: { \"Content-Type\": \"image/jpeg\" },
mode: \"cors\",
cache: \"default\"
}
);
const i: Request = new Request(
\"http://example.org\",
{
method: \"POST\",
headers: { \"Content-Type\": \"image/jpeg\" },
body: new URLSearchParams(\"key=value\"),
mode: \"cors\",
cache: \"default\"
}
);
const j: Request = new Request(
\"http://example.org\",
{
method: \"GET\",
headers: \"Content-Type: image/jpeg\",
mode: \"cors\",
cache: \"default\"
}
);
const k: Request = new Request(
\"http://example.org\",
{
method: \"CONNECT\",
headers: { \"Content-Type\": \"image/jpeg\" },
mode: \"cors\",
cache: \"default\"
}
);
const h: Request = new Request(\"http://example.org\", {
method: \"GET\",
headers: { \"Content-Type\": \"image/jpeg\" },
mode: \"cors\",
cache: \"default\"
});
const i: Request = new Request(\"http://example.org\", {
method: \"POST\",
headers: { \"Content-Type\": \"image/jpeg\" },
body: new URLSearchParams(\"key=value\"),
mode: \"cors\",
cache: \"default\"
});
const j: Request = new Request(\"http://example.org\", {
method: \"GET\",
headers: \"Content-Type: image/jpeg\",
mode: \"cors\",
cache: \"default\"
});
const k: Request = new Request(\"http://example.org\", {
method: \"CONNECT\",
headers: { \"Content-Type\": \"image/jpeg\" },
mode: \"cors\",
cache: \"default\"
});
var l: boolean = h.bodyUsed;
h.text().then((t: string) => t);
@ -319,19 +307,19 @@ const b: Response = new Response(new Blob());
const c: Response = new Response(new FormData());
const d: Response = new Response(new FormData(), { status: 404 });
const e: Response = new Response(\"responsebody\", { status: \"404\" });
const f: Response = new Response(
\"responsebody\",
{ status: 404, headers: \"\'Content-Type\': \'image/jpeg\'\" }
);
const g: Response = new Response(
\"responsebody\",
{ status: 404, headers: { \"Content-Type\": \"image/jpeg\" } }
);
const h: Response = new Response(
\"responsebody\",
{ status: 404, headers: new Headers({ \"Content-Type\": \"image/jpeg\" }) }
);
const i: Response = new Response({
const f: Response = new Response(\"responsebody\", {
status: 404,
headers: \"\'Content-Type\': \'image/jpeg\'\"
});
const g: Response = new Response(\"responsebody\", {
status: 404,
headers: { \"Content-Type\": \"image/jpeg\" }
});
const h: Response = new Response(\"responsebody\", {
status: 404,
headers: new Headers({ \"Content-Type\": \"image/jpeg\" })
});
const i: Response = new Response(, {
status: 404,
headers: new Headers({ \"Content-Type\": \"image/jpeg\" })
});

View File

@ -45,28 +45,24 @@ function mul(x: number, y: number) {
function fix(fold) {
var delta = function(delta) {
return fold(
function(x) {
var eta = delta(delta);
return eta(x);
}
);
return fold(function(x) {
var eta = delta(delta);
return eta(x);
});
};
return delta(delta);
}
function mk_factorial() {
return fix(
function(factorial) {
return function(n) {
if (eq(n, 1)) {
return 1;
}
return fix(function(factorial) {
return function(n) {
if (eq(n, 1)) {
return 1;
}
return mul(factorial(sub(n, 1)), n);
};
}
);
return mul(factorial(sub(n, 1)), n);
};
});
}
var factorial = mk_factorial();

View File

@ -22,22 +22,19 @@ geolocation.clearWatch(id);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var geolocation = new Geolocation();
var id = geolocation.watchPosition(
position => {
var coords: Coordinates = position.coords;
var accuracy: number = coords.accuracy;
},
e => {
var message: string = e.message;
switch (e.code) {
case e.PERMISSION_DENIED:
case e.POSITION_UNAVAILABLE:
case e.TIMEOUT:
default:
break;
}
var id = geolocation.watchPosition(position => {
var coords: Coordinates = position.coords;
var accuracy: number = coords.accuracy;
}, e => {
var message: string = e.message;
switch (e.code) {
case e.PERMISSION_DENIED:
case e.POSITION_UNAVAILABLE:
case e.TIMEOUT:
default:
break;
}
);
});
geolocation.clearWatch(id);
"

View File

@ -103,18 +103,18 @@ buffer = buffer.fill(\"a\", 0, 0, \"utf8\");
buffer = buffer.fill(\"a\", \"utf8\");
maybeNum = buffer.find(
(element: number, index: number, array: Uint8Array) => false
);
maybeNum = buffer.find(, (element: number,
index: number,
array: Uint8Array) => false);
maybeNum = buffer.find(
(element: number, index: number, array: Uint8Array) => false,
buffer
);
num = buffer.findIndex(
(element: number, index: number, array: Uint8Array) => false
);
num = buffer.findIndex(, (element: number,
index: number,
array: Uint8Array) => false);
num = buffer.findIndex(
(element: number, index: number, array: Uint8Array) => false,

View File

@ -22,22 +22,15 @@ exec(\'ls\', {maxBuffer: 100}, function(error, stdout, stderr) {
// options + callback.
var exec = require(\"child_process\").exec;
exec(
\"ls\",
function(error, stdout, stderr) {
console.info(stdout);
}
);
exec(\"ls\", function(error, stdout, stderr) {
console.info(stdout);
});
exec(\"ls\", { timeout: 250 });
exec(
\"ls\",
{ maxBuffer: 100 },
function(error, stdout, stderr) {
console.info(stdout);
}
);
exec(\"ls\", { maxBuffer: 100 }, function(error, stdout, stderr) {
console.info(stdout);
});
"
`;
@ -81,33 +74,21 @@ var execFile = require(\"child_process\").execFile;
execFile(\"ls\", [ \"-lh\" ]);
execFile(
\"ls\",
function(error, stdout, stderr) {
console.info(stdout);
}
);
execFile(\"ls\", function(error, stdout, stderr) {
console.info(stdout);
});
execFile(\"wc\", { timeout: 250 });
execFile(
\"ls\",
[ \"-l\" ],
function(error, stdout, stderr) {
console.info(stdout);
}
);
execFile(\"ls\", [ \"-l\" ], function(error, stdout, stderr) {
console.info(stdout);
});
execFile(\"ls\", [ \"-l\" ], { timeout: 250 });
execFile(
\"ls\",
[ \"-l\" ],
{ timeout: 250 },
function(error, stdout, stderr) {
console.info(stdout);
}
);
execFile(\"ls\", [ \"-l\" ], { timeout: 250 }, function(error, stdout, stderr) {
console.info(stdout);
});
"
`;
@ -185,38 +166,27 @@ var child_process = require(\"child_process\");
var ls = child_process.spawn(\"ls\");
var wc = child_process.spawn(\"wc\", [ \"-l\" ]);
child_process.spawn(
\"echo\",
[ \"-n\", \"\\\"Testing...\\\"\" ],
{ env: { TEST: \"foo\" } }
);
child_process.spawn(\"echo\", [ \"-n\", \"\\\"Testing...\\\"\" ], {
env: { TEST: \"foo\" }
});
child_process.spawn(\"echo\", { env: { FOO: 2 } });
ls.stdout.on(
\"data\",
function(data) {
wc.stdin.write(data);
}
);
ls.stdout.on(\"data\", function(data) {
wc.stdin.write(data);
});
ls.stderr.on(
\"data\",
function(data) {
console.warn(data);
}
);
ls.stderr.on(\"data\", function(data) {
console.warn(data);
});
ls.on(
\"close\",
function(code) {
if (code !== 0) {
console.warn(\"\`ls\` exited with code %s\", code);
}
wc.stdin.end();
ls.on(\"close\", function(code) {
if (code !== 0) {
console.warn(\"\`ls\` exited with code %s\", code);
}
);
wc.stdin.end();
});
wc.stdout.pipe(process.stdout);

View File

@ -53,14 +53,11 @@ let tests = [
function() {
const hmac = crypto.createHmac(\"sha256\", \"a secret\");
hmac.on(
\"readable\",
() => {
(hmac.read(): ?(string | Buffer));
hmac.on(\"readable\", () => {
(hmac.read(): ?(string | Buffer));
(hmac.read(): number);
}
);
(hmac.read(): number);
});
hmac.write(\"some data to hash\");

View File

@ -41,36 +41,21 @@ fs.readFile(\"file.exp\", {}, (_, data) => {
// error
var fs = require(\"fs\");
fs.readFile(
\"file.exp\",
(_, data) => {
(data: Buffer);
}
);
fs.readFile(\"file.exp\", (_, data) => {
(data: Buffer);
});
fs.readFile(
\"file.exp\",
\"blah\",
(_, data) => {
(data: string);
}
);
fs.readFile(\"file.exp\", \"blah\", (_, data) => {
(data: string);
});
fs.readFile(
\"file.exp\",
{ encoding: \"blah\" },
(_, data) => {
(data: string);
}
);
fs.readFile(\"file.exp\", { encoding: \"blah\" }, (_, data) => {
(data: string);
});
fs.readFile(
\"file.exp\",
{},
(_, data) => {
(data: Buffer);
}
);
fs.readFile(\"file.exp\", {}, (_, data) => {
(data: Buffer);
});
(fs.readFileSync(\"file.exp\"): Buffer);

View File

@ -57,14 +57,11 @@ module.exports = export_;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// makes sure this terminates
var export_ = Object.assign(
{},
{
foo: function(param) {
return param;
}
var export_ = Object.assign({}, {
foo: function(param) {
return param;
}
);
});
var decl_export_: { foo: any; bar: any } = Object.assign({}, export_);
let anyObj: Object = {};
@ -192,19 +189,15 @@ var sealed = { one: \"one\", two: \"two\" };
var unsealed = {};
Object.keys(unsealed).forEach(
k => {
(k: number);
}
);
Object.keys(unsealed).forEach(k => {
(k: number);
});
var dict: { [k: number]: string } = {};
Object.keys(dict).forEach(
k => {
(k: number);
}
);
Object.keys(dict).forEach(k => {
(k: number);
});
var any: Object = {};

View File

@ -34,26 +34,18 @@ module.exports = {
// Doesn\'t repro if I extend the class myself
// Calling Good.foo() in the same file doesn\'t error
var EventEmitter = require(\"events\").EventEmitter;
var Bad = Object.assign(
{},
EventEmitter.prototype,
{
foo: function(): string {
return \"hi\";
}
var Bad = Object.assign({}, EventEmitter.prototype, {
foo: function(): string {
return \"hi\";
}
);
});
var bad: number = Bad.foo();
class MyEventEmitter extends events$EventEmitter {}
var Good = Object.assign(
{},
MyEventEmitter.prototype,
{
foo: function(): string {
return \"hi\";
}
var Good = Object.assign({}, MyEventEmitter.prototype, {
foo: function(): string {
return \"hi\";
}
);
});
var good: number = Good.foo();
module.exports = { Bad: Bad, Good: Good };

View File

@ -30,12 +30,10 @@ var o = keyMirror({ FOO: null, BAR: null });
(o.FOO: \"BAR\");
promiseAllByKey({ foo: Promise.resolve(0), bar: \"bar\" }).then(
o => {
(o.foo: string);
promiseAllByKey({ foo: Promise.resolve(0), bar: \"bar\" }).then(o => {
(o.foo: string);
(o.bar: \"bar\");
}
);
(o.bar: \"bar\");
});
"
`;

View File

@ -56,23 +56,19 @@ function tes2(val: Map<string, Promise<number>>) {
declare var pstr: Promise<string>;
declare var pnum: Promise<number>;
Promise.all([ pstr, pnum, true ]).then(
xs => {
let [ a, b, c ] = xs;
Promise.all([ pstr, pnum, true ]).then(xs => {
let [ a, b, c ] = xs;
(a: number);
(a: number);
(b: boolean);
(b: boolean);
(c: string);
(c: string);
xs.forEach(
x => {
(x: void);
}
);
}
);
xs.forEach(x => {
(x: void);
});
});
Promise.all();
@ -428,250 +424,164 @@ Promise.resolve(0)
// TODO: resolvedPromise<T> -> catch() -> then():T
// TODO
// Error: string ~> number
new Promise(
function(resolve, reject) {
resolve(0);
}
).then(
function(num) {
var a: number = num;
var b: string = num;
}
);
new Promise(function(resolve, reject) {
resolve(0);
}).then(function(num) {
var a: number = num;
var b: string = num;
});
new Promise((resolve, reject) => resolve(0)).then(
function(num) {
var a: number = num;
var b: string = num;
}
);
new Promise((resolve, reject) => resolve(0)).then(function(num) {
var a: number = num;
var b: string = num;
});
new Promise(
function(resolve, reject) {
resolve(
new Promise(
function(resolve, reject) {
new Promise(function(resolve, reject) {
resolve(new Promise(function(resolve, reject) {
resolve(0);
}));
}).then(function(num) {
var a: number = num;
var b: string = num;
});
new Promise(function(resolve, reject) {
resolve(new Promise(function(resolve, reject) {
resolve(new Promise(function(resolve, reject) {
resolve(0);
}
)
);
}
).then(
function(num) {
var a: number = num;
var b: string = num;
}
);
}));
}));
}).then(function(num) {
var a: number = num;
var b: string = num;
});
new Promise(
function(resolve, reject) {
resolve(
new Promise(
function(resolve, reject) {
resolve(
new Promise(
function(resolve, reject) {
resolve(0);
}
)
);
}
)
);
new Promise(function(resolve, reject) {
if (Math.random()) {
resolve(42);
} else {
resolve(\"str\");
}
).then(
function(num) {
var a: number = num;
var b: string = num;
}).then(function(numOrStr) {
if (typeof numOrStr === \"string\") {
var a: string = numOrStr;
} else {
var b: number = numOrStr;
}
);
new Promise(
function(resolve, reject) {
if (Math.random()) {
resolve(42);
} else {
resolve(\"str\");
}
}
).then(
function(numOrStr) {
if (typeof numOrStr === \"string\") {
var a: string = numOrStr;
} else {
var b: number = numOrStr;
}
var c: string = numOrStr;
});
var c: string = numOrStr;
}
);
new Promise(function(resolve, reject) {
reject(0);
}).catch(function(num) {
var a: number = num;
var b: string = num;
});
new Promise(
function(resolve, reject) {
reject(0);
}
).catch(
function(num) {
var a: number = num;
var b: string = num;
}
);
new Promise(function(resolve, reject) {
reject(new Promise(function(resolve, reject) {
reject(0);
}));
}).catch(function(num) {
var a: Promise<number> = num;
var b: number = num;
});
new Promise(
function(resolve, reject) {
reject(
new Promise(
function(resolve, reject) {
reject(0);
}
)
);
new Promise(function(resolve, reject) {
if (Math.random()) {
reject(42);
} else {
reject(\"str\");
}
).catch(
function(num) {
var a: Promise<number> = num;
var b: number = num;
}).catch(function(numOrStr) {
if (typeof numOrStr === \"string\") {
var a: string = numOrStr;
} else {
var b: number = numOrStr;
}
);
new Promise(
function(resolve, reject) {
if (Math.random()) {
reject(42);
} else {
reject(\"str\");
}
}
).catch(
function(numOrStr) {
if (typeof numOrStr === \"string\") {
var a: string = numOrStr;
} else {
var b: number = numOrStr;
}
var c: string = numOrStr;
});
var c: string = numOrStr;
}
);
Promise.resolve(0).then(function(num) {
var a: number = num;
var b: string = num;
});
Promise.resolve(0).then(
function(num) {
var a: number = num;
var b: string = num;
}
);
Promise.resolve(Promise.resolve(0)).then(function(num) {
var a: number = num;
var b: string = num;
});
Promise.resolve(Promise.resolve(0)).then(
function(num) {
var a: number = num;
var b: string = num;
}
);
Promise.resolve(Promise.resolve(Promise.resolve(0))).then(function(num) {
var a: number = num;
var b: string = num;
});
Promise.resolve(Promise.resolve(Promise.resolve(0))).then(
function(num) {
var a: number = num;
var b: string = num;
}
);
Promise.reject(0).catch(function(num) {
var a: number = num;
var b: string = num;
});
Promise.reject(0).catch(
function(num) {
var a: number = num;
var b: string = num;
}
);
Promise.reject(Promise.resolve(0)).then(function(num) {
var a: Promise<number> = num;
var b: number = num;
});
Promise.reject(Promise.resolve(0)).then(
function(num) {
var a: Promise<number> = num;
var b: number = num;
}
);
Promise.resolve(0).then(function(num) {
return \"asdf\";
}).then(function(str) {
var a: string = str;
var b: number = str;
});
Promise.resolve(0).then(
function(num) {
return \"asdf\";
}
).then(
function(str) {
var a: string = str;
var b: number = str;
}
);
Promise.resolve(0).then(function(num) {
return Promise.resolve(\"asdf\");
}).then(function(str) {
var a: string = str;
var b: number = str;
});
Promise.resolve(0).then(
function(num) {
return Promise.resolve(\"asdf\");
}
).then(
function(str) {
var a: string = str;
var b: number = str;
}
);
Promise.resolve(0).then(function(num) {
return Promise.resolve(Promise.resolve(\"asdf\"));
}).then(function(str) {
var a: string = str;
var b: number = str;
});
Promise.resolve(0).then(
function(num) {
return Promise.resolve(Promise.resolve(\"asdf\"));
}
).then(
function(str) {
var a: string = str;
var b: number = str;
}
);
Promise.resolve(0).then(function(num) {
throw \"str\";
}).catch(function(str) {
var a: string = str;
var b: number = str;
});
Promise.resolve(0).then(
function(num) {
throw \"str\";
}
).catch(
function(str) {
var a: string = str;
var b: number = str;
}
);
Promise.reject(0).catch(function(num) {
return \"asdf\";
}).then(function(str) {
var a: string = str;
var b: number = str;
});
Promise.reject(0).catch(
function(num) {
return \"asdf\";
}
).then(
function(str) {
var a: string = str;
var b: number = str;
}
);
Promise.reject(0).catch(function(num) {
return Promise.resolve(\"asdf\");
}).then(function(str) {
var a: string = str;
var b: number = str;
});
Promise.reject(0).catch(
function(num) {
return Promise.resolve(\"asdf\");
}
).then(
function(str) {
var a: string = str;
var b: number = str;
}
);
Promise.reject(0).catch(function(num) {
return Promise.resolve(Promise.resolve(\"asdf\"));
}).then(function(str) {
var a: string = str;
var b: number = str;
});
Promise.reject(0).catch(
function(num) {
return Promise.resolve(Promise.resolve(\"asdf\"));
}
).then(
function(str) {
var a: string = str;
var b: number = str;
}
);
Promise.resolve(0).catch(function(err) {}).then(
function(num) {
var a: number = num;
var b: string = num;
}
);
Promise.resolve(0).catch(function(err) {}).then(function(num) {
var a: number = num;
var b: string = num;
});
"
`;

View File

@ -129,7 +129,7 @@ var blah = <Foo {...props} />; // error bar, number given string expected
/* @flow */
// error bar, number given string expected
var React = require(\"react\");
var Foo = React.createClass({
var Foo = React.createClass(, {
propTypes: { bar: React.PropTypes.string.isRequired }
});
var props = { bar: 42 };
@ -155,7 +155,7 @@ var fail_mistyped_elems = <Example arr={[1, \"foo\"]} />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var React = require(\"react\");
var Example = React.createClass({
var Example = React.createClass(, {
propTypes: { arr: React.PropTypes.arrayOf(React.PropTypes.number).isRequired }
});
var ok_empty = <Example arr={[]}/>;
@ -183,7 +183,7 @@ var fail_mistyped = <Example func={2} />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var React = require(\"react\");
var Example = React.createClass({
var Example = React.createClass(, {
propTypes: { func: React.PropTypes.func.isRequired }
});
var ok_void = <Example func={() => {}}/>;
@ -275,7 +275,7 @@ var fail_mistyped = <Example object={2} />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var React = require(\"react\");
var Example = React.createClass({
var Example = React.createClass(, {
propTypes: { object: React.PropTypes.object.isRequired }
});
var ok_empty = <Example object={{}}/>;
@ -302,7 +302,7 @@ var fail_mistyped_props = <Example obj={{foo: \"foo\"}} />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var React = require(\"react\");
var Example = React.createClass({
var Example = React.createClass(, {
propTypes: {
obj: React.PropTypes.objectOf(React.PropTypes.number).isRequired
}
@ -329,7 +329,7 @@ var ex2 = <Example literal=\"bar\" />;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var React = require(\"react\");
var Example = React.createClass({
var Example = React.createClass(, {
propTypes: { literal: React.PropTypes.oneOf([ \"foo\" ]).isRequired }
});
var ex1 = <Example literal=\"foo\"/>;
@ -366,9 +366,10 @@ var fail_bool = <Example prop={true} />
var React = require(\"react\");
var Example = React.createClass({
propTypes: {
prop: React.PropTypes.oneOfType(
[ React.PropTypes.string, React.PropTypes.number ]
).isRequired
prop: React.PropTypes.oneOfType(, [
React.PropTypes.string,
React.PropTypes.number
]).isRequired
},
render() {
if (typeof this.props.prop === \"string\") {

View File

@ -70,19 +70,16 @@ requireLazy([\'A\']); // Error: No calback expression
// Error: No args
// Error: Non-stringliteral args
// Error: No calback expression
requireLazy(
[ \"A\", \"B\" ],
function(A, B) {
var num1: number = A.numberValueA;
var str1: string = A.stringValueA;
var num2: number = A.stringValueA;
var str2: string = A.numberValueA;
var num3: number = B.numberValueB;
var str3: string = B.stringValueB;
var num4: number = B.stringValueB;
var str4: string = B.numberValueB;
}
);
requireLazy([ \"A\", \"B\" ], function(A, B) {
var num1: number = A.numberValueA;
var str1: string = A.stringValueA;
var num2: number = A.stringValueA;
var str2: string = A.numberValueA;
var num3: number = B.numberValueB;
var str3: string = B.stringValueB;
var num4: number = B.stringValueB;
var str4: string = B.numberValueB;
});
var notA: Object = A;
var notB: Object = B;

View File

@ -167,14 +167,11 @@ function test(
x: { kind: ?string },
kinds: { [key: string]: string }
): Array<{ kind: ?string }> {
return map(
kinds,
value => {
(value: string);
return map(kinds, value => {
(value: string);
return { ...x, kind: value };
}
);
return { ...x, kind: value };
});
}
"
`;

View File

@ -280,12 +280,10 @@ class K_ {
}
class K extends K_ {
constructor() {
super(
() => {
if (_this)
_this.foo();
}
);
super(() => {
if (_this)
_this.foo();
});
var _this = this;

View File

@ -46,11 +46,9 @@ function f2(xlam) {
g2(xlam);
}
f2(
function(x) {
return x * x;
}
);
f2(function(x) {
return x * x;
});
function g3(ylam: (s: string) => number) {}
@ -89,10 +87,10 @@ function f(b): React.Element<*> {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
var React = require(\"react\");
var A = React.createClass({
var A = React.createClass(, {
propTypes: { foo: React.PropTypes.string.isRequired }
});
var B = React.createClass({
var B = React.createClass(, {
propTypes: { bar: React.PropTypes.string.isRequired }
});

View File

@ -15,15 +15,13 @@ foo();
// OK to leave out arg, same as resolve(undefined)
// simpler repro to show that too few args are fine when expecting void
function doSomethingAsync(): Promise<void> {
return new Promise(
(resolve, reject) => {
resolve();
return new Promise((resolve, reject) => {
resolve();
var anotherVoidPromise: Promise<void> = Promise.resolve();
var anotherVoidPromise: Promise<void> = Promise.resolve();
resolve(anotherVoidPromise);
}
);
resolve(anotherVoidPromise);
});
}
function foo(x: void) {}

View File

@ -84,19 +84,13 @@ exports[`test issue-198.js 1`] = `
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This should fail because str is string, not number
var p = new Promise(
function(resolve, reject) {
resolve(5);
}
).then(
function(num) {
return num.toFixed();
}
).then(
function(str) {
return str.toFixed();
}
);
var p = new Promise(function(resolve, reject) {
resolve(5);
}).then(function(num) {
return num.toFixed();
}).then(function(str) {
return str.toFixed();
});
"
`;

View File

@ -1461,12 +1461,9 @@ exports[`test test20.js 1`] = `
// Array#reduce
[ 0, 1 ].reduce((x, y, i) => y);
[ \"a\", \"b\" ].reduce(
(regex, representation, index) => {
[ \"a\", \"b\" ].reduce((regex, representation, index) => {
return regex + ((index ? \"|\" : \"\")) + \"(\" + representation + \")\";
},
\"\"
);
}, \"\");
[ \"\" ].reduce((acc, str) => acc * str.length);
"