azu / jsdoc-to-assert

JSDoc to assert
MIT License
38 stars 4 forks source link

Issue with transpiling + destructuring #15

Open tonygentilcore opened 7 years ago

tonygentilcore commented 7 years ago

I have a class w/ destructured params in its constructor like this:

class Foo {
  /**
   * @param {?string} x - param.
   */
  constructor({x}) {
    this.x = x

My .babelrc looks like this:

{
  "presets": [["es2015", { "modules": false }], "stage-2"],
  "plugins": [
    "jsdoc-to-assert",
  ],
}

And the code is incorrectly generated like this:

var Foo = function () {
  /**
   * @param {?string} x - param.
   */
  function Foo(_ref) {
    if (!(x == null || typeof x === "string")) {
      console.assert(x == null || typeof x === "string", 'Expected type: @param {?string} x\nActual value:', x, '\nFailure assertion: (x == null || typeof x === "string")');
    }

    var x = _ref.x

NOTE The assert reads x before it's defined.

I'd expect it to be:

var Foo = function () {
  /**
   * @param {?string} x - param.
   */
  function Foo(_ref) {
    var x = _ref.x

    if (!(x == null || typeof x === "string")) {
      console.assert(x == null || typeof x === "string", 'Expected type: @param {?string} x\nActual value:', x, '\nFailure assertion: (x == null || typeof x === "string")');
    }

NOTE that the destructuring happens before the assertion. The current order would also work if the assertion were based on _ref.x instead of x.

azu commented 7 years ago

@tonygentilcore Thanks for report. I've created test case, but it will be difference result

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Foo =
/**
 * @param {?string} x - param.
 */
function Foo(_ref) {
  var x = _ref.x;

  _classCallCheck(this, Foo);

  this.x = x;
};

Maybe enabling "passPerPreset": true and it will be better.

{
  "passPerPreset": true,
  "presets": [["es2015", { "modules": false }], "stage-2"],
  "plugins": [
    "jsdoc-to-assert",
  ],
}

Result:

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Foo =
/**
 * @param {string} x
 */
function Foo(_ref) {
  var x = _ref.x;

  _classCallCheck(this, Foo);

  console.assert(typeof x === "string");

  this.x = x;
};
tonygentilcore commented 7 years ago

Unfortunately, passPerPreset didn't solve it for me. Also, the result you pasted above is different from the PR you linked to.

azu commented 7 years ago

Another snippet to use passPerPreset.

{
  "passPerPreset": true,
  "presets": [
    [
      "es2015",
      {
        "modules": false
      }
    ],
    "stage-2",
    [
      {
        "plugins": [
          "jsdoc-to-assert"
        ]
      }
    ]
  ]
}

Maybe, We should start from creating minimum reproduce repository...