Various fixes with destructuring default, JSX, and more; all tests pass!
parent
649e8a1efe
commit
7ea2348b03
|
@ -27,7 +27,8 @@
|
|||
"jsfmt\\.spec\\.js$"
|
||||
],
|
||||
"testPathIgnorePatterns": [
|
||||
"tests/new_react"
|
||||
"tests/new_react",
|
||||
"tests/more_react"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -320,7 +320,8 @@ FPp.needsParens = function(assumeExpressionContext) {
|
|||
return parent.type === "ArrayTypeAnnotation";
|
||||
|
||||
case "FunctionTypeAnnotation":
|
||||
return parent.type === "UnionTypeAnnotation";
|
||||
return parent.type === "UnionTypeAnnotation" ||
|
||||
parent.type === "IntersectionTypeAnnotation";
|
||||
|
||||
case "Literal":
|
||||
return parent.type === "MemberExpression"
|
||||
|
@ -351,7 +352,8 @@ FPp.needsParens = function(assumeExpressionContext) {
|
|||
&& parent.object === node;
|
||||
|
||||
default:
|
||||
return false;
|
||||
return n.ObjectPattern.check(node.left) &&
|
||||
this.firstInStatement();
|
||||
}
|
||||
|
||||
case "ArrowFunctionExpression":
|
||||
|
@ -439,7 +441,9 @@ FPp.canBeFirstInStatement = function() {
|
|||
var node = this.getNode();
|
||||
return !n.FunctionExpression.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() {
|
||||
|
|
|
@ -668,15 +668,18 @@ function genericPrintNoParens(path, options, print) {
|
|||
return printMethod(path, options, print);
|
||||
}
|
||||
|
||||
var key = path.call(print, "key");
|
||||
if (n.computed) {
|
||||
parts.push("[", key, "]");
|
||||
} else {
|
||||
parts.push(key);
|
||||
parts.push("[", path.call(print, "key"), "]")
|
||||
}
|
||||
else {
|
||||
parts.push(path.call(print, n.shorthand ? "value" : "key"));
|
||||
}
|
||||
|
||||
if(!n.shorthand) {
|
||||
parts.push(": ", path.call(print, "value"));
|
||||
parts.push(
|
||||
": ",
|
||||
path.call(print, "value")
|
||||
);
|
||||
}
|
||||
|
||||
return concat(parts);
|
||||
|
@ -1082,19 +1085,27 @@ function genericPrintNoParens(path, options, print) {
|
|||
return openingLines;
|
||||
}
|
||||
|
||||
var children = path.map(function(childPath) {
|
||||
var children = [];
|
||||
path.map(function(childPath) {
|
||||
var child = childPath.getValue();
|
||||
|
||||
if (namedTypes.Literal.check(child) &&
|
||||
typeof child.value === "string") {
|
||||
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)) {
|
||||
return hardline;
|
||||
children.push(hardline);
|
||||
}
|
||||
}
|
||||
|
||||
return print(childPath);
|
||||
else {
|
||||
children.push(print(childPath));
|
||||
}
|
||||
}, "children");
|
||||
|
||||
var mostChildren = children.slice(0, -1);
|
||||
|
@ -1120,10 +1131,10 @@ function genericPrintNoParens(path, options, print) {
|
|||
return concat(["</", path.call(print, "name"), ">"]);
|
||||
|
||||
case "JSXText":
|
||||
return fromString(n.value, options);
|
||||
throw new Error("JSXTest should be handled by JSXElement");
|
||||
|
||||
case "JSXEmptyExpression":
|
||||
return fromString("");
|
||||
return "";
|
||||
|
||||
case "TypeAnnotatedIdentifier":
|
||||
return concat([
|
||||
|
@ -1425,7 +1436,11 @@ function genericPrintNoParens(path, options, print) {
|
|||
return fromString("number", options);
|
||||
|
||||
case "ObjectTypeCallProperty":
|
||||
return path.call(print, "value");
|
||||
if(n.static) {
|
||||
parts.push("static ");
|
||||
}
|
||||
parts.push(path.call(print, "value"));
|
||||
return concat(parts);
|
||||
|
||||
case "ObjectTypeIndexer":
|
||||
var variance =
|
||||
|
@ -1808,12 +1823,12 @@ function printExportDeclaration(path, options, print) {
|
|||
|
||||
} else if (decl.specifiers &&
|
||||
decl.specifiers.length > 0) {
|
||||
|
||||
if (decl.specifiers.length === 1 &&
|
||||
decl.specifiers[0].type === "ExportBatchSpecifier") {
|
||||
parts.push("*");
|
||||
} else {
|
||||
parts.push(
|
||||
decl.exportKind === "type" ? "type " : "",
|
||||
shouldPrintSpaces ? "{ " : "{",
|
||||
join(", ", path.map(print, "specifiers")),
|
||||
shouldPrintSpaces ? " }" : "}"
|
||||
|
|
|
@ -40,7 +40,11 @@ Foo.prototype = {
|
|||
};
|
||||
exports.Foo = Foo;
|
||||
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>);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -180,7 +180,7 @@ function default_expr_scope({a, b = a}) {}
|
|||
// ok
|
||||
// union-like 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);
|
||||
}
|
||||
obj_prop_fun();
|
||||
|
@ -188,7 +188,7 @@ obj_prop_fun({});
|
|||
obj_prop_fun({ p: {} });
|
||||
obj_prop_fun({ p: { q: null } });
|
||||
function obj_prop_var(o = { p: { q: \"\" } }) {
|
||||
var { p: { q } = { q: true } } = o;
|
||||
var { p: { q = 0 } = { q: true } } = o;
|
||||
(q: void);
|
||||
}
|
||||
obj_prop_var();
|
||||
|
@ -204,10 +204,10 @@ obj_rest();
|
|||
obj_rest({});
|
||||
obj_rest({ p: {} });
|
||||
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);
|
||||
}
|
||||
var { p }: { p: string } = { p: 0 };
|
||||
var { p = true }: { p: string } = { p: 0 };
|
||||
(p: void);
|
||||
function obj_prop_err({ x: { y } } = null) {
|
||||
|
||||
|
@ -221,7 +221,7 @@ function arr_elem_err([ x ] = 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;
|
||||
}
|
||||
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 default_expr_scope({ a, b }) {
|
||||
function default_expr_scope({ a, b = a }) {
|
||||
|
||||
}
|
||||
"
|
||||
|
@ -330,9 +330,9 @@ declare var b: string;
|
|||
declare var c: string;
|
||||
[ { a1: a, b }, c ] = [ { a1: 0, b: 1 }, 2 ];
|
||||
var { m } = { m: 0 };
|
||||
{ m } = { m: m };
|
||||
({ m } = { m: m });
|
||||
var obj;
|
||||
{ n: obj.x } = { n: 3 };
|
||||
({ n: obj.x } = { n: 3 });
|
||||
[ obj.x ] = [ \"foo\" ];
|
||||
function foo({ p, z: [ r ] }) {
|
||||
a = p;
|
||||
|
@ -420,7 +420,7 @@ exports[`test eager.js 1`] = `
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// error, property \`x\` can not be accessed on \`null\`
|
||||
var x;
|
||||
{ x } = null;
|
||||
({ x } = null);
|
||||
"
|
||||
`;
|
||||
|
||||
|
|
|
@ -99,10 +99,10 @@ export type inlinedType1 = number;
|
|||
var a: inlinedType1 = 42;
|
||||
var b: inlinedType1 = \"asdf\";
|
||||
type standaloneType1 = number;
|
||||
export { standaloneType1 }
|
||||
export type { standaloneType1 }
|
||||
type standaloneType2 = number;
|
||||
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 }
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -45,7 +45,7 @@ import type {Foo} from \'./types\';
|
|||
// Follows non-destructured property access of \`require(\'Parent\')\`
|
||||
var Parent = require(\"./Parent\");
|
||||
let ParentFoo;
|
||||
{ ParentFoo } = Parent;
|
||||
({ ParentFoo } = Parent);
|
||||
ParentFoo;
|
||||
let ParentFoo2;
|
||||
ParentFoo2 = Parent;
|
||||
|
|
|
@ -147,7 +147,7 @@ type FG = (_: ObjA | ObjB) => void;
|
|||
declare var fun1: F & G;
|
||||
(fun1: FG);
|
||||
var fun2: FG = fun1;
|
||||
declare var f: (_: number) => void & (_: string) => void;
|
||||
declare var f: ((_: number) => void) & ((_: string) => void);
|
||||
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