Merge pull request #3 from jlongster/expand-last-arg

Add `conditionalGroup` to allow manually specifying multiple represen…
master
James Long 2017-01-04 16:53:25 -05:00 committed by GitHub
commit fae314bee0
37 changed files with 747 additions and 839 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 multiple 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;
@ -357,17 +358,7 @@ function genericPrintNoParens(path, options, print) {
parts.push(
path.call(print, "typeParameters"),
concat(
[
"(",
indent(
options.tabWidth,
concat([ softline, printFunctionParams(path, print) ])
),
softline,
")"
]
),
printFunctionParams(path, print, options),
printReturnType(path, print),
" ",
path.call(print, "body")
@ -393,9 +384,7 @@ function genericPrintNoParens(path, options, print) {
parts.push(path.call(print, "params", 0));
} else {
parts.push(
"(",
printFunctionParams(path, print),
")",
printFunctionParams(path, print, options),
printReturnType(path, print)
);
}
@ -1175,13 +1164,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
]
);
@ -1408,7 +1396,7 @@ else
parts.push(path.call(print, "typeParameters"));
parts.push("(", printFunctionParams(path, print), ")");
parts.push(printFunctionParams(path, print, options));
// The returnType is not wrapped in a TypeAnnotation, so the colon
// needs to be added separately.
@ -1724,14 +1712,12 @@ function printMethod(path, options, print) {
parts.push(
key,
path.call(print, "value", "typeParameters"),
"(",
path.call(
function(valuePath) {
return printFunctionParams(valuePath, print);
return printFunctionParams(valuePath, print, options);
},
"value"
),
")",
path.call(p => printReturnType(p, print), "value"),
" ",
path.call(print, "value", "body")
@ -1746,28 +1732,68 @@ 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)),
printed.length > 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) {
function printFunctionParams(path, print, options) {
var fun = path.getValue();
// namedTypes.Function.assert(fun);
var printed = path.map(print, "params");
@ -1790,7 +1816,15 @@ function printFunctionParams(path, print) {
printed.push(concat([ "...", path.call(print, "rest") ]));
}
return join(concat([ ",", line ]), printed);
return concat([
"(",
indent(
options.tabWidth,
concat([ softline, join(concat([ ",", line ]), printed) ])
),
softline,
")"
]);
}
function printObjectMethod(path, options, print) {
@ -1818,9 +1852,7 @@ function printObjectMethod(path, options, print) {
}
parts.push(
"(",
printFunctionParams(path, print),
")",
printReturnType(path, print),
" ",
path.call(print, "body")

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

@ -1250,68 +1250,102 @@ export const builders: {
emptyStatement(): EmptyStatement;
blockStatement(body: Statement[]): BlockStatement;
expressionStatement(expression: Expression): ExpressionStatement;
ifStatement(test: Expression,
consequent: Statement,
alternate?: Statement): IfStatement;
ifStatement(
test: Expression,
consequent: Statement,
alternate?: Statement
): IfStatement;
breakStatement(label?: Identifier): BreakStatement;
continueStatement(label?: Identifier): ContinueStatement;
returnStatement(argument: ?Expression): ReturnStatement;
throwStatement(argument: ?Expression): ThrowStatement;
whileStatement(test: Expression, body: Statement): WhileStatement;
forStatement(init: ?(VariableDeclaration | Expression),
test: ?Expression,
update: ?Expression,
body: Statement): ForStatement;
forInStatement(left: VariableDeclaration | Expression,
right: Expression,
body: Statement): ForInStatement;
tryStatement(block: BlockStatement,
handler: ?CatchClause,
handlers: CatchClause[],
finalizer?: BlockStatement): TryStatement;
catchClause(param: Pattern,
guard: ?Expression,
body: BlockStatement): CatchClause;
forStatement(
init: ?(VariableDeclaration | Expression),
test: ?Expression,
update: ?Expression,
body: Statement
): ForStatement;
forInStatement(
left: VariableDeclaration | Expression,
right: Expression,
body: Statement
): ForInStatement;
tryStatement(
block: BlockStatement,
handler: ?CatchClause,
handlers: CatchClause[],
finalizer?: BlockStatement
): TryStatement;
catchClause(
param: Pattern,
guard: ?Expression,
body: BlockStatement
): CatchClause;
identifier(name: string): Identifier;
literal(value: ?(string | boolean | number | RegExp),
regex?: { pattern: string; flags: string }): Literal;
literal(
value: ?(string | boolean | number | RegExp),
regex?: { pattern: string; flags: string }
): Literal;
thisExpression(): ThisExpression;
arrayExpression(elements: Expression[]): ArrayExpression;
objectExpreession(properties: Property[]): ObjectExpreession;
property(kind: \"init\" | \"get\" | \"set\",
key: Literal | Identifier,
value: Expression): Property;
functionExpression(id: ?Identifier,
params: Pattern[],
body: BlockStatement): FunctionExpression;
binaryExpression(operator: BinaryOperator,
left: Expression,
right: Expression): BinaryExpression;
unaryExpression(operator: UnaryOperator,
argument: Expression,
prefix: boolean): UnaryExpression;
assignmentExpression(operator: AssignmentOperator,
left: Pattern,
right: Expression): AssignmentExpression;
updateExpression(operator: UpdateOperator,
argument: Expression,
prefix: boolean): UpdateExpression;
logicalExpression(operator: LogicalOperator,
left: Expression,
right: Expression): LogicalExpression;
conditionalExpression(test: Expression,
consequent: Expression,
alternate: Expression): ConditionalExpression;
property(
kind: \"init\" | \"get\" | \"set\",
key: Literal | Identifier,
value: Expression
): Property;
functionExpression(
id: ?Identifier,
params: Pattern[],
body: BlockStatement
): FunctionExpression;
binaryExpression(
operator: BinaryOperator,
left: Expression,
right: Expression
): BinaryExpression;
unaryExpression(
operator: UnaryOperator,
argument: Expression,
prefix: boolean
): UnaryExpression;
assignmentExpression(
operator: AssignmentOperator,
left: Pattern,
right: Expression
): AssignmentExpression;
updateExpression(
operator: UpdateOperator,
argument: Expression,
prefix: boolean
): UpdateExpression;
logicalExpression(
operator: LogicalOperator,
left: Expression,
right: Expression
): LogicalExpression;
conditionalExpression(
test: Expression,
consequent: Expression,
alternate: Expression
): ConditionalExpression;
newExpression(callee: Expression, arguments: Expression[]): NewExpression;
callExpression(callee: Expression, arguments: Expression[]): CallExpression;
memberExpression(object: Expression,
property: Identifier | Expression,
computed: boolean): MemberExpression;
variableDeclaration(kind: \"var\" | \"let\" | \"const\",
declarations: VariableDeclarator[]): VariableDeclaration;
functionDeclaration(id: Identifier,
body: BlockStatement,
params: Pattern[]): FunctionDeclaration;
memberExpression(
object: Expression,
property: Identifier | Expression,
computed: boolean
): MemberExpression;
variableDeclaration(
kind: \"var\" | \"let\" | \"const\",
declarations: VariableDeclarator[]
): VariableDeclaration;
functionDeclaration(
id: Identifier,
body: BlockStatement,
params: Pattern[]
): FunctionDeclaration;
variableDeclarator(id: Pattern, init?: Expression): VariableDeclarator
} = a;
"

View File

@ -447,59 +447,48 @@ 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,
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) {}
}
namespace: string
) {}
}
);
});
}
];
"
@ -907,17 +896,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 +915,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,18 +307,18 @@ 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 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,22 @@ 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

