2023-04-20 11:26:34 +03:00
/* @minVersion 7.20.0 */
/ * *
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
* /
2023-10-16 23:38:53 +03:00
export function _apply _decs _2203 _r ( targetClass , memberDecs , classDecs , parentClass ) {
2023-04-20 11:26:34 +03:00
function createAddInitializerMethod ( initializers , decoratorFinishedRef ) {
return function addInitializer ( initializer ) {
assertNotFinished ( decoratorFinishedRef , "addInitializer" ) ;
assertCallable ( initializer , "An initializer" ) ;
initializers . push ( initializer ) ;
} ;
}
2023-10-16 23:38:53 +03:00
function memberDec ( dec , name , desc , initializers , kind , isStatic , isPrivate , metadata , value ) {
2023-04-20 11:26:34 +03:00
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 ( kind === 0 /* FIELD */ ) {
if ( isPrivate ) {
get = desc . get ;
set = desc . set ;
} else {
get = function ( ) {
return this [ name ] ;
} ;
set = function ( v ) {
this [ name ] = v ;
} ;
}
} else if ( kind === 2 /* METHOD */ ) {
get = function ( ) {
return desc . value ;
} ;
} else {
// replace with values that will go through the final getter and setter
if ( kind === 1 /* ACCESSOR */ || kind === 3 /* GETTER */ ) {
get = function ( ) {
return desc . get . call ( this ) ;
} ;
}
if ( kind === 1 /* ACCESSOR */ || kind === 4 /* SETTER */ ) {
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 = 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" ) ;
}
}
2023-10-16 23:38:53 +03:00
function applyMemberDec ( ret , base , decInfo , name , kind , isStatic , isPrivate , initializers , metadata ) {
2023-04-20 11:26:34 +03:00
var decs = decInfo [ 0 ] ;
var desc , init , value ;
if ( isPrivate ) {
if ( kind === 0 /* FIELD */ || kind === 1 /* ACCESSOR */ ) {
desc = { get : decInfo [ 3 ] , set : 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" ) {
2023-10-16 23:38:53 +03:00
newValue = memberDec ( decs , name , desc , initializers , kind , isStatic , isPrivate , metadata , value ) ;
2023-04-20 11:26:34 +03:00
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 ] ;
2023-10-16 23:38:53 +03:00
newValue = memberDec ( dec , name , desc , initializers , kind , isStatic , isPrivate , metadata , value ) ;
2023-04-20 11:26:34 +03:00
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 ) ;
}
}
}
2023-10-16 23:38:53 +03:00
function applyMemberDecs ( Class , decInfos , metadata ) {
2023-04-20 11:26:34 +03:00
var ret = [ ] ;
var protoInitializers ;
var staticInitializers ;
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 ;
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 ) ;
}
}
2023-10-16 23:38:53 +03:00
applyMemberDec ( ret , base , decInfo , name , kind , isStatic , isPrivate , initializers , metadata ) ;
2023-04-20 11:26:34 +03:00
}
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 ;
} ) ;
}
}
2023-10-16 23:38:53 +03:00
function applyClassDecs ( targetClass , classDecs , metadata ) {
2023-04-20 11:26:34 +03:00
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 {
2023-10-16 23:38:53 +03:00
var nextNewClass = classDecs [ i ] ( newClass , { kind : "class" , name : name , addInitializer : createAddInitializerMethod ( initializers , decoratorFinishedRef ) , metadata } ) ;
2023-04-20 11:26:34 +03:00
} finally {
decoratorFinishedRef . v = true ;
}
if ( nextNewClass !== undefined ) {
assertValidReturnValue ( 10 , /* CLASS */ nextNewClass ) ;
newClass = nextNewClass ;
}
}
2023-10-16 23:38:53 +03:00
return [ defineMetadata ( newClass , metadata ) , function ( ) {
2023-04-20 11:26:34 +03:00
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.
}
2023-10-16 23:38:53 +03:00
function defineMetadata ( Class , metadata ) {
return Object . defineProperty ( Class , Symbol . metadata || Symbol . for ( "Symbol.metadata" ) , { configurable : true , enumerable : true , value : metadata } ) ;
}
2023-04-20 11:26:34 +03:00
/ * *
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 ) ;
* /
2023-10-16 23:38:53 +03:00
_apply _decs _2203 _r = function ( targetClass , memberDecs , classDecs , parentClass ) {
if ( parentClass !== void 0 ) {
var parentMetadata = parentClass [ Symbol . metadata || Symbol . for ( "Symbol.metadata" ) ] ;
}
var metadata = Object . create ( parentMetadata === void 0 ? null : parentMetadata ) ;
var e = applyMemberDecs ( targetClass , memberDecs , metadata ) ;
if ( ! classDecs . length ) defineMetadata ( targetClass , metadata ) ;
2023-04-20 11:26:34 +03:00
return {
2023-10-16 23:38:53 +03:00
e : e ,
2023-04-20 11:26:34 +03:00
// Lazily apply class decorations so that member init locals can be properly bound.
get c ( ) {
2023-10-16 23:38:53 +03:00
return applyClassDecs ( targetClass , classDecs , metadata ) ;
2023-04-20 11:26:34 +03:00
}
} ;
} ;
2023-10-16 23:38:53 +03:00
return _apply _decs _2203 _r ( targetClass , memberDecs , classDecs , parentClass ) ;
2023-04-20 11:26:34 +03:00
}
export { _apply _decs _2203 _r as _ } ;