Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new decorators transform #14004

Merged
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3f76448
Adds the 2021-12 transform for decorators
pzuraq Nov 27, 2021
ab6d74a
Ensure private UID generation takes into account all referenced priva…
pzuraq Dec 31, 2021
46c54fb
Allow version: "legacy", use built-in Identifier generation, simplify…
pzuraq Jan 1, 2022
910e1a7
Rename tests
nicolo-ribaudo Jan 6, 2022
e1c0086
Install static fields and private methods on the correct class
nicolo-ribaudo Jan 6, 2022
9ce9c7b
Update makefile
nicolo-ribaudo Jan 7, 2022
0e745e5
`undefined` -> `void 0` in helper
nicolo-ribaudo Jan 8, 2022
f23bcbc
Minor code update
nicolo-ribaudo Jan 8, 2022
faf44db
Add test for _initProto with existing constructor
nicolo-ribaudo Jan 8, 2022
5ba1365
Fix `_initProto` injection
nicolo-ribaudo Jan 8, 2022
9a876a2
Simplify _initProto injection for existing super()
nicolo-ribaudo Jan 8, 2022
9ecadfd
Fix test
nicolo-ribaudo Jan 9, 2022
62acebe
add decoratorsVersion support to babel-standalone
JLHwung Jan 14, 2022
e67b698
fix: throw when legacy and version are both specified
JLHwung Jan 14, 2022
e52f1dc
fix init
JLHwung Jan 14, 2022
be798df
refactor: centralize option validation in syntax-decorators
JLHwung Jan 15, 2022
e9f56f3
remove noop parser plugin
JLHwung Jan 15, 2022
351f158
fix test errors
JLHwung Jan 15, 2022
2fc8ad9
fix TS errors
JLHwung Jan 15, 2022
0876e7a
Fallback to `Symbol.for("Symbol.metadata")`
nicolo-ribaudo Jan 16, 2022
938ce50
Object.create(null) -> standard object
pzuraq Jan 16, 2022
aa4d6e2
use legacy visitor when version is "legacy"
JLHwung Jan 16, 2022
1eb2e68
Fix interop between class and static decorators
pzuraq Jan 16, 2022
df637f9
Update contrib.md
pzuraq Jan 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 9 additions & 9 deletions Makefile
Expand Up @@ -187,15 +187,15 @@ prepublish:
IS_PUBLISH=true $(MAKE) test

new-version-checklist:
# @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# @echo "!!!!!! !!!!!!"
# @echo "!!!!!! Write any message that should !!!!!!"
# @echo "!!!!!! block the release here !!!!!!"
# @echo "!!!!!! !!!!!!"
# @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# @exit 1
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@echo "!!!!!! !!!!!!"
@echo "!!!!!! Update the version of the "identity" !!!!!!"
@echo "!!!!!! and "applyDecs" helpers to 7.17.0 !!!!!!"
@echo "!!!!!! !!!!!!"
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@exit 1