@ -15,8 +15,10 @@ function is_string(x): %checks {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Filter the contents of an array
declare function my_filter<T, P: $Pred<1>>(v: Array<T>,
cb: P): Array<$Refine<T, P, 1>>;
declare function my_filter<T, P: $Pred<1>>(
v: Array<T>,
cb: P
): Array<$Refine<T, P, 1>>;
declare var arr: Array<mixed>;
const barr = my_filter(arr, is_string);
@ -51,8 +53,10 @@ declare var ab: Array<A|B|C>;
// Filter the contents of an array
// OK
// OK
declare function my_filter<T, P: $Pred<1>>(v: Array<T>,
cb: P): Array<$Refine<T, P, 1>>;
declare function my_filter<T, P: $Pred<1>>(
v: Array<T>,
cb: P
): Array<$Refine<T, P, 1>>;
type A = { kind: \"A\"; u: number };
type B = { kind: \"B\"; v: string };
type C = { kind: \"C\"; y: boolean };
@ -140,9 +144,11 @@ var b = refine(a, is_string);
(b: string);
declare function refine_fst<T, P: $Pred<2>>(v: T,
w: T,
cb: P): $Refine<T, P, 1>;
declare function refine_fst<T, P: $Pred<2>>(
v: T,
w: T,
cb: P
): $Refine<T, P, 1>;
declare var c: mixed;
declare var d: mixed;
var e = refine2(c, d, is_string_and_number);
@ -188,8 +194,10 @@ function is_string_regular(x): boolean {
// @flow
// Sanity check A: filtering the wrong type
// Sanity check B: Passing non-predicate function to filter
declare function my_filter<T, P: $Pred<1>>(v: Array<T>,
cb: P): Array<$Refine<T, P, 1>>;
declare function my_filter<T, P: $Pred<1>>(
v: Array<T>,
cb: P
): Array<$Refine<T, P, 1>>;
declare var a: Array<mixed>;
const b = my_filter(a, is_string);
@ -233,8 +241,10 @@ declare var ab: Array<A|B|C>;
// Filter the contents of an array
// ERROR
// ERROR
declare function my_filter<T, P: $Pred<1>>(v: Array<T>,
cb: P): Array<$Refine<T, P, 1>>;
declare function my_filter<T, P: $Pred<1>>(
v: Array<T>,
cb: P
): Array<$Refine<T, P, 1>>;
type A = { kind: \"A\"; u: number };
type B = { kind: \"B\"; v: string };
type C = { kind: \"C\"; y: boolean };
@ -312,10 +322,12 @@ var b = refine(a, is_string);
declare var c: mixed;
declare var d: mixed;
declare var e: mixed;
declare function refine3<T, P: $Pred<3>>(u: T,
v: T,
w: T,
cb: P): $Refine<T, P, 1>;
declare function refine3<T, P: $Pred<3>>(
u: T,
v: T,
w: T,
cb: P
): $Refine<T, P, 1>;
var e = refine3(c, d, e, is_string_and_number);
(e: string);

View File

@ -400,9 +400,10 @@ foo(3, 3);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Sanity check: make sure the parameters are checked as usual
declare function foo(input: mixed,
types: string | Array<string>): boolean %checks(typeof input === \"string\" ||
Array.isArray(input));
declare function foo(
input: mixed,
types: string | Array<string>
): boolean %checks(typeof input === \"string\" || Array.isArray(input));
foo(3, 3);
"

View File

@ -102,8 +102,9 @@ var a1 = (x: mixed): %checks => x !== null;
(x): %checks => x !== null;
const insert_a_really_big_predicated_arrow_function_name_here = (x): %checks => x !==
null;
const insert_a_really_big_predicated_arrow_function_name_here = (
x
): %checks => x !== null;
declare var x;
x;

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

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

@ -61,7 +61,9 @@ function id(x: Task<any,any>): Task<any,any> { return x; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
type Task<error, value> = {
chain<tagged>(next: (input: value) => Task<error, tagged>): Task<error, tagged>
chain<tagged>(
next: (input: value) => Task<error, tagged>
): Task<error, tagged>
};
function id(x: Task<any, any>): Task<any, any> {

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

@ -160,21 +160,20 @@ function test(
* result is a new object.
*/
// OK
declare function map<Tv, TNext>(obj: { [key: string]: Tv },
iterator: (obj: Tv) => TNext): Array<TNext>;
declare function map<Tv, TNext>(
obj: { [key: string]: Tv },
iterator: (obj: Tv) => TNext
): Array<TNext>;
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) {}

View File

@ -55,12 +55,20 @@ declare class Promise<R> {
// library files declared earlier, including default flow libs.
// Non-standard APIs
declare class Promise<R> {
constructor(callback: (resolve: (result?: Promise<R> | R) => void,
reject: (error?: any) => void) => void): void;
then<U>(onFulfill?: ?(value: R) => Promise<U> | ?U,
onReject?: ?(error: any) => Promise<U> | ?U): Promise<U>;
done<U>(onFulfill?: ?(value: R) => void,
onReject?: ?(error: any) => void): void;
constructor(
callback: (
resolve: (result?: Promise<R> | R) => void,
reject: (error?: any) => void
) => void
): void;
then<U>(
onFulfill?: ?(value: R) => Promise<U> | ?U,
onReject?: ?(error: any) => Promise<U> | ?U
): Promise<U>;
done<U>(
onFulfill?: ?(value: R) => void,
onReject?: ?(error: any) => void
): void;
catch<U>(onReject?: (error: any) => ?Promise<U> | U): Promise<U>;
static resolve<T>(object?: Promise<T> | T): Promise<T>;
static reject<T>(error?: any): Promise<T>;
@ -68,9 +76,9 @@ declare class Promise<R> {
static cast<T>(object?: T): Promise<T>;
static all<T>(promises: Array<?Promise<T> | T>): Promise<Array<T>>;
static race<T>(promises: Array<Promise<T>>): Promise<T>;
static allObject<T: Object>(promisesByKey: T): Promise<{
[key: $Keys<T>]: any
}>
static allObject<T: Object>(
promisesByKey: T
): Promise<{ [key: $Keys<T>]: any }>
}
"
`;

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);
"
@ -1629,10 +1626,12 @@ declare class C {
setMaxListeners(n: number): void
}
declare class D extends C {
listen(port: number,
hostname?: string,
backlog?: number,
callback?: Function): D;
listen(
port: number,
hostname?: string,
backlog?: number,
callback?: Function
): D;
listen(path: string, callback?: Function): D;
listen(handle: Object, callback?: Function): D;
close(callback?: Function): D;
@ -1815,10 +1814,14 @@ class C {
// with different instantiations.
type Row = { x: string };
declare class D<T> {
reduce(callbackfn: (previousValue: T, currentValue: T) => T,
initialValue: void): T;
reduce<U>(callbackfn: (previousValue: U, currentValue: T) => U,
initialValue: U): U
reduce(
callbackfn: (previousValue: T, currentValue: T) => T,
initialValue: void
): T;
reduce<U>(
callbackfn: (previousValue: U, currentValue: T) => U,
initialValue: U
): U
}
class C {
foo(rows: D<Row>, minWidth: number): number {

View File

@ -30,15 +30,20 @@ declare class Rows {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
declare class Set<T> { add(): Set<T> }
declare class Row {
reduce_row(callbackfn: (previousValue: number,
currentValue: number) => number,
initialValue: void): number;
reduce_row<U>(callbackfn: (previousValue: U, currentValue: number) => U,
initialValue: U): U
reduce_row(
callbackfn: (previousValue: number, currentValue: number) => number,
initialValue: void
): number;
reduce_row<U>(
callbackfn: (previousValue: U, currentValue: number) => U,
initialValue: U
): U
}
declare class Rows {
reduce_rows<X>(callbackfn: (previousValue: X, currentValue: Row) => X,
initialValue: X): X
reduce_rows<X>(
callbackfn: (previousValue: X, currentValue: Row) => X,
initialValue: X
): X
}
"
`;