Name resolution bug

Posted on
  • The following module code throws an exception:

    // constructor function
    function PengMod(a) {
          // "a" will be resolved with the method a not with the locale variable a.
          console.log( a );
          if (a !== "hello" ) throw Error("Bug!");
    }
    
    // This function masks the local variable a in the constructor!!!
    PengMod.a = function () {
    };
    
    new PengMod( "hello" );
    

    The code is a snippet from a larger module which must be minified because of its size. I cannot rename the method oder variable because the names come from a minification step with name mangling. The transpiler always starts in every new scope with a, b, c, .

    Any ideas?

  • What about line 9 reading PengMod.prototype.a = function() { ...? Because the object (instance of PengMod 'class') created in line 12 will not understand method .a(). I know that there are 'tricks' to stick also properties to a function (constructor), but I'm not sure that you really want this... or do you?

    But in deed, in a 'regular' js environment it works as expected... @Gordon? ...I guess the context where Espruino tries to resolve the variable is in the function's properties rather than in the function body's scope, of which arguments is a part of... and arguments is messed up too...

    function PengMod(a) {
      console.log("arguments: ", arguments.length, arguments );
      console.log("var a: " + a );
    }
    PengMod.a = function () {
    };
    new PengMod( "hello" );  console.log("arguments: ", arguments.length, arguments );
    

    produces this console output:

     1v86 Copyright 2016 G.Williams
    >echo(0);
    arguments:  2 [
      function () {},
      "hello"
     ]
    var a: function () {}
    

    I hoped that at least arguments wasn't messed up... but may be these things are all very and intrinsicly intertwined...

  • The sample code above is the result of a two-step transpilation (TypeScript, Google Closure with advanced minification): mod.ts → mod.js → mod.min.js.

    The original TypeScript code is

    class SHT1x {
          constructor( options: SHT1xOptions, onReady?: () => void ) { … }
    
          // Propiatary CRC checksum calculation for SHTx - has nothing to do with a real CRC calculation!
          private static calculateCrcChecksum( data: number, initialCrcValue: number ): number { … }
    }        
    

    I can remove the "static" keyword but it wouldn't be 100% semantically correct because there could be more instances of SHT1x and the checksum method does not need any instance variables. Nevertheless it's a good workaround.

    Otherwise it would be good to know the origin of the problem. So the current Espruino rule to work around the bug is: Don't use class methods at all?

    I have to check other modules I contributed:

  • Wow, that's an odd one. I don't have time to sort this now but I have filed a bug: https://github.com/espruino/Espruino/iss­ues/913

    Hopefully I'll get that fixed today

  • Ok, it's more painful than I expected. See the issue above for some notes.

  • Fixed now - not ideal, but it seems to work well enough and to be least likely to break anything else.

  • Thank you for the quick solution.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Name resolution bug

Posted by Avatar for luwar @luwar

Actions