Skip to content

Commit cea6ad5

Browse files
feat: v-bind (francoismassart#208)
* chore: add wip v-bind tests for no-custom-classname * chore: first beta tests for v-bind * 3.9.0-beta.0 * refactor(no-custom-classname): templateVisitor * tests(no-custom-classname): v-bind * feat(no-contradicting-classname): v-bind * feat(no-arbitrary-value): v-bind * feat(migration-from-tailwind-2): v-bind * feat(enforces-shorthand): v-bind * feat(enforces-negative-arbitrary-values): v-bind * feat(classnames-order): v-bind * chore: cleaning temp code * 3.9.0-beta.1 * fix: francoismassart#168 (comment) * 3.9.0-beta.2 * fix: property of null * 3.9.0-beta.3
1 parent 59a84be commit cea6ad5

17 files changed

+722
-130
lines changed

lib/rules/classnames-order.js

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,15 @@ module.exports = {
129129
return;
130130
case 'ObjectExpression':
131131
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
132-
132+
const isVue = node.key && node.key.type === 'VDirectiveKey';
133133
arg.properties.forEach((prop) => {
134-
sortNodeArgumentValue(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
134+
const propVal = isUsedByClassNamesPlugin || isVue ? prop.key : prop.value;
135+
sortNodeArgumentValue(node, propVal);
135136
});
136137
return;
138+
case 'Property':
139+
sortNodeArgumentValue(node, arg.key);
140+
break;
137141
case 'Literal':
138142
originalClassNamesValue = arg.value;
139143
start = arg.range[0] + 1;
@@ -210,18 +214,20 @@ module.exports = {
210214
}
211215
};
212216

217+
const callExpressionVisitor = function (node) {
218+
if (callees.findIndex((name) => node.callee.name === name) === -1) {
219+
return;
220+
}
221+
222+
node.arguments.forEach((arg) => {
223+
sortNodeArgumentValue(node, arg);
224+
});
225+
};
226+
213227
const scriptVisitor = {
214228
JSXAttribute: attributeVisitor,
215229
TextAttribute: attributeVisitor,
216-
CallExpression: function (node) {
217-
if (callees.findIndex((name) => node.callee.name === name) === -1) {
218-
return;
219-
}
220-
221-
node.arguments.forEach((arg) => {
222-
sortNodeArgumentValue(node, arg);
223-
});
224-
},
230+
CallExpression: callExpressionVisitor,
225231
TaggedTemplateExpression: function (node) {
226232
if (!tags.includes(node.tag.name)) {
227233
return;
@@ -231,11 +237,29 @@ module.exports = {
231237
},
232238
};
233239
const templateVisitor = {
240+
CallExpression: callExpressionVisitor,
241+
/*
242+
Tagged templates inside data bindings
243+
https://github.com/vuejs/vue/issues/9721
244+
*/
234245
VAttribute: function (node) {
235-
if (!astUtil.isValidVueAttribute(node)) {
236-
return;
246+
switch (true) {
247+
case !astUtil.isValidVueAttribute(node):
248+
return;
249+
case astUtil.isVLiteralValue(node):
250+
sortNodeArgumentValue(node, null);
251+
break;
252+
case astUtil.isArrayExpression(node):
253+
node.value.expression.elements.forEach((arg) => {
254+
sortNodeArgumentValue(node, arg);
255+
});
256+
break;
257+
case astUtil.isObjectExpression(node):
258+
node.value.expression.properties.forEach((prop) => {
259+
sortNodeArgumentValue(node, prop);
260+
});
261+
break;
237262
}
238-
sortNodeArgumentValue(node);
239263
},
240264
};
241265

lib/rules/enforces-negative-arbitrary-values.js

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,15 @@ module.exports = {
103103
return;
104104
case 'ObjectExpression':
105105
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
106-
106+
const isVue = node.key && node.key.type === 'VDirectiveKey';
107107
arg.properties.forEach((prop) => {
108-
parseForNegativeArbitraryClassNames(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
108+
const propVal = isUsedByClassNamesPlugin || isVue ? prop.key : prop.value;
109+
parseForNegativeArbitraryClassNames(node, propVal);
109110
});
110111
return;
112+
case 'Property':
113+
parseForNegativeArbitraryClassNames(node, arg.key);
114+
return;
111115
case 'Literal':
112116
originalClassNamesValue = arg.value;
113117
break;
@@ -155,17 +159,19 @@ module.exports = {
155159
}
156160
};
157161

162+
const callExpressionVisitor = function (node) {
163+
if (callees.findIndex((name) => node.callee.name === name) === -1) {
164+
return;
165+
}
166+
node.arguments.forEach((arg) => {
167+
parseForNegativeArbitraryClassNames(node, arg);
168+
});
169+
};
170+
158171
const scriptVisitor = {
159172
JSXAttribute: attributeVisitor,
160173
TextAttribute: attributeVisitor,
161-
CallExpression: function (node) {
162-
if (callees.findIndex((name) => node.callee.name === name) === -1) {
163-
return;
164-
}
165-
node.arguments.forEach((arg) => {
166-
parseForNegativeArbitraryClassNames(node, arg);
167-
});
168-
},
174+
CallExpression: callExpressionVisitor,
169175
TaggedTemplateExpression: function (node) {
170176
if (!tags.includes(node.tag.name)) {
171177
return;
@@ -175,11 +181,29 @@ module.exports = {
175181
};
176182

177183
const templateVisitor = {
184+
CallExpression: callExpressionVisitor,
185+
/*
186+
Tagged templates inside data bindings
187+
https://github.com/vuejs/vue/issues/9721
188+
*/
178189
VAttribute: function (node) {
179-
if (!astUtil.isValidVueAttribute(node)) {
180-
return;
190+
switch (true) {
191+
case !astUtil.isValidVueAttribute(node):
192+
return;
193+
case astUtil.isVLiteralValue(node):
194+
parseForNegativeArbitraryClassNames(node);
195+
break;
196+
case astUtil.isArrayExpression(node):
197+
node.value.expression.elements.forEach((arg) => {
198+
parseForNegativeArbitraryClassNames(node, arg);
199+
});
200+
break;
201+
case astUtil.isObjectExpression(node):
202+
node.value.expression.properties.forEach((prop) => {
203+
parseForNegativeArbitraryClassNames(node, prop);
204+
});
205+
break;
181206
}
182-
parseForNegativeArbitraryClassNames(node);
183207
},
184208
};
185209

lib/rules/enforces-shorthand.js

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,16 @@ module.exports = {
156156
return;
157157
case 'ObjectExpression':
158158
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
159-
159+
const isVue = node.key && node.key.type === 'VDirectiveKey';
160160
arg.properties.forEach((prop) => {
161-
parseForShorthandCandidates(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
161+
const propVal = isUsedByClassNamesPlugin || isVue ? prop.key : prop.value;
162+
parseForShorthandCandidates(node, propVal);
162163
});
163164
return;
165+
case 'Property':
166+
parseForShorthandCandidates(node, arg.key);
167+
return;
168+
164169
case 'Literal':
165170
originalClassNamesValue = arg.value;
166171
start = arg.range[0] + 1;
@@ -385,18 +390,20 @@ module.exports = {
385390
}
386391
};
387392

393+
const callExpressionVisitor = function (node) {
394+
if (callees.findIndex((name) => node.callee.name === name) === -1) {
395+
return;
396+
}
397+
398+
node.arguments.forEach((arg) => {
399+
parseForShorthandCandidates(node, arg);
400+
});
401+
};
402+
388403
const scriptVisitor = {
389404
JSXAttribute: attributeVisitor,
390405
TextAttribute: attributeVisitor,
391-
CallExpression: function (node) {
392-
if (callees.findIndex((name) => node.callee.name === name) === -1) {
393-
return;
394-
}
395-
396-
node.arguments.forEach((arg) => {
397-
parseForShorthandCandidates(node, arg);
398-
});
399-
},
406+
CallExpression: callExpressionVisitor,
400407
TaggedTemplateExpression: function (node) {
401408
if (!tags.includes(node.tag.name)) {
402409
return;
@@ -407,11 +414,29 @@ module.exports = {
407414
};
408415

409416
const templateVisitor = {
417+
CallExpression: callExpressionVisitor,
418+
/*
419+
Tagged templates inside data bindings
420+
https://github.com/vuejs/vue/issues/9721
421+
*/
410422
VAttribute: function (node) {
411-
if (!astUtil.isValidVueAttribute(node)) {
412-
return;
423+
switch (true) {
424+
case !astUtil.isValidVueAttribute(node):
425+
return;
426+
case astUtil.isVLiteralValue(node):
427+
parseForShorthandCandidates(node);
428+
break;
429+
case astUtil.isArrayExpression(node):
430+
node.value.expression.elements.forEach((arg) => {
431+
parseForShorthandCandidates(node, arg);
432+
});
433+
break;
434+
case astUtil.isObjectExpression(node):
435+
node.value.expression.properties.forEach((prop) => {
436+
parseForShorthandCandidates(node, prop);
437+
});
438+
break;
413439
}
414-
parseForShorthandCandidates(node);
415440
},
416441
};
417442

lib/rules/migration-from-tailwind-2.js

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ module.exports = {
124124
parseForObsoleteClassNames(node, prop.key);
125125
});
126126
return;
127+
case 'Property':
128+
parseForObsoleteClassNames(node, arg.key);
129+
return;
127130
case 'Literal':
128131
originalClassNamesValue = arg.value;
129132
start = arg.range[0] + 1;
@@ -267,17 +270,19 @@ module.exports = {
267270
}
268271
};
269272

273+
const callExpressionVisitor = function (node) {
274+
if (callees.findIndex((name) => node.callee.name === name) === -1) {
275+
return;
276+
}
277+
node.arguments.forEach((arg) => {
278+
parseForObsoleteClassNames(node, arg);
279+
});
280+
};
281+
270282
const scriptVisitor = {
271283
JSXAttribute: attributeVisitor,
272284
TextAttribute: attributeVisitor,
273-
CallExpression: function (node) {
274-
if (callees.findIndex((name) => node.callee.name === name) === -1) {
275-
return;
276-
}
277-
node.arguments.forEach((arg) => {
278-
parseForObsoleteClassNames(node, arg);
279-
});
280-
},
285+
CallExpression: callExpressionVisitor,
281286
TaggedTemplateExpression: function (node) {
282287
if (!tags.includes(node.tag.name)) {
283288
return;
@@ -287,11 +292,29 @@ module.exports = {
287292
};
288293

289294
const templateVisitor = {
295+
CallExpression: callExpressionVisitor,
296+
/*
297+
Tagged templates inside data bindings
298+
https://github.com/vuejs/vue/issues/9721
299+
*/
290300
VAttribute: function (node) {
291-
if (!astUtil.isValidVueAttribute(node)) {
292-
return;
301+
switch (true) {
302+
case !astUtil.isValidVueAttribute(node):
303+
return;
304+
case astUtil.isVLiteralValue(node):
305+
parseForObsoleteClassNames(node);
306+
break;
307+
case astUtil.isArrayExpression(node):
308+
node.value.expression.elements.forEach((arg) => {
309+
parseForObsoleteClassNames(node, arg);
310+
});
311+
break;
312+
case astUtil.isObjectExpression(node):
313+
node.value.expression.properties.forEach((prop) => {
314+
parseForObsoleteClassNames(node, prop);
315+
});
316+
break;
293317
}
294-
parseForObsoleteClassNames(node);
295318
},
296319
};
297320

lib/rules/no-arbitrary-value.js

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,15 @@ module.exports = {
103103
return;
104104
case 'ObjectExpression':
105105
const isUsedByClassNamesPlugin = node.callee && node.callee.name === 'classnames';
106-
106+
const isVue = node.key && node.key.type === 'VDirectiveKey';
107107
arg.properties.forEach((prop) => {
108-
parseForArbitraryValues(node, isUsedByClassNamesPlugin ? prop.key : prop.value);
108+
const propVal = isUsedByClassNamesPlugin || isVue ? prop.key : prop.value;
109+
parseForArbitraryValues(node, propVal);
109110
});
110111
return;
112+
case 'Property':
113+
parseForArbitraryValues(node, arg.key);
114+
return;
111115
case 'Literal':
112116
originalClassNamesValue = arg.value;
113117
break;
@@ -155,17 +159,19 @@ module.exports = {
155159
}
156160
};
157161

162+
const callExpressionVisitor = function (node) {
163+
if (callees.findIndex((name) => node.callee.name === name) === -1) {
164+
return;
165+
}
166+
node.arguments.forEach((arg) => {
167+
parseForArbitraryValues(node, arg);
168+
});
169+
};
170+
158171
const scriptVisitor = {
159172
JSXAttribute: attributeVisitor,
160173
TextAttribute: attributeVisitor,
161-
CallExpression: function (node) {
162-
if (callees.findIndex((name) => node.callee.name === name) === -1) {
163-
return;
164-
}
165-
node.arguments.forEach((arg) => {
166-
parseForArbitraryValues(node, arg);
167-
});
168-
},
174+
CallExpression: callExpressionVisitor,
169175
TaggedTemplateExpression: function (node) {
170176
if (!tags.includes(node.tag.name)) {
171177
return;
@@ -175,11 +181,29 @@ module.exports = {
175181
};
176182

177183
const templateVisitor = {
184+
CallExpression: callExpressionVisitor,
185+
/*
186+
Tagged templates inside data bindings
187+
https://github.com/vuejs/vue/issues/9721
188+
*/
178189
VAttribute: function (node) {
179-
if (!astUtil.isValidVueAttribute(node)) {
180-
return;
190+
switch (true) {
191+
case !astUtil.isValidVueAttribute(node):
192+
return;
193+
case astUtil.isVLiteralValue(node):
194+
parseForArbitraryValues(node, null);
195+
break;
196+
case astUtil.isArrayExpression(node):
197+
node.value.expression.elements.forEach((arg) => {
198+
parseForArbitraryValues(node, arg);
199+
});
200+
break;
201+
case astUtil.isObjectExpression(node):
202+
node.value.expression.properties.forEach((prop) => {
203+
parseForArbitraryValues(node, prop);
204+
});
205+
break;
181206
}
182-
parseForArbitraryValues(node);
183207
},
184208
};
185209

0 commit comments

Comments
 (0)