Skip to content

Commit

Permalink
Adds the 2021-12 transform for decorators
Browse files Browse the repository at this point in the history
Implements the 2021-12 transform for the decorators proposal, with
support for the `accessor` keyword.
  • Loading branch information
pzuraq committed Dec 29, 2021
1 parent ee06a98 commit 6a86175
Show file tree
Hide file tree
Showing 233 changed files with 7,352 additions and 8 deletions.
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 @@ -170,7 +170,7 @@ export function createClassFeaturePlugin({
path.isPrivate() ||
path.isStaticBlock?.()
) {
props.push(path);
props.push(path as PropPath);
}
}
}
Expand Down Expand Up @@ -246,7 +246,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],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]=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 undefined")}else if("function"!==type)throw 0===kind?new Error("field decorators must return a initializer function or undefined"):new Error("method decorators must return a function or undefined")}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((function(instance,args){return value.apply(instance,args)})):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)}))):ret.push((function(){}))}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

0 comments on commit 6a86175

Please sign in to comment.