123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- "use strict";
- function isInitialized(node) {
- return Boolean(node.init);
- }
- function isUnreachable(segment) {
- return !segment.reachable;
- }
- class ConsecutiveRange {
- constructor(sourceCode) {
- this.sourceCode = sourceCode;
- this.startNode = null;
- this.endNode = null;
- }
-
- get location() {
- return {
- start: this.startNode.loc.start,
- end: this.endNode.loc.end
- };
- }
-
- get isEmpty() {
- return !(this.startNode && this.endNode);
- }
-
- contains(node) {
- return (
- node.range[0] >= this.startNode.range[0] &&
- node.range[1] <= this.endNode.range[1]
- );
- }
-
- isConsecutive(node) {
- return this.contains(this.sourceCode.getTokenBefore(node));
- }
-
- merge(node) {
- this.endNode = node;
- }
-
- reset(node) {
- this.startNode = this.endNode = node;
- }
- }
- module.exports = {
- meta: {
- type: "problem",
- docs: {
- description: "disallow unreachable code after `return`, `throw`, `continue`, and `break` statements",
- category: "Possible Errors",
- recommended: true,
- url: "https://eslint.org/docs/rules/no-unreachable"
- },
- schema: [],
- messages: {
- unreachableCode: "Unreachable code."
- }
- },
- create(context) {
- let currentCodePath = null;
- const range = new ConsecutiveRange(context.getSourceCode());
-
- function reportIfUnreachable(node) {
- let nextNode = null;
- if (node && currentCodePath.currentSegments.every(isUnreachable)) {
-
- if (range.isEmpty) {
- range.reset(node);
- return;
- }
-
- if (range.contains(node)) {
- return;
- }
-
- if (range.isConsecutive(node)) {
- range.merge(node);
- return;
- }
- nextNode = node;
- }
-
- if (!range.isEmpty) {
- context.report({
- messageId: "unreachableCode",
- loc: range.location,
- node: range.startNode
- });
- }
-
- range.reset(nextNode);
- }
- return {
-
- onCodePathStart(codePath) {
- currentCodePath = codePath;
- },
- onCodePathEnd() {
- currentCodePath = currentCodePath.upper;
- },
-
- BlockStatement: reportIfUnreachable,
- BreakStatement: reportIfUnreachable,
- ClassDeclaration: reportIfUnreachable,
- ContinueStatement: reportIfUnreachable,
- DebuggerStatement: reportIfUnreachable,
- DoWhileStatement: reportIfUnreachable,
- ExpressionStatement: reportIfUnreachable,
- ForInStatement: reportIfUnreachable,
- ForOfStatement: reportIfUnreachable,
- ForStatement: reportIfUnreachable,
- IfStatement: reportIfUnreachable,
- ImportDeclaration: reportIfUnreachable,
- LabeledStatement: reportIfUnreachable,
- ReturnStatement: reportIfUnreachable,
- SwitchStatement: reportIfUnreachable,
- ThrowStatement: reportIfUnreachable,
- TryStatement: reportIfUnreachable,
- VariableDeclaration(node) {
- if (node.kind !== "var" || node.declarations.some(isInitialized)) {
- reportIfUnreachable(node);
- }
- },
- WhileStatement: reportIfUnreachable,
- WithStatement: reportIfUnreachable,
- ExportNamedDeclaration: reportIfUnreachable,
- ExportDefaultDeclaration: reportIfUnreachable,
- ExportAllDeclaration: reportIfUnreachable,
- "Program:exit"() {
- reportIfUnreachable();
- }
- };
- }
- };
|