import { Node , ESTree } from "../../Node" ; import { BaseClosure , } from '../../Closure' ; import { Messages } from '../../Message' ; import { Interpreter } from '../../../interpreter/main' ; import { createScope } from '../../Scope' ; import { Return } from '../../TokenClass' ; import { defineFunctionName } from '../../../util' ; import { isSymbol , storeKey } from "../../Symbols" ; let extendStatics = function ( d , b ) { extendStatics = Object . setPrototypeOf || ( { __proto__ : [ ] } instanceof Array && function ( d , b ) { d . __proto__ = b ; } ) || function ( d , b ) { for ( var p in b ) if ( b . hasOwnProperty ( p ) ) d [ p ] = b [ p ] ; } ; return extendStatics ( d , b ) ; } ; function __extend ( child , father ) { extendStatics ( child , father ) ; function __ ( ) { this . constructor = father ; } child . prototype = father === null ? Object . create ( father ) : ( __ . prototype = father . prototype , new __ ( ) ) ; } ; type seeyouagain = { name : { computed : boolean ; value : BaseClosure | string ; } ; value : BaseClosure ; } ; export function classExpressionHandler ( this , node ) { const className = node . id ? node . id . name : "" ; let classDecl = { static : [ ] , fieldsArrow : [ ] , fieldsProperty : [ ] , method : [ ] , } ; let superClass = node . superClass ? this . createClosure ( node . superClass ) : null ; node . body . body . forEach ( item => { if ( item . type === 'MethodDefinition' ) { if ( item . kind === 'constructor' ) { classDecl . cons = this . createClosure ( item . value ) ; } else if ( item . kind === 'method' ) { classDecl [ item . static ? 'static' : 'method' ] . push ( { name : { computed : item . computed , value : item . computed ? this . createClosure ( item . key ) : item . key . name } , value : this . createClosure ( item . value ) } ) ; } else if ( item . kind === 'get' || item . kind === 'set' ) { throw this . createInternalThrowError ( Messages . NormalError , 'not support getter and setter in class' , node ) ; } } else if ( item . type === 'FieldDefinition' ) { if ( item . static ) { classDecl . static . push ( { name : { computed : item . computed , value : item . computed ? this . createClosure ( item . key ) : item . key . name } , value : this . createClosure ( item . value ) } ) ; } else { let t = item . value . type == 'ArrowFunctionExpression' ? 'fieldsArrow' : 'fieldsProperty' ; classDecl [ t ] . push ( { name : { computed : item . computed , value : item . computed ? this . createClosure ( item . key ) : item . key . name } , value : this . createClosure ( item . value ) } ) ; } } else { throw this . createInternalThrowError ( Messages . NormalError , 'unknown class body type ' + item . type , node . body ) ; } } ) ; return ( ) => { let self = this ; let _super = superClass ? superClass ( ) : null ; let cons ; if ( _super && classDecl . cons ) { let newScope = createScope ( this . getCurrentScope ( ) , `FScope(constructor)` , 'block' ) ; newScope . lexDeclared = { super : { kind : 'const' , init : true } } ; newScope . data [ 'super' ] = _super ; let prevScope = this . entryBlockScope ( newScope ) ; cons = classDecl . cons ( ) ; this . setCurrentScope ( prevScope ) ; } else { cons = classDecl . cons ? classDecl . cons ( ) : null ; } let func = function ( ) { let _this = this ; if ( superClass && ! cons ) { _this = _super . call ( _this ) || _this ; } classDecl . fieldsArrow . forEach ( item => { let prev = self . getCurrentContext ( ) ; self . setCurrentContext ( _this ) ; let fn = item . value ( ) ; self . setCurrentContext ( prev ) ; setKeyVal ( _this , item , fn ) ; } ) ; classDecl . fieldsProperty . forEach ( item => { setKeyVal ( _this , item , item . value ( ) ) ; } ) ; if ( cons ) { cons . apply ( _this , arguments ) ; } return _this ; } ; superClass && __extend ( func , _super ) ; classDecl . method . forEach ( item => { func . prototype [ item . name . computed ? ( item . name . value as BaseClosure ) ( ) : item . name . value ] = item . value ( ) ; } ) ; classDecl . static . forEach ( item => { func [ item . name . computed ? ( item . name . value as BaseClosure ) ( ) : item . name . value ] = item . value ( ) ; } ) ; if ( className ) { Object . defineProperty ( func , "name" , { value : className , writable : false , enumerable : false , configurable : true , } ) ; } return func ; } ; } function setKeyVal ( _this , item , val ) { let keyval ; let sbl = false ; if ( item . name . computed ) { let t = ( item . name . value as BaseClosure ) ( ) ; if ( isSymbol ( t ) ) { sbl = true ; keyval = storeKey ( t ) ; } else { keyval = t ; } } else { keyval = item . name . value ; } if ( sbl ) { Object . defineProperty ( _this , keyval , { value : val , writable : true , enumerable : false , configurable : true , } ) ; } else { _this [ keyval ] = val ; } }