Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

100% code-coverage by removing deadcode #296

Open
kaizhu256 opened this issue May 27, 2021 · 1 comment
Open

100% code-coverage by removing deadcode #296

kaizhu256 opened this issue May 27, 2021 · 1 comment

Comments

@kaizhu256
Copy link
Member

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"
@kaizhu256
Copy link
Member Author

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);
+//              }
+//          }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
@kaizhu256 and others