feat(typescript): add TSTypeAssertionExpression and naive TSX detection (#1545)
parent
3471ce4584
commit
fa27e5838c
|
@ -313,6 +313,7 @@ FPp.needsParens = function() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// else fall through
|
// else fall through
|
||||||
|
case "TSTypeAssertionExpression":
|
||||||
case "TSAsExpression":
|
case "TSAsExpression":
|
||||||
case "LogicalExpression":
|
case "LogicalExpression":
|
||||||
switch (parent.type) {
|
switch (parent.type) {
|
||||||
|
@ -320,6 +321,7 @@ FPp.needsParens = function() {
|
||||||
case "NewExpression":
|
case "NewExpression":
|
||||||
return name === "callee" && parent.callee === node;
|
return name === "callee" && parent.callee === node;
|
||||||
|
|
||||||
|
case "TSTypeAssertionExpression":
|
||||||
case "TaggedTemplateExpression":
|
case "TaggedTemplateExpression":
|
||||||
case "UnaryExpression":
|
case "UnaryExpression":
|
||||||
case "SpreadElement":
|
case "SpreadElement":
|
||||||
|
|
|
@ -64,7 +64,7 @@ function parseWithTypeScript(text) {
|
||||||
tokens: true,
|
tokens: true,
|
||||||
attachComment: true,
|
attachComment: true,
|
||||||
ecmaFeatures: {
|
ecmaFeatures: {
|
||||||
jsx: true
|
jsx: isJsx(text)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -76,4 +76,16 @@ function parseWithTypeScript(text) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use a naive regular expression until we address
|
||||||
|
* https://github.com/prettier/prettier/issues/1538
|
||||||
|
*/
|
||||||
|
function isJsx(text) {
|
||||||
|
return new RegExp([
|
||||||
|
"(</)", // Contains "</"
|
||||||
|
"|",
|
||||||
|
"(^[^/]{2}.*\/>)" // Contains "/>" on line not starting with "//"
|
||||||
|
].join(""), "m").test(text);
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = { parseWithFlow, parseWithBabylon, parseWithTypeScript };
|
module.exports = { parseWithFlow, parseWithBabylon, parseWithTypeScript };
|
||||||
|
|
|
@ -257,6 +257,13 @@ function genericPrintNoParens(path, options, print, args) {
|
||||||
" = ",
|
" = ",
|
||||||
path.call(print, "right")
|
path.call(print, "right")
|
||||||
]);
|
]);
|
||||||
|
case "TSTypeAssertionExpression":
|
||||||
|
return concat([
|
||||||
|
"<",
|
||||||
|
path.call(print, "typeAnnotation"),
|
||||||
|
">",
|
||||||
|
path.call(print, "expression")
|
||||||
|
]);
|
||||||
case "MemberExpression": {
|
case "MemberExpression": {
|
||||||
const parent = path.getParentNode();
|
const parent = path.getParentNode();
|
||||||
let firstNonMemberParent;
|
let firstNonMemberParent;
|
||||||
|
|
|
@ -180,4 +180,10 @@ module.exports = function(fork) {
|
||||||
def("TSTypeParameter").build("name").field("name", def("Identifier"));
|
def("TSTypeParameter").build("name").field("name", def("Identifier"));
|
||||||
|
|
||||||
def("TSParameterProperty").build("accessibility", "isReadonly", "parameters");
|
def("TSParameterProperty").build("accessibility", "isReadonly", "parameters");
|
||||||
|
|
||||||
|
def("TSTypeAssertionExpression")
|
||||||
|
.build("expression", "typeAnnotation")
|
||||||
|
.field("expression", def("Identifier"))
|
||||||
|
.field("typeAnnotation", def("TSType"))
|
||||||
|
.bases("Expression");
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,6 +20,119 @@ var results = number[];
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`castOfAwait.ts 1`] = `
|
||||||
|
// @target: es6
|
||||||
|
async function f() {
|
||||||
|
<number> await 0;
|
||||||
|
typeof await 0;
|
||||||
|
void await 0;
|
||||||
|
await void <string> typeof <number> void await 0;
|
||||||
|
await await 0;
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// @target: es6
|
||||||
|
async function f() {
|
||||||
|
<number>await 0;
|
||||||
|
typeof await 0;
|
||||||
|
void await 0;
|
||||||
|
await void (<string>typeof (<number>void await 0));
|
||||||
|
await await 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`castParentheses.ts 1`] = `
|
||||||
|
class a {
|
||||||
|
static b: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
var b = (<any>a);
|
||||||
|
var b = (<any>a).b;
|
||||||
|
var b = (<any>a.b).c;
|
||||||
|
var b = (<any>a.b()).c;
|
||||||
|
var b = (<any>new a);
|
||||||
|
var b = (<any>new a.b);
|
||||||
|
var b = (<any>new a).b
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
class a {
|
||||||
|
static b: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
var b = <any>a;
|
||||||
|
var b = (<any>a).b;
|
||||||
|
var b = (<any>a.b).c;
|
||||||
|
var b = (<any>a.b()).c;
|
||||||
|
var b = <any>new a();
|
||||||
|
var b = <any>new a.b();
|
||||||
|
var b = (<any>new a()).b;
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`castTest.ts 1`] = `
|
||||||
|
|
||||||
|
var x : any = 0;
|
||||||
|
var z = <number> x;
|
||||||
|
var y = x + z;
|
||||||
|
|
||||||
|
var a = <any>0;
|
||||||
|
var b = <boolean>true;
|
||||||
|
var s = <string>"";
|
||||||
|
|
||||||
|
var ar = <any[]>null;
|
||||||
|
|
||||||
|
var f = <(res : number) => void>null;
|
||||||
|
|
||||||
|
declare class Point
|
||||||
|
{
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
add(dx: number, dy: number): Point;
|
||||||
|
mult(p: Point): Point;
|
||||||
|
constructor(x: number, y: number);
|
||||||
|
}
|
||||||
|
|
||||||
|
var p_cast = <Point> ({
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
add: function(dx, dy) {
|
||||||
|
return new Point(this.x + dx, this.y + dy);
|
||||||
|
},
|
||||||
|
mult: function(p) { return p; }
|
||||||
|
})
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
var x: any = 0;
|
||||||
|
var z = <number>x;
|
||||||
|
var y = x + z;
|
||||||
|
|
||||||
|
var a = <any>0;
|
||||||
|
var b = <boolean>true;
|
||||||
|
var s = <string>"";
|
||||||
|
|
||||||
|
var ar = <any[]>null;
|
||||||
|
|
||||||
|
var f = <(res: number) => void>null;
|
||||||
|
|
||||||
|
declare class Point {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
add(dx: number, dy: number): Point;
|
||||||
|
mult(p: Point): Point;
|
||||||
|
constructor(x: number, y: number);
|
||||||
|
}
|
||||||
|
|
||||||
|
var p_cast = <Point>{
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
add: function(dx, dy) {
|
||||||
|
return new Point(this.x + dx, this.y + dy);
|
||||||
|
},
|
||||||
|
mult: function(p) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`checkInfiniteExpansionTermination.ts 1`] = `
|
exports[`checkInfiniteExpansionTermination.ts 1`] = `
|
||||||
// Regression test for #1002
|
// Regression test for #1002
|
||||||
// Before fix this code would cause infinite loop
|
// Before fix this code would cause infinite loop
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// @target: es6
|
||||||
|
async function f() {
|
||||||
|
<number> await 0;
|
||||||
|
typeof await 0;
|
||||||
|
void await 0;
|
||||||
|
await void <string> typeof <number> void await 0;
|
||||||
|
await await 0;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
class a {
|
||||||
|
static b: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
var b = (<any>a);
|
||||||
|
var b = (<any>a).b;
|
||||||
|
var b = (<any>a.b).c;
|
||||||
|
var b = (<any>a.b()).c;
|
||||||
|
var b = (<any>new a);
|
||||||
|
var b = (<any>new a.b);
|
||||||
|
var b = (<any>new a).b
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
var x : any = 0;
|
||||||
|
var z = <number> x;
|
||||||
|
var y = x + z;
|
||||||
|
|
||||||
|
var a = <any>0;
|
||||||
|
var b = <boolean>true;
|
||||||
|
var s = <string>"";
|
||||||
|
|
||||||
|
var ar = <any[]>null;
|
||||||
|
|
||||||
|
var f = <(res : number) => void>null;
|
||||||
|
|
||||||
|
declare class Point
|
||||||
|
{
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
add(dx: number, dy: number): Point;
|
||||||
|
mult(p: Point): Point;
|
||||||
|
constructor(x: number, y: number);
|
||||||
|
}
|
||||||
|
|
||||||
|
var p_cast = <Point> ({
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
add: function(dx, dy) {
|
||||||
|
return new Point(this.x + dx, this.y + dy);
|
||||||
|
},
|
||||||
|
mult: function(p) { return p; }
|
||||||
|
})
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`templateStringWithEmbeddedTypeAssertionOnAdditionES6.ts 1`] = `
|
||||||
|
// @target: ES6
|
||||||
|
var x = \`abc\${ <any>(10 + 10) }def\`;
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// @target: ES6
|
||||||
|
var x = \`abc\${<any>(10 + 10)}def\`;
|
||||||
|
|
||||||
|
`;
|
|
@ -0,0 +1 @@
|
||||||
|
run_spec(__dirname, { parser: "typescript" });
|
|
@ -0,0 +1,2 @@
|
||||||
|
// @target: ES6
|
||||||
|
var x = `abc${ <any>(10 + 10) }def`;
|
|
@ -0,0 +1,106 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`callWithSpreadES6.ts 1`] = `
|
||||||
|
// @target: ES6
|
||||||
|
|
||||||
|
interface X {
|
||||||
|
foo(x: number, y: number, ...z: string[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function foo(x: number, y: number, ...z: string[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
var a: string[];
|
||||||
|
var z: number[];
|
||||||
|
var obj: X;
|
||||||
|
var xa: X[];
|
||||||
|
|
||||||
|
foo(1, 2, "abc");
|
||||||
|
foo(1, 2, ...a);
|
||||||
|
foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
obj.foo(1, 2, "abc");
|
||||||
|
obj.foo(1, 2, ...a);
|
||||||
|
obj.foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
(obj.foo)(1, 2, "abc");
|
||||||
|
(obj.foo)(1, 2, ...a);
|
||||||
|
(obj.foo)(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
xa[1].foo(1, 2, "abc");
|
||||||
|
xa[1].foo(1, 2, ...a);
|
||||||
|
xa[1].foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
(<Function>xa[1].foo)(...[1, 2, "abc"]);
|
||||||
|
|
||||||
|
class C {
|
||||||
|
constructor(x: number, y: number, ...z: string[]) {
|
||||||
|
this.foo(x, y);
|
||||||
|
this.foo(x, y, ...z);
|
||||||
|
}
|
||||||
|
foo(x: number, y: number, ...z: string[]) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class D extends C {
|
||||||
|
constructor() {
|
||||||
|
super(1, 2);
|
||||||
|
super(1, 2, ...a);
|
||||||
|
}
|
||||||
|
foo() {
|
||||||
|
super.foo(1, 2);
|
||||||
|
super.foo(1, 2, ...a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// @target: ES6
|
||||||
|
|
||||||
|
interface X {
|
||||||
|
foo(x: number, y: number, ...z: string[])
|
||||||
|
}
|
||||||
|
|
||||||
|
function foo(x: number, y: number, ...z: string[]) {}
|
||||||
|
|
||||||
|
var a: string[];
|
||||||
|
var z: number[];
|
||||||
|
var obj: X;
|
||||||
|
var xa: X[];
|
||||||
|
|
||||||
|
foo(1, 2, "abc");
|
||||||
|
foo(1, 2, ...a);
|
||||||
|
foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
obj.foo(1, 2, "abc");
|
||||||
|
obj.foo(1, 2, ...a);
|
||||||
|
obj.foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
obj.foo(1, 2, "abc");
|
||||||
|
obj.foo(1, 2, ...a);
|
||||||
|
obj.foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
xa[1].foo(1, 2, "abc");
|
||||||
|
xa[1].foo(1, 2, ...a);
|
||||||
|
xa[1].foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
(<Function>xa[1].foo)(...[1, 2, "abc"]);
|
||||||
|
|
||||||
|
class C {
|
||||||
|
constructor(x: number, y: number, ...z: string[]) {
|
||||||
|
this.foo(x, y);
|
||||||
|
this.foo(x, y, ...z);
|
||||||
|
}
|
||||||
|
foo(x: number, y: number, ...z: string[]) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class D extends C {
|
||||||
|
constructor() {
|
||||||
|
super(1, 2);
|
||||||
|
super(1, 2, ...a);
|
||||||
|
}
|
||||||
|
foo() {
|
||||||
|
super.foo(1, 2);
|
||||||
|
super.foo(1, 2, ...a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
`;
|
|
@ -0,0 +1,51 @@
|
||||||
|
// @target: ES6
|
||||||
|
|
||||||
|
interface X {
|
||||||
|
foo(x: number, y: number, ...z: string[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function foo(x: number, y: number, ...z: string[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
var a: string[];
|
||||||
|
var z: number[];
|
||||||
|
var obj: X;
|
||||||
|
var xa: X[];
|
||||||
|
|
||||||
|
foo(1, 2, "abc");
|
||||||
|
foo(1, 2, ...a);
|
||||||
|
foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
obj.foo(1, 2, "abc");
|
||||||
|
obj.foo(1, 2, ...a);
|
||||||
|
obj.foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
(obj.foo)(1, 2, "abc");
|
||||||
|
(obj.foo)(1, 2, ...a);
|
||||||
|
(obj.foo)(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
xa[1].foo(1, 2, "abc");
|
||||||
|
xa[1].foo(1, 2, ...a);
|
||||||
|
xa[1].foo(1, 2, ...a, "abc");
|
||||||
|
|
||||||
|
(<Function>xa[1].foo)(...[1, 2, "abc"]);
|
||||||
|
|
||||||
|
class C {
|
||||||
|
constructor(x: number, y: number, ...z: string[]) {
|
||||||
|
this.foo(x, y);
|
||||||
|
this.foo(x, y, ...z);
|
||||||
|
}
|
||||||
|
foo(x: number, y: number, ...z: string[]) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class D extends C {
|
||||||
|
constructor() {
|
||||||
|
super(1, 2);
|
||||||
|
super(1, 2, ...a);
|
||||||
|
}
|
||||||
|
foo() {
|
||||||
|
super.foo(1, 2);
|
||||||
|
super.foo(1, 2, ...a);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
run_spec(__dirname, { parser: "typescript" });
|
Loading…
Reference in New Issue