@@ -24,51 +24,16 @@ export type Options = [Config];
24
24
export type MessageIds = 'unbound' | 'unboundWithoutThisAnnotation' ;
25
25
26
26
/**
27
- * The following is a list of exceptions to the rule
28
- * Generated via the following script.
29
- * This is statically defined to save making purposely invalid calls every lint run
30
- * ```
31
- SUPPORTED_GLOBALS.flatMap(namespace => {
32
- const object = window[namespace];
33
- return Object.getOwnPropertyNames(object)
34
- .filter(
35
- name =>
36
- !name.startsWith('_') &&
37
- typeof object[name] === 'function',
38
- )
39
- .map(name => {
40
- try {
41
- const x = object[name];
42
- x();
43
- } catch (e) {
44
- if (e.message.includes("called on non-object")) {
45
- return `${namespace}.${name}`;
46
- }
47
- }
48
- });
49
- }).filter(Boolean);
50
- * ```
27
+ * Static methods on these globals are either not `this`-aware or supported being
28
+ * called without `this`.
29
+ *
30
+ * - `Promise` is not in the list because it supports subclassing by using `this`
31
+ * - `Array` is in the list because although it supports subclassing, the `this`
32
+ * value defaults to `Array` when unbound
33
+ *
34
+ * This is now a language-design invariant: static methods are never `this`-aware
35
+ * because TC39 wants to make `array.map(Class.method)` work!
51
36
*/
52
- const nativelyNotBoundMembers = new Set ( [
53
- 'Promise.all' ,
54
- 'Promise.race' ,
55
- 'Promise.resolve' ,
56
- 'Promise.reject' ,
57
- 'Promise.allSettled' ,
58
- 'Object.defineProperties' ,
59
- 'Object.defineProperty' ,
60
- 'Reflect.defineProperty' ,
61
- 'Reflect.deleteProperty' ,
62
- 'Reflect.get' ,
63
- 'Reflect.getOwnPropertyDescriptor' ,
64
- 'Reflect.getPrototypeOf' ,
65
- 'Reflect.has' ,
66
- 'Reflect.isExtensible' ,
67
- 'Reflect.ownKeys' ,
68
- 'Reflect.preventExtensions' ,
69
- 'Reflect.set' ,
70
- 'Reflect.setPrototypeOf' ,
71
- ] ) ;
72
37
const SUPPORTED_GLOBALS = [
73
38
'Number' ,
74
39
'Object' ,
@@ -78,31 +43,30 @@ const SUPPORTED_GLOBALS = [
78
43
'Array' ,
79
44
'Proxy' ,
80
45
'Date' ,
81
- 'Infinity' ,
82
46
'Atomics' ,
83
47
'Reflect' ,
84
48
'console' ,
85
49
'Math' ,
86
50
'JSON' ,
87
51
'Intl' ,
88
52
] as const ;
89
- const nativelyBoundMembers = SUPPORTED_GLOBALS . map ( namespace => {
90
- if ( ! ( namespace in global ) ) {
91
- // node.js might not have namespaces like Intl depending on compilation options
92
- // https://nodejs.org/api/intl.html#intl_options_for_building_node_js
93
- return [ ] ;
94
- }
95
- const object = global [ namespace ] ;
96
- return Object . getOwnPropertyNames ( object )
97
- . filter (
98
- name =>
99
- ! name . startsWith ( '_' ) &&
100
- typeof ( object as Record < string , unknown > ) [ name ] === 'function' ,
101
- )
102
- . map ( name => ` ${ namespace } . ${ name } ` ) ;
103
- } )
104
- . reduce ( ( arr , names ) => arr . concat ( names ) , [ ] )
105
- . filter ( name => ! nativelyNotBoundMembers . has ( name ) ) ;
53
+ const nativelyBoundMembers = new Set (
54
+ SUPPORTED_GLOBALS . flatMap ( namespace => {
55
+ if ( ! ( namespace in global ) ) {
56
+ // node.js might not have namespaces like Intl depending on compilation options
57
+ // https://nodejs.org/api/intl.html#intl_options_for_building_node_js
58
+ return [ ] ;
59
+ }
60
+ const object = global [ namespace ] ;
61
+ return Object . getOwnPropertyNames ( object )
62
+ . filter (
63
+ name =>
64
+ ! name . startsWith ( '_' ) &&
65
+ typeof ( object as Record < string , unknown > ) [ name ] === 'function' ,
66
+ )
67
+ . map ( name => ` ${ namespace } . ${ name } ` ) ;
68
+ } ) ,
69
+ ) ;
106
70
107
71
const isNotImported = (
108
72
symbol : ts . Symbol ,
@@ -201,7 +165,7 @@ export default createRule<Options, MessageIds>({
201
165
202
166
if (
203
167
objectSymbol &&
204
- nativelyBoundMembers . includes ( getMemberFullName ( node ) ) &&
168
+ nativelyBoundMembers . has ( getMemberFullName ( node ) ) &&
205
169
isNotImported ( objectSymbol , currentSourceFile )
206
170
) {
207
171
return ;
@@ -232,7 +196,7 @@ export default createRule<Options, MessageIds>({
232
196
if (
233
197
notImported &&
234
198
isIdentifier ( initNode ) &&
235
- nativelyBoundMembers . includes (
199
+ nativelyBoundMembers . has (
236
200
`${ initNode . name } .${ property . key . name } ` ,
237
201
)
238
202
) {
0 commit comments