Skip to content

Commit 4715787

Browse files
authored
feat: check Object.create() in getter-return (#16420)
Fixes: #16419
1 parent e917a9a commit 4715787

2 files changed

Lines changed: 96 additions & 9 deletions

File tree

lib/rules/getter-return.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,24 @@ module.exports = {
112112
}
113113
if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") {
114114

115-
// Object.defineProperty()
116-
if (parent.parent.parent.type === "CallExpression" &&
117-
astUtils.getStaticPropertyName(parent.parent.parent.callee) === "defineProperty") {
118-
return true;
115+
// Object.defineProperty() or Reflect.defineProperty()
116+
if (parent.parent.parent.type === "CallExpression") {
117+
const callNode = parent.parent.parent.callee;
118+
119+
if (astUtils.isSpecificMemberAccess(callNode, "Object", "defineProperty") ||
120+
astUtils.isSpecificMemberAccess(callNode, "Reflect", "defineProperty")) {
121+
return true;
122+
}
119123
}
120124

121-
// Object.defineProperties()
125+
// Object.defineProperties() or Object.create()
122126
if (parent.parent.parent.type === "Property" &&
123127
parent.parent.parent.parent.type === "ObjectExpression" &&
124-
parent.parent.parent.parent.parent.type === "CallExpression" &&
125-
astUtils.getStaticPropertyName(parent.parent.parent.parent.parent.callee) === "defineProperties") {
126-
return true;
128+
parent.parent.parent.parent.parent.type === "CallExpression") {
129+
const callNode = parent.parent.parent.parent.parent.callee;
130+
131+
return astUtils.isSpecificMemberAccess(callNode, "Object", "defineProperties") ||
132+
astUtils.isSpecificMemberAccess(callNode, "Object", "create");
127133
}
128134
}
129135
}

tests/lib/rules/getter-return.js

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,27 @@ ruleTester.run("getter-return", rule, {
5757
"Object.defineProperties(foo, { bar: { get: function () {return true;}} });",
5858
"Object.defineProperties(foo, { bar: { get: function () { ~function (){ return true; }(); return true;}} });",
5959

60+
/*
61+
* test reflect.defineProperty(s)
62+
* option: {allowImplicit: false}
63+
*/
64+
"Reflect.defineProperty(foo, \"bar\", { get: function () {return true;}});",
65+
"Reflect.defineProperty(foo, \"bar\", { get: function () { ~function (){ return true; }();return true;}});",
66+
67+
/*
68+
* test object.create(s)
69+
* option: {allowImplicit: false}
70+
*/
71+
"Object.create(foo, { bar: { get() {return true;} } });",
72+
"Object.create(foo, { bar: { get: function () {return true;} } });",
73+
"Object.create(foo, { bar: { get: () => {return true;} } });",
74+
6075
// option: {allowImplicit: true}
6176
{ code: "Object.defineProperty(foo, \"bar\", { get: function () {return true;}});", options },
6277
{ code: "Object.defineProperty(foo, \"bar\", { get: function (){return;}});", options },
6378
{ code: "Object.defineProperties(foo, { bar: { get: function () {return true;}} });", options },
6479
{ code: "Object.defineProperties(foo, { bar: { get: function () {return;}} });", options },
80+
{ code: "Reflect.defineProperty(foo, \"bar\", { get: function () {return true;}});", options },
6581

6682
// not getter.
6783
"var get = function(){};",
@@ -73,7 +89,10 @@ ruleTester.run("getter-return", rule, {
7389
"var foo = { bar: function(){return true;} };",
7490
"var foo = { get: function () {} }",
7591
"var foo = { get: () => {}};",
76-
"class C { get; foo() {} }"
92+
"class C { get; foo() {} }",
93+
"foo.defineProperty(null, { get() {} });",
94+
"foo.defineProperties(null, { bar: { get() {} } });",
95+
"foo.create(null, { bar: { get() {} } });"
7796
],
7897

7998
invalid: [
@@ -220,11 +239,67 @@ ruleTester.run("getter-return", rule, {
220239
{ code: "Object.defineProperty(foo, \"bar\", { get: function (){if(bar) {return true;}}});", errors: [{ messageId: "expectedAlways" }] },
221240
{ code: "Object.defineProperty(foo, \"bar\", { get: function (){ ~function () { return true; }()}});", errors: [{ messageId: "expected" }] },
222241

242+
/*
243+
* test reflect.defineProperty(s)
244+
* option: {allowImplicit: false}
245+
*/
246+
{
247+
code: "Reflect.defineProperty(foo, 'bar', { get: function (){}});",
248+
errors: [{
249+
messageId: "expected",
250+
data: { name: "method 'get'" },
251+
line: 1,
252+
column: 38,
253+
endLine: 1,
254+
endColumn: 52
255+
}]
256+
},
257+
258+
/*
259+
* test object.create(s)
260+
* option: {allowImplicit: false}
261+
*/
262+
{
263+
code: "Object.create(foo, { bar: { get: function() {} } })",
264+
errors: [{
265+
messageId: "expected",
266+
data: { name: "method 'get'" },
267+
line: 1,
268+
column: 29,
269+
endLine: 1,
270+
endColumn: 42
271+
}]
272+
},
273+
{
274+
code: "Object.create(foo, { bar: { get() {} } })",
275+
errors: [{
276+
messageId: "expected",
277+
data: { name: "method 'get'" },
278+
line: 1,
279+
column: 29,
280+
endLine: 1,
281+
endColumn: 32
282+
}]
283+
},
284+
{
285+
code: "Object.create(foo, { bar: { get: () => {} } })",
286+
errors: [{
287+
messageId: "expected",
288+
data: { name: "method 'get'" },
289+
line: 1,
290+
column: 29,
291+
endLine: 1,
292+
endColumn: 34
293+
}]
294+
},
295+
223296
// option: {allowImplicit: true}
224297
{ code: "Object.defineProperties(foo, { bar: { get: function () {}} });", options, errors: [{ messageId: "expected" }] },
225298
{ code: "Object.defineProperties(foo, { bar: { get: function (){if(bar) {return true;}}}});", options, errors: [{ messageId: "expectedAlways" }] },
226299
{ code: "Object.defineProperties(foo, { bar: { get: function () {~function () { return true; }()}} });", options, errors: [{ messageId: "expected" }] },
227300
{ code: "Object.defineProperty(foo, \"bar\", { get: function (){}});", options, errors: [{ messageId: "expected" }] },
301+
{ code: "Object.create(foo, { bar: { get: function (){} } });", options, errors: [{ messageId: "expected" }] },
302+
{ code: "Reflect.defineProperty(foo, \"bar\", { get: function (){}});", options, errors: [{ messageId: "expected" }] },
228303

229304
// Optional chaining
230305
{
@@ -248,6 +323,12 @@ ruleTester.run("getter-return", rule, {
248323
options,
249324
parserOptions: { ecmaVersion: 2020 },
250325
errors: [{ messageId: "expected", data: { name: "method 'get'" } }]
326+
},
327+
{
328+
code: "(Object?.create)(foo, { bar: { get: function (){} } });",
329+
options,
330+
parserOptions: { ecmaVersion: 2020 },
331+
errors: [{ messageId: "expected", data: { name: "method 'get'" } }]
251332
}
252333
]
253334
});

0 commit comments

Comments
 (0)