Add TSParameterProperty, TSAbstractClassDeclaration and TSAbstractMethodDefnition (#1410)

* feat(typescript): implement TSParameterProperty

* test(typescript): add TypeScript's classes/constructorDeclarations/constructorParameters tests

* feat(typescript): implement TSAbstractClassDeclaration and TSAbstractMethodDefinition

* test(typescript): add TypeScript's classes/classDeclarations/classAbstractKeyword tests

* fix(build): use join instead of spread operator

* fix(typescript): fix semicolon handling

* fix(typescript): handle accessibility modfiers in TSAbstractMethodDefinition

* test(typescript): remove invalid test results

* test(typescript): remove unimplemented abstract properties from tests

* test(typescript): add snapshots for abstract keyword newline behavior
master
Lucas Azzola 2017-04-27 02:25:58 +10:00 committed by Christopher Chedeau
parent 0a7e462ad7
commit fff743024c
46 changed files with 1951 additions and 6 deletions

View File

@ -67,7 +67,9 @@ function getNodeHelper(path, count) {
for (var i = s.length - 1; i >= 0; i -= 2) {
var value = s[i];
if (n.Node.check(value) && --count < 0) {
// Temp: This can be removed when `ast-types` knows that TSNodes are Nodes.
var isTsNode = value && value.type && value.type.startsWith('TS');
if ((isTsNode || n.Node.check(value)) && --count < 0) {
return value;
}
}

View File

@ -401,9 +401,16 @@ function genericPrintNoParens(path, options, print, args) {
);
}
case "MethodDefinition":
case "TSAbstractMethodDefinition":
if (n.static) {
parts.push("static ");
}
if (n.accessibility) {
parts.push(n.accessibility + " ");
}
if (n.type === "TSAbstractMethodDefinition") {
parts.push("abstract ");
}
parts.push(printMethod(path, options, print));
@ -1468,6 +1475,7 @@ function genericPrintNoParens(path, options, print, args) {
return concat(parts);
case "ClassDeclaration":
case "ClassExpression":
case "TSAbstractClassDeclaration":
return concat(printClass(path, options, print));
case "TemplateElement":
return join(literalline, n.value.raw.split("\n"));
@ -1926,6 +1934,17 @@ function genericPrintNoParens(path, options, print, args) {
parts.push(": ")
parts.push(path.call(print, "typeAnnotation"));
return concat(parts);
case "TSParameterProperty":
if (n.accessibility) {
parts.push(n.accessibility + " ");
}
if (n.isReadonly) {
parts.push("readonly ");
}
parts.push(path.call(print, "parameter"));
return concat(parts);
case "TSTypeReference":
parts.push(path.call(print, "typeName"))
@ -2158,6 +2177,7 @@ function printPropertyKey(path, options, print) {
function printMethod(path, options, print) {
var node = path.getNode();
var semi = options.semi ? ";" : "";
var kind = node.kind;
var parts = [];
@ -2197,11 +2217,15 @@ function printMethod(path, options, print) {
}, "value"),
path.call(p => printReturnType(p, print), "value")
])
),
" ",
path.call(print, "value", "body")
)
);
if (!node.value.body || node.value.body.length === 0) {
parts.push(semi);
} else {
parts.push(" ", path.call(print, "value", "body"));
}
return concat(parts);
}
@ -2679,7 +2703,16 @@ function getFlowVariance(path) {
function printClass(path, options, print) {
const n = path.getValue();
const parts = ["class"];
const parts = [];
if (n.accessibility) {
parts.push(n.accessibility + " ");
}
if (n.type === "TSAbstractClassDeclaration") {
parts.push("abstract ");
}
parts.push("class");
if (n.id) {
parts.push(" ", path.call(print, "id"), path.call(print, "typeParameters"));
@ -3545,6 +3578,8 @@ function classChildNeedsASIProtection(node) {
return node.computed;
// flow
case "MethodDefinition":
// typescript
case "TSAbstractMethodDefinition":
// babylon
case "ClassMethod": {
const isAsync = node.value ? node.value.async : node.async;

View File

@ -0,0 +1,875 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`classAbstractAccessor.ts 1`] = `
abstract class A {
abstract get a();
abstract get aa() { return 1; }
abstract set b(x: string);
abstract set bb(x: string) {}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {
abstract get a();
abstract get aa() {
return 1;
}
abstract set b(x: string);
abstract set bb(x: string) {}
}
`;
exports[`classAbstractAsIdentifier.ts 1`] = `
class abstract {
foo() { return 1; }
}
new abstract;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class abstract {
foo() {
return 1;
}
}
new abstract();
`;
exports[`classAbstractAssignabilityConstructorFunction.ts 1`] = `
abstract class A { }
var AAA: new() => A;
AAA = A;
AAA = "asdf";~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {}
var AAA: new() => A;
AAA = A;
AAA = "asdf";
`;
exports[`classAbstractClinterfaceAssignability.ts 1`] = `
var I: IConstructor;
abstract class A {
x: number;
static y: number;
}
var AA: typeof A;
AA = I;
var AAA: typeof I;
AAA = A;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var I: IConstructor;
abstract class A {
x: number;
static y: number;
}
var AA: typeof A;
AA = I;
var AAA: typeof I;
AAA = A;
`;
exports[`classAbstractConstructorAssignability.ts 1`] = `
class A {}
abstract class B extends A {}
class C extends B {}
var AA : typeof A = B;
var BB : typeof B = A;
var CC : typeof C = B;
new AA;
new BB;
new CC;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {}
abstract class B extends A {}
class C extends B {}
var AA: typeof A = B;
var BB: typeof B = A;
var CC: typeof C = B;
new AA();
new BB();
new CC();
`;
exports[`classAbstractCrashedOnce.ts 1`] = `
abstract class foo {
protected abstract test();
}
class bar extends foo {
test() {
}
}
var x = new bar();~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class foo {
protected abstract test();
}
class bar extends foo {
test() {}
}
var x = new bar();
`;
exports[`classAbstractExtends.ts 1`] = `
class A {
foo() {}
}
abstract class B extends A {
abstract bar();
}
class C extends B { }
abstract class D extends B {}
class E extends B {
bar() {}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {
foo() {}
}
abstract class B extends A {
abstract bar();
}
class C extends B {}
abstract class D extends B {}
class E extends B {
bar() {}
}
`;
exports[`classAbstractFactoryFunction.ts 1`] = `
class A {}
abstract class B extends A {}
function NewA(Factory: typeof A) {
return new A;
}
function NewB(Factory: typeof B) {
return new B;
}
NewA(A);
NewA(B);
NewB(A);
NewB(B);~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {}
abstract class B extends A {}
function NewA(Factory: typeof A) {
return new A();
}
function NewB(Factory: typeof B) {
return new B();
}
NewA(A);
NewA(B);
NewB(A);
NewB(B);
`;
exports[`classAbstractGeneric.ts 1`] = `
abstract class A<T> {
t: T;
abstract foo(): T;
abstract bar(t: T);
}
abstract class B<T> extends A {}
class C<T> extends A {}
class D extends A {}
class E<T> extends A {
foo() { return this.t; }
}
class F<T> extends A {
bar(t : T) {}
}
class G<T> extends A {
foo() { return this.t; }
bar(t: T) { }
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A<T> {
t: T;
abstract foo(): T;
abstract bar(t: T);
}
abstract class B<T> extends A {}
class C<T> extends A {}
class D extends A {}
class E<T> extends A {
foo() {
return this.t;
}
}
class F<T> extends A {
bar(t: T) {}
}
class G<T> extends A {
foo() {
return this.t;
}
bar(t: T) {}
}
`;
exports[`classAbstractImportInstantiation.ts 1`] = `
export abstract class A {}
new A;
new myA;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export abstract class A {}
new A();
new myA();
`;
exports[`classAbstractInAModule.ts 1`] = `
export abstract class A {}
export class B extends A {}
new M.A;
new M.B;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export abstract class A {}
export class B extends A {}
new M.A();
new M.B();
`;
exports[`classAbstractInheritance.ts 1`] = `
abstract class A {}
abstract class B extends A {}
class C extends A {}
abstract class AA {
abstract foo();
}
abstract class BB extends AA {}
class CC extends AA {}
class DD extends BB {}
abstract class EE extends BB {}
class FF extends CC {}
abstract class GG extends CC {}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {}
abstract class B extends A {}
class C extends A {}
abstract class AA {
abstract foo();
}
abstract class BB extends AA {}
class CC extends AA {}
class DD extends BB {}
abstract class EE extends BB {}
class FF extends CC {}
abstract class GG extends CC {}
`;
exports[`classAbstractInstantiations1.ts 1`] = `
abstract class A {}
class B extends A {}
abstract class C extends B {}
new A;
new A(1);
new B;
new C;
var a : A;
var b : B;
var c : C;
a = new B;
b = new B;
c = new B;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {}
class B extends A {}
abstract class C extends B {}
new A();
new A(1);
new B();
new C();
var a: A;
var b: B;
var c: C;
a = new B();
b = new B();
c = new B();
`;
exports[`classAbstractInstantiations2.ts 1`] = `
class A {
}
abstract class B {
foo(): number { return this.bar(); }
abstract bar() : number;
}
new B;
var BB: typeof B = B;
var AA: typeof A = BB;
new AA;
function constructB(Factory : typeof B) {
new Factory;
}
var BB = B;
new BB;
var x : any = C;
new x;
class C extends B { }
abstract class D extends B { }
class E extends B {
bar() { return 1; }
}
abstract class F extends B {
abstract foo() : number;
bar() { return 2; }
}
abstract class G {
abstract qux(x : number) : string;
abstract qux() : number;
y : number;
abstract quz(x : number, y : string) : boolean;
abstract nom(): boolean;
nom(x : number): boolean;
}
class H {
abstract baz() : number;
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {}
abstract class B {
foo(): number {
return this.bar();
}
abstract bar(): number;
}
new B();
var BB: typeof B = B;
var AA: typeof A = BB;
new AA();
function constructB(Factory: typeof B) {
new Factory();
}
var BB = B;
new BB();
var x: any = C;
new x();
class C extends B {}
abstract class D extends B {}
class E extends B {
bar() {
return 1;
}
}
abstract class F extends B {
abstract foo(): number;
bar() {
return 2;
}
}
abstract class G {
abstract qux(x: number): string;
abstract qux(): number;
y: number;
abstract quz(x: number, y: string): boolean;
abstract nom(): boolean;
nom(x: number): boolean;
}
class H {
abstract baz(): number;
}
`;
exports[`classAbstractMethodInNonAbstractClass.ts 1`] = `
class A {
abstract foo();
}
class B {
abstract foo() {}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {
abstract foo();
}
class B {
abstract foo() {}
}
`;
exports[`classAbstractMethodWithImplementation.ts 1`] = `
abstract class A {
abstract foo() {}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {
abstract foo() {}
}
`;
exports[`classAbstractMixedWithModifiers.ts 1`] = `
abstract class A {
abstract foo_a();
public abstract foo_b();
protected abstract foo_c();
private abstract foo_d();
abstract public foo_bb();
abstract protected foo_cc();
abstract private foo_dd();
abstract static foo_d();
static abstract foo_e();
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {
abstract foo_a();
public abstract foo_b();
protected abstract foo_c();
private abstract foo_d();
public abstract foo_bb();
protected abstract foo_cc();
private abstract foo_dd();
static abstract foo_d();
static abstract foo_e();
}
`;
exports[`classAbstractOverloads.ts 1`] = `
abstract class A {
abstract foo();
abstract foo() : number;
abstract foo();
abstract bar();
bar();
abstract bar();
abstract baz();
baz();
abstract baz();
baz() {}
qux();
}
abstract class B {
abstract foo() : number;
abstract foo();
x : number;
abstract foo();
abstract foo();
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {
abstract foo();
abstract foo(): number;
abstract foo();
abstract bar();
bar();
abstract bar();
abstract baz();
baz();
abstract baz();
baz() {}
qux();
}
abstract class B {
abstract foo(): number;
abstract foo();
x: number;
abstract foo();
abstract foo();
}
`;
exports[`classAbstractOverrideWithAbstract.ts 1`] = `
class A {
foo() {}
}
abstract class B extends A {
abstract foo();
}
abstract class AA {
foo() {}
abstract bar();
}
abstract class BB extends AA {
abstract foo();
bar () {}
}
class CC extends BB {}
class DD extends BB {
foo() {}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {
foo() {}
}
abstract class B extends A {
abstract foo();
}
abstract class AA {
foo() {}
abstract bar();
}
abstract class BB extends AA {
abstract foo();
bar() {}
}
class CC extends BB {}
class DD extends BB {
foo() {}
}
`;
exports[`classAbstractProperties.ts 1`] = `
abstract class A {
abstract foo_x() : number;
public abstract foo_y() : number;
protected abstract foo_z() : number;
private abstract foo_w() : number;
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {
abstract foo_x(): number;
public abstract foo_y(): number;
protected abstract foo_z(): number;
private abstract foo_w(): number;
}
`;
exports[`classAbstractSingleLineDecl.ts 1`] = `
abstract class A {}
abstract
class B {}
abstract
class C {}
new A;
new B;
new C;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {}
abstract;
class B {}
abstract;
class C {}
new A();
new B();
new C();
`;
exports[`classAbstractSuperCalls.ts 1`] = `
class A {
foo() { return 1; }
}
abstract class B extends A {
abstract foo();
bar() { super.foo(); }
baz() { return this.foo; }
}
class C extends B {
foo() { return 2; }
qux() { return super.foo() || super.foo; }
norf() { return super.bar(); }
}
class AA {
foo() { return 1; }
bar() { return this.foo(); }
}
abstract class BB extends AA {
abstract foo();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {
foo() {
return 1;
}
}
abstract class B extends A {
abstract foo();
bar() {
super.foo();
}
baz() {
return this.foo;
}
}
class C extends B {
foo() {
return 2;
}
qux() {
return super.foo() || super.foo;
}
norf() {
return super.bar();
}
}
class AA {
foo() {
return 1;
}
bar() {
return this.foo();
}
}
abstract class BB extends AA {
abstract foo();
}
`;
exports[`classAbstractUsingAbstractMethod1.ts 1`] = `
abstract class A {
abstract foo() : number;
}
class B extends A {
foo() { return 1; }
}
abstract class C extends A {
abstract foo() : number;
}
var a = new B;
a.foo();
a = new C;
a.foo();~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
abstract class A {
abstract foo(): number;
}
class B extends A {
foo() {
return 1;
}
}
abstract class C extends A {
abstract foo(): number;
}
var a = new B();
a.foo();
a = new C();
a.foo();
`;
exports[`classAbstractUsingAbstractMethods2.ts 1`] = `
class A {
abstract foo();
}
class B extends A {}
abstract class C extends A {}
class D extends A {
foo() {}
}
abstract class E extends A {
foo() {}
}
abstract class AA {
abstract foo();
}
class BB extends AA {}
abstract class CC extends AA {}
class DD extends AA {
foo() {}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {
abstract foo();
}
class B extends A {}
abstract class C extends A {}
class D extends A {
foo() {}
}
abstract class E extends A {
foo() {}
}
abstract class AA {
abstract foo();
}
class BB extends AA {}
abstract class CC extends AA {}
class DD extends AA {
foo() {}
}
`;
exports[`classAbstractWithInterface.ts 1`] = `
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`;

View File

@ -0,0 +1,7 @@
abstract class A {
abstract get a();
abstract get aa() { return 1; }
abstract set b(x: string);
abstract set bb(x: string) {}
}

View File

@ -0,0 +1,5 @@
class abstract {
foo() { return 1; }
}
new abstract;

View File

@ -0,0 +1,6 @@
abstract class A { }
var AAA: new() => A;
AAA = A;
AAA = "asdf";

View File

@ -0,0 +1,13 @@
var I: IConstructor;
abstract class A {
x: number;
static y: number;
}
var AA: typeof A;
AA = I;
var AAA: typeof I;
AAA = A;

View File

@ -0,0 +1,14 @@
class A {}
abstract class B extends A {}
class C extends B {}
var AA : typeof A = B;
var BB : typeof B = A;
var CC : typeof C = B;
new AA;
new BB;
new CC;

View File

@ -0,0 +1,9 @@
abstract class foo {
protected abstract test();
}
class bar extends foo {
test() {
}
}
var x = new bar();

View File

@ -0,0 +1,16 @@
class A {
foo() {}
}
abstract class B extends A {
abstract bar();
}
class C extends B { }
abstract class D extends B {}
class E extends B {
bar() {}
}

View File

@ -0,0 +1,17 @@
class A {}
abstract class B extends A {}
function NewA(Factory: typeof A) {
return new A;
}
function NewB(Factory: typeof B) {
return new B;
}
NewA(A);
NewA(B);
NewB(A);
NewB(B);

View File

@ -0,0 +1,25 @@
abstract class A<T> {
t: T;
abstract foo(): T;
abstract bar(t: T);
}
abstract class B<T> extends A {}
class C<T> extends A {}
class D extends A {}
class E<T> extends A {
foo() { return this.t; }
}
class F<T> extends A {
bar(t : T) {}
}
class G<T> extends A {
foo() { return this.t; }
bar(t: T) { }
}

View File

@ -0,0 +1,7 @@
export abstract class A {}
new A;
new myA;

View File

@ -0,0 +1,7 @@
export abstract class A {}
export class B extends A {}
new M.A;
new M.B;

View File

@ -0,0 +1,21 @@
abstract class A {}
abstract class B extends A {}
class C extends A {}
abstract class AA {
abstract foo();
}
abstract class BB extends AA {}
class CC extends AA {}
class DD extends BB {}
abstract class EE extends BB {}
class FF extends CC {}
abstract class GG extends CC {}

View File

@ -0,0 +1,19 @@
abstract class A {}
class B extends A {}
abstract class C extends B {}
new A;
new A(1);
new B;
new C;
var a : A;
var b : B;
var c : C;
a = new B;
b = new B;
c = new B;

View File

@ -0,0 +1,50 @@
class A {
}
abstract class B {
foo(): number { return this.bar(); }
abstract bar() : number;
}
new B;
var BB: typeof B = B;
var AA: typeof A = BB;
new AA;
function constructB(Factory : typeof B) {
new Factory;
}
var BB = B;
new BB;
var x : any = C;
new x;
class C extends B { }
abstract class D extends B { }
class E extends B {
bar() { return 1; }
}
abstract class F extends B {
abstract foo() : number;
bar() { return 2; }
}
abstract class G {
abstract qux(x : number) : string;
abstract qux() : number;
y : number;
abstract quz(x : number, y : string) : boolean;
abstract nom(): boolean;
nom(x : number): boolean;
}
class H {
abstract baz() : number;
}

View File

@ -0,0 +1,7 @@
class A {
abstract foo();
}
class B {
abstract foo() {}
}

View File

@ -0,0 +1,3 @@
abstract class A {
abstract foo() {}
}

View File

@ -0,0 +1,15 @@
abstract class A {
abstract foo_a();
public abstract foo_b();
protected abstract foo_c();
private abstract foo_d();
abstract public foo_bb();
abstract protected foo_cc();
abstract private foo_dd();
abstract static foo_d();
static abstract foo_e();
}

View File

@ -0,0 +1,24 @@
abstract class A {
abstract foo();
abstract foo() : number;
abstract foo();
abstract bar();
bar();
abstract bar();
abstract baz();
baz();
abstract baz();
baz() {}
qux();
}
abstract class B {
abstract foo() : number;
abstract foo();
x : number;
abstract foo();
abstract foo();
}

View File

@ -0,0 +1,23 @@
class A {
foo() {}
}
abstract class B extends A {
abstract foo();
}
abstract class AA {
foo() {}
abstract bar();
}
abstract class BB extends AA {
abstract foo();
bar () {}
}
class CC extends BB {}
class DD extends BB {
foo() {}
}

View File

@ -0,0 +1,6 @@
abstract class A {
abstract foo_x() : number;
public abstract foo_y() : number;
protected abstract foo_z() : number;
private abstract foo_w() : number;
}

View File

@ -0,0 +1,12 @@
abstract class A {}
abstract
class B {}
abstract
class C {}
new A;
new B;
new C;

View File

@ -0,0 +1,25 @@
class A {
foo() { return 1; }
}
abstract class B extends A {
abstract foo();
bar() { super.foo(); }
baz() { return this.foo; }
}
class C extends B {
foo() { return 2; }
qux() { return super.foo() || super.foo; }
norf() { return super.bar(); }
}
class AA {
foo() { return 1; }
bar() { return this.foo(); }
}
abstract class BB extends AA {
abstract foo();
}

View File

@ -0,0 +1,17 @@
abstract class A {
abstract foo() : number;
}
class B extends A {
foo() { return 1; }
}
abstract class C extends A {
abstract foo() : number;
}
var a = new B;
a.foo();
a = new C;
a.foo();

View File

@ -0,0 +1,27 @@
class A {
abstract foo();
}
class B extends A {}
abstract class C extends A {}
class D extends A {
foo() {}
}
abstract class E extends A {
foo() {}
}
abstract class AA {
abstract foo();
}
class BB extends AA {}
abstract class CC extends AA {}
class DD extends AA {
foo() {}
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "typescript" });

View File

@ -0,0 +1,420 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`constructorDefaultValuesReferencingThis.ts 1`] = `
class C {
constructor(x = this) { }
}
class D<T> {
constructor(x = this) { }
}
class E<T> {
constructor(public x = this) { }
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
constructor(x = this) {}
}
class D<T> {
constructor(x = this) {}
}
class E<T> {
constructor(public x = this) {}
}
`;
exports[`constructorImplementationWithDefaultValues.ts 1`] = `
class C {
constructor(x);
constructor(x = 1) {
var y = x;
}
}
class D<T> {
constructor(x);
constructor(x:T = null) {
var y = x;
}
}
class E<T extends Date> {
constructor(x);
constructor(x: T = null) {
var y = x;
}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
constructor(x);
constructor(x = 1) {
var y = x;
}
}
class D<T> {
constructor(x);
constructor(x: T = null) {
var y = x;
}
}
class E<T extends Date> {
constructor(x);
constructor(x: T = null) {
var y = x;
}
}
`;
exports[`constructorImplementationWithDefaultValues2.ts 1`] = `
class C {
constructor(x);
constructor(public x: string = 1) {
var y = x;
}
}
class D<T, U> {
constructor(x: T, y: U);
constructor(x: T = 1, public y: U = x) {
var z = x;
}
}
class E<T extends Date> {
constructor(x);
constructor(x: T = new Date()) {
var y = x;
}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
constructor(x);
constructor(public x: string = 1) {
var y = x;
}
}
class D<T, U> {
constructor(x: T, y: U);
constructor(x: T = 1, public y: U = x) {
var z = x;
}
}
class E<T extends Date> {
constructor(x);
constructor(x: T = new Date()) {
var y = x;
}
}
`;
exports[`constructorOverloadsWithDefaultValues.ts 1`] = `
class C {
foo: string;
constructor(x = 1);
constructor() {
}
}
class D<T> {
foo: string;
constructor(x = 1);
constructor() {
}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
foo: string;
constructor(x = 1);
constructor() {}
}
class D<T> {
foo: string;
constructor(x = 1);
constructor() {}
}
`;
exports[`constructorOverloadsWithOptionalParameters.ts 1`] = `
class C {
foo: string;
constructor(x?, y?: any[]);
constructor() {
}
}
class D<T> {
foo: string;
constructor(x?, y?: any[]);
constructor() {
}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
foo: string;
constructor(x?, y?: any[]);
constructor() {}
}
class D<T> {
foo: string;
constructor(x?, y?: any[]);
constructor() {}
}
`;
exports[`constructorParameterProperties.ts 1`] = `
class C {
y: string;
constructor(private x: string, protected z: string) { }
}
var c: C;
var r = c.y;
var r2 = c.x; // error
var r3 = c.z; // error
class D<T> {
y: T;
constructor(a: T, private x: T, protected z: T) { }
}
var d: D<string>;
var r = d.y;
var r2 = d.x; // error
var r3 = d.a; // error
var r4 = d.z; // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
y: string;
constructor(private x: string, protected z: string) {}
}
var c: C;
var r = c.y;
var r2 = c.x; // error
var r3 = c.z; // error
class D<T> {
y: T;
constructor(a: T, private x: T, protected z: T) {}
}
var d: D<string>;
var r = d.y;
var r2 = d.x; // error
var r3 = d.a; // error
var r4 = d.z; // error
`;
exports[`constructorParameterProperties2.ts 1`] = `
class C {
y: number;
constructor(y: number) { } // ok
}
var c: C;
var r = c.y;
class D {
y: number;
constructor(public y: number) { }
}
var d: D;
var r2 = d.y;
class E {
y: number;
constructor(private y: number) { }
}
var e: E;
var r3 = e.y; // error
class F {
y: number;
constructor(protected y: number) { }
}
var f: F;
var r4 = f.y; // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
y: number;
constructor(y: number) {} // ok
}
var c: C;
var r = c.y;
class D {
y: number;
constructor(public y: number) {}
}
var d: D;
var r2 = d.y;
class E {
y: number;
constructor(private y: number) {}
}
var e: E;
var r3 = e.y; // error
class F {
y: number;
constructor(protected y: number) {}
}
var f: F;
var r4 = f.y; // error
`;
exports[`declarationEmitReadonly.ts 1`] = `
// @declaration: true
class C {
constructor(readonly x: number) {}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @declaration: true
class C {
constructor(readonly x: number) {}
}
`;
exports[`readonlyConstructorAssignment.ts 1`] = `
// Tests that readonly parameter properties behave like regular readonly properties
class A {
constructor(readonly x: number) {
this.x = 0;
}
}
class B extends A {
constructor(x: number) {
super(x);
// Fails, x is readonly
this.x = 1;
}
}
class C extends A {
// This is the usual behavior of readonly properties:
// if one is redeclared in a base class, then it can be assigned to.
constructor(readonly x: number) {
super(x);
this.x = 1;
}
}
class D {
constructor(private readonly x: number) {
this.x = 0;
}
}
// Fails, can't redeclare readonly property
class E extends D {
constructor(readonly x: number) {
super(x);
this.x = 1;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Tests that readonly parameter properties behave like regular readonly properties
class A {
constructor(readonly x: number) {
this.x = 0;
}
}
class B extends A {
constructor(x: number) {
super(x);
// Fails, x is readonly
this.x = 1;
}
}
class C extends A {
// This is the usual behavior of readonly properties:
// if one is redeclared in a base class, then it can be assigned to.
constructor(readonly x: number) {
super(x);
this.x = 1;
}
}
class D {
constructor(private readonly x: number) {
this.x = 0;
}
}
// Fails, can't redeclare readonly property
class E extends D {
constructor(readonly x: number) {
super(x);
this.x = 1;
}
}
`;
exports[`readonlyInConstructorParameters.ts 1`] = `
class C {
constructor(readonly x: number) {}
}
new C(1).x = 2;
class E {
constructor(readonly public x: number) {}
}
class F {
constructor(private readonly x: number) {}
}
new F(1).x;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
constructor(readonly x: number) {}
}
new C(1).x = 2;
class E {
constructor(public readonly x: number) {}
}
class F {
constructor(private readonly x: number) {}
}
new F(1).x;
`;
exports[`readonlyReadonly.ts 1`] = `
class C {
readonly readonly x: number;
constructor(readonly readonly y: number) {}
}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {
x: number;
constructor(readonly y: number) {}
}
`;

View File

@ -0,0 +1,11 @@
class C {
constructor(x = this) { }
}
class D<T> {
constructor(x = this) { }
}
class E<T> {
constructor(public x = this) { }
}

View File

@ -0,0 +1,20 @@
class C {
constructor(x);
constructor(x = 1) {
var y = x;
}
}
class D<T> {
constructor(x);
constructor(x:T = null) {
var y = x;
}
}
class E<T extends Date> {
constructor(x);
constructor(x: T = null) {
var y = x;
}
}

View File

@ -0,0 +1,20 @@
class C {
constructor(x);
constructor(public x: string = 1) {
var y = x;
}
}
class D<T, U> {
constructor(x: T, y: U);
constructor(x: T = 1, public y: U = x) {
var z = x;
}
}
class E<T extends Date> {
constructor(x);
constructor(x: T = new Date()) {
var y = x;
}
}

View File

@ -0,0 +1,13 @@
class C {
foo: string;
constructor(x = 1);
constructor() {
}
}
class D<T> {
foo: string;
constructor(x = 1);
constructor() {
}
}

View File

@ -0,0 +1,13 @@
class C {
foo: string;
constructor(x?, y?: any[]);
constructor() {
}
}
class D<T> {
foo: string;
constructor(x?, y?: any[]);
constructor() {
}
}

View File

@ -0,0 +1,20 @@
class C {
y: string;
constructor(private x: string, protected z: string) { }
}
var c: C;
var r = c.y;
var r2 = c.x; // error
var r3 = c.z; // error
class D<T> {
y: T;
constructor(a: T, private x: T, protected z: T) { }
}
var d: D<string>;
var r = d.y;
var r2 = d.x; // error
var r3 = d.a; // error
var r4 = d.z; // error

View File

@ -0,0 +1,31 @@
class C {
y: number;
constructor(y: number) { } // ok
}
var c: C;
var r = c.y;
class D {
y: number;
constructor(public y: number) { }
}
var d: D;
var r2 = d.y;
class E {
y: number;
constructor(private y: number) { }
}
var e: E;
var r3 = e.y; // error
class F {
y: number;
constructor(protected y: number) { }
}
var f: F;
var r4 = f.y; // error

View File

@ -0,0 +1,5 @@
// @declaration: true
class C {
constructor(readonly x: number) {}
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "typescript" });

View File

@ -0,0 +1,38 @@
// Tests that readonly parameter properties behave like regular readonly properties
class A {
constructor(readonly x: number) {
this.x = 0;
}
}
class B extends A {
constructor(x: number) {
super(x);
// Fails, x is readonly
this.x = 1;
}
}
class C extends A {
// This is the usual behavior of readonly properties:
// if one is redeclared in a base class, then it can be assigned to.
constructor(readonly x: number) {
super(x);
this.x = 1;
}
}
class D {
constructor(private readonly x: number) {
this.x = 0;
}
}
// Fails, can't redeclare readonly property
class E extends D {
constructor(readonly x: number) {
super(x);
this.x = 1;
}
}

View File

@ -0,0 +1,13 @@
class C {
constructor(readonly x: number) {}
}
new C(1).x = 2;
class E {
constructor(readonly public x: number) {}
}
class F {
constructor(private readonly x: number) {}
}
new F(1).x;

View File

@ -0,0 +1,4 @@
class C {
readonly readonly x: number;
constructor(readonly readonly y: number) {}
}

View File

@ -6,7 +6,7 @@ declare class MyArray<T> extends Array<T> {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class MyArray<T> extends Array {
sort(compareFn?: (a: T, b: T) => number): this
sort(compareFn?: (a: T, b: T) => number): this;
}
`;

View File

@ -0,0 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`abstractNewlineHandling.ts 1`] = `
var
abstract
class X {}
const
abstract
class Y {}
export let
abstract
class Y {}
let
abstract
export class Y {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var abstract;
class X {}
const abstract;
class Y {}
export let abstract;
class Y {}
let abstract;
export class Y {}
`;

View File

@ -0,0 +1,15 @@
var
abstract
class X {}
const
abstract
class Y {}
export let
abstract
class Y {}
let
abstract
export class Y {}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "typescript" });