loganfsmyth / babel-plugin-transform-decorators-legacy

A plugin for Babel 6 that (mostly) replicates the old decorator behavior from Babel 5
MIT License
817 stars 57 forks source link

Decorator incorrectly applies to nested class if used before export default #51

Closed quassnoi closed 7 years ago

quassnoi commented 7 years ago

If a class decorator is used before export default and the class contains a nested class definition, the decorator applies to that nested class instead.

Steps to reproduce:

package.json:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {},
  "devDependencies": {
    "babel-cli": "^6.18.0",
    "babel-plugin-transform-decorators-legacy": "^1.3.4"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

wrong.es6 (the @id decorator is applied before export default)

const id = _ => _;

class Parent {
}

@id
export default class Sample {
        method() {
                class Child extends Parent {
                }

                return Child;
        }
}

Output:

./node_modules/.bin/babel --plugins transform-decorators-legacy wrong.es6
const id = _ => _;

let Parent = class Parent {};
let Sample = class Sample {
        method() {
                var _class;

                let Child = id(_class = class Child extends Parent {}) || _class;

                return Child;
        }
};
export { Sample as default };

The decorator incorrectly applies to the nested class Child

right.es6 (the decorator is applied after export.default)

const id = _ => _;

class Parent {
}

export default @id class Sample {
        method() {
                class Child extends Parent {
                }

                return Child;
        }
}

Output:

./node_modules/.bin/babel --plugins transform-decorators-legacy right.es6
var _class;

const id = _ => _;

let Parent = class Parent {};

export default id(_class = class Sample {
        method() {
                let Child = class Child extends Parent {};

                return Child;
        }
}) || _class;

I expected transpiling wrong.es6 to either throw an error or apply @id to Parent

loganfsmyth commented 7 years ago

Thanks for the report, this is a parser issue, I've refiled in https://github.com/babel/babylon/issues/357