lautis / uglifier

Ruby wrapper for UglifyJS JavaScript compressor.
http://www.rubydoc.info/gems/uglifier
MIT License
613 stars 82 forks source link

Return statement is wrong #93

Open joker-777 opened 8 years ago

joker-777 commented 8 years ago

Hi,

I use uglifier with Rails and have the following function which is minified incorrectly coffeescript:

_is_selected = (tags, slug) ->
  _.find(tags, slug: slug)?.selected

javascript:

_is_selected = function(tags, slug) {
  var ref;
  return (ref = _.find(tags, {
    slug: slug
  })) != null ? ref.selected : void 0;
};

and this is how it looks minified

n=function(e,n){
var r;
return

null!=(r=t.find(e,{slug:n}))?r.selected:void 0}

The problem is this lonely return statement which return immediately. It works when I write

n=function(e,n){
var r;
return null!=(r=t.find(e,{slug:n}))?r.selected:void 0}

It also minifies it correctly when I put a line before the code. For example

_is_selected = (tags, slug) ->
  bla = "a line of code"
  _.find(tags, slug: slug)?.selected

I also just updated to 3.0.0 and had the same problem again

joker-777 commented 8 years ago

Hi, I now experienced the same problem again but in a different context. This time totally unrelated to coffeescript. This javascript code

function createUnionTypeChecker(arrayOfTypeCheckers) {
  if (!Array.isArray(arrayOfTypeCheckers)) {
    return createChainableTypeChecker(function () {
      return new Error('Invalid argument supplied to oneOfType, expected an instance of array.');
    });
  }

  function validate(props, propName, componentName, location, propFullName) {
    for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
      var checker = arrayOfTypeCheckers[i];
      if (checker(props, propName, componentName, location, propFullName) == null) {
        return null;
      }
    }

    var locationName = ReactPropTypeLocationNames[location];
    return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.'));
  }
  return createChainableTypeChecker(validate);
}

gets minified to

function d(e){

function t(t,n,r,i,o){
for(var a=0;a<e.length;a++){
var s=e[a];
if(null==s(t,n,r,i,o))
return null}

var u=y[i];
return new Error("Invalid "+u+" `"+o+"` supplied to "+("`"+r+"`."))}return

r(Array.isArray(e)?t:function(){return new Error("Invalid argument supplied to oneOfType, expected an instance of array.")})}

The problem is the last return statement which is not at the same line as r(..). This function then return undefined instead of the return value of r(..).

joker-777 commented 8 years ago

IMPORTANT: We use the option :preserve_line => true. Removing this option fixes this error. How can we keep this option?

alexlamsl commented 6 years ago

Fix released in uglify-js@3.4.5