routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
Generated
Vendored
+224
@@ -0,0 +1,224 @@
|
||||
'use strict';
|
||||
|
||||
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
||||
const require_index = require('../utils/index.js');
|
||||
|
||||
//#region lib/rules/no-unused-emit-declarations.js
|
||||
/**
|
||||
* @author ItMaga
|
||||
* See LICENSE file in root directory for full license.
|
||||
*/
|
||||
var require_no_unused_emit_declarations = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
|
||||
const { findVariable } = require("@eslint-community/eslint-utils");
|
||||
const utils = require_index.default;
|
||||
/**
|
||||
* @typedef {import('../utils').ComponentEmit} ComponentEmit
|
||||
* @typedef {import('../utils').VueObjectData} VueObjectData
|
||||
*/
|
||||
/**
|
||||
* @typedef {object} SetupContext
|
||||
* @property {Set<Identifier>} contextReferenceIds
|
||||
* @property {Set<Identifier>} emitReferenceIds
|
||||
*/
|
||||
/**
|
||||
* @typedef {object} NameWithLoc
|
||||
* @property {string} name
|
||||
* @property {SourceLocation} loc
|
||||
* @property {Range} range
|
||||
*/
|
||||
/**
|
||||
* Get the name param node from the given CallExpression
|
||||
* @param {CallExpression} node CallExpression
|
||||
* @returns {NameWithLoc | null}
|
||||
*/
|
||||
function getNameParamNode(node) {
|
||||
const nameLiteralNode = node.arguments[0];
|
||||
if (nameLiteralNode && utils.isStringLiteral(nameLiteralNode)) {
|
||||
const name = utils.getStringLiteralValue(nameLiteralNode);
|
||||
if (name != null) return {
|
||||
name,
|
||||
loc: nameLiteralNode.loc,
|
||||
range: nameLiteralNode.range
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Check if the given node is a reference of setup context
|
||||
* @param {Expression | Super | SpreadElement} value
|
||||
* @param {SetupContext} setupContext
|
||||
* @returns {boolean}
|
||||
* */
|
||||
function hasReferenceId(value, setupContext) {
|
||||
const { contextReferenceIds, emitReferenceIds } = setupContext;
|
||||
return value.type === "Identifier" && (emitReferenceIds.has(value) || contextReferenceIds.has(value));
|
||||
}
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
docs: {
|
||||
description: "disallow unused emit declarations",
|
||||
categories: void 0,
|
||||
url: "https://eslint.vuejs.org/rules/no-unused-emit-declarations.html"
|
||||
},
|
||||
fixable: null,
|
||||
schema: [],
|
||||
messages: { unused: "`{{name}}` is defined as emit but never used." }
|
||||
},
|
||||
create(context) {
|
||||
/** @type {Map<string, ComponentEmit>} */
|
||||
const emitDeclarations = /* @__PURE__ */ new Map();
|
||||
/** @type {Map<string, Expression>} */
|
||||
const emitCalls = /* @__PURE__ */ new Map();
|
||||
/** @type {Map<ObjectExpression | Program, SetupContext>} */
|
||||
const setupContexts = /* @__PURE__ */ new Map();
|
||||
const programNode = context.sourceCode.ast;
|
||||
let emitParamName = "";
|
||||
/**
|
||||
* @param {CallExpression} node
|
||||
* */
|
||||
function addEmitCall(node) {
|
||||
const nameParamNode = getNameParamNode(node);
|
||||
if (nameParamNode) emitCalls.set(nameParamNode.name, node);
|
||||
}
|
||||
function clearEmits() {
|
||||
emitCalls.clear();
|
||||
emitDeclarations.clear();
|
||||
}
|
||||
/**
|
||||
* @param {Expression | SpreadElement} expression
|
||||
* @param {SetupContext} setupContext
|
||||
* @returns {boolean}
|
||||
* */
|
||||
function checkExpressionReference(expression, setupContext) {
|
||||
if (expression.type === "MemberExpression") {
|
||||
if (hasReferenceId(utils.skipChainExpression(expression.object), setupContext)) {
|
||||
clearEmits();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (hasReferenceId(expression, setupContext)) {
|
||||
clearEmits();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {Array<Expression | SpreadElement>} args
|
||||
* @param {SetupContext} setupContext
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function verifyArgumentsReferences(args, setupContext) {
|
||||
for (const argument of args) {
|
||||
if (argument.type === "ObjectExpression") {
|
||||
for (const property of argument.properties) if (property.type === "Property" && checkExpressionReference(property.value, setupContext)) return true;
|
||||
}
|
||||
if (argument.type === "ArrayExpression") for (const element of argument.elements) {
|
||||
if (!element) continue;
|
||||
if (checkExpressionReference(element, setupContext)) return true;
|
||||
}
|
||||
if (checkExpressionReference(argument, setupContext)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @param {Expression | Super} callee
|
||||
* @param {Set<Identifier>} referenceIds
|
||||
* @param {CallExpression} node
|
||||
* */
|
||||
function addEmitCallByReference(callee, referenceIds, node) {
|
||||
if (callee.type === "Identifier" && referenceIds.has(callee)) addEmitCall(node);
|
||||
}
|
||||
const callVisitor = { CallExpression(node, info) {
|
||||
const callee = utils.skipChainExpression(node.callee);
|
||||
let emit = null;
|
||||
if (callee.type === "MemberExpression") {
|
||||
const name = utils.getStaticPropertyName(callee);
|
||||
if (name === "emit" || name === "$emit") emit = {
|
||||
name,
|
||||
member: callee
|
||||
};
|
||||
}
|
||||
const vueDefineNode = info ? info.node : programNode;
|
||||
const setupContext = setupContexts.get(vueDefineNode);
|
||||
if (setupContext) {
|
||||
if (callee.parent.type === "CallExpression" && callee.parent.arguments && verifyArgumentsReferences(callee.parent.arguments, setupContext)) return;
|
||||
const { contextReferenceIds, emitReferenceIds } = setupContext;
|
||||
addEmitCallByReference(callee, emitReferenceIds, node);
|
||||
if (emit && emit.name === "emit") addEmitCallByReference(utils.skipChainExpression(emit.member.object), contextReferenceIds, node);
|
||||
}
|
||||
if (emit && emit.name === "$emit") {
|
||||
const memObject = utils.skipChainExpression(emit.member.object);
|
||||
if (utils.isThis(memObject, context)) addEmitCall(node);
|
||||
}
|
||||
if (callee.type === "Identifier" && (callee.name === "$emit" || callee.name === emitParamName)) addEmitCall(node);
|
||||
} };
|
||||
return utils.compositingVisitors(utils.defineTemplateBodyVisitor(context, callVisitor), utils.defineVueVisitor(context, {
|
||||
...callVisitor,
|
||||
onVueObjectEnter(node) {
|
||||
for (const emit of utils.getComponentEmitsFromOptions(node)) if (emit.emitName) emitDeclarations.set(emit.emitName, emit);
|
||||
},
|
||||
onSetupFunctionEnter(node, { node: vueNode }) {
|
||||
const contextParam = node.params[1];
|
||||
if (!contextParam || contextParam.type === "RestElement" || contextParam.type === "ArrayPattern") return;
|
||||
/** @type {Set<Identifier>} */
|
||||
const contextReferenceIds = /* @__PURE__ */ new Set();
|
||||
/** @type {Set<Identifier>} */
|
||||
const emitReferenceIds = /* @__PURE__ */ new Set();
|
||||
if (contextParam.type === "ObjectPattern") {
|
||||
const emitProperty = utils.findAssignmentProperty(contextParam, "emit");
|
||||
if (!emitProperty) return;
|
||||
const emitParam = emitProperty.value;
|
||||
const variable = emitParam.type === "Identifier" ? findVariable(utils.getScope(context, emitParam), emitParam) : null;
|
||||
if (!variable) return;
|
||||
for (const reference of variable.references) emitReferenceIds.add(reference.identifier);
|
||||
} else if (contextParam.type === "Identifier") {
|
||||
const variable = findVariable(utils.getScope(context, contextParam), contextParam);
|
||||
for (const reference of variable.references) contextReferenceIds.add(reference.identifier);
|
||||
}
|
||||
setupContexts.set(vueNode, {
|
||||
contextReferenceIds,
|
||||
emitReferenceIds
|
||||
});
|
||||
}
|
||||
}), utils.defineScriptSetupVisitor(context, {
|
||||
onDefineEmitsEnter(node, emits) {
|
||||
for (const emit of emits) if (emit.emitName) emitDeclarations.set(emit.emitName, emit);
|
||||
if (!node.parent || node.parent.type !== "VariableDeclarator" || node.parent.init !== node) return;
|
||||
const emitParam = node.parent.id;
|
||||
if (emitParam.type !== "Identifier") return;
|
||||
emitParamName = emitParam.name;
|
||||
const variable = findVariable(utils.getScope(context, emitParam), emitParam);
|
||||
if (!variable) return;
|
||||
/** @type {Set<Identifier>} */
|
||||
const emitReferenceIds = /* @__PURE__ */ new Set();
|
||||
for (const reference of variable.references) emitReferenceIds.add(reference.identifier);
|
||||
setupContexts.set(programNode, {
|
||||
contextReferenceIds: /* @__PURE__ */ new Set(),
|
||||
emitReferenceIds
|
||||
});
|
||||
},
|
||||
onDefineModelEnter(node, model) {
|
||||
if (node.parent && node.parent.type === "VariableDeclarator" && node.parent.init === node) emitCalls.set(`update:${model.name.modelName}`, node);
|
||||
},
|
||||
...callVisitor
|
||||
}), { "Program:exit"() {
|
||||
for (const [name, emit] of emitDeclarations) if (!emitCalls.has(name) && emit.node) context.report({
|
||||
node: emit.node,
|
||||
loc: emit.node.loc,
|
||||
messageId: "unused",
|
||||
data: { name }
|
||||
});
|
||||
} });
|
||||
}
|
||||
};
|
||||
}));
|
||||
|
||||
//#endregion
|
||||
Object.defineProperty(exports, 'default', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return require_no_unused_emit_declarations();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user