2023-04-04 06:05:47 +03:00
import { _to _array } from "./_to_array.js" ;
import { _to _property _key } from "./_to_property_key.js" ;
import { _type _of } from "./_type_of.js" ;
export function _decorate ( decorators , factory , superClass ) {
2023-03-31 09:15:21 +03:00
var r = factory ( function initialize ( O ) {
_initializeInstanceElements ( O , decorated . elements ) ;
} , superClass ) ;
var decorated = _decorateClass ( _coalesceClassElements ( r . d . map ( _createElementDescriptor ) ) , decorators ) ;
_initializeClassElements ( r . F , decorated . elements ) ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return _runClassFinishers ( r . F , decorated . finishers ) ;
2021-12-05 09:46:09 +03:00
}
function _createElementDescriptor ( def ) {
2023-03-31 09:15:21 +03:00
var key = _to _property _key ( def . key ) ;
var descriptor ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
if ( def . kind === "method" ) {
descriptor = { value : def . value , writable : true , configurable : true , enumerable : false } ;
Object . defineProperty ( def . value , "name" , { value : _type _of ( key ) === "symbol" ? "" : key , configurable : true } ) ;
2023-04-04 06:05:47 +03:00
} else if ( def . kind === "get" ) descriptor = { get : def . value , configurable : true , enumerable : false } ;
else if ( def . kind === "set" ) descriptor = { set : def . value , configurable : true , enumerable : false } ;
else if ( def . kind === "field" ) descriptor = { configurable : true , writable : true , enumerable : true } ;
var element = { kind : def . kind === "field" ? "field" : "method" , key : key , placement : def . static ? "static" : def . kind === "field" ? "own" : "prototype" , descriptor : descriptor } ;
2023-03-31 09:15:21 +03:00
if ( def . decorators ) element . decorators = def . decorators ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
if ( def . kind === "field" ) element . initializer = def . value ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return element ;
2021-12-05 09:46:09 +03:00
}
function _coalesceGetterSetter ( element , other ) {
2023-04-04 06:05:47 +03:00
if ( element . descriptor . get !== undefined ) other . descriptor . get = element . descriptor . get ;
else other . descriptor . set = element . descriptor . set ;
2021-12-05 09:46:09 +03:00
}
function _coalesceClassElements ( elements ) {
2023-03-31 09:15:21 +03:00
var newElements = [ ] ;
var isSameElement = function isSameElement ( other ) {
return other . kind === "method" && other . key === element . key && other . placement === element . placement ;
} ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
for ( var i = 0 ; i < elements . length ; i ++ ) {
var element = elements [ i ] ;
var other ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
if ( element . kind === "method" && ( other = newElements . find ( isSameElement ) ) ) {
if ( _isDataDescriptor ( element . descriptor ) || _isDataDescriptor ( other . descriptor ) ) {
if ( _hasDecorators ( element ) || _hasDecorators ( other ) ) {
throw new ReferenceError ( "Duplicated methods (" + element . key + ") can't be decorated." ) ;
}
other . descriptor = element . descriptor ;
} else {
if ( _hasDecorators ( element ) ) {
if ( _hasDecorators ( other ) ) {
2023-04-04 06:05:47 +03:00
throw new ReferenceError ( "Decorators can't be placed on different accessors with for " + "the same property (" + element . key + ")." ) ;
2023-03-31 09:15:21 +03:00
}
other . decorators = element . decorators ;
}
_coalesceGetterSetter ( element , other ) ;
}
} else {
newElements . push ( element ) ;
2021-12-05 09:46:09 +03:00
}
}
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return newElements ;
2021-12-05 09:46:09 +03:00
}
function _hasDecorators ( element ) {
2023-03-31 09:15:21 +03:00
return element . decorators && element . decorators . length ;
2021-12-05 09:46:09 +03:00
}
function _isDataDescriptor ( desc ) {
2023-03-31 09:15:21 +03:00
return desc !== undefined && ! ( desc . value === undefined && desc . writable === undefined ) ;
2021-12-05 09:46:09 +03:00
}
function _initializeClassElements ( F , elements ) {
2023-03-31 09:15:21 +03:00
var proto = F . prototype ;
[ "method" , "field" ] . forEach ( function ( kind ) {
elements . forEach ( function ( element ) {
var placement = element . placement ;
if ( element . kind === kind && ( placement === "static" || placement === "prototype" ) ) {
var receiver = placement === "static" ? F : proto ;
_defineClassElement ( receiver , element ) ;
}
} ) ;
2021-12-05 09:46:09 +03:00
} ) ;
}
function _initializeInstanceElements ( O , elements ) {
2023-03-31 09:15:21 +03:00
[ "method" , "field" ] . forEach ( function ( kind ) {
elements . forEach ( function ( element ) {
2023-04-04 06:05:47 +03:00
if ( element . kind === kind && element . placement === "own" ) _defineClassElement ( O , element ) ;
2023-03-31 09:15:21 +03:00
} ) ;
2021-12-05 09:46:09 +03:00
} ) ;
}
function _defineClassElement ( receiver , element ) {
2023-03-31 09:15:21 +03:00
var descriptor = element . descriptor ;
if ( element . kind === "field" ) {
var initializer = element . initializer ;
2023-04-04 06:05:47 +03:00
descriptor = { enumerable : descriptor . enumerable , writable : descriptor . writable , configurable : descriptor . configurable , value : initializer === void 0 ? void 0 : initializer . call ( receiver ) } ;
2023-03-31 09:15:21 +03:00
}
Object . defineProperty ( receiver , element . key , descriptor ) ;
2021-12-05 09:46:09 +03:00
}
function _decorateClass ( elements , decorators ) {
2023-03-31 09:15:21 +03:00
var newElements = [ ] ;
var finishers = [ ] ;
var placements = { static : [ ] , prototype : [ ] , own : [ ] } ;
elements . forEach ( function ( element ) {
_addElementPlacement ( element , placements ) ;
} ) ;
elements . forEach ( function ( element ) {
if ( ! _hasDecorators ( element ) ) return newElements . push ( element ) ;
var elementFinishersExtras = _decorateElement ( element , placements ) ;
newElements . push ( elementFinishersExtras . element ) ;
newElements . push . apply ( newElements , elementFinishersExtras . extras ) ;
finishers . push . apply ( finishers , elementFinishersExtras . finishers ) ;
} ) ;
2023-04-04 06:05:47 +03:00
if ( ! decorators ) return { elements : newElements , finishers : finishers } ;
2023-03-31 09:15:21 +03:00
var result = _decorateConstructor ( newElements , decorators ) ;
finishers . push . apply ( finishers , result . finishers ) ;
result . finishers = finishers ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return result ;
2021-12-05 09:46:09 +03:00
}
function _addElementPlacement ( element , placements , silent ) {
var keys = placements [ element . placement ] ;
2023-04-04 06:05:47 +03:00
if ( ! silent && keys . indexOf ( element . key ) !== - 1 ) throw new TypeError ( "Duplicated element (" + element . key + ")" ) ;
2023-03-31 09:15:21 +03:00
keys . push ( element . key ) ;
}
function _decorateElement ( element , placements ) {
var extras = [ ] ;
var finishers = [ ] ;
for ( var decorators = element . decorators , i = decorators . length - 1 ; i >= 0 ; i -- ) {
var keys = placements [ element . placement ] ;
keys . splice ( keys . indexOf ( element . key ) , 1 ) ;
var elementObject = _fromElementDescriptor ( element ) ;
var elementFinisherExtras = _toElementFinisherExtras ( ( 0 , decorators [ i ] ) ( elementObject ) || elementObject ) ;
element = elementFinisherExtras . element ;
_addElementPlacement ( element , placements ) ;
2023-04-04 06:05:47 +03:00
if ( elementFinisherExtras . finisher ) finishers . push ( elementFinisherExtras . finisher ) ;
2023-03-31 09:15:21 +03:00
var newExtras = elementFinisherExtras . extras ;
if ( newExtras ) {
2023-04-04 06:05:47 +03:00
for ( var j = 0 ; j < newExtras . length ; j ++ ) _addElementPlacement ( newExtras [ j ] , placements ) ;
2023-03-31 09:15:21 +03:00
extras . push . apply ( extras , newExtras ) ;
}
2021-12-05 09:46:09 +03:00
}
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return { element : element , finishers : finishers , extras : extras } ;
2021-12-05 09:46:09 +03:00
}
function _decorateConstructor ( elements , decorators ) {
2023-03-31 09:15:21 +03:00
var finishers = [ ] ;
for ( var i = decorators . length - 1 ; i >= 0 ; i -- ) {
var obj = _fromClassDescriptor ( elements ) ;
var elementsAndFinisher = _toClassDescriptor ( ( 0 , decorators [ i ] ) ( obj ) || obj ) ;
2023-04-04 06:05:47 +03:00
if ( elementsAndFinisher . finisher !== undefined ) finishers . push ( elementsAndFinisher . finisher ) ;
2023-03-31 09:15:21 +03:00
if ( elementsAndFinisher . elements !== undefined ) {
elements = elementsAndFinisher . elements ;
for ( var j = 0 ; j < elements . length - 1 ; j ++ ) {
for ( var k = j + 1 ; k < elements . length ; k ++ ) {
if ( elements [ j ] . key === elements [ k ] . key && elements [ j ] . placement === elements [ k ] . placement ) {
throw new TypeError ( "Duplicated element (" + elements [ j ] . key + ")" ) ;
}
}
}
2021-12-05 09:46:09 +03:00
}
}
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return { elements : elements , finishers : finishers } ;
2021-12-05 09:46:09 +03:00
}
function _fromElementDescriptor ( element ) {
2023-03-31 09:15:21 +03:00
var obj = { kind : element . kind , key : element . key , placement : element . placement , descriptor : element . descriptor } ;
var desc = { value : "Descriptor" , configurable : true } ;
Object . defineProperty ( obj , Symbol . toStringTag , desc ) ;
if ( element . kind === "field" ) obj . initializer = element . initializer ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return obj ;
2021-12-05 09:46:09 +03:00
}
function _toElementDescriptors ( elementObjects ) {
2023-03-31 09:15:21 +03:00
if ( elementObjects === undefined ) return ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return _to _array ( elementObjects ) . map ( function ( elementObject ) {
var element = _toElementDescriptor ( elementObject ) ;
_disallowProperty ( elementObject , "finisher" , "An element descriptor" ) ;
_disallowProperty ( elementObject , "extras" , "An element descriptor" ) ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return element ;
} ) ;
2021-12-05 09:46:09 +03:00
}
function _toElementDescriptor ( elementObject ) {
2023-03-31 09:15:21 +03:00
var kind = String ( elementObject . kind ) ;
if ( kind !== "method" && kind !== "field" ) {
2023-04-04 06:05:47 +03:00
throw new TypeError ( "An element descriptor's .kind property must be either \"method\" or" + " \"field\", but a decorator created an element descriptor with" + " .kind \"" + kind + "\"" ) ;
2023-03-31 09:15:21 +03:00
}
var key = _to _property _key ( elementObject . key ) ;
var placement = String ( elementObject . placement ) ;
if ( placement !== "static" && placement !== "prototype" && placement !== "own" ) {
throw new TypeError (
"An element descriptor's .placement property must be one of \"static\","
2023-04-04 06:05:47 +03:00
+ " \"prototype\" or \"own\", but a decorator created an element descriptor"
+ " with .placement \""
+ placement
+ "\""
2023-03-31 09:15:21 +03:00
) ;
}
var descriptor = elementObject . descriptor ;
_disallowProperty ( elementObject , "elements" , "An element descriptor" ) ;
var element = { kind : kind , key : key , placement : placement , descriptor : Object . assign ( { } , descriptor ) } ;
2023-04-04 06:05:47 +03:00
if ( kind !== "field" ) _disallowProperty ( elementObject , "initializer" , "A method descriptor" ) ;
else {
2023-03-31 09:15:21 +03:00
_disallowProperty ( descriptor , "get" , "The property descriptor of a field descriptor" ) ;
_disallowProperty ( descriptor , "set" , "The property descriptor of a field descriptor" ) ;
_disallowProperty ( descriptor , "value" , "The property descriptor of a field descriptor" ) ;
element . initializer = elementObject . initializer ;
}
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return element ;
2021-12-05 09:46:09 +03:00
}
function _toElementFinisherExtras ( elementObject ) {
2023-03-31 09:15:21 +03:00
var element = _toElementDescriptor ( elementObject ) ;
var finisher = _optionalCallableProperty ( elementObject , "finisher" ) ;
var extras = _toElementDescriptors ( elementObject . extras ) ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return { element : element , finisher : finisher , extras : extras } ;
2021-12-05 09:46:09 +03:00
}
function _fromClassDescriptor ( elements ) {
2023-03-31 09:15:21 +03:00
var obj = { kind : "class" , elements : elements . map ( _fromElementDescriptor ) } ;
var desc = { value : "Descriptor" , configurable : true } ;
Object . defineProperty ( obj , Symbol . toStringTag , desc ) ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return obj ;
2021-12-05 09:46:09 +03:00
}
function _toClassDescriptor ( obj ) {
2023-03-31 09:15:21 +03:00
var kind = String ( obj . kind ) ;
if ( kind !== "class" ) {
2023-04-04 06:05:47 +03:00
throw new TypeError ( "A class descriptor's .kind property must be \"class\", but a decorator" + " created a class descriptor with .kind \"" + kind + "\"" ) ;
2023-03-31 09:15:21 +03:00
}
_disallowProperty ( obj , "key" , "A class descriptor" ) ;
_disallowProperty ( obj , "placement" , "A class descriptor" ) ;
_disallowProperty ( obj , "descriptor" , "A class descriptor" ) ;
_disallowProperty ( obj , "initializer" , "A class descriptor" ) ;
_disallowProperty ( obj , "extras" , "A class descriptor" ) ;
var finisher = _optionalCallableProperty ( obj , "finisher" ) ;
var elements = _toElementDescriptors ( obj . elements ) ;
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return { elements : elements , finisher : finisher } ;
2021-12-05 09:46:09 +03:00
}
function _disallowProperty ( obj , name , objectType ) {
2023-04-04 06:05:47 +03:00
if ( obj [ name ] !== undefined ) throw new TypeError ( objectType + " can't have a ." + name + " property." ) ;
2021-12-05 09:46:09 +03:00
}
function _optionalCallableProperty ( obj , name ) {
2023-03-31 09:15:21 +03:00
var value = obj [ name ] ;
if ( value !== undefined && typeof value !== "function" ) {
throw new TypeError ( "Expected '" + name + "' to be a function" ) ;
}
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return value ;
2021-12-05 09:46:09 +03:00
}
function _runClassFinishers ( constructor , finishers ) {
2023-03-31 09:15:21 +03:00
for ( var i = 0 ; i < finishers . length ; i ++ ) {
var newConstructor = ( 0 , finishers [ i ] ) ( constructor ) ;
if ( newConstructor !== undefined ) {
2023-04-04 06:05:47 +03:00
if ( typeof newConstructor !== "function" ) throw new TypeError ( "Finishers must return a constructor." ) ;
2023-03-31 09:15:21 +03:00
constructor = newConstructor ;
}
2021-12-05 09:46:09 +03:00
}
2023-04-04 06:05:47 +03:00
2023-03-31 09:15:21 +03:00
return constructor ;
2021-12-05 09:46:09 +03:00
}
2023-04-04 06:05:47 +03:00
export { _decorate as _ } ;