Skip to content

Commit

Permalink
Fix 'accessor' crash for invalid modifier locations (microsoft#58963)
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuckton authored Jun 24, 2024
1 parent 3743fbc commit c76c418
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 3 deletions.
2 changes: 0 additions & 2 deletions src/compiler/transformers/classFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,6 @@ export function transformClassFields(context: TransformationContext): (x: Source
}

switch (node.kind) {
case SyntaxKind.AccessorKeyword:
return Debug.fail("Use `modifierVisitor` instead.");
case SyntaxKind.ClassDeclaration:
return visitClassDeclaration(node as ClassDeclaration);
case SyntaxKind.ClassExpression:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//// [tests/cases/conformance/classes/propertyMemberDeclarations/autoAccessorDisallowedModifiers.ts] ////

//// [autoAccessorDisallowedModifiers.ts]
abstract class C1 {
accessor accessor a: any;
readonly accessor b: any;
declare accessor c: any;
accessor public d: any;
accessor private e: any;
accessor protected f: any;
accessor abstract g: any;
accessor static h: any;
accessor i() {}
accessor get j() { return false; }
accessor set k(v: any) {}
accessor constructor() {}
accessor l?: any;
accessor readonly m: any;
accessor declare n: any;
}

class C2 extends C1 {
accessor override g: any;
}

interface I1 {
accessor a: number;
}

accessor class C3 {}
accessor interface I2 {}
accessor namespace N1 {}
accessor enum E1 {}
accessor var V1: any;
accessor type T1 = never;
accessor function F1() {}
accessor import "x";
accessor import {} from "x";
accessor export { V1 };
accessor export default V1;
accessor import N2 = N1;


//// [autoAccessorDisallowedModifiers.js]
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _a, _C1_a_accessor_storage, _C1_b_accessor_storage, _C1_d_accessor_storage, _C1_e_accessor_storage, _C1_f_accessor_storage, _C1_h_accessor_storage, _C1_l_accessor_storage, _C1_m_accessor_storage, _C2_g_accessor_storage;
class C1 {
get a() { return __classPrivateFieldGet(this, _C1_a_accessor_storage, "f"); }
set a(value) { __classPrivateFieldSet(this, _C1_a_accessor_storage, value, "f"); }
get b() { return __classPrivateFieldGet(this, _C1_b_accessor_storage, "f"); }
set b(value) { __classPrivateFieldSet(this, _C1_b_accessor_storage, value, "f"); }
get d() { return __classPrivateFieldGet(this, _C1_d_accessor_storage, "f"); }
set d(value) { __classPrivateFieldSet(this, _C1_d_accessor_storage, value, "f"); }
get e() { return __classPrivateFieldGet(this, _C1_e_accessor_storage, "f"); }
set e(value) { __classPrivateFieldSet(this, _C1_e_accessor_storage, value, "f"); }
get f() { return __classPrivateFieldGet(this, _C1_f_accessor_storage, "f"); }
set f(value) { __classPrivateFieldSet(this, _C1_f_accessor_storage, value, "f"); }
static get h() { return __classPrivateFieldGet(_a, _a, "f", _C1_h_accessor_storage); }
static set h(value) { __classPrivateFieldSet(_a, _a, value, "f", _C1_h_accessor_storage); }
i() { }
get j() { return false; }
set k(v) { }
constructor() {
_C1_a_accessor_storage.set(this, void 0);
_C1_b_accessor_storage.set(this, void 0);
_C1_d_accessor_storage.set(this, void 0);
_C1_e_accessor_storage.set(this, void 0);
_C1_f_accessor_storage.set(this, void 0);
_C1_l_accessor_storage.set(this, void 0);
_C1_m_accessor_storage.set(this, void 0);
}
get l() { return __classPrivateFieldGet(this, _C1_l_accessor_storage, "f"); }
set l(value) { __classPrivateFieldSet(this, _C1_l_accessor_storage, value, "f"); }
get m() { return __classPrivateFieldGet(this, _C1_m_accessor_storage, "f"); }
set m(value) { __classPrivateFieldSet(this, _C1_m_accessor_storage, value, "f"); }
}
_a = C1, _C1_a_accessor_storage = new WeakMap(), _C1_b_accessor_storage = new WeakMap(), _C1_d_accessor_storage = new WeakMap(), _C1_e_accessor_storage = new WeakMap(), _C1_f_accessor_storage = new WeakMap(), _C1_l_accessor_storage = new WeakMap(), _C1_m_accessor_storage = new WeakMap();
_C1_h_accessor_storage = { value: void 0 };
class C2 extends C1 {
constructor() {
super(...arguments);
_C2_g_accessor_storage.set(this, void 0);
}
get g() { return __classPrivateFieldGet(this, _C2_g_accessor_storage, "f"); }
set g(value) { __classPrivateFieldSet(this, _C2_g_accessor_storage, value, "f"); }
}
_C2_g_accessor_storage = new WeakMap();
class C3 {
}
accessor var E1;
(function (E1) {
})(E1 || (E1 = {}));
accessor var V1;
accessor function F1() { }
accessor import "x";
export { V1 };
export default V1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
autoAccessorDisallowedModifiers.ts(2,14): error TS1030: 'accessor' modifier already seen.
autoAccessorDisallowedModifiers.ts(3,14): error TS1243: 'accessor' modifier cannot be used with 'readonly' modifier.
autoAccessorDisallowedModifiers.ts(4,13): error TS1243: 'accessor' modifier cannot be used with 'declare' modifier.
autoAccessorDisallowedModifiers.ts(5,14): error TS1029: 'public' modifier must precede 'accessor' modifier.
autoAccessorDisallowedModifiers.ts(6,14): error TS1029: 'private' modifier must precede 'accessor' modifier.
autoAccessorDisallowedModifiers.ts(7,14): error TS1029: 'protected' modifier must precede 'accessor' modifier.
autoAccessorDisallowedModifiers.ts(8,14): error TS1029: 'abstract' modifier must precede 'accessor' modifier.
autoAccessorDisallowedModifiers.ts(9,14): error TS1029: 'static' modifier must precede 'accessor' modifier.
autoAccessorDisallowedModifiers.ts(10,5): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(11,5): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(12,5): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(13,5): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(14,15): error TS1276: An 'accessor' property cannot be declared optional.
autoAccessorDisallowedModifiers.ts(15,14): error TS1243: 'readonly' modifier cannot be used with 'accessor' modifier.
autoAccessorDisallowedModifiers.ts(16,14): error TS1243: 'declare' modifier cannot be used with 'accessor' modifier.
autoAccessorDisallowedModifiers.ts(20,14): error TS1029: 'override' modifier must precede 'accessor' modifier.
autoAccessorDisallowedModifiers.ts(24,5): error TS1070: 'accessor' modifier cannot appear on a type member.
autoAccessorDisallowedModifiers.ts(27,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(28,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(29,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(30,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(31,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(32,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(33,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(34,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(35,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(35,25): error TS2792: Cannot find module 'x'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
autoAccessorDisallowedModifiers.ts(36,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(37,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
autoAccessorDisallowedModifiers.ts(38,1): error TS1275: 'accessor' modifier can only appear on a property declaration.


==== autoAccessorDisallowedModifiers.ts (30 errors) ====
abstract class C1 {
accessor accessor a: any;
~~~~~~~~
!!! error TS1030: 'accessor' modifier already seen.
readonly accessor b: any;
~~~~~~~~
!!! error TS1243: 'accessor' modifier cannot be used with 'readonly' modifier.
declare accessor c: any;
~~~~~~~~
!!! error TS1243: 'accessor' modifier cannot be used with 'declare' modifier.
accessor public d: any;
~~~~~~
!!! error TS1029: 'public' modifier must precede 'accessor' modifier.
accessor private e: any;
~~~~~~~
!!! error TS1029: 'private' modifier must precede 'accessor' modifier.
accessor protected f: any;
~~~~~~~~~
!!! error TS1029: 'protected' modifier must precede 'accessor' modifier.
accessor abstract g: any;
~~~~~~~~
!!! error TS1029: 'abstract' modifier must precede 'accessor' modifier.
accessor static h: any;
~~~~~~
!!! error TS1029: 'static' modifier must precede 'accessor' modifier.
accessor i() {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor get j() { return false; }
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor set k(v: any) {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor constructor() {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor l?: any;
~
!!! error TS1276: An 'accessor' property cannot be declared optional.
accessor readonly m: any;
~~~~~~~~
!!! error TS1243: 'readonly' modifier cannot be used with 'accessor' modifier.
accessor declare n: any;
~~~~~~~
!!! error TS1243: 'declare' modifier cannot be used with 'accessor' modifier.
}

class C2 extends C1 {
accessor override g: any;
~~~~~~~~
!!! error TS1029: 'override' modifier must precede 'accessor' modifier.
}

interface I1 {
accessor a: number;
~~~~~~~~
!!! error TS1070: 'accessor' modifier cannot appear on a type member.
}

accessor class C3 {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor interface I2 {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor namespace N1 {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor enum E1 {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor var V1: any;
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor type T1 = never;
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor function F1() {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor import "x";
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor import {} from "x";
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
~~~
!!! error TS2792: Cannot find module 'x'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
accessor export { V1 };
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor export default V1;
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor import N2 = N1;
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// @target: esnext
// @target: esnext,es2017
// @noTypesAndSymbols: true

abstract class C1 {
Expand Down

0 comments on commit c76c418

Please sign in to comment.