Skip to content

Commit 45b698b

Browse files
authored
fix(40632): skip emitting abstract members (#40699)
1 parent 76cf8fd commit 45b698b

11 files changed

+240
-13
lines changed

src/compiler/transformers/classFields.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ namespace ts {
579579
}
580580

581581
function isPropertyDeclarationThatRequiresConstructorStatement(member: ClassElement): member is PropertyDeclaration {
582-
if (!isPropertyDeclaration(member) || hasStaticModifier(member)) {
582+
if (!isPropertyDeclaration(member) || hasStaticModifier(member) || hasSyntacticModifier(getOriginalNode(member), ModifierFlags.Abstract)) {
583583
return false;
584584
}
585585
if (context.getCompilerOptions().useDefineForClassFields) {
@@ -779,6 +779,9 @@ namespace ts {
779779
}
780780

781781
const propertyOriginalNode = getOriginalNode(property);
782+
if (hasSyntacticModifier(propertyOriginalNode, ModifierFlags.Abstract)) {
783+
return undefined;
784+
}
782785
const initializer = property.initializer || emitAssignment ? visitNode(property.initializer, visitor, isExpression) ?? factory.createVoidZero()
783786
: isParameterPropertyDeclaration(propertyOriginalNode, propertyOriginalNode.parent) && isIdentifier(propertyName) ? propertyName
784787
: factory.createVoidZero();

src/compiler/transformers/ts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1900,7 +1900,7 @@ namespace ts {
19001900
}
19011901

19021902
function visitPropertyDeclaration(node: PropertyDeclaration) {
1903-
if (node.flags & NodeFlags.Ambient) {
1903+
if (node.flags & NodeFlags.Ambient || hasSyntacticModifier(node, ModifierFlags.Abstract)) {
19041904
return undefined;
19051905
}
19061906
const updated = factory.updatePropertyDeclaration(
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//// [abstractProperty.ts]
2+
abstract class A {
3+
protected abstract x: string;
4+
public foo() {
5+
console.log(this.x);
6+
}
7+
}
8+
9+
class B extends A {
10+
protected x = 'B.x';
11+
}
12+
13+
class C extends A {
14+
protected get x() { return 'C.x' };
15+
}
16+
17+
18+
//// [abstractProperty.js]
19+
class A {
20+
foo() {
21+
console.log(this.x);
22+
}
23+
}
24+
class B extends A {
25+
constructor() {
26+
super(...arguments);
27+
Object.defineProperty(this, "x", {
28+
enumerable: true,
29+
configurable: true,
30+
writable: true,
31+
value: 'B.x'
32+
});
33+
}
34+
}
35+
class C extends A {
36+
get x() { return 'C.x'; }
37+
;
38+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/conformance/classes/propertyMemberDeclarations/abstractProperty.ts ===
2+
abstract class A {
3+
>A : Symbol(A, Decl(abstractProperty.ts, 0, 0))
4+
5+
protected abstract x: string;
6+
>x : Symbol(A.x, Decl(abstractProperty.ts, 0, 18))
7+
8+
public foo() {
9+
>foo : Symbol(A.foo, Decl(abstractProperty.ts, 1, 33))
10+
11+
console.log(this.x);
12+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
13+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
14+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
15+
>this.x : Symbol(A.x, Decl(abstractProperty.ts, 0, 18))
16+
>this : Symbol(A, Decl(abstractProperty.ts, 0, 0))
17+
>x : Symbol(A.x, Decl(abstractProperty.ts, 0, 18))
18+
}
19+
}
20+
21+
class B extends A {
22+
>B : Symbol(B, Decl(abstractProperty.ts, 5, 1))
23+
>A : Symbol(A, Decl(abstractProperty.ts, 0, 0))
24+
25+
protected x = 'B.x';
26+
>x : Symbol(B.x, Decl(abstractProperty.ts, 7, 19))
27+
}
28+
29+
class C extends A {
30+
>C : Symbol(C, Decl(abstractProperty.ts, 9, 1))
31+
>A : Symbol(A, Decl(abstractProperty.ts, 0, 0))
32+
33+
protected get x() { return 'C.x' };
34+
>x : Symbol(C.x, Decl(abstractProperty.ts, 11, 19))
35+
}
36+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
=== tests/cases/conformance/classes/propertyMemberDeclarations/abstractProperty.ts ===
2+
abstract class A {
3+
>A : A
4+
5+
protected abstract x: string;
6+
>x : string
7+
8+
public foo() {
9+
>foo : () => void
10+
11+
console.log(this.x);
12+
>console.log(this.x) : void
13+
>console.log : (...data: any[]) => void
14+
>console : Console
15+
>log : (...data: any[]) => void
16+
>this.x : string
17+
>this : this
18+
>x : string
19+
}
20+
}
21+
22+
class B extends A {
23+
>B : B
24+
>A : A
25+
26+
protected x = 'B.x';
27+
>x : string
28+
>'B.x' : "B.x"
29+
}
30+
31+
class C extends A {
32+
>C : C
33+
>A : A
34+
35+
protected get x() { return 'C.x' };
36+
>x : string
37+
>'C.x' : "C.x"
38+
}
39+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [abstractProperty.ts]
2+
abstract class A {
3+
protected abstract x: string;
4+
public foo() {
5+
console.log(this.x);
6+
}
7+
}
8+
9+
class B extends A {
10+
protected x = 'B.x';
11+
}
12+
13+
class C extends A {
14+
protected get x() { return 'C.x' };
15+
}
16+
17+
18+
//// [abstractProperty.js]
19+
class A {
20+
foo() {
21+
console.log(this.x);
22+
}
23+
}
24+
class B extends A {
25+
x = 'B.x';
26+
}
27+
class C extends A {
28+
get x() { return 'C.x'; }
29+
;
30+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/conformance/classes/propertyMemberDeclarations/abstractProperty.ts ===
2+
abstract class A {
3+
>A : Symbol(A, Decl(abstractProperty.ts, 0, 0))
4+
5+
protected abstract x: string;
6+
>x : Symbol(A.x, Decl(abstractProperty.ts, 0, 18))
7+
8+
public foo() {
9+
>foo : Symbol(A.foo, Decl(abstractProperty.ts, 1, 33))
10+
11+
console.log(this.x);
12+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
13+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
14+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
15+
>this.x : Symbol(A.x, Decl(abstractProperty.ts, 0, 18))
16+
>this : Symbol(A, Decl(abstractProperty.ts, 0, 0))
17+
>x : Symbol(A.x, Decl(abstractProperty.ts, 0, 18))
18+
}
19+
}
20+
21+
class B extends A {
22+
>B : Symbol(B, Decl(abstractProperty.ts, 5, 1))
23+
>A : Symbol(A, Decl(abstractProperty.ts, 0, 0))
24+
25+
protected x = 'B.x';
26+
>x : Symbol(B.x, Decl(abstractProperty.ts, 7, 19))
27+
}
28+
29+
class C extends A {
30+
>C : Symbol(C, Decl(abstractProperty.ts, 9, 1))
31+
>A : Symbol(A, Decl(abstractProperty.ts, 0, 0))
32+
33+
protected get x() { return 'C.x' };
34+
>x : Symbol(C.x, Decl(abstractProperty.ts, 11, 19))
35+
}
36+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
=== tests/cases/conformance/classes/propertyMemberDeclarations/abstractProperty.ts ===
2+
abstract class A {
3+
>A : A
4+
5+
protected abstract x: string;
6+
>x : string
7+
8+
public foo() {
9+
>foo : () => void
10+
11+
console.log(this.x);
12+
>console.log(this.x) : void
13+
>console.log : (...data: any[]) => void
14+
>console : Console
15+
>log : (...data: any[]) => void
16+
>this.x : string
17+
>this : this
18+
>x : string
19+
}
20+
}
21+
22+
class B extends A {
23+
>B : B
24+
>A : A
25+
26+
protected x = 'B.x';
27+
>x : string
28+
>'B.x' : "B.x"
29+
}
30+
31+
class C extends A {
32+
>C : C
33+
>A : A
34+
35+
protected get x() { return 'C.x' };
36+
>x : string
37+
>'C.x' : "C.x"
38+
}
39+

tests/baselines/reference/accessorsOverrideProperty7.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@ var __extends = (this && this.__extends) || (function () {
2323
})();
2424
var A = /** @class */ (function () {
2525
function A() {
26-
Object.defineProperty(this, "p", {
27-
enumerable: true,
28-
configurable: true,
29-
writable: true,
30-
value: 'yep'
31-
});
3226
}
3327
return A;
3428
}());

tests/baselines/reference/privateNamesIncompatibleModifiers.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ abstract class B {
1414

1515
//// [privateNamesIncompatibleModifiers.js]
1616
"use strict";
17-
var _foo, _bar, _baz, _qux, _quux;
17+
var _foo, _bar, _baz, _qux;
1818
class A {
1919
constructor() {
2020
_foo.set(this, 3); // Error
@@ -25,8 +25,4 @@ class A {
2525
}
2626
_foo = new WeakMap(), _bar = new WeakMap(), _baz = new WeakMap(), _qux = new WeakMap();
2727
class B {
28-
constructor() {
29-
_quux.set(this, 3); // Error
30-
}
3128
}
32-
_quux = new WeakMap();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @target: es2015,esnext
2+
// @useDefineForClassFields: true
3+
abstract class A {
4+
protected abstract x: string;
5+
public foo() {
6+
console.log(this.x);
7+
}
8+
}
9+
10+
class B extends A {
11+
protected x = 'B.x';
12+
}
13+
14+
class C extends A {
15+
protected get x() { return 'C.x' };
16+
}

0 commit comments

Comments
 (0)