eslint-plugin-stratified-design 0.12.2 → 0.12.4
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,9 +17,39 @@ const { fromCwd, match } = require("../helpers/common");
|
|
|
17
17
|
* @typedef {import('eslint').Rule.Node} Node
|
|
18
18
|
* @typedef {import('eslint').AST.Token} Token
|
|
19
19
|
* @typedef {import('eslint').SourceCode} SourceCode
|
|
20
|
-
* @typedef {({[name: string]: number
|
|
20
|
+
* @typedef {({[name: string]: number})} Levels
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @param {Node | Token} nodeOrToken
|
|
25
|
+
* @returns {string | null}
|
|
26
|
+
*/
|
|
27
|
+
const deriveFuncName = (nodeOrToken) => {
|
|
28
|
+
const declaration =
|
|
29
|
+
(nodeOrToken.type === "ExportNamedDeclaration" ||
|
|
30
|
+
nodeOrToken.type === "ExportDefaultDeclaration") &&
|
|
31
|
+
Boolean(nodeOrToken.declaration)
|
|
32
|
+
? nodeOrToken.declaration
|
|
33
|
+
: nodeOrToken;
|
|
34
|
+
const isFuncDeclaration = declaration.type === "FunctionDeclaration";
|
|
35
|
+
const isVarDeclaration =
|
|
36
|
+
declaration.type === "VariableDeclaration" &&
|
|
37
|
+
[
|
|
38
|
+
"ArrowFunctionExpression",
|
|
39
|
+
"FunctionExpression",
|
|
40
|
+
"CallExpression",
|
|
41
|
+
"TaggedTemplateExpression",
|
|
42
|
+
].includes(declaration.declarations[0].init.type);
|
|
43
|
+
|
|
44
|
+
if (isFuncDeclaration || isVarDeclaration) {
|
|
45
|
+
const name = isFuncDeclaration
|
|
46
|
+
? declaration.id.name
|
|
47
|
+
: declaration.declarations[0].id.name;
|
|
48
|
+
return name;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
};
|
|
52
|
+
|
|
23
53
|
/**
|
|
24
54
|
* @param {SourceCode} sourceCode
|
|
25
55
|
* @param {Node | Token} nodeOrToken
|
|
@@ -34,7 +64,7 @@ const deriveLevel = (sourceCode, nodeOrToken) => {
|
|
|
34
64
|
return levelInNum;
|
|
35
65
|
}
|
|
36
66
|
}
|
|
37
|
-
return
|
|
67
|
+
return 1;
|
|
38
68
|
};
|
|
39
69
|
|
|
40
70
|
/**
|
|
@@ -56,12 +86,15 @@ const isCalleeLowerLevel = (sourceCode, levels) => {
|
|
|
56
86
|
*/
|
|
57
87
|
return (node, calleeName) => {
|
|
58
88
|
const calleeLevel = levels[calleeName];
|
|
59
|
-
if (calleeLevel === undefined) return true;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
89
|
+
if (calleeLevel === undefined) return true; // 호출되는 함수가 존재하지 않으면 true 리턴. 함수 내의 함수의 경우에는 항상 calleeLevel 이 undefined 이다.
|
|
90
|
+
|
|
91
|
+
const caller = traceAncestor(sourceCode, node);
|
|
92
|
+
const callerLevel = deriveLevel(sourceCode, caller);
|
|
93
|
+
if (callerLevel < calleeLevel) return true;
|
|
94
|
+
|
|
95
|
+
const callerName = deriveFuncName(caller);
|
|
96
|
+
if (callerName === calleeName) return true; // recursive function
|
|
97
|
+
|
|
65
98
|
return false;
|
|
66
99
|
};
|
|
67
100
|
};
|
|
@@ -116,6 +149,7 @@ module.exports = {
|
|
|
116
149
|
if (isExcludedFile) return {};
|
|
117
150
|
|
|
118
151
|
/**
|
|
152
|
+
* @description 함수들의 레벨. 함수 내의 함수는 여기에 기록되지 않는다.
|
|
119
153
|
* @type {Levels}
|
|
120
154
|
*/
|
|
121
155
|
const levels = {};
|
|
@@ -140,22 +174,9 @@ module.exports = {
|
|
|
140
174
|
return {
|
|
141
175
|
Program(node) {
|
|
142
176
|
node.body.forEach((token) => {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
declaration.type === "VariableDeclaration" &&
|
|
147
|
-
[
|
|
148
|
-
"ArrowFunctionExpression",
|
|
149
|
-
"FunctionExpression",
|
|
150
|
-
"CallExpression",
|
|
151
|
-
"TaggedTemplateExpression",
|
|
152
|
-
].includes(declaration.declarations[0].init.type);
|
|
153
|
-
|
|
154
|
-
if (isFuncDeclaration || isVarDeclaration) {
|
|
155
|
-
const level = deriveLevel(sourceCode, declaration);
|
|
156
|
-
const name = isFuncDeclaration
|
|
157
|
-
? declaration.id.name
|
|
158
|
-
: declaration.declarations[0].id.name;
|
|
177
|
+
const name = deriveFuncName(token);
|
|
178
|
+
if (name) {
|
|
179
|
+
const level = deriveLevel(sourceCode, token);
|
|
159
180
|
levels[name] = level;
|
|
160
181
|
}
|
|
161
182
|
});
|
package/package.json
CHANGED
|
@@ -50,30 +50,114 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
50
50
|
filename: "./src/foo.js",
|
|
51
51
|
options: [{ include: ["src/**/*.*"], exclude: ["src/foo.js"] }],
|
|
52
52
|
},
|
|
53
|
+
|
|
53
54
|
{
|
|
54
55
|
code: "// @level 2\nfunction func2(){};\n// @level 1\nfunction func1(){ func2(); }",
|
|
55
56
|
filename: "./src/foo.js",
|
|
56
57
|
},
|
|
58
|
+
{
|
|
59
|
+
code: "/*@level 2*/function func2(){}; /*@level 1*/function func1(){ func2(); }",
|
|
60
|
+
filename: "./src/foo.js",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
code: "/*@level 2*/function func2(){}; function func1(){ func2(); }",
|
|
64
|
+
filename: "./src/foo.js",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
code: "/*@level 2*/export function func2(){}; /*@level 1*/function func1(){ func2(); }",
|
|
68
|
+
filename: "./src/foo.js",
|
|
69
|
+
},
|
|
70
|
+
|
|
57
71
|
{
|
|
58
72
|
code: "// @level 2\nconst func2 = () => {};\n// @level 1\nfunction func1(){ func2(); }",
|
|
59
73
|
filename: "./src/foo.js",
|
|
60
74
|
},
|
|
75
|
+
{
|
|
76
|
+
code: "// @level 2\nexport const func2 = () => {};\n// @level 1\nfunction func1(){ func2(); }",
|
|
77
|
+
filename: "./src/foo.js",
|
|
78
|
+
},
|
|
79
|
+
|
|
61
80
|
{
|
|
62
81
|
code: "// @level 2\nconst func2 = () => {};\n// @level 1\nconst func1 = () => func2();",
|
|
63
82
|
filename: "./src/foo.js",
|
|
64
83
|
},
|
|
84
|
+
{
|
|
85
|
+
code: "// @level 2\nexport const func2 = () => {};\n// @level 1\nconst func1 = () => func2();",
|
|
86
|
+
filename: "./src/foo.js",
|
|
87
|
+
},
|
|
88
|
+
|
|
65
89
|
{
|
|
66
90
|
code: "/*@level 2*/\nconst func2 = () => {};\n/*@level 1*/\nconst func1 = () => func2();",
|
|
67
91
|
filename: "./src/foo.js",
|
|
68
92
|
},
|
|
93
|
+
{
|
|
94
|
+
code: "/*@level 2*/\nexport const func2 = () => {};\n/*@level 1*/\nconst func1 = () => func2();",
|
|
95
|
+
filename: "./src/foo.js",
|
|
96
|
+
},
|
|
97
|
+
|
|
69
98
|
{
|
|
70
99
|
code: "// @level 2 something\nconst func2 = () => {};\n// @level 1 something\nconst func1 = () => func2();",
|
|
71
100
|
filename: "./src/foo.js",
|
|
72
101
|
},
|
|
102
|
+
{
|
|
103
|
+
code: "// @level 2 something\nexport const func2 = () => {};\n// @level 1 something\nconst func1 = () => func2();",
|
|
104
|
+
filename: "./src/foo.js",
|
|
105
|
+
},
|
|
106
|
+
|
|
73
107
|
{
|
|
74
108
|
code: "/*\n@level 2\nsomething\n*/\nconst func2 = () => {};\n/*something\n@level 1\n*/\nconst func1 = () => func2();",
|
|
75
109
|
filename: "./src/foo.js",
|
|
76
110
|
},
|
|
111
|
+
{
|
|
112
|
+
code: "/*\n@level 2\nsomething\n*/\nexport const func2 = () => {};\n/*something\n@level 1\n*/\nconst func1 = () => func2();",
|
|
113
|
+
filename: "./src/foo.js",
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
{
|
|
117
|
+
code: "// @level 2\nfunction func2(){};\nfunction func1(){ func2(); }",
|
|
118
|
+
filename: "./src/foo.js",
|
|
119
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "func2" } }],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
code: "// @level 2\nexport function func2(){};\nfunction func1(){ func2(); }",
|
|
123
|
+
filename: "./src/foo.js",
|
|
124
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "func2" } }],
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
{
|
|
128
|
+
code: "function recursiveFunc() { recursiveFunc() }",
|
|
129
|
+
filename: "./src/foo.js",
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
code: "const recursiveFunc = () => { recursiveFunc() }",
|
|
133
|
+
filename: "./src/foo.js",
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
code: "export const recursiveFunc = () => { recursiveFunc() }",
|
|
137
|
+
filename: "./src/foo.js",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
code: "//@level 2\nconst recursiveFunc = () => { recursiveFunc() }",
|
|
141
|
+
filename: "./src/foo.js",
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
{
|
|
145
|
+
code: "const funcWithInnerFunc = () => { const innerFunc = () => {}; innerFunc() }",
|
|
146
|
+
filename: "./src/foo.js",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
code: "/*@level 2*/const func2 = () => {}; /*@level 1*/const func1 = () => { const innerFunc = () => { func2() }; innerFunc(); }",
|
|
150
|
+
filename: "./src/foo.js",
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
{
|
|
154
|
+
code: "/*@level 2*/const func = () => 'a'; /*@level 1*/const obj = { a: func() } ",
|
|
155
|
+
filename: "./src/foo.js",
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
code: "/*@level 2*/const func = () => 'a'; /*@level 1*/const obj = { func: () => { func() } } ",
|
|
159
|
+
filename: "./src/foo.js",
|
|
160
|
+
},
|
|
77
161
|
],
|
|
78
162
|
invalid: [
|
|
79
163
|
{
|
|
@@ -192,15 +276,22 @@ ruleTester.run("no-same-level-funcs", rule, {
|
|
|
192
276
|
filename: "./src/foo.js",
|
|
193
277
|
errors: [{ messageId: "no-same-level-funcs", data: { func: "func1" } }],
|
|
194
278
|
},
|
|
279
|
+
|
|
195
280
|
{
|
|
196
|
-
code: "
|
|
281
|
+
code: "function func2(){};\n// @level 1\nfunction func1(){ func2(); }",
|
|
197
282
|
filename: "./src/foo.js",
|
|
198
283
|
errors: [{ messageId: "no-same-level-funcs", data: { func: "func2" } }],
|
|
199
284
|
},
|
|
285
|
+
|
|
200
286
|
{
|
|
201
|
-
code: "
|
|
287
|
+
code: "const func = () => 'a'; const obj = { a: func() } ",
|
|
202
288
|
filename: "./src/foo.js",
|
|
203
|
-
errors: [{ messageId: "no-same-level-funcs", data: { func: "
|
|
289
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "func" } }],
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
code: "const func = () => 'a'; const obj = { func: () => { func() } } ",
|
|
293
|
+
filename: "./src/foo.js",
|
|
294
|
+
errors: [{ messageId: "no-same-level-funcs", data: { func: "func" } }],
|
|
204
295
|
},
|
|
205
296
|
],
|
|
206
297
|
});
|