new-version:
$(MAKE) new-version-checklist
Expand Down
5 changes: 4 additions & 1 deletion babel.config.js
Expand Up @@ -194,7 +194,10 @@ module.exports = function (api) {
assumptions: parserAssumptions,
},
{
test: ["packages/babel-generator"].map(normalize),
test: [
"packages/babel-generator",
"packages/babel-plugin-proposal-decorators",
].map(normalize),
plugins: ["babel-plugin-transform-charcodes"],
},
convertESM && {
Expand Down
Expand Up @@ -80,7 +80,10 @@ function extractElementDescriptor(
const properties: t.ObjectExpression["properties"] = [
prop("kind", t.stringLiteral(t.isClassMethod(node) ? node.kind : "field")),
prop("decorators", takeDecorators(node as Decorable)),
prop("static", node.static && t.booleanLiteral(true)),
prop(
"static",
!t.isStaticBlock(node) && node.static && t.booleanLiteral(true),
),
prop("key", getKey(node)),
].filter(Boolean);

Expand Down
Expand Up @@ -911,7 +911,7 @@ function replaceThisContext(
getSuperRef,
getObjectRef() {
state.needsClassRef = true;
return isStaticBlock || path.node.static
return t.isStaticBlock(path.node) || path.node.static
? ref
: t.memberExpression(ref, t.identifier("prototype"));
},
Expand All @@ -931,7 +931,8 @@ function replaceThisContext(
export type PropNode =
| t.ClassProperty
| t.ClassPrivateMethod
| t.ClassPrivateProperty;
| t.ClassPrivateProperty
| t.StaticBlock;
export type PropPath = NodePath<PropNode>;

export function buildFieldsInitNodes(
Expand Down Expand Up @@ -963,7 +964,7 @@ export function buildFieldsInitNodes(
for (const prop of props) {
prop.isClassProperty() && ts.assertFieldTransformed(prop);

const isStatic = prop.node.static;
const isStatic = !t.isStaticBlock(prop.node) && prop.node.static;
const isInstance = !isStatic;
const isPrivate = prop.isPrivate();
const isPublic = !isPrivate;
Expand Down
Expand Up @@ -38,6 +38,7 @@ interface Options {
name: string;
feature: number;
loose?: boolean;
inherits?: (api: any, options: any) => any;
// same as PluginObject.manipulateOptions
manipulateOptions: (options: unknown, parserOpts: ParserOptions) => void;
// TODO(flow->ts): change to babel api
Expand All @@ -51,6 +52,7 @@ export function createClassFeaturePlugin({
manipulateOptions,
// TODO(Babel 8): Remove the default value
api = { assumption: () => void 0 },
inherits,
}: Options) {
const setPublicClassFields = api.assumption("setPublicClassFields");
const privateFieldsAsProperties = api.assumption("privateFieldsAsProperties");
Expand Down Expand Up @@ -85,6 +87,7 @@ export function createClassFeaturePlugin({
return {
name,
manipulateOptions,
inherits,

pre() {
enableFeature(this.file, feature, loose);
Expand Down Expand Up @@ -170,7 +173,7 @@ export function createClassFeaturePlugin({
path.isPrivate() ||
path.isStaticBlock?.()
) {
props.push(path);
props.push(path as PropPath);
}
}
}
Expand Down Expand Up @@ -246,7 +249,7 @@ export function createClassFeaturePlugin({
(referenceVisitor, state) => {
if (isDecorated) return;
for (const prop of props) {
if (prop.node.static) continue;
if (t.isStaticBlock(prop.node) || prop.node.static) continue;
prop.traverse(referenceVisitor, state);
}
},
Expand Down
4 changes: 4 additions & 0 deletions packages/babel-helpers/src/helpers-generated.ts
Expand Up @@ -13,6 +13,10 @@ function helper(minVersion, source) {
}

export default Object.freeze({
applyDecs: helper(
"7.16.6",
'function createMetadataMethodsForProperty(metadataMap,kind,property){return{getMetadata(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(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=Object.create(null)),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<metadataKeys.length;i++){var key=metadataKeys[i],metaForKey=metadataMap[key],parentMetaForKey=parentMetadataMap?parentMetadataMap[key]:null,pub=metaForKey.public,parentPub=parentMetaForKey?parentMetaForKey.public:null;pub&&parentPub&&Object.setPrototypeOf(pub,parentPub);var priv=metaForKey.private;if(priv){var privArr=Array.from(priv.values()),parentPriv=parentMetaForKey?parentMetaForKey.private:null;parentPriv&&(privArr=privArr.concat(parentPriv)),metaForKey.private=privArr}parentMetaForKey&&Object.setPrototypeOf(metaForKey,parentMetaForKey)}parentMetadataMap&&Object.setPrototypeOf(metadataMap,parentMetadataMap),obj[Symbol.metadata||Symbol.for("Symbol.metadata")]=metadataMap}}function createAddInitializerMethod(initializers){return function(initializer){assertValidInitializer(initializer),initializers.push(initializer)}}function memberDecCtx(base,name,desc,metadataMap,initializers,kind,isStatic,isPrivate){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 metadataKind,metadataName,ctx={kind:kindStr,name:isPrivate?"#"+name:name,isStatic:isStatic,isPrivate:isPrivate};if(0!==kind&&(ctx.addInitializer=createAddInitializerMethod(initializers)),isPrivate){metadataKind=2,metadataName=Symbol(name);var access={};0===kind?(access.get=desc.get,access.set=desc.set):2===kind?access.get=function(){return desc.value}:(1!==kind&&3!==kind||(access.get=function(){return desc.get.call(this)}),1!==kind&&4!==kind||(access.set=function(v){desc.set.call(this,v)})),ctx.access=access}else metadataKind=1,metadataName=name;return Object.assign(ctx,createMetadataMethodsForProperty(metadataMap,metadataKind,metadataName))}function assertValidInitializer(initializer){if("function"!=typeof initializer)throw new Error("initializers must be functions")}function assertValidReturnValue(kind,value){var type=typeof value;if(1===kind){if("object"!==type||null===value)throw new Error("accessor decorators must return an object with get, set, or initializer properties or void 0")}else if("function"!==type)throw 0===kind?new Error("field decorators must return a initializer function or void 0"):new Error("method decorators must return a function or void 0")}function applyMemberDec(ret,base,decInfo,name,kind,isStatic,isPrivate,metadataMap,initializers){var desc,initializer,value,decs=decInfo[0];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);var newValue,get,set,ctx=memberDecCtx(base,name,desc,metadataMap,initializers,kind,isStatic,isPrivate);if("function"==typeof decs)void 0!==(newValue=decs(value,ctx))&&(assertValidReturnValue(kind,newValue),0===kind?initializer=newValue:1===kind?(initializer=newValue.initializer,get=newValue.get||value.get,set=newValue.set||value.set,value={get:get,set:set}):value=newValue);else for(var i=0;i<decs.length;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;i<ownInitializers.length;i++)value=ownInitializers[i].call(instance,value);return value}}else{var originalInitializer=initializer;initializer=function(instance,init){return originalInitializer.call(instance,init)}}ret.push(initializer)}0!==kind&&(1===kind?(desc.get=value.get,desc.set=value.set):2===kind?desc.value=value:3===kind?desc.get=value:4===kind&&(desc.set=value),isPrivate?1===kind?(ret.push((function(instance,args){return value.get.call(instance,args)})),ret.push((function(instance,args){return value.set.call(instance,args)}))):2===kind?ret.push(value):ret.push((function(instance,args){return value.call(instance,args)})):Object.defineProperty(base,name,desc))}function applyMemberDecs(ret,Class,protoMetadataMap,staticMetadataMap,decInfos){for(var protoInitializers,staticInitializers,existingProtoNonFields=new Map,existingStaticNonFields=new Map,i=0;i<decInfos.length;i++){var decInfo=decInfos[i];if(Array.isArray(decInfo)){var base,metadataMap,initializers,kind=decInfo[1],name=decInfo[2],isPrivate=decInfo.length>3,isStatic=kind>=5;if(isStatic?(base=Class,metadataMap=staticMetadataMap,kind-=5,staticInitializers||(staticInitializers=[]),initializers=staticInitializers):(base=Class.prototype,metadataMap=protoMetadataMap,protoInitializers||(protoInitializers=[]),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)}}protoInitializers&&pushInitializers(ret,protoInitializers),staticInitializers&&pushInitializers(ret,staticInitializers)}function pushInitializers(ret,initializers){initializers.length>0?(initializers=initializers.slice(),ret.push((function(instance){for(var i=0;i<initializers.length;i++)initializers[i].call(instance,instance);return instance}))):ret.push((function(instance){return instance}))}function applyClassDecs(ret,targetClass,metadataMap,classDecs){for(var initializers=[],newClass=targetClass,name=targetClass.name,ctx=Object.assign({kind:"class",name:name,addInitializer:createAddInitializerMethod(initializers)},createMetadataMethodsForProperty(metadataMap,0,name)),i=0;i<classDecs.length;i++)newClass=classDecs[i](newClass,ctx)||newClass;ret.push(newClass),initializers.length>0?ret.push((function(){for(var i=0;i<initializers.length;i++)initializers[i].call(newClass,newClass)})):ret.push((function(){}))}export default function applyDecs(targetClass,memberDecs,classDecs){var ret=[],staticMetadataMap={};if(memberDecs){var protoMetadataMap={};applyMemberDecs(ret,targetClass,protoMetadataMap,staticMetadataMap,memberDecs),convertMetadataMapToFinal(targetClass.prototype,protoMetadataMap)}return classDecs&&applyClassDecs(ret,targetClass,staticMetadataMap,classDecs),convertMetadataMapToFinal(targetClass,staticMetadataMap),ret}',
),
asyncIterator: helper(
"7.15.9",
'export default function _asyncIterator(iterable){var method,async,sync,retry=2;for("undefined"!=typeof Symbol&&(async=Symbol.asyncIterator,sync=Symbol.iterator);retry--;){if(async&&null!=(method=iterable[async]))return method.call(iterable);if(sync&&null!=(method=iterable[sync]))return new AsyncFromSyncIterator(method.call(iterable));async="@@asyncIterator",sync="@@iterator"}throw new TypeError("Object is not async iterable")}function AsyncFromSyncIterator(s){function AsyncFromSyncIteratorContinuation(r){if(Object(r)!==r)return Promise.reject(new TypeError(r+" is not an object."));var done=r.done;return Promise.resolve(r.value).then((function(value){return{value:value,done:done}}))}return AsyncFromSyncIterator=function(s){this.s=s,this.n=s.next},AsyncFromSyncIterator.prototype={s:null,n:null,next:function(){return AsyncFromSyncIteratorContinuation(this.n.apply(this.s,arguments))},return:function(value){var ret=this.s.return;return void 0===ret?Promise.resolve({value:value,done:!0}):AsyncFromSyncIteratorContinuation(ret.apply(this.s,arguments))},throw:function(value){var thr=this.s.return;return void 0===thr?Promise.reject(value):AsyncFromSyncIteratorContinuation(thr.apply(this.s,arguments))}},new AsyncFromSyncIterator(s)}',
Expand Down
6 changes: 6 additions & 0 deletions packages/babel-helpers/src/helpers.ts
Expand Up @@ -2052,3 +2052,9 @@ if (!process.env.BABEL_8_BREAKING) {
}
`;
}

helpers.identity = helper("7.16.7")`
export default function _identity(x) {
return x;
}
`;