jslint-org / jslint

JSLint, The JavaScript Code Quality and Coverage Tool

Home Page:https://www.jslint.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

100% code-coverage by removing deadcode

kaizhu256 opened this issue · comments

in commit a422783,

the following snippets appear to be deadcode. they will be replaced with internal-assertions just in case they're actually reachable. if anyone can figure out some weird javascript-code that can reach the branches below, please let me know, so i can add extra coverage tests!

diff --git a/jslint.js b/jslint.js
index 141f38f..65c6d7e 100755
--- a/jslint.js
+++ b/jslint.js
@@ -2062,9 +2062,10 @@ function are_similar(a, b) {

 // cause: "0&&0"

-    if (a === b) {
-        return true;
-    }
+    assert_or_throw(a !== b, "Expected a !== b.");
+//  if (a === b) {
+//      return true;
+//  }
     if (Array.isArray(a)) {
         return (
             Array.isArray(b)
@@ -2077,9 +2078,10 @@ function are_similar(a, b) {
             })
         );
     }
-    if (Array.isArray(b)) {
-        return false;
-    }
+    assert_or_throw(!Array.isArray(b), "Expected !Array.isArray(b).");
+//  if (Array.isArray(b)) {
+//      return false;
+//  }
     if (a.id === "(number)" && b.id === "(number)") {
         return a.value === b.value;
     }
