@@ -266,6 +266,7 @@ function node_loader_trampoline_discover_function(func) {
266
266
if ( node_loader_trampoline_is_callable ( func ) ) {
267
267
// Espree can't parse native code functions so we can do a workaround
268
268
const str = func . toString ( ) . replace ( '{ [native code] }' , '{}' ) ;
269
+
269
270
const ast = espree . parse ( `(${ str } )` , {
270
271
ecmaVersion : 14
271
272
} ) ;
@@ -276,7 +277,7 @@ function node_loader_trampoline_discover_function(func) {
276
277
if ( node_loader_trampoline_is_valid_symbol ( node ) ) {
277
278
const args = node_loader_trampoline_discover_arguments ( node ) ;
278
279
const discover = {
279
- ptr : func ,
280
+ func,
280
281
signature : args ,
281
282
async : node . async ,
282
283
} ;
@@ -293,6 +294,94 @@ function node_loader_trampoline_discover_function(func) {
293
294
}
294
295
}
295
296
297
+ function node_loader_trampoline_discover_klass_attributes ( node ) {
298
+ /* We only discover attributes defined/declared in the body of the constructor.
299
+ * Attributes defined in other blocks within the constructor might not exist in
300
+ * an instance of the class */
301
+ let attributes = [ ] ;
302
+ for ( let i = 0 ; i < node . length ; i ++ ) {
303
+ if ( node [ i ] . kind === 'constructor' )
304
+ {
305
+ for ( let exp of node [ i ] . value . body . body )
306
+ {
307
+ if ( exp . type === 'ExpressionStatement' && exp . expression . type === 'AssignmentExpression' ) {
308
+ let left = exp . expression . left ;
309
+
310
+ if ( left . type == 'MemberExpression' && ( left . object && left . object . type === 'ThisExpression' ) ) {
311
+ attributes . push ( left . property && left . property . name ) ;
312
+ }
313
+ }
314
+ }
315
+ }
316
+ }
317
+
318
+ return attributes ;
319
+ }
320
+
321
+ function node_loader_trampoline_discover_klass_methods ( node , str ) {
322
+ const ret = { } ;
323
+ for ( let method of node ) {
324
+ if ( method . type === 'MethodDefinition' ) {
325
+ let method_name = method . key . name ;
326
+ if ( method . kind === 'constructor' ) {
327
+ method_name = 'klass_' + method_name ;
328
+ }
329
+ ret [ method_name ] = {
330
+ name : method . key . name ,
331
+ signature : node_loader_trampoline_discover_arguments ( method . value )
332
+ }
333
+
334
+ if ( method . kind === 'method' && str . substring ( method . start - 1 , method . start + 5 ) === 'static' ) {
335
+ ret [ method_name ] . static = true ;
336
+ }
337
+ }
338
+ }
339
+
340
+ return ret
341
+ }
342
+
343
+ function node_loader_trampoline_discover_klass ( klass ) {
344
+ try {
345
+ if ( node_loader_trampoline_is_callable ( klass ) ) {
346
+ const str = klass . toString ( ) ;
347
+ const ast = espree . parse ( `(${ str } )` , {
348
+ ecmaVersion : 14
349
+ } ) ;
350
+
351
+ const node = ( ast . body [ 0 ] . type === 'ExpressionStatement' ) && ast . body [ 0 ] . expression ;
352
+ if ( node . type === 'ClassExpression' ) {
353
+ const methods = node_loader_trampoline_discover_klass_methods ( node . body . body , str )
354
+ const discover = {
355
+ klass,
356
+ methods
357
+ } ;
358
+
359
+ if ( node . id && node . id . name ) {
360
+ discover [ 'name' ] = node . id . name ;
361
+ }
362
+
363
+ if ( methods . klass_constructor ) {
364
+ discover [ 'attributes' ] = node_loader_trampoline_discover_klass_attributes ( node . body . body ) ;
365
+ }
366
+
367
+ return discover ;
368
+ }
369
+ }
370
+ } catch ( ex ) {
371
+ console . log ( `Exception while parsing '${ klass } ' in node_loader_trampoline_discover_klass` , ex ) ;
372
+ }
373
+ }
374
+
375
+ function node_loader_trampoline_discover_object ( obj ) {
376
+ if ( typeof obj === 'object' ) {
377
+ const constructor = ( obj && obj . constructor ) && obj . constructor . name
378
+ if ( constructor !== 'Object' && constructor !== 'Array' )
379
+ return {
380
+ obj
381
+ } ;
382
+ }
383
+ }
384
+
296
385
function node_loader_trampoline_discover ( handle ) {
297
386
const discover = { } ;
298
387
@@ -305,8 +394,9 @@ function node_loader_trampoline_discover(handle) {
305
394
306
395
for ( let j = 0 ; j < keys . length ; ++ j ) {
307
396
const key = keys [ j ] ;
308
- const func = exports [ key ] ;
309
- const descriptor = node_loader_trampoline_discover_function ( func ) ;
397
+ const value = exports [ key ] ;
398
+ const descriptor = node_loader_trampoline_discover_function ( value )
399
+ || node_loader_trampoline_discover_klass ( value ) || node_loader_trampoline_discover_object ( value ) ;
310
400
311
401
if ( descriptor !== undefined ) {
312
402
discover [ key ] = descriptor ;
@@ -411,6 +501,8 @@ module.exports = ((impl, ptr) => {
411
501
'clear' : node_loader_trampoline_clear ,
412
502
'discover' : node_loader_trampoline_discover ,
413
503
'discover_function' : node_loader_trampoline_discover_function ,
504
+ 'discover_klass' : node_loader_trampoline_discover_klass ,
505
+ 'discover_object' : node_loader_trampoline_discover_object ,
414
506
'test' : node_loader_trampoline_test ,
415
507
'await_function' : node_loader_trampoline_await_function ( trampoline ) ,
416
508
'await_future' : node_loader_trampoline_await_future ( trampoline ) ,
0 commit comments