diff --git a/packages/babel-generator/src/generators/expressions.ts b/packages/babel-generator/src/generators/expressions.ts index 9ff9c6db032e..10b382f4e3ab 100644 --- a/packages/babel-generator/src/generators/expressions.ts +++ b/packages/babel-generator/src/generators/expressions.ts @@ -131,14 +131,13 @@ function isDecoratorMemberExpression( function shouldParenthesizeDecoratorExpression( node: t.Expression | t.Super | t.V8IntrinsicIdentifier, ) { - if (node.type === "CallExpression") { - node = node.callee; - } if (node.type === "ParenthesizedExpression") { // We didn't check extra?.parenthesized here because we don't track decorators in needsParen return false; } - return !isDecoratorMemberExpression(node); + return !isDecoratorMemberExpression( + node.type === "CallExpression" ? node.callee : node, + ); } export function Decorator(this: Printer, node: t.Decorator) { diff --git a/packages/babel-generator/test/fixtures/decorators/decorator-parenthesized-expression-createParenthesizedExpression/input.js b/packages/babel-generator/test/fixtures/decorators/decorator-parenthesized-expression-createParenthesizedExpression/input.js index 8cec169bc925..52a448176dfa 100644 --- a/packages/babel-generator/test/fixtures/decorators/decorator-parenthesized-expression-createParenthesizedExpression/input.js +++ b/packages/babel-generator/test/fixtures/decorators/decorator-parenthesized-expression-createParenthesizedExpression/input.js @@ -9,7 +9,6 @@ class C extends class {} { @(this.dec) @(super.dec) @(new DecFactory) - @(decs[three])() p; } @@ -20,6 +19,11 @@ class C extends class {} { p; } + class ShouldAddParens { + @(decs[three])() + p; + } + class WillPreserveParens { @(decs) @(decs.one) diff --git a/packages/babel-generator/test/fixtures/decorators/decorator-parenthesized-expression-createParenthesizedExpression/output.js b/packages/babel-generator/test/fixtures/decorators/decorator-parenthesized-expression-createParenthesizedExpression/output.js index a3e2fb794feb..05b8e9379125 100644 --- a/packages/babel-generator/test/fixtures/decorators/decorator-parenthesized-expression-createParenthesizedExpression/output.js +++ b/packages/babel-generator/test/fixtures/decorators/decorator-parenthesized-expression-createParenthesizedExpression/output.js @@ -10,7 +10,6 @@ class C extends class {} { @(this.dec) @(super.dec) @(new DecFactory()) - @(decs[three])() p; } @@ -21,6 +20,11 @@ class C extends class {} { p; } + class ShouldAddParens { + @((decs[three])()) + p; + } + class WillPreserveParens { @(decs) @(decs.one) diff --git a/packages/babel-helpers/src/helpers-generated.ts b/packages/babel-helpers/src/helpers-generated.ts index d40d731026b9..facb5286bc61 100644 --- a/packages/babel-helpers/src/helpers-generated.ts +++ b/packages/babel-helpers/src/helpers-generated.ts @@ -15,7 +15,11 @@ function helper(minVersion: string, source: string) { export default Object.freeze({ applyDecs: helper( "7.17.8", - 'function createMetadataMethodsForProperty(metadataMap,kind,property,decoratorFinishedRef){return{getMetadata:function(key){assertNotFinished(decoratorFinishedRef,"getMetadata"),assertMetadataKey(key);var metadataForKey=metadataMap[key];if(void 0!==metadataForKey)if(1===kind){var pub=metadataForKey.public;if(void 0!==pub)return pub[property]}else if(2===kind){var priv=metadataForKey.private;if(void 0!==priv)return priv.get(property)}else if(Object.hasOwnProperty.call(metadataForKey,"constructor"))return metadataForKey.constructor},setMetadata:function(key,value){assertNotFinished(decoratorFinishedRef,"setMetadata"),assertMetadataKey(key);var metadataForKey=metadataMap[key];if(void 0===metadataForKey&&(metadataForKey=metadataMap[key]={}),1===kind){var pub=metadataForKey.public;void 0===pub&&(pub=metadataForKey.public={}),pub[property]=value}else if(2===kind){var priv=metadataForKey.priv;void 0===priv&&(priv=metadataForKey.private=new Map),priv.set(property,value)}else metadataForKey.constructor=value}}}function convertMetadataMapToFinal(obj,metadataMap){var parentMetadataMap=obj[Symbol.metadata||Symbol.for("Symbol.metadata")],metadataKeys=Object.getOwnPropertySymbols(metadataMap);if(0!==metadataKeys.length){for(var i=0;i=0;i--){var newInit;if(void 0!==(newValue=memberDec(decs[i],name,desc,metadataMap,initializers,kind,isStatic,isPrivate,value)))assertValidReturnValue(kind,newValue),0===kind?newInit=newValue:1===kind?(newInit=getInit(newValue),get=newValue.get||value.get,set=newValue.set||value.set,value={get:get,set:set}):value=newValue,void 0!==newInit&&(void 0===initializer?initializer=newInit:"function"==typeof initializer?initializer=[initializer,newInit]:initializer.push(newInit))}if(0===kind||1===kind){if(void 0===initializer)initializer=function(instance,init){return init};else if("function"!=typeof initializer){var ownInitializers=initializer;initializer=function(instance,init){for(var value=init,i=0;i3,isStatic=kind>=5;if(isStatic?(base=Class,metadataMap=staticMetadataMap,0!==(kind-=5)&&(initializers=staticInitializers=staticInitializers||[])):(base=Class.prototype,metadataMap=protoMetadataMap,0!==kind&&(initializers=protoInitializers=protoInitializers||[])),0!==kind&&!isPrivate){var existingNonFields=isStatic?existingStaticNonFields:existingProtoNonFields,existingKind=existingNonFields.get(name)||0;if(!0===existingKind||3===existingKind&&4!==kind||4===existingKind&&3!==kind)throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: "+name);!existingKind&&kind>2?existingNonFields.set(name,kind):existingNonFields.set(name,!0)}applyMemberDec(ret,base,decInfo,name,kind,isStatic,isPrivate,metadataMap,initializers)}}pushInitializers(ret,protoInitializers),pushInitializers(ret,staticInitializers)}function pushInitializers(ret,initializers){initializers&&ret.push((function(instance){for(var i=0;i0){for(var initializers=[],newClass=targetClass,name=targetClass.name,i=classDecs.length-1;i>=0;i--){var decoratorFinishedRef={v:!1};try{var ctx=Object.assign({kind:"class",name:name,addInitializer:createAddInitializerMethod(initializers,decoratorFinishedRef)},createMetadataMethodsForProperty(metadataMap,0,name,decoratorFinishedRef)),nextNewClass=classDecs[i](newClass,ctx)}finally{decoratorFinishedRef.v=!0}void 0!==nextNewClass&&(assertValidReturnValue(10,nextNewClass),newClass=nextNewClass)}ret.push(newClass,(function(){for(var i=0;i=0;i--){var newInit;if(void 0!==(newValue=old_memberDec(decs[i],name,desc,metadataMap,initializers,kind,isStatic,isPrivate,value)))old_assertValidReturnValue(kind,newValue),0===kind?newInit=newValue:1===kind?(newInit=old_getInit(newValue),get=newValue.get||value.get,set=newValue.set||value.set,value={get:get,set:set}):value=newValue,void 0!==newInit&&(void 0===initializer?initializer=newInit:"function"==typeof initializer?initializer=[initializer,newInit]:initializer.push(newInit))}if(0===kind||1===kind){if(void 0===initializer)initializer=function(instance,init){return init};else if("function"!=typeof initializer){var ownInitializers=initializer;initializer=function(instance,init){for(var value=init,i=0;i3,isStatic=kind>=5;if(isStatic?(base=Class,metadataMap=staticMetadataMap,0!==(kind-=5)&&(initializers=staticInitializers=staticInitializers||[])):(base=Class.prototype,metadataMap=protoMetadataMap,0!==kind&&(initializers=protoInitializers=protoInitializers||[])),0!==kind&&!isPrivate){var existingNonFields=isStatic?existingStaticNonFields:existingProtoNonFields,existingKind=existingNonFields.get(name)||0;if(!0===existingKind||3===existingKind&&4!==kind||4===existingKind&&3!==kind)throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: "+name);!existingKind&&kind>2?existingNonFields.set(name,kind):existingNonFields.set(name,!0)}old_applyMemberDec(ret,base,decInfo,name,kind,isStatic,isPrivate,metadataMap,initializers)}}old_pushInitializers(ret,protoInitializers),old_pushInitializers(ret,staticInitializers)}function old_pushInitializers(ret,initializers){initializers&&ret.push((function(instance){for(var i=0;i0){for(var initializers=[],newClass=targetClass,name=targetClass.name,i=classDecs.length-1;i>=0;i--){var decoratorFinishedRef={v:!1};try{var ctx=Object.assign({kind:"class",name:name,addInitializer:old_createAddInitializerMethod(initializers,decoratorFinishedRef)},old_createMetadataMethodsForProperty(metadataMap,0,name,decoratorFinishedRef)),nextNewClass=classDecs[i](newClass,ctx)}finally{decoratorFinishedRef.v=!0}void 0!==nextNewClass&&(old_assertValidReturnValue(10,nextNewClass),newClass=nextNewClass)}ret.push(newClass,(function(){for(var i=0;i=0;i--){var newInit;if(void 0!==(newValue=memberDec(decs[i],name,desc,initializers,kind,isStatic,isPrivate,value)))assertValidReturnValue(kind,newValue),0===kind?newInit=newValue:1===kind?(newInit=newValue.init,get=newValue.get||value.get,set=newValue.set||value.set,value={get:get,set:set}):value=newValue,void 0!==newInit&&(void 0===init?init=newInit:"function"==typeof init?init=[init,newInit]:init.push(newInit))}if(0===kind||1===kind){if(void 0===init)init=function(instance,init){return init};else if("function"!=typeof init){var ownInitializers=init;init=function(instance,init){for(var value=init,i=0;i3,isStatic=kind>=5;if(isStatic?(base=Class,0!==(kind-=5)&&(initializers=staticInitializers=staticInitializers||[])):(base=Class.prototype,0!==kind&&(initializers=protoInitializers=protoInitializers||[])),0!==kind&&!isPrivate){var existingNonFields=isStatic?existingStaticNonFields:existingProtoNonFields,existingKind=existingNonFields.get(name)||0;if(!0===existingKind||3===existingKind&&4!==kind||4===existingKind&&3!==kind)throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: "+name);!existingKind&&kind>2?existingNonFields.set(name,kind):existingNonFields.set(name,!0)}applyMemberDec(ret,base,decInfo,name,kind,isStatic,isPrivate,initializers)}}pushInitializers(ret,protoInitializers),pushInitializers(ret,staticInitializers)}function pushInitializers(ret,initializers){initializers&&ret.push((function(instance){for(var i=0;i0){for(var initializers=[],newClass=targetClass,name=targetClass.name,i=classDecs.length-1;i>=0;i--){var decoratorFinishedRef={v:!1};try{var nextNewClass=classDecs[i](newClass,{kind:"class",name:name,addInitializer:createAddInitializerMethod(initializers,decoratorFinishedRef)})}finally{decoratorFinishedRef.v=!0}void 0!==nextNewClass&&(assertValidReturnValue(10,nextNewClass),newClass=nextNewClass)}ret.push(newClass,(function(){for(var i=0;i= 0; i--) { var dec = decs[i]; - newValue = memberDec( + newValue = old_memberDec( dec, name, desc, @@ -395,13 +400,13 @@ function applyMemberDec( ); if (newValue !== void 0) { - assertValidReturnValue(kind, newValue); + old_assertValidReturnValue(kind, newValue); var newInit; if (kind === 0 /* FIELD */) { newInit = newValue; } else if (kind === 1 /* ACCESSOR */) { - newInit = getInit(newValue); + newInit = old_getInit(newValue); get = newValue.get || value.get; set = newValue.set || value.set; @@ -485,7 +490,7 @@ function applyMemberDec( } } -function applyMemberDecs( +function old_applyMemberDecs( ret, Class, protoMetadataMap, @@ -555,7 +560,7 @@ function applyMemberDecs( } } - applyMemberDec( + old_applyMemberDec( ret, base, decInfo, @@ -568,11 +573,11 @@ function applyMemberDecs( ); } - pushInitializers(ret, protoInitializers); - pushInitializers(ret, staticInitializers); + old_pushInitializers(ret, protoInitializers); + old_pushInitializers(ret, staticInitializers); } -function pushInitializers(ret, initializers) { +function old_pushInitializers(ret, initializers) { if (initializers) { ret.push(function (instance) { for (var i = 0; i < initializers.length; i++) { @@ -583,7 +588,7 @@ function pushInitializers(ret, initializers) { } } -function applyClassDecs(ret, targetClass, metadataMap, classDecs) { +function old_applyClassDecs(ret, targetClass, metadataMap, classDecs) { if (classDecs.length > 0) { var initializers = []; var newClass = targetClass; @@ -597,12 +602,12 @@ function applyClassDecs(ret, targetClass, metadataMap, classDecs) { { kind: "class", name: name, - addInitializer: createAddInitializerMethod( + addInitializer: old_createAddInitializerMethod( initializers, decoratorFinishedRef ), }, - createMetadataMethodsForProperty( + old_createMetadataMethodsForProperty( metadataMap, 0 /* CONSTRUCTOR */, name, @@ -615,7 +620,7 @@ function applyClassDecs(ret, targetClass, metadataMap, classDecs) { } if (nextNewClass !== undefined) { - assertValidReturnValue(10 /* CLASS */, nextNewClass); + old_assertValidReturnValue(10 /* CLASS */, nextNewClass); newClass = nextNewClass; } } @@ -779,7 +784,7 @@ export default function applyDecs(targetClass, memberDecs, classDecs) { var protoMetadataMap = {}; - applyMemberDecs( + old_applyMemberDecs( ret, targetClass, protoMetadataMap, @@ -787,11 +792,11 @@ export default function applyDecs(targetClass, memberDecs, classDecs) { memberDecs ); - convertMetadataMapToFinal(targetClass.prototype, protoMetadataMap); + old_convertMetadataMapToFinal(targetClass.prototype, protoMetadataMap); - applyClassDecs(ret, targetClass, staticMetadataMap, classDecs); + old_applyClassDecs(ret, targetClass, staticMetadataMap, classDecs); - convertMetadataMapToFinal(targetClass, staticMetadataMap); + old_convertMetadataMapToFinal(targetClass, staticMetadataMap); return ret; } diff --git a/packages/babel-helpers/src/helpers/applyDecs2203.js b/packages/babel-helpers/src/helpers/applyDecs2203.js new file mode 100644 index 000000000000..f512d686fb9b --- /dev/null +++ b/packages/babel-helpers/src/helpers/applyDecs2203.js @@ -0,0 +1,619 @@ +/* @minVersion 7.17.8 */ + +/** + Enums are used in this file, but not assigned to vars to avoid non-hoistable values + + CONSTRUCTOR = 0; + PUBLIC = 1; + PRIVATE = 2; + + FIELD = 0; + ACCESSOR = 1; + METHOD = 2; + GETTER = 3; + SETTER = 4; + + STATIC = 5; + + CLASS = 10; // only used in assertValidReturnValue +*/ + +function createAddInitializerMethod(initializers, decoratorFinishedRef) { + return function addInitializer(initializer) { + assertNotFinished(decoratorFinishedRef, "addInitializer"); + assertCallable(initializer, "An initializer"); + initializers.push(initializer); + }; +} + +function memberDec( + dec, + name, + desc, + initializers, + kind, + isStatic, + isPrivate, + value +) { + var kindStr; + + switch (kind) { + case 1 /* ACCESSOR */: + kindStr = "accessor"; + break; + case 2 /* METHOD */: + kindStr = "method"; + break; + case 3 /* GETTER */: + kindStr = "getter"; + break; + case 4 /* SETTER */: + kindStr = "setter"; + break; + default: + kindStr = "field"; + } + + var ctx = { + kind: kindStr, + name: isPrivate ? "#" + name : name, + static: isStatic, + private: isPrivate, + }; + + var decoratorFinishedRef = { v: false }; + + if (kind !== 0 /* FIELD */) { + ctx.addInitializer = createAddInitializerMethod( + initializers, + decoratorFinishedRef + ); + } + + var get, set; + if (kind === 0 /* FIELD */) { + if (isPrivate) { + get = desc.get; + set = desc.set; + } else { + get = function () { + return this[name]; + }; + set = function (v) { + this[name] = v; + }; + } + } else if (kind === 2 /* METHOD */) { + get = function () { + return desc.value; + }; + } else { + // replace with values that will go through the final getter and setter + if (kind === 1 /* ACCESSOR */ || kind === 3 /* GETTER */) { + get = function () { + return desc.get.call(this); + }; + } + + if (kind === 1 /* ACCESSOR */ || kind === 4 /* SETTER */) { + set = function (v) { + desc.set.call(this, v); + }; + } + } + ctx.access = + get && set ? { get: get, set: set } : get ? { get: get } : { set: set }; + + try { + return dec(value, ctx); + } finally { + decoratorFinishedRef.v = true; + } +} + +function assertNotFinished(decoratorFinishedRef, fnName) { + if (decoratorFinishedRef.v) { + throw new Error( + "attempted to call " + fnName + " after decoration was finished" + ); + } +} + +function assertCallable(fn, hint) { + if (typeof fn !== "function") { + throw new TypeError(hint + " must be a function"); + } +} + +function assertValidReturnValue(kind, value) { + var type = typeof value; + + if (kind === 1 /* ACCESSOR */) { + if (type !== "object" || value === null) { + throw new TypeError( + "accessor decorators must return an object with get, set, or init properties or void 0" + ); + } + if (value.get !== undefined) { + assertCallable(value.get, "accessor.get"); + } + if (value.set !== undefined) { + assertCallable(value.set, "accessor.set"); + } + if (value.init !== undefined) { + assertCallable(value.init, "accessor.init"); + } + } else if (type !== "function") { + var hint; + if (kind === 0 /* FIELD */) { + hint = "field"; + } else if (kind === 10 /* CLASS */) { + hint = "class"; + } else { + hint = "method"; + } + throw new TypeError(hint + " decorators must return a function or void 0"); + } +} + +function applyMemberDec( + ret, + base, + decInfo, + name, + kind, + isStatic, + isPrivate, + initializers +) { + var decs = decInfo[0]; + + var desc, init, value; + + if (isPrivate) { + if (kind === 0 /* FIELD */ || kind === 1 /* ACCESSOR */) { + desc = { + get: decInfo[3], + set: decInfo[4], + }; + } else if (kind === 3 /* GETTER */) { + desc = { + get: decInfo[3], + }; + } else if (kind === 4 /* SETTER */) { + desc = { + set: decInfo[3], + }; + } else { + desc = { + value: decInfo[3], + }; + } + } else if (kind !== 0 /* FIELD */) { + desc = Object.getOwnPropertyDescriptor(base, name); + } + + if (kind === 1 /* ACCESSOR */) { + value = { + get: desc.get, + set: desc.set, + }; + } else if (kind === 2 /* METHOD */) { + value = desc.value; + } else if (kind === 3 /* GETTER */) { + value = desc.get; + } else if (kind === 4 /* SETTER */) { + value = desc.set; + } + + var newValue, get, set; + + if (typeof decs === "function") { + newValue = memberDec( + decs, + name, + desc, + initializers, + kind, + isStatic, + isPrivate, + value + ); + + if (newValue !== void 0) { + assertValidReturnValue(kind, newValue); + + if (kind === 0 /* FIELD */) { + init = newValue; + } else if (kind === 1 /* ACCESSOR */) { + init = newValue.init; + get = newValue.get || value.get; + set = newValue.set || value.set; + + value = { get: get, set: set }; + } else { + value = newValue; + } + } + } else { + for (var i = decs.length - 1; i >= 0; i--) { + var dec = decs[i]; + + newValue = memberDec( + dec, + name, + desc, + initializers, + kind, + isStatic, + isPrivate, + value + ); + + if (newValue !== void 0) { + assertValidReturnValue(kind, newValue); + var newInit; + + if (kind === 0 /* FIELD */) { + newInit = newValue; + } else if (kind === 1 /* ACCESSOR */) { + newInit = newValue.init; + get = newValue.get || value.get; + set = newValue.set || value.set; + + value = { get: get, set: set }; + } else { + value = newValue; + } + + if (newInit !== void 0) { + if (init === void 0) { + init = newInit; + } else if (typeof init === "function") { + init = [init, newInit]; + } else { + init.push(newInit); + } + } + } + } + } + + if (kind === 0 /* FIELD */ || kind === 1 /* ACCESSOR */) { + if (init === void 0) { + // If the initializer was void 0, sub in a dummy initializer + init = function (instance, init) { + return init; + }; + } else if (typeof init !== "function") { + var ownInitializers = init; + + init = function (instance, init) { + var value = init; + + for (var i = 0; i < ownInitializers.length; i++) { + value = ownInitializers[i].call(instance, value); + } + + return value; + }; + } else { + var originalInitializer = init; + + init = function (instance, init) { + return originalInitializer.call(instance, init); + }; + } + + ret.push(init); + } + + if (kind !== 0 /* FIELD */) { + if (kind === 1 /* ACCESSOR */) { + desc.get = value.get; + desc.set = value.set; + } else if (kind === 2 /* METHOD */) { + desc.value = value; + } else if (kind === 3 /* GETTER */) { + desc.get = value; + } else if (kind === 4 /* SETTER */) { + desc.set = value; + } + + if (isPrivate) { + if (kind === 1 /* ACCESSOR */) { + ret.push(function (instance, args) { + return value.get.call(instance, args); + }); + ret.push(function (instance, args) { + return value.set.call(instance, args); + }); + } else if (kind === 2 /* METHOD */) { + ret.push(value); + } else { + ret.push(function (instance, args) { + return value.call(instance, args); + }); + } + } else { + Object.defineProperty(base, name, desc); + } + } +} + +function applyMemberDecs(ret, Class, decInfos) { + var protoInitializers; + var staticInitializers; + + var existingProtoNonFields = new Map(); + var existingStaticNonFields = new Map(); + + for (var i = 0; i < decInfos.length; i++) { + var decInfo = decInfos[i]; + + // skip computed property names + if (!Array.isArray(decInfo)) continue; + + var kind = decInfo[1]; + var name = decInfo[2]; + var isPrivate = decInfo.length > 3; + + var isStatic = kind >= 5; /* STATIC */ + var base; + var initializers; + + if (isStatic) { + base = Class; + kind = kind - 5 /* STATIC */; + // initialize staticInitializers when we see a non-field static member + if (kind !== 0 /* FIELD */) { + staticInitializers = staticInitializers || []; + initializers = staticInitializers; + } + } else { + base = Class.prototype; + // initialize protoInitializers when we see a non-field member + if (kind !== 0 /* FIELD */) { + protoInitializers = protoInitializers || []; + initializers = protoInitializers; + } + } + + if (kind !== 0 /* FIELD */ && !isPrivate) { + var existingNonFields = isStatic + ? existingStaticNonFields + : existingProtoNonFields; + + var existingKind = existingNonFields.get(name) || 0; + + if ( + existingKind === true || + (existingKind === 3 /* GETTER */ && kind !== 4) /* SETTER */ || + (existingKind === 4 /* SETTER */ && kind !== 3) /* GETTER */ + ) { + throw new Error( + "Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + + name + ); + } else if (!existingKind && kind > 2 /* METHOD */) { + existingNonFields.set(name, kind); + } else { + existingNonFields.set(name, true); + } + } + + applyMemberDec( + ret, + base, + decInfo, + name, + kind, + isStatic, + isPrivate, + initializers + ); + } + + pushInitializers(ret, protoInitializers); + pushInitializers(ret, staticInitializers); +} + +function pushInitializers(ret, initializers) { + if (initializers) { + ret.push(function (instance) { + for (var i = 0; i < initializers.length; i++) { + initializers[i].call(instance); + } + return instance; + }); + } +} + +function applyClassDecs(ret, targetClass, classDecs) { + if (classDecs.length > 0) { + var initializers = []; + var newClass = targetClass; + var name = targetClass.name; + + for (var i = classDecs.length - 1; i >= 0; i--) { + var decoratorFinishedRef = { v: false }; + + try { + var nextNewClass = classDecs[i](newClass, { + kind: "class", + name: name, + addInitializer: createAddInitializerMethod( + initializers, + decoratorFinishedRef + ), + }); + } finally { + decoratorFinishedRef.v = true; + } + + if (nextNewClass !== undefined) { + assertValidReturnValue(10 /* CLASS */, nextNewClass); + newClass = nextNewClass; + } + } + + ret.push(newClass, function () { + for (var i = 0; i < initializers.length; i++) { + initializers[i].call(newClass); + } + }); + } +} + +/** + Basic usage: + + applyDecs( + Class, + [ + // member decorators + [ + dec, // dec or array of decs + 0, // kind of value being decorated + 'prop', // name of public prop on class containing the value being decorated, + '#p', // the name of the private property (if is private, void 0 otherwise), + ] + ], + [ + // class decorators + dec1, dec2 + ] + ) + ``` + + Fully transpiled example: + + ```js + @dec + class Class { + @dec + a = 123; + + @dec + #a = 123; + + @dec + @dec2 + accessor b = 123; + + @dec + accessor #b = 123; + + @dec + c() { console.log('c'); } + + @dec + #c() { console.log('privC'); } + + @dec + get d() { console.log('d'); } + + @dec + get #d() { console.log('privD'); } + + @dec + set e(v) { console.log('e'); } + + @dec + set #e(v) { console.log('privE'); } + } + + + // becomes + let initializeInstance; + let initializeClass; + + let initA; + let initPrivA; + + let initB; + let initPrivB, getPrivB, setPrivB; + + let privC; + let privD; + let privE; + + let Class; + class _Class { + static { + let ret = applyDecs( + this, + [ + [dec, 0, 'a'], + [dec, 0, 'a', (i) => i.#a, (i, v) => i.#a = v], + [[dec, dec2], 1, 'b'], + [dec, 1, 'b', (i) => i.#privBData, (i, v) => i.#privBData = v], + [dec, 2, 'c'], + [dec, 2, 'c', () => console.log('privC')], + [dec, 3, 'd'], + [dec, 3, 'd', () => console.log('privD')], + [dec, 4, 'e'], + [dec, 4, 'e', () => console.log('privE')], + ], + [ + dec + ] + ) + + initA = ret[0]; + + initPrivA = ret[1]; + + initB = ret[2]; + + initPrivB = ret[3]; + getPrivB = ret[4]; + setPrivB = ret[5]; + + privC = ret[6]; + + privD = ret[7]; + + privE = ret[8]; + + initializeInstance = ret[9]; + + Class = ret[10] + + initializeClass = ret[11]; + } + + a = (initializeInstance(this), initA(this, 123)); + + #a = initPrivA(this, 123); + + #bData = initB(this, 123); + get b() { return this.#bData } + set b(v) { this.#bData = v } + + #privBData = initPrivB(this, 123); + get #b() { return getPrivB(this); } + set #b(v) { setPrivB(this, v); } + + c() { console.log('c'); } + + #c(...args) { return privC(this, ...args) } + + get d() { console.log('d'); } + + get #d() { return privD(this); } + + set e(v) { console.log('e'); } + + set #e(v) { privE(this, v); } + } + + initializeClass(Class); + */ +export default function applyDecs2203(targetClass, memberDecs, classDecs) { + var ret = []; + applyMemberDecs(ret, targetClass, memberDecs); + applyClassDecs(ret, targetClass, classDecs); + return ret; +} diff --git a/packages/babel-parser/src/parse-error/standard-errors.ts b/packages/babel-parser/src/parse-error/standard-errors.ts index a4087dfcc718..e50a5a33e007 100644 --- a/packages/babel-parser/src/parse-error/standard-errors.ts +++ b/packages/babel-parser/src/parse-error/standard-errors.ts @@ -50,6 +50,8 @@ export default { }: { kind: "const" | "destructuring"; }) => `Missing initializer in ${kind} declaration.`, + DecoratorArgumentsOutsideParentheses: + "Decorator arguments must be moved inside parentheses: use '@(decorator(args))' instead of '@(decorator)(args)'.", DecoratorBeforeExport: "Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax.", DecoratorConstructor: diff --git a/packages/babel-parser/src/parser/statement.ts b/packages/babel-parser/src/parser/statement.ts index a882dc382092..4c2fc5237a9b 100644 --- a/packages/babel-parser/src/parser/statement.ts +++ b/packages/babel-parser/src/parser/statement.ts @@ -580,6 +580,18 @@ export default abstract class StatementParser extends ExpressionParser { expr = this.parseExpression(); this.expect(tt.parenR); expr = this.wrapParenthesis(startPos, startLoc, expr); + + const paramsStartLoc = this.state.startLoc; + node.expression = this.parseMaybeDecoratorArguments(expr); + if ( + this.getPluginOption("decorators", "allowCallParenthesized") === + false && + node.expression !== expr + ) { + this.raise(Errors.DecoratorArgumentsOutsideParentheses, { + at: paramsStartLoc, + }); + } } else { expr = this.parseIdentifier(false); @@ -598,9 +610,10 @@ export default abstract class StatementParser extends ExpressionParser { node.computed = false; expr = this.finishNode(node, "MemberExpression"); } + + node.expression = this.parseMaybeDecoratorArguments(expr); } - node.expression = this.parseMaybeDecoratorArguments(expr); this.state.decoratorStack.pop(); } else { node.expression = this.parseExprSubscripts(); diff --git a/packages/babel-parser/src/plugin-utils.ts b/packages/babel-parser/src/plugin-utils.ts index 8242c6b3d806..ee90be06e2d2 100644 --- a/packages/babel-parser/src/plugin-utils.ts +++ b/packages/babel-parser/src/plugin-utils.ts @@ -93,6 +93,18 @@ export function validatePlugins(plugins: PluginList) { ) { throw new Error("'decoratorsBeforeExport' must be a boolean."); } + + const allowCallParenthesized = getPluginOption( + plugins, + "decorators", + "allowCallParenthesized", + ); + if ( + allowCallParenthesized != null && + typeof allowCallParenthesized !== "boolean" + ) { + throw new Error("'allowCallParenthesized' must be a boolean."); + } } if (hasPlugin(plugins, "flow") && hasPlugin(plugins, "typescript")) { diff --git a/packages/babel-parser/src/typings.ts b/packages/babel-parser/src/typings.ts index d932bba05572..6cf279daa349 100644 --- a/packages/babel-parser/src/typings.ts +++ b/packages/babel-parser/src/typings.ts @@ -55,6 +55,7 @@ export type PluginOptions = export interface DecoratorsPluginOptions { decoratorsBeforeExport?: boolean; + allowCallParenthesized?: boolean; } export interface PipelineOperatorPluginOptions { diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/input.js new file mode 100644 index 000000000000..1d12a355a9d1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/input.js @@ -0,0 +1,3 @@ +class Foo { + @(this.foo)(bar) method3() {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/options.json new file mode 100644 index 000000000000..9a7fd5e2efb9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/options.json @@ -0,0 +1,11 @@ +{ + "plugins": [ + [ + "decorators", + { + "allowCallParenthesized": false, + "decoratorsBeforeExport": false + } + ] + ] +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/output.json new file mode 100644 index 000000000000..436ea880e3cf --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-invalid/output.json @@ -0,0 +1,89 @@ +{ + "type": "File", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":45}}, + "errors": [ + "SyntaxError: Decorator arguments must be moved inside parentheses: use '@(decorator(args))' instead of '@(decorator)(args)'. (2:13)" + ], + "program": { + "type": "Program", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":45}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":45}}, + "id": { + "type": "Identifier", + "start":6,"end":9,"loc":{"start":{"line":1,"column":6,"index":6},"end":{"line":1,"column":9,"index":9},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":10,"end":45,"loc":{"start":{"line":1,"column":10,"index":10},"end":{"line":3,"column":1,"index":45}}, + "body": [ + { + "type": "ClassMethod", + "start":14,"end":43,"loc":{"start":{"line":2,"column":2,"index":14},"end":{"line":2,"column":31,"index":43}}, + "decorators": [ + { + "type": "Decorator", + "start":14,"end":30,"loc":{"start":{"line":2,"column":2,"index":14},"end":{"line":2,"column":18,"index":30}}, + "expression": { + "type": "CallExpression", + "start":16,"end":30,"loc":{"start":{"line":2,"column":4,"index":16},"end":{"line":2,"column":18,"index":30}}, + "callee": { + "type": "MemberExpression", + "start":16,"end":24,"loc":{"start":{"line":2,"column":4,"index":16},"end":{"line":2,"column":12,"index":24}}, + "object": { + "type": "ThisExpression", + "start":16,"end":20,"loc":{"start":{"line":2,"column":4,"index":16},"end":{"line":2,"column":8,"index":20}} + }, + "computed": false, + "property": { + "type": "Identifier", + "start":21,"end":24,"loc":{"start":{"line":2,"column":9,"index":21},"end":{"line":2,"column":12,"index":24},"identifierName":"foo"}, + "name": "foo" + }, + "extra": { + "parenthesized": true, + "parenStart": 15 + } + }, + "arguments": [ + { + "type": "Identifier", + "start":26,"end":29,"loc":{"start":{"line":2,"column":14,"index":26},"end":{"line":2,"column":17,"index":29},"identifierName":"bar"}, + "name": "bar" + } + ] + } + } + ], + "static": false, + "key": { + "type": "Identifier", + "start":31,"end":38,"loc":{"start":{"line":2,"column":19,"index":31},"end":{"line":2,"column":26,"index":38},"identifierName":"method3"}, + "name": "method3" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":41,"end":43,"loc":{"start":{"line":2,"column":29,"index":41},"end":{"line":2,"column":31,"index":43}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/input.js new file mode 100644 index 000000000000..bc018da1c6f6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/input.js @@ -0,0 +1,8 @@ +@(foo().bar) +class Foo { + @(member[expression]) method() {} + + @(foo + bar) method2() {} + + @(this.foo(bar)) method3() {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/options.json new file mode 100644 index 000000000000..9a7fd5e2efb9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/options.json @@ -0,0 +1,11 @@ +{ + "plugins": [ + [ + "decorators", + { + "allowCallParenthesized": false, + "decoratorsBeforeExport": false + } + ] + ] +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/output.json new file mode 100644 index 000000000000..0fd3d0d4cee6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-false-valid/output.json @@ -0,0 +1,210 @@ +{ + "type": "File", + "start":0,"end":124,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":8,"column":1,"index":124}}, + "program": { + "type": "Program", + "start":0,"end":124,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":8,"column":1,"index":124}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":124,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":8,"column":1,"index":124}}, + "decorators": [ + { + "type": "Decorator", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":12,"index":12}}, + "expression": { + "type": "MemberExpression", + "start":2,"end":11,"loc":{"start":{"line":1,"column":2,"index":2},"end":{"line":1,"column":11,"index":11}}, + "object": { + "type": "CallExpression", + "start":2,"end":7,"loc":{"start":{"line":1,"column":2,"index":2},"end":{"line":1,"column":7,"index":7}}, + "callee": { + "type": "Identifier", + "start":2,"end":5,"loc":{"start":{"line":1,"column":2,"index":2},"end":{"line":1,"column":5,"index":5},"identifierName":"foo"}, + "name": "foo" + }, + "arguments": [] + }, + "computed": false, + "property": { + "type": "Identifier", + "start":8,"end":11,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":1,"column":11,"index":11},"identifierName":"bar"}, + "name": "bar" + }, + "extra": { + "parenthesized": true, + "parenStart": 1 + } + } + } + ], + "id": { + "type": "Identifier", + "start":19,"end":22,"loc":{"start":{"line":2,"column":6,"index":19},"end":{"line":2,"column":9,"index":22},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":23,"end":124,"loc":{"start":{"line":2,"column":10,"index":23},"end":{"line":8,"column":1,"index":124}}, + "body": [ + { + "type": "ClassMethod", + "start":27,"end":60,"loc":{"start":{"line":3,"column":2,"index":27},"end":{"line":3,"column":35,"index":60}}, + "decorators": [ + { + "type": "Decorator", + "start":27,"end":48,"loc":{"start":{"line":3,"column":2,"index":27},"end":{"line":3,"column":23,"index":48}}, + "expression": { + "type": "MemberExpression", + "start":29,"end":47,"loc":{"start":{"line":3,"column":4,"index":29},"end":{"line":3,"column":22,"index":47}}, + "object": { + "type": "Identifier", + "start":29,"end":35,"loc":{"start":{"line":3,"column":4,"index":29},"end":{"line":3,"column":10,"index":35},"identifierName":"member"}, + "name": "member" + }, + "computed": true, + "property": { + "type": "Identifier", + "start":36,"end":46,"loc":{"start":{"line":3,"column":11,"index":36},"end":{"line":3,"column":21,"index":46},"identifierName":"expression"}, + "name": "expression" + }, + "extra": { + "parenthesized": true, + "parenStart": 28 + } + } + } + ], + "static": false, + "key": { + "type": "Identifier", + "start":49,"end":55,"loc":{"start":{"line":3,"column":24,"index":49},"end":{"line":3,"column":30,"index":55},"identifierName":"method"}, + "name": "method" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":58,"end":60,"loc":{"start":{"line":3,"column":33,"index":58},"end":{"line":3,"column":35,"index":60}}, + "body": [], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start":64,"end":89,"loc":{"start":{"line":5,"column":2,"index":64},"end":{"line":5,"column":27,"index":89}}, + "decorators": [ + { + "type": "Decorator", + "start":64,"end":76,"loc":{"start":{"line":5,"column":2,"index":64},"end":{"line":5,"column":14,"index":76}}, + "expression": { + "type": "BinaryExpression", + "start":66,"end":75,"loc":{"start":{"line":5,"column":4,"index":66},"end":{"line":5,"column":13,"index":75}}, + "left": { + "type": "Identifier", + "start":66,"end":69,"loc":{"start":{"line":5,"column":4,"index":66},"end":{"line":5,"column":7,"index":69},"identifierName":"foo"}, + "name": "foo" + }, + "operator": "+", + "right": { + "type": "Identifier", + "start":72,"end":75,"loc":{"start":{"line":5,"column":10,"index":72},"end":{"line":5,"column":13,"index":75},"identifierName":"bar"}, + "name": "bar" + }, + "extra": { + "parenthesized": true, + "parenStart": 65 + } + } + } + ], + "static": false, + "key": { + "type": "Identifier", + "start":77,"end":84,"loc":{"start":{"line":5,"column":15,"index":77},"end":{"line":5,"column":22,"index":84},"identifierName":"method2"}, + "name": "method2" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":87,"end":89,"loc":{"start":{"line":5,"column":25,"index":87},"end":{"line":5,"column":27,"index":89}}, + "body": [], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start":93,"end":122,"loc":{"start":{"line":7,"column":2,"index":93},"end":{"line":7,"column":31,"index":122}}, + "decorators": [ + { + "type": "Decorator", + "start":93,"end":109,"loc":{"start":{"line":7,"column":2,"index":93},"end":{"line":7,"column":18,"index":109}}, + "expression": { + "type": "CallExpression", + "start":95,"end":108,"loc":{"start":{"line":7,"column":4,"index":95},"end":{"line":7,"column":17,"index":108}}, + "callee": { + "type": "MemberExpression", + "start":95,"end":103,"loc":{"start":{"line":7,"column":4,"index":95},"end":{"line":7,"column":12,"index":103}}, + "object": { + "type": "ThisExpression", + "start":95,"end":99,"loc":{"start":{"line":7,"column":4,"index":95},"end":{"line":7,"column":8,"index":99}} + }, + "computed": false, + "property": { + "type": "Identifier", + "start":100,"end":103,"loc":{"start":{"line":7,"column":9,"index":100},"end":{"line":7,"column":12,"index":103},"identifierName":"foo"}, + "name": "foo" + } + }, + "arguments": [ + { + "type": "Identifier", + "start":104,"end":107,"loc":{"start":{"line":7,"column":13,"index":104},"end":{"line":7,"column":16,"index":107},"identifierName":"bar"}, + "name": "bar" + } + ], + "extra": { + "parenthesized": true, + "parenStart": 94 + } + } + } + ], + "static": false, + "key": { + "type": "Identifier", + "start":110,"end":117,"loc":{"start":{"line":7,"column":19,"index":110},"end":{"line":7,"column":26,"index":117},"identifierName":"method3"}, + "name": "method3" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":120,"end":122,"loc":{"start":{"line":7,"column":29,"index":120},"end":{"line":7,"column":31,"index":122}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/input.js new file mode 100644 index 000000000000..1d12a355a9d1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/input.js @@ -0,0 +1,3 @@ +class Foo { + @(this.foo)(bar) method3() {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/options.json new file mode 100644 index 000000000000..f3e252789e44 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + [ + "decorators", + { "allowCallParenthesized": true, "decoratorsBeforeExport": false } + ] + ] +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/output.json new file mode 100644 index 000000000000..881c8a693af6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/parenthesized-allowCallParenthesized-true/output.json @@ -0,0 +1,86 @@ +{ + "type": "File", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":45}}, + "program": { + "type": "Program", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":45}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ClassDeclaration", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":1,"index":45}}, + "id": { + "type": "Identifier", + "start":6,"end":9,"loc":{"start":{"line":1,"column":6,"index":6},"end":{"line":1,"column":9,"index":9},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":10,"end":45,"loc":{"start":{"line":1,"column":10,"index":10},"end":{"line":3,"column":1,"index":45}}, + "body": [ + { + "type": "ClassMethod", + "start":14,"end":43,"loc":{"start":{"line":2,"column":2,"index":14},"end":{"line":2,"column":31,"index":43}}, + "decorators": [ + { + "type": "Decorator", + "start":14,"end":30,"loc":{"start":{"line":2,"column":2,"index":14},"end":{"line":2,"column":18,"index":30}}, + "expression": { + "type": "CallExpression", + "start":16,"end":30,"loc":{"start":{"line":2,"column":4,"index":16},"end":{"line":2,"column":18,"index":30}}, + "callee": { + "type": "MemberExpression", + "start":16,"end":24,"loc":{"start":{"line":2,"column":4,"index":16},"end":{"line":2,"column":12,"index":24}}, + "object": { + "type": "ThisExpression", + "start":16,"end":20,"loc":{"start":{"line":2,"column":4,"index":16},"end":{"line":2,"column":8,"index":20}} + }, + "computed": false, + "property": { + "type": "Identifier", + "start":21,"end":24,"loc":{"start":{"line":2,"column":9,"index":21},"end":{"line":2,"column":12,"index":24},"identifierName":"foo"}, + "name": "foo" + }, + "extra": { + "parenthesized": true, + "parenStart": 15 + } + }, + "arguments": [ + { + "type": "Identifier", + "start":26,"end":29,"loc":{"start":{"line":2,"column":14,"index":26},"end":{"line":2,"column":17,"index":29},"identifierName":"bar"}, + "name": "bar" + } + ] + } + } + ], + "static": false, + "key": { + "type": "Identifier", + "start":31,"end":38,"loc":{"start":{"line":2,"column":19,"index":31},"end":{"line":2,"column":26,"index":38},"identifierName":"method3"}, + "name": "method3" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":41,"end":43,"loc":{"start":{"line":2,"column":29,"index":41},"end":{"line":2,"column":31,"index":43}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-plugin-proposal-decorators/src/index.ts b/packages/babel-plugin-proposal-decorators/src/index.ts index 2cc119636033..5720fc5ff52b 100644 --- a/packages/babel-plugin-proposal-decorators/src/index.ts +++ b/packages/babel-plugin-proposal-decorators/src/index.ts @@ -7,7 +7,7 @@ import { FEATURES, } from "@babel/helper-create-class-features-plugin"; import legacyVisitor from "./transformer-legacy"; -import transformer2021_12 from "./transformer-2021-12"; +import transformer2022_03 from "./transformer-2022-03"; import type { Options as SyntaxOptions } from "@babel/plugin-syntax-decorators"; interface Options extends SyntaxOptions { @@ -37,8 +37,8 @@ export default declare((api, options: Options) => { inherits: syntaxDecorators, visitor: legacyVisitor, }; - } else if (version === "2021-12") { - return transformer2021_12(api, options); + } else if (version === "2021-12" || version === "2022-03") { + return transformer2022_03(api, options, version); } else if (!process.env.BABEL_8_BREAKING) { return createClassFeaturePlugin({ name: "proposal-decorators", @@ -50,7 +50,7 @@ export default declare((api, options: Options) => { }); } else { throw new Error( - "The '.version' option must be one of 'legacy' or '2021-12'", + "The '.version' option must be one of 'legacy', '2021-12' or '2022-03'.", ); } }); diff --git a/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts b/packages/babel-plugin-proposal-decorators/src/transformer-2022-03.ts similarity index 98% rename from packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts rename to packages/babel-plugin-proposal-decorators/src/transformer-2022-03.ts index 53011ef94fda..0e7061564685 100644 --- a/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts +++ b/packages/babel-plugin-proposal-decorators/src/transformer-2022-03.ts @@ -487,6 +487,7 @@ function transformClass( path: NodePath, state: PluginPass, constantSuper: boolean, + version: "2022-03" | "2021-12", ): NodePath { const body = path.get("body.body"); @@ -981,11 +982,12 @@ function transformClass( t.assignmentExpression( "=", t.arrayPattern(locals), - t.callExpression(state.addHelper("applyDecs"), [ - t.thisExpression(), - elementDecorations, - classDecorations, - ]), + t.callExpression( + state.addHelper( + version === "2021-12" ? "applyDecs" : "applyDecs2203", + ), + [t.thisExpression(), elementDecorations, classDecorations], + ), ), ), requiresStaticInit && @@ -1011,6 +1013,7 @@ function transformClass( export default function ( { assertVersion, assumption }: PluginAPI, { loose }: Options, + version: "2022-03" | "2021-12", ): PluginObject { assertVersion("^7.16.0"); @@ -1039,7 +1042,7 @@ export default function ( Class(path, state) { if (VISITED.has(path)) return; - const newPath = transformClass(path, state, constantSuper); + const newPath = transformClass(path, state, constantSuper, version); if (newPath) VISITED.add(newPath); }, }, diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-ordering/accessor-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-ordering/accessor-initializers/exec.js index 892ced55301d..8a3d020240e0 100644 --- a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-ordering/accessor-initializers/exec.js +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-ordering/accessor-initializers/exec.js @@ -11,7 +11,7 @@ function logClassDecoratorRun(a, b, c) { }; } -function logAccessorDecoratorRun(a, b, c, d) { +function decorator(a, b, c, d) { push(a); return function (el, { addInitializer }) { push(b); @@ -25,20 +25,20 @@ function logAccessorDecoratorRun(a, b, c, d) { @logClassDecoratorRun(0, 19, 29) @logClassDecoratorRun(1, 18, 28) class A { - @logAccessorDecoratorRun(2, 15, 31, 35) - @logAccessorDecoratorRun(3, 14, 30, 34) + @decorator(2, 15, 31, 35) + @decorator(3, 14, 30, 34) accessor a; - @logAccessorDecoratorRun(4, 11, 21, 25) - @logAccessorDecoratorRun(5, 10, 20, 24) + @decorator(4, 11, 21, 25) + @decorator(5, 10, 20, 24) static accessor b; - @logAccessorDecoratorRun(6, 13, 23, 27) - @logAccessorDecoratorRun(7, 12, 22, 26) + @decorator(6, 13, 23, 27) + @decorator(7, 12, 22, 26) static accessor #c; - @logAccessorDecoratorRun(8, 17, 33, 37) - @logAccessorDecoratorRun(9, 16, 32, 36) + @decorator(8, 17, 33, 37) + @decorator(9, 16, 32, 36) accessor #d; } diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/exec.js new file mode 100644 index 000000000000..278b5bc4c5ac --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/exec.js @@ -0,0 +1,50 @@ +function dec({ get, set }, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return { + get() { + return get.call(this) + 1; + }, + + set(v) { + set.call(this, v + 1); + }, + + init(v) { + return v ? v : 1; + } + } +} + +class Foo { + @dec + accessor #a; + + @dec + accessor #b = 123; +} + +let foo = new Foo(); + +const aContext = foo['#aContext']; +const bContext = foo['#bContext']; + +expect(aContext.access.get.call(foo)).toBe(2); +aContext.access.set.call(foo, 123); +expect(aContext.access.get.call(foo)).toBe(125); +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('accessor'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('function'); + +expect(bContext.access.get.call(foo)).toBe(124); +bContext.access.set.call(foo, 123); +expect(bContext.access.get.call(foo)).toBe(125); +expect(bContext.name).toBe('#b'); +expect(bContext.kind).toBe('accessor'); +expect(bContext.static).toBe(false); +expect(bContext.private).toBe(true); +expect(typeof bContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/input.js new file mode 100644 index 000000000000..aa152db91d94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec + accessor #a; + + @dec + accessor #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/output.js new file mode 100644 index 000000000000..93010b43a0cc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/private/output.js @@ -0,0 +1,59 @@ +var _init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initProto; + +const dec = () => {}; + +var _A = /*#__PURE__*/new WeakMap(); + +var _a = /*#__PURE__*/new WeakMap(); + +var _B = /*#__PURE__*/new WeakMap(); + +var _b = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor() { + babelHelpers.classPrivateFieldInitSpec(this, _b, { + get: _get_b2, + set: _set_b2 + }); + babelHelpers.classPrivateFieldInitSpec(this, _a, { + get: _get_a2, + set: _set_a2 + }); + babelHelpers.classPrivateFieldInitSpec(this, _A, { + writable: true, + value: (_initProto(this), _init_a(this)) + }); + babelHelpers.classPrivateFieldInitSpec(this, _B, { + writable: true, + value: _init_b(this, 123) + }); + } + +} + +function _set_a2(v) { + _set_a(this, v); +} + +function _get_a2() { + return _get_a(this); +} + +function _set_b2(v) { + _set_b(this, v); +} + +function _get_b2() { + return _get_b(this); +} + +[_init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 1, "a", function () { + return babelHelpers.classPrivateFieldGet(this, _A); +}, function (value) { + babelHelpers.classPrivateFieldSet(this, _A, value); +}], [dec, 1, "b", function () { + return babelHelpers.classPrivateFieldGet(this, _B); +}, function (value) { + babelHelpers.classPrivateFieldSet(this, _B, value); +}]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/exec.js new file mode 100644 index 000000000000..ca549f75b729 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/exec.js @@ -0,0 +1,74 @@ +function dec({ get, set }, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return { + get() { + return get.call(this) + 1; + }, + + set(v) { + set.call(this, v + 1); + }, + + init(v) { + return v ? v : 1; + } + } +} + +class Foo { + @dec + accessor a; + + @dec + accessor b = 123; + + @dec + accessor ['c'] = 456; +} + +let foo = new Foo(); + +const aContext = foo['aContext']; +const bContext = foo['bContext']; +const cContext = foo['cContext']; + +expect(foo.a).toBe(2); +expect(aContext.access.get.call(foo)).toBe(2); +foo.a = 123; +expect(foo.a).toBe(125); +expect(aContext.access.get.call(foo)).toBe(125); +aContext.access.set.call(foo, 456); +expect(foo.a).toBe(458); +expect(aContext.access.get.call(foo)).toBe(458); +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('accessor'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('function'); +expect(foo.hasOwnProperty('a')).toBe(false); +expect(Foo.prototype.hasOwnProperty('a')).toBe(true); + +expect(foo.b).toBe(124); +foo.b = 123; +expect(foo.b).toBe(125); +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('accessor'); +expect(bContext.static).toBe(false); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('function'); +expect(foo.hasOwnProperty('b')).toBe(false); +expect(Foo.prototype.hasOwnProperty('b')).toBe(true); + +expect(foo.c).toBe(457); +foo.c = 456; +expect(foo.c).toBe(458); +expect(cContext.name).toBe('c'); +expect(cContext.kind).toBe('accessor'); +expect(cContext.static).toBe(false); +expect(cContext.private).toBe(false); +expect(typeof cContext.addInitializer).toBe('function'); +expect(foo.hasOwnProperty('c')).toBe(false); +expect(Foo.prototype.hasOwnProperty('c')).toBe(true); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/input.js new file mode 100644 index 000000000000..bd8be5cbe225 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class Foo { + @dec + accessor a; + + @dec + accessor b = 123; + + @dec + accessor ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/output.js new file mode 100644 index 000000000000..6b7c4e24e667 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/public/output.js @@ -0,0 +1,55 @@ +var _init_a, _init_b, _computedKey, _init_computedKey, _initProto; + +const dec = () => {}; + +_computedKey = 'c'; + +var _A = /*#__PURE__*/new WeakMap(); + +var _B = /*#__PURE__*/new WeakMap(); + +var _C = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor() { + babelHelpers.classPrivateFieldInitSpec(this, _A, { + writable: true, + value: (_initProto(this), _init_a(this)) + }); + babelHelpers.classPrivateFieldInitSpec(this, _B, { + writable: true, + value: _init_b(this, 123) + }); + babelHelpers.classPrivateFieldInitSpec(this, _C, { + writable: true, + value: _init_computedKey(this, 456) + }); + } + + get a() { + return babelHelpers.classPrivateFieldGet(this, _A); + } + + set a(v) { + babelHelpers.classPrivateFieldSet(this, _A, v); + } + + get b() { + return babelHelpers.classPrivateFieldGet(this, _B); + } + + set b(v) { + babelHelpers.classPrivateFieldSet(this, _B, v); + } + + get [_computedKey]() { + return babelHelpers.classPrivateFieldGet(this, _C); + } + + set [_computedKey](v) { + babelHelpers.classPrivateFieldSet(this, _C, v); + } + +} + +[_init_a, _init_b, _init_computedKey, _initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 1, "a"], [dec, 1, "b"], [dec, 1, _computedKey]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..60d34c7ceea2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/exec.js @@ -0,0 +1,48 @@ +function dec({ get, set }, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return { + get() { + return get.call(this) + 1; + }, + + set(v) { + set.call(this, v + 1); + }, + + init(v) { + return v ? v : 1; + } + } +} + +class Foo { + @dec + static accessor #a; + + @dec + static accessor #b = 123; +} + +const aContext = Foo['#aContext']; +const bContext = Foo['#bContext']; + +expect(aContext.access.get.call(Foo)).toBe(2); +aContext.access.set.call(Foo, 123); +expect(aContext.access.get.call(Foo)).toBe(125); +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('accessor'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('function'); + +expect(bContext.access.get.call(Foo)).toBe(124); +bContext.access.set.call(Foo, 123); +expect(bContext.access.get.call(Foo)).toBe(125); +expect(bContext.name).toBe('#b'); +expect(bContext.kind).toBe('accessor'); +expect(bContext.static).toBe(true); +expect(bContext.private).toBe(true); +expect(typeof bContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/input.js new file mode 100644 index 000000000000..c30e61d463bc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec + static accessor #a; + + @dec + static accessor #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/output.js new file mode 100644 index 000000000000..2d65c3fe55ad --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-private/output.js @@ -0,0 +1,60 @@ +var _init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initStatic; + +const dec = () => {}; + +var _a = /*#__PURE__*/new WeakMap(); + +var _b = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor() { + babelHelpers.classPrivateFieldInitSpec(this, _b, { + get: _get_b2, + set: _set_b2 + }); + babelHelpers.classPrivateFieldInitSpec(this, _a, { + get: _get_a2, + set: _set_a2 + }); + } + +} + +function _set_a2(v) { + _set_a(this, v); +} + +function _get_a2() { + return _get_a(this); +} + +function _set_b2(v) { + _set_b(this, v); +} + +function _get_b2() { + return _get_b(this); +} + +(() => { + [_init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 6, "a", function () { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _A); + }, function (value) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _A, value); + }], [dec, 6, "b", function () { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _B); + }, function (value) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _B, value); + }]], []); + + _initStatic(Foo); +})(); + +var _A = { + writable: true, + value: _init_a(Foo) +}; +var _B = { + writable: true, + value: _init_b(Foo, 123) +}; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..fc23b83e8563 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/exec.js @@ -0,0 +1,69 @@ +function dec({ get, set }, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return { + get() { + return get.call(this) + 1; + }, + + set(v) { + set.call(this, v + 1); + }, + + init(v) { + return v ? v : 1; + } + } +} + +class Foo { + @dec + static accessor a; + + @dec + static accessor b = 123; + + @dec + static accessor ['c'] = 456; +} + +const aContext = Foo['aContext']; +const bContext = Foo['bContext']; +const cContext = Foo['cContext']; + +expect(Foo.a).toBe(2); +expect(aContext.access.get.call(Foo)).toBe(2); +Foo.a = 123; +expect(Foo.a).toBe(125); +expect(aContext.access.get.call(Foo)).toBe(125); +aContext.access.set.call(Foo, 456); +expect(Foo.a).toBe(458); +expect(aContext.access.get.call(Foo)).toBe(458); +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('accessor'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('function'); +expect(Foo.hasOwnProperty('a')).toBe(true); + +expect(Foo.b).toBe(124); +Foo.b = 123; +expect(Foo.b).toBe(125); +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('accessor'); +expect(bContext.static).toBe(true); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('function'); +expect(Foo.hasOwnProperty('b')).toBe(true); + +expect(Foo.c).toBe(457); +Foo.c = 456; +expect(Foo.c).toBe(458); +expect(cContext.name).toBe('c'); +expect(cContext.kind).toBe('accessor'); +expect(cContext.static).toBe(true); +expect(cContext.private).toBe(false); +expect(typeof cContext.addInitializer).toBe('function'); +expect(Foo.hasOwnProperty('c')).toBe(true); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/input.js new file mode 100644 index 000000000000..50f05c065848 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class Foo { + @dec + static accessor a; + + @dec + static accessor b = 123; + + @dec + static accessor ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/output.js new file mode 100644 index 000000000000..78a029f66e10 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/static-public/output.js @@ -0,0 +1,51 @@ +var _init_a, _init_b, _computedKey, _init_computedKey, _initStatic; + +const dec = () => {}; + +_computedKey = 'c'; + +class Foo { + static get a() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _A); + } + + static set a(v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _A, v); + } + + static get b() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _B); + } + + static set b(v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _B, v); + } + + static get [_computedKey]() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _C); + } + + static set [_computedKey](v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _C, v); + } + +} + +(() => { + [_init_a, _init_b, _init_computedKey, _initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 6, "a"], [dec, 6, "b"], [dec, 6, _computedKey]], []); + + _initStatic(Foo); +})(); + +var _A = { + writable: true, + value: _init_a(Foo) +}; +var _B = { + writable: true, + value: _init_b(Foo, 123) +}; +var _C = { + writable: true, + value: _init_computedKey(Foo, 456) +}; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/exec.js new file mode 100644 index 000000000000..51715be9f173 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/exec.js @@ -0,0 +1,31 @@ +class Foo { + accessor #a; + + accessor #b = 123; + + getA() { + return this.#a; + } + + setA(v) { + this.#a = v; + } + + getB() { + return this.#b; + } + + setB(v) { + this.#b = v; + } +} + +let foo = new Foo(); + +expect(foo.getA()).toBe(undefined); +foo.setA(123) +expect(foo.getA()).toBe(123); + +expect(foo.getB()).toBe(123); +foo.setB(456) +expect(foo.getB()).toBe(456); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/input.js new file mode 100644 index 000000000000..07804cb8a125 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/input.js @@ -0,0 +1,6 @@ +const dec = () => {}; +class Foo { + accessor #a; + + accessor #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/output.js new file mode 100644 index 000000000000..ff585899f911 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-private/output.js @@ -0,0 +1,47 @@ +const dec = () => {}; + +var _A = /*#__PURE__*/new WeakMap(); + +var _a = /*#__PURE__*/new WeakMap(); + +var _B = /*#__PURE__*/new WeakMap(); + +var _b = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor() { + babelHelpers.classPrivateFieldInitSpec(this, _b, { + get: _get_b, + set: _set_b + }); + babelHelpers.classPrivateFieldInitSpec(this, _a, { + get: _get_a, + set: _set_a + }); + babelHelpers.classPrivateFieldInitSpec(this, _A, { + writable: true, + value: void 0 + }); + babelHelpers.classPrivateFieldInitSpec(this, _B, { + writable: true, + value: 123 + }); + } + +} + +function _get_a() { + return babelHelpers.classPrivateFieldGet(this, _A); +} + +function _set_a(v) { + babelHelpers.classPrivateFieldSet(this, _A, v); +} + +function _get_b() { + return babelHelpers.classPrivateFieldGet(this, _B); +} + +function _set_b(v) { + babelHelpers.classPrivateFieldSet(this, _B, v); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/exec.js new file mode 100644 index 000000000000..5ccd5dcce44d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/exec.js @@ -0,0 +1,27 @@ +class Foo { + accessor a; + + accessor b = 123; + + accessor ['c'] = 456; +} + +let foo = new Foo(); + +expect(foo.a).toBe(undefined); +foo.a = 123; +expect(foo.a).toBe(123); +expect(foo.hasOwnProperty('a')).toBe(false); +expect(Foo.prototype.hasOwnProperty('a')).toBe(true); + +expect(foo.b).toBe(123); +foo.b = 456 +expect(foo.b).toBe(456); +expect(foo.hasOwnProperty('b')).toBe(false); +expect(Foo.prototype.hasOwnProperty('b')).toBe(true); + +expect(foo.c).toBe(456); +foo.c = 789 +expect(foo.c).toBe(789); +expect(foo.hasOwnProperty('c')).toBe(false); +expect(Foo.prototype.hasOwnProperty('c')).toBe(true); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/input.js new file mode 100644 index 000000000000..62dbd0c0381a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + accessor a; + + accessor b = 123; + + accessor ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/output.js new file mode 100644 index 000000000000..1f6ec6aea769 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-public/output.js @@ -0,0 +1,49 @@ +const dec = () => {}; + +var _A = /*#__PURE__*/new WeakMap(); + +var _B = /*#__PURE__*/new WeakMap(); + +var _C = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor() { + babelHelpers.classPrivateFieldInitSpec(this, _A, { + writable: true, + value: void 0 + }); + babelHelpers.classPrivateFieldInitSpec(this, _B, { + writable: true, + value: 123 + }); + babelHelpers.classPrivateFieldInitSpec(this, _C, { + writable: true, + value: 456 + }); + } + + get a() { + return babelHelpers.classPrivateFieldGet(this, _A); + } + + set a(v) { + babelHelpers.classPrivateFieldSet(this, _A, v); + } + + get b() { + return babelHelpers.classPrivateFieldGet(this, _B); + } + + set b(v) { + babelHelpers.classPrivateFieldSet(this, _B, v); + } + + get ['c']() { + return babelHelpers.classPrivateFieldGet(this, _C); + } + + set ['c'](v) { + babelHelpers.classPrivateFieldSet(this, _C, v); + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/exec.js new file mode 100644 index 000000000000..21defb3f24d8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/exec.js @@ -0,0 +1,29 @@ +class Foo { + static accessor #a; + + static accessor #b = 123; + + static getA() { + return this.#a; + } + + static setA(v) { + this.#a = v; + } + + static getB() { + return this.#b; + } + + static setB(v) { + this.#b = v; + } +} + +expect(Foo.getA()).toBe(undefined); +Foo.setA(123) +expect(Foo.getA()).toBe(123); + +expect(Foo.getB()).toBe(123); +Foo.setB(456) +expect(Foo.getB()).toBe(456); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/input.js new file mode 100644 index 000000000000..9e893b86b863 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/input.js @@ -0,0 +1,6 @@ +const dec = () => {}; +class Foo { + static accessor #a; + + static accessor #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/output.js new file mode 100644 index 000000000000..cd052d1aa957 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-private/output.js @@ -0,0 +1,36 @@ +const dec = () => {}; + +class Foo {} + +function _get_a() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _A); +} + +function _set_a(v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _A, v); +} + +function _get_b() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _B); +} + +function _set_b(v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _B, v); +} + +var _b = { + get: _get_b, + set: _set_b +}; +var _a = { + get: _get_a, + set: _set_a +}; +var _A = { + writable: true, + value: void 0 +}; +var _B = { + writable: true, + value: 123 +}; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/exec.js new file mode 100644 index 000000000000..d22a4e710dd8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/exec.js @@ -0,0 +1,22 @@ +class Foo { + static accessor a; + + static accessor b = 123; + + static accessor ['c'] = 456; +} + +expect(Foo.a).toBe(undefined); +Foo.a = 123; +expect(Foo.a).toBe(123); +expect(Foo.hasOwnProperty('a')).toBe(true); + +expect(Foo.b).toBe(123); +Foo.b = 456 +expect(Foo.b).toBe(456); +expect(Foo.hasOwnProperty('b')).toBe(true); + +expect(Foo.c).toBe(456); +Foo.c = 789 +expect(Foo.c).toBe(789); +expect(Foo.hasOwnProperty('c')).toBe(true); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/input.js new file mode 100644 index 000000000000..eb7463cb9fc1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + static accessor a; + + static accessor b = 123; + + static accessor ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/output.js new file mode 100644 index 000000000000..ae182c2ec54d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors--to-es2015/undecorated-static-public/output.js @@ -0,0 +1,41 @@ +const dec = () => {}; + +class Foo { + static get a() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _A); + } + + static set a(v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _A, v); + } + + static get b() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _B); + } + + static set b(v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _B, v); + } + + static get ['c']() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _C); + } + + static set ['c'](v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _C, v); + } + +} + +var _A = { + writable: true, + value: void 0 +}; +var _B = { + writable: true, + value: 123 +}; +var _C = { + writable: true, + value: 456 +}; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/private/input.js new file mode 100644 index 000000000000..aa152db91d94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/private/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec + accessor #a; + + @dec + accessor #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/private/output.js new file mode 100644 index 000000000000..347c3b41dcf1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/private/output.js @@ -0,0 +1,37 @@ +var _init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initProto; + +const dec = () => {}; + +class Foo { + static { + [_init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 1, "a", function () { + return this.#A; + }, function (value) { + this.#A = value; + }], [dec, 1, "b", function () { + return this.#B; + }, function (value) { + this.#B = value; + }]], []); + } + #A = (_initProto(this), _init_a(this)); + + set #a(v) { + _set_a(this, v); + } + + get #a() { + return _get_a(this); + } + + #B = _init_b(this, 123); + + set #b(v) { + _set_b(this, v); + } + + get #b() { + return _get_b(this); + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/public/input.js new file mode 100644 index 000000000000..bd8be5cbe225 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/public/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class Foo { + @dec + accessor a; + + @dec + accessor b = 123; + + @dec + accessor ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/public/output.js new file mode 100644 index 000000000000..ae0f0f9f915a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/public/output.js @@ -0,0 +1,41 @@ +var _init_a, _init_b, _computedKey, _init_computedKey, _initProto; + +const dec = () => {}; + +_computedKey = 'c'; + +class Foo { + static { + [_init_a, _init_b, _init_computedKey, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 1, "a"], [dec, 1, "b"], [dec, 1, _computedKey]], []); + } + #A = (_initProto(this), _init_a(this)); + + get a() { + return this.#A; + } + + set a(v) { + this.#A = v; + } + + #B = _init_b(this, 123); + + get b() { + return this.#B; + } + + set b(v) { + this.#B = v; + } + + #C = _init_computedKey(this, 456); + + get [_computedKey]() { + return this.#C; + } + + set [_computedKey](v) { + this.#C = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-private/input.js new file mode 100644 index 000000000000..c30e61d463bc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-private/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec + static accessor #a; + + @dec + static accessor #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-private/output.js new file mode 100644 index 000000000000..164fcb6545a7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-private/output.js @@ -0,0 +1,40 @@ +var _init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initStatic; + +const dec = () => {}; + +class Foo { + static { + [_init_a, _get_a, _set_a, _init_b, _get_b, _set_b, _initStatic] = babelHelpers.applyDecs2203(this, [[dec, 6, "a", function () { + return this.#A; + }, function (value) { + this.#A = value; + }], [dec, 6, "b", function () { + return this.#B; + }, function (value) { + this.#B = value; + }]], []); + + _initStatic(this); + + } + static #A = _init_a(this); + + set #a(v) { + _set_a(this, v); + } + + get #a() { + return _get_a(this); + } + + static #B = _init_b(this, 123); + + set #b(v) { + _set_b(this, v); + } + + get #b() { + return _get_b(this); + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-public/input.js new file mode 100644 index 000000000000..50f05c065848 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-public/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class Foo { + @dec + static accessor a; + + @dec + static accessor b = 123; + + @dec + static accessor ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-public/output.js new file mode 100644 index 000000000000..150aecee50ed --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/static-public/output.js @@ -0,0 +1,44 @@ +var _init_a, _init_b, _computedKey, _init_computedKey, _initStatic; + +const dec = () => {}; + +_computedKey = 'c'; + +class Foo { + static { + [_init_a, _init_b, _init_computedKey, _initStatic] = babelHelpers.applyDecs2203(this, [[dec, 6, "a"], [dec, 6, "b"], [dec, 6, _computedKey]], []); + + _initStatic(this); + + } + static #A = _init_a(this); + + static get a() { + return this.#A; + } + + static set a(v) { + this.#A = v; + } + + static #B = _init_b(this, 123); + + static get b() { + return this.#B; + } + + static set b(v) { + this.#B = v; + } + + static #C = _init_computedKey(this, 456); + + static get [_computedKey]() { + return this.#C; + } + + static set [_computedKey](v) { + this.#C = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-private/input.js new file mode 100644 index 000000000000..07804cb8a125 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-private/input.js @@ -0,0 +1,6 @@ +const dec = () => {}; +class Foo { + accessor #a; + + accessor #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-private/output.js new file mode 100644 index 000000000000..48bd7037ef2c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-private/output.js @@ -0,0 +1,24 @@ +const dec = () => {}; + +class Foo { + #A; + + get #a() { + return this.#A; + } + + set #a(v) { + this.#A = v; + } + + #B = 123; + + get #b() { + return this.#B; + } + + set #b(v) { + this.#B = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-public/input.js new file mode 100644 index 000000000000..62dbd0c0381a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-public/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + accessor a; + + accessor b = 123; + + accessor ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-public/output.js new file mode 100644 index 000000000000..9dafa0eebbab --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-public/output.js @@ -0,0 +1,34 @@ +const dec = () => {}; + +class Foo { + #A; + + get a() { + return this.#A; + } + + set a(v) { + this.#A = v; + } + + #B = 123; + + get b() { + return this.#B; + } + + set b(v) { + this.#B = v; + } + + #C = 456; + + get ['c']() { + return this.#C; + } + + set ['c'](v) { + this.#C = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-private/input.js new file mode 100644 index 000000000000..9e893b86b863 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-private/input.js @@ -0,0 +1,6 @@ +const dec = () => {}; +class Foo { + static accessor #a; + + static accessor #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-private/output.js new file mode 100644 index 000000000000..985081906eb4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-private/output.js @@ -0,0 +1,24 @@ +const dec = () => {}; + +class Foo { + static #A; + + static get #a() { + return this.#A; + } + + static set #a(v) { + this.#A = v; + } + + static #B = 123; + + static get #b() { + return this.#B; + } + + static set #b(v) { + this.#B = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-public/input.js new file mode 100644 index 000000000000..eb7463cb9fc1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-public/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + static accessor a; + + static accessor b = 123; + + static accessor ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-public/output.js new file mode 100644 index 000000000000..5c287481b56f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-accessors/undecorated-static-public/output.js @@ -0,0 +1,34 @@ +const dec = () => {}; + +class Foo { + static #A; + + static get a() { + return this.#A; + } + + static set a(v) { + this.#A = v; + } + + static #B = 123; + + static get b() { + return this.#B; + } + + static set b(v) { + this.#B = v; + } + + static #C = 456; + + static get ['c']() { + return this.#C; + } + + static set ['c'](v) { + this.#C = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/options.json new file mode 100644 index 000000000000..443b4b4eb858 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]], + "assumptions": { + "constantSuper": true + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-nested-constructor-expression/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-nested-constructor-expression/input.js new file mode 100644 index 000000000000..6bc1a7dbbc4b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-nested-constructor-expression/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +@dec +class Foo extends Bar { + constructor() { + let foo = super(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-nested-constructor-expression/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-nested-constructor-expression/output.js new file mode 100644 index 000000000000..afffeda95f1b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-nested-constructor-expression/output.js @@ -0,0 +1,20 @@ +var _initClass; + +const dec = () => {}; + +let _Foo; + +class Foo extends Bar { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2203(this, [], [dec]); + } + + constructor() { + let foo = super(); + } + + static { + _initClass(); + + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-accessor/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-accessor/input.js new file mode 100644 index 000000000000..b32ea0bd378f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-accessor/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +class Foo extends Bar { + @dec + get #x() { + return super.foo(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-accessor/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-accessor/output.js new file mode 100644 index 000000000000..738186ec1b10 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-accessor/output.js @@ -0,0 +1,22 @@ +var _call_x, _initProto; + +const dec = () => {}; + +class Foo extends Bar { + static { + [_call_x, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 3, "x", function () { + return Bar.prototype.foo.call(this); + }]], []); + } + + constructor(...args) { + super(...args); + + _initProto(this); + } + + get #x() { + return _call_x(this); + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-method/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-method/input.js new file mode 100644 index 000000000000..36f9bd37dfa7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-method/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +class Foo extends Bar { + @dec + #x() { + return super.foo(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-method/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-method/output.js new file mode 100644 index 000000000000..36a1726170fb --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-assumption-constantSuper/super-in-private-method/output.js @@ -0,0 +1,19 @@ +var _call_x, _initProto; + +const dec = () => {}; + +class Foo extends Bar { + static { + [_call_x, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, "x", function () { + return Bar.prototype.foo.call(this); + }]], []); + } + + constructor(...args) { + super(...args); + + _initProto(this); + } + + #x = _call_x; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/expressions/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/expressions/input.js new file mode 100644 index 000000000000..77060bea50ff --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/expressions/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +const A = @dec class A {} +const B = @dec class C {} +const D = @dec class {} +const E = (@dec class {}, 123); +const F = [@dec class G {}, @dec class {}]; +const H = @dec class extends I {}; +const J = @dec class K extends L {}; + +function classFactory() { + return @dec class {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/expressions/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/expressions/output.js new file mode 100644 index 000000000000..d38cab6978eb --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/expressions/output.js @@ -0,0 +1,17 @@ +var _initClass, _A, _class, _initClass2, _C, _class2, _initClass3, _D, _class3, _initClass4, _decorated_class, _class4, _initClass5, _G, _class5, _initClass6, _decorated_class2, _class6, _initClass7, _H, _class7, _initClass8, _K, _class8; + +const dec = () => {}; + +const A = ((_class = class A {}, [_A, _initClass] = babelHelpers.applyDecs2203(_class, [], [dec]), _initClass()), _A); +const B = ((_class2 = class C {}, [_C, _initClass2] = babelHelpers.applyDecs2203(_class2, [], [dec]), _initClass2()), _C); +const D = ((_class3 = class D {}, [_D, _initClass3] = babelHelpers.applyDecs2203(_class3, [], [dec]), _initClass3()), _D); +const E = (((_class4 = class {}, [_decorated_class, _initClass4] = babelHelpers.applyDecs2203(_class4, [], [dec]), _initClass4()), _decorated_class), 123); +const F = [((_class5 = class G {}, [_G, _initClass5] = babelHelpers.applyDecs2203(_class5, [], [dec]), _initClass5()), _G), ((_class6 = class {}, [_decorated_class2, _initClass6] = babelHelpers.applyDecs2203(_class6, [], [dec]), _initClass6()), _decorated_class2)]; +const H = ((_class7 = class H extends I {}, [_H, _initClass7] = babelHelpers.applyDecs2203(_class7, [], [dec]), _initClass7()), _H); +const J = ((_class8 = class K extends L {}, [_K, _initClass8] = babelHelpers.applyDecs2203(_class8, [], [dec]), _initClass8()), _K); + +function classFactory() { + var _initClass9, _decorated_class3, _class9; + + return (_class9 = class {}, [_decorated_class3, _initClass9] = babelHelpers.applyDecs2203(_class9, [], [dec]), _initClass9()), _decorated_class3; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/exec.js new file mode 100644 index 000000000000..889e8c102cf4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/exec.js @@ -0,0 +1,18 @@ +let count = 0; + +function dec1(Klass) { + expect(++count).toBe(1); + expect(Klass.name).toBe('Bar'); +} + +@dec1 +class Bar {} + +function dec2(Klass) { + expect(++count).toBe(2); + expect(Klass.name).toBe('Foo'); + expect(Object.getPrototypeOf(Klass)).toBe(Bar); +} + +@dec2 +class Foo extends Bar {} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/input.js new file mode 100644 index 000000000000..96a13523506c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/input.js @@ -0,0 +1,7 @@ +const dec1 = () => {}; +const dec2 = () => {}; +@dec1 +class Bar {} + +@dec2 +class Foo extends Bar {} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/output.js new file mode 100644 index 000000000000..1c00e365582d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/inheritance/output.js @@ -0,0 +1,21 @@ +var _initClass, _initClass2; + +const dec1 = () => {}; + +const dec2 = () => {}; + +let _Bar; + +class Bar {} + +[_Bar, _initClass] = babelHelpers.applyDecs2203(Bar, [], [dec1]); + +_initClass(); + +let _Foo; + +class Foo extends _Bar {} + +[_Foo, _initClass2] = babelHelpers.applyDecs2203(Foo, [], [dec2]); + +_initClass2(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/exec.js new file mode 100644 index 000000000000..aefc3ba5b88c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/exec.js @@ -0,0 +1,41 @@ +function dec1(Foo, { addInitializer }) { + expect(Foo.field).toBe(undefined); + addInitializer(() => { + Foo.initField = 123; + }); +} + +@dec1 +class Foo { + static { + expect(this.initField).toBe(undefined); + } + + static field = 123; +} + +expect(Foo.initField).toBe(123); +expect(Foo.field).toBe(123); + +function dec2(Bar, { addInitializer }) { + expect(Bar.field).toBe(123); + expect(Bar.otherField).toBe(undefined); + expect(Bar.initField).toBe(123); + addInitializer(() => { + Bar.initField = 456; + }); +} + +@dec2 +class Bar extends Foo { + static { + expect(this.initField).toBe(123); + this.otherField = 456; + } + + static field = 456; +} + +expect(Bar.initField).toBe(456); +expect(Bar.field).toBe(456); +expect(Bar.otherField).toBe(456); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/input.js new file mode 100644 index 000000000000..87c785d39a93 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +@dec +class Foo { + static field = 123; +} + +@dec +class Bar extends Foo { + static { + this.otherField = 456; + } + + static field = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/output.js new file mode 100644 index 000000000000..2b98ee90461d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/initializers/output.js @@ -0,0 +1,31 @@ +var _initClass, _temp, _initClass2, _temp2; + +const dec = () => {}; + +let _Foo; + +new (_temp = class extends babelHelpers.identity { + constructor() { + (super(_Foo), babelHelpers.defineProperty(this, "field", 123)), _initClass(); + } + +}, (() => { + class Foo {} + + [_Foo, _initClass] = babelHelpers.applyDecs2203(Foo, [], [dec]); +})(), _temp)(); + +let _Bar; + +new (_temp2 = class extends babelHelpers.identity { + constructor() { + (super(_Bar), babelHelpers.defineProperty(this, "field", ((() => { + this.otherField = 456; + })(), 123))), _initClass2(); + } + +}, (() => { + class Bar extends _Foo {} + + [_Bar, _initClass2] = babelHelpers.applyDecs2203(Bar, [], [dec]); +})(), _temp2)(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/exec.js new file mode 100644 index 000000000000..2f4e342e3eee --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/exec.js @@ -0,0 +1,33 @@ +let hasX, hasM, OriginalFoo; + +class Bar {} + +function dec(Foo) { + OriginalFoo = Foo; + return Bar; +} + +@dec +class Foo { + static #x; + static #m() {} + + static x; + static m() {} + + static { + hasX = o => #x in o; + hasM = o => #m in o; + } +} + +expect(hasX(Bar)).toBe(true); +expect(hasM(Bar)).toBe(true); +expect(hasX(OriginalFoo)).toBe(false); +expect(hasM(OriginalFoo)).toBe(false); + +expect(Bar.hasOwnProperty("x")).toBe(true); +expect(OriginalFoo.hasOwnProperty("x")).toBe(false); + +expect(Bar.hasOwnProperty("m")).toBe(false); +expect(OriginalFoo.hasOwnProperty("m")).toBe(true); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/input.js new file mode 100644 index 000000000000..e8c62db59046 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/input.js @@ -0,0 +1,16 @@ +const dec = () => {}; +let hasX, hasM; + +@dec +class Foo { + static #x; + static #m() {} + + static x; + static m() {} + + static { + hasX = o => #x in o; + hasM = o => #m in o; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/output.js new file mode 100644 index 000000000000..361a921adc47 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-installed-on-correct-class/output.js @@ -0,0 +1,30 @@ +var _initClass, _x, _m, _temp; + +const dec = () => {}; + +let hasX, hasM; + +let _Foo; + +new (_x = /*#__PURE__*/new WeakMap(), _m = /*#__PURE__*/new WeakSet(), (_temp = class extends babelHelpers.identity { + constructor() { + (super(_Foo), babelHelpers.classPrivateMethodInitSpec(this, _m), babelHelpers.classPrivateFieldInitSpec(this, _x, { + writable: true, + value: void 0 + }), babelHelpers.defineProperty(this, "x", void 0)), (() => { + hasX = o => _x.has(o); + + hasM = o => _m.has(o); + })(), _initClass(); + } + +}, (() => { + class Foo { + static m() {} + + } + + [_Foo, _initClass] = babelHelpers.applyDecs2203(Foo, [], [dec]); +})(), _temp))(); + +function _m2() {} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/exec.js new file mode 100644 index 000000000000..6b55df43edc8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/exec.js @@ -0,0 +1,19 @@ + +class Bar {} + +let _this, _this2, _this3; + +@(() => Bar) +class Foo { + static { + _this = this; + } + static field = (_this2 = this); + static { + _this3 = this; + } +} + +expect(_this).toBe(Bar); +expect(_this2).toBe(Bar); +expect(_this3).toBe(Bar); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/input.js new file mode 100644 index 000000000000..1b8d46cf3ac0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +@dec +class Foo { + static { + this + } + static field = this; + static { + this + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/output.js new file mode 100644 index 000000000000..71b417e0a02e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-static-this/output.js @@ -0,0 +1,20 @@ +var _initClass, _temp; + +const dec = () => {}; + +let _Foo; + +new (_temp = class extends babelHelpers.identity { + constructor() { + (super(_Foo), babelHelpers.defineProperty(this, "field", ((() => { + this; + })(), this))), (() => { + this; + })(), _initClass(); + } + +}, (() => { + class Foo {} + + [_Foo, _initClass] = babelHelpers.applyDecs2203(Foo, [], [dec]); +})(), _temp)(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/exec.js new file mode 100644 index 000000000000..739e33a05be5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/exec.js @@ -0,0 +1,17 @@ +let replaced; + +function dec(Klass) { + replaced = class extends Klass {}; + + return replaced; +} + +const Foo = @dec class Bar { + static bar = new Bar(); +}; + +const foo = new Foo(); + +expect(Foo).toBe(replaced); +expect(Foo.bar).toBeInstanceOf(replaced); +expect(foo).toBeInstanceOf(replaced); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/input.js new file mode 100644 index 000000000000..0cd5e45110b7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +const Foo = @dec class Bar { + bar = new Bar(); +}; + +const foo = new Foo(); + diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/output.js new file mode 100644 index 000000000000..c4cfde48efbc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement-with-expr/output.js @@ -0,0 +1,11 @@ +var _initClass, _Bar, _class; + +const dec = () => {}; + +const Foo = ((_class = class Bar { + constructor() { + babelHelpers.defineProperty(this, "bar", new _Bar()); + } + +}, [_Bar, _initClass] = babelHelpers.applyDecs2203(_class, [], [dec]), _initClass()), _Bar); +const foo = new Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/exec.js new file mode 100644 index 000000000000..c8dc49c0d85e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/exec.js @@ -0,0 +1,19 @@ + +let replaced; + +function dec(Klass) { + replaced = class extends Klass {}; + + return replaced; +} + +@dec +class Foo { + static foo = new Foo(); +} + +const foo = new Foo(); + +expect(Foo).toBe(replaced); +expect(Foo.foo).toBeInstanceOf(replaced); +expect(foo).toBeInstanceOf(replaced); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/input.js new file mode 100644 index 000000000000..8f0a4dfe092f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +@dec +class Foo { + static foo = new Foo(); +} + +const foo = new Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/output.js new file mode 100644 index 000000000000..4ede0640591a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes--to-es2015/replacement/output.js @@ -0,0 +1,17 @@ +var _initClass, _temp; + +const dec = () => {}; + +let _Foo; + +new (_temp = class extends babelHelpers.identity { + constructor() { + (super(_Foo), babelHelpers.defineProperty(this, "foo", new _Foo())), _initClass(); + } + +}, (() => { + class Foo {} + + [_Foo, _initClass] = babelHelpers.applyDecs2203(Foo, [], [dec]); +})(), _temp)(); +const foo = new _Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/expressions/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/expressions/input.js new file mode 100644 index 000000000000..77060bea50ff --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/expressions/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +const A = @dec class A {} +const B = @dec class C {} +const D = @dec class {} +const E = (@dec class {}, 123); +const F = [@dec class G {}, @dec class {}]; +const H = @dec class extends I {}; +const J = @dec class K extends L {}; + +function classFactory() { + return @dec class {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/expressions/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/expressions/output.js new file mode 100644 index 000000000000..4d82a70b0f00 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/expressions/output.js @@ -0,0 +1,89 @@ +var _initClass, _A, _initClass2, _C, _initClass3, _D, _initClass4, _decorated_class, _initClass5, _G, _initClass6, _decorated_class2, _initClass7, _H, _initClass8, _K; + +const dec = () => {}; + +const A = (class A { + static { + [_A, _initClass] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass(); + + } +}, _A); +const B = (class C { + static { + [_C, _initClass2] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass2(); + + } +}, _C); +const D = (class D { + static { + [_D, _initClass3] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass3(); + + } +}, _D); +const E = ((class { + static { + [_decorated_class, _initClass4] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass4(); + + } +}, _decorated_class), 123); +const F = [(class G { + static { + [_G, _initClass5] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass5(); + + } +}, _G), (class { + static { + [_decorated_class2, _initClass6] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass6(); + + } +}, _decorated_class2)]; +const H = (class H extends I { + static { + [_H, _initClass7] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass7(); + + } +}, _H); +const J = (class K extends L { + static { + [_K, _initClass8] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass8(); + + } +}, _K); + +function classFactory() { + var _initClass9, _decorated_class3; + + return class { + static { + [_decorated_class3, _initClass9] = babelHelpers.applyDecs2203(this, [], [dec]); + } + static { + _initClass9(); + + } + }, _decorated_class3; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/inheritance/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/inheritance/input.js new file mode 100644 index 000000000000..0657f6e2b364 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/inheritance/input.js @@ -0,0 +1,6 @@ +const dec = () => {}; +@dec1 +class Bar {} + +@dec2 +class Foo extends Bar {} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/inheritance/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/inheritance/output.js new file mode 100644 index 000000000000..2fda665bd499 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/inheritance/output.js @@ -0,0 +1,31 @@ +var _initClass, _dec, _initClass2, _dec2; + +const dec = () => {}; + +let _Bar; + +_dec = dec1; + +class Bar { + static { + [_Bar, _initClass] = babelHelpers.applyDecs2203(this, [], [_dec]); + } + static { + _initClass(); + + } +} + +let _Foo; + +_dec2 = dec2; + +class Foo extends _Bar { + static { + [_Foo, _initClass2] = babelHelpers.applyDecs2203(this, [], [_dec2]); + } + static { + _initClass2(); + + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/initializers/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/initializers/input.js new file mode 100644 index 000000000000..87c785d39a93 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/initializers/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +@dec +class Foo { + static field = 123; +} + +@dec +class Bar extends Foo { + static { + this.otherField = 456; + } + + static field = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/initializers/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/initializers/output.js new file mode 100644 index 000000000000..ea8301d94ecc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/initializers/output.js @@ -0,0 +1,43 @@ +var _initClass, _initClass2; + +const dec = () => {}; + +let _Foo; + +new class extends babelHelpers.identity { + static { + class Foo { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2203(this, [], [dec]); + } + } + + } + field = 123; + + constructor() { + super(_Foo), _initClass(); + } + +}(); + +let _Bar; + +new class extends babelHelpers.identity { + static { + class Bar extends _Foo { + static { + [_Bar, _initClass2] = babelHelpers.applyDecs2203(this, [], [dec]); + } + } + + } + field = ((() => { + this.otherField = 456; + })(), 123); + + constructor() { + super(_Bar), _initClass2(); + } + +}(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-installed-on-correct-class/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-installed-on-correct-class/input.js new file mode 100644 index 000000000000..e8c62db59046 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-installed-on-correct-class/input.js @@ -0,0 +1,16 @@ +const dec = () => {}; +let hasX, hasM; + +@dec +class Foo { + static #x; + static #m() {} + + static x; + static m() {} + + static { + hasX = o => #x in o; + hasM = o => #m in o; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-installed-on-correct-class/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-installed-on-correct-class/output.js new file mode 100644 index 000000000000..0aeb619ee742 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-installed-on-correct-class/output.js @@ -0,0 +1,35 @@ +var _initClass; + +const dec = () => {}; + +let hasX, hasM; + +let _Foo; + +new class extends babelHelpers.identity { + static { + class Foo { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2203(this, [], [dec]); + } + + static m() {} + + } + + } + #x; + + #m() {} + + x; + + constructor() { + super(_Foo), (() => { + hasX = o => #x in o; + + hasM = o => #m in o; + })(), _initClass(); + } + +}(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-this/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-this/input.js new file mode 100644 index 000000000000..1b8d46cf3ac0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-this/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +@dec +class Foo { + static { + this + } + static field = this; + static { + this + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-this/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-this/output.js new file mode 100644 index 000000000000..1a5de927563c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-static-this/output.js @@ -0,0 +1,26 @@ +var _initClass; + +const dec = () => {}; + +let _Foo; + +new class extends babelHelpers.identity { + static { + class Foo { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2203(this, [], [dec]); + } + } + + } + field = ((() => { + this; + })(), this); + + constructor() { + super(_Foo), (() => { + this; + })(), _initClass(); + } + +}(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-with-expr/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-with-expr/input.js new file mode 100644 index 000000000000..0cd5e45110b7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-with-expr/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +const Foo = @dec class Bar { + bar = new Bar(); +}; + +const foo = new Foo(); + diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-with-expr/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-with-expr/output.js new file mode 100644 index 000000000000..a623e9f228ef --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement-with-expr/output.js @@ -0,0 +1,15 @@ +var _initClass, _Bar; + +const dec = () => {}; + +const Foo = (class Bar { + static { + [_Bar, _initClass] = babelHelpers.applyDecs2203(this, [], [dec]); + } + bar = new _Bar(); + static { + _initClass(); + + } +}, _Bar); +const foo = new Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement/input.js new file mode 100644 index 000000000000..8f0a4dfe092f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +@dec +class Foo { + static foo = new Foo(); +} + +const foo = new Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement/output.js new file mode 100644 index 000000000000..63f25772c6af --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-classes/replacement/output.js @@ -0,0 +1,23 @@ +var _initClass; + +const dec = () => {}; + +let _Foo; + +new class extends babelHelpers.identity { + static { + class Foo { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2203(this, [], [dec]); + } + } + + } + foo = new _Foo(); + + constructor() { + super(_Foo), _initClass(); + } + +}(); +const foo = new _Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/exec.js new file mode 100644 index 000000000000..49fad189f4e2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/exec.js @@ -0,0 +1,33 @@ +var i = 0; + +function getKey() { + return (i++).toString(); +} + +let elements = []; + +function dec(fn, context) { + elements.push({ fn, context }); +} + +class Foo { + @dec + [getKey()]() { + return 1; + } + + @dec + [getKey()]() { + return 2; + } +} + +expect(elements).toHaveLength(2); + +expect(elements[0].context.name).toBe("0"); +expect(elements[0].fn()).toBe(1); + +expect(elements[1].context.name).toBe("1"); +expect(elements[1].fn()).toBe(2); + +expect(i).toBe(2); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/input.js new file mode 100644 index 000000000000..fd4743f81bc7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +class Foo { + @dec + [getKey()]() { + return 1; + } + + @dec + [getKey()]() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/output.js new file mode 100644 index 000000000000..5ed10d296d3b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-ast/output.js @@ -0,0 +1,23 @@ +var _computedKey, _computedKey2, _initProto; + +const dec = () => {}; + +_computedKey = getKey(); +_computedKey2 = getKey(); + +class Foo { + constructor(...args) { + _initProto(this); + } + + [_computedKey]() { + return 1; + } + + [_computedKey2]() { + return 2; + } + +} + +[_initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 2, _computedKey], [dec, 2, _computedKey2]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/exec.js new file mode 100644 index 000000000000..c97e2293ac96 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/exec.js @@ -0,0 +1,29 @@ +expect(() => { + var i = 0; + var j = 0; + + function getKeyI() { + return (i++).toString(); + } + function getKeyJ() { + return (j++).toString(); + } + + let elements = []; + + function dec(fn, context) { + elements.push({ fn, context }); + } + + class Foo { + @dec + [getKeyI()]() { + return 1; + } + + @dec + [getKeyJ()]() { + return 2; + } + } +}).toThrow("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: 0") diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/input.js new file mode 100644 index 000000000000..0f6e2ca31d39 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +class Foo { + @dec + [getKeyI()]() { + return 1; + } + + @dec + [getKeyJ()]() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/output.js new file mode 100644 index 000000000000..4f1d223b9838 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/computed-keys-same-value/output.js @@ -0,0 +1,23 @@ +var _computedKey, _computedKey2, _initProto; + +const dec = () => {}; + +_computedKey = getKeyI(); +_computedKey2 = getKeyJ(); + +class Foo { + constructor(...args) { + _initProto(this); + } + + [_computedKey]() { + return 1; + } + + [_computedKey2]() { + return 2; + } + +} + +[_initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 2, _computedKey], [dec, 2, _computedKey2]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/exec.js new file mode 100644 index 000000000000..72e253d55578 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/exec.js @@ -0,0 +1,23 @@ +let elements = []; + +function dec(val, context) { + elements.push({ val, context }); +} + +class Foo { + @dec + a = 123; + + @dec + a() { + return 1; + } +} + +expect(elements).toHaveLength(2); + +expect(elements[0].context.name).toBe("a"); +expect(elements[0].val()).toBe(1); + +expect(elements[1].context.name).toBe("a"); +expect(elements[1].val).toBe(undefined); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/input.js new file mode 100644 index 000000000000..e2bfd2a7b415 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/input.js @@ -0,0 +1,10 @@ +const dec = () => {}; +class Foo { + @dec + a = 123; + + @dec + a() { + return 1; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/output.js new file mode 100644 index 000000000000..0cc5dce15176 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/method-and-field/output.js @@ -0,0 +1,16 @@ +var _init_a, _initProto; + +const dec = () => {}; + +class Foo { + constructor() { + babelHelpers.defineProperty(this, "a", (_initProto(this), _init_a(this, 123))); + } + + a() { + return 1; + } + +} + +[_init_a, _initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 2, "a"], [dec, 0, "a"]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/exec.js new file mode 100644 index 000000000000..9e270b2a7488 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/exec.js @@ -0,0 +1,19 @@ +expect(() => { + let elements = []; + + function dec(val, context) { + elements.push({ val, context }); + } + + class Foo { + @dec + a() { + return 1; + } + + @dec + a() { + return 2; + } + } +}).toThrow("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: a") diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/input.js new file mode 100644 index 000000000000..ab961fbc9dfb --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +class Foo { + @dec + a() { + return 1; + } + + @dec + a() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/output.js new file mode 100644 index 000000000000..f195d75e01b4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/methods-with-same-key/output.js @@ -0,0 +1,20 @@ +var _initProto; + +const dec = () => {}; + +class Foo { + constructor(...args) { + _initProto(this); + } + + a() { + return 1; + } + + a() { + return 2; + } + +} + +[_initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 2, "a"], [dec, 2, "a"]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-ast/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-ast/input.js new file mode 100644 index 000000000000..fd4743f81bc7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-ast/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +class Foo { + @dec + [getKey()]() { + return 1; + } + + @dec + [getKey()]() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-ast/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-ast/output.js new file mode 100644 index 000000000000..063d219d6033 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-ast/output.js @@ -0,0 +1,25 @@ +var _computedKey, _computedKey2, _initProto; + +const dec = () => {}; + +_computedKey = getKey(); +_computedKey2 = getKey(); + +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, _computedKey], [dec, 2, _computedKey2]], []); + } + + constructor(...args) { + _initProto(this); + } + + [_computedKey]() { + return 1; + } + + [_computedKey2]() { + return 2; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-value/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-value/input.js new file mode 100644 index 000000000000..0f6e2ca31d39 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-value/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +class Foo { + @dec + [getKeyI()]() { + return 1; + } + + @dec + [getKeyJ()]() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-value/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-value/output.js new file mode 100644 index 000000000000..1eafe7d1ef90 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/computed-keys-same-value/output.js @@ -0,0 +1,25 @@ +var _computedKey, _computedKey2, _initProto; + +const dec = () => {}; + +_computedKey = getKeyI(); +_computedKey2 = getKeyJ(); + +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, _computedKey], [dec, 2, _computedKey2]], []); + } + + constructor(...args) { + _initProto(this); + } + + [_computedKey]() { + return 1; + } + + [_computedKey2]() { + return 2; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/method-and-field/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/method-and-field/input.js new file mode 100644 index 000000000000..e2bfd2a7b415 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/method-and-field/input.js @@ -0,0 +1,10 @@ +const dec = () => {}; +class Foo { + @dec + a = 123; + + @dec + a() { + return 1; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/method-and-field/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/method-and-field/output.js new file mode 100644 index 000000000000..818a4de6d213 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/method-and-field/output.js @@ -0,0 +1,15 @@ +var _init_a, _initProto; + +const dec = () => {}; + +class Foo { + static { + [_init_a, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, "a"], [dec, 0, "a"]], []); + } + a = (_initProto(this), _init_a(this, 123)); + + a() { + return 1; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/methods-with-same-key/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/methods-with-same-key/input.js new file mode 100644 index 000000000000..ab961fbc9dfb --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/methods-with-same-key/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +class Foo { + @dec + a() { + return 1; + } + + @dec + a() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/methods-with-same-key/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/methods-with-same-key/output.js new file mode 100644 index 000000000000..497aee692657 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/methods-with-same-key/output.js @@ -0,0 +1,22 @@ +var _initProto; + +const dec = () => {}; + +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, "a"], [dec, 2, "a"]], []); + } + + constructor(...args) { + _initProto(this); + } + + a() { + return 1; + } + + a() { + return 2; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-duplicated-keys/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-anonymous/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-anonymous/input.mjs new file mode 100644 index 000000000000..05db70faed30 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-anonymous/input.mjs @@ -0,0 +1 @@ +export default @dec class A {} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-anonymous/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-anonymous/output.mjs new file mode 100644 index 000000000000..6ebcc322bb71 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-anonymous/output.mjs @@ -0,0 +1,17 @@ +var _initClass, _dec; + +let _A; + +_dec = dec; + +class A { + static { + [_A, _initClass] = babelHelpers.applyDecs2203(this, [], [_dec]); + } + static { + _initClass(); + + } +} + +export { _A as default }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-named/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-named/input.mjs new file mode 100644 index 000000000000..31cdac17444e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-named/input.mjs @@ -0,0 +1 @@ +export default @dec class {} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-named/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-named/output.mjs new file mode 100644 index 000000000000..c052f17f84ab --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/default-named/output.mjs @@ -0,0 +1,17 @@ +var _initClass, _dec; + +let _default2; + +_dec = dec; + +class _default { + static { + [_default2, _initClass] = babelHelpers.applyDecs2203(this, [], [_dec]); + } + static { + _initClass(); + + } +} + +export { _default2 as default }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/member-decorator/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/member-decorator/input.mjs new file mode 100644 index 000000000000..f72e0e9c2249 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/member-decorator/input.mjs @@ -0,0 +1,3 @@ +export class A { + @dec x; +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/member-decorator/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/member-decorator/output.mjs new file mode 100644 index 000000000000..9ee437055ce9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/member-decorator/output.mjs @@ -0,0 +1,9 @@ +var _dec, _init_x; + +_dec = dec; +export class A { + static { + [_init_x] = babelHelpers.applyDecs2203(this, [[_dec, 0, "x"]], []); + } + x = _init_x(this); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/named/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/named/input.mjs new file mode 100644 index 000000000000..367f946714b0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/named/input.mjs @@ -0,0 +1 @@ +export @dec class A {} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/named/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/named/output.mjs new file mode 100644 index 000000000000..755c70108fa6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/named/output.mjs @@ -0,0 +1,17 @@ +var _initClass, _dec; + +let _A; + +_dec = dec; + +class A { + static { + [_A, _initClass] = babelHelpers.applyDecs2203(this, [], [_dec]); + } + static { + _initClass(); + + } +} + +export { _A as A }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/no-decorators/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/no-decorators/input.mjs new file mode 100644 index 000000000000..bc88730f95a8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/no-decorators/input.mjs @@ -0,0 +1,4 @@ +export class A {} + +class B {} +export { B }; \ No newline at end of file diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/no-decorators/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/no-decorators/output.mjs new file mode 100644 index 000000000000..f95acfebc1c9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/no-decorators/output.mjs @@ -0,0 +1,5 @@ +export class A {} + +class B {} + +export { B }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-exported/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/exec.js new file mode 100644 index 000000000000..a2f8421a7a08 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/exec.js @@ -0,0 +1,37 @@ +function dec(_v, context) { + return function (v) { + this[context.name + 'Context'] = context; + return (v || 1) + 1; + } +} + +class Foo { + @dec + #a; + + @dec + #b = 123; +} + +let foo = new Foo(); + +const aContext = foo['#aContext']; +const bContext = foo['#bContext']; + +expect(aContext.access.get.call(foo)).toBe(2); +aContext.access.set.call(foo, 123); +expect(aContext.access.get.call(foo)).toBe(123); +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('field'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('undefined'); + +expect(bContext.access.get.call(foo)).toBe(124); +bContext.access.set.call(foo, 123); +expect(bContext.access.get.call(foo)).toBe(123); +expect(bContext.name).toBe('#b'); +expect(bContext.kind).toBe('field'); +expect(bContext.static).toBe(false); +expect(bContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('undefined'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/input.js new file mode 100644 index 000000000000..2cd77e99b7e3 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec + #a; + + @dec + #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/output.js new file mode 100644 index 000000000000..88b71d52b3c1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/private/output.js @@ -0,0 +1,31 @@ +var _init_a, _init_b; + +const dec = () => {}; + +var _a = /*#__PURE__*/new WeakMap(); + +var _b = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor() { + babelHelpers.classPrivateFieldInitSpec(this, _a, { + writable: true, + value: _init_a(this) + }); + babelHelpers.classPrivateFieldInitSpec(this, _b, { + writable: true, + value: _init_b(this, 123) + }); + } + +} + +[_init_a, _init_b] = babelHelpers.applyDecs2203(Foo, [[dec, 0, "a", function () { + return babelHelpers.classPrivateFieldGet(this, _a); +}, function (value) { + babelHelpers.classPrivateFieldSet(this, _a, value); +}], [dec, 0, "b", function () { + return babelHelpers.classPrivateFieldGet(this, _b); +}, function (value) { + babelHelpers.classPrivateFieldSet(this, _b, value); +}]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/exec.js new file mode 100644 index 000000000000..70883de50493 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/exec.js @@ -0,0 +1,61 @@ +function dec(_v, context) { + return function (v) { + this[context.name + 'Context'] = context; + return (v || 1) + 1; + } +} + +class Foo { + @dec + a; + + @dec + b = 123; + + @dec + ['c'] = 456; +} + +let foo = new Foo(); + +const aContext = foo['aContext']; +const bContext = foo['bContext']; +const cContext = foo['cContext']; + +expect(foo.a).toBe(2); +expect(aContext.access.get.call(foo)).toBe(2); +foo.a = 123; +expect(foo.a).toBe(123); +expect(aContext.access.get.call(foo)).toBe(123); +aContext.access.set.call(foo, 456); +expect(foo.a).toBe(456); +expect(aContext.access.get.call(foo)).toBe(456); +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('field'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('undefined'); +expect(foo.hasOwnProperty('a')).toBe(true); +expect(Foo.prototype.hasOwnProperty('a')).toBe(false); + +expect(foo.b).toBe(124); +foo.b = 123; +expect(foo.b).toBe(123); +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('field'); +expect(bContext.static).toBe(false); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('undefined'); +expect(foo.hasOwnProperty('b')).toBe(true); +expect(Foo.prototype.hasOwnProperty('b')).toBe(false); + +expect(foo.c).toBe(457); +foo.c = 456; +expect(foo.c).toBe(456); +expect(cContext.name).toBe('c'); +expect(cContext.kind).toBe('field'); +expect(cContext.static).toBe(false); +expect(cContext.private).toBe(false); +expect(typeof cContext.addInitializer).toBe('undefined'); +expect(foo.hasOwnProperty('c')).toBe(true); +expect(Foo.prototype.hasOwnProperty('c')).toBe(false); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/input.js new file mode 100644 index 000000000000..16a36d324047 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class Foo { + @dec + a; + + @dec + b = 123; + + @dec + ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/output.js new file mode 100644 index 000000000000..6b06bcb4efd9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/public/output.js @@ -0,0 +1,16 @@ +var _init_a, _init_b, _computedKey, _init_computedKey; + +const dec = () => {}; + +_computedKey = 'c'; + +class Foo { + constructor() { + babelHelpers.defineProperty(this, "a", _init_a(this)); + babelHelpers.defineProperty(this, "b", _init_b(this, 123)); + babelHelpers.defineProperty(this, _computedKey, _init_computedKey(this, 456)); + } + +} + +[_init_a, _init_b, _init_computedKey] = babelHelpers.applyDecs2203(Foo, [[dec, 0, "a"], [dec, 0, "b"], [dec, 0, _computedKey]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..586dc935111d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/exec.js @@ -0,0 +1,35 @@ +function dec(_v, context) { + return function (v) { + this[context.name + 'Context'] = context; + return (v || 1) + 1; + } +} + +class Foo { + @dec + static #a; + + @dec + static #b = 123; +} + +const aContext = Foo['#aContext']; +const bContext = Foo['#bContext']; + +expect(aContext.access.get.call(Foo)).toBe(2); +aContext.access.set.call(Foo, 123); +expect(aContext.access.get.call(Foo)).toBe(123); +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('field'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('undefined'); + +expect(bContext.access.get.call(Foo)).toBe(124); +bContext.access.set.call(Foo, 123); +expect(bContext.access.get.call(Foo)).toBe(123); +expect(bContext.name).toBe('#b'); +expect(bContext.kind).toBe('field'); +expect(bContext.static).toBe(true); +expect(bContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('undefined'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/input.js new file mode 100644 index 000000000000..bc6f56f17527 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec + static #a; + + @dec + static #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/output.js new file mode 100644 index 000000000000..5f2d9e1e71bf --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-private/output.js @@ -0,0 +1,23 @@ +var _init_a, _init_b; + +const dec = () => {}; + +class Foo {} + +[_init_a, _init_b] = babelHelpers.applyDecs2203(Foo, [[dec, 5, "a", function () { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _a); +}, function (value) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _a, value); +}], [dec, 5, "b", function () { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _b); +}, function (value) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _b, value); +}]], []); +var _a = { + writable: true, + value: _init_a(Foo) +}; +var _b = { + writable: true, + value: _init_b(Foo, 123) +}; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..534fb5d049c2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/exec.js @@ -0,0 +1,56 @@ +function dec(_v, context) { + return function (v) { + this[context.name + 'Context'] = context; + return (v || 1) + 1; + } +} + +class Foo { + @dec + static a; + + @dec + static b = 123; + + @dec + static ['c'] = 456; +} + +const aContext = Foo['aContext']; +const bContext = Foo['bContext']; +const cContext = Foo['cContext']; + +expect(Foo.a).toBe(2); +expect(aContext.access.get.call(Foo)).toBe(2); +Foo.a = 123; +expect(Foo.a).toBe(123); +expect(aContext.access.get.call(Foo)).toBe(123); +aContext.access.set.call(Foo, 456); +expect(Foo.a).toBe(456); +expect(aContext.access.get.call(Foo)).toBe(456); +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('field'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('undefined'); +expect(Foo.hasOwnProperty('a')).toBe(true); + +expect(Foo.b).toBe(124); +Foo.b = 123; +expect(Foo.b).toBe(123); +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('field'); +expect(bContext.static).toBe(true); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('undefined'); +expect(Foo.hasOwnProperty('b')).toBe(true); + +expect(Foo.c).toBe(457); +Foo.c = 456; +expect(Foo.c).toBe(456); +expect(cContext.name).toBe('c'); +expect(cContext.kind).toBe('field'); +expect(cContext.static).toBe(true); +expect(cContext.private).toBe(false); +expect(typeof cContext.addInitializer).toBe('undefined'); +expect(Foo.hasOwnProperty('c')).toBe(true); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/input.js new file mode 100644 index 000000000000..e7e44bf1ec16 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class Foo { + @dec + static a; + + @dec + static b = 123; + + @dec + static ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/output.js new file mode 100644 index 000000000000..0c5bce6cafed --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields--to-es2015/static-public/output.js @@ -0,0 +1,12 @@ +var _init_a, _init_b, _computedKey, _init_computedKey; + +const dec = () => {}; + +_computedKey = 'c'; + +class Foo {} + +[_init_a, _init_b, _init_computedKey] = babelHelpers.applyDecs2203(Foo, [[dec, 5, "a"], [dec, 5, "b"], [dec, 5, _computedKey]], []); +babelHelpers.defineProperty(Foo, "a", _init_a(Foo)); +babelHelpers.defineProperty(Foo, "b", _init_b(Foo, 123)); +babelHelpers.defineProperty(Foo, _computedKey, _init_computedKey(Foo, 456)); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/private/input.js new file mode 100644 index 000000000000..2cd77e99b7e3 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/private/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec + #a; + + @dec + #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/private/output.js new file mode 100644 index 000000000000..6d53d088914b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/private/output.js @@ -0,0 +1,19 @@ +var _init_a, _init_b; + +const dec = () => {}; + +class Foo { + static { + [_init_a, _init_b] = babelHelpers.applyDecs2203(this, [[dec, 0, "a", function () { + return this.#a; + }, function (value) { + this.#a = value; + }], [dec, 0, "b", function () { + return this.#b; + }, function (value) { + this.#b = value; + }]], []); + } + #a = _init_a(this); + #b = _init_b(this, 123); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/public/input.js new file mode 100644 index 000000000000..16a36d324047 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/public/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class Foo { + @dec + a; + + @dec + b = 123; + + @dec + ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/public/output.js new file mode 100644 index 000000000000..fc3b6eb61e64 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/public/output.js @@ -0,0 +1,14 @@ +var _init_a, _init_b, _computedKey, _init_computedKey; + +const dec = () => {}; + +_computedKey = 'c'; + +class Foo { + static { + [_init_a, _init_b, _init_computedKey] = babelHelpers.applyDecs2203(this, [[dec, 0, "a"], [dec, 0, "b"], [dec, 0, _computedKey]], []); + } + a = _init_a(this); + b = _init_b(this, 123); + [_computedKey] = _init_computedKey(this, 456); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-private/input.js new file mode 100644 index 000000000000..bc6f56f17527 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-private/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec + static #a; + + @dec + static #b = 123; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-private/output.js new file mode 100644 index 000000000000..f67f3b81e367 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-private/output.js @@ -0,0 +1,19 @@ +var _init_a, _init_b; + +const dec = () => {}; + +class Foo { + static { + [_init_a, _init_b] = babelHelpers.applyDecs2203(this, [[dec, 5, "a", function () { + return this.#a; + }, function (value) { + this.#a = value; + }], [dec, 5, "b", function () { + return this.#b; + }, function (value) { + this.#b = value; + }]], []); + } + static #a = _init_a(this); + static #b = _init_b(this, 123); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-public/input.js new file mode 100644 index 000000000000..e7e44bf1ec16 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-public/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class Foo { + @dec + static a; + + @dec + static b = 123; + + @dec + static ['c'] = 456; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-public/output.js new file mode 100644 index 000000000000..3625ff464717 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-fields/static-public/output.js @@ -0,0 +1,14 @@ +var _init_a, _init_b, _computedKey, _init_computedKey; + +const dec = () => {}; + +_computedKey = 'c'; + +class Foo { + static { + [_init_a, _init_b, _init_computedKey] = babelHelpers.applyDecs2203(this, [[dec, 5, "a"], [dec, 5, "b"], [dec, 5, _computedKey]], []); + } + static a = _init_a(this); + static b = _init_b(this, 123); + static [_computedKey] = _init_computedKey(this, 456); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/exec.js new file mode 100644 index 000000000000..a7ffbd9d4ee6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/exec.js @@ -0,0 +1,37 @@ +function dec(get, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function () { + return get.call(this) + 1; + } +} + +class Foo { + value = 1; + + @dec + get #a() { + return this.value; + } + + getA() { + return this.#a; + } +} + +let foo = new Foo(); + +const aContext = foo['#aContext']; + +expect(aContext.access.get.call(foo)).toBe(2); +expect(foo.getA()).toBe(2); +foo.value = 123; +expect(aContext.access.get.call(foo)).toBe(124); +expect(foo.getA()).toBe(124); +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('getter'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/input.js new file mode 100644 index 000000000000..28519502bf46 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + get #a() { + return this.value; + } + + getA() { + return this.#a; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/output.js new file mode 100644 index 000000000000..b28f700db155 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/private/output.js @@ -0,0 +1,30 @@ +var _call_a, _initProto; + +const dec = () => {}; + +var _a = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor(...args) { + babelHelpers.classPrivateFieldInitSpec(this, _a, { + get: _get_a, + set: void 0 + }); + babelHelpers.defineProperty(this, "value", 1); + + _initProto(this); + } + + getA() { + return babelHelpers.classPrivateFieldGet(this, _a); + } + +} + +function _get_a() { + return _call_a(this); +} + +[_call_a, _initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 3, "a", function () { + return this.value; +}]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/exec.js new file mode 100644 index 000000000000..470b37f23c94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/exec.js @@ -0,0 +1,50 @@ +function dec(get, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function () { + return get.call(this) + 1; + } +} + +class Foo { + value = 1; + + @dec + get a() { + return this.value; + } + + @dec + get ['b']() { + return this.value; + } +} + +let foo = new Foo(); + +const aContext = foo['aContext']; +const bContext = foo['bContext']; + +expect(foo.a).toBe(2); +expect(foo.b).toBe(2); +expect(aContext.access.get.call(foo)).toBe(2); +expect(bContext.access.get.call(foo)).toBe(2); +foo.value = 123; +expect(foo.a).toBe(124); +expect(foo.b).toBe(124); +expect(aContext.access.get.call(foo)).toBe(124); +expect(bContext.access.get.call(foo)).toBe(124); + +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('getter'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('function'); + +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('getter'); +expect(bContext.static).toBe(false); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/input.js new file mode 100644 index 000000000000..392f9e03412f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + get a() { + return this.value; + } + + @dec + get ['b']() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/output.js new file mode 100644 index 000000000000..8ff67a927dc4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initProto; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + constructor(...args) { + babelHelpers.defineProperty(this, "value", 1); + + _initProto(this); + } + + get a() { + return this.value; + } + + get [_computedKey]() { + return this.value; + } + +} + +[_initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 3, "a"], [dec, 3, _computedKey]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..6d4ea7f3a294 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/exec.js @@ -0,0 +1,36 @@ +function dec(get, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function () { + return get.call(this) + 1; + } +} + +class Foo { + static value = 1; + + @dec + static get #a() { + return this.value; + } + + static getA() { + return this.#a; + } +} + +const aContext = Foo['#aContext']; + +expect(aContext.access.get.call(Foo)).toBe(2); +expect(Foo.getA()).toBe(2); +Foo.value = 123; +expect(aContext.access.get.call(Foo)).toBe(124); +expect(Foo.getA()).toBe(124); + +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('getter'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/input.js new file mode 100644 index 000000000000..9d64c02982da --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static get #a() { + return this.value; + } + + static getA() { + return this.#a; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/output.js new file mode 100644 index 000000000000..7ceeacaa466b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-private/output.js @@ -0,0 +1,29 @@ +var _call_a, _initStatic; + +const dec = () => {}; + +class Foo { + static getA() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _a); + } + +} + +function _get_a() { + return _call_a(this); +} + +var _a = { + get: _get_a, + set: void 0 +}; + +(() => { + [_call_a, _initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 8, "a", function () { + return this.value; + }]], []); + + _initStatic(Foo); +})(); + +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..5bb0aa12f675 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/exec.js @@ -0,0 +1,48 @@ +function dec(get, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function () { + return get.call(this) + 1; + } +} + +class Foo { + static value = 1; + + @dec + static get a() { + return this.value; + } + + @dec + static get ['b']() { + return this.value; + } +} + +const aContext = Foo['aContext']; +const bContext = Foo['bContext']; + +expect(Foo.a).toBe(2); +expect(Foo.b).toBe(2); +expect(aContext.access.get.call(Foo)).toBe(2); +expect(bContext.access.get.call(Foo)).toBe(2); +Foo.value = 123; +expect(Foo.a).toBe(124); +expect(Foo.b).toBe(124); +expect(aContext.access.get.call(Foo)).toBe(124); +expect(bContext.access.get.call(Foo)).toBe(124); + +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('getter'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('function'); + +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('getter'); +expect(bContext.static).toBe(true); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/input.js new file mode 100644 index 000000000000..3bc53fb17cc5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static get a() { + return this.value; + } + + @dec + static get ['b']() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/output.js new file mode 100644 index 000000000000..bad772f1776c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters--to-es2015/static-public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initStatic; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static get a() { + return this.value; + } + + static get [_computedKey]() { + return this.value; + } + +} + +(() => { + [_initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 8, "a"], [dec, 8, _computedKey]], []); + + _initStatic(Foo); +})(); + +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/exec.js new file mode 100644 index 000000000000..27218da84ab3 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/exec.js @@ -0,0 +1,63 @@ +function dec(value, context) { + context.addInitializer(function() { + this[context.name + '_' + context.kind + 'Context'] = context; + }); + + if (context.kind === 'getter') { + return function () { + return value.call(this) + 1; + } + } else { + return function (v) { + return value.call(this, v + 1); + } + } +} + +class Foo { + value = 1; + + @dec + get #a() { + return this.value; + } + + @dec + set #a(v) { + this.value = v; + } + + getA() { + return this.#a; + } + + setA(v) { + this.#a = v; + } +} + +let foo = new Foo(); + +const a_getterContext = foo['#a_getterContext']; +const a_setterContext = foo['#a_setterContext']; + +expect(a_getterContext.access.get.call(foo)).toBe(2); +expect(foo.getA()).toBe(2); +a_setterContext.access.set.call(foo, 123); +expect(a_getterContext.access.get.call(foo)).toBe(125); +expect(foo.getA()).toBe(125); +foo.setA(456); +expect(a_getterContext.access.get.call(foo)).toBe(458); +expect(foo.getA()).toBe(458); + +expect(a_getterContext.name).toBe('#a'); +expect(a_getterContext.kind).toBe('getter'); +expect(a_getterContext.static).toBe(false); +expect(a_getterContext.private).toBe(true); +expect(typeof a_getterContext.addInitializer).toBe('function'); + +expect(a_setterContext.name).toBe('#a'); +expect(a_setterContext.kind).toBe('setter'); +expect(a_setterContext.static).toBe(false); +expect(a_setterContext.private).toBe(true); +expect(typeof a_setterContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/input.js new file mode 100644 index 000000000000..fdf137cc4a64 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/input.js @@ -0,0 +1,22 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + get #a() { + return this.value; + } + + @dec + set #a(v) { + this.value = v; + } + + getA() { + return this.#a; + } + + setA(v) { + this.#a = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/output.js new file mode 100644 index 000000000000..1568c07f4b65 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/private/output.js @@ -0,0 +1,40 @@ +var _call_a, _call_a2, _initProto; + +const dec = () => {}; + +var _a = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor(...args) { + babelHelpers.classPrivateFieldInitSpec(this, _a, { + get: _get_a, + set: _set_a + }); + babelHelpers.defineProperty(this, "value", 1); + + _initProto(this); + } + + getA() { + return babelHelpers.classPrivateFieldGet(this, _a); + } + + setA(v) { + babelHelpers.classPrivateFieldSet(this, _a, v); + } + +} + +function _get_a() { + return _call_a(this); +} + +function _set_a(v) { + _call_a2(this, v); +} + +[_call_a, _call_a2, _initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 3, "a", function () { + return this.value; +}], [dec, 4, "a", function (v) { + this.value = v; +}]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/exec.js new file mode 100644 index 000000000000..9f6c5b8ae575 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/exec.js @@ -0,0 +1,91 @@ +function dec(value, context) { + context.addInitializer(function() { + this[context.name + '_' + context.kind + 'Context'] = context; + }); + + if (context.kind === 'getter') { + return function () { + return value.call(this) + 1; + } + } else { + return function (v) { + return value.call(this, v + 1); + } + } +} + +class Foo { + value = 1; + + @dec + get a() { + return this.value; + } + + @dec + set a(v) { + this.value = v; + } + + @dec + get ['b']() { + return this.value; + } + + @dec + set ['b'](v) { + this.value = v; + } +} + +let foo = new Foo(); + +const a_getterContext = foo['a_getterContext']; +const a_setterContext = foo['a_setterContext']; + +const b_getterContext = foo['b_getterContext']; +const b_setterContext = foo['b_setterContext']; + +expect(foo.a).toBe(2); +expect(foo.b).toBe(2); +expect(a_getterContext.access.get.call(foo)).toBe(2); +expect(b_getterContext.access.get.call(foo)).toBe(2); +foo.a = 123; +expect(foo.a).toBe(125); +expect(foo.b).toBe(125); +expect(a_getterContext.access.get.call(foo)).toBe(125); +expect(b_getterContext.access.get.call(foo)).toBe(125); +foo.b = 456; +expect(foo.a).toBe(458); +expect(foo.b).toBe(458); +expect(a_getterContext.access.get.call(foo)).toBe(458); +expect(b_getterContext.access.get.call(foo)).toBe(458); +a_setterContext.access.set.call(foo, 789); +expect(foo.a).toBe(791); +expect(foo.b).toBe(791); +expect(a_getterContext.access.get.call(foo)).toBe(791); +expect(b_getterContext.access.get.call(foo)).toBe(791); + +expect(a_getterContext.name).toBe('a'); +expect(a_getterContext.kind).toBe('getter'); +expect(a_getterContext.static).toBe(false); +expect(a_getterContext.private).toBe(false); +expect(typeof a_getterContext.addInitializer).toBe('function'); + +expect(a_setterContext.name).toBe('a'); +expect(a_setterContext.kind).toBe('setter'); +expect(a_setterContext.static).toBe(false); +expect(a_setterContext.private).toBe(false); +expect(typeof a_setterContext.addInitializer).toBe('function'); + +expect(b_getterContext.name).toBe('b'); +expect(b_getterContext.kind).toBe('getter'); +expect(b_getterContext.static).toBe(false); +expect(b_getterContext.private).toBe(false); +expect(typeof b_getterContext.addInitializer).toBe('function'); + +expect(b_setterContext.name).toBe('b'); +expect(b_setterContext.kind).toBe('setter'); +expect(b_setterContext.static).toBe(false); +expect(b_setterContext.private).toBe(false); +expect(typeof b_setterContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/input.js new file mode 100644 index 000000000000..1af1569ba988 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/input.js @@ -0,0 +1,24 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + get a() { + return this.value; + } + + @dec + set a(v) { + this.value = v; + } + + @dec + get ['b']() { + return this.value; + } + + @dec + set ['b'](v) { + this.value = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/output.js new file mode 100644 index 000000000000..833c9497ec2e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/public/output.js @@ -0,0 +1,33 @@ +var _computedKey, _computedKey2, _initProto; + +const dec = () => {}; + +_computedKey = 'b'; +_computedKey2 = 'b'; + +class Foo { + constructor(...args) { + babelHelpers.defineProperty(this, "value", 1); + + _initProto(this); + } + + get a() { + return this.value; + } + + set a(v) { + this.value = v; + } + + get [_computedKey]() { + return this.value; + } + + set [_computedKey2](v) { + this.value = v; + } + +} + +[_initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 3, "a"], [dec, 4, "a"], [dec, 3, _computedKey], [dec, 4, _computedKey2]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..eb5bca4c7996 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/exec.js @@ -0,0 +1,61 @@ +function dec(value, context) { + context.addInitializer(function() { + this[context.name + '_' + context.kind + 'Context'] = context; + }); + + if (context.kind === 'getter') { + return function () { + return value.call(this) + 1; + } + } else { + return function (v) { + return value.call(this, v + 1); + } + } +} + +class Foo { + static value = 1; + + @dec + static get #a() { + return this.value; + } + + @dec + static set #a(v) { + this.value = v; + } + + static getA() { + return this.#a; + } + + static setA(v) { + this.#a = v; + } +} + +const a_getterContext = Foo['#a_getterContext']; +const a_setterContext = Foo['#a_setterContext']; + +expect(a_getterContext.access.get.call(Foo)).toBe(2); +expect(Foo.getA()).toBe(2); +a_setterContext.access.set.call(Foo, 123); +expect(a_getterContext.access.get.call(Foo)).toBe(125); +expect(Foo.getA()).toBe(125); +Foo.setA(456); +expect(a_getterContext.access.get.call(Foo)).toBe(458); +expect(Foo.getA()).toBe(458); + +expect(a_getterContext.name).toBe('#a'); +expect(a_getterContext.kind).toBe('getter'); +expect(a_getterContext.static).toBe(true); +expect(a_getterContext.private).toBe(true); +expect(typeof a_getterContext.addInitializer).toBe('function'); + +expect(a_setterContext.name).toBe('#a'); +expect(a_setterContext.kind).toBe('setter'); +expect(a_setterContext.static).toBe(true); +expect(a_setterContext.private).toBe(true); +expect(typeof a_setterContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/input.js new file mode 100644 index 000000000000..c832634c6b72 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/input.js @@ -0,0 +1,22 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static get #a() { + return this.value; + } + + @dec + static set #a(v) { + this.value = v; + } + + static getA() { + return this.#a; + } + + static setA(v) { + this.#a = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/output.js new file mode 100644 index 000000000000..4df4bc62095c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-private/output.js @@ -0,0 +1,39 @@ +var _call_a, _call_a2, _initStatic; + +const dec = () => {}; + +class Foo { + static getA() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _a); + } + + static setA(v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _a, v); + } + +} + +function _get_a() { + return _call_a(this); +} + +function _set_a(v) { + _call_a2(this, v); +} + +var _a = { + get: _get_a, + set: _set_a +}; + +(() => { + [_call_a, _call_a2, _initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 8, "a", function () { + return this.value; + }], [dec, 9, "a", function (v) { + this.value = v; + }]], []); + + _initStatic(Foo); +})(); + +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..6abca4f5c5d6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/exec.js @@ -0,0 +1,90 @@ +function dec(value, context) { + context.addInitializer(function() { + this[context.name + '_' + context.kind + 'Context'] = context; + }); + + if (context.kind === 'getter') { + return function () { + return value.call(this) + 1; + } + } else { + return function (v) { + return value.call(this, v + 1); + } + } +} + +class Foo { + static value = 1; + + @dec + static get a() { + return this.value; + } + + @dec + static set a(v) { + this.value = v; + } + + @dec + static get ['b']() { + return this.value; + } + + @dec + static set ['b'](v) { + this.value = v; + } +} + +const a_getterContext = Foo['a_getterContext']; +const a_setterContext = Foo['a_setterContext']; + +const b_getterContext = Foo['b_getterContext']; +const b_setterContext = Foo['b_setterContext']; + +expect(Foo.a).toBe(2); +expect(Foo.b).toBe(2); +expect(a_getterContext.access.get.call(Foo)).toBe(2); +expect(b_getterContext.access.get.call(Foo)).toBe(2); +Foo.a = 123; +expect(Foo.a).toBe(125); +expect(Foo.b).toBe(125); +expect(a_getterContext.access.get.call(Foo)).toBe(125); +expect(b_getterContext.access.get.call(Foo)).toBe(125); +Foo.b = 456; +expect(Foo.a).toBe(458); +expect(Foo.b).toBe(458); +expect(a_getterContext.access.get.call(Foo)).toBe(458); +expect(b_getterContext.access.get.call(Foo)).toBe(458); +a_setterContext.access.set.call(Foo, 789); +expect(Foo.a).toBe(791); +expect(Foo.b).toBe(791); +expect(a_getterContext.access.get.call(Foo)).toBe(791); +expect(b_getterContext.access.get.call(Foo)).toBe(791); + +expect(a_getterContext.name).toBe('a'); +expect(a_getterContext.kind).toBe('getter'); +expect(a_getterContext.static).toBe(true); +expect(a_getterContext.private).toBe(false); +expect(typeof a_getterContext.addInitializer).toBe('function'); + +expect(a_setterContext.name).toBe('a'); +expect(a_setterContext.kind).toBe('setter'); +expect(a_setterContext.static).toBe(true); +expect(a_setterContext.private).toBe(false); +expect(typeof a_setterContext.addInitializer).toBe('function'); + +expect(b_getterContext.name).toBe('b'); +expect(b_getterContext.kind).toBe('getter'); +expect(b_getterContext.static).toBe(true); +expect(b_getterContext.private).toBe(false); +expect(typeof b_getterContext.addInitializer).toBe('function'); + +expect(b_setterContext.name).toBe('b'); +expect(b_setterContext.kind).toBe('setter'); +expect(b_setterContext.static).toBe(true); +expect(b_setterContext.private).toBe(false); +expect(typeof b_setterContext.addInitializer).toBe('function'); + diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/input.js new file mode 100644 index 000000000000..bbad4af972ed --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/input.js @@ -0,0 +1,24 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static get a() { + return this.value; + } + + @dec + static set a(v) { + this.value = v; + } + + @dec + static get ['b']() { + return this.value; + } + + @dec + static set ['b'](v) { + this.value = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/output.js new file mode 100644 index 000000000000..2c7e517ae4c5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters--to-es2015/static-public/output.js @@ -0,0 +1,33 @@ +var _computedKey, _computedKey2, _initStatic; + +const dec = () => {}; + +_computedKey = 'b'; +_computedKey2 = 'b'; + +class Foo { + static get a() { + return this.value; + } + + static set a(v) { + this.value = v; + } + + static get [_computedKey]() { + return this.value; + } + + static set [_computedKey2](v) { + this.value = v; + } + +} + +(() => { + [_initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 8, "a"], [dec, 9, "a"], [dec, 8, _computedKey], [dec, 9, _computedKey2]], []); + + _initStatic(Foo); +})(); + +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/private/input.js new file mode 100644 index 000000000000..fdf137cc4a64 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/private/input.js @@ -0,0 +1,22 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + get #a() { + return this.value; + } + + @dec + set #a(v) { + this.value = v; + } + + getA() { + return this.#a; + } + + setA(v) { + this.#a = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/private/output.js new file mode 100644 index 000000000000..e284e2c0696d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/private/output.js @@ -0,0 +1,36 @@ +var _call_a, _call_a2, _initProto; + +const dec = () => {}; + +class Foo { + static { + [_call_a, _call_a2, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 3, "a", function () { + return this.value; + }], [dec, 4, "a", function (v) { + this.value = v; + }]], []); + } + + constructor(...args) { + _initProto(this); + } + + value = 1; + + get #a() { + return _call_a(this); + } + + set #a(v) { + _call_a2(this, v); + } + + getA() { + return this.#a; + } + + setA(v) { + this.#a = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/public/input.js new file mode 100644 index 000000000000..1af1569ba988 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/public/input.js @@ -0,0 +1,24 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + get a() { + return this.value; + } + + @dec + set a(v) { + this.value = v; + } + + @dec + get ['b']() { + return this.value; + } + + @dec + set ['b'](v) { + this.value = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/public/output.js new file mode 100644 index 000000000000..9ace7f12f8d1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/public/output.js @@ -0,0 +1,35 @@ +var _computedKey, _computedKey2, _initProto; + +const dec = () => {}; + +_computedKey = 'b'; +_computedKey2 = 'b'; + +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[dec, 3, "a"], [dec, 4, "a"], [dec, 3, _computedKey], [dec, 4, _computedKey2]], []); + } + + constructor(...args) { + _initProto(this); + } + + value = 1; + + get a() { + return this.value; + } + + set a(v) { + this.value = v; + } + + get [_computedKey]() { + return this.value; + } + + set [_computedKey2](v) { + this.value = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-private/input.js new file mode 100644 index 000000000000..c832634c6b72 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-private/input.js @@ -0,0 +1,22 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static get #a() { + return this.value; + } + + @dec + static set #a(v) { + this.value = v; + } + + static getA() { + return this.#a; + } + + static setA(v) { + this.#a = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-private/output.js new file mode 100644 index 000000000000..e8bb314208e4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-private/output.js @@ -0,0 +1,34 @@ +var _call_a, _call_a2, _initStatic; + +const dec = () => {}; + +class Foo { + static { + [_call_a, _call_a2, _initStatic] = babelHelpers.applyDecs2203(this, [[dec, 8, "a", function () { + return this.value; + }], [dec, 9, "a", function (v) { + this.value = v; + }]], []); + + _initStatic(this); + + } + static value = 1; + + static get #a() { + return _call_a(this); + } + + static set #a(v) { + _call_a2(this, v); + } + + static getA() { + return this.#a; + } + + static setA(v) { + this.#a = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-public/input.js new file mode 100644 index 000000000000..bbad4af972ed --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-public/input.js @@ -0,0 +1,24 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static get a() { + return this.value; + } + + @dec + static set a(v) { + this.value = v; + } + + @dec + static get ['b']() { + return this.value; + } + + @dec + static set ['b'](v) { + this.value = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-public/output.js new file mode 100644 index 000000000000..99c2827c1571 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters-and-setters/static-public/output.js @@ -0,0 +1,33 @@ +var _computedKey, _computedKey2, _initStatic; + +const dec = () => {}; + +_computedKey = 'b'; +_computedKey2 = 'b'; + +class Foo { + static { + [_initStatic] = babelHelpers.applyDecs2203(this, [[dec, 8, "a"], [dec, 9, "a"], [dec, 8, _computedKey], [dec, 9, _computedKey2]], []); + + _initStatic(this); + + } + static value = 1; + + static get a() { + return this.value; + } + + static set a(v) { + this.value = v; + } + + static get [_computedKey]() { + return this.value; + } + + static set [_computedKey2](v) { + this.value = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/private/input.js new file mode 100644 index 000000000000..28519502bf46 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + get #a() { + return this.value; + } + + getA() { + return this.#a; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/private/output.js new file mode 100644 index 000000000000..9251e9447242 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/private/output.js @@ -0,0 +1,26 @@ +var _call_a, _initProto; + +const dec = () => {}; + +class Foo { + static { + [_call_a, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 3, "a", function () { + return this.value; + }]], []); + } + + constructor(...args) { + _initProto(this); + } + + value = 1; + + get #a() { + return _call_a(this); + } + + getA() { + return this.#a; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/public/input.js new file mode 100644 index 000000000000..392f9e03412f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + get a() { + return this.value; + } + + @dec + get ['b']() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/public/output.js new file mode 100644 index 000000000000..de4a028facc0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/public/output.js @@ -0,0 +1,26 @@ +var _computedKey, _initProto; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[dec, 3, "a"], [dec, 3, _computedKey]], []); + } + + constructor(...args) { + _initProto(this); + } + + value = 1; + + get a() { + return this.value; + } + + get [_computedKey]() { + return this.value; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-private/input.js new file mode 100644 index 000000000000..9d64c02982da --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static get #a() { + return this.value; + } + + static getA() { + return this.#a; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-private/output.js new file mode 100644 index 000000000000..1044920a188f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-private/output.js @@ -0,0 +1,24 @@ +var _call_a, _initStatic; + +const dec = () => {}; + +class Foo { + static { + [_call_a, _initStatic] = babelHelpers.applyDecs2203(this, [[dec, 8, "a", function () { + return this.value; + }]], []); + + _initStatic(this); + + } + static value = 1; + + static get #a() { + return _call_a(this); + } + + static getA() { + return this.#a; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-public/input.js new file mode 100644 index 000000000000..3bc53fb17cc5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static get a() { + return this.value; + } + + @dec + static get ['b']() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-public/output.js new file mode 100644 index 000000000000..38a584d07390 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-getters/static-public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initStatic; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static { + [_initStatic] = babelHelpers.applyDecs2203(this, [[dec, 8, "a"], [dec, 8, _computedKey]], []); + + _initStatic(this); + + } + static value = 1; + + static get a() { + return this.value; + } + + static get [_computedKey]() { + return this.value; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private-with-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private-with-initializers/exec.js new file mode 100644 index 000000000000..ebbb23bd408b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private-with-initializers/exec.js @@ -0,0 +1,39 @@ +function dec(fn, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function () { + return fn.call(this) + 1; + } +} + +class Foo { + value = 1; + + @dec + #a() { + return this.value; + } + + callA() { + return this.#a(); + } +} + +let foo = new Foo(); + +const aContext = foo['#aContext']; + +// First call gets the method, second call calls the method with correct `this` +expect(aContext.access.get.call(foo).call(foo)).toBe(2); +expect(foo.callA()).toBe(2); +foo.value = 123; +expect(aContext.access.get.call(foo).call(foo)).toBe(124); +expect(foo.callA()).toBe(124); + +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('method'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/exec.js new file mode 100644 index 000000000000..a74cb2331eca --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/exec.js @@ -0,0 +1,24 @@ +function dec(fn, context) { + return function () { + return fn.call(this) + 1; + } +} + +class Foo { + value = 1; + + @dec + #a() { + return this.value; + } + + callA() { + return this.#a(); + } +} + +let foo = new Foo(); + +expect(foo.callA()).toBe(2); +foo.value = 123; +expect(foo.callA()).toBe(124); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/input.js new file mode 100644 index 000000000000..098bbbb687f2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + #a() { + return this.value; + } + + callA() { + return this.#a(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/output.js new file mode 100644 index 000000000000..0aaf92f8bd60 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/private/output.js @@ -0,0 +1,26 @@ +var _call_a, _initProto; + +const dec = () => {}; + +var _a = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor(...args) { + babelHelpers.classPrivateFieldInitSpec(this, _a, { + writable: true, + value: _call_a + }); + babelHelpers.defineProperty(this, "value", 1); + + _initProto(this); + } + + callA() { + return babelHelpers.classPrivateFieldGet(this, _a).call(this); + } + +} + +[_call_a, _initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 2, "a", function () { + return this.value; +}]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public-with-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public-with-initializers/exec.js new file mode 100644 index 000000000000..85a4246eadfa --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public-with-initializers/exec.js @@ -0,0 +1,50 @@ +function dec(fn, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function () { + return fn.call(this) + 1; + } +} + +class Foo { + value = 1; + + @dec + a() { + return this.value; + } + + @dec + ['b']() { + return this.value; + } +} + +let foo = new Foo(); + +const aContext = foo['aContext']; +const bContext = foo['bContext']; + +expect(foo.a()).toBe(2); +expect(aContext.access.get.call(foo).call(foo)).toBe(2); +expect(foo.b()).toBe(2); +expect(bContext.access.get.call(foo).call(foo)).toBe(2); +foo.value = 123; +expect(aContext.access.get.call(foo).call(foo)).toBe(124); +expect(foo.a()).toBe(124); +expect(bContext.access.get.call(foo).call(foo)).toBe(124); +expect(foo.b()).toBe(124); + +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('method'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('function'); + +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('method'); +expect(bContext.static).toBe(false); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/exec.js new file mode 100644 index 000000000000..b9ec2b92e328 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/exec.js @@ -0,0 +1,27 @@ +function dec(fn, context) { + return function () { + return fn.call(this) + 1; + } +} + +class Foo { + value = 1; + + @dec + a() { + return this.value; + } + + @dec + ['b']() { + return this.value; + } +} + +let foo = new Foo(); + +expect(foo.a()).toBe(2); +expect(foo.b()).toBe(2); +foo.value = 123; +expect(foo.a()).toBe(124); +expect(foo.b()).toBe(124); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/input.js new file mode 100644 index 000000000000..3a7f4cfaae9c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + a() { + return this.value; + } + + @dec + ['b']() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/output.js new file mode 100644 index 000000000000..b30a3a5d4d41 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initProto; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + constructor(...args) { + babelHelpers.defineProperty(this, "value", 1); + + _initProto(this); + } + + a() { + return this.value; + } + + [_computedKey]() { + return this.value; + } + +} + +[_initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 2, "a"], [dec, 2, _computedKey]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private-with-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private-with-initializers/exec.js new file mode 100644 index 000000000000..56ca1d2bb86c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private-with-initializers/exec.js @@ -0,0 +1,37 @@ +function dec(fn, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function () { + return fn.call(this) + 1; + } +} + +class Foo { + static value = 1; + + @dec + static #a() { + return this.value; + } + + static callA() { + return this.#a(); + } +} + +const aContext = Foo['#aContext']; + +// First call gets the method, second call calls the method with correct `this` +expect(aContext.access.get.call(Foo).call(Foo)).toBe(2); +expect(Foo.callA()).toBe(2); +Foo.value = 123; +expect(aContext.access.get.call(Foo).call(Foo)).toBe(124); +expect(Foo.callA()).toBe(124); + +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('method'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..47deb64ec304 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/exec.js @@ -0,0 +1,22 @@ +function dec(fn, context) { + return function () { + return fn.call(this) + 1; + } +} + +class Foo { + static value = 1; + + @dec + static #a() { + return this.value; + } + + static callA() { + return this.#a(); + } +} + +expect(Foo.callA()).toBe(2); +Foo.value = 123; +expect(Foo.callA()).toBe(124); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/input.js new file mode 100644 index 000000000000..4a6ae5d4d7fd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static #a() { + return this.value; + } + + static callA() { + return this.#a(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/output.js new file mode 100644 index 000000000000..8acda26e3993 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-private/output.js @@ -0,0 +1,24 @@ +var _call_a, _initStatic; + +const dec = () => {}; + +class Foo { + static callA() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _a).call(this); + } + +} + +(() => { + [_call_a, _initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 7, "a", function () { + return this.value; + }]], []); + + _initStatic(Foo); +})(); + +var _a = { + writable: true, + value: _call_a +}; +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public-with-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public-with-initializers/exec.js new file mode 100644 index 000000000000..78b0de2d871f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public-with-initializers/exec.js @@ -0,0 +1,48 @@ +function dec(fn, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function () { + return fn.call(this) + 1; + } +} + +class Foo { + static value = 1; + + @dec + static a() { + return this.value; + } + + @dec + static ['b']() { + return this.value; + } +} + +const aContext = Foo['aContext']; +const bContext = Foo['bContext']; + +expect(Foo.a()).toBe(2); +expect(aContext.access.get.call(Foo).call(Foo)).toBe(2); +expect(Foo.b()).toBe(2); +expect(bContext.access.get.call(Foo).call(Foo)).toBe(2); +Foo.value = 123; +expect(aContext.access.get.call(Foo).call(Foo)).toBe(124); +expect(Foo.a()).toBe(124); +expect(bContext.access.get.call(Foo).call(Foo)).toBe(124); +expect(Foo.b()).toBe(124); + +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('method'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('function'); + +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('method'); +expect(bContext.static).toBe(true); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..e5d03ee48021 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/exec.js @@ -0,0 +1,25 @@ +function dec(fn, context) { + return function () { + return fn.call(this) + 1; + } +} + +class Foo { + static value = 1; + + @dec + static a() { + return this.value; + } + + @dec + static ['b']() { + return this.value; + } +} + +expect(Foo.a()).toBe(2); +expect(Foo.b()).toBe(2); +Foo.value = 123; +expect(Foo.a()).toBe(124); +expect(Foo.b()).toBe(124); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/input.js new file mode 100644 index 000000000000..5f81da5c0405 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static a() { + return this.value; + } + + @dec + static ['b']() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/output.js new file mode 100644 index 000000000000..ab728c74c2b7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods--to-es2015/static-public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initStatic; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static a() { + return this.value; + } + + static [_computedKey]() { + return this.value; + } + +} + +(() => { + [_initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 7, "a"], [dec, 7, _computedKey]], []); + + _initStatic(Foo); +})(); + +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/private/input.js new file mode 100644 index 000000000000..098bbbb687f2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + #a() { + return this.value; + } + + callA() { + return this.#a(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/private/output.js new file mode 100644 index 000000000000..38e9e76bb3f6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/private/output.js @@ -0,0 +1,23 @@ +var _call_a, _initProto; + +const dec = () => {}; + +class Foo { + static { + [_call_a, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, "a", function () { + return this.value; + }]], []); + } + + constructor(...args) { + _initProto(this); + } + + #a = _call_a; + value = 1; + + callA() { + return this.#a(); + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/public/input.js new file mode 100644 index 000000000000..3a7f4cfaae9c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + a() { + return this.value; + } + + @dec + ['b']() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/public/output.js new file mode 100644 index 000000000000..4d645c91a455 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/public/output.js @@ -0,0 +1,26 @@ +var _computedKey, _initProto; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, "a"], [dec, 2, _computedKey]], []); + } + + constructor(...args) { + _initProto(this); + } + + value = 1; + + a() { + return this.value; + } + + [_computedKey]() { + return this.value; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-private/input.js new file mode 100644 index 000000000000..4a6ae5d4d7fd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static #a() { + return this.value; + } + + static callA() { + return this.#a(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-private/output.js new file mode 100644 index 000000000000..ef82ddc64436 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-private/output.js @@ -0,0 +1,21 @@ +var _call_a, _initStatic; + +const dec = () => {}; + +class Foo { + static { + [_call_a, _initStatic] = babelHelpers.applyDecs2203(this, [[dec, 7, "a", function () { + return this.value; + }]], []); + + _initStatic(this); + + } + static #a = _call_a; + static value = 1; + + static callA() { + return this.#a(); + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-public/input.js new file mode 100644 index 000000000000..5f81da5c0405 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static a() { + return this.value; + } + + @dec + static ['b']() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-public/output.js new file mode 100644 index 000000000000..ec7c017dcbdb --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-methods/static-public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initStatic; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static { + [_initStatic] = babelHelpers.applyDecs2203(this, [[dec, 7, "a"], [dec, 7, _computedKey]], []); + + _initStatic(this); + + } + static value = 1; + + static a() { + return this.value; + } + + static [_computedKey]() { + return this.value; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/class-and-method-decorators/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/class-and-method-decorators/exec.js new file mode 100644 index 000000000000..11aae499cb0d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/class-and-method-decorators/exec.js @@ -0,0 +1,77 @@ +function dec() {} + +var i = 0; +var log = []; + +function push(x) { log.push(x); return x; } + +function decWithInitializer(_, { addInitializer }) { + addInitializer(() => push(i++) ); +} + +new @dec class C1 { + @dec static m() {} +} + +new @dec class C2 { + @dec static #m() {} +} + +new @dec class C3 { + @dec m() {} +} + +new @dec class C4 { + @dec #m() {} +} + +new @decWithInitializer class C5 { + @dec static m() {} +} + +new @decWithInitializer class C6 { + @dec static #m() {} +} + +new @decWithInitializer class C7 { + @dec m() {} +} + +new @decWithInitializer class C8 { + @dec #m() {} +} + +new @dec class C9 { + @decWithInitializer static m() {} +} + +new @dec class C10 { + @decWithInitializer static #m() {} +} + +new @dec class C11 { + @decWithInitializer m() {} +} + +new @dec class C12 { + @decWithInitializer #m() {} +} + +new @decWithInitializer class C13 { + @decWithInitializer static m() {} +} + +new @decWithInitializer class C14 { + @decWithInitializer static #m() {} +} + +new @decWithInitializer class C15 { + @decWithInitializer m() {} +} + +new @decWithInitializer class C16 { + @decWithInitializer #m() {} +} + +var nums = Array.from({ length: 16 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/class-and-property-decorators/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/class-and-property-decorators/exec.js new file mode 100644 index 000000000000..3993d925adec --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/class-and-property-decorators/exec.js @@ -0,0 +1,45 @@ +function dec() {} + +var i = 0; +var log = []; + +function push(x) { log.push(x); return x; } + +function decWithInitializer(_, { addInitializer }) { + addInitializer(() => push(i++) ); +} + +new @dec class C1 { + @dec static p +} + +new @dec class C2 { + @dec static #p +} + +new @dec class C3 { + @dec p +} + +new @dec class C4 { + @dec #p +} + +new @decWithInitializer class C5 { + @dec static p +} + +new @decWithInitializer class C6 { + @dec static #p +} + +new @decWithInitializer class C7 { + @dec p +} + +new @decWithInitializer class C8 { + @dec #p +} + +var nums = Array.from({ length: 4 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/decorator-evaluation-scope/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/decorator-evaluation-scope/exec.js new file mode 100644 index 000000000000..ec8beb3b8cbf --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/decorator-evaluation-scope/exec.js @@ -0,0 +1,12 @@ +let receivedName; +function decFactory(name) { receivedName = name; return x => x } +class B { + static m() { + class C { + @decFactory(this.name) p; + } + } +} + +B.m(); +expect(receivedName).toBe("B"); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/exec.js new file mode 100644 index 000000000000..3d81b8cdf452 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/exec.js @@ -0,0 +1,28 @@ +let self, a, initCalled; + +function deco(_, context) { + context.addInitializer(() => { + initCalled = true; + }) +} + +class B { + constructor(s) { + a = s; + } +} + +class A extends B { + constructor() { + let a = 2; + self = super(a); + } + + @deco + method() {} +} + +let instance = new A(); +expect(self).toBe(instance); +expect(a).toBe(2); +expect(initCalled).toBe(true); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/input.js new file mode 100644 index 000000000000..68484c72749d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class A extends B { + constructor() { + let a = 2; + super(a); + foo(); + } + + @deco + method() {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/output.js new file mode 100644 index 000000000000..75cf6186645c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initProto-existing-derived-constructor/output.js @@ -0,0 +1,20 @@ +var _dec, _initProto; + +const dec = () => {}; + +_dec = deco; + +class A extends B { + constructor() { + let a = 2; + + _initProto(super(a)); + + foo(); + } + + method() {} + +} + +[_initProto] = babelHelpers.applyDecs2203(A, [[_dec, 2, "method"]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initializer-property-ignored/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initializer-property-ignored/exec.js new file mode 100644 index 000000000000..2828e1c22408 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initializer-property-ignored/exec.js @@ -0,0 +1,25 @@ +let init = false; +let initializer = false; + +function decorator() { + return { + get init() { + init = true; + return () => {}; + }, + get initializer() { + initializer = true; + return () => {}; + } + }; +} + +class A { + @decorator + accessor x; +} + +new A(); + +expect(init).toBe(true); +expect(initializer).toBe(false); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initializer-timing/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initializer-timing/exec.js new file mode 100644 index 000000000000..ac5920dcd16a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/initializer-timing/exec.js @@ -0,0 +1,34 @@ +function dec1(fn, context) { + context.addInitializer((instance) => { + expect(instance.value).toBe(undefined); + }); + + return fn; +} + +class Foo { + value = 1; + + @dec1 + foo() {} +} + +function dec2(fn, context) { + context.addInitializer((instance) => { + expect(instance.value).toBe(1); + }); + + return fn; +} + + +class Bar extends Foo { + constructor() { + super(); + + this.value = 2; + } + + @dec2 + bar() {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/leaked-context-addInitializer-throw/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/leaked-context-addInitializer-throw/exec.js new file mode 100644 index 000000000000..ccf93163d0fa --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/leaked-context-addInitializer-throw/exec.js @@ -0,0 +1,17 @@ +let addInitializer; + +function decMethod(_, context) { + ({ addInitializer } = context); + addInitializer(() => null); +} + +try { + class C { + @decMethod + m() {} + } +} finally {} + +expect(() => { + addInitializer(() => null); +}).toThrow('attempted to call addInitializer after decoration was finished') diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/leaked-context-addInitializer/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/leaked-context-addInitializer/exec.js new file mode 100644 index 000000000000..61cd2063364c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/leaked-context-addInitializer/exec.js @@ -0,0 +1,18 @@ +let addInitializer; + +function callCapturedFunc() { + addInitializer(() => null); +} + +function decMethod(_, context) { + ({ addInitializer } = context); + addInitializer(() => null); +} + +expect(() => { + class C { + @callCapturedFunc + @decMethod + m() {} + } +}).toThrow('attempted to call addInitializer after decoration was finished') diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/valid-expression-formats/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/valid-expression-formats/input.js new file mode 100644 index 000000000000..586564c5e219 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/valid-expression-formats/input.js @@ -0,0 +1,23 @@ +const dec = () => {}; +@dec +@call() +@chain.expr() +@(arbitrary + expr) +@(array[expr]) +class Foo { + #a; + + @dec + @call() + @chain.expr() + @(arbitrary + expr) + @(array[expr]) + method() {} + + makeClass() { + return class Nested { + @(this.#a) + bar; + } + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/valid-expression-formats/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/valid-expression-formats/output.js new file mode 100644 index 000000000000..71a3e02461c2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc--to-es2015/valid-expression-formats/output.js @@ -0,0 +1,45 @@ +var _initClass, _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto; + +const dec = () => {}; + +let _Foo; + +_dec = call(); +_dec2 = chain.expr(); +_dec3 = arbitrary + expr; +_dec4 = array[expr]; +_dec5 = call(); +_dec6 = chain.expr(); +_dec7 = arbitrary + expr; +_dec8 = array[expr]; + +var _a = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor(...args) { + babelHelpers.classPrivateFieldInitSpec(this, _a, { + writable: true, + value: void 0 + }); + + _initProto(this); + } + + method() {} + + makeClass() { + var _dec9, _init_bar, _class; + + return _dec9 = babelHelpers.classPrivateFieldGet(this, _a), (_class = class Nested { + constructor() { + babelHelpers.defineProperty(this, "bar", _init_bar(this)); + } + + }, [_init_bar] = babelHelpers.applyDecs2203(_class, [[_dec9, 0, "bar"]], []), _class); + } + +} + +[_initProto, _Foo, _initClass] = babelHelpers.applyDecs2203(Foo, [[[dec, _dec5, _dec6, _dec7, _dec8], 2, "method"]], [dec, _dec, _dec2, _dec3, _dec4]); + +_initClass(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/all-decorators/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/all-decorators/input.js new file mode 100644 index 000000000000..6986908e606d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/all-decorators/input.js @@ -0,0 +1,27 @@ +const dec = () => {}; +@dec +class Class { + @dec a; + @dec b() {} + @dec get c() {} + @dec set c(v) {} + @dec accessor d; + + @dec #e; + @dec #f() {} + @dec get #g() {} + @dec set #g(v) {} + @dec accessor #h; + + @dec static i; + @dec static j() {} + @dec static get k() {} + @dec static set l(v) {} + @dec static accessor m; + + @dec static #n; + @dec static #o() {} + @dec static get #p() {} + @dec static set #q(v) {} + @dec static accessor #r; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/all-decorators/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/all-decorators/output.js new file mode 100644 index 000000000000..015d5bddebdc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/all-decorators/output.js @@ -0,0 +1,115 @@ +var _initClass, _init_a, _init_d, _init_e, _call_f, _call_g, _call_g2, _init_h, _get_h, _set_h, _init_i, _init_m, _init_n, _call_o, _call_p, _call_q, _init_r, _get_r, _set_r, _initProto, _initStatic; + +const dec = () => {}; + +let _Class; + +new class extends babelHelpers.identity { + static { + class Class { + static { + [_init_m, _call_o, _call_p, _call_q, _init_r, _get_r, _set_r, _init_d, _call_f, _call_g, _call_g2, _init_h, _get_h, _set_h, _init_i, _init_n, _init_a, _init_e, _initProto, _initStatic, _Class, _initClass] = babelHelpers.applyDecs2203(this, [[dec, 7, "j"], [dec, 8, "k"], [dec, 9, "l"], [dec, 6, "m"], [dec, 7, "o", function () {}], [dec, 8, "p", function () {}], [dec, 9, "q", function (v) {}], [dec, 6, "r", function () { + return this.#D; + }, function (value) { + this.#D = value; + }], [dec, 2, "b"], [dec, 3, "c"], [dec, 4, "c"], [dec, 1, "d"], [dec, 2, "f", function () {}], [dec, 3, "g", function () {}], [dec, 4, "g", function (v) {}], [dec, 1, "h", function () { + return this.#B; + }, function (value) { + this.#B = value; + }], [dec, 5, "i"], [dec, 5, "n", function () { + return this.#n; + }, function (value) { + this.#n = value; + }], [dec, 0, "a"], [dec, 0, "e", function () { + return this.#e; + }, function (value) { + this.#e = value; + }]], [dec]); + + _initStatic(this); + + } + #f = _call_f; + a = (_initProto(this), _init_a(this)); + + b() {} + + get c() {} + + set c(v) {} + + #A = _init_d(this); + + get d() { + return this.#A; + } + + set d(v) { + this.#A = v; + } + + #e = _init_e(this); + + get #g() { + return _call_g(this); + } + + set #g(v) { + _call_g2(this, v); + } + + #B = _init_h(this); + + set #h(v) { + _set_h(this, v); + } + + get #h() { + return _get_h(this); + } + + static j() {} + + static get k() {} + + static set l(v) {} + + static get m() { + return this.#C; + } + + static set m(v) { + this.#C = v; + } + + set #r(v) { + _set_r(this, v); + } + + get #r() { + return _get_r(this); + } + + } + + } + #o = _call_o; + i = _init_i(this); + #C = _init_m(this); + #n = _init_n(this); + + get #p() { + return _call_p(this); + } + + set #q(v) { + _call_q(this, v); + } + + #D = _init_r(this); + + constructor() { + super(_Class), _initClass(); + } + +}(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/decorator-evaluation-scope/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/decorator-evaluation-scope/exec.js new file mode 100644 index 000000000000..ec8beb3b8cbf --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/decorator-evaluation-scope/exec.js @@ -0,0 +1,12 @@ +let receivedName; +function decFactory(name) { receivedName = name; return x => x } +class B { + static m() { + class C { + @decFactory(this.name) p; + } + } +} + +B.m(); +expect(receivedName).toBe("B"); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/decorator-evaluation-scope/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/decorator-evaluation-scope/options.json new file mode 100644 index 000000000000..b7625bc806d8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/decorator-evaluation-scope/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-static-block" + ], + "minNodeVersion": "12.0.0" +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor-multiple-super/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor-multiple-super/input.js new file mode 100644 index 000000000000..a8da039942d6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor-multiple-super/input.js @@ -0,0 +1,24 @@ +const dec = () => {}; +class A extends B { + constructor() { + if (Math.random() > 0.5) { + super(true); + } else { + super(false); + } + } + + @deco + method() {} +} + +class C extends B { + constructor() { + try { + super(super(), null.x); + } catch {} + } + + @deco + method() {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor-multiple-super/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor-multiple-super/output.js new file mode 100644 index 000000000000..878d76826d5b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor-multiple-super/output.js @@ -0,0 +1,39 @@ +var _dec, _initProto, _dec2, _initProto2; + +const dec = () => {}; + +_dec = deco; + +class A extends B { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[_dec, 2, "method"]], []); + } + + constructor() { + if (Math.random() > 0.5) { + _initProto(super(true)); + } else { + _initProto(super(false)); + } + } + + method() {} + +} + +_dec2 = deco; + +class C extends B { + static { + [_initProto2] = babelHelpers.applyDecs2203(this, [[_dec2, 2, "method"]], []); + } + + constructor() { + try { + _initProto2(super(_initProto2(super()), null.x)); + } catch {} + } + + method() {} + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor/input.js new file mode 100644 index 000000000000..b3c7b6f85e9b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class A extends B { + constructor() { + let a = 2; + super(a); + foo(); + } + + @dec + method() {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor/output.js new file mode 100644 index 000000000000..6377154deda6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initProto-existing-derived-constructor/output.js @@ -0,0 +1,20 @@ +var _initProto; + +const dec = () => {}; + +class A extends B { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, "method"]], []); + } + + constructor() { + let a = 2; + + _initProto(super(a)); + + foo(); + } + + method() {} + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initializer-property-ignored/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initializer-property-ignored/exec.js new file mode 100644 index 000000000000..2828e1c22408 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initializer-property-ignored/exec.js @@ -0,0 +1,25 @@ +let init = false; +let initializer = false; + +function decorator() { + return { + get init() { + init = true; + return () => {}; + }, + get initializer() { + initializer = true; + return () => {}; + } + }; +} + +class A { + @decorator + accessor x; +} + +new A(); + +expect(init).toBe(true); +expect(initializer).toBe(false); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initializer-property-ignored/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initializer-property-ignored/options.json new file mode 100644 index 000000000000..b7625bc806d8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/initializer-property-ignored/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-static-block" + ], + "minNodeVersion": "12.0.0" +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/private-keys-in-enclosing-class/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/private-keys-in-enclosing-class/input.js new file mode 100644 index 000000000000..0e7ac6161824 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/private-keys-in-enclosing-class/input.js @@ -0,0 +1,11 @@ +const dec = () => {}; +class A { + #A = 1; + static B = class B extends A { + accessor a = 2; + + getA() { + return this.#A; + } + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/private-keys-in-enclosing-class/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/private-keys-in-enclosing-class/output.js new file mode 100644 index 000000000000..501a4db46595 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/private-keys-in-enclosing-class/output.js @@ -0,0 +1,21 @@ +const dec = () => {}; + +class A { + #A = 1; + static B = class B extends A { + #B = 2; + + get a() { + return this.#B; + } + + set a(v) { + this.#B = v; + } + + getA() { + return this.#A; + } + + }; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-array-pattern/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-array-pattern/input.js new file mode 100644 index 000000000000..53848c42cb07 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-array-pattern/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec #x() {} + + bar() { + ([this.#x] = this.baz); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-array-pattern/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-array-pattern/options.json new file mode 100644 index 000000000000..188eae592ec5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-array-pattern/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Decorated private methods are not updatable, but \"#x\" is updated via this expression." +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-for-of/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-for-of/input.js new file mode 100644 index 000000000000..2ffabb75d901 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-for-of/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec #x() {} + + bar() { + for (this.#x of this.baz); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-for-of/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-for-of/options.json new file mode 100644 index 000000000000..188eae592ec5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-for-of/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Decorated private methods are not updatable, but \"#x\" is updated via this expression." +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-object-pattern/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-object-pattern/input.js new file mode 100644 index 000000000000..a60de2bae344 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-object-pattern/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec #x() {} + + bar() { + ({ x: this.#x } = this.baz); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-object-pattern/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-object-pattern/options.json new file mode 100644 index 000000000000..188eae592ec5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-object-pattern/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Decorated private methods are not updatable, but \"#x\" is updated via this expression." +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-rest/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-rest/input.js new file mode 100644 index 000000000000..6b513a380627 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-rest/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec #x() {} + + bar() { + ([...this.#x] = this.baz); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-rest/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-rest/options.json new file mode 100644 index 000000000000..188eae592ec5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-rest/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Decorated private methods are not updatable, but \"#x\" is updated via this expression." +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-update/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-update/input.js new file mode 100644 index 000000000000..7d01837e1b51 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-update/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec #x() {} + + bar() { + this.#x++; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-update/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-update/options.json new file mode 100644 index 000000000000..188eae592ec5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method-via-update/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Decorated private methods are not updatable, but \"#x\" is updated via this expression." +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method/input.js new file mode 100644 index 000000000000..b6417214fec7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method/input.js @@ -0,0 +1,8 @@ +const dec = () => {}; +class Foo { + @dec #x() {} + + bar() { + this.#x = 123; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method/options.json new file mode 100644 index 000000000000..188eae592ec5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/setting-private-method/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Decorated private methods are not updatable, but \"#x\" is updated via this expression." +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-nested-constructor-expression/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-nested-constructor-expression/input.js new file mode 100644 index 000000000000..6bc1a7dbbc4b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-nested-constructor-expression/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +@dec +class Foo extends Bar { + constructor() { + let foo = super(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-nested-constructor-expression/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-nested-constructor-expression/output.js new file mode 100644 index 000000000000..afffeda95f1b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-nested-constructor-expression/output.js @@ -0,0 +1,20 @@ +var _initClass; + +const dec = () => {}; + +let _Foo; + +class Foo extends Bar { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2203(this, [], [dec]); + } + + constructor() { + let foo = super(); + } + + static { + _initClass(); + + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-accessor/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-accessor/input.js new file mode 100644 index 000000000000..b32ea0bd378f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-accessor/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +class Foo extends Bar { + @dec + get #x() { + return super.foo(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-accessor/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-accessor/output.js new file mode 100644 index 000000000000..7586519f462f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-accessor/output.js @@ -0,0 +1,22 @@ +var _call_x, _initProto; + +const dec = () => {}; + +class Foo extends Bar { + static { + [_call_x, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 3, "x", function () { + return babelHelpers.get(babelHelpers.getPrototypeOf(Foo), "foo", this).call(this); + }]], []); + } + + constructor(...args) { + super(...args); + + _initProto(this); + } + + get #x() { + return _call_x(this); + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-method/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-method/input.js new file mode 100644 index 000000000000..36f9bd37dfa7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-method/input.js @@ -0,0 +1,7 @@ +const dec = () => {}; +class Foo extends Bar { + @dec + #x() { + return super.foo(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-method/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-method/output.js new file mode 100644 index 000000000000..5bb7a0899d4e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/super-in-private-method/output.js @@ -0,0 +1,19 @@ +var _call_x, _initProto; + +const dec = () => {}; + +class Foo extends Bar { + static { + [_call_x, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 2, "x", function () { + return babelHelpers.get(babelHelpers.getPrototypeOf(Foo), "foo", this).call(this); + }]], []); + } + + constructor(...args) { + super(...args); + + _initProto(this); + } + + #x = _call_x; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/valid-expression-formats/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/valid-expression-formats/input.js new file mode 100644 index 000000000000..586564c5e219 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/valid-expression-formats/input.js @@ -0,0 +1,23 @@ +const dec = () => {}; +@dec +@call() +@chain.expr() +@(arbitrary + expr) +@(array[expr]) +class Foo { + #a; + + @dec + @call() + @chain.expr() + @(arbitrary + expr) + @(array[expr]) + method() {} + + makeClass() { + return class Nested { + @(this.#a) + bar; + } + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/valid-expression-formats/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/valid-expression-formats/output.js new file mode 100644 index 000000000000..3438a804bfbc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-misc/valid-expression-formats/output.js @@ -0,0 +1,44 @@ +var _initClass, _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto; + +const dec = () => {}; + +let _Foo; + +_dec = call(); +_dec2 = chain.expr(); +_dec3 = arbitrary + expr; +_dec4 = array[expr]; +_dec5 = call(); +_dec6 = chain.expr(); +_dec7 = arbitrary + expr; +_dec8 = array[expr]; + +class Foo { + static { + [_initProto, _Foo, _initClass] = babelHelpers.applyDecs2203(this, [[[dec, _dec5, _dec6, _dec7, _dec8], 2, "method"]], [dec, _dec, _dec2, _dec3, _dec4]); + } + + constructor(...args) { + _initProto(this); + } + + #a; + + method() {} + + makeClass() { + var _dec9, _init_bar; + + return _dec9 = this.#a, class Nested { + static { + [_init_bar] = babelHelpers.applyDecs2203(this, [[_dec9, 0, "bar"]], []); + } + bar = _init_bar(this); + }; + } + + static { + _initClass(); + + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/accessor-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/accessor-initializers/exec.js new file mode 100644 index 000000000000..892ced55301d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/accessor-initializers/exec.js @@ -0,0 +1,48 @@ +var log = []; + +function push(x) { log.push(x); return x; } + +function logClassDecoratorRun(a, b, c) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { push(c); }); + return el; + }; +} + +function logAccessorDecoratorRun(a, b, c, d) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { push(c); }); + return { + init: () => push(d) + }; + }; +} + +@logClassDecoratorRun(0, 19, 29) +@logClassDecoratorRun(1, 18, 28) +class A { + @logAccessorDecoratorRun(2, 15, 31, 35) + @logAccessorDecoratorRun(3, 14, 30, 34) + accessor a; + + @logAccessorDecoratorRun(4, 11, 21, 25) + @logAccessorDecoratorRun(5, 10, 20, 24) + static accessor b; + + @logAccessorDecoratorRun(6, 13, 23, 27) + @logAccessorDecoratorRun(7, 12, 22, 26) + static accessor #c; + + @logAccessorDecoratorRun(8, 17, 33, 37) + @logAccessorDecoratorRun(9, 16, 32, 36) + accessor #d; +} + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/decorators/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/decorators/exec.js new file mode 100644 index 000000000000..f44656aaee7c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/decorators/exec.js @@ -0,0 +1,31 @@ +var log = []; + +function push(x) { log.push(x); return x; } + +function logDecoratorRun(a, b) { + push(a); + return function (el) { push(b); return el; }; +} + +@logDecoratorRun(0, 19) +@logDecoratorRun(1, 18) +class A { + @logDecoratorRun(2, 15) + @logDecoratorRun(3, 14) + a; + + @logDecoratorRun(4, 11) + @logDecoratorRun(5, 10) + static b; + + @logDecoratorRun(6, 13) + @logDecoratorRun(7, 12) + static #c; + + @logDecoratorRun(8, 17) + @logDecoratorRun(9, 16) + #d; +} + +var nums = Array.from({ length: 20 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/field-initializers-after-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/field-initializers-after-methods/exec.js new file mode 100644 index 000000000000..46e71f7281db --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/field-initializers-after-methods/exec.js @@ -0,0 +1,27 @@ +var counter = 0; + +@(x => x) +class A { + foo = (() => { + counter++; + expect(typeof this.method).toBe("function"); + expect(this.foo).toBeUndefined(); + expect(this.bar).toBeUndefined(); + return "foo"; + })(); + + method() {} + + bar = (() => { + counter++; + expect(typeof this.method).toBe("function"); + expect(this.foo).toBe("foo"); + expect(this.bar).toBeUndefined(); + })(); +} + +expect(counter).toBe(0); + +new A(); + +expect(counter).toBe(2); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/initializers/exec.js new file mode 100644 index 000000000000..35e07dd009a1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/initializers/exec.js @@ -0,0 +1,53 @@ +var log = []; + +function push(x) { log.push(x); return x; } + +function logDecoratorRun(a, b, c) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { push(c); }); + return el; + }; +} + +@logDecoratorRun(0, 35, 45) +@logDecoratorRun(1, 34, 44) +class A { + @logDecoratorRun(2, 27, 47) + @logDecoratorRun(3, 26, 46) + a() {}; + + @logDecoratorRun(4, 19, 37) + @logDecoratorRun(5, 18, 36) + static b() {}; + + @logDecoratorRun(6, 21, 39) + @logDecoratorRun(7, 20, 38) + static #c() {}; + + @logDecoratorRun(8, 29, 49) + @logDecoratorRun(9, 28, 48) + #d() {}; + + @logDecoratorRun(10, 31, 51) + @logDecoratorRun(11, 30, 50) + accessor e; + + @logDecoratorRun(12, 23, 41) + @logDecoratorRun(13, 22, 40) + static accessor f; + + @logDecoratorRun(14, 25, 43) + @logDecoratorRun(15, 24, 42) + static accessor #g; + + @logDecoratorRun(16, 33, 53) + @logDecoratorRun(17, 32, 52) + accessor #h; +} + +new A(); + +var nums = Array.from({ length: 54 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/static-field-initializers-after-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/static-field-initializers-after-methods/exec.js new file mode 100644 index 000000000000..0703f091cc8d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering--to-es2015/static-field-initializers-after-methods/exec.js @@ -0,0 +1,23 @@ +var counter = 0; + +@(x => x) +class A { + static foo = (() => { + counter++; + expect(typeof this.method).toBe("function"); + expect(this.foo).toBeUndefined(); + expect(this.bar).toBeUndefined(); + return "foo"; + })(); + + static method() {} + + static bar = (() => { + counter++; + expect(typeof this.method).toBe("function"); + expect(this.foo).toBe("foo"); + expect(this.bar).toBeUndefined(); + })(); +} + +expect(counter).toBe(2); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/accessor-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/accessor-initializers/exec.js new file mode 100644 index 000000000000..892ced55301d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/accessor-initializers/exec.js @@ -0,0 +1,48 @@ +var log = []; + +function push(x) { log.push(x); return x; } + +function logClassDecoratorRun(a, b, c) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { push(c); }); + return el; + }; +} + +function logAccessorDecoratorRun(a, b, c, d) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { push(c); }); + return { + init: () => push(d) + }; + }; +} + +@logClassDecoratorRun(0, 19, 29) +@logClassDecoratorRun(1, 18, 28) +class A { + @logAccessorDecoratorRun(2, 15, 31, 35) + @logAccessorDecoratorRun(3, 14, 30, 34) + accessor a; + + @logAccessorDecoratorRun(4, 11, 21, 25) + @logAccessorDecoratorRun(5, 10, 20, 24) + static accessor b; + + @logAccessorDecoratorRun(6, 13, 23, 27) + @logAccessorDecoratorRun(7, 12, 22, 26) + static accessor #c; + + @logAccessorDecoratorRun(8, 17, 33, 37) + @logAccessorDecoratorRun(9, 16, 32, 36) + accessor #d; +} + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/decorators/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/decorators/exec.js new file mode 100644 index 000000000000..7a51e8b93b7e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/decorators/exec.js @@ -0,0 +1,31 @@ +var log = []; + +function push(x) { log.push(x); return x; } + +function logDecoratorRun(a, b) { + push(a); + return function (el) { push(b); return el; }; +} + +@logDecoratorRun(0, 21) +@logDecoratorRun(1, 20) +class A { + @logDecoratorRun(2, 17) + @logDecoratorRun(3, 16) + [push(4)]; + + @logDecoratorRun(5, 13) + @logDecoratorRun(6, 12) + static [push(7)]; + + @logDecoratorRun(8, 15) + @logDecoratorRun(9, 14) + static #c; + + @logDecoratorRun(10, 19) + @logDecoratorRun(11, 18) + #d; +} + +var nums = Array.from({ length: 22 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/field-initializers-after-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/field-initializers-after-methods/exec.js new file mode 100644 index 000000000000..46e71f7281db --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/field-initializers-after-methods/exec.js @@ -0,0 +1,27 @@ +var counter = 0; + +@(x => x) +class A { + foo = (() => { + counter++; + expect(typeof this.method).toBe("function"); + expect(this.foo).toBeUndefined(); + expect(this.bar).toBeUndefined(); + return "foo"; + })(); + + method() {} + + bar = (() => { + counter++; + expect(typeof this.method).toBe("function"); + expect(this.foo).toBe("foo"); + expect(this.bar).toBeUndefined(); + })(); +} + +expect(counter).toBe(0); + +new A(); + +expect(counter).toBe(2); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/initializers/exec.js new file mode 100644 index 000000000000..35e07dd009a1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/initializers/exec.js @@ -0,0 +1,53 @@ +var log = []; + +function push(x) { log.push(x); return x; } + +function logDecoratorRun(a, b, c) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { push(c); }); + return el; + }; +} + +@logDecoratorRun(0, 35, 45) +@logDecoratorRun(1, 34, 44) +class A { + @logDecoratorRun(2, 27, 47) + @logDecoratorRun(3, 26, 46) + a() {}; + + @logDecoratorRun(4, 19, 37) + @logDecoratorRun(5, 18, 36) + static b() {}; + + @logDecoratorRun(6, 21, 39) + @logDecoratorRun(7, 20, 38) + static #c() {}; + + @logDecoratorRun(8, 29, 49) + @logDecoratorRun(9, 28, 48) + #d() {}; + + @logDecoratorRun(10, 31, 51) + @logDecoratorRun(11, 30, 50) + accessor e; + + @logDecoratorRun(12, 23, 41) + @logDecoratorRun(13, 22, 40) + static accessor f; + + @logDecoratorRun(14, 25, 43) + @logDecoratorRun(15, 24, 42) + static accessor #g; + + @logDecoratorRun(16, 33, 53) + @logDecoratorRun(17, 32, 52) + accessor #h; +} + +new A(); + +var nums = Array.from({ length: 54 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/options.json new file mode 100644 index 000000000000..0afee1a5fdcb --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/options.json @@ -0,0 +1,4 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]], + "minNodeVersion": "16.11.0" +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/static-field-initializers-after-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/static-field-initializers-after-methods/exec.js new file mode 100644 index 000000000000..0703f091cc8d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-ordering/static-field-initializers-after-methods/exec.js @@ -0,0 +1,23 @@ +var counter = 0; + +@(x => x) +class A { + static foo = (() => { + counter++; + expect(typeof this.method).toBe("function"); + expect(this.foo).toBeUndefined(); + expect(this.bar).toBeUndefined(); + return "foo"; + })(); + + static method() {} + + static bar = (() => { + counter++; + expect(typeof this.method).toBe("function"); + expect(this.foo).toBe("foo"); + expect(this.bar).toBeUndefined(); + })(); +} + +expect(counter).toBe(2); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-accessor-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-accessor-decorator-return/exec.js new file mode 100644 index 000000000000..cd977fce13e0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-accessor-decorator-return/exec.js @@ -0,0 +1,20 @@ +const returnsUndefined = () => void 0; +const returnsNull = () => null; +const returnsFalse = () => false; +const returnsFunction = () => () => {} +const returnsGetSet = () => ({ set(v) {}, get() {} }); +const returnsInit = () => ({ init() {} }); +const returnsGetFalse = () => ({ get: false }); +const returnsSetFalse = () => ({ set: false }); +const returnsInitFalse = () => ({ init: false }); + +expect(() => class { @returnsNull accessor a }).toThrow("accessor decorators must return an object with get, set, or init properties or void 0") +expect(() => class { @returnsFalse accessor a }).toThrow("accessor decorators must return an object with get, set, or init properties or void 0") +expect(() => class { @returnsFunction accessor a }).toThrow("accessor decorators must return an object with get, set, or init properties or void 0") +expect(() => class { @returnsGetFalse accessor a }).toThrow("accessor.get must be a function"); +expect(() => class { @returnsSetFalse accessor a }).toThrow("accessor.set must be a function"); +expect(() => class { @returnsInitFalse accessor a }).toThrow("accessor.init must be a function"); + +expect(() => class { @returnsGetSet accessor a }).not.toThrow(); +expect(() => class { @returnsInit accessor a }).not.toThrow(); +expect(() => class { @returnsUndefined accessor a }).not.toThrow(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-add-initializer/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-add-initializer/exec.js new file mode 100644 index 000000000000..a91c771ca9b8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-add-initializer/exec.js @@ -0,0 +1,6 @@ +const decWithInitializer = (init) => (_, context) => { context.addInitializer(init) } + +expect(() => class { @decWithInitializer(null) static m() {} }).toThrow("An initializer must be a function") +expect(() => class { @decWithInitializer(false) static m() {} }).toThrow("An initializer must be a function") +expect(() => class { @decWithInitializer(void 0) static m() {} }).toThrow("An initializer must be a function"); +expect(() => class { @decWithInitializer(() => {}) static m() {} }).not.toThrow(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-class-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-class-decorator-return/exec.js new file mode 100644 index 000000000000..dc0b566937ae --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-class-decorator-return/exec.js @@ -0,0 +1,9 @@ +const returnsUndefined = () => void 0; +const returnsNull = () => null; +const returnsFalse = () => false; +const returnsFunction = () => () => {}; + +expect(() => @returnsNull class {}).toThrow("class decorators must return a function or void 0") +expect(() => @returnsFalse class {}).toThrow("class decorators must return a function or void 0") +expect(() => @returnsFunction class {}).not.toThrow(); +expect(() => @returnsUndefined class {}).not.toThrow(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-field-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-field-decorator-return/exec.js new file mode 100644 index 000000000000..2776eb4561c6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-field-decorator-return/exec.js @@ -0,0 +1,9 @@ +const returnsUndefined = () => void 0; +const returnsNull = () => null; +const returnsFalse = () => false; +const returnsFunction = () => () => {}; + +expect(() => class { @returnsNull m() {} }).toThrow("method decorators must return a function or void 0") +expect(() => class { @returnsFalse m() {} }).toThrow("method decorators must return a function or void 0") +expect(() => class { @returnsFunction m() {} }).not.toThrow(); +expect(() => class { @returnsUndefined m() {} }).not.toThrow(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-getter-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-getter-decorator-return/exec.js new file mode 100644 index 000000000000..eb9e8bcdcc03 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-getter-decorator-return/exec.js @@ -0,0 +1,9 @@ +const returnsUndefined = () => void 0; +const returnsNull = () => null; +const returnsFalse = () => false; +const returnsFunction = () => () => {}; + +expect(() => class { @returnsNull get p() {} }).toThrow("method decorators must return a function or void 0") +expect(() => class { @returnsFalse get p() {} }).toThrow("method decorators must return a function or void 0") +expect(() => class { @returnsFunction get p() {} }).not.toThrow(); +expect(() => class { @returnsUndefined get p() {} }).not.toThrow(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-method-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-method-decorator-return/exec.js new file mode 100644 index 000000000000..181333cf4840 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-method-decorator-return/exec.js @@ -0,0 +1,9 @@ +const returnsUndefined = () => void 0; +const returnsNull = () => null; +const returnsFalse = () => false; +const returnsFunction = () => () => {}; + +expect(() => class { @returnsNull p }).toThrow("field decorators must return a function or void 0") +expect(() => class { @returnsFalse p }).toThrow("field decorators must return a function or void 0") +expect(() => class { @returnsFunction p }).not.toThrow(); +expect(() => class { @returnsUndefined p }).not.toThrow(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-setter-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-setter-decorator-return/exec.js new file mode 100644 index 000000000000..d0f7f5115a97 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/invalid-setter-decorator-return/exec.js @@ -0,0 +1,9 @@ +const returnsUndefined = () => void 0; +const returnsNull = () => null; +const returnsFalse = () => false; +const returnsFunction = () => () => {}; + +expect(() => class { @returnsNull set p(v) {} }).toThrow("method decorators must return a function or void 0") +expect(() => class { @returnsFalse set p(v) {} }).toThrow("method decorators must return a function or void 0") +expect(() => class { @returnsFunction set p(v) {} }).not.toThrow(); +expect(() => class { @returnsUndefined set p(v) {} }).not.toThrow(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-runtime-errors--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/options.json new file mode 100644 index 000000000000..d10a62d5e998 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2022-03" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/exec.js new file mode 100644 index 000000000000..92edbba8d758 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/exec.js @@ -0,0 +1,38 @@ +function dec(set, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function (v) { + return set.call(this, v + 1); + } +} + +class Foo { + value = 1; + + @dec + set #a(v) { + return this.value = v; + } + + setA(v) { + this.#a = v; + } +} + +let foo = new Foo(); + +const aContext = foo['#aContext']; + +expect(foo.value).toBe(1); +aContext.access.set.call(foo, 123); +expect(foo.value).toBe(124); +foo.setA(456); +expect(foo.value).toBe(457); + +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('setter'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/input.js new file mode 100644 index 000000000000..66dd78268d19 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + set #a(v) { + return this.value = v; + } + + setA(v) { + this.#a = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/output.js new file mode 100644 index 000000000000..56d7e1460884 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/private/output.js @@ -0,0 +1,30 @@ +var _call_a, _initProto; + +const dec = () => {}; + +var _a = /*#__PURE__*/new WeakMap(); + +class Foo { + constructor(...args) { + babelHelpers.classPrivateFieldInitSpec(this, _a, { + get: void 0, + set: _set_a + }); + babelHelpers.defineProperty(this, "value", 1); + + _initProto(this); + } + + setA(v) { + babelHelpers.classPrivateFieldSet(this, _a, v); + } + +} + +function _set_a(v) { + _call_a(this, v); +} + +[_call_a, _initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 4, "a", function (v) { + return this.value = v; +}]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/exec.js new file mode 100644 index 000000000000..2088079a4c03 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/exec.js @@ -0,0 +1,46 @@ +function dec(set, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function (v) { + return set.call(this, v + 1); + } +} + +class Foo { + value = 1; + + @dec + set a(v) { + return this.value = v; + } + + @dec + set ['b'](v) { + return this.value = v; + } +} + +let foo = new Foo(); + +const aContext = foo['aContext']; +const bContext = foo['bContext']; + +expect(foo.value).toBe(1); +foo.a = 123; +expect(foo.value).toBe(124); +aContext.access.set.call(foo, 456); +expect(foo.value).toBe(457); + +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('setter'); +expect(aContext.static).toBe(false); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('function'); + +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('setter'); +expect(bContext.static).toBe(false); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/input.js new file mode 100644 index 000000000000..9a7faf175edd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + set a(v) { + return this.value = v; + } + + @dec + set ['b'](v) { + return this.value = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/output.js new file mode 100644 index 000000000000..499ca8bf355c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initProto; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + constructor(...args) { + babelHelpers.defineProperty(this, "value", 1); + + _initProto(this); + } + + set a(v) { + return this.value = v; + } + + set [_computedKey](v) { + return this.value = v; + } + +} + +[_initProto] = babelHelpers.applyDecs2203(Foo, [[dec, 4, "a"], [dec, 4, _computedKey]], []); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..7d90402d8101 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/exec.js @@ -0,0 +1,36 @@ +function dec(set, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function (v) { + return set.call(this, v + 1); + } +} + +class Foo { + static value = 1; + + @dec + static set #a(v) { + return this.value = v; + } + + static setA(v) { + this.#a = v; + } +} + +const aContext = Foo['#aContext']; + +expect(Foo.value).toBe(1); +aContext.access.set.call(Foo, 123); +expect(Foo.value).toBe(124); +Foo.setA(456); +expect(Foo.value).toBe(457); + +expect(aContext.name).toBe('#a'); +expect(aContext.kind).toBe('setter'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(true); +expect(typeof aContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/input.js new file mode 100644 index 000000000000..6bf29a2a2c94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static set #a(v) { + return this.value = v; + } + + static setA(v) { + this.#a = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/output.js new file mode 100644 index 000000000000..09f58c0ddabe --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-private/output.js @@ -0,0 +1,29 @@ +var _call_a, _initStatic; + +const dec = () => {}; + +class Foo { + static setA(v) { + babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _a, v); + } + +} + +function _set_a(v) { + _call_a(this, v); +} + +var _a = { + get: void 0, + set: _set_a +}; + +(() => { + [_call_a, _initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 9, "a", function (v) { + return this.value = v; + }]], []); + + _initStatic(Foo); +})(); + +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..818681cbe4c3 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/exec.js @@ -0,0 +1,45 @@ +function dec(set, context) { + context.addInitializer(function() { + this[context.name + 'Context'] = context; + }); + + return function (v) { + return set.call(this, v + 1); + } +} + +class Foo { + static value = 1; + + @dec + static set a(v) { + return this.value = v; + } + + @dec + static set ['b'](v) { + return this.value = v; + } +} + +const aContext = Foo['aContext']; +const bContext = Foo['bContext']; + + +expect(Foo.value).toBe(1); +Foo.a = 123; +expect(Foo.value).toBe(124); +aContext.access.set.call(Foo, 456); +expect(Foo.value).toBe(457); + +expect(aContext.name).toBe('a'); +expect(aContext.kind).toBe('setter'); +expect(aContext.static).toBe(true); +expect(aContext.private).toBe(false); +expect(typeof aContext.addInitializer).toBe('function'); + +expect(bContext.name).toBe('b'); +expect(bContext.kind).toBe('setter'); +expect(bContext.static).toBe(true); +expect(bContext.private).toBe(false); +expect(typeof bContext.addInitializer).toBe('function'); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/input.js new file mode 100644 index 000000000000..ed0a661dcb2d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static set a(v) { + return this.value = v; + } + + @dec + static set ['b'](v) { + return this.value = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/output.js new file mode 100644 index 000000000000..5383f8640e15 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters--to-es2015/static-public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initStatic; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static set a(v) { + return this.value = v; + } + + static set [_computedKey](v) { + return this.value = v; + } + +} + +(() => { + [_initStatic] = babelHelpers.applyDecs2203(Foo, [[dec, 9, "a"], [dec, 9, _computedKey]], []); + + _initStatic(Foo); +})(); + +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/options.json new file mode 100644 index 000000000000..bc44f5391db6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2022-03" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/private/input.js new file mode 100644 index 000000000000..66dd78268d19 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + set #a(v) { + return this.value = v; + } + + setA(v) { + this.#a = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/private/output.js new file mode 100644 index 000000000000..eed6978af80a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/private/output.js @@ -0,0 +1,26 @@ +var _call_a, _initProto; + +const dec = () => {}; + +class Foo { + static { + [_call_a, _initProto] = babelHelpers.applyDecs2203(this, [[dec, 4, "a", function (v) { + return this.value = v; + }]], []); + } + + constructor(...args) { + _initProto(this); + } + + value = 1; + + set #a(v) { + _call_a(this, v); + } + + setA(v) { + this.#a = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/public/input.js new file mode 100644 index 000000000000..9a7faf175edd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + value = 1; + + @dec + set a(v) { + return this.value = v; + } + + @dec + set ['b'](v) { + return this.value = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/public/output.js new file mode 100644 index 000000000000..028f0d6b04e5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/public/output.js @@ -0,0 +1,26 @@ +var _computedKey, _initProto; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2203(this, [[dec, 4, "a"], [dec, 4, _computedKey]], []); + } + + constructor(...args) { + _initProto(this); + } + + value = 1; + + set a(v) { + return this.value = v; + } + + set [_computedKey](v) { + return this.value = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-private/input.js new file mode 100644 index 000000000000..6bf29a2a2c94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-private/input.js @@ -0,0 +1,13 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static set #a(v) { + return this.value = v; + } + + static setA(v) { + this.#a = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-private/output.js new file mode 100644 index 000000000000..3019c8c51d6c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-private/output.js @@ -0,0 +1,24 @@ +var _call_a, _initStatic; + +const dec = () => {}; + +class Foo { + static { + [_call_a, _initStatic] = babelHelpers.applyDecs2203(this, [[dec, 9, "a", function (v) { + return this.value = v; + }]], []); + + _initStatic(this); + + } + static value = 1; + + static set #a(v) { + _call_a(this, v); + } + + static setA(v) { + this.#a = v; + } + +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-public/input.js new file mode 100644 index 000000000000..ed0a661dcb2d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-public/input.js @@ -0,0 +1,14 @@ +const dec = () => {}; +class Foo { + static value = 1; + + @dec + static set a(v) { + return this.value = v; + } + + @dec + static set ['b'](v) { + return this.value = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-public/output.js new file mode 100644 index 000000000000..5c6b2d0069f0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2022-03-setters/static-public/output.js @@ -0,0 +1,24 @@ +var _computedKey, _initStatic; + +const dec = () => {}; + +_computedKey = 'b'; + +class Foo { + static { + [_initStatic] = babelHelpers.applyDecs2203(this, [[dec, 9, "a"], [dec, 9, _computedKey]], []); + + _initStatic(this); + + } + static value = 1; + + static set a(v) { + return this.value = v; + } + + static set [_computedKey](v) { + return this.value = v; + } + +} diff --git a/packages/babel-plugin-syntax-decorators/src/index.ts b/packages/babel-plugin-syntax-decorators/src/index.ts index d4f914ce38ed..00a35d163ef1 100644 --- a/packages/babel-plugin-syntax-decorators/src/index.ts +++ b/packages/babel-plugin-syntax-decorators/src/index.ts @@ -3,8 +3,8 @@ import { declare } from "@babel/helper-plugin-utils"; export interface Options { // TODO(Babel 8): Remove legacy?: boolean; - // TODO(Babel 8): Remove "2018-09" - version?: "legacy" | "2018-09" | "2021-12"; + // TODO(Babel 8): Remove "2018-09" and "2021-12" + version?: "legacy" | "2018-09" | "2021-12" | "2022-03"; // TODO(Babel 8): Remove decoratorsBeforeExport?: boolean; } @@ -18,10 +18,14 @@ export default declare((api, options: Options) => { if (version === undefined) { throw new Error( "The decorators plugin requires a 'version' option, whose value must be one of: " + - "'2021-12', '2018-09', or 'legacy'.", + "'2022-03', '2021-12', '2018-09', or 'legacy'.", ); } - if (version !== "2021-12" && version !== "legacy") { + if ( + version !== "2022-03" && + version !== "2021-12" && + version !== "legacy" + ) { throw new Error("Unsupported decorators version: " + version); } if (options.legacy !== undefined) { @@ -51,6 +55,7 @@ export default declare((api, options: Options) => { if (version === undefined) { version = legacy ? "legacy" : "2018-09"; } else if ( + version !== "2022-03" && version !== "2021-12" && version !== "2018-09" && version !== "legacy" @@ -61,7 +66,7 @@ export default declare((api, options: Options) => { // eslint-disable-next-line no-var var { decoratorsBeforeExport } = options; if (decoratorsBeforeExport === undefined) { - if (version === "2021-12") { + if (version === "2021-12" || version === "2022-03") { decoratorsBeforeExport = false; } else if (version === "2018-09") { throw new Error( @@ -70,9 +75,9 @@ export default declare((api, options: Options) => { ); } } else { - if (version === "legacy") { + if (version === "legacy" || version === "2022-03") { throw new Error( - "'decoratorsBeforeExport' can't be used with legacy decorators.", + `'decoratorsBeforeExport' can't be used with ${version} decorators.`, ); } if (typeof decoratorsBeforeExport !== "boolean") { @@ -89,11 +94,22 @@ export default declare((api, options: Options) => { parserOpts.plugins.push("decorators-legacy"); } else if (process.env.BABEL_8_BREAKING) { parserOpts.plugins.push( - ["decorators", { decoratorsBeforeExport: false }], + [ + "decorators", + { decoratorsBeforeExport: false, allowCallParenthesized: false }, + ], "decoratorAutoAccessors", ); } else { - if (version === "2021-12") { + if (version === "2022-03") { + parserOpts.plugins.push( + [ + "decorators", + { decoratorsBeforeExport: false, allowCallParenthesized: false }, + ], + "decoratorAutoAccessors", + ); + } else if (version === "2021-12") { parserOpts.plugins.push( ["decorators", { decoratorsBeforeExport }], "decoratorAutoAccessors", diff --git a/packages/babel-plugin-syntax-decorators/test/index.js b/packages/babel-plugin-syntax-decorators/test/index.js index 0d7927af9dd3..c15d7db243e8 100644 --- a/packages/babel-plugin-syntax-decorators/test/index.js +++ b/packages/babel-plugin-syntax-decorators/test/index.js @@ -67,6 +67,15 @@ babel7describe("'decoratorsBeforeExport' option", function () { ).not.toThrow(); }); + test("is incompatible with 2022-03 decorators", function () { + expect( + makeParser("", { decoratorsBeforeExport: false, version: "2022-03" }), + ).toThrow(); + expect( + makeParser("", { decoratorsBeforeExport: true, version: "2022-03" }), + ).toThrow(); + }); + const BEFORE = "@dec export class Foo {}"; const AFTER = "export @dec class Foo {}"; @@ -112,6 +121,13 @@ describe("'version' option", function () { ).toThrow(); }); + test("'2022-03' disallows @(...)()", function () { + expect(makeParser("@(foo)() class A {}", { version: "2022-03" })).toThrow(); + expect( + makeParser("@(foo()) class A {}", { version: "2022-03" }), + ).not.toThrow(); + }); + babel8("is required", function () { expect(makeParser("", {})).toThrow(); }); diff --git a/packages/babel-runtime-corejs2/package.json b/packages/babel-runtime-corejs2/package.json index 33fa3fb70952..1118ee1b6f87 100644 --- a/packages/babel-runtime-corejs2/package.json +++ b/packages/babel-runtime-corejs2/package.json @@ -27,6 +27,15 @@ "./helpers/applyDecs.js" ], "./helpers/esm/applyDecs": "./helpers/esm/applyDecs.js", + "./helpers/applyDecs2203": [ + { + "node": "./helpers/applyDecs2203.js", + "import": "./helpers/esm/applyDecs2203.js", + "default": "./helpers/applyDecs2203.js" + }, + "./helpers/applyDecs2203.js" + ], + "./helpers/esm/applyDecs2203": "./helpers/esm/applyDecs2203.js", "./helpers/asyncIterator": [ { "node": "./helpers/asyncIterator.js", diff --git a/packages/babel-runtime-corejs3/package.json b/packages/babel-runtime-corejs3/package.json index d09fad753c0a..09ae601a81df 100644 --- a/packages/babel-runtime-corejs3/package.json +++ b/packages/babel-runtime-corejs3/package.json @@ -26,6 +26,15 @@ "./helpers/applyDecs.js" ], "./helpers/esm/applyDecs": "./helpers/esm/applyDecs.js", + "./helpers/applyDecs2203": [ + { + "node": "./helpers/applyDecs2203.js", + "import": "./helpers/esm/applyDecs2203.js", + "default": "./helpers/applyDecs2203.js" + }, + "./helpers/applyDecs2203.js" + ], + "./helpers/esm/applyDecs2203": "./helpers/esm/applyDecs2203.js", "./helpers/asyncIterator": [ { "node": "./helpers/asyncIterator.js", diff --git a/packages/babel-runtime/package.json b/packages/babel-runtime/package.json index 4615d956ecd2..43641a1efd21 100644 --- a/packages/babel-runtime/package.json +++ b/packages/babel-runtime/package.json @@ -26,6 +26,15 @@ "./helpers/applyDecs.js" ], "./helpers/esm/applyDecs": "./helpers/esm/applyDecs.js", + "./helpers/applyDecs2203": [ + { + "node": "./helpers/applyDecs2203.js", + "import": "./helpers/esm/applyDecs2203.js", + "default": "./helpers/applyDecs2203.js" + }, + "./helpers/applyDecs2203.js" + ], + "./helpers/esm/applyDecs2203": "./helpers/esm/applyDecs2203.js", "./helpers/asyncIterator": [ { "node": "./helpers/asyncIterator.js",