diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18bf064feccf..c1e17ef67840 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,6 +106,9 @@ jobs: env: BABEL_8_BREAKING: false STRIP_BABEL_8_FLAG: true + - name: Ensure cwd does not contain uncommitted changes + run: | + ./scripts/assert-dir-git-clean.sh - uses: actions/upload-artifact@v2 with: name: babel-artifact diff --git a/Gulpfile.mjs b/Gulpfile.mjs index 6d15d7a8e27a..d3541f4db119 100644 --- a/Gulpfile.mjs +++ b/Gulpfile.mjs @@ -137,7 +137,7 @@ async function generateTypeHelpers(helperKind, filename = "index.ts") { * @typedef {("asserts" | "validators" | "virtual-types")} TraverseHelperKind * @param {TraverseHelperKind} helperKind */ -async function generateTraverseHelpers(helperKind) { +function generateTraverseHelpers(helperKind) { return generateHelpers( `./packages/babel-traverse/scripts/generators/${helperKind}.js`, `./packages/babel-traverse/src/path/generated/`, @@ -146,7 +146,7 @@ async function generateTraverseHelpers(helperKind) { ); } -async function generateRuntimeHelpers() { +function generateRuntimeHelpers() { return generateHelpers( `./packages/babel-helpers/scripts/generate-helpers.js`, `./packages/babel-helpers/src/`, @@ -602,6 +602,7 @@ gulp.task( "build-no-bundle", gulp.parallel( "generate-standalone", + "generate-runtime-helpers", gulp.series( "generate-type-helpers", // rebuild @babel/types since type-helpers may be changed diff --git a/packages/babel-helpers/src/helpers-generated.ts b/packages/babel-helpers/src/helpers-generated.ts index 15c28b9b2de4..337ae5a0c176 100644 --- a/packages/babel-helpers/src/helpers-generated.ts +++ b/packages/babel-helpers/src/helpers-generated.ts @@ -15,7 +15,7 @@ function helper(minVersion, source) { export default Object.freeze({ applyDecs: helper( "7.17.0", - 'function createMetadataMethodsForProperty(metadataMap,kind,property){return{getMetadata:function(key){if("symbol"!=typeof key)throw new TypeError("Metadata keys must be symbols, received: "+key);var metadataForKey=metadataMap[key];if(void 0!==metadataForKey)if(1===kind){var pub=metadataForKey.public;if(void 0!==pub)return pub[property]}else if(2===kind){var priv=metadataForKey.private;if(void 0!==priv)return priv.get(property)}else if(Object.hasOwnProperty.call(metadataForKey,"constructor"))return metadataForKey.constructor},setMetadata:function(key,value){if("symbol"!=typeof key)throw new TypeError("Metadata keys must be symbols, received: "+key);var metadataForKey=metadataMap[key];if(void 0===metadataForKey&&(metadataForKey=metadataMap[key]={}),1===kind){var pub=metadataForKey.public;void 0===pub&&(pub=metadataForKey.public={}),pub[property]=value}else if(2===kind){var priv=metadataForKey.priv;void 0===priv&&(priv=metadataForKey.private=new Map),priv.set(property,value)}else metadataForKey.constructor=value}}}function convertMetadataMapToFinal(obj,metadataMap){var parentMetadataMap=obj[Symbol.metadata||Symbol.for("Symbol.metadata")],metadataKeys=Object.getOwnPropertySymbols(metadataMap);if(0!==metadataKeys.length){for(var i=0;i=0;i--){var newInit;if(void 0!==(newValue=(0,decs[i])(value,ctx)))assertValidReturnValue(kind,newValue),0===kind?newInit=newValue:1===kind?(newInit=newValue.initializer,get=newValue.get||value.get,set=newValue.set||value.set,value={get:get,set:set}):value=newValue,void 0!==newInit&&(void 0===initializer?initializer=newInit:"function"==typeof initializer?initializer=[initializer,newInit]:initializer.push(newInit))}if(0===kind||1===kind){if(void 0===initializer)initializer=function(instance,init){return init};else if("function"!=typeof initializer){var ownInitializers=initializer;initializer=function(instance,init){for(var value=init,i=0;i3,isStatic=kind>=5;if(isStatic?(base=Class,metadataMap=staticMetadataMap,kind-=5,initializers=staticInitializers):(base=Class.prototype,metadataMap=protoMetadataMap,initializers=protoInitializers),0!==kind&&!isPrivate){var existingNonFields=isStatic?existingStaticNonFields:existingProtoNonFields,existingKind=existingNonFields.get(name)||0;if(!0===existingKind||3===existingKind&&4!==kind||4===existingKind&&3!==kind)throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: "+name);!existingKind&&kind>2?existingNonFields.set(name,kind):existingNonFields.set(name,!0)}applyMemberDec(ret,base,decInfo,name,kind,isStatic,isPrivate,metadataMap,initializers)}}pushInitializers(ret,protoInitializers),pushInitializers(ret,staticInitializers)}function pushInitializers(ret,initializers){initializers.length>0&&(initializers=initializers.slice(),ret.push((function(instance){for(var i=0;i0){for(var newClass=targetClass,name=targetClass.name,ctx=Object.assign({kind:"class",name:name,addInitializer:createAddInitializerMethod(initializers)},createMetadataMethodsForProperty(metadataMap,0,name)),i=classDecs.length-1;i>=0;i--)newClass=classDecs[i](newClass,ctx)||newClass;ret.push(newClass)}initializers.length>0?ret.push((function(){for(var i=0;i=0;i--){var newInit;if(void 0!==(newValue=(0,decs[i])(value,ctx)))assertValidReturnValue(kind,newValue),0===kind?newInit=newValue:1===kind?(newInit=newValue.initializer,get=newValue.get||value.get,set=newValue.set||value.set,value={get:get,set:set}):value=newValue,void 0!==newInit&&(void 0===initializer?initializer=newInit:"function"==typeof initializer?initializer=[initializer,newInit]:initializer.push(newInit))}if(0===kind||1===kind){if(void 0===initializer)initializer=function(instance,init){return init};else if("function"!=typeof initializer){var ownInitializers=initializer;initializer=function(instance,init){for(var value=init,i=0;i3,isStatic=kind>=5;if(isStatic?(base=Class,metadataMap=staticMetadataMap,0!==(kind-=5)&&(initializers=staticInitializers=staticInitializers||[])):(base=Class.prototype,metadataMap=protoMetadataMap,0!==kind&&(initializers=protoInitializers=protoInitializers||[])),0!==kind&&!isPrivate){var existingNonFields=isStatic?existingStaticNonFields:existingProtoNonFields,existingKind=existingNonFields.get(name)||0;if(!0===existingKind||3===existingKind&&4!==kind||4===existingKind&&3!==kind)throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: "+name);!existingKind&&kind>2?existingNonFields.set(name,kind):existingNonFields.set(name,!0)}applyMemberDec(ret,base,decInfo,name,kind,isStatic,isPrivate,metadataMap,initializers)}}pushInitializers(ret,protoInitializers),pushInitializers(ret,staticInitializers)}function pushInitializers(ret,initializers){initializers&&(initializers.length>0?(initializers=initializers.slice(),ret.push((function(instance){for(var i=0;i0){for(var initializers=[],newClass=targetClass,name=targetClass.name,ctx=Object.assign({kind:"class",name:name,addInitializer:createAddInitializerMethod(initializers)},createMetadataMethodsForProperty(metadataMap,0,name)),i=classDecs.length-1;i>=0;i--)newClass=classDecs[i](newClass,ctx)||newClass;ret.push(newClass),initializers.length>0?ret.push((function(){for(var i=0;i 0) { - // Slice the array, which means that `addInitializer` can no longer add - // additional initializers to the array - initializers = initializers.slice(); - - ret.push(function (instance) { - for (var i = 0; i < initializers.length; i++) { - initializers[i].call(instance, instance); - } - return instance; - }); - } else { - ret.push(function (instance) { - return instance; - }); + if (initializers) { + if (initializers.length > 0) { + // Slice the array, which means that `addInitializer` can no longer add + // additional initializers to the array + initializers = initializers.slice(); + + ret.push(function (instance) { + for (var i = 0; i < initializers.length; i++) { + initializers[i].call(instance, instance); + } + return instance; + }); + } else { + ret.push(function (instance) { + return instance; + }); + } } } function applyClassDecs(ret, targetClass, metadataMap, classDecs) { - var initializers = []; if (classDecs.length > 0) { + var initializers = []; var newClass = targetClass; var name = targetClass.name; @@ -534,16 +542,16 @@ function applyClassDecs(ret, targetClass, metadataMap, classDecs) { } ret.push(newClass); - } - if (initializers.length > 0) { - ret.push(function () { - for (var i = 0; i < initializers.length; i++) { - initializers[i].call(newClass, newClass); - } - }); - } else { - ret.push(function () {}); + if (initializers.length > 0) { + ret.push(function () { + for (var i = 0; i < initializers.length; i++) { + initializers[i].call(newClass, newClass); + } + }); + } else { + ret.push(function () {}); + } } } diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-misc--to-es2015/class-and-method-decorators/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-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/2021-12-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/2021-12-misc--to-es2015/class-and-property-decorators/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/2021-12-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/2021-12-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/scripts/assert-dir-git-clean.sh b/scripts/assert-dir-git-clean.sh new file mode 100755 index 000000000000..2dcefe0119cd --- /dev/null +++ b/scripts/assert-dir-git-clean.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +# Must run at a git working dir +if [ -n "$(git status --porcelain=v1 2>/dev/null)" ]; then + echo "Please re-run \"make build\" and checkout the following changes to git" + git status + exit 1 +fi