Распознавание функций JavaScript с помощью GJS (Spidermonkey 1.7)
Я играю с Christian Hergert GtkBuilder + встроенный JavaScript и пишу плагин Glade для редактирования кода JavaScript. Вот скриншот:
http://sanaviron.googlecode.com/files/scr.png
Я хочу узнать функции JavaScript с помощью GJS (Spidermonker 1.7 GObject привязка). Основная идея состоит в том, чтобы отделить скрипт от функций для создания редактора исходного кода, такого как (например, Visual Basic):
http://sanaviron.googlecode.com/files/scr2.png
Я не хочу оценивать сценарий и попробуйте следующий тестовый код:
#include <gjs/gjs-module.h>
#include <gjs/gjs.h>
#include <string.h>
#include <stdio.h>
const char *script =
"const Gtk = imports.gi.Gtk;"
""
"function onClicked(widget, data) {"
" let w = new Gtk.Window();"
" w.set_default_size(320, 240);"
" let l = new Gtk.Label();"
" l.set_text('You clicked on ' + widget.get_label());"
" w.add(l);"
" w.show_all();"
"}"
""
"var onQuit = function() {"
" Gtk.main_quit();"
"}";
int
main (int argc, char *artv[])
{
GjsContext *context;
JSContext *native;
JSScript *compiled;
JSObject *object;
JSObject *global;
JSObject *callable = NULL;
JSIdArray *array;
JSBool status;
jsval val = { 0 };
int i;
context = gjs_context_new();
native = gjs_context_get_native_context(context);
JS_BeginRequest(native);
global = gjs_get_import_global(native);
compiled = JS_CompileScript(native, global, script, strlen(script), "__test__", 0);
if (compiled == NULL)
{
printf("error\n");
}
object = JS_GetGlobalFromScript(compiled);
array = JS_Enumerate(native, global);
for (i = 0; i < JS_IdArrayLength(native, array); i++)
{
status = JS_GetPropertyById(native, object, JS_IdArrayGet(native, array, i), &val);
callable = JSVAL_TO_OBJECT(val);
if (JS_ObjectIsFunction(native, callable))
{
JSString *str = JS_ValueToString(native, val);
printf("%s\n", JS_EncodeString(native, str));
printf("%d, %p\n", status, callable);
}
}
JS_EndRequest(native);
return 0;
}
Мне нужно получить OnClicked и OnClick, но я получаю:
function log() {
[native code]
}
1, 0xb4c186c0
function logError() {
[native code]
}
1, 0xb4c186e0
function print() {
[native code]
}
1, 0xb4c18700
function printerr() {
[native code]
}
1, 0xb4c18720
Эти функции внутренне созданы GJS, но мои функции? Что не так? Возможно ли получить функции с помощью SpiderMonkey 1.7? Если это возможно, как я могу получить тело (код) каждой функции? Мне нужно реализовать свой собственный анализатор JS?
Заранее спасибо.
Наконец, я разрешаю это, используя Reflect от Spidermonkey:
const Gio = imports.gi.Gio;
const Mainloop = imports.mainloop;
function load (filename)
{
var file = Gio.file_new_for_path(filename);
var contents;
file.load_contents_async(null, function(file, result)
{
try
{
contents = file.load_contents_finish(result)[1];
}
catch (exception)
{
printerr(exception.message);
Mainloop.quit('');
return null;
}
Mainloop.quit('');
return null; /* to avoid warning */
});
Mainloop.run('');
return contents;
}
function print_function_info (node)
{
print('function ' + node.id.name + ' at ' +
node.loc.start.line + ':' + node.loc.start.column + '-' +
node.loc.end.line + ':' + node.loc.end.column);
}
function parse_source (source)
{
var reflect = Reflect.parse(load(ARGV[0]));
for (var element in reflect.body)
{
var node = reflect.body[element];
if (node.type == 'VariableDeclaration')
{
for (element in node.declarations)
{
var declaration = node.declarations[element];
if (declaration.init.type == 'FunctionExpression')
{
print_function_info(declaration);
}
}
}
else if (node.type == 'FunctionDeclaration')
{
print_function_info(node);
}
}
}
function parse_file (file)
{
parse_source(load(file));
}
function main ()
{
if (ARGV.length != 1)
{
printerr("Usage: introspect.js filename");
}
else
{
parse_file(ARGV[0]);
}
}
main ();