eslint-plugin-stratified-design 0.12.9 → 0.12.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -17,6 +17,7 @@ const { fromCwd, match, or } = require("../helpers/common");
|
|
|
17
17
|
* @typedef {import('eslint').AST.Token} Token
|
|
18
18
|
* @typedef {import('eslint').SourceCode} SourceCode
|
|
19
19
|
* @typedef {({[name: string]: number})} Levels
|
|
20
|
+
* @typedef {({[name: string]: boolean})} DataNames
|
|
20
21
|
*/
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -35,7 +36,12 @@ const deriveDeclaration = (nodeOrToken) => {
|
|
|
35
36
|
);
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
/**
|
|
40
|
+
* @param {any} declarationInit
|
|
41
|
+
* @param {DataNames} dataNames
|
|
42
|
+
* @returns {boolean}
|
|
43
|
+
*/
|
|
44
|
+
const isData = (declarationInit, dataNames) => {
|
|
39
45
|
const expression = or(
|
|
40
46
|
() => declarationInit.expression,
|
|
41
47
|
() => declarationInit
|
|
@@ -46,39 +52,45 @@ const isDataOrImported = (declarationInit, levels) => {
|
|
|
46
52
|
if (type === "Literal") return true;
|
|
47
53
|
if (type === "Identifier") {
|
|
48
54
|
const name = or(() => expression.name);
|
|
49
|
-
return name &&
|
|
55
|
+
return name && dataNames[name];
|
|
50
56
|
}
|
|
51
57
|
if (type === "MemberExpression") {
|
|
52
58
|
const name = or(() => expression.object.name);
|
|
53
|
-
return name &&
|
|
59
|
+
return name && dataNames[name];
|
|
54
60
|
}
|
|
55
61
|
if (type === "CallExpression") {
|
|
56
62
|
const name = or(() => expression.callee.name);
|
|
57
|
-
return name &&
|
|
63
|
+
return name && dataNames[name];
|
|
58
64
|
}
|
|
59
65
|
if (type === "JSXElement") {
|
|
60
66
|
const name = or(() => expression.openingElement.name.name);
|
|
61
|
-
return name &&
|
|
67
|
+
return name && dataNames[name];
|
|
62
68
|
}
|
|
63
|
-
if (type === "SpreadElement")
|
|
64
|
-
return isDataOrImported(expression.argument, levels);
|
|
69
|
+
if (type === "SpreadElement") return isData(expression.argument, dataNames);
|
|
65
70
|
if (type === "ArrayExpression")
|
|
66
|
-
return expression.elements.every((init) =>
|
|
71
|
+
return expression.elements.every((init) => isData(init, dataNames));
|
|
67
72
|
if (type === "ObjectExpression")
|
|
68
|
-
return expression.properties.every(({ value }) =>
|
|
69
|
-
isDataOrImported(value, levels)
|
|
70
|
-
);
|
|
73
|
+
return expression.properties.every(({ value }) => isData(value, dataNames));
|
|
71
74
|
return false;
|
|
72
75
|
};
|
|
73
76
|
|
|
77
|
+
/**
|
|
78
|
+
* @param {Node | Token} nodeOrToken
|
|
79
|
+
* @param {DataNames} dataNames
|
|
80
|
+
* @returns {boolean}
|
|
81
|
+
*/
|
|
82
|
+
const isNodeData = (nodeOrToken, dataNames) => {
|
|
83
|
+
const declaration = deriveDeclaration(nodeOrToken);
|
|
84
|
+
return isData(declaration.init, dataNames);
|
|
85
|
+
};
|
|
86
|
+
|
|
74
87
|
/**
|
|
75
88
|
* @param {Node | Token} nodeOrToken
|
|
76
89
|
* @param {Levels} levels
|
|
77
90
|
* @returns {string[] | undefined}
|
|
78
91
|
*/
|
|
79
|
-
const deriveNames = (nodeOrToken
|
|
92
|
+
const deriveNames = (nodeOrToken) => {
|
|
80
93
|
const declaration = deriveDeclaration(nodeOrToken);
|
|
81
|
-
if (isDataOrImported(declaration.init, levels)) return [];
|
|
82
94
|
const names = or(
|
|
83
95
|
() => declaration.id.name,
|
|
84
96
|
() => declaration.id.elements.map(({ name }) => name),
|
|
@@ -97,12 +109,37 @@ const deriveCallerName = (nodeOrToken) =>
|
|
|
97
109
|
/**
|
|
98
110
|
* @param {SourceCode} sourceCode
|
|
99
111
|
* @param {Node | Token} nodeOrToken
|
|
100
|
-
* @returns {
|
|
112
|
+
* @returns {boolean}
|
|
113
|
+
*/
|
|
114
|
+
const hasDataComment = (sourceCode, nodeOrToken) => {
|
|
115
|
+
const comments = sourceCode.getCommentsBefore(nodeOrToken);
|
|
116
|
+
for (const { value: comment } of comments) {
|
|
117
|
+
if (comment.includes("@data")) return true;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {SourceCode} sourceCode
|
|
124
|
+
* @param {Node | Token} nodeOrToken
|
|
125
|
+
* @returns {boolean}
|
|
126
|
+
*/
|
|
127
|
+
const hasImportComment = (sourceCode, nodeOrToken) => {
|
|
128
|
+
const comments = sourceCode.getCommentsBefore(nodeOrToken);
|
|
129
|
+
for (const { value: comment } of comments) {
|
|
130
|
+
if (comment.includes("@import")) return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @param {SourceCode} sourceCode
|
|
137
|
+
* @param {Node | Token} nodeOrToken
|
|
138
|
+
* @returns {number}
|
|
101
139
|
*/
|
|
102
140
|
const deriveLevel = (sourceCode, nodeOrToken) => {
|
|
103
141
|
const comments = sourceCode.getCommentsBefore(nodeOrToken);
|
|
104
142
|
for (const { value: comment } of comments) {
|
|
105
|
-
if (comment.includes("@data") || comment.includes("@import")) return null;
|
|
106
143
|
const levelInStr = comment.replace(/^[^]*@level\s+?([0-9]+)[^0-9]*$/, "$1");
|
|
107
144
|
const levelInNum = Number(levelInStr);
|
|
108
145
|
if (levelInStr && !Number.isNaN(levelInNum)) {
|
|
@@ -208,6 +245,12 @@ module.exports = {
|
|
|
208
245
|
*/
|
|
209
246
|
const levels = {};
|
|
210
247
|
|
|
248
|
+
/**
|
|
249
|
+
* 선언된 것이 데이터인지 여부를 나타내는 객체.
|
|
250
|
+
* @type {DataNames}
|
|
251
|
+
*/
|
|
252
|
+
const dataNames = {};
|
|
253
|
+
|
|
211
254
|
const sourceCode = context.sourceCode;
|
|
212
255
|
|
|
213
256
|
/**
|
|
@@ -228,9 +271,17 @@ module.exports = {
|
|
|
228
271
|
return {
|
|
229
272
|
Program(node) {
|
|
230
273
|
node.body.forEach((token) => {
|
|
231
|
-
deriveNames(token
|
|
274
|
+
deriveNames(token).forEach((name) => {
|
|
275
|
+
if (!name || hasImportComment(sourceCode, token)) return;
|
|
276
|
+
if (
|
|
277
|
+
hasDataComment(sourceCode, token) ||
|
|
278
|
+
isNodeData(token, dataNames)
|
|
279
|
+
) {
|
|
280
|
+
dataNames[name] = true;
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
232
283
|
const level = deriveLevel(sourceCode, token);
|
|
233
|
-
|
|
284
|
+
levels[name] = level;
|
|
234
285
|
});
|
|
235
286
|
});
|
|
236
287
|
},
|
package/package.json
CHANGED
|
@@ -268,35 +268,7 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
268
268
|
filename: "./src/foo.js",
|
|
269
269
|
},
|
|
270
270
|
{
|
|
271
|
-
code: "import { lib } from 'lib'; const { fn2 } = lib; const fn1 = () => fn2()",
|
|
272
|
-
filename: "./src/foo.js",
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
code: "import { lib } from 'lib'; const fn2 = lib.fn2; const fn1 = () => fn2()",
|
|
276
|
-
filename: "./src/foo.js",
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
code: "import { fn2 } from 'lib'; const arr = [fn2]; const fn1 = () => arr[0]()",
|
|
280
|
-
filename: "./src/foo.js",
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
code: "import { fn2 } from 'lib'; const arr = [fn2()]; const fn1 = () => arr.push(1)",
|
|
284
|
-
filename: "./src/foo.js",
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
code: "import { fn2 } from 'lib'; const data = [...fn2()]; const fn1 = () => data.push(1)",
|
|
288
|
-
filename: "./src/foo.js",
|
|
289
|
-
},
|
|
290
|
-
{
|
|
291
|
-
code: "import { fn2 } from 'lib'; const arr = [fn2]; const fn1 = () => arr.push(1)",
|
|
292
|
-
filename: "./src/foo.js",
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
code: "import { Comp2 } from 'lib'; const arr = [<Comp2 />]; const fn1 = () => arr.push(1)",
|
|
296
|
-
filename: "./src/foo.js",
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
code: "import { Comp2 } from 'lib'; const arr = [Comp2]; const fn1 = () => arr.push(1)",
|
|
271
|
+
code: "import { lib } from 'lib'; /*@import*/const { fn2 } = lib; const fn1 = () => fn2()",
|
|
300
272
|
filename: "./src/foo.js",
|
|
301
273
|
},
|
|
302
274
|
],
|
|
@@ -483,5 +455,51 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
483
455
|
filename: "./src/foo.js",
|
|
484
456
|
errors: [{ messageId: "no-same-level-funcs", data: { func: "__fn2" } }],
|
|
485
457
|
},
|
|
458
|
+
|
|
459
|
+
{
|
|
460
|
+
code: "import { lib } from 'lib'; const { fn2 } = lib; const fn1 = () => fn2()",
|
|
461
|
+
filename: "./src/foo.js",
|
|
462
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn2" } }],
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
code: "import { lib } from 'lib'; const fn2 = lib.fn2; const fn1 = () => fn2()",
|
|
466
|
+
filename: "./src/foo.js",
|
|
467
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn2" } }],
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
code: "import { fn2 } from 'lib'; const arr = [fn2]; const fn1 = () => arr[0]()",
|
|
471
|
+
filename: "./src/foo.js",
|
|
472
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
code: "import { hof1, hof2 } from 'lib'; const fn2 = hof2(); const fn1 = () => hof1(fn2)",
|
|
476
|
+
filename: "./src/foo.js",
|
|
477
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "fn2" } }],
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
code: "import { fn2 } from 'lib'; const arr = [fn2()]; const fn1 = () => arr.push(1)",
|
|
481
|
+
filename: "./src/foo.js",
|
|
482
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
code: "import { fn2 } from 'lib'; const data = [...fn2()]; const fn1 = () => data.push(1)",
|
|
486
|
+
filename: "./src/foo.js",
|
|
487
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "data" } }],
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
code: "import { fn2 } from 'lib'; const arr = [fn2]; const fn1 = () => arr.push(1)",
|
|
491
|
+
filename: "./src/foo.js",
|
|
492
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
code: "import { Comp2 } from 'lib'; const arr = [<Comp2 />]; const fn1 = () => arr.push(1)",
|
|
496
|
+
filename: "./src/foo.js",
|
|
497
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
code: "import { Comp2 } from 'lib'; const arr = [Comp2]; const fn1 = () => arr.push(1)",
|
|
501
|
+
filename: "./src/foo.js",
|
|
502
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "arr" } }],
|
|
503
|
+
},
|
|
486
504
|
],
|
|
487
505
|
});
|