UNPKG

eslint-plugin-sonarjs

Version:
64 lines (63 loc) • 2.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isInsideVueSetupScript = isInsideVueSetupScript; exports.isVue2OrEarlier = isVue2OrEarlier; exports.getVueReactiveBindingKind = getVueReactiveBindingKind; const semver_1 = require("semver"); const dependencies_js_1 = require("./dependency-manifests/dependencies.js"); const ast_js_1 = require("./ast.js"); const module_js_1 = require("./module.js"); // "-0" makes the lower bound prerelease-inclusive, so an exact pin like "3.0.0-rc.13" still counts as Vue 3+ const VUE_3_OR_LATER_RANGE = '>=3.0.0-0'; const VUE_REF_FQN = 'vue.ref'; const VUE_REACTIVE_FQN = 'vue.reactive'; function isVueSetupScript(element) { return (element.type === 'VElement' && element.name === 'script' && element.startTag.attributes.some(attr => attr.key.name === 'setup')); } function isInsideVueSetupScript(node, ctx) { const doc = ctx.sourceCode.parserServices?.getDocumentFragment?.(); const setupScript = doc?.children.find(isVueSetupScript); return (!!setupScript && !!node.range && setupScript.range[0] <= node.range[0] && setupScript.range[1] >= node.range[1]); } /** Returns true when no Vue dependency is declared, or a declared parseable range provably excludes Vue 3+; an unparseable range (workspace:, catalog:, git:) keeps reporting, unlike a missing dependency. */ function isVue2OrEarlier(context) { const vueVersionRange = (0, dependencies_js_1.getVueVersion)(context); if (!vueVersionRange) { return true; } if (!(0, semver_1.validRange)(vueVersionRange)) { return false; } return !(0, semver_1.intersects)(vueVersionRange, VUE_3_OR_LATER_RANGE); } /** * Resolves `identifier` to the variable it references and, if that variable is initialized by a * call to `ref()` or `reactive()` imported from 'vue', returns which one. Used to recognize * mutations of tracked reactive state without requiring the enclosing code to be independently * proven to be a Vue component: an import-resolved `ref`/`reactive` binding is itself a strong * enough Vue signal. */ function getVueReactiveBindingKind(context, identifier) { const variable = (0, ast_js_1.getVariableFromName)(context, identifier.name, identifier); const definition = variable?.defs[0]; if (definition?.type !== 'Variable') { return undefined; } const init = definition.node.init; if (init?.type !== 'CallExpression') { return undefined; } const fqn = (0, module_js_1.getFullyQualifiedName)(context, init); if (fqn === VUE_REF_FQN) { return 'ref'; } if (fqn === VUE_REACTIVE_FQN) { return 'reactive'; } return undefined; }