Various fixes with destructuring default, JSX, and more; all tests pass!
parent
649e8a1efe
commit
7ea2348b03
|
@ -27,7 +27,8 @@
|
||||||
"jsfmt\\.spec\\.js$"
|
"jsfmt\\.spec\\.js$"
|
||||||
],
|
],
|
||||||
"testPathIgnorePatterns": [
|
"testPathIgnorePatterns": [
|
||||||
"tests/new_react"
|
"tests/new_react",
|
||||||
|
"tests/more_react"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,8 @@ FPp.needsParens = function(assumeExpressionContext) {
|
||||||
return parent.type === "ArrayTypeAnnotation";
|
return parent.type === "ArrayTypeAnnotation";
|
||||||
|
|
||||||
case "FunctionTypeAnnotation":
|
case "FunctionTypeAnnotation":
|
||||||
return parent.type === "UnionTypeAnnotation";
|
return parent.type === "UnionTypeAnnotation" ||
|
||||||
|
parent.type === "IntersectionTypeAnnotation";
|
||||||
|
|
||||||
case "Literal":
|
case "Literal":
|
||||||
return parent.type === "MemberExpression"
|
return parent.type === "MemberExpression"
|
||||||
|
@ -351,7 +352,8 @@ FPp.needsParens = function(assumeExpressionContext) {
|
||||||
&& parent.object === node;
|
&& parent.object === node;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return n.ObjectPattern.check(node.left) &&
|
||||||
|
this.firstInStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
case "ArrowFunctionExpression":
|
case "ArrowFunctionExpression":
|
||||||
|
@ -439,7 +441,9 @@ FPp.canBeFirstInStatement = function() {
|
||||||
var node = this.getNode();
|
var node = this.getNode();
|
||||||
return !n.FunctionExpression.check(node)
|
return !n.FunctionExpression.check(node)
|
||||||
&& !n.ObjectExpression.check(node)
|
&& !n.ObjectExpression.check(node)
|
||||||
&& !n.ClassExpression.check(node);
|
&& !n.ClassExpression.check(node)
|
||||||
|
&& !(n.AssignmentExpression.check(node) &&
|
||||||
|
n.ObjectPattern.check(node.left));
|
||||||
};
|
};
|
||||||
|
|
||||||
FPp.firstInStatement = function() {
|
FPp.firstInStatement = function() {
|
||||||
|
|
|
@ -668,15 +668,18 @@ function genericPrintNoParens(path, options, print) {
|
||||||
return printMethod(path, options, print);
|
return printMethod(path, options, print);
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = path.call(print, "key");
|
|
||||||
if (n.computed) {
|
if (n.computed) {
|
||||||
parts.push("[", key, "]");
|
parts.push("[", path.call(print, "key"), "]")
|
||||||
} else {
|
}
|
||||||
parts.push(key);
|
else {
|
||||||
|
parts.push(path.call(print, n.shorthand ? "value" : "key"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!n.shorthand) {
|
if(!n.shorthand) {
|
||||||
parts.push(": ", path.call(print, "value"));
|
parts.push(
|
||||||
|
": ",
|
||||||
|
path.call(print, "value")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return concat(parts);
|
return concat(parts);
|
||||||
|
@ -1082,19 +1085,27 @@ function genericPrintNoParens(path, options, print) {
|
||||||
return openingLines;
|
return openingLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
var children = path.map(function(childPath) {
|
var children = [];
|
||||||
|
path.map(function(childPath) {
|
||||||
var child = childPath.getValue();
|
var child = childPath.getValue();
|
||||||
|
|
||||||
if (namedTypes.Literal.check(child) &&
|
if (namedTypes.Literal.check(child) &&
|
||||||
typeof child.value === "string") {
|
typeof child.value === "string") {
|
||||||
if (/\S/.test(child.value)) {
|
if (/\S/.test(child.value)) {
|
||||||
return child.value.replace(/^\s+|\s+$/g, "").replace(/\n/, hardline);
|
const beginBreak = child.value.match(/^\s*\n/);
|
||||||
|
const endBreak = child.value.match(/\n\s*$/);
|
||||||
|
children.push(
|
||||||
|
beginBreak ? hardline : "",
|
||||||
|
child.value.replace(/^\s+|\s+$/g, ""),
|
||||||
|
endBreak ? hardline : ""
|
||||||
|
);
|
||||||
} else if (/\n/.test(child.value)) {
|
} else if (/\n/.test(child.value)) {
|
||||||
return hardline;
|
children.push(hardline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return print(childPath);
|
children.push(print(childPath));
|
||||||
|
}
|
||||||
}, "children");
|
}, "children");
|
||||||
|
|
||||||
var mostChildren = children.slice(0, -1);
|
var mostChildren = children.slice(0, -1);
|
||||||
|
@ -1120,10 +1131,10 @@ function genericPrintNoParens(path, options, print) {
|
||||||
return concat(["</", path.call(print, "name"), ">"]);
|
return concat(["</", path.call(print, "name"), ">"]);
|
||||||
|
|
||||||
case "JSXText":
|
case "JSXText":
|
||||||
return fromString(n.value, options);
|
throw new Error("JSXTest should be handled by JSXElement");
|
||||||
|
|
||||||
case "JSXEmptyExpression":
|
case "JSXEmptyExpression":
|
||||||
return fromString("");
|
return "";
|
||||||
|
|
||||||
case "TypeAnnotatedIdentifier":
|
case "TypeAnnotatedIdentifier":
|
||||||
return concat([
|
return concat([
|
||||||
|
@ -1425,7 +1436,11 @@ function genericPrintNoParens(path, options, print) {
|
||||||
return fromString("number", options);
|
return fromString("number", options);
|
||||||
|
|
||||||
case "ObjectTypeCallProperty":
|
case "ObjectTypeCallProperty":
|
||||||
return path.call(print, "value");
|
if(n.static) {
|
||||||
|
parts.push("static ");
|
||||||
|
}
|
||||||
|
parts.push(path.call(print, "value"));
|
||||||
|
return concat(parts);
|
||||||
|
|
||||||
case "ObjectTypeIndexer":
|
case "ObjectTypeIndexer":
|
||||||
var variance =
|
var variance =
|
||||||
|
@ -1808,12 +1823,12 @@ function printExportDeclaration(path, options, print) {
|
||||||
|
|
||||||
} else if (decl.specifiers &&
|
} else if (decl.specifiers &&
|
||||||
decl.specifiers.length > 0) {
|
decl.specifiers.length > 0) {
|
||||||
|
|
||||||
if (decl.specifiers.length === 1 &&
|
if (decl.specifiers.length === 1 &&
|
||||||
decl.specifiers[0].type === "ExportBatchSpecifier") {
|
decl.specifiers[0].type === "ExportBatchSpecifier") {
|
||||||
parts.push("*");
|
parts.push("*");
|
||||||
} else {
|
} else {
|
||||||
parts.push(
|
parts.push(
|
||||||
|
decl.exportKind === "type" ? "type " : "",
|
||||||
shouldPrintSpaces ? "{ " : "{",
|
shouldPrintSpaces ? "{ " : "{",
|
||||||
join(", ", path.map(print, "specifiers")),
|
join(", ", path.map(print, "specifiers")),
|
||||||
shouldPrintSpaces ? " }" : "}"
|
shouldPrintSpaces ? " }" : "}"
|
||||||
|
|
|
@ -40,7 +40,11 @@ Foo.prototype = {
|
||||||
};
|
};
|
||||||
exports.Foo = Foo;
|
exports.Foo = Foo;
|
||||||
interface IFooPrototype { m(): number }
|
interface IFooPrototype { m(): number }
|
||||||
interface IFoo extends IFooPrototype { (): void; x: boolean; static y: boolean }
|
interface IFoo extends IFooPrototype {
|
||||||
|
static (): void;
|
||||||
|
x: boolean;
|
||||||
|
static y: boolean
|
||||||
|
}
|
||||||
exports.Foo2 = (Foo: Class<IFoo>);
|
exports.Foo2 = (Foo: Class<IFoo>);
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -180,7 +180,7 @@ function default_expr_scope({a, b = a}) {}
|
||||||
// ok
|
// ok
|
||||||
// union-like upper bounds preserved through destructuring
|
// union-like upper bounds preserved through destructuring
|
||||||
// TODO: union-of-objects upper bounds preserved through destructuring
|
// TODO: union-of-objects upper bounds preserved through destructuring
|
||||||
function obj_prop_fun({ p: { q } = { q: true } } = { p: { q: \"\" } }) {
|
function obj_prop_fun({ p: { q = 0 } = { q: true } } = { p: { q: \"\" } }) {
|
||||||
(q: void);
|
(q: void);
|
||||||
}
|
}
|
||||||
obj_prop_fun();
|
obj_prop_fun();
|
||||||
|
@ -188,7 +188,7 @@ obj_prop_fun({});
|
||||||
obj_prop_fun({ p: {} });
|
obj_prop_fun({ p: {} });
|
||||||
obj_prop_fun({ p: { q: null } });
|
obj_prop_fun({ p: { q: null } });
|
||||||
function obj_prop_var(o = { p: { q: \"\" } }) {
|
function obj_prop_var(o = { p: { q: \"\" } }) {
|
||||||
var { p: { q } = { q: true } } = o;
|
var { p: { q = 0 } = { q: true } } = o;
|
||||||
(q: void);
|
(q: void);
|
||||||
}
|
}
|
||||||
obj_prop_var();
|
obj_prop_var();
|
||||||
|
@ -204,10 +204,10 @@ obj_rest();
|
||||||
obj_rest({});
|
obj_rest({});
|
||||||
obj_rest({ p: {} });
|
obj_rest({ p: {} });
|
||||||
obj_rest({ p: { q: 0, r: null } });
|
obj_rest({ p: { q: 0, r: null } });
|
||||||
function obj_prop_annot({ p }: { p: string } = { p: 0 }) {
|
function obj_prop_annot({ p = true }: { p: string } = { p: 0 }) {
|
||||||
(p: void);
|
(p: void);
|
||||||
}
|
}
|
||||||
var { p }: { p: string } = { p: 0 };
|
var { p = true }: { p: string } = { p: 0 };
|
||||||
(p: void);
|
(p: void);
|
||||||
function obj_prop_err({ x: { y } } = null) {
|
function obj_prop_err({ x: { y } } = null) {
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ function arr_elem_err([ x ] = null) {
|
||||||
function arr_rest_err([ ...a ] = null) {
|
function arr_rest_err([ ...a ] = null) {
|
||||||
|
|
||||||
}
|
}
|
||||||
function gen<T>(x: T, { p }: { p: T }): T {
|
function gen<T>(x: T, { p = x }: { p: T }): T {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
obj_prop_fun(({}: { p?: { q?: null } }));
|
obj_prop_fun(({}: { p?: { q?: null } }));
|
||||||
|
@ -238,7 +238,7 @@ function obj_prop_union({ p }: { p: number | string } = { p: true }) {
|
||||||
function obj_prop_union2({ p }: { p: number } | { p: string } = { p: true }) {
|
function obj_prop_union2({ p }: { p: number } | { p: string } = { p: true }) {
|
||||||
|
|
||||||
}
|
}
|
||||||
function default_expr_scope({ a, b }) {
|
function default_expr_scope({ a, b = a }) {
|
||||||
|
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
@ -330,9 +330,9 @@ declare var b: string;
|
||||||
declare var c: string;
|
declare var c: string;
|
||||||
[ { a1: a, b }, c ] = [ { a1: 0, b: 1 }, 2 ];
|
[ { a1: a, b }, c ] = [ { a1: 0, b: 1 }, 2 ];
|
||||||
var { m } = { m: 0 };
|
var { m } = { m: 0 };
|
||||||
{ m } = { m: m };
|
({ m } = { m: m });
|
||||||
var obj;
|
var obj;
|
||||||
{ n: obj.x } = { n: 3 };
|
({ n: obj.x } = { n: 3 });
|
||||||
[ obj.x ] = [ \"foo\" ];
|
[ obj.x ] = [ \"foo\" ];
|
||||||
function foo({ p, z: [ r ] }) {
|
function foo({ p, z: [ r ] }) {
|
||||||
a = p;
|
a = p;
|
||||||
|
@ -420,7 +420,7 @@ exports[`test eager.js 1`] = `
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, property \`x\` can not be accessed on \`null\`
|
// error, property \`x\` can not be accessed on \`null\`
|
||||||
var x;
|
var x;
|
||||||
{ x } = null;
|
({ x } = null);
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -99,10 +99,10 @@ export type inlinedType1 = number;
|
||||||
var a: inlinedType1 = 42;
|
var a: inlinedType1 = 42;
|
||||||
var b: inlinedType1 = \"asdf\";
|
var b: inlinedType1 = \"asdf\";
|
||||||
type standaloneType1 = number;
|
type standaloneType1 = number;
|
||||||
export { standaloneType1 }
|
export type { standaloneType1 }
|
||||||
type standaloneType2 = number;
|
type standaloneType2 = number;
|
||||||
export { standaloneType2 }
|
export { standaloneType2 }
|
||||||
export { talias1, talias2 as talias3, IFoo2 } from \"./types_only2\"
|
export type { talias1, talias2 as talias3, IFoo2 } from \"./types_only2\"
|
||||||
export interface IFoo { prop: number }
|
export interface IFoo { prop: number }
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -45,7 +45,7 @@ import type {Foo} from \'./types\';
|
||||||
// Follows non-destructured property access of \`require(\'Parent\')\`
|
// Follows non-destructured property access of \`require(\'Parent\')\`
|
||||||
var Parent = require(\"./Parent\");
|
var Parent = require(\"./Parent\");
|
||||||
let ParentFoo;
|
let ParentFoo;
|
||||||
{ ParentFoo } = Parent;
|
({ ParentFoo } = Parent);
|
||||||
ParentFoo;
|
ParentFoo;
|
||||||
let ParentFoo2;
|
let ParentFoo2;
|
||||||
ParentFoo2 = Parent;
|
ParentFoo2 = Parent;
|
||||||
|
|
|
@ -147,7 +147,7 @@ type FG = (_: ObjA | ObjB) => void;
|
||||||
declare var fun1: F & G;
|
declare var fun1: F & G;
|
||||||
(fun1: FG);
|
(fun1: FG);
|
||||||
var fun2: FG = fun1;
|
var fun2: FG = fun1;
|
||||||
declare var f: (_: number) => void & (_: string) => void;
|
declare var f: ((_: number) => void) & ((_: string) => void);
|
||||||
var g: (_: number | string) => void = f;
|
var g: (_: number | string) => void = f;
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,160 +0,0 @@
|
||||||
exports[`test API.react.js 1`] = `
|
|
||||||
"
|
|
||||||
var app = require(\'JSX\');
|
|
||||||
|
|
||||||
app.setProps({y:42}); // error, y:number but foo expects string in App.react
|
|
||||||
app.setState({z:42}); // error, z:number but foo expects string in App.react
|
|
||||||
|
|
||||||
function bar(x:number) { }
|
|
||||||
bar(app.props.children); // No error, App doesn\'t specify propTypes so anything goes
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
// error, y:number but foo expects string in App.react
|
|
||||||
// error, z:number but foo expects string in App.react
|
|
||||||
// No error, App doesn\'t specify propTypes so anything goes
|
|
||||||
var app = require(\"JSX\");
|
|
||||||
app.setProps({ y: 42 });
|
|
||||||
app.setState({ z: 42 });
|
|
||||||
function bar(x: number) {
|
|
||||||
|
|
||||||
}
|
|
||||||
bar(app.props.children);
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`test App.react.js 1`] = `
|
|
||||||
"
|
|
||||||
/**
|
|
||||||
* @providesModule App.react
|
|
||||||
* @jsx React.DOM
|
|
||||||
*/
|
|
||||||
|
|
||||||
var React = require(\'react\');
|
|
||||||
|
|
||||||
// expect args to be strings
|
|
||||||
function foo(p:string,q:string):string { return p+q; }
|
|
||||||
|
|
||||||
var App = React.createClass({
|
|
||||||
|
|
||||||
getDefaultProps: function(): { y: string } {
|
|
||||||
return {y:\"\"}; // infer props.y: string
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function() {
|
|
||||||
return {z:0}; // infer state.z: number
|
|
||||||
},
|
|
||||||
|
|
||||||
handler: function() {
|
|
||||||
this.setState({z:42}); // ok
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
|
||||||
var x = this.props.x;
|
|
||||||
var y = this.props.y;
|
|
||||||
var z = this.state.z;
|
|
||||||
|
|
||||||
//this.state;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{foo(x,y)}
|
|
||||||
{foo(z,x)} // error, since z: number
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = App;
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
/**
|
|
||||||
* @providesModule App.react
|
|
||||||
* @jsx React.DOM
|
|
||||||
*/
|
|
||||||
// expect args to be strings
|
|
||||||
// infer props.y: string
|
|
||||||
// infer state.z: number
|
|
||||||
// ok
|
|
||||||
//this.state;
|
|
||||||
var React = require(\"react\");
|
|
||||||
function foo(p: string, q: string): string {
|
|
||||||
return p + q;
|
|
||||||
}
|
|
||||||
var App = React.createClass({
|
|
||||||
getDefaultProps: function(): { y: string } {
|
|
||||||
return { y: \"\" };
|
|
||||||
},
|
|
||||||
getInitialState: function() {
|
|
||||||
return { z: 0 };
|
|
||||||
},
|
|
||||||
handler: function() {
|
|
||||||
this.setState({ z: 42 });
|
|
||||||
},
|
|
||||||
render: function() {
|
|
||||||
var x = this.props.x;
|
|
||||||
var y = this.props.y;
|
|
||||||
var z = this.state.z;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{foo(x, y)}
|
|
||||||
{foo(z, x)}// error, since z: number</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
module.exports = App;
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`test JSX.js 1`] = `
|
|
||||||
"
|
|
||||||
/* @providesModule JSX */
|
|
||||||
|
|
||||||
var React = require(\'react\');
|
|
||||||
var App = require(\'App.react\');
|
|
||||||
|
|
||||||
var app =
|
|
||||||
<App y={42}> // error, y: number but foo expects string in App.react
|
|
||||||
Some text.
|
|
||||||
</App>;
|
|
||||||
|
|
||||||
module.exports = app;
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
/* @providesModule JSX */
|
|
||||||
var React = require(\"react\");
|
|
||||||
var App = require(\"App.react\");
|
|
||||||
var app = <App y={42}>// error, y: number but foo expects string in App.react[object Object] Some text.</App>;
|
|
||||||
module.exports = app;
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`test propTypes.js 1`] = `
|
|
||||||
"var React = require(\'React\');
|
|
||||||
|
|
||||||
var C = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
title: React.PropTypes.string.isRequired,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var D = React.createClass({
|
|
||||||
propTypes: {
|
|
||||||
name: React.PropTypes.string.isRequired,
|
|
||||||
...C.propTypes,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
<D
|
|
||||||
namee=\'foo\' // error (as usual)
|
|
||||||
titlee=\'bar\' // OK (error ignored when spread is used)
|
|
||||||
/>;
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
/* error (as usual)*/
|
|
||||||
/* OK (error ignored when spread is used)*/
|
|
||||||
var React = require(\"React\");
|
|
||||||
var C = React.createClass({
|
|
||||||
propTypes: { title: React.PropTypes.string.isRequired }
|
|
||||||
});
|
|
||||||
var D = React.createClass({
|
|
||||||
propTypes: { name: React.PropTypes.string.isRequired, ...C.propTypes }
|
|
||||||
});
|
|
||||||
<D namee=\"foo\" titlee=\"bar\"/>;
|
|
||||||
"
|
|
||||||
`;
|
|
Loading…
Reference in New Issue