Skip to content

Commit 2843205

Browse files
committed
add base support for exporting objects and classes in node_loader
1 parent bb79a77 commit 2843205

File tree

2 files changed

+263
-161
lines changed

2 files changed

+263
-161
lines changed

source/loaders/node_loader/bootstrap/lib/bootstrap.js

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ function node_loader_trampoline_discover_function(func) {
266266
if (node_loader_trampoline_is_callable(func)) {
267267
// Espree can't parse native code functions so we can do a workaround
268268
const str = func.toString().replace('{ [native code] }', '{}');
269+
269270
const ast = espree.parse(`(${str})`, {
270271
ecmaVersion: 14
271272
});
@@ -276,7 +277,7 @@ function node_loader_trampoline_discover_function(func) {
276277
if (node_loader_trampoline_is_valid_symbol(node)) {
277278
const args = node_loader_trampoline_discover_arguments(node);
278279
const discover = {
279-
ptr: func,
280+
func,
280281
signature: args,
281282
async: node.async,
282283
};
@@ -293,6 +294,94 @@ function node_loader_trampoline_discover_function(func) {
293294
}
294295
}
295296

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+
296385
function node_loader_trampoline_discover(handle) {
297386
const discover = {};
298387

@@ -305,8 +394,9 @@ function node_loader_trampoline_discover(handle) {
305394

306395
for (let j = 0; j < keys.length; ++j) {
307396
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);
310400

311401
if (descriptor !== undefined) {
312402
discover[key] = descriptor;
@@ -411,6 +501,8 @@ module.exports = ((impl, ptr) => {
411501
'clear': node_loader_trampoline_clear,
412502
'discover': node_loader_trampoline_discover,
413503
'discover_function': node_loader_trampoline_discover_function,
504+
'discover_klass': node_loader_trampoline_discover_klass,
505+
'discover_object': node_loader_trampoline_discover_object,
414506
'test': node_loader_trampoline_test,
415507
'await_function': node_loader_trampoline_await_function(trampoline),
416508
'await_future': node_loader_trampoline_await_future(trampoline),

0 commit comments

Comments
 (0)