Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Parse variable declarations
  • Loading branch information
jd-carroll committed Aug 11, 2023
commit 443106b0028b4c65a09398c7028becc3c7af2b9f
13 changes: 13 additions & 0 deletions lib/rules/no-contradicting-classname.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ module.exports = {
const tags = getOption(context, 'tags');
const twConfig = getOption(context, 'config');
const classRegex = getOption(context, 'classRegex');
const classDeclarationRegex = getOption(context, 'declarationRegex');
const skipClassDeclaration = getOption(context, 'skipClassDeclaration');

const mergedConfig = customConfig.resolve(twConfig);

Expand Down Expand Up @@ -198,10 +200,21 @@ module.exports = {
parseForContradictingClassNames(allClassnamesForNode, node);
};

const variableDeclaratorVistor = function (node) {
if (!astUtil.isClassDeclaration(node, classDeclarationRegex) || skipClassDeclaration) {
return;
}
if (!astUtil.isValidDeclaratorValue(node)) {
return;
}
astUtil.parseNodeRecursive(node, node.init, parseForContradictingClassNames, true, false, ignoredKeys);
};

const scriptVisitor = {
JSXAttribute: attributeVisitor,
TextAttribute: attributeVisitor,
CallExpression: callExpressionVisitor,
VariableDeclarator: variableDeclaratorVistor,
TaggedTemplateExpression: function (node) {
if (!tags.includes(node.tag.name)) {
return;
Expand Down
13 changes: 13 additions & 0 deletions lib/rules/no-custom-classname.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ module.exports = {
const cssFilesRefreshRate = getOption(context, 'cssFilesRefreshRate');
const whitelist = getOption(context, 'whitelist');
const classRegex = getOption(context, 'classRegex');
const classDeclarationRegex = getOption(context, 'declarationRegex');
const skipClassDeclaration = getOption(context, 'skipClassDeclaration');

const mergedConfig = customConfig.resolve(twConfig);
const contextFallback = // Set the created contextFallback in the cache if it does not exist yet.
Expand Down Expand Up @@ -177,10 +179,21 @@ module.exports = {
});
};

const variableDeclaratorVistor = function (node) {
if (!astUtil.isClassDeclaration(node, classDeclarationRegex) || skipClassDeclaration) {
return;
}
if (!astUtil.isValidDeclaratorValue(node)) {
return;
}
astUtil.parseNodeRecursive(node, node.init, parseForCustomClassNames, false, false, ignoredKeys);
};

const scriptVisitor = {
JSXAttribute: attributeVisitor,
TextAttribute: attributeVisitor,
CallExpression: callExpressionVisitor,
VariableDeclarator: variableDeclaratorVistor,
TaggedTemplateExpression: function (node) {
if (!tags.includes(node.tag.name)) {
return;
Expand Down
74 changes: 74 additions & 0 deletions lib/util/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,28 @@ function isClassAttribute(node, classRegex) {
return new RegExp(classRegex).test(name);
}

/**
* Find out if node is a class variable declaration
*
* @param {ASTNode} node The AST node being checked
* @param {String} classDeclarationRegex Regex to test the attribute that is being checked against
* @returns {Boolean}
*/
function isClassDeclaration(node, classDeclarationRegex) {
let name;
switch (node.type) {
case 'VariableDeclarator':
name = node.id.name;
break;
default:
name = '';
}
if (!name) {
return false;
}
return new RegExp(classDeclarationRegex).test(name);
}

/**
* Find out if node is `class`
*
Expand Down Expand Up @@ -71,6 +93,53 @@ function isVueClassAttribute(node, classRegex) {
}
}

/**
* Find out if a node is just simple text
*
* @param {ASTNode} node The AST node being checked
* @returns {Boolean}
*/
function isLiteralValue(node) {
return node && node.type === 'Literal';
}

/**
* Find out if a node is an ArrayExpression
*
* @param {ASTNode} node The AST node being checked
* @returns {Boolean}
*/
function isArrayExpression(node) {
return node && node.type === 'ArrayExpression';
}

/**
* Find out if a node is an ObjectExpression
*
* @param {ASTNode} node The AST node being checked
* @returns {Boolean}
*/
function isObjectExpression(node) {
return node && node.type === 'ObjectExpression';
}

/**
* Find out if node's init attribute is just simple text
*
* @param {ASTNode} node The AST node being checked
* @returns {Boolean}
*/
function isValidDeclaratorValue(node) {
switch (true) {
case isLiteralValue(node.init): // Simple string
case isArrayExpression(node.init): // ['tw-unknown-class']
case isObjectExpression(node.init): // {'tw-unknown-class': true}
return true;
default:
return false;
}
}

/**
* Find out if node's value attribute is just simple text
*
Expand Down Expand Up @@ -360,7 +429,12 @@ module.exports = {
extractValueFromNode,
extractClassnamesFromValue,
isClassAttribute,
isClassDeclaration,
isLiteralValue,
isArrayExpression,
isObjectExpression,
isLiteralAttributeValue,
isValidDeclaratorValue,
isVArrayExpression,
isVObjectExpression,
isValidJSXAttribute,
Expand Down
4 changes: 4 additions & 0 deletions lib/util/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ function getOption(context, name) {
return [];
case 'whitelist':
return [];
case 'declarationRegex':
return '^(classes|classNames?|.*Styles)$';
case 'skipClassDeclaration':
return false;
}
}

Expand Down