blob: b11fa4b4db9c09c98bd08138d424a4447ca11661 [file] [log] [blame]
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (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 ts = __importStar(require("typescript"));
const util = __importStar(require("../util"));
const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
exports.default = util.createRule({
name: 'no-throw-literal',
meta: {
type: 'problem',
docs: {
description: 'Disallow throwing literals as exceptions',
category: 'Best Practices',
recommended: false,
requiresTypeChecking: true,
},
schema: [],
messages: {
object: 'Expected an error object to be thrown.',
undef: 'Do not throw undefined.',
},
},
defaultOptions: [],
create(context) {
const parserServices = util.getParserServices(context);
const program = parserServices.program;
const checker = program.getTypeChecker();
function isErrorLike(type) {
var _a;
if (type.isIntersection()) {
return type.types.some(isErrorLike);
}
if (type.isUnion()) {
return type.types.every(isErrorLike);
}
const symbol = type.getSymbol();
if (!symbol) {
return false;
}
if (symbol.getName() === 'Error') {
const declarations = (_a = symbol.getDeclarations()) !== null && _a !== void 0 ? _a : [];
for (const declaration of declarations) {
const sourceFile = declaration.getSourceFile();
if (program.isSourceFileDefaultLibrary(sourceFile)) {
return true;
}
}
}
if (symbol.flags & (ts.SymbolFlags.Class | ts.SymbolFlags.Interface)) {
for (const baseType of checker.getBaseTypes(type)) {
if (isErrorLike(baseType)) {
return true;
}
}
}
return false;
}
function tryGetThrowArgumentType(node) {
switch (node.type) {
case experimental_utils_1.AST_NODE_TYPES.Identifier:
case experimental_utils_1.AST_NODE_TYPES.CallExpression:
case experimental_utils_1.AST_NODE_TYPES.NewExpression:
case experimental_utils_1.AST_NODE_TYPES.MemberExpression:
case experimental_utils_1.AST_NODE_TYPES.TSAsExpression: {
const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
return checker.getTypeAtLocation(tsNode);
}
case experimental_utils_1.AST_NODE_TYPES.AssignmentExpression:
return tryGetThrowArgumentType(node.right);
case experimental_utils_1.AST_NODE_TYPES.SequenceExpression:
return tryGetThrowArgumentType(node.expressions[node.expressions.length - 1]);
case experimental_utils_1.AST_NODE_TYPES.LogicalExpression: {
const left = tryGetThrowArgumentType(node.left);
return left !== null && left !== void 0 ? left : tryGetThrowArgumentType(node.right);
}
case experimental_utils_1.AST_NODE_TYPES.ConditionalExpression: {
const consequent = tryGetThrowArgumentType(node.consequent);
return consequent !== null && consequent !== void 0 ? consequent : tryGetThrowArgumentType(node.alternate);
}
default:
return null;
}
}
function checkThrowArgument(node) {
if (node.type === experimental_utils_1.AST_NODE_TYPES.AwaitExpression ||
node.type === experimental_utils_1.AST_NODE_TYPES.YieldExpression) {
return;
}
const type = tryGetThrowArgumentType(node);
if (type) {
if (type.flags & ts.TypeFlags.Undefined) {
context.report({ node, messageId: 'undef' });
return;
}
if (util.isTypeAnyType(type) ||
util.isTypeUnknownType(type) ||
isErrorLike(type)) {
return;
}
}
context.report({ node, messageId: 'object' });
}
return {
ThrowStatement(node) {
if (node.argument) {
checkThrowArgument(node.argument);
}
},
};
},
});
//# sourceMappingURL=no-throw-literal.js.map