Fix decorators interop bug with class field tdz

Co-authored-by: Jan Buschtöns <jan@buschtoens.me>
This commit is contained in:
Mauro Bringolf 2018-03-03 10:46:34 +01:00 committed by Nicolò Ribaudo
parent de16ac08be
commit 427aff559f
4 changed files with 57 additions and 3 deletions

View File

@ -39,7 +39,10 @@ export default declare((api, options) => {
const classFieldDefinitionEvaluationTDZVisitor = traverse.visitors.merge([ const classFieldDefinitionEvaluationTDZVisitor = traverse.visitors.merge([
{ {
ReferencedIdentifier(path) { ReferencedIdentifier(path) {
if (this.classRef === path.scope.getBinding(path.node.name)) { if (
this.classBinding &&
this.classBinding === path.scope.getBinding(path.node.name)
) {
const classNameTDZError = this.file.addHelper("classNameTDZError"); const classNameTDZError = this.file.addHelper("classNameTDZError");
const throwNode = t.callExpression(classNameTDZError, [ const throwNode = t.callExpression(classNameTDZError, [
t.stringLiteral(path.node.name), t.stringLiteral(path.node.name),
@ -312,7 +315,6 @@ export default declare((api, options) => {
if (!props.length) return; if (!props.length) return;
let ref; let ref;
if (path.isClassExpression() || !path.node.id) { if (path.isClassExpression() || !path.node.id) {
nameFunction(path); nameFunction(path);
ref = path.scope.generateUidIdentifier("class"); ref = path.scope.generateUidIdentifier("class");
@ -327,7 +329,8 @@ export default declare((api, options) => {
for (const computedPath of computedPaths) { for (const computedPath of computedPaths) {
computedPath.traverse(classFieldDefinitionEvaluationTDZVisitor, { computedPath.traverse(classFieldDefinitionEvaluationTDZVisitor, {
classRef: path.scope.getBinding(ref.name), classBinding:
path.node.id && path.scope.getBinding(path.node.id.name),
file: this.file, file: this.file,
}); });

View File

@ -0,0 +1,7 @@
function dec() {}
class A {
@dec a;
[Symbol.search]() {}
}

View File

@ -0,0 +1,7 @@
{
"plugins": [
["proposal-decorators", { "legacy": true }],
["proposal-class-properties", { "loose": true }],
"transform-classes"
]
}

View File

@ -0,0 +1,37 @@
var _class, _descriptor, _class2, _Symbol$search, _temp;
function _initializerDefineProperty(target, property, descriptor, context) { if (!descriptor) return; Object.defineProperty(target, property, { enumerable: descriptor.enumerable, configurable: descriptor.configurable, writable: descriptor.writable, value: descriptor.initializer ? descriptor.initializer.call(context) : void 0 }); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc; }
function _initializerWarningHelper(descriptor, context) { throw new Error('Decorating class property failed. Please ensure that ' + 'proposal-class-properties is enabled and set to use loose mode. ' + 'To use proposal-class-properties in spec mode with decorators, wait for ' + 'the next major version of decorators in stage 2.'); }
function dec() {}
let A = (_class = (_temp = (_Symbol$search = Symbol.search, _class2 =
/*#__PURE__*/
function () {
"use strict";
function A() {
_classCallCheck(this, A);
_initializerDefineProperty(this, "a", _descriptor, this);
}
_createClass(A, [{
key: _Symbol$search,
value: function () {}
}]);
return A;
}()), _temp), (_descriptor = _applyDecoratedDescriptor(_class.prototype, "a", [dec], {
enumerable: true,
initializer: null
})), _class);