Search code examples
javascriptandroidgoogle-closure-compilerduktape

Understanding Closure Compiler warnings


I am in the process of using Google's closure compiler to optimize+ obfuscate code which I run in an Android app via Duktape. I have successfully dealt with the majority of the warning messages that Closure throws back at me. However, there are a few which leave me stumped. What I should do in order to deal with them?

var Uny = 
  {"version":1, "d":new Date(), "uOff":new Date().getTimezoneOffset()*60}

accessing name Date in externs has no effect. Perhaps you forgot to add a var keyword?

This is an object I declare in the externs.js file I provide to Closure CLI.

function moreSlotsToCome(slots,ndx)
{
 var i,range;
 for(i= ndx + 1;i < slots.length;i++)
 {
  range = makeRange(slots[i]);
  if (range[0] == range[1]) break;
  return 1;
 } 
 return 0;
}

which throws up WARNING - unreachable code with the ^^^ error indicator pointing to i++ in the for loop above.

  var obj = JSON.parse(iBridge.rule()),
  keys = Object.keys(obj);

WARNING - actual parameter 1 of Object.keys does not match formal parameter
found   : *
required: Object

with the ^^^ indicator pointing to the obj in Object.keys(obj). I realize that JSON.parse() here could return null so I tried to put in an explicit test for null but that did not help.


Solution

  • WARNING - accessing name Date in externs has no effect. Perhaps you forgot to add a var keyword?

    Externs should only be type declarations. In general, they should not contain executable code (the right-hand side of an expression). Write your extern like:

    /** @const */
    var Uny = {};
    /** @type {number} */ Uny.version;
    /** @type {!Date} */ Uny.d;
    /** @type {number} */ Uny.uOff;
    

    WARNING - unreachable code

    Your loop body will only ever execute once. You have an unconditional exit return 1 so the compiler is correct, i++ will never execute. This probably shouldn't be a loop.

    WARNING - actual parameter 1 of Object.keys does not match formal parameter

    In addition to null, JSON.parse can also return primitives such as boolean, number, and string. These aren't objects and don't have keys. They are frequently promoted to an object through the concept of auto-boxing.

    If you can guaranteee that the return value is an Object, you can type cast it.

    var obj = /** @type {Object} */ (JSON.parse(iBridge.rule()))
    

    The extra parenthesis are required.