diff --git a/Makefile b/Makefile index 62b5b9e54e6f..213654ec7370 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -FLOW_COMMIT = 92bbb5e9dacb8185aa73ea343954d0434b42c40b -TEST262_COMMIT = a29788dd5d4d7664478985928e82f2a1cd7fb37d -TYPESCRIPT_COMMIT = ce85d647ef88183c019588bcf398320ce29b625a +FLOW_COMMIT = 105ad30f566f401db9cafcb49cd2831fb29e87c5 +TEST262_COMMIT = 76a14bf659be962dd0efa694c4f9fc12f159f774 +TYPESCRIPT_COMMIT = d87d0adcd30ac285393bf3bfbbb4d94d50c4f3c9 # Fix color output until TravisCI fixes https://github.com/travis-ci/travis-ci/issues/7967 export FORCE_COLOR = true @@ -177,15 +177,16 @@ test-test262-update-allowlist: new-version-checklist: - # @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - # @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - # @echo "!!!!!! !!!!!!" - # @echo "!!!!!! Add any message here, and UNCOMMENT THESE LINES! !!!!!!" - # @echo "!!!!!! !!!!!!" - # @echo "!!!!!! !!!!!!" - # @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - # @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - # @exit 1 + @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + @echo "!!!!!! !!!!!!" + @echo "!!!!!! Update the version to 7.21.0 in the applyDecs2301 !!!!!!" + @echo "!!!!!! helper, and in the assertVersion call for 2023-01 !!!!!!" + @echo "!!!!!! in transformer-2023-01.ts !!!!!!" + @echo "!!!!!! !!!!!!" + @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + @exit 1 new-version: $(MAKE) new-version-checklist diff --git a/packages/babel-generator/src/generators/classes.ts b/packages/babel-generator/src/generators/classes.ts index e1b4b401d26d..adbb030aea80 100644 --- a/packages/babel-generator/src/generators/classes.ts +++ b/packages/babel-generator/src/generators/classes.ts @@ -11,15 +11,16 @@ export function ClassDeclaration( node: t.ClassDeclaration, parent: t.Node, ) { - if (process.env.BABEL_8_BREAKING) { + const inExport = + isExportDefaultDeclaration(parent) || isExportNamedDeclaration(parent); + + if ( + !inExport || + !this._shouldPrintDecoratorsBeforeExport( + parent as t.ExportDeclaration & { declaration: t.ClassDeclaration }, + ) + ) { this.printJoin(node.decorators, node); - } else { - if ( - !this.format.decoratorsBeforeExport || - (!isExportDefaultDeclaration(parent) && !isExportNamedDeclaration(parent)) - ) { - this.printJoin(node.decorators, node); - } } if (node.declare) { diff --git a/packages/babel-generator/src/generators/expressions.ts b/packages/babel-generator/src/generators/expressions.ts index 458e0d9af3d2..9244f6005956 100644 --- a/packages/babel-generator/src/generators/expressions.ts +++ b/packages/babel-generator/src/generators/expressions.ts @@ -140,6 +140,18 @@ function shouldParenthesizeDecoratorExpression( ); } +export function _shouldPrintDecoratorsBeforeExport( + this: Printer, + node: t.ExportDeclaration & { declaration: t.ClassDeclaration }, +) { + if (typeof this.format.decoratorsBeforeExport === "boolean") { + return this.format.decoratorsBeforeExport; + } + return ( + typeof node.start === "number" && node.start === node.declaration.start + ); +} + export function Decorator(this: Printer, node: t.Decorator) { this.token("@"); const { expression } = node; diff --git a/packages/babel-generator/src/generators/modules.ts b/packages/babel-generator/src/generators/modules.ts index 0b8d426f22f2..b34eb14f0139 100644 --- a/packages/babel-generator/src/generators/modules.ts +++ b/packages/babel-generator/src/generators/modules.ts @@ -106,18 +106,25 @@ export function ExportAllDeclaration( this.semicolon(); } +function maybePrintDecoratorsBeforeExport( + printer: Printer, + node: t.ExportNamedDeclaration | t.ExportDefaultDeclaration, +) { + if ( + isClassDeclaration(node.declaration) && + printer._shouldPrintDecoratorsBeforeExport( + node as t.ExportNamedDeclaration & { declaration: t.ClassDeclaration }, + ) + ) { + printer.printJoin(node.declaration.decorators, node); + } +} + export function ExportNamedDeclaration( this: Printer, node: t.ExportNamedDeclaration, ) { - if (!process.env.BABEL_8_BREAKING) { - if ( - this.format.decoratorsBeforeExport && - isClassDeclaration(node.declaration) - ) { - this.printJoin(node.declaration.decorators, node); - } - } + maybePrintDecoratorsBeforeExport(this, node); this.word("export"); this.space(); @@ -183,14 +190,7 @@ export function ExportDefaultDeclaration( this: Printer, node: t.ExportDefaultDeclaration, ) { - if (!process.env.BABEL_8_BREAKING) { - if ( - this.format.decoratorsBeforeExport && - isClassDeclaration(node.declaration) - ) { - this.printJoin(node.declaration.decorators, node); - } - } + maybePrintDecoratorsBeforeExport(this, node); this.word("export"); this.noIndentInnerCommentsHere(); diff --git a/packages/babel-generator/src/index.ts b/packages/babel-generator/src/index.ts index 2b3982cfe986..08c2377dd201 100644 --- a/packages/babel-generator/src/index.ts +++ b/packages/babel-generator/src/index.ts @@ -76,7 +76,7 @@ function normalizeOptions( }; if (!process.env.BABEL_8_BREAKING) { - format.decoratorsBeforeExport = !!opts.decoratorsBeforeExport; + format.decoratorsBeforeExport = opts.decoratorsBeforeExport; format.jsonCompatibleStrings = opts.jsonCompatibleStrings; } @@ -200,8 +200,9 @@ export interface GeneratorOptions { jsonCompatibleStrings?: boolean; /** - * Set to true to enable support for experimental decorators syntax before module exports. - * Defaults to `false`. + * Set to true to enable support for experimental decorators syntax before + * module exports. If not specified, decorators will be printed in the same + * position as they were in the input source code. * @deprecated Removed in Babel 8 */ decoratorsBeforeExport?: boolean; diff --git a/packages/babel-generator/test/fixtures/comments/decorators-after-export/input.js b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-after/input.js similarity index 100% rename from packages/babel-generator/test/fixtures/comments/decorators-after-export/input.js rename to packages/babel-generator/test/fixtures/comments/decorators-after-export-to-after/input.js diff --git a/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-after/options.json b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-after/options.json new file mode 100644 index 000000000000..24702bf30c9e --- /dev/null +++ b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-after/options.json @@ -0,0 +1,4 @@ +{ + "plugins": ["decorators"], + "decoratorsBeforeExport": false +} diff --git a/packages/babel-generator/test/fixtures/comments/decorators-after-export/output.js b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-after/output.js similarity index 100% rename from packages/babel-generator/test/fixtures/comments/decorators-after-export/output.js rename to packages/babel-generator/test/fixtures/comments/decorators-after-export-to-after/output.js diff --git a/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/input.js b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/input.js new file mode 100644 index 000000000000..1f389f07c313 --- /dev/null +++ b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/input.js @@ -0,0 +1,5 @@ +/* 1 */ export /* 2 */ @dec1 /* 3 */ @dec2 +/* 4 */ class /* 5 */ C /* 6 */ { /* 7 */ } /* 8 */ + +/* A */ export /* B */ default /* C */ @dec1 /* D */ @dec2 +/* E */ class /* F */ { /* G */ } /* H */ diff --git a/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/options.json b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/options.json new file mode 100644 index 000000000000..95f7a731442d --- /dev/null +++ b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/options.json @@ -0,0 +1,5 @@ +{ + "BABEL_8_BREAKING": false, + "plugins": ["decorators"], + "decoratorsBeforeExport": true +} diff --git a/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/output.js b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/output.js new file mode 100644 index 000000000000..22eb11b1791c --- /dev/null +++ b/packages/babel-generator/test/fixtures/comments/decorators-after-export-to-before/output.js @@ -0,0 +1,9 @@ +/* 1 */@dec1 +/* 3 */@dec2 +/* 4 */export /* 2 */class /* 5 */C /* 6 */ {/* 7 */} /* 8 */ + +/* A */ +@dec1 +/* D */@dec2 +/* E */export /* B */ +default /* C */class /* F */{/* G */} /* H */ \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/comments/decorators-before-export/input.js b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-after/input.js similarity index 100% rename from packages/babel-generator/test/fixtures/comments/decorators-before-export/input.js rename to packages/babel-generator/test/fixtures/comments/decorators-before-export-to-after/input.js diff --git a/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-after/options.json b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-after/options.json new file mode 100644 index 000000000000..e49ab63ebb5a --- /dev/null +++ b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-after/options.json @@ -0,0 +1,5 @@ +{ + "BABEL_8_BREAKING": false, + "plugins": ["decorators"], + "decoratorsBeforeExport": false +} diff --git a/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-after/output.js b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-after/output.js new file mode 100644 index 000000000000..932d02fb4263 --- /dev/null +++ b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-after/output.js @@ -0,0 +1,9 @@ +/* 1 */export /* 4 */@dec1 +/* 2 */@dec2 +/* 3 */class /* 5 */C /* 6 */ {/* 7 */} /* 8 */ + +/* A */ +export +/* D */ default /* E */@dec1 +/* B */@dec2 +/* C */class /* F */{/* G */} /* H */ \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-before/input.js b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-before/input.js new file mode 100644 index 000000000000..83739b654ed7 --- /dev/null +++ b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-before/input.js @@ -0,0 +1,5 @@ +/* 1 */ @dec1 /* 2 */ @dec2 /* 3 */ +export /* 4 */ class /* 5 */ C /* 6 */ { /* 7 */ } /* 8 */ + +/* A */ @dec1 /* B */ @dec2 /* C */ +export /* D */ default /* E */ class /* F */ { /* G */ } /* H */ diff --git a/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-before/options.json b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-before/options.json new file mode 100644 index 000000000000..95f7a731442d --- /dev/null +++ b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-before/options.json @@ -0,0 +1,5 @@ +{ + "BABEL_8_BREAKING": false, + "plugins": ["decorators"], + "decoratorsBeforeExport": true +} diff --git a/packages/babel-generator/test/fixtures/comments/decorators-before-export/output.js b/packages/babel-generator/test/fixtures/comments/decorators-before-export-to-before/output.js similarity index 100% rename from packages/babel-generator/test/fixtures/comments/decorators-before-export/output.js rename to packages/babel-generator/test/fixtures/comments/decorators-before-export-to-before/output.js diff --git a/packages/babel-generator/test/fixtures/decorators/export-after/input.js b/packages/babel-generator/test/fixtures/decorators/export-after/input.js new file mode 100644 index 000000000000..231c34bf4a86 --- /dev/null +++ b/packages/babel-generator/test/fixtures/decorators/export-after/input.js @@ -0,0 +1,2 @@ +@dec export class A {} +@dec export default class {} diff --git a/packages/babel-generator/test/fixtures/decorators/export-after/output.js b/packages/babel-generator/test/fixtures/decorators/export-after/output.js new file mode 100644 index 000000000000..398434600c57 --- /dev/null +++ b/packages/babel-generator/test/fixtures/decorators/export-after/output.js @@ -0,0 +1,4 @@ +@dec +export class A {} +@dec +export default class {} \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/decorators/export-before/input.js b/packages/babel-generator/test/fixtures/decorators/export-before/input.js new file mode 100644 index 000000000000..bcee35982c4e --- /dev/null +++ b/packages/babel-generator/test/fixtures/decorators/export-before/input.js @@ -0,0 +1,2 @@ +export @dec class A {} +export default @dec class {} diff --git a/packages/babel-generator/test/fixtures/decorators/export-before/output.js b/packages/babel-generator/test/fixtures/decorators/export-before/output.js new file mode 100644 index 000000000000..0b2f865e5692 --- /dev/null +++ b/packages/babel-generator/test/fixtures/decorators/export-before/output.js @@ -0,0 +1,4 @@ +export @dec +class A {} +export default @dec +class {} \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/decorators/options.json b/packages/babel-generator/test/fixtures/decorators/options.json index 234fb2bac889..d760b0afda2a 100644 --- a/packages/babel-generator/test/fixtures/decorators/options.json +++ b/packages/babel-generator/test/fixtures/decorators/options.json @@ -1,4 +1,3 @@ { - "plugins": [["decorators", { "decoratorsBeforeExport": false }]], - "decoratorsBeforeExport": true + "plugins": ["decorators"] } diff --git a/packages/babel-helpers/src/helpers-generated.ts b/packages/babel-helpers/src/helpers-generated.ts index c089739f9b9f..cd7f37a0b0c9 100644 --- a/packages/babel-helpers/src/helpers-generated.ts +++ b/packages/babel-helpers/src/helpers-generated.ts @@ -31,7 +31,11 @@ export default Object.freeze({ ), applyDecs2203R: helper( "7.20.0", - 'function createAddInitializerMethod(initializers,decoratorFinishedRef){return function(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:kindStr="accessor";break;case 2:kindStr="method";break;case 3:kindStr="getter";break;case 4:kindStr="setter";break;default:kindStr="field"}var get,set,ctx={kind:kindStr,name:isPrivate?"#"+name:name,static:isStatic,private:isPrivate},decoratorFinishedRef={v:!1};0!==kind&&(ctx.addInitializer=createAddInitializerMethod(initializers,decoratorFinishedRef)),0===kind?isPrivate?(get=desc.get,set=desc.set):(get=function(){return this[name]},set=function(v){this[name]=v}):2===kind?get=function(){return desc.value}:(1!==kind&&3!==kind||(get=function(){return desc.get.call(this)}),1!==kind&&4!==kind||(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=!0}}function assertNotFinished(decoratorFinishedRef,fnName){if(decoratorFinishedRef.v)throw new Error("attempted to call "+fnName+" after decoration was finished")}function assertCallable(fn,hint){if("function"!=typeof fn)throw new TypeError(hint+" must be a function")}function assertValidReturnValue(kind,value){var type=typeof value;if(1===kind){if("object"!==type||null===value)throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");void 0!==value.get&&assertCallable(value.get,"accessor.get"),void 0!==value.set&&assertCallable(value.set,"accessor.set"),void 0!==value.init&&assertCallable(value.init,"accessor.init")}else if("function"!==type){var hint;throw hint=0===kind?"field":10===kind?"class":"method",new TypeError(hint+" decorators must return a function or void 0")}}function applyMemberDec(ret,base,decInfo,name,kind,isStatic,isPrivate,initializers){var desc,init,value,newValue,get,set,decs=decInfo[0];if(isPrivate?desc=0===kind||1===kind?{get:decInfo[3],set:decInfo[4]}:3===kind?{get:decInfo[3]}:4===kind?{set:decInfo[3]}:{value:decInfo[3]}:0!==kind&&(desc=Object.getOwnPropertyDescriptor(base,name)),1===kind?value={get:desc.get,set:desc.set}:2===kind?value=desc.value:3===kind?value=desc.get:4===kind&&(value=desc.set),"function"==typeof decs)void 0!==(newValue=memberDec(decs,name,desc,initializers,kind,isStatic,isPrivate,value))&&(assertValidReturnValue(kind,newValue),0===kind?init=newValue:1===kind?(init=newValue.init,get=newValue.get||value.get,set=newValue.set||value.set,value={get:get,set:set}):value=newValue);else for(var i=decs.length-1;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)}}return pushInitializers(ret,protoInitializers),pushInitializers(ret,staticInitializers),ret}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)}return[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)}}return pushInitializers(ret,protoInitializers),pushInitializers(ret,staticInitializers),ret}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)}return[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,hasPrivateBrand)))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,hasPrivateBrand=instanceBrand;if(isStatic?(base=Class,0!==(kind-=5)&&(initializers=staticInitializers=staticInitializers||[]),isPrivate&&!staticBrand&&(staticBrand=function(_){return checkInRHS(_)===Class}),hasPrivateBrand=staticBrand):(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,hasPrivateBrand)}}return pushInitializers(ret,protoInitializers),pushInitializers(ret,staticInitializers),ret}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)}return[newClass,function(){for(var i=0;i= 0; i--) { - var dec = decs[i]; + var newValue, get, set; + + if (typeof decs === "function") { newValue = memberDec( - dec, + decs, name, desc, initializers, @@ -253,12 +226,11 @@ function applyMemberDec( if (newValue !== void 0) { assertValidReturnValue(kind, newValue); - var newInit; if (kind === 0 /* FIELD */) { - newInit = newValue; + init = newValue; } else if (kind === 1 /* ACCESSOR */) { - newInit = newValue.init; + init = newValue.init; get = newValue.get || value.get; set = newValue.set || value.set; @@ -266,214 +238,245 @@ function applyMemberDec( } 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 (newInit !== void 0) { - if (init === void 0) { - init = newInit; - } else if (typeof init === "function") { - init = [init, 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 { - init.push(newInit); + 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; + 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); + } - init = function (instance, init) { - return originalInitializer.call(instance, init); - }; - } + return value; + }; + } else { + var originalInitializer = init; - ret.push(init); - } + init = function (instance, init) { + return originalInitializer.call(instance, 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; + ret.push(init); } - if (isPrivate) { + if (kind !== 0 /* FIELD */) { 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); - }); + desc.get = value.get; + desc.set = value.set; } else if (kind === 2 /* METHOD */) { - ret.push(value); + 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 { - ret.push(function (instance, args) { - return value.call(instance, args); - }); + Object.defineProperty(base, name, desc); } - } else { - Object.defineProperty(base, name, desc); } } -} -function applyMemberDecs(Class, decInfos) { - var ret = []; - var protoInitializers; - var staticInitializers; + function applyMemberDecs(Class, decInfos) { + var ret = []; + var protoInitializers; + var staticInitializers; - var existingProtoNonFields = new Map(); - var existingStaticNonFields = new Map(); + var existingProtoNonFields = new Map(); + var existingStaticNonFields = new Map(); - for (var i = 0; i < decInfos.length; i++) { - var decInfo = decInfos[i]; + for (var i = 0; i < decInfos.length; i++) { + var decInfo = decInfos[i]; - // skip computed property names - if (!Array.isArray(decInfo)) continue; + // skip computed property names + if (!Array.isArray(decInfo)) continue; - var kind = decInfo[1]; - var name = decInfo[2]; - var isPrivate = decInfo.length > 3; + var kind = decInfo[1]; + var name = decInfo[2]; + var isPrivate = decInfo.length > 3; - var isStatic = kind >= 5; /* STATIC */ - var base; - var initializers; + 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 (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); + 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 + ); } - applyMemberDec( - ret, - base, - decInfo, - name, - kind, - isStatic, - isPrivate, - initializers - ); + pushInitializers(ret, protoInitializers); + pushInitializers(ret, staticInitializers); + return ret; } - pushInitializers(ret, protoInitializers); - pushInitializers(ret, staticInitializers); - return ret; -} - -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 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(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; - } + function applyClassDecs(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; + if (nextNewClass !== undefined) { + assertValidReturnValue(10 /* CLASS */, nextNewClass); + newClass = nextNewClass; + } } - } - return [ - newClass, - function () { - for (var i = 0; i < initializers.length; i++) { - initializers[i].call(newClass); - } - }, - ]; + return [ + newClass, + function () { + for (var i = 0; i < initializers.length; i++) { + initializers[i].call(newClass); + } + }, + ]; + } + // The transformer will not emit assignment when there are no class decorators, + // so we don't have to return an empty array here. } - // The transformer will not emit assignment when there are no class decorators, - // so we don't have to return an empty array here. -} -/** + /** Basic usage: applyDecs( @@ -618,12 +621,22 @@ function applyClassDecs(targetClass, classDecs) { initializeClass(Class); */ -export default function applyDecs2203R(targetClass, memberDecs, classDecs) { - return { - e: applyMemberDecs(targetClass, memberDecs), - // Lazily apply class decorations so that member init locals can be properly bound. - get c() { - return applyClassDecs(targetClass, classDecs); - }, + + return function applyDecs2203R(targetClass, memberDecs, classDecs) { + return { + e: applyMemberDecs(targetClass, memberDecs), + // Lazily apply class decorations so that member init locals can be properly bound. + get c() { + return applyClassDecs(targetClass, classDecs); + }, + }; }; } + +export default function applyDecs2203R(targetClass, memberDecs, classDecs) { + return (applyDecs2203R = applyDecs2203RFactory())( + targetClass, + memberDecs, + classDecs + ); +} diff --git a/packages/babel-helpers/src/helpers/applyDecs2301.js b/packages/babel-helpers/src/helpers/applyDecs2301.js new file mode 100644 index 000000000000..813df640a4d8 --- /dev/null +++ b/packages/babel-helpers/src/helpers/applyDecs2301.js @@ -0,0 +1,691 @@ +/* @minVersion 7.20.0 */ + +import checkInRHS from "checkInRHS"; + +/** + 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 assertInstanceIfPrivate(has, target) { + if (!has(target)) { + throw new TypeError("Attempted to access private element on non-instance"); + } +} + +function memberDec( + dec, + name, + desc, + initializers, + kind, + isStatic, + isPrivate, + value, + hasPrivateBrand +) { + 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 (!isPrivate && (kind === 0 /* FIELD */ || kind === 2) /* METHOD */) { + get = function (target) { + return target[name]; + }; + if (kind === 0 /* FIELD */) { + set = function (target, v) { + target[name] = v; + }; + } + } else if (kind === 2 /* METHOD */) { + // Assert: isPrivate is true. + get = function (target) { + assertInstanceIfPrivate(hasPrivateBrand, target); + return desc.value; + }; + } else { + // Assert: If kind === 0, then isPrivate is true. + var t = kind === 0 /* FIELD */ || kind === 1; /* ACCESSOR */ + if (t || kind === 3 /* GETTER */) { + if (isPrivate) { + get = function (target) { + assertInstanceIfPrivate(hasPrivateBrand, target); + return desc.get.call(target); + }; + } else { + get = function (target) { + return desc.get.call(target); + }; + } + } + if (t || kind === 4 /* SETTER */) { + if (isPrivate) { + set = function (target, value) { + assertInstanceIfPrivate(hasPrivateBrand, target); + desc.set.call(target, value); + }; + } else { + set = function (target, value) { + desc.set.call(target, value); + }; + } + } + } + var has = isPrivate + ? hasPrivateBrand.bind() + : function (target) { + return name in target; + }; + ctx.access = + get && set + ? { get: get, set: set, has: has } + : get + ? { get: get, has: has } + : { set: set, has: has }; + + 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 curryThis1(fn) { + return function () { + return fn(this); + }; +} +function curryThis2(fn) { + return function (value) { + fn(this, value); + }; +} + +function applyMemberDec( + ret, + base, + decInfo, + name, + kind, + isStatic, + isPrivate, + initializers, + hasPrivateBrand +) { + var decs = decInfo[0]; + + var desc, init, value; + + if (isPrivate) { + if (kind === 0 /* FIELD */ || kind === 1 /* ACCESSOR */) { + desc = { + get: curryThis1(decInfo[3]), + set: curryThis2(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, + hasPrivateBrand + ); + + 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, + hasPrivateBrand + ); + + 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(Class, decInfos, instanceBrand) { + var ret = []; + var protoInitializers; + var staticInitializers; + var staticBrand; + + 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; + var hasPrivateBrand = instanceBrand; + + 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; + } + if (isPrivate && !staticBrand) { + staticBrand = function (_) { + return checkInRHS(_) === Class; + }; + } + hasPrivateBrand = staticBrand; + } 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, + hasPrivateBrand + ); + } + + pushInitializers(ret, protoInitializers); + pushInitializers(ret, staticInitializers); + return ret; +} + +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(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; + } + } + + return [ + newClass, + function () { + for (var i = 0; i < initializers.length; i++) { + initializers[i].call(newClass); + } + }, + ]; + } + // The transformer will not emit assignment when there are no class decorators, + // so we don't have to return an empty array here. +} + +/** + 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 applyDecs2301( + targetClass, + memberDecs, + classDecs, + instanceBrand +) { + return { + e: applyMemberDecs(targetClass, memberDecs, instanceBrand), + // Lazily apply class decorations so that member init locals can be properly bound. + get c() { + return applyClassDecs(targetClass, classDecs); + }, + }; +} diff --git a/packages/babel-parser/src/parse-error/standard-errors.ts b/packages/babel-parser/src/parse-error/standard-errors.ts index 11550e0e11d7..b68c923dbaad 100644 --- a/packages/babel-parser/src/parse-error/standard-errors.ts +++ b/packages/babel-parser/src/parse-error/standard-errors.ts @@ -56,11 +56,13 @@ export default { 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.", + "Decorators must be placed *before* the 'export' keyword. Remove the 'decoratorsBeforeExport: true' option to use the 'export @decorator class {}' syntax.", + DecoratorsBeforeAfterExport: + "Decorators can be placed *either* before or after the 'export' keyword, but not in both locations at the same time.", DecoratorConstructor: "Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?", DecoratorExportClass: - "Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.", + "Decorators must be placed *after* the 'export' keyword. Remove the 'decoratorsBeforeExport: false' option to use the '@decorator export class {}' syntax.", DecoratorSemicolon: "Decorators must not be followed by a semicolon.", DecoratorStaticBlock: "Decorators can't be used with a static block.", DeletePrivateField: "Deleting a private field is not allowed.", diff --git a/packages/babel-parser/src/parser/statement.ts b/packages/babel-parser/src/parser/statement.ts index 6fa0049c5910..7d1506ab558e 100644 --- a/packages/babel-parser/src/parser/statement.ts +++ b/packages/babel-parser/src/parser/statement.ts @@ -658,7 +658,7 @@ export default abstract class StatementParser extends ExpressionParser { if (this.hasPlugin("decorators-legacy")) return true; return ( this.hasPlugin("decorators") && - !!this.getPluginOption("decorators", "decoratorsBeforeExport") + this.getPluginOption("decorators", "decoratorsBeforeExport") !== false ); } @@ -674,7 +674,26 @@ export default abstract class StatementParser extends ExpressionParser { exportNode?: Undone, ): T { if (maybeDecorators) { - classNode.decorators = maybeDecorators; + if (classNode.decorators && classNode.decorators.length > 0) { + // Note: decorators attachment is only attempred multiple times + // when the class is part of an export declaration. + if ( + typeof this.getPluginOption( + "decorators", + "decoratorsBeforeExport", + ) !== "boolean" + ) { + // If `decoratorsBeforeExport` was set to `true` or `false`, we + // already threw an error about decorators not being in a valid + // position. + this.raise(Errors.DecoratorsBeforeAfterExport, { + at: classNode.decorators[0], + }); + } + classNode.decorators.unshift(...maybeDecorators); + } else { + classNode.decorators = maybeDecorators; + } this.resetStartLocationFromNode(classNode, maybeDecorators[0]); if (exportNode) this.resetStartLocationFromNode(exportNode, classNode); } @@ -2481,7 +2500,7 @@ export default abstract class StatementParser extends ExpressionParser { if (this.match(tt.at)) { if ( this.hasPlugin("decorators") && - this.getPluginOption("decorators", "decoratorsBeforeExport") + this.getPluginOption("decorators", "decoratorsBeforeExport") === true ) { this.raise(Errors.DecoratorBeforeExport, { at: this.state.startLoc }); } @@ -2596,8 +2615,10 @@ export default abstract class StatementParser extends ExpressionParser { if (type === tt.at) { this.expectOnePlugin(["decorators", "decorators-legacy"]); if (this.hasPlugin("decorators")) { - if (this.getPluginOption("decorators", "decoratorsBeforeExport")) { - throw this.raise(Errors.DecoratorBeforeExport, { + if ( + this.getPluginOption("decorators", "decoratorsBeforeExport") === true + ) { + this.raise(Errors.DecoratorBeforeExport, { at: this.state.startLoc, }); } diff --git a/packages/babel-parser/src/plugin-utils.ts b/packages/babel-parser/src/plugin-utils.ts index 6c3893e6fd0c..40d1babe1f27 100644 --- a/packages/babel-parser/src/plugin-utils.ts +++ b/packages/babel-parser/src/plugin-utils.ts @@ -91,7 +91,9 @@ export function validatePlugins(plugins: PluginList) { decoratorsBeforeExport != null && typeof decoratorsBeforeExport !== "boolean" ) { - throw new Error("'decoratorsBeforeExport' must be a boolean."); + throw new Error( + "'decoratorsBeforeExport' must be a boolean, if specified.", + ); } const allowCallParenthesized = getPluginOption( diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/input.js new file mode 100644 index 000000000000..47821207173b --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/input.js @@ -0,0 +1,3 @@ +@dec1 export @dec2 class Foo {} + +@dec3 export default @dec2 class Bar {} diff --git a/packages/babel-generator/test/fixtures/comments/decorators-after-export/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/options.json similarity index 64% rename from packages/babel-generator/test/fixtures/comments/decorators-after-export/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/options.json index 7ebfdd91777b..ca59dc053473 100644 --- a/packages/babel-generator/test/fixtures/comments/decorators-after-export/options.json +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/options.json @@ -1,4 +1,4 @@ { - "plugins": [["decorators", { "decoratorsBeforeExport": false }]], - "decoratorsBeforeExport": false + "sourceType": "module", + "plugins": [["decorators", { "decoratorsBeforeExport": false }]] } diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/output.json new file mode 100644 index 000000000000..9dc84d208871 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-false/output.json @@ -0,0 +1,97 @@ +{ + "type": "File", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":39,"index":72}}, + "errors": [ + "SyntaxError: Decorators must be placed *after* the 'export' keyword. Remove the 'decoratorsBeforeExport: false' option to use the '@decorator export class {}' syntax. (1:6)", + "SyntaxError: Decorators must be placed *after* the 'export' keyword. Remove the 'decoratorsBeforeExport: false' option to use the '@decorator export class {}' syntax. (3:6)" + ], + "program": { + "type": "Program", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":39,"index":72}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":31,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":31,"index":31}}, + "specifiers": [], + "source": null, + "declaration": { + "type": "ClassDeclaration", + "start":0,"end":31,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":31,"index":31}}, + "decorators": [ + { + "type": "Decorator", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":5,"index":5}}, + "expression": { + "type": "Identifier", + "start":1,"end":5,"loc":{"start":{"line":1,"column":1,"index":1},"end":{"line":1,"column":5,"index":5},"identifierName":"dec1"}, + "name": "dec1" + } + }, + { + "type": "Decorator", + "start":13,"end":18,"loc":{"start":{"line":1,"column":13,"index":13},"end":{"line":1,"column":18,"index":18}}, + "expression": { + "type": "Identifier", + "start":14,"end":18,"loc":{"start":{"line":1,"column":14,"index":14},"end":{"line":1,"column":18,"index":18},"identifierName":"dec2"}, + "name": "dec2" + } + } + ], + "id": { + "type": "Identifier", + "start":25,"end":28,"loc":{"start":{"line":1,"column":25,"index":25},"end":{"line":1,"column":28,"index":28},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":29,"end":31,"loc":{"start":{"line":1,"column":29,"index":29},"end":{"line":1,"column":31,"index":31}}, + "body": [] + } + } + }, + { + "type": "ExportDefaultDeclaration", + "start":33,"end":72,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":39,"index":72}}, + "declaration": { + "type": "ClassDeclaration", + "start":33,"end":72,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":39,"index":72}}, + "decorators": [ + { + "type": "Decorator", + "start":33,"end":38,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":5,"index":38}}, + "expression": { + "type": "Identifier", + "start":34,"end":38,"loc":{"start":{"line":3,"column":1,"index":34},"end":{"line":3,"column":5,"index":38},"identifierName":"dec3"}, + "name": "dec3" + } + }, + { + "type": "Decorator", + "start":54,"end":59,"loc":{"start":{"line":3,"column":21,"index":54},"end":{"line":3,"column":26,"index":59}}, + "expression": { + "type": "Identifier", + "start":55,"end":59,"loc":{"start":{"line":3,"column":22,"index":55},"end":{"line":3,"column":26,"index":59},"identifierName":"dec2"}, + "name": "dec2" + } + } + ], + "id": { + "type": "Identifier", + "start":66,"end":69,"loc":{"start":{"line":3,"column":33,"index":66},"end":{"line":3,"column":36,"index":69},"identifierName":"Bar"}, + "name": "Bar" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":70,"end":72,"loc":{"start":{"line":3,"column":37,"index":70},"end":{"line":3,"column":39,"index":72}}, + "body": [] + } + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-true/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-true/input.js new file mode 100644 index 000000000000..47821207173b --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-true/input.js @@ -0,0 +1,3 @@ +@dec1 export @dec2 class Foo {} + +@dec3 export default @dec2 class Bar {} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-with-parens/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-true/options.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-with-parens/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-true/options.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-true/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-true/output.json new file mode 100644 index 000000000000..b6987b28bb29 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export-decoratorsBeforeExport-true/output.json @@ -0,0 +1,97 @@ +{ + "type": "File", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":39,"index":72}}, + "errors": [ + "SyntaxError: Decorators must be placed *before* the 'export' keyword. Remove the 'decoratorsBeforeExport: true' option to use the 'export @decorator class {}' syntax. (1:13)", + "SyntaxError: Decorators must be placed *before* the 'export' keyword. Remove the 'decoratorsBeforeExport: true' option to use the 'export @decorator class {}' syntax. (3:21)" + ], + "program": { + "type": "Program", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":39,"index":72}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":31,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":31,"index":31}}, + "specifiers": [], + "source": null, + "declaration": { + "type": "ClassDeclaration", + "start":0,"end":31,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":31,"index":31}}, + "decorators": [ + { + "type": "Decorator", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":5,"index":5}}, + "expression": { + "type": "Identifier", + "start":1,"end":5,"loc":{"start":{"line":1,"column":1,"index":1},"end":{"line":1,"column":5,"index":5},"identifierName":"dec1"}, + "name": "dec1" + } + }, + { + "type": "Decorator", + "start":13,"end":18,"loc":{"start":{"line":1,"column":13,"index":13},"end":{"line":1,"column":18,"index":18}}, + "expression": { + "type": "Identifier", + "start":14,"end":18,"loc":{"start":{"line":1,"column":14,"index":14},"end":{"line":1,"column":18,"index":18},"identifierName":"dec2"}, + "name": "dec2" + } + } + ], + "id": { + "type": "Identifier", + "start":25,"end":28,"loc":{"start":{"line":1,"column":25,"index":25},"end":{"line":1,"column":28,"index":28},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":29,"end":31,"loc":{"start":{"line":1,"column":29,"index":29},"end":{"line":1,"column":31,"index":31}}, + "body": [] + } + } + }, + { + "type": "ExportDefaultDeclaration", + "start":33,"end":72,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":39,"index":72}}, + "declaration": { + "type": "ClassDeclaration", + "start":33,"end":72,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":39,"index":72}}, + "decorators": [ + { + "type": "Decorator", + "start":33,"end":38,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":5,"index":38}}, + "expression": { + "type": "Identifier", + "start":34,"end":38,"loc":{"start":{"line":3,"column":1,"index":34},"end":{"line":3,"column":5,"index":38},"identifierName":"dec3"}, + "name": "dec3" + } + }, + { + "type": "Decorator", + "start":54,"end":59,"loc":{"start":{"line":3,"column":21,"index":54},"end":{"line":3,"column":26,"index":59}}, + "expression": { + "type": "Identifier", + "start":55,"end":59,"loc":{"start":{"line":3,"column":22,"index":55},"end":{"line":3,"column":26,"index":59},"identifierName":"dec2"}, + "name": "dec2" + } + } + ], + "id": { + "type": "Identifier", + "start":66,"end":69,"loc":{"start":{"line":3,"column":33,"index":66},"end":{"line":3,"column":36,"index":69},"identifierName":"Bar"}, + "name": "Bar" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":70,"end":72,"loc":{"start":{"line":3,"column":37,"index":70},"end":{"line":3,"column":39,"index":72}}, + "body": [] + } + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export/input.js new file mode 100644 index 000000000000..47821207173b --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export/input.js @@ -0,0 +1,3 @@ +@dec1 export @dec2 class Foo {} + +@dec3 export default @dec2 class Bar {} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export/options.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export/options.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export/output.json new file mode 100644 index 000000000000..08196a336718 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decorators-before-and-after-export/output.json @@ -0,0 +1,97 @@ +{ + "type": "File", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":39,"index":72}}, + "errors": [ + "SyntaxError: Decorators can be placed *either* before or after the 'export' keyword, but not in both locations at the same time. (1:13)", + "SyntaxError: Decorators can be placed *either* before or after the 'export' keyword, but not in both locations at the same time. (3:21)" + ], + "program": { + "type": "Program", + "start":0,"end":72,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":39,"index":72}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":31,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":31,"index":31}}, + "specifiers": [], + "source": null, + "declaration": { + "type": "ClassDeclaration", + "start":0,"end":31,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":31,"index":31}}, + "decorators": [ + { + "type": "Decorator", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":5,"index":5}}, + "expression": { + "type": "Identifier", + "start":1,"end":5,"loc":{"start":{"line":1,"column":1,"index":1},"end":{"line":1,"column":5,"index":5},"identifierName":"dec1"}, + "name": "dec1" + } + }, + { + "type": "Decorator", + "start":13,"end":18,"loc":{"start":{"line":1,"column":13,"index":13},"end":{"line":1,"column":18,"index":18}}, + "expression": { + "type": "Identifier", + "start":14,"end":18,"loc":{"start":{"line":1,"column":14,"index":14},"end":{"line":1,"column":18,"index":18},"identifierName":"dec2"}, + "name": "dec2" + } + } + ], + "id": { + "type": "Identifier", + "start":25,"end":28,"loc":{"start":{"line":1,"column":25,"index":25},"end":{"line":1,"column":28,"index":28},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":29,"end":31,"loc":{"start":{"line":1,"column":29,"index":29},"end":{"line":1,"column":31,"index":31}}, + "body": [] + } + } + }, + { + "type": "ExportDefaultDeclaration", + "start":33,"end":72,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":39,"index":72}}, + "declaration": { + "type": "ClassDeclaration", + "start":33,"end":72,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":39,"index":72}}, + "decorators": [ + { + "type": "Decorator", + "start":33,"end":38,"loc":{"start":{"line":3,"column":0,"index":33},"end":{"line":3,"column":5,"index":38}}, + "expression": { + "type": "Identifier", + "start":34,"end":38,"loc":{"start":{"line":3,"column":1,"index":34},"end":{"line":3,"column":5,"index":38},"identifierName":"dec3"}, + "name": "dec3" + } + }, + { + "type": "Decorator", + "start":54,"end":59,"loc":{"start":{"line":3,"column":21,"index":54},"end":{"line":3,"column":26,"index":59}}, + "expression": { + "type": "Identifier", + "start":55,"end":59,"loc":{"start":{"line":3,"column":22,"index":55},"end":{"line":3,"column":26,"index":59},"identifierName":"dec2"}, + "name": "dec2" + } + } + ], + "id": { + "type": "Identifier", + "start":66,"end":69,"loc":{"start":{"line":3,"column":33,"index":66},"end":{"line":3,"column":36,"index":69},"identifierName":"Bar"}, + "name": "Bar" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":70,"end":72,"loc":{"start":{"line":3,"column":37,"index":70},"end":{"line":3,"column":39,"index":72}}, + "body": [] + } + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-boolean/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-boolean/options.json deleted file mode 100644 index 2397f70ee665..000000000000 --- a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-boolean/options.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "plugins": [["decorators", { "decoratorsBeforeExport": "yes" }]], - "throws": "'decoratorsBeforeExport' must be a boolean." -} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/no-export-decorators-on-class/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-false-decorator-before-export/input.js similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/no-export-decorators-on-class/input.js rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-false-decorator-before-export/input.js diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-false-decorator-before-export/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-false-decorator-before-export/options.json new file mode 100644 index 000000000000..ca59dc053473 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-false-decorator-before-export/options.json @@ -0,0 +1,4 @@ +{ + "sourceType": "module", + "plugins": [["decorators", { "decoratorsBeforeExport": false }]] +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/no-export-decorators-on-class/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-false-decorator-before-export/output.json similarity index 89% rename from packages/babel-parser/test/fixtures/experimental/decorators/no-export-decorators-on-class/output.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-false-decorator-before-export/output.json index 4f2b0e7f3213..db02aae1a90b 100644 --- a/packages/babel-parser/test/fixtures/experimental/decorators/no-export-decorators-on-class/output.json +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-false-decorator-before-export/output.json @@ -2,7 +2,7 @@ "type": "File", "start":0,"end":28,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":2,"column":23,"index":28}}, "errors": [ - "SyntaxError: Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead. (2:0)" + "SyntaxError: Decorators must be placed *after* the 'export' keyword. Remove the 'decoratorsBeforeExport: false' option to use the '@decorator export class {}' syntax. (2:0)" ], "program": { "type": "Program", diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-boolean/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-invalid/input.js similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-boolean/input.js rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-invalid/input.js diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-invalid/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-invalid/options.json new file mode 100644 index 000000000000..ae07b71cb51e --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-invalid/options.json @@ -0,0 +1,11 @@ +{ + "plugins": [ + [ + "decorators", + { + "decoratorsBeforeExport": "yes" + } + ] + ], + "throws": "'decoratorsBeforeExport' must be a boolean, if specified." +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-decorator-after-export/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-decorator-after-export/options.json index fb8aa087e818..3d20bee94540 100644 --- a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-decorator-after-export/options.json +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-decorator-after-export/options.json @@ -1,12 +1,4 @@ { - "plugins": [ - [ - "decorators", - { - "decoratorsBeforeExport": true - } - ] - ], "sourceType": "module", - "throws": "Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax. (1:7)" -} \ No newline at end of file + "plugins": [["decorators", { "decoratorsBeforeExport": true }]] +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-decorator-after-export/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-decorator-after-export/output.json new file mode 100644 index 000000000000..5fad089a6d2f --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-decorator-after-export/output.json @@ -0,0 +1,48 @@ +{ + "type": "File", + "start":0,"end":30,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":30,"index":30}}, + "errors": [ + "SyntaxError: Decorators must be placed *before* the 'export' keyword. Remove the 'decoratorsBeforeExport: true' option to use the 'export @decorator class {}' syntax. (1:7)" + ], + "program": { + "type": "Program", + "start":0,"end":30,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":30,"index":30}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":30,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":30,"index":30}}, + "specifiers": [], + "source": null, + "declaration": { + "type": "ClassDeclaration", + "start":7,"end":30,"loc":{"start":{"line":1,"column":7,"index":7},"end":{"line":1,"column":30,"index":30}}, + "decorators": [ + { + "type": "Decorator", + "start":7,"end":17,"loc":{"start":{"line":1,"column":7,"index":7},"end":{"line":1,"column":17,"index":17}}, + "expression": { + "type": "Identifier", + "start":8,"end":17,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":1,"column":17,"index":17},"identifierName":"decorator"}, + "name": "decorator" + } + } + ], + "id": { + "type": "Identifier", + "start":24,"end":27,"loc":{"start":{"line":1,"column":24,"index":24},"end":{"line":1,"column":27,"index":27},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":28,"end":30,"loc":{"start":{"line":1,"column":28,"index":28},"end":{"line":1,"column":30,"index":30}}, + "body": [] + } + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-with-parens/input.mjs b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-with-parens/input.mjs similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-with-parens/input.mjs rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-with-parens/input.mjs diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-with-parens/options.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-with-parens/options.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-with-parens/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-with-parens/output.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-with-parens/output.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-with-parens/output.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-without-parens/input.mjs b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-without-parens/input.mjs similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-without-parens/input.mjs rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-without-parens/input.mjs diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-without-parens/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-without-parens/options.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-without-parens/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-without-parens/options.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-without-parens/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-without-parens/output.json similarity index 93% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-without-parens/output.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-without-parens/output.json index 1ce5385eaf13..e737f77793fa 100644 --- a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default-decorated-expression-without-parens/output.json +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default-decorated-expression-without-parens/output.json @@ -2,7 +2,7 @@ "type": "File", "start":0,"end":38,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":38,"index":38}}, "errors": [ - "SyntaxError: Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax. (1:15)" + "SyntaxError: Decorators must be placed *before* the 'export' keyword. Remove the 'decoratorsBeforeExport: true' option to use the 'export @decorator class {}' syntax. (1:15)" ], "program": { "type": "Program", diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default/input.mjs b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default/input.mjs similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default/input.mjs rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default/input.mjs diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default/options.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default/options.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default/output.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export-default/output.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export-default/output.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export/input.mjs b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export/input.mjs similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export/input.mjs rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export/input.mjs diff --git a/packages/babel-generator/test/fixtures/comments/decorators-before-export/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export/options.json similarity index 51% rename from packages/babel-generator/test/fixtures/comments/decorators-before-export/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export/options.json index f82968d9ccb5..3d20bee94540 100644 --- a/packages/babel-generator/test/fixtures/comments/decorators-before-export/options.json +++ b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export/options.json @@ -1,5 +1,4 @@ { - "BABEL_8_BREAKING": false, - "plugins": [["decorators", { "decoratorsBeforeExport": true }]], - "decoratorsBeforeExport": true + "sourceType": "module", + "plugins": [["decorators", { "decoratorsBeforeExport": true }]] } diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export/output.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-export/output.json rename to packages/babel-parser/test/fixtures/experimental/decorators/decoratorsBeforeExport-true-export/output.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-after-export/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-after-export/input.js new file mode 100644 index 000000000000..dd0a3dc22a5a --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-after-export/input.js @@ -0,0 +1,3 @@ +export @dec2 class Foo {} + +export default @dec2 class Bar {} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-default-decorated-class/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-after-export/options.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/export-default-decorated-class/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-after-export/options.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-after-export/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-after-export/output.json new file mode 100644 index 000000000000..4ad0fbb3d9c2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-after-export/output.json @@ -0,0 +1,75 @@ +{ + "type": "File", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":33,"index":60}}, + "program": { + "type": "Program", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":33,"index":60}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":25,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":25,"index":25}}, + "specifiers": [], + "source": null, + "declaration": { + "type": "ClassDeclaration", + "start":7,"end":25,"loc":{"start":{"line":1,"column":7,"index":7},"end":{"line":1,"column":25,"index":25}}, + "decorators": [ + { + "type": "Decorator", + "start":7,"end":12,"loc":{"start":{"line":1,"column":7,"index":7},"end":{"line":1,"column":12,"index":12}}, + "expression": { + "type": "Identifier", + "start":8,"end":12,"loc":{"start":{"line":1,"column":8,"index":8},"end":{"line":1,"column":12,"index":12},"identifierName":"dec2"}, + "name": "dec2" + } + } + ], + "id": { + "type": "Identifier", + "start":19,"end":22,"loc":{"start":{"line":1,"column":19,"index":19},"end":{"line":1,"column":22,"index":22},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":23,"end":25,"loc":{"start":{"line":1,"column":23,"index":23},"end":{"line":1,"column":25,"index":25}}, + "body": [] + } + } + }, + { + "type": "ExportDefaultDeclaration", + "start":27,"end":60,"loc":{"start":{"line":3,"column":0,"index":27},"end":{"line":3,"column":33,"index":60}}, + "declaration": { + "type": "ClassDeclaration", + "start":42,"end":60,"loc":{"start":{"line":3,"column":15,"index":42},"end":{"line":3,"column":33,"index":60}}, + "decorators": [ + { + "type": "Decorator", + "start":42,"end":47,"loc":{"start":{"line":3,"column":15,"index":42},"end":{"line":3,"column":20,"index":47}}, + "expression": { + "type": "Identifier", + "start":43,"end":47,"loc":{"start":{"line":3,"column":16,"index":43},"end":{"line":3,"column":20,"index":47},"identifierName":"dec2"}, + "name": "dec2" + } + } + ], + "id": { + "type": "Identifier", + "start":54,"end":57,"loc":{"start":{"line":3,"column":27,"index":54},"end":{"line":3,"column":30,"index":57},"identifierName":"Bar"}, + "name": "Bar" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":58,"end":60,"loc":{"start":{"line":3,"column":31,"index":58},"end":{"line":3,"column":33,"index":60}}, + "body": [] + } + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-before-export/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-before-export/input.js new file mode 100644 index 000000000000..6decee2eaa0c --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-before-export/input.js @@ -0,0 +1,3 @@ +@dec1 export class Foo {} + +@dec3 export default class Bar {} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/no-export-decorators-on-class/options.json b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-before-export/options.json similarity index 100% rename from packages/babel-parser/test/fixtures/experimental/decorators/no-export-decorators-on-class/options.json rename to packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-before-export/options.json diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-before-export/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-before-export/output.json new file mode 100644 index 000000000000..83487439893b --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class-decorators-before-export/output.json @@ -0,0 +1,75 @@ +{ + "type": "File", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":33,"index":60}}, + "program": { + "type": "Program", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":3,"column":33,"index":60}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":25,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":25,"index":25}}, + "specifiers": [], + "source": null, + "declaration": { + "type": "ClassDeclaration", + "start":0,"end":25,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":25,"index":25}}, + "id": { + "type": "Identifier", + "start":19,"end":22,"loc":{"start":{"line":1,"column":19,"index":19},"end":{"line":1,"column":22,"index":22},"identifierName":"Foo"}, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":23,"end":25,"loc":{"start":{"line":1,"column":23,"index":23},"end":{"line":1,"column":25,"index":25}}, + "body": [] + }, + "decorators": [ + { + "type": "Decorator", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":5,"index":5}}, + "expression": { + "type": "Identifier", + "start":1,"end":5,"loc":{"start":{"line":1,"column":1,"index":1},"end":{"line":1,"column":5,"index":5},"identifierName":"dec1"}, + "name": "dec1" + } + } + ] + } + }, + { + "type": "ExportDefaultDeclaration", + "start":27,"end":60,"loc":{"start":{"line":3,"column":0,"index":27},"end":{"line":3,"column":33,"index":60}}, + "declaration": { + "type": "ClassDeclaration", + "start":27,"end":60,"loc":{"start":{"line":3,"column":0,"index":27},"end":{"line":3,"column":33,"index":60}}, + "id": { + "type": "Identifier", + "start":54,"end":57,"loc":{"start":{"line":3,"column":27,"index":54},"end":{"line":3,"column":30,"index":57},"identifierName":"Bar"}, + "name": "Bar" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start":58,"end":60,"loc":{"start":{"line":3,"column":31,"index":58},"end":{"line":3,"column":33,"index":60}}, + "body": [] + }, + "decorators": [ + { + "type": "Decorator", + "start":27,"end":32,"loc":{"start":{"line":3,"column":0,"index":27},"end":{"line":3,"column":5,"index":32}}, + "expression": { + "type": "Identifier", + "start":28,"end":32,"loc":{"start":{"line":3,"column":1,"index":28},"end":{"line":3,"column":5,"index":32},"identifierName":"dec3"}, + "name": "dec3" + } + } + ] + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class/input.js deleted file mode 100644 index 54720fa38516..000000000000 --- a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class/input.js +++ /dev/null @@ -1 +0,0 @@ -export @bar class Foo { } diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class/output.json deleted file mode 100644 index c4fbf64ae1b9..000000000000 --- a/packages/babel-parser/test/fixtures/experimental/decorators/export-decorated-class/output.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "type": "File", - "start":0,"end":25,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":25,"index":25}}, - "program": { - "type": "Program", - "start":0,"end":25,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":25,"index":25}}, - "sourceType": "module", - "interpreter": null, - "body": [ - { - "type": "ExportNamedDeclaration", - "start":0,"end":25,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":25,"index":25}}, - "specifiers": [], - "source": null, - "declaration": { - "type": "ClassDeclaration", - "start":7,"end":25,"loc":{"start":{"line":1,"column":7,"index":7},"end":{"line":1,"column":25,"index":25}}, - "decorators": [ - { - "type": "Decorator", - "start":7,"end":11,"loc":{"start":{"line":1,"column":7,"index":7},"end":{"line":1,"column":11,"index":11}}, - "expression": { - "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" - } - } - ], - "id": { - "type": "Identifier", - "start":18,"end":21,"loc":{"start":{"line":1,"column":18,"index":18},"end":{"line":1,"column":21,"index":21},"identifierName":"Foo"}, - "name": "Foo" - }, - "superClass": null, - "body": { - "type": "ClassBody", - "start":22,"end":25,"loc":{"start":{"line":1,"column":22,"index":22},"end":{"line":1,"column":25,"index":25}}, - "body": [] - } - } - } - ], - "directives": [] - } -} diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-default-decorated-class/input.js b/packages/babel-parser/test/fixtures/experimental/decorators/export-default-decorated-class/input.js deleted file mode 100644 index 80ba64f71a2a..000000000000 --- a/packages/babel-parser/test/fixtures/experimental/decorators/export-default-decorated-class/input.js +++ /dev/null @@ -1,2 +0,0 @@ -export default -@bar class Foo { } diff --git a/packages/babel-parser/test/fixtures/experimental/decorators/export-default-decorated-class/output.json b/packages/babel-parser/test/fixtures/experimental/decorators/export-default-decorated-class/output.json deleted file mode 100644 index 10a8536d840d..000000000000 --- a/packages/babel-parser/test/fixtures/experimental/decorators/export-default-decorated-class/output.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "type": "File", - "start":0,"end":34,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":2,"column":18,"index":34}}, - "program": { - "type": "Program", - "start":0,"end":34,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":2,"column":18,"index":34}}, - "sourceType": "module", - "interpreter": null, - "body": [ - { - "type": "ExportDefaultDeclaration", - "start":0,"end":34,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":2,"column":18,"index":34}}, - "declaration": { - "type": "ClassDeclaration", - "start":16,"end":34,"loc":{"start":{"line":2,"column":0,"index":16},"end":{"line":2,"column":18,"index":34}}, - "decorators": [ - { - "type": "Decorator", - "start":16,"end":20,"loc":{"start":{"line":2,"column":0,"index":16},"end":{"line":2,"column":4,"index":20}}, - "expression": { - "type": "Identifier", - "start":17,"end":20,"loc":{"start":{"line":2,"column":1,"index":17},"end":{"line":2,"column":4,"index":20},"identifierName":"bar"}, - "name": "bar" - } - } - ], - "id": { - "type": "Identifier", - "start":27,"end":30,"loc":{"start":{"line":2,"column":11,"index":27},"end":{"line":2,"column":14,"index":30},"identifierName":"Foo"}, - "name": "Foo" - }, - "superClass": null, - "body": { - "type": "ClassBody", - "start":31,"end":34,"loc":{"start":{"line":2,"column":15,"index":31},"end":{"line":2,"column":18,"index":34}}, - "body": [] - } - } - } - ], - "directives": [] - } -} diff --git a/packages/babel-plugin-proposal-decorators/src/index.ts b/packages/babel-plugin-proposal-decorators/src/index.ts index 0b21ac34fec3..5c91f5aa6ae5 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 transformer2022_03 from "./transformer-2022-03"; +import transformer2022_03 from "./transformer-2023-01"; import type { Options as SyntaxOptions } from "@babel/plugin-syntax-decorators"; interface Options extends SyntaxOptions { @@ -37,7 +37,11 @@ export default declare((api, options: Options) => { inherits: syntaxDecorators, visitor: legacyVisitor, }; - } else if (version === "2021-12" || version === "2022-03") { + } else if ( + version === "2021-12" || + version === "2022-03" || + version === "2023-01" + ) { return transformer2022_03(api, options, version); } else if (!process.env.BABEL_8_BREAKING) { api.assertVersion("^7.0.2"); @@ -51,7 +55,7 @@ export default declare((api, options: Options) => { }); } else { throw new Error( - "The '.version' option must be one of 'legacy', '2021-12' or '2022-03'.", + "The '.version' option must be one of 'legacy', '2021-12', '2022-03', or '2023-01'.", ); } }); diff --git a/packages/babel-plugin-proposal-decorators/src/transformer-2022-03.ts b/packages/babel-plugin-proposal-decorators/src/transformer-2023-01.ts similarity index 91% rename from packages/babel-plugin-proposal-decorators/src/transformer-2022-03.ts rename to packages/babel-plugin-proposal-decorators/src/transformer-2023-01.ts index 25660922f7be..38128a62362c 100644 --- a/packages/babel-plugin-proposal-decorators/src/transformer-2022-03.ts +++ b/packages/babel-plugin-proposal-decorators/src/transformer-2023-01.ts @@ -20,7 +20,7 @@ type ClassElement = | t.TSIndexSignature | t.StaticBlock; -type DecoratorVersionKind = "2022-03" | "2021-12"; +type DecoratorVersionKind = "2023-01" | "2022-03" | "2021-12"; function incrementId(id: number[], idx = id.length - 1): void { // If index is -1, id needs an additional character, unshift A @@ -231,30 +231,29 @@ function addProxyAccessorsFor( function extractProxyAccessorsFor( targetKey: t.PrivateName, -): t.FunctionExpression[] { + version: DecoratorVersionKind, +): (t.FunctionExpression | t.ArrowFunctionExpression)[] { + if (version !== "2023-01") { + return [ + template.expression.ast` + function () { + return this.${t.cloneNode(targetKey)}; + } + ` as t.FunctionExpression, + template.expression.ast` + function (value) { + this.${t.cloneNode(targetKey)} = value; + } + ` as t.FunctionExpression, + ]; + } return [ - t.functionExpression( - undefined, - [], - t.blockStatement([ - t.returnStatement( - t.memberExpression(t.thisExpression(), t.cloneNode(targetKey)), - ), - ]), - ), - t.functionExpression( - undefined, - [t.identifier("value")], - t.blockStatement([ - t.expressionStatement( - t.assignmentExpression( - "=", - t.memberExpression(t.thisExpression(), t.cloneNode(targetKey)), - t.identifier("value"), - ), - ), - ]), - ), + template.expression.ast` + o => o.${t.cloneNode(targetKey)} + ` as t.ArrowFunctionExpression, + template.expression.ast` + (o, v) => o.${t.cloneNode(targetKey)} = v + ` as t.ArrowFunctionExpression, ]; } @@ -299,7 +298,9 @@ interface DecoratorInfo { // The name of the decorator name: t.StringLiteral | t.Expression; - privateMethods: t.FunctionExpression | t.FunctionExpression[] | undefined; + privateMethods: + | (t.FunctionExpression | t.ArrowFunctionExpression)[] + | undefined; // The names of local variables that will be used/returned from the decoration locals: t.Identifier | t.Identifier[] | undefined; @@ -348,17 +349,12 @@ function generateDecorationExprs( const kind = el.isStatic ? el.kind + STATIC : el.kind; - const decInfo = [decs, t.numericLiteral(kind), el.name]; - - const { privateMethods } = el; - - if (Array.isArray(privateMethods)) { - decInfo.push(...privateMethods); - } else if (privateMethods) { - decInfo.push(privateMethods); - } - - return t.arrayExpression(decInfo); + return t.arrayExpression([ + decs, + t.numericLiteral(kind), + el.name, + ...(el.privateMethods || []), + ]); }), ); } @@ -572,6 +568,9 @@ function transformClass( classIdLocal = t.cloneNode(path.node.id); } + let lastInstancePrivateName: t.PrivateName; + let needsInstancePrivateBrandCheck = false; + if (hasElementDecorators) { for (const element of body) { if (!isClassDecoratableElementPath(element)) { @@ -617,13 +616,24 @@ function transformClass( name = key.name; } + if (isPrivate && !isStatic) { + if (hasDecorators) { + needsInstancePrivateBrandCheck = true; + } + if (t.isClassPrivateProperty(node) || !lastInstancePrivateName) { + lastInstancePrivateName = key; + } + } + if (element.isClassMethod({ kind: "constructor" })) { constructorPath = element; } if (hasDecorators) { let locals: t.Identifier | t.Identifier[]; - let privateMethods: t.FunctionExpression | t.FunctionExpression[]; + let privateMethods: Array< + t.FunctionExpression | t.ArrowFunctionExpression + >; if (kind === ACCESSOR) { const { value } = element.node as t.ClassAccessorProperty; @@ -646,7 +656,7 @@ function transformClass( const [newPath] = element.replaceWith(newField); if (isPrivate) { - privateMethods = extractProxyAccessorsFor(newId); + privateMethods = extractProxyAccessorsFor(newId, version); const getId = newPath.scope.parent.generateDeclaredUidIdentifier( `get_${name}`, @@ -680,7 +690,7 @@ function transformClass( locals = initId; if (isPrivate) { - privateMethods = extractProxyAccessorsFor(key); + privateMethods = extractProxyAccessorsFor(key, version); } } else if (isPrivate) { locals = element.scope.parent.generateDeclaredUidIdentifier( @@ -704,12 +714,14 @@ function transformClass( async: isAsync, } = element.node as t.ClassPrivateMethod; - privateMethods = t.functionExpression( - undefined, - params.filter(isNotTsParameter), - body, - isAsync, - ); + privateMethods = [ + t.functionExpression( + undefined, + params.filter(isNotTsParameter), + body, + isAsync, + ), + ]; if (kind === GETTER || kind === SETTER) { movePrivateAccessor( @@ -992,6 +1004,7 @@ function transformClass( classLocals, elementDecorations, classDecorations, + needsInstancePrivateBrandCheck ? lastInstancePrivateName : null, state, version, ), @@ -1021,10 +1034,16 @@ function createLocalsAssignment( classLocals: t.Identifier[], elementDecorations: t.ArrayExpression, classDecorations: t.ArrayExpression, + maybePrivateBranName: t.PrivateName | null, state: PluginPass, version: DecoratorVersionKind, ) { let lhs, rhs; + const args: t.Expression[] = [ + t.thisExpression(), + elementDecorations, + classDecorations, + ]; // TODO(Babel 8): Only keep the else branch if ( version === "2021-12" || @@ -1033,14 +1052,22 @@ function createLocalsAssignment( lhs = t.arrayPattern([...elementLocals, ...classLocals]); rhs = t.callExpression( state.addHelper(version === "2021-12" ? "applyDecs" : "applyDecs2203"), - [t.thisExpression(), elementDecorations, classDecorations], + args, ); } else { - rhs = t.callExpression(state.addHelper("applyDecs2203R"), [ - t.thisExpression(), - elementDecorations, - classDecorations, - ]); + // TODO(Babel 8): Only keep the if branch + if (version === "2023-01") { + if (maybePrivateBranName) { + args.push( + template.expression.ast` + _ => ${t.cloneNode(maybePrivateBranName)} in _ + ` as t.ArrowFunctionExpression, + ); + } + rhs = t.callExpression(state.addHelper("applyDecs2301"), args); + } else { + rhs = t.callExpression(state.addHelper("applyDecs2203R"), args); + } // optimize `{ c: [classLocals] } = applyapplyDecs2203R(...)` to // `[classLocals] = applyapplyDecs2203R(...).c` if (elementLocals.length > 0) { @@ -1065,9 +1092,15 @@ function createLocalsAssignment( export default function ( { assertVersion, assumption }: PluginAPI, { loose }: Options, - version: "2022-03" | "2021-12", + version: "2023-01" | "2022-03" | "2021-12", ): PluginObject { - assertVersion(version === "2021-12" ? "^7.16.0" : "^7.19.0"); + if (version === "2023-01") { + assertVersion("^7.20.0"); + } else if (version === "2021-12") { + assertVersion("^7.16.0"); + } else { + assertVersion("^7.19.0"); + } const VISITED = new WeakSet(); const constantSuper = assumption("constantSuper") ?? loose; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/private/exec.js new file mode 100644 index 000000000000..3b8e879c54b8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/private/exec.js @@ -0,0 +1,56 @@ +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.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(false); + +expect(aContext.access.get(foo)).toBe(2); +expect(() => aContext.access.get({})).toThrow(TypeError); +aContext.access.set(foo, 123); +expect(aContext.access.get(foo)).toBe(125); +expect(() => aContext.access.set({}, 456)).toThrow(TypeError); +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(foo)).toBe(124); +bContext.access.set(foo, 123); +expect(bContext.access.get(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/2023-01-accessors--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/private/input.js new file mode 100644 index 000000000000..aa152db91d94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/private/output.js new file mode 100644 index 000000000000..1a790e85d83b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/private/output.js @@ -0,0 +1,39 @@ +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.applyDecs2301(Foo, [[dec, 1, "a", o => babelHelpers.classPrivateFieldGet(o, _A), (o, v) => babelHelpers.classPrivateFieldSet(o, _A, v)], [dec, 1, "b", o => babelHelpers.classPrivateFieldGet(o, _B), (o, v) => babelHelpers.classPrivateFieldSet(o, _B, v)]], [], _ => _a.has(babelHelpers.checkInRHS(_))).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/public/exec.js new file mode 100644 index 000000000000..834c6deaecfe --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/public/exec.js @@ -0,0 +1,80 @@ +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(aContext.access.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(foo.a).toBe(2); +expect(aContext.access.get(foo)).toBe(2); +foo.a = 123; +expect(foo.a).toBe(125); +expect(aContext.access.get(foo)).toBe(125); +aContext.access.set(foo, 456); +expect(foo.a).toBe(458); +expect(aContext.access.get(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/2023-01-accessors--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/public/input.js new file mode 100644 index 000000000000..bd8be5cbe225 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/public/output.js new file mode 100644 index 000000000000..d685cdf23bcf --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/public/output.js @@ -0,0 +1,41 @@ +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.applyDecs2301(Foo, [[dec, 1, "a"], [dec, 1, "b"], [dec, 1, _computedKey]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..14008e61c117 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-private/exec.js @@ -0,0 +1,55 @@ +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.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(false); + +expect(aContext.access.get(Foo)).toBe(2); +expect(() => aContext.access.get({})).toThrow(TypeError); +aContext.access.set(Foo, 123); +expect(aContext.access.get(Foo)).toBe(125); +expect(() => aContext.access.set({}, 456)).toThrow(TypeError); +expect(aContext.access.get(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(Foo)).toBe(124); +bContext.access.set(Foo, 123); +expect(bContext.access.get(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/2023-01-accessors--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-private/input.js new file mode 100644 index 000000000000..c30e61d463bc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-private/output.js new file mode 100644 index 000000000000..4d6a6173b157 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-private/output.js @@ -0,0 +1,40 @@ +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.applyDecs2301(Foo, [[dec, 6, "a", o => babelHelpers.classStaticPrivateFieldSpecGet(o, Foo, _A), (o, v) => babelHelpers.classStaticPrivateFieldSpecSet(o, Foo, _A, v)], [dec, 6, "b", o => babelHelpers.classStaticPrivateFieldSpecGet(o, Foo, _B), (o, v) => babelHelpers.classStaticPrivateFieldSpecSet(o, Foo, _B, v)]], []).e; + _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/2023-01-accessors--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..402618d18490 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-public/exec.js @@ -0,0 +1,75 @@ +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(aContext.access.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(Foo.a).toBe(2); +expect(aContext.access.get(Foo)).toBe(2); +Foo.a = 123; +expect(Foo.a).toBe(125); +expect(aContext.access.get(Foo)).toBe(125); +aContext.access.set(Foo, 456); +expect(Foo.a).toBe(458); +expect(aContext.access.get(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/2023-01-accessors--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-public/input.js new file mode 100644 index 000000000000..50f05c065848 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-public/output.js new file mode 100644 index 000000000000..8997d41cffa4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/static-public/output.js @@ -0,0 +1,39 @@ +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.applyDecs2301(Foo, [[dec, 6, "a"], [dec, 6, "b"], [dec, 6, _computedKey]], []).e; + _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/2023-01-accessors--to-es2015/undecorated-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-private/exec.js new file mode 100644 index 000000000000..51715be9f173 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors--to-es2015/undecorated-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-private/input.js new file mode 100644 index 000000000000..07804cb8a125 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors--to-es2015/undecorated-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-private/output.js new file mode 100644 index 000000000000..84ce390b7799 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-private/output.js @@ -0,0 +1,37 @@ +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/2023-01-accessors--to-es2015/undecorated-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-public/exec.js new file mode 100644 index 000000000000..5ccd5dcce44d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors--to-es2015/undecorated-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-public/input.js new file mode 100644 index 000000000000..62dbd0c0381a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors--to-es2015/undecorated-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-public/output.js new file mode 100644 index 000000000000..070b4006e2e9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-public/output.js @@ -0,0 +1,38 @@ +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/2023-01-accessors--to-es2015/undecorated-static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-accessors--to-es2015/undecorated-static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-accessors--to-es2015/undecorated-static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-static-private/output.js new file mode 100644 index 000000000000..ab3a0e1b2678 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-static-private/output.js @@ -0,0 +1,30 @@ +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/2023-01-accessors--to-es2015/undecorated-static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-accessors--to-es2015/undecorated-static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-accessors--to-es2015/undecorated-static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-static-public/output.js new file mode 100644 index 000000000000..5041e9a95d6e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors--to-es2015/undecorated-static-public/output.js @@ -0,0 +1,33 @@ +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/2023-01-accessors/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/private/input.js new file mode 100644 index 000000000000..aa152db91d94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/private/output.js new file mode 100644 index 000000000000..49c48efe62e0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/private/output.js @@ -0,0 +1,21 @@ +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.applyDecs2301(this, [[dec, 1, "a", o => o.#A, (o, v) => o.#A = v], [dec, 1, "b", o => o.#B, (o, v) => o.#B = v]], [], _ => #a in _).e; + } + #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/2023-01-accessors/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/public/input.js new file mode 100644 index 000000000000..bd8be5cbe225 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/public/output.js new file mode 100644 index 000000000000..149f45430bd5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/public/output.js @@ -0,0 +1,29 @@ +var _init_a, _init_b, _computedKey, _init_computedKey, _initProto; +const dec = () => {}; +_computedKey = 'c'; +class Foo { + static { + [_init_a, _init_b, _init_computedKey, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 1, "a"], [dec, 1, "b"], [dec, 1, _computedKey]], []).e; + } + #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/2023-01-accessors/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/static-private/input.js new file mode 100644 index 000000000000..c30e61d463bc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/static-private/output.js new file mode 100644 index 000000000000..ba21a2e3649e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/static-private/output.js @@ -0,0 +1,22 @@ +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.applyDecs2301(this, [[dec, 6, "a", o => o.#A, (o, v) => o.#A = v], [dec, 6, "b", o => o.#B, (o, v) => o.#B = v]], []).e; + _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/2023-01-accessors/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/static-public/input.js new file mode 100644 index 000000000000..50f05c065848 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/static-public/output.js new file mode 100644 index 000000000000..2642e4cd8958 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/static-public/output.js @@ -0,0 +1,30 @@ +var _init_a, _init_b, _computedKey, _init_computedKey, _initStatic; +const dec = () => {}; +_computedKey = 'c'; +class Foo { + static { + [_init_a, _init_b, _init_computedKey, _initStatic] = babelHelpers.applyDecs2301(this, [[dec, 6, "a"], [dec, 6, "b"], [dec, 6, _computedKey]], []).e; + _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/2023-01-accessors/undecorated-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-private/input.js new file mode 100644 index 000000000000..07804cb8a125 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors/undecorated-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-private/output.js new file mode 100644 index 000000000000..50efd9ecf14f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-private/output.js @@ -0,0 +1,17 @@ +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/2023-01-accessors/undecorated-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-public/input.js new file mode 100644 index 000000000000..62dbd0c0381a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors/undecorated-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-public/output.js new file mode 100644 index 000000000000..0082fd52b442 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-public/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; + } + #C = 456; + get ['c']() { + return this.#C; + } + set ['c'](v) { + this.#C = v; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-static-private/input.js new file mode 100644 index 000000000000..9e893b86b863 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors/undecorated-static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-static-private/output.js new file mode 100644 index 000000000000..9268d8a99d07 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-static-private/output.js @@ -0,0 +1,17 @@ +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/2023-01-accessors/undecorated-static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-static-public/input.js new file mode 100644 index 000000000000..eb7463cb9fc1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-accessors/undecorated-static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-static-public/output.js new file mode 100644 index 000000000000..32b5ee6911b8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-accessors/undecorated-static-public/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; + } + 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/2023-01-assumption-constantSuper/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/options.json new file mode 100644 index 000000000000..fe71b45cf3bb --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/options.json @@ -0,0 +1,6 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]], + "assumptions": { + "constantSuper": true + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-nested-constructor-expression/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-assumption-constantSuper/super-in-nested-constructor-expression/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-nested-constructor-expression/output.js new file mode 100644 index 000000000000..eb1b5daf423b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-nested-constructor-expression/output.js @@ -0,0 +1,14 @@ +var _initClass; +const dec = () => {}; +let _Foo; +class Foo extends Bar { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + constructor() { + let foo = super(); + } + static { + _initClass(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-private-accessor/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-assumption-constantSuper/super-in-private-accessor/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-private-accessor/output.js new file mode 100644 index 000000000000..d05b26d27f5a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-private-accessor/output.js @@ -0,0 +1,16 @@ +var _call_x, _initProto; +const dec = () => {}; +class Foo extends Bar { + static { + [_call_x, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 3, "x", function () { + return Bar.prototype.foo.call(this); + }]], [], _ => #x in _).e; + } + constructor(...args) { + super(...args); + _initProto(this); + } + get #x() { + return _call_x(this); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-private-method/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-assumption-constantSuper/super-in-private-method/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-private-method/output.js new file mode 100644 index 000000000000..29b0c3f17885 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-assumption-constantSuper/super-in-private-method/output.js @@ -0,0 +1,14 @@ +var _call_x, _initProto; +const dec = () => {}; +class Foo extends Bar { + static { + [_call_x, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, "x", function () { + return Bar.prototype.foo.call(this); + }]], [], _ => #x in _).e; + } + constructor(...args) { + super(...args); + _initProto(this); + } + #x = _call_x; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/exec.js new file mode 100644 index 000000000000..9d5c4bbf3d15 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/exec.js @@ -0,0 +1,14 @@ +var value; +const classDec = (Class) => { + value = (new Class).m; + return Class +}; + +const memberDec = () => () => 42; + +@classDec +class C { + @memberDec m; +} + +expect(value).toBe(42); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/input.js new file mode 100644 index 000000000000..8689cf13f9e5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/input.js @@ -0,0 +1,12 @@ +var value; +const classDec = (Class) => { + value = (new Class).p; + return Class +}; + +const memberDec = () => () => 42; + +@classDec +class C { + @memberDec m; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/output.js new file mode 100644 index 000000000000..8214f837e24f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-fields/output.js @@ -0,0 +1,18 @@ +var _initClass, _init_m; +var value; +const classDec = Class => { + value = new Class().p; + return Class; +}; +const memberDec = () => () => 42; +let _C; +class C { + constructor() { + babelHelpers.defineProperty(this, "m", _init_m(this)); + } +} +({ + e: [_init_m], + c: [_C, _initClass] +} = babelHelpers.applyDecs2301(C, [[memberDec, 0, "m"]], [classDec])); +_initClass(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/exec.js new file mode 100644 index 000000000000..a85569beafbc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/exec.js @@ -0,0 +1,14 @@ +var value; +const classDec = (Class) => { + value = (new Class).m(); + return Class +}; + +const memberDec = () => () => 42; + +@classDec +class C { + @memberDec m() {}; +} + +expect(value).toBe(42); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/input.js new file mode 100644 index 000000000000..7d8094583001 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/input.js @@ -0,0 +1,12 @@ +var value; +const classDec = (Class) => { + value = (new Class).m(); + return Class +}; + +const memberDec = () => () => 42; + +@classDec +class C { + @memberDec m() {}; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/output.js new file mode 100644 index 000000000000..c8de3426e3aa --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/decorator-access-modified-methods/output.js @@ -0,0 +1,19 @@ +var _initClass, _initProto; +var value; +const classDec = Class => { + value = new Class().m(); + return Class; +}; +const memberDec = () => () => 42; +let _C; +class C { + constructor(...args) { + _initProto(this); + } + m() {} +} +({ + e: [_initProto], + c: [_C, _initClass] +} = babelHelpers.applyDecs2301(C, [[memberDec, 2, "m"]], [classDec])); +_initClass(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions-static-blocks/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions-static-blocks/input.js new file mode 100644 index 000000000000..853ac0e6a43b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions-static-blocks/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +const A = @dec class A { static {} } +const B = @dec class C { static {} } +const D = @dec class { static {} } +const E = (@dec class { static {} }, 123); +const F = [@dec class G { static {} }, @dec class { static {} }]; +const H = @dec class extends I { static {} }; +const J = @dec class K extends L { static {} }; + +function classFactory() { + return @dec class { static {} } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions-static-blocks/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions-static-blocks/output.js new file mode 100644 index 000000000000..e157affdb977 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions-static-blocks/output.js @@ -0,0 +1,67 @@ +var _initClass, _A, _temp, _initClass2, _C, _temp2, _initClass3, _D, _temp3, _initClass4, _decorated_class, _temp4, _class2, _initClass5, _G, _temp5, _initClass6, _decorated_class2, _temp6, _class3, _initClass7, _H, _temp7, _initClass8, _K, _temp8; +const dec = () => {}; +const A = (new (_temp = class extends babelHelpers.identity { + constructor() { + super(_A), (() => {})(), _initClass(); + } +}, (() => { + class A {} + [_A, _initClass] = babelHelpers.applyDecs2301(A, [], [dec]).c; +})(), _temp)(), _A); +const B = (new (_temp2 = class extends babelHelpers.identity { + constructor() { + super(_C), (() => {})(), _initClass2(); + } +}, (() => { + class C {} + [_C, _initClass2] = babelHelpers.applyDecs2301(C, [], [dec]).c; +})(), _temp2)(), _C); +const D = (new (_temp3 = class extends babelHelpers.identity { + constructor() { + super(_D), (() => {})(), _initClass3(); + } +}, (() => { + class D {} + [_D, _initClass3] = babelHelpers.applyDecs2301(D, [], [dec]).c; +})(), _temp3)(), _D); +const E = ((new (_temp4 = class extends babelHelpers.identity { + constructor() { + super(_decorated_class), (() => {})(), _initClass4(); + } +}, (_class2 = class {}, [_decorated_class, _initClass4] = babelHelpers.applyDecs2301(_class2, [], [dec]).c), _temp4)(), _decorated_class), 123); +const F = [(new (_temp5 = class extends babelHelpers.identity { + constructor() { + super(_G), (() => {})(), _initClass5(); + } +}, (() => { + class G {} + [_G, _initClass5] = babelHelpers.applyDecs2301(G, [], [dec]).c; +})(), _temp5)(), _G), (new (_temp6 = class extends babelHelpers.identity { + constructor() { + super(_decorated_class2), (() => {})(), _initClass6(); + } +}, (_class3 = class {}, [_decorated_class2, _initClass6] = babelHelpers.applyDecs2301(_class3, [], [dec]).c), _temp6)(), _decorated_class2)]; +const H = (new (_temp7 = class extends babelHelpers.identity { + constructor() { + super(_H), (() => {})(), _initClass7(); + } +}, (() => { + class H extends I {} + [_H, _initClass7] = babelHelpers.applyDecs2301(H, [], [dec]).c; +})(), _temp7)(), _H); +const J = (new (_temp8 = class extends babelHelpers.identity { + constructor() { + super(_K), (() => {})(), _initClass8(); + } +}, (() => { + class K extends L {} + [_K, _initClass8] = babelHelpers.applyDecs2301(K, [], [dec]).c; +})(), _temp8)(), _K); +function classFactory() { + var _initClass9, _decorated_class3, _temp9, _class5; + return new (_temp9 = class extends babelHelpers.identity { + constructor() { + super(_decorated_class3), (() => {})(), _initClass9(); + } + }, (_class5 = class {}, [_decorated_class3, _initClass9] = babelHelpers.applyDecs2301(_class5, [], [dec]).c), _temp9)(), _decorated_class3; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions/input.js new file mode 100644 index 000000000000..77060bea50ff --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes--to-es2015/expressions/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions/output.js new file mode 100644 index 000000000000..1549614786a8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/expressions/output.js @@ -0,0 +1,13 @@ +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.applyDecs2301(_class, [], [dec]).c, _initClass()), _A); +const B = ((_class2 = class C {}, [_C, _initClass2] = babelHelpers.applyDecs2301(_class2, [], [dec]).c, _initClass2()), _C); +const D = ((_class3 = class D {}, [_D, _initClass3] = babelHelpers.applyDecs2301(_class3, [], [dec]).c, _initClass3()), _D); +const E = (((_class4 = class {}, [_decorated_class, _initClass4] = babelHelpers.applyDecs2301(_class4, [], [dec]).c, _initClass4()), _decorated_class), 123); +const F = [((_class5 = class G {}, [_G, _initClass5] = babelHelpers.applyDecs2301(_class5, [], [dec]).c, _initClass5()), _G), ((_class6 = class {}, [_decorated_class2, _initClass6] = babelHelpers.applyDecs2301(_class6, [], [dec]).c, _initClass6()), _decorated_class2)]; +const H = ((_class7 = class H extends I {}, [_H, _initClass7] = babelHelpers.applyDecs2301(_class7, [], [dec]).c, _initClass7()), _H); +const J = ((_class8 = class K extends L {}, [_K, _initClass8] = babelHelpers.applyDecs2301(_class8, [], [dec]).c, _initClass8()), _K); +function classFactory() { + var _initClass9, _decorated_class3, _class9; + return (_class9 = class {}, [_decorated_class3, _initClass9] = babelHelpers.applyDecs2301(_class9, [], [dec]).c, _initClass9()), _decorated_class3; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/inheritance/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/inheritance/exec.js new file mode 100644 index 000000000000..889e8c102cf4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes--to-es2015/inheritance/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/inheritance/input.js new file mode 100644 index 000000000000..96a13523506c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes--to-es2015/inheritance/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/inheritance/output.js new file mode 100644 index 000000000000..e0134f55a6ec --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/inheritance/output.js @@ -0,0 +1,11 @@ +var _initClass, _initClass2; +const dec1 = () => {}; +const dec2 = () => {}; +let _Bar; +class Bar {} +[_Bar, _initClass] = babelHelpers.applyDecs2301(Bar, [], [dec1]).c; +_initClass(); +let _Foo; +class Foo extends _Bar {} +[_Foo, _initClass2] = babelHelpers.applyDecs2301(Foo, [], [dec2]).c; +_initClass2(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/initializers/exec.js new file mode 100644 index 000000000000..aefc3ba5b88c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes--to-es2015/initializers/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/initializers/input.js new file mode 100644 index 000000000000..87c785d39a93 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes--to-es2015/initializers/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/initializers/output.js new file mode 100644 index 000000000000..eb1f5f3e2915 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/initializers/output.js @@ -0,0 +1,22 @@ +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.applyDecs2301(Foo, [], [dec]).c; +})(), _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.applyDecs2301(Bar, [], [dec]).c; +})(), _temp2)(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-static-installed-on-correct-class/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-classes--to-es2015/replacement-static-installed-on-correct-class/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-classes--to-es2015/replacement-static-installed-on-correct-class/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-static-installed-on-correct-class/output.js new file mode 100644 index 000000000000..085cb13bfe75 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-static-installed-on-correct-class/output.js @@ -0,0 +1,21 @@ +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(babelHelpers.checkInRHS(o)); + hasM = o => _m.has(babelHelpers.checkInRHS(o)); + })(), _initClass(); + } +}, (() => { + class Foo { + static m() {} + } + [_Foo, _initClass] = babelHelpers.applyDecs2301(Foo, [], [dec]).c; +})(), _temp))(); +function _m2() {} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-static-this/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-classes--to-es2015/replacement-static-this/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-classes--to-es2015/replacement-static-this/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-static-this/output.js new file mode 100644 index 000000000000..3902eb6f083b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-static-this/output.js @@ -0,0 +1,15 @@ +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.applyDecs2301(Foo, [], [dec]).c; +})(), _temp)(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-with-expr/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-classes--to-es2015/replacement-with-expr/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-classes--to-es2015/replacement-with-expr/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-with-expr/output.js new file mode 100644 index 000000000000..4554f9e5d0be --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement-with-expr/output.js @@ -0,0 +1,8 @@ +var _initClass, _Bar, _class; +const dec = () => {}; +const Foo = ((_class = class Bar { + constructor() { + babelHelpers.defineProperty(this, "bar", new _Bar()); + } +}, [_Bar, _initClass] = babelHelpers.applyDecs2301(_class, [], [dec]).c, _initClass()), _Bar); +const foo = new Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement/exec.js new file mode 100644 index 000000000000..c8dc49c0d85e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes--to-es2015/replacement/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement/input.js new file mode 100644 index 000000000000..8f0a4dfe092f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes--to-es2015/replacement/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement/output.js new file mode 100644 index 000000000000..b3913e89cdcf --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes--to-es2015/replacement/output.js @@ -0,0 +1,12 @@ +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.applyDecs2301(Foo, [], [dec]).c; +})(), _temp)(); +const foo = new _Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/exec.js new file mode 100644 index 000000000000..9d5c4bbf3d15 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/exec.js @@ -0,0 +1,14 @@ +var value; +const classDec = (Class) => { + value = (new Class).m; + return Class +}; + +const memberDec = () => () => 42; + +@classDec +class C { + @memberDec m; +} + +expect(value).toBe(42); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/input.js new file mode 100644 index 000000000000..8689cf13f9e5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/input.js @@ -0,0 +1,12 @@ +var value; +const classDec = (Class) => { + value = (new Class).p; + return Class +}; + +const memberDec = () => () => 42; + +@classDec +class C { + @memberDec m; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/options.json new file mode 100644 index 000000000000..f97653393918 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/options.json @@ -0,0 +1,3 @@ +{ + "minNodeVersion": "16.11.0" +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/output.js new file mode 100644 index 000000000000..dc983990beaf --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-fields/output.js @@ -0,0 +1,20 @@ +var _initClass, _init_m; +var value; +const classDec = Class => { + value = new Class().p; + return Class; +}; +const memberDec = () => () => 42; +let _C; +class C { + static { + ({ + e: [_init_m], + c: [_C, _initClass] + } = babelHelpers.applyDecs2301(this, [[memberDec, 0, "m"]], [classDec])); + } + m = _init_m(this); + static { + _initClass(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/exec.js new file mode 100644 index 000000000000..a85569beafbc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/exec.js @@ -0,0 +1,14 @@ +var value; +const classDec = (Class) => { + value = (new Class).m(); + return Class +}; + +const memberDec = () => () => 42; + +@classDec +class C { + @memberDec m() {}; +} + +expect(value).toBe(42); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/input.js new file mode 100644 index 000000000000..7d8094583001 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/input.js @@ -0,0 +1,12 @@ +var value; +const classDec = (Class) => { + value = (new Class).m(); + return Class +}; + +const memberDec = () => () => 42; + +@classDec +class C { + @memberDec m() {}; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/options.json new file mode 100644 index 000000000000..f97653393918 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/options.json @@ -0,0 +1,3 @@ +{ + "minNodeVersion": "16.11.0" +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/output.js new file mode 100644 index 000000000000..6fc59bb2e887 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/decorator-access-modified-methods/output.js @@ -0,0 +1,23 @@ +var _initClass, _initProto; +var value; +const classDec = Class => { + value = new Class().m(); + return Class; +}; +const memberDec = () => () => 42; +let _C; +class C { + static { + ({ + e: [_initProto], + c: [_C, _initClass] + } = babelHelpers.applyDecs2301(this, [[memberDec, 2, "m"]], [classDec])); + } + constructor(...args) { + _initProto(this); + } + m() {} + static { + _initClass(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions-static-blocks/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions-static-blocks/input.js new file mode 100644 index 000000000000..853ac0e6a43b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions-static-blocks/input.js @@ -0,0 +1,12 @@ +const dec = () => {}; +const A = @dec class A { static {} } +const B = @dec class C { static {} } +const D = @dec class { static {} } +const E = (@dec class { static {} }, 123); +const F = [@dec class G { static {} }, @dec class { static {} }]; +const H = @dec class extends I { static {} }; +const J = @dec class K extends L { static {} }; + +function classFactory() { + return @dec class { static {} } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions-static-blocks/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions-static-blocks/output.js new file mode 100644 index 000000000000..0eaacf73aea2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions-static-blocks/output.js @@ -0,0 +1,112 @@ +var _initClass, _A, _initClass2, _C, _initClass3, _D, _initClass4, _decorated_class, _initClass5, _G, _initClass6, _decorated_class2, _initClass7, _H, _initClass8, _K; +const dec = () => {}; +const A = (new class extends babelHelpers.identity { + static { + class A { + static { + [_A, _initClass] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + constructor() { + super(_A), (() => {})(), _initClass(); + } +}(), _A); +const B = (new class extends babelHelpers.identity { + static { + class C { + static { + [_C, _initClass2] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + constructor() { + super(_C), (() => {})(), _initClass2(); + } +}(), _C); +const D = (new class extends babelHelpers.identity { + static { + class D { + static { + [_D, _initClass3] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + constructor() { + super(_D), (() => {})(), _initClass3(); + } +}(), _D); +const E = ((new class extends babelHelpers.identity { + static { + (class { + static { + [_decorated_class, _initClass4] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + }); + } + constructor() { + super(_decorated_class), (() => {})(), _initClass4(); + } +}(), _decorated_class), 123); +const F = [(new class extends babelHelpers.identity { + static { + class G { + static { + [_G, _initClass5] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + constructor() { + super(_G), (() => {})(), _initClass5(); + } +}(), _G), (new class extends babelHelpers.identity { + static { + (class { + static { + [_decorated_class2, _initClass6] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + }); + } + constructor() { + super(_decorated_class2), (() => {})(), _initClass6(); + } +}(), _decorated_class2)]; +const H = (new class extends babelHelpers.identity { + static { + class H extends I { + static { + [_H, _initClass7] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + constructor() { + super(_H), (() => {})(), _initClass7(); + } +}(), _H); +const J = (new class extends babelHelpers.identity { + static { + class K extends L { + static { + [_K, _initClass8] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + constructor() { + super(_K), (() => {})(), _initClass8(); + } +}(), _K); +function classFactory() { + var _initClass9, _decorated_class3; + return new class extends babelHelpers.identity { + static { + (class { + static { + [_decorated_class3, _initClass9] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + }); + } + constructor() { + super(_decorated_class3), (() => {})(), _initClass9(); + } + }(), _decorated_class3; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions/input.js new file mode 100644 index 000000000000..77060bea50ff --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes/expressions/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions/output.js new file mode 100644 index 000000000000..888927c0d164 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/expressions/output.js @@ -0,0 +1,76 @@ +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.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass(); + } +}, _A); +const B = (class C { + static { + [_C, _initClass2] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass2(); + } +}, _C); +const D = (class D { + static { + [_D, _initClass3] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass3(); + } +}, _D); +const E = ((class { + static { + [_decorated_class, _initClass4] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass4(); + } +}, _decorated_class), 123); +const F = [(class G { + static { + [_G, _initClass5] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass5(); + } +}, _G), (class { + static { + [_decorated_class2, _initClass6] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass6(); + } +}, _decorated_class2)]; +const H = (class H extends I { + static { + [_H, _initClass7] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass7(); + } +}, _H); +const J = (class K extends L { + static { + [_K, _initClass8] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass8(); + } +}, _K); +function classFactory() { + var _initClass9, _decorated_class3; + return class { + static { + [_decorated_class3, _initClass9] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + static { + _initClass9(); + } + }, _decorated_class3; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/inheritance/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/inheritance/input.js new file mode 100644 index 000000000000..0657f6e2b364 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes/inheritance/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/inheritance/output.js new file mode 100644 index 000000000000..51ccb5dd0487 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/inheritance/output.js @@ -0,0 +1,22 @@ +var _initClass, _dec, _initClass2, _dec2; +const dec = () => {}; +let _Bar; +_dec = dec1; +class Bar { + static { + [_Bar, _initClass] = babelHelpers.applyDecs2301(this, [], [_dec]).c; + } + static { + _initClass(); + } +} +let _Foo; +_dec2 = dec2; +class Foo extends _Bar { + static { + [_Foo, _initClass2] = babelHelpers.applyDecs2301(this, [], [_dec2]).c; + } + static { + _initClass2(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/initializers/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/initializers/input.js new file mode 100644 index 000000000000..87c785d39a93 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes/initializers/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/initializers/output.js new file mode 100644 index 000000000000..c1faba79db32 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/initializers/output.js @@ -0,0 +1,32 @@ +var _initClass, _initClass2; +const dec = () => {}; +let _Foo; +new class extends babelHelpers.identity { + static { + class Foo { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + field = 123; + constructor() { + super(_Foo), _initClass(); + } +}(); +let _Bar; +new class extends babelHelpers.identity { + static { + class Bar extends _Foo { + static { + [_Bar, _initClass2] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + field = ((() => { + this.otherField = 456; + })(), 123); + constructor() { + super(_Bar), _initClass2(); + } +}(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-static-installed-on-correct-class/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-classes/replacement-static-installed-on-correct-class/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-static-installed-on-correct-class/output.js new file mode 100644 index 000000000000..f03a66e5858c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-static-installed-on-correct-class/output.js @@ -0,0 +1,23 @@ +var _initClass; +const dec = () => {}; +let hasX, hasM; +let _Foo; +new class extends babelHelpers.identity { + static { + class Foo { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + 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/2023-01-classes/replacement-static-this/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-static-this/input.js new file mode 100644 index 000000000000..1b8d46cf3ac0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes/replacement-static-this/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-static-this/output.js new file mode 100644 index 000000000000..f92f9c39a1b9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-static-this/output.js @@ -0,0 +1,20 @@ +var _initClass; +const dec = () => {}; +let _Foo; +new class extends babelHelpers.identity { + static { + class Foo { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + field = ((() => { + this; + })(), this); + constructor() { + super(_Foo), (() => { + this; + })(), _initClass(); + } +}(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-with-expr/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-with-expr/input.js new file mode 100644 index 000000000000..0cd5e45110b7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes/replacement-with-expr/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-with-expr/output.js new file mode 100644 index 000000000000..d11cd576836b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement-with-expr/output.js @@ -0,0 +1,12 @@ +var _initClass, _Bar; +const dec = () => {}; +const Foo = (class Bar { + static { + [_Bar, _initClass] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + bar = new _Bar(); + static { + _initClass(); + } +}, _Bar); +const foo = new Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement/input.js new file mode 100644 index 000000000000..8f0a4dfe092f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-classes/replacement/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement/output.js new file mode 100644 index 000000000000..07f11fb76c4f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-classes/replacement/output.js @@ -0,0 +1,17 @@ +var _initClass; +const dec = () => {}; +let _Foo; +new class extends babelHelpers.identity { + static { + class Foo { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + } + } + foo = new _Foo(); + constructor() { + super(_Foo), _initClass(); + } +}(); +const foo = new _Foo(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/computed-keys-same-ast/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys--to-es2015/computed-keys-same-ast/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys--to-es2015/computed-keys-same-ast/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/computed-keys-same-ast/output.js new file mode 100644 index 000000000000..8bb518437ebf --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/computed-keys-same-ast/output.js @@ -0,0 +1,16 @@ +var _computedKey, _computedKey2, _initProto; +const dec = () => {}; +_computedKey = getKey(); +_computedKey2 = getKey(); +class Foo { + constructor(...args) { + _initProto(this); + } + [_computedKey]() { + return 1; + } + [_computedKey2]() { + return 2; + } +} +[_initProto] = babelHelpers.applyDecs2301(Foo, [[dec, 2, _computedKey], [dec, 2, _computedKey2]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/computed-keys-same-value/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys--to-es2015/computed-keys-same-value/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys--to-es2015/computed-keys-same-value/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/computed-keys-same-value/output.js new file mode 100644 index 000000000000..a78f39229e61 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/computed-keys-same-value/output.js @@ -0,0 +1,16 @@ +var _computedKey, _computedKey2, _initProto; +const dec = () => {}; +_computedKey = getKeyI(); +_computedKey2 = getKeyJ(); +class Foo { + constructor(...args) { + _initProto(this); + } + [_computedKey]() { + return 1; + } + [_computedKey2]() { + return 2; + } +} +[_initProto] = babelHelpers.applyDecs2301(Foo, [[dec, 2, _computedKey], [dec, 2, _computedKey2]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/method-and-field/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys--to-es2015/method-and-field/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys--to-es2015/method-and-field/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/method-and-field/output.js new file mode 100644 index 000000000000..c6e50e06cdf2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/method-and-field/output.js @@ -0,0 +1,11 @@ +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.applyDecs2301(Foo, [[dec, 2, "a"], [dec, 0, "a"]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/methods-with-same-key/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys--to-es2015/methods-with-same-key/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys--to-es2015/methods-with-same-key/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/methods-with-same-key/output.js new file mode 100644 index 000000000000..614b5f44db48 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/methods-with-same-key/output.js @@ -0,0 +1,14 @@ +var _initProto; +const dec = () => {}; +class Foo { + constructor(...args) { + _initProto(this); + } + a() { + return 1; + } + a() { + return 2; + } +} +[_initProto] = babelHelpers.applyDecs2301(Foo, [[dec, 2, "a"], [dec, 2, "a"]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/computed-keys-same-ast/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys/computed-keys-same-ast/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/computed-keys-same-ast/output.js new file mode 100644 index 000000000000..7ad035287be2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/computed-keys-same-ast/output.js @@ -0,0 +1,18 @@ +var _computedKey, _computedKey2, _initProto; +const dec = () => {}; +_computedKey = getKey(); +_computedKey2 = getKey(); +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, _computedKey], [dec, 2, _computedKey2]], []).e; + } + constructor(...args) { + _initProto(this); + } + [_computedKey]() { + return 1; + } + [_computedKey2]() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/computed-keys-same-value/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys/computed-keys-same-value/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/computed-keys-same-value/output.js new file mode 100644 index 000000000000..02fa21ce8c87 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/computed-keys-same-value/output.js @@ -0,0 +1,18 @@ +var _computedKey, _computedKey2, _initProto; +const dec = () => {}; +_computedKey = getKeyI(); +_computedKey2 = getKeyJ(); +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, _computedKey], [dec, 2, _computedKey2]], []).e; + } + constructor(...args) { + _initProto(this); + } + [_computedKey]() { + return 1; + } + [_computedKey2]() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/method-and-field/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/method-and-field/input.js new file mode 100644 index 000000000000..e2bfd2a7b415 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-duplicated-keys/method-and-field/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/method-and-field/output.js new file mode 100644 index 000000000000..ecdfedf0e092 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/method-and-field/output.js @@ -0,0 +1,11 @@ +var _init_a, _initProto; +const dec = () => {}; +class Foo { + static { + [_init_a, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, "a"], [dec, 0, "a"]], []).e; + } + a = (_initProto(this), _init_a(this, 123)); + a() { + return 1; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/methods-with-same-key/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-duplicated-keys/methods-with-same-key/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/methods-with-same-key/output.js new file mode 100644 index 000000000000..9e58c5937595 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/methods-with-same-key/output.js @@ -0,0 +1,16 @@ +var _initProto; +const dec = () => {}; +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, "a"], [dec, 2, "a"]], []).e; + } + constructor(...args) { + _initProto(this); + } + a() { + return 1; + } + a() { + return 2; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-duplicated-keys/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/default-anonymous/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/default-anonymous/input.mjs new file mode 100644 index 000000000000..05db70faed30 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-exported/default-anonymous/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/default-anonymous/output.mjs new file mode 100644 index 000000000000..7864d21e01c6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/default-anonymous/output.mjs @@ -0,0 +1,12 @@ +var _initClass, _dec; +let _A; +_dec = dec; +class A { + static { + [_A, _initClass] = babelHelpers.applyDecs2301(this, [], [_dec]).c; + } + static { + _initClass(); + } +} +export { _A as default }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/default-named/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/default-named/input.mjs new file mode 100644 index 000000000000..31cdac17444e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-exported/default-named/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/default-named/output.mjs new file mode 100644 index 000000000000..a3141f23bd05 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/default-named/output.mjs @@ -0,0 +1,12 @@ +var _initClass, _dec; +let _default2; +_dec = dec; +class _default { + static { + [_default2, _initClass] = babelHelpers.applyDecs2301(this, [], [_dec]).c; + } + static { + _initClass(); + } +} +export { _default2 as default }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/member-decorator/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/member-decorator/input.mjs new file mode 100644 index 000000000000..f72e0e9c2249 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-exported/member-decorator/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/member-decorator/output.mjs new file mode 100644 index 000000000000..bd681ef2c806 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/member-decorator/output.mjs @@ -0,0 +1,8 @@ +var _dec, _init_x; +_dec = dec; +export class A { + static { + [_init_x] = babelHelpers.applyDecs2301(this, [[_dec, 0, "x"]], []).e; + } + x = _init_x(this); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/named/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/named/input.mjs new file mode 100644 index 000000000000..367f946714b0 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-exported/named/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/named/output.mjs new file mode 100644 index 000000000000..0365d3a39903 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/named/output.mjs @@ -0,0 +1,12 @@ +var _initClass, _dec; +let _A; +_dec = dec; +class A { + static { + [_A, _initClass] = babelHelpers.applyDecs2301(this, [], [_dec]).c; + } + static { + _initClass(); + } +} +export { _A as A }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/no-decorators/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/no-decorators/input.mjs new file mode 100644 index 000000000000..bc88730f95a8 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-exported/no-decorators/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/no-decorators/output.mjs new file mode 100644 index 000000000000..9ac373c42b10 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/no-decorators/output.mjs @@ -0,0 +1,3 @@ +export class A {} +class B {} +export { B }; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-exported/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/private/exec.js new file mode 100644 index 000000000000..5d9715ee8ee7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/private/exec.js @@ -0,0 +1,44 @@ +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.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(false); + +expect(aContext.access.get(foo)).toBe(2); +expect(() => aContext.access.get({})).toThrow(TypeError); +aContext.access.set(foo, 123); +expect(aContext.access.get(foo)).toBe(123); +expect(() => aContext.access.set({}, 456)).toThrow(TypeError); +expect(aContext.access.get(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(foo)).toBe(124); +bContext.access.set(foo, 123); +expect(bContext.access.get(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/2023-01-fields--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/private/input.js new file mode 100644 index 000000000000..2cd77e99b7e3 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-fields--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/private/output.js new file mode 100644 index 000000000000..5cad57d59921 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/private/output.js @@ -0,0 +1,17 @@ +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.applyDecs2301(Foo, [[dec, 0, "a", o => babelHelpers.classPrivateFieldGet(o, _a), (o, v) => babelHelpers.classPrivateFieldSet(o, _a, v)], [dec, 0, "b", o => babelHelpers.classPrivateFieldGet(o, _b), (o, v) => babelHelpers.classPrivateFieldSet(o, _b, v)]], [], _ => _b.has(babelHelpers.checkInRHS(_))).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/public/exec.js new file mode 100644 index 000000000000..df182db7ac21 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/public/exec.js @@ -0,0 +1,67 @@ +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(aContext.access.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(foo.a).toBe(2); +expect(aContext.access.get(foo)).toBe(2); +foo.a = 123; +expect(foo.a).toBe(123); +expect(aContext.access.get(foo)).toBe(123); +aContext.access.set(foo, 456); +expect(foo.a).toBe(456); +expect(aContext.access.get(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/2023-01-fields--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/public/input.js new file mode 100644 index 000000000000..16a36d324047 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-fields--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/public/output.js new file mode 100644 index 000000000000..e3c1bf64c347 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/public/output.js @@ -0,0 +1,11 @@ +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.applyDecs2301(Foo, [[dec, 0, "a"], [dec, 0, "b"], [dec, 0, _computedKey]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..bafdfec712f5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-private/exec.js @@ -0,0 +1,42 @@ +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.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(false); + +expect(aContext.access.get(Foo)).toBe(2); +expect(() => aContext.access.get({})).toThrow(TypeError); +aContext.access.set(Foo, 123); +expect(aContext.access.get(Foo)).toBe(123); +expect(() => aContext.access.set({}, 456)).toThrow(TypeError); +expect(aContext.access.get(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(Foo)).toBe(124); +bContext.access.set(Foo, 123); +expect(bContext.access.get(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/2023-01-fields--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-private/input.js new file mode 100644 index 000000000000..bc6f56f17527 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-fields--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-private/output.js new file mode 100644 index 000000000000..65bd019bca8a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-private/output.js @@ -0,0 +1,12 @@ +var _init_a, _init_b; +const dec = () => {}; +class Foo {} +[_init_a, _init_b] = babelHelpers.applyDecs2301(Foo, [[dec, 5, "a", o => babelHelpers.classStaticPrivateFieldSpecGet(o, Foo, _a), (o, v) => babelHelpers.classStaticPrivateFieldSpecSet(o, Foo, _a, v)], [dec, 5, "b", o => babelHelpers.classStaticPrivateFieldSpecGet(o, Foo, _b), (o, v) => babelHelpers.classStaticPrivateFieldSpecSet(o, Foo, _b, v)]], []).e; +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/2023-01-fields--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..36113e23c702 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-public/exec.js @@ -0,0 +1,62 @@ +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(aContext.access.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(Foo.a).toBe(2); +expect(aContext.access.get(Foo)).toBe(2); +Foo.a = 123; +expect(Foo.a).toBe(123); +expect(aContext.access.get(Foo)).toBe(123); +aContext.access.set(Foo, 456); +expect(Foo.a).toBe(456); +expect(aContext.access.get(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/2023-01-fields--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-public/input.js new file mode 100644 index 000000000000..e7e44bf1ec16 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-fields--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-public/output.js new file mode 100644 index 000000000000..94a501e72ffc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields--to-es2015/static-public/output.js @@ -0,0 +1,8 @@ +var _init_a, _init_b, _computedKey, _init_computedKey; +const dec = () => {}; +_computedKey = 'c'; +class Foo {} +[_init_a, _init_b, _init_computedKey] = babelHelpers.applyDecs2301(Foo, [[dec, 5, "a"], [dec, 5, "b"], [dec, 5, _computedKey]], []).e; +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/2023-01-fields/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/private/input.js new file mode 100644 index 000000000000..2cd77e99b7e3 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-fields/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/private/output.js new file mode 100644 index 000000000000..3d22e40e6b74 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/private/output.js @@ -0,0 +1,9 @@ +var _init_a, _init_b; +const dec = () => {}; +class Foo { + static { + [_init_a, _init_b] = babelHelpers.applyDecs2301(this, [[dec, 0, "a", o => o.#a, (o, v) => o.#a = v], [dec, 0, "b", o => o.#b, (o, v) => o.#b = v]], [], _ => #b in _).e; + } + #a = _init_a(this); + #b = _init_b(this, 123); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/public/input.js new file mode 100644 index 000000000000..16a36d324047 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-fields/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/public/output.js new file mode 100644 index 000000000000..f49ca9745779 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/public/output.js @@ -0,0 +1,11 @@ +var _init_a, _init_b, _computedKey, _init_computedKey; +const dec = () => {}; +_computedKey = 'c'; +class Foo { + static { + [_init_a, _init_b, _init_computedKey] = babelHelpers.applyDecs2301(this, [[dec, 0, "a"], [dec, 0, "b"], [dec, 0, _computedKey]], []).e; + } + a = _init_a(this); + b = _init_b(this, 123); + [_computedKey] = _init_computedKey(this, 456); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/static-private/input.js new file mode 100644 index 000000000000..bc6f56f17527 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-fields/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/static-private/output.js new file mode 100644 index 000000000000..2e1b13998e1f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/static-private/output.js @@ -0,0 +1,9 @@ +var _init_a, _init_b; +const dec = () => {}; +class Foo { + static { + [_init_a, _init_b] = babelHelpers.applyDecs2301(this, [[dec, 5, "a", o => o.#a, (o, v) => o.#a = v], [dec, 5, "b", o => o.#b, (o, v) => o.#b = v]], []).e; + } + static #a = _init_a(this); + static #b = _init_b(this, 123); +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/static-public/input.js new file mode 100644 index 000000000000..e7e44bf1ec16 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-fields/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/static-public/output.js new file mode 100644 index 000000000000..ebc3178435b6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-fields/static-public/output.js @@ -0,0 +1,11 @@ +var _init_a, _init_b, _computedKey, _init_computedKey; +const dec = () => {}; +_computedKey = 'c'; +class Foo { + static { + [_init_a, _init_b, _init_computedKey] = babelHelpers.applyDecs2301(this, [[dec, 5, "a"], [dec, 5, "b"], [dec, 5, _computedKey]], []).e; + } + 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/2023-01-getters--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/private/exec.js new file mode 100644 index 000000000000..eab384f77836 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/private/exec.js @@ -0,0 +1,42 @@ +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.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(false); + +expect(aContext.access.get(foo)).toBe(2); +expect(() => aContext.access.get({})).toThrow(TypeError); +expect(foo.getA()).toBe(2); +foo.value = 123; +expect(aContext.access.get(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/2023-01-getters--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/private/input.js new file mode 100644 index 000000000000..28519502bf46 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/private/output.js new file mode 100644 index 000000000000..c3a4d559cec1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/private/output.js @@ -0,0 +1,22 @@ +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.applyDecs2301(Foo, [[dec, 3, "a", function () { + return this.value; +}]], [], _ => _a.has(babelHelpers.checkInRHS(_))).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/public/exec.js new file mode 100644 index 000000000000..1e2bbfd6f644 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/public/exec.js @@ -0,0 +1,56 @@ +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(aContext.access.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(foo.a).toBe(2); +expect(foo.b).toBe(2); +expect(aContext.access.get(foo)).toBe(2); +expect(bContext.access.get(foo)).toBe(2); +foo.value = 123; +expect(foo.a).toBe(124); +expect(foo.b).toBe(124); +expect(aContext.access.get(foo)).toBe(124); +expect(bContext.access.get(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/2023-01-getters--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/public/input.js new file mode 100644 index 000000000000..392f9e03412f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/public/output.js new file mode 100644 index 000000000000..b5f2ed2457dd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/public/output.js @@ -0,0 +1,16 @@ +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.applyDecs2301(Foo, [[dec, 3, "a"], [dec, 3, _computedKey]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..082c93bd57ad --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-private/exec.js @@ -0,0 +1,41 @@ +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.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(false); + +expect(aContext.access.get(Foo)).toBe(2); +expect(() => aContext.access.get({})).toThrow(TypeError); +expect(Foo.getA()).toBe(2); +Foo.value = 123; +expect(aContext.access.get(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/2023-01-getters--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-private/input.js new file mode 100644 index 000000000000..9d64c02982da --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-private/output.js new file mode 100644 index 000000000000..98ae05095661 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-private/output.js @@ -0,0 +1,21 @@ +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.applyDecs2301(Foo, [[dec, 8, "a", function () { + return this.value; + }]], []).e; + _initStatic(Foo); +})(); +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..aaebed1470da --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-public/exec.js @@ -0,0 +1,54 @@ +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(aContext.access.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(Foo.a).toBe(2); +expect(Foo.b).toBe(2); +expect(aContext.access.get(Foo)).toBe(2); +expect(bContext.access.get(Foo)).toBe(2); +Foo.value = 123; +expect(Foo.a).toBe(124); +expect(Foo.b).toBe(124); +expect(aContext.access.get(Foo)).toBe(124); +expect(bContext.access.get(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/2023-01-getters--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-public/input.js new file mode 100644 index 000000000000..3bc53fb17cc5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-public/output.js new file mode 100644 index 000000000000..09963ed18bbc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters--to-es2015/static-public/output.js @@ -0,0 +1,16 @@ +var _computedKey, _initStatic; +const dec = () => {}; +_computedKey = 'b'; +class Foo { + static get a() { + return this.value; + } + static get [_computedKey]() { + return this.value; + } +} +(() => { + [_initStatic] = babelHelpers.applyDecs2301(Foo, [[dec, 8, "a"], [dec, 8, _computedKey]], []).e; + _initStatic(Foo); +})(); +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/private/exec.js new file mode 100644 index 000000000000..4fd73c4c5ca1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/private/exec.js @@ -0,0 +1,74 @@ +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.has(foo)).toBe(true); +expect(a_getterContext.access.has({})).toBe(false); +expect(a_getterContext.access.has(Object.create(foo))).toBe(false); +expect(a_setterContext.access.has(foo)).toBe(true); +expect(a_setterContext.access.has({})).toBe(false); +expect(a_setterContext.access.has(Object.create(foo))).toBe(false); +expect(a_getterContext.access.has).not.toBe(a_setterContext.access.has); + +expect(a_getterContext.access.get(foo)).toBe(2); +expect(() => a_getterContext.access.get({})).toThrow(TypeError); +expect(foo.getA()).toBe(2); +a_setterContext.access.set(foo, 123); +expect(a_getterContext.access.get(foo)).toBe(125); +expect(() => a_setterContext.access.set({}, 456)).toThrow(TypeError); +expect(a_getterContext.access.get(foo)).toBe(125); +expect(foo.getA()).toBe(125); +foo.setA(456); +expect(a_getterContext.access.get(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/2023-01-getters-and-setters--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-getters-and-setters--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/private/output.js new file mode 100644 index 000000000000..bb503fb9f577 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/private/output.js @@ -0,0 +1,30 @@ +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.applyDecs2301(Foo, [[dec, 3, "a", function () { + return this.value; +}], [dec, 4, "a", function (v) { + this.value = v; +}]], [], _ => _a.has(babelHelpers.checkInRHS(_))).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/public/exec.js new file mode 100644 index 000000000000..fa548d8d5c40 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/public/exec.js @@ -0,0 +1,103 @@ +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(a_getterContext.access.has(foo)).toBe(true); +expect(a_getterContext.access.has({})).toBe(false); +expect(a_getterContext.access.has(Object.create(foo))).toBe(true); +expect(a_getterContext.access.has({ a: 1 })).toBe(true); +expect(a_getterContext.access.has(Object.create({ a: 1 }))).toBe(true); +expect(a_setterContext.access.has(foo)).toBe(true); +expect(a_setterContext.access.has({})).toBe(false); +expect(a_setterContext.access.has(Object.create(foo))).toBe(true); +expect(a_setterContext.access.has({ a: 1 })).toBe(true); +expect(a_setterContext.access.has(Object.create({ a: 1 }))).toBe(true); +expect(a_getterContext.access.has).not.toBe(a_setterContext.access.has); + +expect(foo.a).toBe(2); +expect(foo.b).toBe(2); +expect(a_getterContext.access.get(foo)).toBe(2); +expect(b_getterContext.access.get(foo)).toBe(2); +foo.a = 123; +expect(foo.a).toBe(125); +expect(foo.b).toBe(125); +expect(a_getterContext.access.get(foo)).toBe(125); +expect(b_getterContext.access.get(foo)).toBe(125); +foo.b = 456; +expect(foo.a).toBe(458); +expect(foo.b).toBe(458); +expect(a_getterContext.access.get(foo)).toBe(458); +expect(b_getterContext.access.get(foo)).toBe(458); +a_setterContext.access.set(foo, 789); +expect(foo.a).toBe(791); +expect(foo.b).toBe(791); +expect(a_getterContext.access.get(foo)).toBe(791); +expect(b_getterContext.access.get(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/2023-01-getters-and-setters--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-getters-and-setters--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/public/output.js new file mode 100644 index 000000000000..407ecd9ad3dc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/public/output.js @@ -0,0 +1,23 @@ +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.applyDecs2301(Foo, [[dec, 3, "a"], [dec, 4, "a"], [dec, 3, _computedKey], [dec, 4, _computedKey2]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..c7faf2394242 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-private/exec.js @@ -0,0 +1,72 @@ +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.has(Foo)).toBe(true); +expect(a_getterContext.access.has({})).toBe(false); +expect(a_getterContext.access.has(Object.create(Foo))).toBe(false); +expect(a_setterContext.access.has(Foo)).toBe(true); +expect(a_setterContext.access.has({})).toBe(false); +expect(a_setterContext.access.has(Object.create(Foo))).toBe(false); +expect(a_getterContext.access.has).not.toBe(a_setterContext.access.has); + +expect(a_getterContext.access.get(Foo)).toBe(2); +expect(() => a_getterContext.access.get({})).toThrow(TypeError); +expect(Foo.getA()).toBe(2); +a_setterContext.access.set(Foo, 123); +expect(a_getterContext.access.get(Foo)).toBe(125); +expect(() => a_setterContext.access.set({}, 456)).toThrow(TypeError); +expect(a_getterContext.access.get(Foo)).toBe(125); +expect(Foo.getA()).toBe(125); +Foo.setA(456); +expect(a_getterContext.access.get(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/2023-01-getters-and-setters--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-getters-and-setters--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-private/output.js new file mode 100644 index 000000000000..c36e28d689f6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-private/output.js @@ -0,0 +1,29 @@ +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.applyDecs2301(Foo, [[dec, 8, "a", function () { + return this.value; + }], [dec, 9, "a", function (v) { + this.value = v; + }]], []).e; + _initStatic(Foo); +})(); +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..9b4f9539e2e4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-public/exec.js @@ -0,0 +1,102 @@ +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(a_getterContext.access.has(Foo)).toBe(true); +expect(a_getterContext.access.has({})).toBe(false); +expect(a_getterContext.access.has(Object.create(Foo))).toBe(true); +expect(a_getterContext.access.has({ a: 1 })).toBe(true); +expect(a_getterContext.access.has(Object.create({ a: 1 }))).toBe(true); +expect(a_setterContext.access.has(Foo)).toBe(true); +expect(a_setterContext.access.has({})).toBe(false); +expect(a_setterContext.access.has(Object.create(Foo))).toBe(true); +expect(a_setterContext.access.has({ a: 1 })).toBe(true); +expect(a_setterContext.access.has(Object.create({ a: 1 }))).toBe(true); +expect(a_getterContext.access.has).not.toBe(a_setterContext.access.has); + +expect(Foo.a).toBe(2); +expect(Foo.b).toBe(2); +expect(a_getterContext.access.get(Foo)).toBe(2); +expect(b_getterContext.access.get(Foo)).toBe(2); +Foo.a = 123; +expect(Foo.a).toBe(125); +expect(Foo.b).toBe(125); +expect(a_getterContext.access.get(Foo)).toBe(125); +expect(b_getterContext.access.get(Foo)).toBe(125); +Foo.b = 456; +expect(Foo.a).toBe(458); +expect(Foo.b).toBe(458); +expect(a_getterContext.access.get(Foo)).toBe(458); +expect(b_getterContext.access.get(Foo)).toBe(458); +a_setterContext.access.set(Foo, 789); +expect(Foo.a).toBe(791); +expect(Foo.b).toBe(791); +expect(a_getterContext.access.get(Foo)).toBe(791); +expect(b_getterContext.access.get(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/2023-01-getters-and-setters--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-getters-and-setters--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-public/output.js new file mode 100644 index 000000000000..0ede14869719 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters--to-es2015/static-public/output.js @@ -0,0 +1,23 @@ +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.applyDecs2301(Foo, [[dec, 8, "a"], [dec, 9, "a"], [dec, 8, _computedKey], [dec, 9, _computedKey2]], []).e; + _initStatic(Foo); +})(); +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/private/input.js new file mode 100644 index 000000000000..fdf137cc4a64 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters-and-setters/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/private/output.js new file mode 100644 index 000000000000..d3e63656c91c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/private/output.js @@ -0,0 +1,27 @@ +var _call_a, _call_a2, _initProto; +const dec = () => {}; +class Foo { + static { + [_call_a, _call_a2, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 3, "a", function () { + return this.value; + }], [dec, 4, "a", function (v) { + this.value = v; + }]], [], _ => #a in _).e; + } + 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/2023-01-getters-and-setters/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/public/input.js new file mode 100644 index 000000000000..1af1569ba988 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters-and-setters/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/public/output.js new file mode 100644 index 000000000000..9ff2a86b99a4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/public/output.js @@ -0,0 +1,25 @@ +var _computedKey, _computedKey2, _initProto; +const dec = () => {}; +_computedKey = 'b'; +_computedKey2 = 'b'; +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[dec, 3, "a"], [dec, 4, "a"], [dec, 3, _computedKey], [dec, 4, _computedKey2]], []).e; + } + 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/2023-01-getters-and-setters/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/static-private/input.js new file mode 100644 index 000000000000..c832634c6b72 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters-and-setters/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/static-private/output.js new file mode 100644 index 000000000000..6ab3c888227b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/static-private/output.js @@ -0,0 +1,25 @@ +var _call_a, _call_a2, _initStatic; +const dec = () => {}; +class Foo { + static { + [_call_a, _call_a2, _initStatic] = babelHelpers.applyDecs2301(this, [[dec, 8, "a", function () { + return this.value; + }], [dec, 9, "a", function (v) { + this.value = v; + }]], []).e; + _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/2023-01-getters-and-setters/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/static-public/input.js new file mode 100644 index 000000000000..bbad4af972ed --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters-and-setters/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/static-public/output.js new file mode 100644 index 000000000000..a2f916e4a81b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters-and-setters/static-public/output.js @@ -0,0 +1,23 @@ +var _computedKey, _computedKey2, _initStatic; +const dec = () => {}; +_computedKey = 'b'; +_computedKey2 = 'b'; +class Foo { + static { + [_initStatic] = babelHelpers.applyDecs2301(this, [[dec, 8, "a"], [dec, 9, "a"], [dec, 8, _computedKey], [dec, 9, _computedKey2]], []).e; + _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/2023-01-getters/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/private/input.js new file mode 100644 index 000000000000..28519502bf46 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/private/output.js new file mode 100644 index 000000000000..aa2ee78b680a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/private/output.js @@ -0,0 +1,19 @@ +var _call_a, _initProto; +const dec = () => {}; +class Foo { + static { + [_call_a, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 3, "a", function () { + return this.value; + }]], [], _ => #a in _).e; + } + 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/2023-01-getters/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/public/input.js new file mode 100644 index 000000000000..392f9e03412f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/public/output.js new file mode 100644 index 000000000000..78daafe15287 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/public/output.js @@ -0,0 +1,18 @@ +var _computedKey, _initProto; +const dec = () => {}; +_computedKey = 'b'; +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[dec, 3, "a"], [dec, 3, _computedKey]], []).e; + } + 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/2023-01-getters/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/static-private/input.js new file mode 100644 index 000000000000..9d64c02982da --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/static-private/output.js new file mode 100644 index 000000000000..16853b029714 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/static-private/output.js @@ -0,0 +1,17 @@ +var _call_a, _initStatic; +const dec = () => {}; +class Foo { + static { + [_call_a, _initStatic] = babelHelpers.applyDecs2301(this, [[dec, 8, "a", function () { + return this.value; + }]], []).e; + _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/2023-01-getters/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/static-public/input.js new file mode 100644 index 000000000000..3bc53fb17cc5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-getters/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/static-public/output.js new file mode 100644 index 000000000000..cf2def1dbe4f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-getters/static-public/output.js @@ -0,0 +1,16 @@ +var _computedKey, _initStatic; +const dec = () => {}; +_computedKey = 'b'; +class Foo { + static { + [_initStatic] = babelHelpers.applyDecs2301(this, [[dec, 8, "a"], [dec, 8, _computedKey]], []).e; + _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/2023-01-methods--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/private-with-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/private-with-initializers/exec.js new file mode 100644 index 000000000000..493327c91c46 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/private-with-initializers/exec.js @@ -0,0 +1,44 @@ +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']; + +expect(aContext.access.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(false); + +// First call gets the method, second call calls the method with correct `this` +expect(aContext.access.get(foo).call(foo)).toBe(2); +expect(() => aContext.access.get({})).toThrow(TypeError); +expect(foo.callA()).toBe(2); +foo.value = 123; +expect(aContext.access.get(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/2023-01-methods--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/private/exec.js new file mode 100644 index 000000000000..a74cb2331eca --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/private/input.js new file mode 100644 index 000000000000..098bbbb687f2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/private/output.js new file mode 100644 index 000000000000..88bd08521712 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/private/output.js @@ -0,0 +1,19 @@ +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.applyDecs2301(Foo, [[dec, 2, "a", function () { + return this.value; +}]], [], _ => _a.has(babelHelpers.checkInRHS(_))).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/public-with-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/public-with-initializers/exec.js new file mode 100644 index 000000000000..d7f969ca466e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/public-with-initializers/exec.js @@ -0,0 +1,59 @@ +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(aContext.access.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(foo.a()).toBe(2); +expect(aContext.access.get(foo).call(foo)).toBe(2); +expect(foo.b()).toBe(2); +expect(bContext.access.get(foo).call(foo)).toBe(2); +foo.value = 123; +expect(aContext.access.get(foo).call(foo)).toBe(124); +expect(foo.a()).toBe(124); +expect(bContext.access.get(foo).call(foo)).toBe(124); +expect(foo.b()).toBe(124); + +expect(aContext.access.get({})).toBe(undefined); +expect(aContext.access.get({ a: 3 })).toBe(3); + +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/2023-01-methods--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/public/exec.js new file mode 100644 index 000000000000..b9ec2b92e328 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/public/input.js new file mode 100644 index 000000000000..3a7f4cfaae9c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/public/output.js new file mode 100644 index 000000000000..a2bde70bd68c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/public/output.js @@ -0,0 +1,16 @@ +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.applyDecs2301(Foo, [[dec, 2, "a"], [dec, 2, _computedKey]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-private-with-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-private-with-initializers/exec.js new file mode 100644 index 000000000000..b94e75710e49 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-private-with-initializers/exec.js @@ -0,0 +1,42 @@ +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']; + +expect(aContext.access.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(false); + +// First call gets the method, second call calls the method with correct `this` +expect(aContext.access.get(Foo).call(Foo)).toBe(2); +expect(() => aContext.access.get({})).toThrow(TypeError); +expect(Foo.callA()).toBe(2); +Foo.value = 123; +expect(aContext.access.get(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/2023-01-methods--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..47deb64ec304 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-private/input.js new file mode 100644 index 000000000000..4a6ae5d4d7fd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-private/output.js new file mode 100644 index 000000000000..37add57acdd1 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-private/output.js @@ -0,0 +1,18 @@ +var _call_a, _initStatic; +const dec = () => {}; +class Foo { + static callA() { + return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _a).call(this); + } +} +(() => { + [_call_a, _initStatic] = babelHelpers.applyDecs2301(Foo, [[dec, 7, "a", function () { + return this.value; + }]], []).e; + _initStatic(Foo); +})(); +var _a = { + writable: true, + value: _call_a +}; +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-public-with-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-public-with-initializers/exec.js new file mode 100644 index 000000000000..910dae50598e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-public-with-initializers/exec.js @@ -0,0 +1,54 @@ +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(aContext.access.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(Foo.a()).toBe(2); +expect(aContext.access.get(Foo).call(Foo)).toBe(2); +expect(Foo.b()).toBe(2); +expect(bContext.access.get(Foo).call(Foo)).toBe(2); +Foo.value = 123; +expect(aContext.access.get(Foo).call(Foo)).toBe(124); +expect(Foo.a()).toBe(124); +expect(bContext.access.get(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/2023-01-methods--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..e5d03ee48021 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-public/input.js new file mode 100644 index 000000000000..5f81da5c0405 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-public/output.js new file mode 100644 index 000000000000..13af2ebdb8f6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods--to-es2015/static-public/output.js @@ -0,0 +1,16 @@ +var _computedKey, _initStatic; +const dec = () => {}; +_computedKey = 'b'; +class Foo { + static a() { + return this.value; + } + static [_computedKey]() { + return this.value; + } +} +(() => { + [_initStatic] = babelHelpers.applyDecs2301(Foo, [[dec, 7, "a"], [dec, 7, _computedKey]], []).e; + _initStatic(Foo); +})(); +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/private/input.js new file mode 100644 index 000000000000..098bbbb687f2 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/private/output.js new file mode 100644 index 000000000000..1a093ee88e38 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/private/output.js @@ -0,0 +1,17 @@ +var _call_a, _initProto; +const dec = () => {}; +class Foo { + static { + [_call_a, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, "a", function () { + return this.value; + }]], [], _ => #a in _).e; + } + constructor(...args) { + _initProto(this); + } + #a = _call_a; + value = 1; + callA() { + return this.#a(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/public/input.js new file mode 100644 index 000000000000..3a7f4cfaae9c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/public/output.js new file mode 100644 index 000000000000..52878333662e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/public/output.js @@ -0,0 +1,18 @@ +var _computedKey, _initProto; +const dec = () => {}; +_computedKey = 'b'; +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, "a"], [dec, 2, _computedKey]], []).e; + } + constructor(...args) { + _initProto(this); + } + value = 1; + a() { + return this.value; + } + [_computedKey]() { + return this.value; + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/static-private/input.js new file mode 100644 index 000000000000..4a6ae5d4d7fd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/static-private/output.js new file mode 100644 index 000000000000..ee2073fb7892 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/static-private/output.js @@ -0,0 +1,15 @@ +var _call_a, _initStatic; +const dec = () => {}; +class Foo { + static { + [_call_a, _initStatic] = babelHelpers.applyDecs2301(this, [[dec, 7, "a", function () { + return this.value; + }]], []).e; + _initStatic(this); + } + static #a = _call_a; + static value = 1; + static callA() { + return this.#a(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/static-public/input.js new file mode 100644 index 000000000000..5f81da5c0405 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-methods/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/static-public/output.js new file mode 100644 index 000000000000..5f090c42976d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-methods/static-public/output.js @@ -0,0 +1,16 @@ +var _computedKey, _initStatic; +const dec = () => {}; +_computedKey = 'b'; +class Foo { + static { + [_initStatic] = babelHelpers.applyDecs2301(this, [[dec, 7, "a"], [dec, 7, _computedKey]], []).e; + _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/2023-01-misc--to-es2015/class-and-method-decorators/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/class-and-property-decorators/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/decorator-evaluation-scope/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/initProto-existing-derived-constructor/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/initProto-existing-derived-constructor/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/initProto-existing-derived-constructor/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/initProto-existing-derived-constructor/output.js new file mode 100644 index 000000000000..77537d357bdc --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/initProto-existing-derived-constructor/output.js @@ -0,0 +1,12 @@ +var _dec, _initProto; +const dec = () => {}; +_dec = deco; +class A extends B { + constructor() { + let a = 2; + _initProto(super(a)); + foo(); + } + method() {} +} +[_initProto] = babelHelpers.applyDecs2301(A, [[_dec, 2, "method"]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/initializer-property-ignored/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/initializer-timing/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/initializer-timing/exec.js new file mode 100644 index 000000000000..ac5920dcd16a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc--to-es2015/leaked-context-addInitializer-throw/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/leaked-context-addInitializer/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/valid-expression-formats/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc--to-es2015/valid-expression-formats/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/valid-expression-formats/output.js new file mode 100644 index 000000000000..e8eb5d866edd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc--to-es2015/valid-expression-formats/output.js @@ -0,0 +1,35 @@ +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.applyDecs2301(_class, [[_dec9, 0, "bar"]], []).e, _class); + } +} +({ + e: [_initProto], + c: [_Foo, _initClass] +} = babelHelpers.applyDecs2301(Foo, [[[dec, _dec5, _dec6, _dec7, _dec8], 2, "method"]], [dec, _dec, _dec2, _dec3, _dec4])); +_initClass(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/all-decorators/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/all-decorators/input.js new file mode 100644 index 000000000000..6986908e606d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/all-decorators/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/all-decorators/output.js new file mode 100644 index 000000000000..28de8eccd406 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/all-decorators/output.js @@ -0,0 +1,71 @@ +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 { + ({ + e: [_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], + c: [_Class, _initClass] + } = babelHelpers.applyDecs2301(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", o => o.#D, (o, v) => o.#D = v], [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", o => o.#B, (o, v) => o.#B = v], [dec, 5, "i"], [dec, 5, "n", o => o.#n, (o, v) => o.#n = v], [dec, 0, "a"], [dec, 0, "e", o => o.#e, (o, v) => o.#e = v]], [dec], _ => #e in _)); + _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/2023-01-misc/decorator-evaluation-scope/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/decorator-evaluation-scope/exec.js new file mode 100644 index 000000000000..ec8beb3b8cbf --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/decorator-evaluation-scope/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/decorator-evaluation-scope/options.json new file mode 100644 index 000000000000..6be5cab9a28e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/decorator-evaluation-scope/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-static-block" + ], + "minNodeVersion": "12.0.0" +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initProto-existing-derived-constructor-multiple-super/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/initProto-existing-derived-constructor-multiple-super/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initProto-existing-derived-constructor-multiple-super/output.js new file mode 100644 index 000000000000..1ffcedd2aeea --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initProto-existing-derived-constructor-multiple-super/output.js @@ -0,0 +1,28 @@ +var _dec, _initProto, _dec2, _initProto2; +const dec = () => {}; +_dec = deco; +class A extends B { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[_dec, 2, "method"]], []).e; + } + constructor() { + if (Math.random() > 0.5) { + _initProto(super(true)); + } else { + _initProto(super(false)); + } + } + method() {} +} +_dec2 = deco; +class C extends B { + static { + [_initProto2] = babelHelpers.applyDecs2301(this, [[_dec2, 2, "method"]], []).e; + } + constructor() { + try { + _initProto2(super(_initProto2(super()), null.x)); + } catch {} + } + method() {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initProto-existing-derived-constructor/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initProto-existing-derived-constructor/input.js new file mode 100644 index 000000000000..b3c7b6f85e9b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/initProto-existing-derived-constructor/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initProto-existing-derived-constructor/output.js new file mode 100644 index 000000000000..cebf325ff164 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initProto-existing-derived-constructor/output.js @@ -0,0 +1,13 @@ +var _initProto; +const dec = () => {}; +class A extends B { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, "method"]], []).e; + } + constructor() { + let a = 2; + _initProto(super(a)); + foo(); + } + method() {} +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initializer-property-ignored/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initializer-property-ignored/exec.js new file mode 100644 index 000000000000..2828e1c22408 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/initializer-property-ignored/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initializer-property-ignored/options.json new file mode 100644 index 000000000000..6be5cab9a28e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/initializer-property-ignored/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-static-block" + ], + "minNodeVersion": "12.0.0" +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/private-keys-in-enclosing-class/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/private-keys-in-enclosing-class/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/private-keys-in-enclosing-class/output.js new file mode 100644 index 000000000000..ec3d19f84d2a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/private-keys-in-enclosing-class/output.js @@ -0,0 +1,16 @@ +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/2023-01-misc/setting-private-method-via-array-pattern/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-array-pattern/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-for-of/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-for-of/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-object-pattern/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-object-pattern/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-rest/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-rest/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-update/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method-via-update/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/setting-private-method/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/setting-private-method/input.js new file mode 100644 index 000000000000..b6417214fec7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/setting-private-method/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/setting-private-method/options.json new file mode 100644 index 000000000000..188eae592ec5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/super-in-nested-constructor-expression/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-misc/super-in-nested-constructor-expression/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-nested-constructor-expression/output.js new file mode 100644 index 000000000000..eb1b5daf423b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-nested-constructor-expression/output.js @@ -0,0 +1,14 @@ +var _initClass; +const dec = () => {}; +let _Foo; +class Foo extends Bar { + static { + [_Foo, _initClass] = babelHelpers.applyDecs2301(this, [], [dec]).c; + } + constructor() { + let foo = super(); + } + static { + _initClass(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-private-accessor/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-private-accessor/input.js new file mode 100644 index 000000000000..b32ea0bd378f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/super-in-private-accessor/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-private-accessor/output.js new file mode 100644 index 000000000000..4319528e4129 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-private-accessor/output.js @@ -0,0 +1,16 @@ +var _call_x, _initProto; +const dec = () => {}; +class Foo extends Bar { + static { + [_call_x, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 3, "x", function () { + return babelHelpers.get(babelHelpers.getPrototypeOf(Foo), "foo", this).call(this); + }]], [], _ => #x in _).e; + } + constructor(...args) { + super(...args); + _initProto(this); + } + get #x() { + return _call_x(this); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-private-method/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-private-method/input.js new file mode 100644 index 000000000000..36f9bd37dfa7 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/super-in-private-method/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-private-method/output.js new file mode 100644 index 000000000000..10c86c690683 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/super-in-private-method/output.js @@ -0,0 +1,14 @@ +var _call_x, _initProto; +const dec = () => {}; +class Foo extends Bar { + static { + [_call_x, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 2, "x", function () { + return babelHelpers.get(babelHelpers.getPrototypeOf(Foo), "foo", this).call(this); + }]], [], _ => #x in _).e; + } + constructor(...args) { + super(...args); + _initProto(this); + } + #x = _call_x; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/valid-expression-formats/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/valid-expression-formats/input.js new file mode 100644 index 000000000000..586564c5e219 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-misc/valid-expression-formats/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/valid-expression-formats/output.js new file mode 100644 index 000000000000..80d58c4f92b5 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-misc/valid-expression-formats/output.js @@ -0,0 +1,36 @@ +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 { + ({ + e: [_initProto], + c: [_Foo, _initClass] + } = babelHelpers.applyDecs2301(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.applyDecs2301(this, [[_dec9, 0, "bar"]], []).e; + } + bar = _init_bar(this); + }; + } + static { + _initClass(); + } +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-initializers-fields/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-initializers-fields/exec.js new file mode 100644 index 000000000000..a59b51cc2314 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-initializers-fields/exec.js @@ -0,0 +1,67 @@ +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), + }; + }; +} + +function logFieldDecoratorRun(a, b) { + push(a); + return function (el) { push(b); return el; }; +} + +@logClassDecoratorRun(0, 19, 21) +@logClassDecoratorRun(1, 18, 20) +class A { + @logAccessorDecoratorRun(2, 11, 23, 27) + @logAccessorDecoratorRun(3, 10, 22, 26) + accessor a; + + @logFieldDecoratorRun(4, 15) + @logFieldDecoratorRun(5, 14) + b; + + @logFieldDecoratorRun(6, 17) + @logFieldDecoratorRun(7, 16) + #c; + + @logAccessorDecoratorRun(8, 13, 25, 29) + @logAccessorDecoratorRun(9, 12, 24, 28) + accessor #d; + + constructor() { + this.a = this.#d = null; + } +} + +var nums = Array.from({ length: 22 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 30 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-method-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-method-initializers/exec.js new file mode 100644 index 000000000000..a3efd8e40a6d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-method-initializers/exec.js @@ -0,0 +1,75 @@ +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), + }; + }; +} + +function logMethodDecoratorRun(a, b, c, d) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { + push(c); + }); + return () => (el(), push(d)) + }; +} + +@logClassDecoratorRun(0, 19, 21) +@logClassDecoratorRun(1, 18, 20) +class A { + @logAccessorDecoratorRun(2, 11, 23, 31) + @logAccessorDecoratorRun(3, 10, 22, 30) + accessor a; + + @logMethodDecoratorRun(4, 13, 25, 35) + @logMethodDecoratorRun(5, 12, 24, 34) + b() {}; + + @logMethodDecoratorRun(6, 15, 27, 37) + @logMethodDecoratorRun(7, 14, 26, 36) + #c() {}; + + @logAccessorDecoratorRun(8, 17, 29, 33) + @logAccessorDecoratorRun(9, 16, 28, 32) + accessor #d; + + constructor() { + this.b(); + this.#c(); + this.a = this.#d = null; + } +} + +var nums = Array.from({ length: 22 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-static-accessor-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-static-accessor-initializers/exec.js new file mode 100644 index 000000000000..448854862950 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-static-accessor-initializers/exec.js @@ -0,0 +1,51 @@ +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; +} + +var nums = Array.from({ length: 30 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-static-method-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-static-method-initializers/exec.js new file mode 100644 index 000000000000..d940e8c8f379 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/accessor-static-method-initializers/exec.js @@ -0,0 +1,77 @@ +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), + }; + }; +} + +function logMethodDecoratorRun(a, b, c, d) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { + push(c); + }); + return () => (el(), push(d)) + }; +} + +@logClassDecoratorRun(0, 19, 29) +@logClassDecoratorRun(1, 18, 28) +class A { + static { + A.b(), A.#c(); + } + + @logAccessorDecoratorRun(2, 15, 31, 35) + @logAccessorDecoratorRun(3, 14, 30, 34) + accessor a; + + @logMethodDecoratorRun(4, 11, 21, 25) + @logMethodDecoratorRun(5, 10, 20, 24) + static b() {}; + + @logMethodDecoratorRun(6, 13, 23, 27) + @logMethodDecoratorRun(7, 12, 22, 26) + static #c() {}; + + @logAccessorDecoratorRun(8, 17, 33, 37) + @logAccessorDecoratorRun(9, 16, 32, 36) + accessor #d; + + constructor() { + this.a = this.#d = null; + } +} + +var nums = Array.from({ length: 30 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/field-initializers-after-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-ordering--to-es2015/field/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/field/exec.js new file mode 100644 index 000000000000..7a51e8b93b7e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/field/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/2023-01-ordering--to-es2015/initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/initializers/exec.js new file mode 100644 index 000000000000..2a43cb651ee9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/initializers/exec.js @@ -0,0 +1,56 @@ +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; +} + +var nums = Array.from({ length: 46 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 54 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/static-accessor-method-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/static-accessor-method-initializers/exec.js new file mode 100644 index 000000000000..e1ec45be3190 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/static-accessor-method-initializers/exec.js @@ -0,0 +1,74 @@ +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), + }; + }; +} + +function logMethodDecoratorRun(a, b, c, d) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { + push(c); + }); + return () => (el(), push(d)) + }; +} + +@logClassDecoratorRun(0, 19, 29) +@logClassDecoratorRun(1, 18, 28) +class A { + @logMethodDecoratorRun(2, 15, 31, 35) + @logMethodDecoratorRun(3, 14, 30, 34) + 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; + + @logMethodDecoratorRun(8, 17, 33, 37) + @logMethodDecoratorRun(9, 16, 32, 36) + #d() {} + + constructor() { + this.a(); + this.#d(); + } +} + +var nums = Array.from({ length: 30 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering--to-es2015/static-field-initializers-after-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-ordering/accessor-initializers-fields/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-initializers-fields/exec.js new file mode 100644 index 000000000000..a59b51cc2314 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-initializers-fields/exec.js @@ -0,0 +1,67 @@ +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), + }; + }; +} + +function logFieldDecoratorRun(a, b) { + push(a); + return function (el) { push(b); return el; }; +} + +@logClassDecoratorRun(0, 19, 21) +@logClassDecoratorRun(1, 18, 20) +class A { + @logAccessorDecoratorRun(2, 11, 23, 27) + @logAccessorDecoratorRun(3, 10, 22, 26) + accessor a; + + @logFieldDecoratorRun(4, 15) + @logFieldDecoratorRun(5, 14) + b; + + @logFieldDecoratorRun(6, 17) + @logFieldDecoratorRun(7, 16) + #c; + + @logAccessorDecoratorRun(8, 13, 25, 29) + @logAccessorDecoratorRun(9, 12, 24, 28) + accessor #d; + + constructor() { + this.a = this.#d = null; + } +} + +var nums = Array.from({ length: 22 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 30 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-method-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-method-initializers/exec.js new file mode 100644 index 000000000000..a3efd8e40a6d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-method-initializers/exec.js @@ -0,0 +1,75 @@ +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), + }; + }; +} + +function logMethodDecoratorRun(a, b, c, d) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { + push(c); + }); + return () => (el(), push(d)) + }; +} + +@logClassDecoratorRun(0, 19, 21) +@logClassDecoratorRun(1, 18, 20) +class A { + @logAccessorDecoratorRun(2, 11, 23, 31) + @logAccessorDecoratorRun(3, 10, 22, 30) + accessor a; + + @logMethodDecoratorRun(4, 13, 25, 35) + @logMethodDecoratorRun(5, 12, 24, 34) + b() {}; + + @logMethodDecoratorRun(6, 15, 27, 37) + @logMethodDecoratorRun(7, 14, 26, 36) + #c() {}; + + @logAccessorDecoratorRun(8, 17, 29, 33) + @logAccessorDecoratorRun(9, 16, 28, 32) + accessor #d; + + constructor() { + this.b(); + this.#c(); + this.a = this.#d = null; + } +} + +var nums = Array.from({ length: 22 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-static-accessor-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-static-accessor-initializers/exec.js new file mode 100644 index 000000000000..448854862950 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-static-accessor-initializers/exec.js @@ -0,0 +1,51 @@ +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; +} + +var nums = Array.from({ length: 30 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-static-method-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-static-method-initializers/exec.js new file mode 100644 index 000000000000..d940e8c8f379 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/accessor-static-method-initializers/exec.js @@ -0,0 +1,77 @@ +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), + }; + }; +} + +function logMethodDecoratorRun(a, b, c, d) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { + push(c); + }); + return () => (el(), push(d)) + }; +} + +@logClassDecoratorRun(0, 19, 29) +@logClassDecoratorRun(1, 18, 28) +class A { + static { + A.b(), A.#c(); + } + + @logAccessorDecoratorRun(2, 15, 31, 35) + @logAccessorDecoratorRun(3, 14, 30, 34) + accessor a; + + @logMethodDecoratorRun(4, 11, 21, 25) + @logMethodDecoratorRun(5, 10, 20, 24) + static b() {}; + + @logMethodDecoratorRun(6, 13, 23, 27) + @logMethodDecoratorRun(7, 12, 22, 26) + static #c() {}; + + @logAccessorDecoratorRun(8, 17, 33, 37) + @logAccessorDecoratorRun(9, 16, 32, 36) + accessor #d; + + constructor() { + this.a = this.#d = null; + } +} + +var nums = Array.from({ length: 30 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/field-initializers-after-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/field-initializers-after-methods/exec.js new file mode 100644 index 000000000000..46e71f7281db --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-ordering/field/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/field/exec.js new file mode 100644 index 000000000000..7a51e8b93b7e --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/field/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/2023-01-ordering/initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/initializers/exec.js new file mode 100644 index 000000000000..2a43cb651ee9 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/initializers/exec.js @@ -0,0 +1,56 @@ +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; +} + +var nums = Array.from({ length: 46 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 54 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/options.json new file mode 100644 index 000000000000..8c6c1b05890a --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/options.json @@ -0,0 +1,4 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]], + "minNodeVersion": "16.11.0" +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/static-accessor-method-initializers/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/static-accessor-method-initializers/exec.js new file mode 100644 index 000000000000..e1ec45be3190 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/static-accessor-method-initializers/exec.js @@ -0,0 +1,74 @@ +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), + }; + }; +} + +function logMethodDecoratorRun(a, b, c, d) { + push(a); + return function (el, { addInitializer }) { + push(b); + addInitializer(function () { + push(c); + }); + return () => (el(), push(d)) + }; +} + +@logClassDecoratorRun(0, 19, 29) +@logClassDecoratorRun(1, 18, 28) +class A { + @logMethodDecoratorRun(2, 15, 31, 35) + @logMethodDecoratorRun(3, 14, 30, 34) + 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; + + @logMethodDecoratorRun(8, 17, 33, 37) + @logMethodDecoratorRun(9, 16, 32, 36) + #d() {} + + constructor() { + this.a(); + this.#d(); + } +} + +var nums = Array.from({ length: 30 }, (_, i) => i); +expect(log).toEqual(nums); + +new A(); + +var nums = Array.from({ length: 38 }, (_, i) => i); +expect(log).toEqual(nums); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-ordering/static-field-initializers-after-methods/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-runtime-errors--to-es2015/invalid-accessor-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-runtime-errors--to-es2015/invalid-add-initializer/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-runtime-errors--to-es2015/invalid-class-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-runtime-errors--to-es2015/invalid-field-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-runtime-errors--to-es2015/invalid-getter-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-runtime-errors--to-es2015/invalid-method-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-runtime-errors--to-es2015/invalid-setter-decorator-return/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-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/2023-01-runtime-errors--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-runtime-errors--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-runtime-errors--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/options.json new file mode 100644 index 000000000000..d108c768296c --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + ["proposal-decorators", { "version": "2023-01" }], + "proposal-class-properties", + "proposal-private-methods", + "proposal-class-static-block" + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/private/exec.js new file mode 100644 index 000000000000..2e5ed8d74721 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/private/exec.js @@ -0,0 +1,44 @@ +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(aContext.access.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(false); + +expect(foo.value).toBe(1); +aContext.access.set(foo, 123); +expect(foo.value).toBe(124); +expect(() => aContext.access.set({}, 456)).toThrow(TypeError); +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/2023-01-setters--to-es2015/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/private/input.js new file mode 100644 index 000000000000..66dd78268d19 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-setters--to-es2015/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/private/output.js new file mode 100644 index 000000000000..28a954ff3228 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/private/output.js @@ -0,0 +1,22 @@ +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.applyDecs2301(Foo, [[dec, 4, "a", function (v) { + return this.value = v; +}]], [], _ => _a.has(babelHelpers.checkInRHS(_))).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/public/exec.js new file mode 100644 index 000000000000..f82fb5e637da --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/public/exec.js @@ -0,0 +1,52 @@ +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(aContext.access.has(foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(foo.value).toBe(1); +foo.a = 123; +expect(foo.value).toBe(124); +aContext.access.set(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/2023-01-setters--to-es2015/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/public/input.js new file mode 100644 index 000000000000..9a7faf175edd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-setters--to-es2015/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/public/output.js new file mode 100644 index 000000000000..52abac66ef06 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/public/output.js @@ -0,0 +1,16 @@ +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.applyDecs2301(Foo, [[dec, 4, "a"], [dec, 4, _computedKey]], []).e; diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-private/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-private/exec.js new file mode 100644 index 000000000000..6314a3393e05 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-private/exec.js @@ -0,0 +1,42 @@ +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(aContext.access.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(false); + +expect(Foo.value).toBe(1); +aContext.access.set(Foo, 123); +expect(Foo.value).toBe(124); +expect(() => aContext.access.set({}, 456)).toThrow(TypeError); +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/2023-01-setters--to-es2015/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-private/input.js new file mode 100644 index 000000000000..6bf29a2a2c94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-setters--to-es2015/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-private/output.js new file mode 100644 index 000000000000..81b70713008f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-private/output.js @@ -0,0 +1,21 @@ +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.applyDecs2301(Foo, [[dec, 9, "a", function (v) { + return this.value = v; + }]], []).e; + _initStatic(Foo); +})(); +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-public/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-public/exec.js new file mode 100644 index 000000000000..e6c67fe0217d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-public/exec.js @@ -0,0 +1,50 @@ +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(aContext.access.has(Foo)).toBe(true); +expect(aContext.access.has({})).toBe(false); +expect(aContext.access.has(Object.create(Foo))).toBe(true); +expect(aContext.access.has({ a: 1 })).toBe(true); +expect(aContext.access.has(Object.create({ a: 1 }))).toBe(true); + +expect(Foo.value).toBe(1); +Foo.a = 123; +expect(Foo.value).toBe(124); +aContext.access.set(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/2023-01-setters--to-es2015/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-public/input.js new file mode 100644 index 000000000000..ed0a661dcb2d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-setters--to-es2015/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-public/output.js new file mode 100644 index 000000000000..916682510354 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters--to-es2015/static-public/output.js @@ -0,0 +1,16 @@ +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.applyDecs2301(Foo, [[dec, 9, "a"], [dec, 9, _computedKey]], []).e; + _initStatic(Foo); +})(); +babelHelpers.defineProperty(Foo, "value", 1); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/options.json new file mode 100644 index 000000000000..ba7a7231ab0f --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["proposal-decorators", { "version": "2023-01" }]] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/private/input.js new file mode 100644 index 000000000000..66dd78268d19 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-setters/private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/private/output.js new file mode 100644 index 000000000000..d95063e256e6 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/private/output.js @@ -0,0 +1,19 @@ +var _call_a, _initProto; +const dec = () => {}; +class Foo { + static { + [_call_a, _initProto] = babelHelpers.applyDecs2301(this, [[dec, 4, "a", function (v) { + return this.value = v; + }]], [], _ => #a in _).e; + } + 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/2023-01-setters/public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/public/input.js new file mode 100644 index 000000000000..9a7faf175edd --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-setters/public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/public/output.js new file mode 100644 index 000000000000..d745ca34214d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/public/output.js @@ -0,0 +1,18 @@ +var _computedKey, _initProto; +const dec = () => {}; +_computedKey = 'b'; +class Foo { + static { + [_initProto] = babelHelpers.applyDecs2301(this, [[dec, 4, "a"], [dec, 4, _computedKey]], []).e; + } + 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/2023-01-setters/static-private/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/static-private/input.js new file mode 100644 index 000000000000..6bf29a2a2c94 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-setters/static-private/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/static-private/output.js new file mode 100644 index 000000000000..2ec483f1d1f4 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/static-private/output.js @@ -0,0 +1,17 @@ +var _call_a, _initStatic; +const dec = () => {}; +class Foo { + static { + [_call_a, _initStatic] = babelHelpers.applyDecs2301(this, [[dec, 9, "a", function (v) { + return this.value = v; + }]], []).e; + _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/2023-01-setters/static-public/input.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/static-public/input.js new file mode 100644 index 000000000000..ed0a661dcb2d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-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/2023-01-setters/static-public/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/static-public/output.js new file mode 100644 index 000000000000..80a151f3405b --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/2023-01-setters/static-public/output.js @@ -0,0 +1,16 @@ +var _computedKey, _initStatic; +const dec = () => {}; +_computedKey = 'b'; +class Foo { + static { + [_initStatic] = babelHelpers.applyDecs2301(this, [[dec, 9, "a"], [dec, 9, _computedKey]], []).e; + _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 00a35d163ef1..292e48fe2587 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" and "2021-12" - version?: "legacy" | "2018-09" | "2021-12" | "2022-03"; + // TODO(Babel 8): Remove "2018-09", "2021-12", and '2022-03' + version?: "legacy" | "2018-09" | "2021-12" | "2022-03" | "2023-01"; // TODO(Babel 8): Remove decoratorsBeforeExport?: boolean; } @@ -18,10 +18,11 @@ 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: " + - "'2022-03', '2021-12', '2018-09', or 'legacy'.", + "'2023-01', '2022-03', '2021-12', '2018-09', or 'legacy'.", ); } if ( + version !== "2023-01" && version !== "2022-03" && version !== "2021-12" && version !== "legacy" @@ -55,6 +56,7 @@ export default declare((api, options: Options) => { if (version === undefined) { version = legacy ? "legacy" : "2018-09"; } else if ( + version !== "2023-01" && version !== "2022-03" && version !== "2021-12" && version !== "2018-09" && @@ -75,7 +77,11 @@ export default declare((api, options: Options) => { ); } } else { - if (version === "legacy" || version === "2022-03") { + if ( + version === "legacy" || + version === "2022-03" || + version === "2023-01" + ) { throw new Error( `'decoratorsBeforeExport' can't be used with ${version} decorators.`, ); @@ -94,14 +100,16 @@ export default declare((api, options: Options) => { parserOpts.plugins.push("decorators-legacy"); } else if (process.env.BABEL_8_BREAKING) { parserOpts.plugins.push( - [ - "decorators", - { decoratorsBeforeExport: false, allowCallParenthesized: false }, - ], + ["decorators", { allowCallParenthesized: false }], "decoratorAutoAccessors", ); } else { - if (version === "2022-03") { + if (version === "2023-01") { + parserOpts.plugins.push( + ["decorators", { allowCallParenthesized: false }], + "decoratorAutoAccessors", + ); + } else if (version === "2022-03") { parserOpts.plugins.push( [ "decorators", diff --git a/packages/babel-plugin-syntax-decorators/test/index.js b/packages/babel-plugin-syntax-decorators/test/index.js index c15d7db243e8..d89618a1e209 100644 --- a/packages/babel-plugin-syntax-decorators/test/index.js +++ b/packages/babel-plugin-syntax-decorators/test/index.js @@ -76,6 +76,15 @@ babel7describe("'decoratorsBeforeExport' option", function () { ).toThrow(); }); + test("is incompatible with 2023-01 decorators", function () { + expect( + makeParser("", { decoratorsBeforeExport: false, version: "2023-01" }), + ).toThrow(); + expect( + makeParser("", { decoratorsBeforeExport: true, version: "2023-01" }), + ).toThrow(); + }); + const BEFORE = "@dec export class Foo {}"; const AFTER = "export @dec class Foo {}"; @@ -128,6 +137,22 @@ describe("'version' option", function () { ).not.toThrow(); }); + test("'2023-01' disallows @(...)()", function () { + expect(makeParser("@(foo)() class A {}", { version: "2023-01" })).toThrow(); + expect( + makeParser("@(foo()) class A {}", { version: "2023-01" }), + ).not.toThrow(); + }); + + test("'2023-01' allows decorators both before and after export", function () { + expect( + makeParser("@dec export class A {}", { version: "2023-01" }), + ).not.toThrow(); + expect( + makeParser("export @dec class A {}", { version: "2023-01" }), + ).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 fcf7fc0d5525..238402395fba 100644 --- a/packages/babel-runtime-corejs2/package.json +++ b/packages/babel-runtime-corejs2/package.json @@ -63,6 +63,15 @@ "./helpers/applyDecs2203R.js" ], "./helpers/esm/applyDecs2203R": "./helpers/esm/applyDecs2203R.js", + "./helpers/applyDecs2301": [ + { + "node": "./helpers/applyDecs2301.js", + "import": "./helpers/esm/applyDecs2301.js", + "default": "./helpers/applyDecs2301.js" + }, + "./helpers/applyDecs2301.js" + ], + "./helpers/esm/applyDecs2301": "./helpers/esm/applyDecs2301.js", "./helpers/asyncGeneratorDelegate": [ { "node": "./helpers/asyncGeneratorDelegate.js", diff --git a/packages/babel-runtime-corejs3/package.json b/packages/babel-runtime-corejs3/package.json index 3763b28e20bc..ed17d959dc1a 100644 --- a/packages/babel-runtime-corejs3/package.json +++ b/packages/babel-runtime-corejs3/package.json @@ -62,6 +62,15 @@ "./helpers/applyDecs2203R.js" ], "./helpers/esm/applyDecs2203R": "./helpers/esm/applyDecs2203R.js", + "./helpers/applyDecs2301": [ + { + "node": "./helpers/applyDecs2301.js", + "import": "./helpers/esm/applyDecs2301.js", + "default": "./helpers/applyDecs2301.js" + }, + "./helpers/applyDecs2301.js" + ], + "./helpers/esm/applyDecs2301": "./helpers/esm/applyDecs2301.js", "./helpers/asyncGeneratorDelegate": [ { "node": "./helpers/asyncGeneratorDelegate.js", diff --git a/packages/babel-runtime/package.json b/packages/babel-runtime/package.json index 6259350746f6..d6b76d3a9355 100644 --- a/packages/babel-runtime/package.json +++ b/packages/babel-runtime/package.json @@ -62,6 +62,15 @@ "./helpers/applyDecs2203R.js" ], "./helpers/esm/applyDecs2203R": "./helpers/esm/applyDecs2203R.js", + "./helpers/applyDecs2301": [ + { + "node": "./helpers/applyDecs2301.js", + "import": "./helpers/esm/applyDecs2301.js", + "default": "./helpers/applyDecs2301.js" + }, + "./helpers/applyDecs2301.js" + ], + "./helpers/esm/applyDecs2301": "./helpers/esm/applyDecs2301.js", "./helpers/asyncGeneratorDelegate": [ { "node": "./helpers/asyncGeneratorDelegate.js", diff --git a/scripts/parser-tests/flow/allowlist.txt b/scripts/parser-tests/flow/allowlist.txt index bfab48c5b138..bfe4caa2347d 100644 --- a/scripts/parser-tests/flow/allowlist.txt +++ b/scripts/parser-tests/flow/allowlist.txt @@ -1,20 +1,42 @@ -ES6/modules/export_default_class_implements.js -ES6/modules/migrated_0020.js +# 21 invalid programs did not produce a parsing error + JSX/invalid_unpaired_gt.js JSX/invalid_unpaired_rcurly.js JSX_invalid/migrated_0000.js -arrow_function/object_return_type.js arrow_function_invalid/migrated_0002.js async_arrow_functions/with_type_parameters_types_disabled.js +class_method_kinds/polymorphic_getter.js +class_properties/migrated_0026.js +comment_interning/declare_variable.js +for_await_loops/migrated_0000.js +ts_syntax/invalid_alias_keyof.js +ts_syntax/invalid_alias_never.js +ts_syntax/invalid_alias_readonly.js +ts_syntax/invalid_alias_undefined.js +ts_syntax/invalid_alias_unknown.js +ts_syntax/invalid_readonly_type.js +types/aliases/invalid_keyword_symbol.js +types/declare_export/var/migrated_0009.js +types/declare_export/var/migrated_0010.js +types/declare_statements/migrated_0000.js +types/declare_statements/migrated_0001.js +types/reserved/function.js + + +# 49 valid programs produced a parsing error + +ES6/modules/export_default_class_implements.js +ES6/modules/migrated_0020.js +JSX/jsx_type_args.js +JSX/jsx_type_args_implicit.js +JSX/jsx_type_args_multiple.js +JSX/jsx_type_args_with_children.js +arrow_function/object_return_type.js async_await/migrated_0020.js async_await/migrated_0024.js async_await/migrated_0027.js class_expression/anonymous_implements.js -class_method_kinds/polymorphic_getter.js -class_properties/migrated_0003.js -class_properties/migrated_0008.js class_properties/migrated_0021.js -class_properties/migrated_0026.js comment_interning/class_method.js comment_interning/class_property.js comment_interning/declare_export_declaration.js @@ -29,9 +51,26 @@ comment_interning/remove_type_trailing_comments.js comment_interning/super.js comment_interning/type_alias.js decorators/migrated_0003.js +decorators/migrated_0005.js +enums/declare-enum.js export_import_reserved_words/migrated_0003.js +export_statements/export_specifier_await.js +export_statements/export_specifier_reserved_alias.js export_statements/export_trailing_comma.js -for_await_loops/migrated_0000.js -nullish_coalescing/missing-plugin.js -optional_chaining/missing-plugin.js -types/member/reserved_words.js +ts_syntax/as.js +ts_syntax/in_out_variance.js +ts_syntax/readonly_type.js +ts_syntax/readonly_variance.js +ts_syntax/satisfies.js +ts_syntax/type_param_extends.js +types/declare_export/var/const.js +types/declare_export/var/let.js +types/declare_module/enum.js +types/declare_module_with_exports/enum.js +types/declare_statements/decalre_let.js +types/declare_statements/declare_const.js +types/tuples/labeled.js +types/tuples/optional.js +types/tuples/spread.js +types/tuples/variance.js +types/typeof/type-like-argument.js diff --git a/scripts/parser-tests/typescript/allowlist.txt b/scripts/parser-tests/typescript/allowlist.txt index 17b027afe5dc..250dea0f2a9a 100644 --- a/scripts/parser-tests/typescript/allowlist.txt +++ b/scripts/parser-tests/typescript/allowlist.txt @@ -1,7 +1,6 @@ -# 9 invalid programs did not produce a parsing error +# 8 invalid programs did not produce a parsing error bigintIndex.ts -classExpressionWithDecorator1.ts collisionArgumentsArrowFunctions.ts # TypeScript doesn't allow a parameter to be named arguments even in non-strict mode, which we don't catch. collisionArgumentsFunction.ts # TypeScript doesn't allow a parameter to be named arguments even in non-strict mode, which we don't catch. collisionArgumentsFunctionExpressions.ts # TypeScript doesn't allow a parameter to be named arguments even in non-strict mode, which we don't catch. @@ -11,7 +10,7 @@ exportDeclarationsInAmbientNamespaces2.ts multipleExports.ts -# 131 valid programs produced a parsing error +# 136 valid programs produced a parsing error ArrowFunctionExpression1.ts MemberAccessorDeclaration15.ts @@ -36,6 +35,8 @@ classCannotExtendVar.ts classExtendsMultipleBaseClasses.ts classOverloadForFunction.ts classWithEmptyTypeParameter.ts +conflictingDeclarationsImportFromNamespace1.ts +conflictingDeclarationsImportFromNamespace2.ts constDeclarations-invalidContexts.ts constDeclarations-scopes.ts constDeclarations-validContexts.ts @@ -75,14 +76,13 @@ exportInterfaceClassAndValue.ts exportSameNameFuncVar.ts exportSpecifierForAGlobal.ts # We handle this fine, but it doesn't consider the different files together exportSpecifierReferencingOuterDeclaration2.ts # We handle this fine, but it doesn't consider the different files together +expressionWithJSDocTypeArguments.ts expressionsForbiddenInParameterInitializers.ts extendsClauseAlreadySeen.ts extendsClauseAlreadySeen2.ts fileWithNextLine2.ts funClodule.ts functionCall15.ts -gettersAndSettersErrors.ts -giant.ts implementClausePrecedingExtends.ts implementsClauseAlreadySeen.ts importAndVariableDeclarationConflict3.ts @@ -98,6 +98,7 @@ indexerSignatureWithRestParam.ts interfaceMayNotBeExtendedWitACall.ts interfaceNaming1.ts # We correctly identify this error, but we can't bring it in without bringing a bunch of other tests too. interfaceWithImplements1.ts +invalidOptionalChainFromNewExpression.ts jsxAttributeMissingInitializer.tsx jsxAttributeWithoutExpressionReact.tsx letAndVarRedeclaration.ts @@ -123,8 +124,11 @@ multipleInheritance.ts nameCollisions.ts noImplicitAnyDestructuringVarDeclaration.ts nonMergedOverloads.ts +optionalChainWithInstantiationExpression1.ts parameterInitializerBeforeDestructuringEmit.ts parameterPropertyOutsideConstructor.ts +parseInvalidNonNullableTypes.ts +parseInvalidNullableTypes.ts parserConstructorDeclaration12.ts reExportGlobalDeclaration1.ts reExportGlobalDeclaration2.ts # We handle this fine, but it doesn't consider the different files together @@ -142,4 +146,5 @@ staticAsIdentifier.ts staticModifierAlreadySeen.ts strictOptionalProperties1.ts superCallFromClassThatHasNoBaseType1.ts +unicodeEscapesInNames02.ts varArgConstructorMemberParameter.ts