madskristensen / WebEssentials2012

http://vswebessentials.com
Other
95 stars 46 forks source link

Invalid squashing of ELSE clause followed by a block comment with conditional-compilation directives #84

Open quetzalcoatl opened 9 years ago

quetzalcoatl commented 9 years ago

I'm using VisualStudio plugin version 3.8, the current one at the time of writing this.

I've been trying to user minimifier on Handsontable.js version 0.12.2 (not the current 0.12.4 one) (https://github.com/handsontable/handsontable/blob/eaa761856b524c64687b44452b4b7b6e9d072d0a/dist/handsontable.full.js)

In one part of this library, there's a keydownListener declaration preceded by a small IF with ELSE with block-comment inside:

(......line 7714....)
  if (typeof style.opacity !== 'undefined') {
    style.opacity = 0;
  }
  else {
    /*@cc_on @if (@_jscript)
     if(typeof style.filter === 'string') {
     style.filter = 'alpha(opacity=0)';
     }
     @end @*/
  }
}

this.keydownListener = function (event) {
  var isCtrlDown = false;
  if (event.metaKey) { //mac
    isCtrlDown = true;
  }
(......)

When processed with minifier into a .min.js, the process:

The result is similar to:

else /*@cc_on @if (@_jscript) ........... @end @*/ this.keydownListener = function (event) {

Please note that when first brackets were removed from the ELSE and when the comment was squashed, the minifier forgot to include a semicolon that would terminate the ELSE clause.

Effectively, the resulting expression pulls the this.keydownListener into the ELSE, which, well, breaks some things in the handsontable library, but that's not the point.

Summarizing, there's an invalid transformation:

else { /* barr */ }    ->        else  /* barr */

BTW. I fixed the issue locally by changing the source script to:

  if (typeof style.opacity !== 'undefined') {
    style.opacity = 0;
  }
  else {
    /*@cc_on @if (@_jscript)
     if(typeof style.filter === 'string') {
     style.filter = 'alpha(opacity=0)';
     }
     @end @*/
     void 0;
  }
}

in this case, the minifier outputs something like:

else{/*@cc_on @if (@_jscript) ........... @end @*/ void 0;} this.keydownListener = 

as you see, some trash is left, but braces are preserved and the tail is not pulled into ELSE, so I'm pretty sure it's all only about else, brace, and block-comment.