@@ -2102,16 +2104,25 @@ function are_similar(a, b) {
         return false;
     }
     if (a.arity === b.arity && a.id === b.id) {
+
+// cause: "aa.bb&&aa.bb"
+
         if (a.id === ".") {
             return (
                 are_similar(a.expression, b.expression)
                 && are_similar(a.name, b.name)
             );
         }
+
+// cause: "+0&&+0"
+
         if (a.arity === "unary") {
             return are_similar(a.expression, b.expression);
         }
         if (a.arity === "binary") {
+
+// cause: "aa[0]&&aa[0]"
+
             return (
                 a.id !== "("
                 && are_similar(a.expression[0], b.expression[0])
@@ -2128,9 +2139,13 @@ function are_similar(a, b) {
                 && are_similar(a.expression[2], b.expression[2])
             );
         }
-        if (a.arity === "function" && a.arity === "regexp") {
-            return false;
-        }
+        assert_or_throw(
+            a.arity !== "function" && a.arity !== "regexp",
+            "Expected a.arity !== \"function\" && a.arity !== \"regexp\"."
+        );
+//      if (a.arity === "function" && a.arity === "regexp") {
+//          return false;
+//      }

 // cause: "undefined&&undefined"

here is diff-comparison of the 12 places where "deadcode" was replaced with assertion-checks in jslint to get full-code-coverage @
https://github.com/jslint-org/jslint/compare/v2020.11.6..v2021.5.30#diff-4822639e8179a5188bdfd8cfb48d9e103a7dcc1f2b1036465ab7017d4166c2a8

the purpose of this issue is to track regression/blame in case any of the deadcode raises assertion-check (and turns out not be dead afterall).

diff --git a/jslint.js b/jslint.js
old mode 100644
new mode 100755
index 4f365ef..3fc58fa
--- a/jslint.js
+++ b/jslint.js
@@ -561,7 +557,28 @@ function warn_at(code, line, column, a, b, c, d) {
     if (d !== undefined) {
         warning.d = d;
     }
-    warning.message = supplant(bundle[code] || code, warning);
+    warning.message = bundle[code].replace(rx_supplant, function (
+        ignore,
+        filling
+    ) {
+        assert_or_throw(
+            warning[filling] !== undefined,
+            "Expected warning[filling] !== undefined."
+        );
+//      Probably deadcode.
+//      return (
+//          replacement !== undefined
+//          ? replacement
+//          : found
+//      );
+        return warning[filling];
+    });
@@ -880,21 +926,27 @@ function tokenize(source) {
                     typeof allowed === "boolean"
                     || typeof allowed === "object"
                 ) {
-                    if (
-                        value === ""
-                        || value === "true"
-                        || value === undefined
-                    ) {
+                    if (value === "true" || value === undefined) {
                         option[name] = true;
                         if (Array.isArray(allowed)) {
                             populate(allowed, declared_globals, false);
                         }
-                    } else if (value === "false") {
-                        option[name] = false;
                     } else {
-                        warn("bad_option_a", the_comment, name + ":" + value);
+                        assert_or_throw(
+                            value === "false",
+                            `Expected value === "false".`
+                        );
+                        option[name] = false;
+//                  Probably deadcode.
+//                  } else if (value === "false") {
+//                      option[name] = false;
+//                  } else {
+//                      warn("bad_option_a", the_comment, name + ":" + value);
                     }
                 } else {
@@ -1045,54 +1124,68 @@ function tokenize(source) {
         }

         function choice() {
+            let follow;

-            function group() {
+// Parse sequence of characters in regexp.
+
+            while (true) {
+                switch (char) {
+                case "":
+                case "/":
+                case "]":
+                case ")":
+                    if (!follow) {
+
+// cause: "/ /"
+
+                        warn_at("expected_regexp_factor_a", line, column, char);
+                    }
+
+// Match a choice (a sequence that can be followed by | and another choice).
+
+                    assert_or_throw(
+                        !(char === "|"),
+                        `Expected !(char === "|").`
+                    );
+//                  Probably deadcode.
+//                  if (char === "|") {
+//                      next_char("|");
+//                      return choice();
+//                  }
+                    return;
+                case "(":
@@ -1937,21 +2155,31 @@ function is_weird(thing) {
 }

 function are_similar(a, b) {
-    if (a === b) {
-        return true;
-    }
+
+// cause: "0&&0"
+
+    assert_or_throw(!(a === b), `Expected !(a === b).`);
+//  Probably deadcode.
+//  if (a === b) {
+//      return true;
+//  }
     if (Array.isArray(a)) {
         return (
             Array.isArray(b)
             && a.length === b.length
             && a.every(function (value, index) {
+
+// cause: "`${0}`&&`${0}`"
+
                 return are_similar(value, b[index]);
             })
         );
     }
-    if (Array.isArray(b)) {
-        return false;
-    }
+    assert_or_throw(!Array.isArray(b), `Expected !Array.isArray(b).`);
+//  Probably deadcode.
+//  if (Array.isArray(b)) {
+//      return false;
+//  }
     if (a.id === "(number)" && b.id === "(number)") {
         return a.value === b.value;
     }
@@ -1991,17 +2228,31 @@ function are_similar(a, b) {
             );
         }
         if (a.arity === "ternary") {
+
+// cause: "aa=(``?``:``)&&(``?``:``)"
+
             return (
                 are_similar(a.expression[0], b.expression[0])
                 && are_similar(a.expression[1], b.expression[1])
                 && are_similar(a.expression[2], b.expression[2])
             );
         }
-        if (a.arity === "function" && a.arity === "regexp") {
-            return false;
-        }
+        assert_or_throw(
+            !(a.arity === "function" || a.arity === "regexp"),
+            `Expected !(a.arity === "function" || a.arity === "regexp").`
+        );
+//      Probably deadcode.
+//      if (a.arity === "function" || a.arity === "regexp") {
+//          return false;
+//      }
@@ -2913,14 +3327,19 @@ function do_function(the_function) {
         name = the_function.name;
     }
     the_function.level = functionage.level + 1;
-    if (mega_mode) {
-        warn("unexpected_a", the_function);
-    }
+    assert_or_throw(!mega_mode, `Expected !mega_mode.`);
+//  Probably deadcode.
+//  if (mega_mode) {
+//      warn("unexpected_a", the_function);
+//  }

 // Don't make functions in loops. It is inefficient, and it can lead to scoping
 // errors.

     if (functionage.loop > 0) {
@@ -4024,21 +4817,25 @@ function pop_block() {
     blockage = block_stack.pop();
 }

-function activate(name) {
-    name.dead = false;
-    if (name.expression !== undefined) {
-        walk_expression(name.expression);
-        if (name.id === "{" || name.id === "[") {
-            name.names.forEach(subactivate);
-        } else {
+function action_var(thing) {
+    thing.names.forEach(function (name) {
+        name.dead = false;
+        if (name.expression !== undefined) {
+            walk_expression(name.expression);
+            assert_or_throw(
+                !(name.id === "{" || name.id === "["),
+                `Expected !(name.id === "{" || name.id === "[").`
+            );
+//          Probably deadcode.
+//          if (name.id === "{" || name.id === "[") {
+//              name.names.forEach(subactivate);
+//          } else {
+//              name.init = true;
+//          }
             name.init = true;
         }
@@ -4182,11 +5004,20 @@ postaction("assignment", function (thing) {
     const lvalue = thing.expression[0];
     if (thing.id === "=") {
         if (thing.names !== undefined) {
-            if (Array.isArray(thing.names)) {
-                thing.names.forEach(init_variable);
-            } else {
-                init_variable(thing.names);
-            }
+
+// cause: "if(0){aa=0}"
+
+            assert_or_throw(
+                !Array.isArray(thing.names),
+                `Expected !Array.isArray(thing.names).`
+            );
+//          Probably deadcode.
+//          if (Array.isArray(thing.names)) {
+//              thing.names.forEach(init_variable);
+//          } else {
+//              init_variable(thing.names);
+//          }
+            init_variable(thing.names);
         } else {
             if (lvalue.id === "[" || lvalue.id === "{") {
                 lvalue.expression.forEach(function (thing) {
@@ -4533,19 +5463,37 @@ function delve(the_function) {
         if (id !== "ignore") {
             const name = the_function.context[id];
             if (name.parent === the_function) {
+
+// cause: "let aa=function bb(){return;};"
+
                 if (
                     name.used === 0
-                    && (
-                        name.role !== "function"
-                        || name.parent.arity !== "unary"
+                    && assert_or_throw(
+                        name.role !== "function",
+                        `Expected name.role !== "function".`
                     )
+//                  Probably deadcode.
+//                  && (
+//                      name.role !== "function"
+//                      || name.parent.arity !== "unary"
+//                  )
                 ) {
@@ -4593,12 +5561,23 @@ function whitage() {
     }

     function expected_at(at) {
+        assert_or_throw(
+            !(right === undefined),
+            `Expected !(right === undefined).`
+        );
+//      Probably deadcode.
+//      if (right === undefined) {
+//          right = next_token;
+//      }
         warn(
             "expected_a_at_b_c",
             right,
             artifact(right),
             fudge + at,
@@ -4638,19 +5653,42 @@ function whitage() {
                 );
             }
         } else {
-            if (open) {
-                const at = (
-                    free
-                    ? margin
-                    : margin + 8
-                );
-                if (right.from < at) {
-                    expected_at(at);
-                }
-            } else {
-                if (right.from !== margin + 8) {
-                    expected_at(margin + 8);
-                }
+
+// from:
+//                  } else if (
+//                      right.arity === "binary"
+//                      && right.id === "("
+//                      && free
+//                  ) {
+//                      no_space();
+//                  } else if (
+
+            assert_or_throw(open, `Expected open.`);
+            assert_or_throw(free, `Expected free.`);
+//          Probably deadcode.
+//          if (open) {
+//              const at = (
+//                  free
+//                  ? margin
+//                  : margin + 8
+//              );
+//              if (right.from < at) {
+//                  expected_at(at);
+//              }
+//          } else {
+//              if (right.from !== margin + 8) {
+//                  expected_at(margin + 8);
+//              }
+//          }