UNPKG

eslint-plugin-vue-scoped-css

Version:
289 lines (288 loc) 9.46 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.VueComponentContext = void 0; exports.createVueComponentContext = createVueComponentContext; const vue_eslint_parser_1 = require("vue-eslint-parser"); const find_vue_1 = __importDefault(require("./find-vue")); const utils_1 = require("../../../utils/utils"); const compat_1 = require("../../../utils/compat"); const traverseNodes = vue_eslint_parser_1.AST.traverseNodes; const UNKNOWN = Symbol("unknown"); class VueComponentContext { constructor(node, context) { this.properties = null; this.node = node; this.context = context; } findVueComponentProperty(name) { const properties = this.properties || (this.properties = extractVueComponentProperties(this.node, this.context)); if (properties[UNKNOWN]) { return null; } if (properties.data === UNKNOWN || properties.data[UNKNOWN]) { return null; } if (properties.computed === UNKNOWN || properties.computed[UNKNOWN]) { return null; } if (properties.data[name]) { return properties.data[name]; } if (properties.computed[name]) { return properties.computed[name]; } return null; } getClassesOperatedByClassList(refNames, isRoot) { return getClassesOperatedByClassList(this.node, refNames, isRoot, this.context); } } exports.VueComponentContext = VueComponentContext; function createVueComponentContext(context) { const node = (0, find_vue_1.default)(context); if (!node) { return null; } return new VueComponentContext(node, context); } function extractVueComponentProperties(vueNode, context) { const result = { data: {}, computed: {}, }; for (const p of vueNode.properties) { if (p.type !== "Property") { result[UNKNOWN] = true; continue; } const keyName = getPropertyOrIdentifierName(p); if (keyName === "data") { result.data = extractVueComponentData(p.value, context); } else if (keyName === "computed") { result.computed = extractVueComponentComputed(p.value, context); } } return result; } function extractVueComponentData(dataNode, context) { const dataNodes = []; if ((dataNode.type === "ArrowFunctionExpression" && dataNode.body.type === "BlockStatement") || dataNode.type === "FunctionExpression") { if (dataNode.body.type === "BlockStatement") { for (const returnStatement of getReturnStatements(dataNode.body, context)) { if (returnStatement.argument) { dataNodes.push(returnStatement.argument); } } } else { dataNodes.push(dataNode.body); } } else if (dataNode.type === "ArrowFunctionExpression" && dataNode.body.type !== "BlockStatement") { dataNodes.push(dataNode.body); } else if (dataNode.type === "ObjectExpression") { dataNodes.push(dataNode); } else { return UNKNOWN; } const data = {}; for (const dataObj of dataNodes) { if (dataObj.type !== "ObjectExpression") { data[UNKNOWN] = true; continue; } for (const prop of dataObj.properties) { if (prop.type === "Property") { const keyName = getPropertyOrIdentifierName(prop); if (keyName == null) { data[UNKNOWN] = true; } else { const values = data[keyName] || (data[keyName] = []); values.push(prop.value); } } else { data[UNKNOWN] = true; } } } return data; } function extractVueComponentComputed(computedNode, context) { if (computedNode.type !== "ObjectExpression") { return UNKNOWN; } const computed = {}; for (const p of computedNode.properties) { if (p.type !== "Property") { computed[UNKNOWN] = true; continue; } const keyName = getPropertyOrIdentifierName(p); if (!keyName) { computed[UNKNOWN] = true; continue; } const values = computed[keyName] || (computed[keyName] = []); const value = p.value; let func = value; if (value.type === "ObjectExpression") { const get = value.properties .filter(isProperty) .find((prop) => getPropertyOrIdentifierName(prop) === "get"); if (get) { func = get.value; } } if ((func.type === "ArrowFunctionExpression" && func.body.type === "BlockStatement") || func.type === "FunctionExpression") { if (func.body.type === "BlockStatement") { const exprs = getReturnStatements(func.body, context) .map((r) => r.argument) .filter(utils_1.isDefined); values.push(...exprs); } else { values.push(func.body); } } else if (func.type === "ArrowFunctionExpression" && func.body.type !== "BlockStatement") { values.push(func.body); } else { computed[UNKNOWN] = true; } } return computed; } function getClassesOperatedByClassList(vueNode, refNames, isRoot, context) { const results = []; traverseNodes(vueNode, { visitorKeys: (0, compat_1.getSourceCode)(context).visitorKeys, enterNode(node) { if (node.type !== "CallExpression" || node.callee.type !== "MemberExpression") { return; } const o = node.callee.object; if (getPropertyOrIdentifierName(o) !== "classList") { return; } if (o.type === "MemberExpression" && getPropertyOrIdentifierName(o.object) === "$el") { if (!isRoot) { return; } } if (refNames != null) { const $refName = o.type === "MemberExpression" && o.object.type !== "Super" ? get$RefName(o.object) : null; if ($refName != null) { if (!refNames.some((r) => r.matchString($refName))) { return; } } } const argumentNodes = getClassesArguments(node); results.push(...argumentNodes); }, leaveNode() { }, }); return results; } function getReturnStatements(body, context) { const returnStatements = []; const skipNodes = []; traverseNodes(body, { visitorKeys: (0, compat_1.getSourceCode)(context).visitorKeys, enterNode(node) { if (skipNodes.length) { return; } if (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression" || node.type === "FunctionDeclaration") { skipNodes.unshift(node); } else if (node.type === "ReturnStatement") { returnStatements.push(node); } }, leaveNode(node) { if (skipNodes[0] === node) { skipNodes.shift(); } }, }); return returnStatements; } function getPropertyOrIdentifierName(node) { if (node.type === "Identifier") { return node.name; } else if (node.type === "MemberExpression") { if (node.property.type === "Identifier" && !node.computed) { return node.property.name; } else if (node.property.type === "Literal" && node.computed) { return getLiteralString(node.property); } } else if (node.type === "Property") { if (node.key.type === "Identifier" && !node.computed) { return node.key.name; } else if (node.key.type === "Literal") { return getLiteralString(node.key); } } return null; } function get$RefName(expr) { if (expr.type !== "MemberExpression") { return null; } const { object } = expr; const name = getPropertyOrIdentifierName(object); if (name !== "$refs") { return null; } return getPropertyOrIdentifierName(expr); } function getClassesArguments(node) { const methodName = getPropertyOrIdentifierName(node.callee); if (methodName === "add" || methodName === "remove") { return node.arguments; } else if (methodName === "toggle" || methodName === "contains") { return [node.arguments[0]]; } else if (methodName === "replace") { return [node.arguments[0], node.arguments[1]]; } return []; } function getLiteralString(node) { if (typeof node.value === "string") { return node.value; } return `${node.value}`; } function isProperty(node) { return node.type === "Property"; }