Skip to content

Commit

Permalink
Adds the 2020-09 transform for decorators
Browse files Browse the repository at this point in the history
Implements the 2020-09 transform for the decorators proposal, with
support for the `accessor` keyword.
  • Loading branch information
pzuraq committed Dec 25, 2021
1 parent ee06a98 commit f922636
Show file tree
Hide file tree
Showing 148 changed files with 5,748 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",
'var getOwnPropertyDescriptor=Object.getOwnPropertyDescriptor,defineProperty=Object.defineProperty,hasOwnProperty=Object.hasOwnProperty,create=Object.create,getOwnPropertySymbols=Object.getOwnPropertySymbols,setPrototypeOf=Object.setPrototypeOf,assign=Object.assign,isArray=Array.isArray,arrayFrom=Array.from,CONSTRUCTOR=0,PUBLIC=1,PRIVATE=2,symbolMessage="Metadata keys must be symbols, received: ";function createMetadataMethodsForProperty(metadataMap,kind,property){return{getMetadata(key){if("symbol"!=typeof key)throw new TypeError(symbolMessage+key);var metadataForKey=metadataMap[key];if(void 0!==metadataForKey)if(kind===PUBLIC){var pub=metadataForKey.public;if(void 0!==pub)return pub[property]}else if(kind===PRIVATE){var priv=metadataForKey.private;if(void 0!==priv)return priv.get(property)}else if(hasOwnProperty.call(metadataForKey,"constructor"))return metadataForKey.constructor},setMetadata(key,value){if("symbol"!=typeof key)throw new TypeError(symbolMessage+key);var metadataForKey=metadataMap[key];if(void 0===metadataForKey&&(metadataForKey=metadataMap[key]={}),kind===PUBLIC){var pub=metadataForKey.public;void 0===pub&&(pub=metadataForKey.public=create(null)),pub[property]=value}else if(kind===PRIVATE){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=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&&setPrototypeOf(pub,parentPub);var priv=metaForKey.private;if(priv){var privArr=arrayFrom(priv.values()),parentPriv=parentMetaForKey?parentMetaForKey.private:null;parentPriv&&(privArr=privArr.concat(parentPriv)),metaForKey.private=privArr}parentMetaForKey&&setPrototypeOf(metaForKey,parentMetaForKey)}parentMetadataMap&&setPrototypeOf(metadataMap,parentMetadataMap),obj[Symbol.metadata]=metadataMap}}function createAddInitializerMethod(initializers){return function(initializer){assertValidInitializer(initializer),initializers.push(initializer)}}function memberDecCtx(base,prop,desc,metadataMap,initializers,kind,name,isStatic,isPrivate){var kindStr;switch(kind){case ACCESSOR:kindStr="accessor";break;case METHOD:kindStr="method";break;case GETTER:kindStr="getter";break;case SETTER:kindStr="setter";break;default:kindStr="field"}var metadataKind,metadataName,ctx={kind:kindStr,name:isPrivate?"#"+name:name,isStatic:isStatic,isPrivate:isPrivate};if(kind!==FIELD&&(ctx.addInitializer=createAddInitializerMethod(initializers)),isPrivate){metadataKind=PRIVATE,metadataName=Symbol(name);var access={};kind===FIELD?(access.get=desc.get,access.set=desc.set):kind===METHOD?access.get=function(){return desc.value}:(kind!==ACCESSOR&&kind!==GETTER||(access.get=function(){return desc.get.call(this)}),kind!==ACCESSOR&&kind!==SETTER||(access.set=function(v){desc.set.call(this,v)})),ctx.access=access}else metadataKind=PUBLIC,metadataName=name;return assign(ctx,createMetadataMethodsForProperty(metadataMap,metadataKind,metadataName))}var FIELD=0,ACCESSOR=1,METHOD=2,GETTER=3,SETTER=4,STATIC=5;function assertValidInitializer(initializer){if("function"!=typeof initializer)throw new Error("initializers must be functions")}function assertValidReturnValue(kind,value){var type=typeof value;if(kind===ACCESSOR){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 kind===FIELD?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,isStatic,metadataMap,initializers,decs,kind,prop,privateName){var desc,initializer,value,isPrivate="string"==typeof privateName,name=isPrivate?privateName:prop;isPrivate?(desc=getOwnPropertyDescriptor(base,prop),value=kind===FIELD||kind===ACCESSOR?{get:desc.get,set:desc.set}:desc.value,delete base[prop]):kind!==FIELD&&(desc=getOwnPropertyDescriptor(base,prop),value=kind===ACCESSOR?{get:desc.get,set:desc.set}:kind===GETTER?desc.get:kind===SETTER?desc.set:desc.value);var newValue,get,set,ctx=memberDecCtx(base,prop,desc,metadataMap,initializers,kind,name,isStatic,isPrivate);if("function"==typeof decs)void 0!==(newValue=decs(value,ctx))&&(assertValidReturnValue(kind,newValue),kind===FIELD?initializer=newValue:kind===ACCESSOR?(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),kind===FIELD?newInit=newValue:kind===ACCESSOR?(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(kind===FIELD||kind===ACCESSOR){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)}kind!==FIELD&&(kind===ACCESSOR?(desc.get=value.get,desc.set=value.set):kind===METHOD?desc.value=value:kind===GETTER?desc.get=value:kind===SETTER&&(desc.set=value),isPrivate?kind===ACCESSOR?(ret.push((function(instance,args){return value.get.apply(instance,args)})),ret.push((function(instance,args){return value.set.apply(instance,args)}))):kind===METHOD?ret.push((function(instance,args){return value.apply(instance,args)})):ret.push((function(instance,args){return value.call(instance,args)})):defineProperty(base,prop,desc))}function applyMemberDecs(ret,Class,protoMetadataMap,staticMetadataMap,members){for(var protoInitializers,staticInitializers,existingProtoNonFields=new Map,existingStaticNonFields=new Map,i=0;i<members.length;i++){var member=members[i];if(isArray(member)){var base,metadataMap,initializers,decs=member[0],kind=member[1],prop=member[2],privateName=member[3],isStatic=kind>=STATIC;if(isStatic?(base=Class,metadataMap=staticMetadataMap,kind-=STATIC,staticInitializers||(staticInitializers=[]),initializers=staticInitializers):(base=Class.prototype,metadataMap=protoMetadataMap,protoInitializers||(protoInitializers=[]),initializers=protoInitializers),kind!==FIELD&&!privateName){var existingNonFields=isStatic?existingStaticNonFields:existingProtoNonFields,existingKind=existingNonFields.get(prop)||0;if(!0===existingKind||existingKind===GETTER&&kind!==SETTER||existingKind===SETTER&&kind!==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: "+prop);!existingKind&&kind>METHOD?existingNonFields.set(prop,kind):existingNonFields.set(prop,!0)}applyMemberDec(ret,base,isStatic,metadataMap,initializers,decs,kind,prop,privateName)}}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=assign({kind:"class",name:name,addInitializer:createAddInitializerMethod(initializers)},createMetadataMethodsForProperty(metadataMap,CONSTRUCTOR,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 f922636

Please sign in to comment.