Skip to content

Commit

Permalink
add base support for exporting objects and classes in node_loader
Browse files Browse the repository at this point in the history
  • Loading branch information
rxbryan committed Jan 28, 2023
1 parent 011617e commit 2678438
Show file tree
Hide file tree
Showing 2 changed files with 434 additions and 335 deletions.
95 changes: 92 additions & 3 deletions source/loaders/node_loader/bootstrap/lib/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ function node_loader_trampoline_discover_function(func) {
if (node_loader_trampoline_is_callable(func)) {
// Espree can't parse native code functions so we can do a workaround
const str = func.toString().replace('{ [native code] }', '{}');

const ast = espree.parse(`(${str})`, {
ecmaVersion: 14
});
Expand All @@ -276,7 +277,7 @@ function node_loader_trampoline_discover_function(func) {
if (node_loader_trampoline_is_valid_symbol(node)) {
const args = node_loader_trampoline_discover_arguments(node);
const discover = {
ptr: func,
func,
signature: args,
async: node.async,
};
Expand All @@ -293,6 +294,91 @@ function node_loader_trampoline_discover_function(func) {
}
}

function node_loader_trampoline_discover_klass_attributes(node) {
let attributes = [];
for (let i = 0; i < node.length; i++) {
if (node[i].kind === 'constructor')
{
for (let exp of node[i].value.body.body)
{
if (exp.type === 'ExpressionStatement' && exp.expression.type === 'AssignmentExpression') {
let left = exp.expression.left;

if (left.type == 'MemberExpression' && (left.object && left.object.type === 'ThisExpression')) {
attributes.push(left.property && left.property.name);
}
}
}
}
}

return attributes;
}

function node_loader_trampoline_discover_klass_methods(node, str) {
const ret = {};
for (let method of node) {
if (method.type === 'MethodDefinition') {
let method_name = method.key.name;
if (method.kind === 'constructor') {
method_name = 'klass_' + method_name;
}
ret[method_name] = {
name: method.key.name,
signature: node_loader_trampoline_discover_arguments(method.value)
}

if (method.kind === 'method' && str.substring(method.start-1, method.start+5) === 'static') {
ret[method_name].static = true;
}
}
}

return ret
}

function node_loader_trampoline_discover_klass(klass) {
try {
if (node_loader_trampoline_is_callable(klass)) {
const str = klass.toString();
const ast = espree.parse(`(${str})`, {
ecmaVersion: 14
});

const node = (ast.body[0].type === 'ExpressionStatement') && ast.body[0].expression;
if (node.type === 'ClassExpression') {
const methods = node_loader_trampoline_discover_klass_methods(node.body.body, str)
const discover = {
klass,
methods
};

if (node.id && node.id.name) {
discover['name'] = node.id.name;
}

if (methods.klass_constructor) {
discover['attributes'] = node_loader_trampoline_discover_klass_attributes(node.body.body);
}

return discover;
}
}
} catch (ex) {
console.log(`Exception while parsing '${klass}' in node_loader_trampoline_discover_klass`, ex);
}
}

function node_loader_trampoline_discover_object(obj) {
if (typeof obj === 'object') {
const constructor = (obj && obj.constructor) && obj.constructor.name
if (constructor !== 'Object' && constructor !== 'Array')
return {
obj
};
}
}

function node_loader_trampoline_discover(handle) {
const discover = {};

Expand All @@ -305,8 +391,9 @@ function node_loader_trampoline_discover(handle) {

for (let j = 0; j < keys.length; ++j) {
const key = keys[j];
const func = exports[key];
const descriptor = node_loader_trampoline_discover_function(func);
const value = exports[key];
const descriptor = node_loader_trampoline_discover_function(value)
|| node_loader_trampoline_discover_klass(value) || node_loader_trampoline_discover_object(value);

if (descriptor !== undefined) {
discover[key] = descriptor;
Expand Down Expand Up @@ -411,6 +498,8 @@ module.exports = ((impl, ptr) => {
'clear': node_loader_trampoline_clear,
'discover': node_loader_trampoline_discover,
'discover_function': node_loader_trampoline_discover_function,
'discover_klass': node_loader_trampoline_discover_klass,
'discover_object': node_loader_trampoline_discover_object,
'test': node_loader_trampoline_test,
'await_function': node_loader_trampoline_await_function(trampoline),
'await_future': node_loader_trampoline_await_future(trampoline),
Expand Down
Loading

0 comments on commit 2678438

Please sign in to comment.