mirror of
https://github.com/Sevichecc/Urara-Blog.git
synced 2025-05-02 20:09:30 +08:00
244 lines
No EOL
10 KiB
Text
244 lines
No EOL
10 KiB
Text
"use strict";
|
||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
}
|
||
Object.defineProperty(o, k2, desc);
|
||
}) : (function(o, m, k, k2) {
|
||
if (k2 === undefined) k2 = k;
|
||
o[k2] = m[k];
|
||
}));
|
||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
}) : function(o, v) {
|
||
o["default"] = v;
|
||
});
|
||
var __importStar = (this && this.__importStar) || function (mod) {
|
||
if (mod && mod.__esModule) return mod;
|
||
var result = {};
|
||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
__setModuleDefault(result, mod);
|
||
return result;
|
||
};
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const utils_1 = require("@typescript-eslint/utils");
|
||
const util = __importStar(require("../util"));
|
||
const getESLintCoreRule_1 = require("../util/getESLintCoreRule");
|
||
const baseRule = (0, getESLintCoreRule_1.getESLintCoreRule)('no-magic-numbers');
|
||
// Extend base schema with additional property to ignore TS numeric literal types
|
||
const schema = util.deepMerge(
|
||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- https://github.com/microsoft/TypeScript/issues/17002
|
||
Array.isArray(baseRule.meta.schema)
|
||
? baseRule.meta.schema[0]
|
||
: baseRule.meta.schema, {
|
||
properties: {
|
||
ignoreNumericLiteralTypes: {
|
||
type: 'boolean',
|
||
},
|
||
ignoreEnums: {
|
||
type: 'boolean',
|
||
},
|
||
ignoreReadonlyClassProperties: {
|
||
type: 'boolean',
|
||
},
|
||
ignoreTypeIndexes: {
|
||
type: 'boolean',
|
||
},
|
||
},
|
||
});
|
||
exports.default = util.createRule({
|
||
name: 'no-magic-numbers',
|
||
meta: {
|
||
type: 'suggestion',
|
||
docs: {
|
||
description: 'Disallow magic numbers',
|
||
recommended: false,
|
||
extendsBaseRule: true,
|
||
},
|
||
schema: [schema],
|
||
messages: baseRule.meta.messages,
|
||
},
|
||
defaultOptions: [
|
||
{
|
||
ignore: [],
|
||
ignoreArrayIndexes: false,
|
||
enforceConst: false,
|
||
detectObjects: false,
|
||
ignoreNumericLiteralTypes: false,
|
||
ignoreEnums: false,
|
||
ignoreReadonlyClassProperties: false,
|
||
},
|
||
],
|
||
create(context, [options]) {
|
||
const rules = baseRule.create(context);
|
||
return {
|
||
Literal(node) {
|
||
var _a;
|
||
// If it’s not a numeric literal we’re not interested
|
||
if (typeof node.value !== 'number' && typeof node.value !== 'bigint') {
|
||
return;
|
||
}
|
||
// This will be `true` if we’re configured to ignore this case (eg. it’s
|
||
// an enum and `ignoreEnums` is `true`). It will be `false` if we’re not
|
||
// configured to ignore this case. It will remain `undefined` if this is
|
||
// not one of our exception cases, and we’ll fall back to the base rule.
|
||
let isAllowed;
|
||
// Check if the node is a TypeScript enum declaration
|
||
if (isParentTSEnumDeclaration(node)) {
|
||
isAllowed = options.ignoreEnums === true;
|
||
}
|
||
// Check TypeScript specific nodes for Numeric Literal
|
||
else if (isTSNumericLiteralType(node)) {
|
||
isAllowed = options.ignoreNumericLiteralTypes === true;
|
||
}
|
||
// Check if the node is a type index
|
||
else if (isAncestorTSIndexedAccessType(node)) {
|
||
isAllowed = options.ignoreTypeIndexes === true;
|
||
}
|
||
// Check if the node is a readonly class property
|
||
else if (isParentTSReadonlyPropertyDefinition(node)) {
|
||
isAllowed = options.ignoreReadonlyClassProperties === true;
|
||
}
|
||
// If we’ve hit a case where the ignore option is true we can return now
|
||
if (isAllowed === true) {
|
||
return;
|
||
}
|
||
// If the ignore option is *not* set we can report it now
|
||
else if (isAllowed === false) {
|
||
let fullNumberNode = node;
|
||
let raw = node.raw;
|
||
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.UnaryExpression &&
|
||
// the base rule only shows the operator for negative numbers
|
||
// https://github.com/eslint/eslint/blob/9dfc8501fb1956c90dc11e6377b4cb38a6bea65d/lib/rules/no-magic-numbers.js#L126
|
||
node.parent.operator === '-') {
|
||
fullNumberNode = node.parent;
|
||
raw = `${node.parent.operator}${node.raw}`;
|
||
}
|
||
context.report({
|
||
messageId: 'noMagic',
|
||
node: fullNumberNode,
|
||
data: { raw },
|
||
});
|
||
return;
|
||
}
|
||
// Let the base rule deal with the rest
|
||
rules.Literal(node);
|
||
},
|
||
};
|
||
},
|
||
});
|
||
/**
|
||
* Gets the true parent of the literal, handling prefixed numbers (-1 / +1)
|
||
*/
|
||
function getLiteralParent(node) {
|
||
var _a;
|
||
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.UnaryExpression &&
|
||
['-', '+'].includes(node.parent.operator)) {
|
||
return node.parent.parent;
|
||
}
|
||
return node.parent;
|
||
}
|
||
/**
|
||
* Checks if the node grandparent is a Typescript type alias declaration
|
||
* @param node the node to be validated.
|
||
* @returns true if the node grandparent is a Typescript type alias declaration
|
||
* @private
|
||
*/
|
||
function isGrandparentTSTypeAliasDeclaration(node) {
|
||
var _a, _b;
|
||
return ((_b = (_a = node.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.type) === utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration;
|
||
}
|
||
/**
|
||
* Checks if the node grandparent is a Typescript union type and its parent is a type alias declaration
|
||
* @param node the node to be validated.
|
||
* @returns true if the node grandparent is a Typescript union type and its parent is a type alias declaration
|
||
* @private
|
||
*/
|
||
function isGrandparentTSUnionType(node) {
|
||
var _a, _b;
|
||
if (((_b = (_a = node.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.type) === utils_1.AST_NODE_TYPES.TSUnionType) {
|
||
return isGrandparentTSTypeAliasDeclaration(node.parent);
|
||
}
|
||
return false;
|
||
}
|
||
/**
|
||
* Checks if the node parent is a Typescript enum member
|
||
* @param node the node to be validated.
|
||
* @returns true if the node parent is a Typescript enum member
|
||
* @private
|
||
*/
|
||
function isParentTSEnumDeclaration(node) {
|
||
const parent = getLiteralParent(node);
|
||
return (parent === null || parent === void 0 ? void 0 : parent.type) === utils_1.AST_NODE_TYPES.TSEnumMember;
|
||
}
|
||
/**
|
||
* Checks if the node parent is a Typescript literal type
|
||
* @param node the node to be validated.
|
||
* @returns true if the node parent is a Typescript literal type
|
||
* @private
|
||
*/
|
||
function isParentTSLiteralType(node) {
|
||
var _a;
|
||
return ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.TSLiteralType;
|
||
}
|
||
/**
|
||
* Checks if the node is a valid TypeScript numeric literal type.
|
||
* @param node the node to be validated.
|
||
* @returns true if the node is a TypeScript numeric literal type.
|
||
* @private
|
||
*/
|
||
function isTSNumericLiteralType(node) {
|
||
var _a;
|
||
// For negative numbers, use the parent node
|
||
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.UnaryExpression &&
|
||
node.parent.operator === '-') {
|
||
node = node.parent;
|
||
}
|
||
// If the parent node is not a TSLiteralType, early return
|
||
if (!isParentTSLiteralType(node)) {
|
||
return false;
|
||
}
|
||
// If the grandparent is a TSTypeAliasDeclaration, ignore
|
||
if (isGrandparentTSTypeAliasDeclaration(node)) {
|
||
return true;
|
||
}
|
||
// If the grandparent is a TSUnionType and it's parent is a TSTypeAliasDeclaration, ignore
|
||
if (isGrandparentTSUnionType(node)) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
/**
|
||
* Checks if the node parent is a readonly class property
|
||
* @param node the node to be validated.
|
||
* @returns true if the node parent is a readonly class property
|
||
* @private
|
||
*/
|
||
function isParentTSReadonlyPropertyDefinition(node) {
|
||
const parent = getLiteralParent(node);
|
||
if ((parent === null || parent === void 0 ? void 0 : parent.type) === utils_1.AST_NODE_TYPES.PropertyDefinition && parent.readonly) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
/**
|
||
* Checks if the node is part of a type indexed access (eg. Foo[4])
|
||
* @param node the node to be validated.
|
||
* @returns true if the node is part of an indexed access
|
||
* @private
|
||
*/
|
||
function isAncestorTSIndexedAccessType(node) {
|
||
var _a, _b, _c;
|
||
// Handle unary expressions (eg. -4)
|
||
let ancestor = getLiteralParent(node);
|
||
// Go up another level while we’re part of a type union (eg. 1 | 2) or
|
||
// intersection (eg. 1 & 2)
|
||
while (((_a = ancestor === null || ancestor === void 0 ? void 0 : ancestor.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.TSUnionType ||
|
||
((_b = ancestor === null || ancestor === void 0 ? void 0 : ancestor.parent) === null || _b === void 0 ? void 0 : _b.type) === utils_1.AST_NODE_TYPES.TSIntersectionType) {
|
||
ancestor = ancestor.parent;
|
||
}
|
||
return ((_c = ancestor === null || ancestor === void 0 ? void 0 : ancestor.parent) === null || _c === void 0 ? void 0 : _c.type) === utils_1.AST_NODE_TYPES.TSIndexedAccessType;
|
||
}
|
||
//# sourceMappingURL=no-magic-numbers.js.map |