[gjs/wip/coverage-2: 9/10] ff5
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/coverage-2: 9/10] ff5
- Date: Wed, 15 Jan 2014 23:49:20 +0000 (UTC)
commit 6e48143bb5eded789d6a50bf490ad7427152dcff
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Wed Jan 15 18:16:53 2014 -0500
ff5
gjs/console.cpp | 3 +-
gjs/coverage.cpp | 110 ++++--------
gjs/coverage.h | 4 +-
gjs/reflected-script.cpp | 344 ++++++++++++------------------------
gjs/reflected-script.h | 10 +-
installed-tests/gjs-unit.cpp | 3 +-
modules/infoReflect.js | 13 ++-
test/gjs-test-coverage.cpp | 15 +--
test/gjs-test-debug-hooks.cpp | 5 +-
test/gjs-test-reflected-script.cpp | 29 ++--
10 files changed, 187 insertions(+), 349 deletions(-)
---
diff --git a/gjs/console.cpp b/gjs/console.cpp
index d25d890..85d6161 100644
--- a/gjs/console.cpp
+++ b/gjs/console.cpp
@@ -143,8 +143,7 @@ main(int argc, char **argv)
if (!coverage_output_path)
g_error("--coverage-output-path is required when taking coverage statistics");
- coverage = gjs_coverage_new(gjs_context_get_debug_hooks(js_context),
- (const gchar **) coverage_paths);
+ coverage = gjs_coverage_new(js_context, (const gchar **) coverage_paths);
}
/* prepare command line arguments */
diff --git a/gjs/coverage.cpp b/gjs/coverage.cpp
index ad4eacf..6ef4cbf 100644
--- a/gjs/coverage.cpp
+++ b/gjs/coverage.cpp
@@ -31,23 +31,10 @@
typedef struct _GjsCoverageBranchData GjsCoverageBranchData;
struct _GjsCoveragePrivate {
+ GjsContext *context;
GHashTable *file_statistics;
- GjsDebugHooks *debug_hooks;
gchar **covered_paths;
- /* A separate context where reflection is performed. We don't
- * want to use the main context because we don't want to
- * modify its state while it is being debugged.
- *
- * A single context is shared across all reflections because
- * the reflection functions are effectively const.
- *
- * This is created on-demand when debugging is enabled. GjsContext
- * creates an instance of us by default so we obviously don't want
- * to recurse into creating an instance of GjsContext by default.
- */
- GjsContext *reflection_context;
-
guint new_scripts_connection;
guint single_step_connection;
guint frame_step_connection;
@@ -68,7 +55,7 @@ G_DEFINE_TYPE_WITH_PRIVATE(GjsCoverage,
enum {
PROP_0,
- PROP_DEBUG_HOOKS,
+ PROP_CONTEXT,
PROP_COVERAGE_PATHS,
PROP_N
};
@@ -496,13 +483,10 @@ create_statistics_from_reflection(GjsReflectedScript *reflected_script)
}
static GjsCoverageFileStatistics *
-new_statistics_for_filename(GjsContext *reflection_context,
- const char *filename)
+new_statistics_for_filename(GjsContext *context, const char *filename)
{
- GjsReflectedScript *reflected_script =
- gjs_reflected_script_new(filename, reflection_context);
- GjsCoverageFileStatistics *stats =
- create_statistics_from_reflection(reflected_script);
+ GjsReflectedScript *reflected_script = gjs_reflected_script_new(context, filename);
+ GjsCoverageFileStatistics *stats = create_statistics_from_reflection(reflected_script);
g_object_unref(reflected_script);
return stats;
@@ -525,7 +509,7 @@ gjs_coverage_new_script_available_hook(GjsDebugHooks *reg,
filename);
if (!statistics) {
- statistics = new_statistics_for_filename(priv->reflection_context, filename);
+ statistics = new_statistics_for_filename(context, filename);
/* If create_statistics_for_filename returns NULL then we can
* just bail out here, the stats print function will handle
@@ -836,7 +820,7 @@ copy_source_file_to_coverage_output(const char *source,
}
typedef struct _StatisticsPrintUserData {
- GjsContext *reflection_context;
+ GjsContext *context;
GFileOutputStream *ostream;
const gchar *output_directory;
} StatisticsPrintUserData;
@@ -944,8 +928,7 @@ print_statistics_for_files(gpointer key,
/* If there is no statistics for this file, then we should
* compile the script and print statistics for it now */
if (!stats)
- stats = new_statistics_for_filename(statistics_print_data->reflection_context,
- filename);
+ stats = new_statistics_for_filename(statistics_print_data->context, filename);
/* Still couldn't create statistics, bail out */
if (!stats)
@@ -1019,6 +1002,7 @@ gjs_coverage_write_statistics(GjsCoverage *coverage,
GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
GError *error = NULL;
GFileOutputStream *ostream = NULL;
+ GjsDebugHooks *hooks = gjs_context_get_debug_hooks(priv->context);
/* Create output_directory if it doesn't exist */
g_mkdir_with_parents(output_directory, 0755);
@@ -1031,7 +1015,7 @@ gjs_coverage_write_statistics(GjsCoverage *coverage,
/* Remove our new script hook so that we don't get spurious calls
* to it whilst compiling new scripts */
- gjs_debug_hooks_remove_script_load_hook(priv->debug_hooks, priv->new_scripts_connection);
+ gjs_debug_hooks_remove_script_load_hook(hooks, priv->new_scripts_connection);
priv->new_scripts_connection = 0;
ostream = g_file_append_to(output_file,
@@ -1052,7 +1036,7 @@ gjs_coverage_write_statistics(GjsCoverage *coverage,
* case just fine, so there's no need to return if
* output_file is NULL */
StatisticsPrintUserData data = {
- priv->reflection_context,
+ priv->context,
ostream,
output_directory
};
@@ -1065,10 +1049,9 @@ gjs_coverage_write_statistics(GjsCoverage *coverage,
g_object_unref(output_file);
/* Re-insert our new script hook in case we need it again */
- priv->new_scripts_connection =
- gjs_debug_hooks_add_script_load_hook(priv->debug_hooks,
- gjs_coverage_new_script_available_hook,
- coverage);
+ priv->new_scripts_connection = gjs_debug_hooks_add_script_load_hook(hooks,
+
gjs_coverage_new_script_available_hook,
+ coverage);
}
static void
@@ -1083,7 +1066,6 @@ gjs_coverage_init(GjsCoverage *self)
{
GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(self);
- priv->reflection_context = gjs_reflected_script_create_reflection_context();
priv->file_statistics = g_hash_table_new_full(g_str_hash,
g_str_equal,
g_free,
@@ -1098,6 +1080,7 @@ gjs_coverage_constructed(GObject *object)
GjsCoverage *coverage = GJS_DEBUG_COVERAGE(object);
GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
+ GjsDebugHooks *hooks = gjs_context_get_debug_hooks(priv->context);
/* Take the list of covered paths and add them to the coverage report */
if (priv->covered_paths) {
@@ -1116,20 +1099,17 @@ gjs_coverage_constructed(GObject *object)
}
/* Add hook for new scripts and singlestep execution */
- priv->new_scripts_connection =
- gjs_debug_hooks_add_script_load_hook(priv->debug_hooks,
- gjs_coverage_new_script_available_hook,
- coverage);
-
- priv->single_step_connection =
- gjs_debug_hooks_add_singlestep_hook(priv->debug_hooks,
- gjs_coverage_single_step_interrupt_hook,
- coverage);
-
- priv->frame_step_connection =
- gjs_debug_hooks_add_frame_step_hook(priv->debug_hooks,
- gjs_coverage_frame_execution_hook,
- priv->file_statistics);
+ priv->new_scripts_connection = gjs_debug_hooks_add_script_load_hook(hooks,
+
gjs_coverage_new_script_available_hook,
+ coverage);
+
+ priv->single_step_connection = gjs_debug_hooks_add_singlestep_hook(hooks,
+
gjs_coverage_single_step_interrupt_hook,
+ coverage);
+
+ priv->frame_step_connection = gjs_debug_hooks_add_frame_step_hook(hooks,
+ gjs_coverage_frame_execution_hook,
+ priv->file_statistics);
}
static void
@@ -1141,8 +1121,8 @@ gjs_coverage_set_property(GObject *object,
GjsCoverage *coverage = GJS_DEBUG_COVERAGE(object);
GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
switch (prop_id) {
- case PROP_DEBUG_HOOKS:
- priv->debug_hooks = GJS_DEBUG_HOOKS(g_value_dup_object(value));
+ case PROP_CONTEXT:
+ priv->context = GJS_CONTEXT(g_value_dup_object(value));
break;
case PROP_COVERAGE_PATHS:
g_assert(priv->covered_paths == NULL);
@@ -1172,13 +1152,13 @@ gjs_coverage_dispose(GObject *object)
{
GjsCoverage *coverage = GJS_DEBUG_COVERAGE (object);
GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);
+ GjsDebugHooks *hooks = gjs_context_get_debug_hooks(priv->context);
- clear_debug_handle(priv->debug_hooks, gjs_debug_hooks_remove_script_load_hook,
&priv->new_scripts_connection);
- clear_debug_handle(priv->debug_hooks, gjs_debug_hooks_remove_singlestep_hook,
&priv->single_step_connection);
- clear_debug_handle(priv->debug_hooks, gjs_debug_hooks_remove_frame_step_hook,
&priv->frame_step_connection);
+ clear_debug_handle(hooks, gjs_debug_hooks_remove_script_load_hook, &priv->new_scripts_connection);
+ clear_debug_handle(hooks, gjs_debug_hooks_remove_singlestep_hook, &priv->single_step_connection);
+ clear_debug_handle(hooks, gjs_debug_hooks_remove_frame_step_hook, &priv->frame_step_connection);
- g_clear_object(&priv->debug_hooks);
- g_clear_object(&priv->reflection_context);
+ g_clear_object(&priv->context);
G_OBJECT_CLASS(gjs_coverage_parent_class)->dispose(object);
}
@@ -1205,37 +1185,27 @@ gjs_coverage_class_init (GjsCoverageClass *klass)
object_class->finalize = gjs_coverage_finalize;
object_class->set_property = gjs_coverage_set_property;
- properties[PROP_DEBUG_HOOKS] = g_param_spec_object("debug-hooks",
- "Debug Hooks",
- "Debug Hooks",
- GJS_TYPE_DEBUG_HOOKS,
- (GParamFlags) (G_PARAM_CONSTRUCT_ONLY |
G_PARAM_WRITABLE));
+ properties[PROP_CONTEXT] = g_param_spec_object("context", "", "",
+ GJS_TYPE_CONTEXT,
+ (GParamFlags) (G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE
| G_PARAM_STATIC_STRINGS));
properties[PROP_COVERAGE_PATHS] = g_param_spec_boxed("coverage-paths",
"Coverage Paths",
"Paths (and included subdirectories) of which to
perform coverage analysis",
G_TYPE_STRV,
- (GParamFlags) (G_PARAM_CONSTRUCT_ONLY |
G_PARAM_WRITABLE));
+ (GParamFlags) (G_PARAM_CONSTRUCT_ONLY |
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties(object_class,
PROP_N,
properties);
}
-/**
- * gjs_coverage_new:
- * @debug_hooks: (transfer full): A #GjsDebugHooks to register callbacks on.
- * @coverage_paths: (transfer none): A null-terminated strv of directories to generate
- * coverage_data for
- *
- * Returns: A #GjsDebugCoverage
- */
GjsCoverage *
-gjs_coverage_new (GjsDebugHooks *debug_hooks,
- const char **coverage_paths)
+gjs_coverage_new (GjsContext *context,
+ const char **coverage_paths)
{
GjsCoverage *coverage =
GJS_DEBUG_COVERAGE(g_object_new(GJS_TYPE_DEBUG_COVERAGE,
- "debug-hooks", debug_hooks,
+ "context", context,
"coverage-paths", coverage_paths,
NULL));
diff --git a/gjs/coverage.h b/gjs/coverage.h
index 2c872ea..a29df21 100644
--- a/gjs/coverage.h
+++ b/gjs/coverage.h
@@ -78,8 +78,8 @@ GType gjs_debug_coverage_get_type(void);
void gjs_coverage_write_statistics(GjsCoverage *coverage,
const char *output_directory);
-GjsCoverage * gjs_coverage_new(GjsDebugHooks *debug_hooks,
- const char **covered_directories);
+GjsCoverage * gjs_coverage_new(GjsContext *context,
+ const char **covered_directories);
G_END_DECLS
diff --git a/gjs/reflected-script.cpp b/gjs/reflected-script.cpp
index fa64c3c..5f2f2d7 100644
--- a/gjs/reflected-script.cpp
+++ b/gjs/reflected-script.cpp
@@ -30,21 +30,12 @@
#include "reflected-script-private.h"
struct _GjsReflectedScriptPrivate {
- /* External context where the reflection happens. We take
- * a reference to it so that we can still do evaluation even
- * if the original owner of the context goes away
- *
- * One important precondition is that the context needs to
- * be "initialized" to a state that we expect it to be in,
- * eg, we need to have loaded the infoReflect.js script
- * and set up some global variables. If it hasn't then
- * this will trigger an assertion */
- GjsContext *reflection_context;
+ GjsContext *context;
char *script_filename;
- /* Array of strings, null-terminated */
- GArray *all_function_names;
+ /* Array of GjsReflectedScriptFunctionInfo */
+ GArray *all_functions;
/* Array of GjsReflectedScriptBranchInfo */
GArray *all_branches;
@@ -69,7 +60,7 @@ G_DEFINE_TYPE_WITH_PRIVATE(GjsReflectedScript,
enum {
PROP_0,
PROP_SCRIPT_FILENAME,
- PROP_REFLECTION_CONTEXT,
+ PROP_CONTEXT,
PROP_N
};
@@ -77,40 +68,6 @@ static GParamSpec *properties[PROP_N];
static void ensure_script_reflected(GjsReflectedScript *script);
-GjsReflectedScriptBranchInfo *
-gjs_reflected_script_branch_info_new(unsigned int branch_point,
- GArray *alternatives)
-{
- GjsReflectedScriptBranchInfo *info = g_new0(GjsReflectedScriptBranchInfo, 1);
- info->branch_point = branch_point;
- info->branch_alternatives = alternatives;
- return info;
-}
-
-void
-gjs_reflected_script_branch_info_destroy(gpointer info_data)
-{
- GjsReflectedScriptBranchInfo *info = (GjsReflectedScriptBranchInfo *) info_data;
- g_array_free(info->branch_alternatives, TRUE);
- g_free(info);
-}
-
-unsigned int
-gjs_reflected_script_branch_info_get_branch_point(const GjsReflectedScriptBranchInfo *info)
-{
- return info->branch_point;
-}
-
-const unsigned int *
-gjs_reflected_script_branch_info_get_branch_alternatives(const GjsReflectedScriptBranchInfo *info,
- unsigned int *n)
-{
- g_return_val_if_fail(n, NULL);
-
- *n = info->branch_alternatives->len;
- return (unsigned int *) info->branch_alternatives->data;
-}
-
GjsReflectedScriptFunctionInfo *
gjs_reflected_script_function_info_new(char *name,
unsigned int line_number,
@@ -146,16 +103,47 @@ void
gjs_reflected_script_function_info_destroy(gpointer info_data)
{
GjsReflectedScriptFunctionInfo *info = (GjsReflectedScriptFunctionInfo *) info_data;
+ g_free(info->name);
+ g_free(info);
+}
- if (info->name)
- g_free(info->name);
+GjsReflectedScriptBranchInfo *
+gjs_reflected_script_branch_info_new(unsigned int branch_point,
+ GArray *alternatives)
+{
+ GjsReflectedScriptBranchInfo *info = g_new0(GjsReflectedScriptBranchInfo, 1);
+ info->branch_point = branch_point;
+ info->branch_alternatives = alternatives;
+ return info;
+}
+
+void
+gjs_reflected_script_branch_info_destroy(gpointer info_data)
+{
+ GjsReflectedScriptBranchInfo *info = (GjsReflectedScriptBranchInfo *) info_data;
+ g_array_free(info->branch_alternatives, TRUE);
g_free(info);
}
+unsigned int
+gjs_reflected_script_branch_info_get_branch_point(const GjsReflectedScriptBranchInfo *info)
+{
+ return info->branch_point;
+}
+
+const unsigned int *
+gjs_reflected_script_branch_info_get_branch_alternatives(const GjsReflectedScriptBranchInfo *info,
+ unsigned int *n)
+{
+ g_return_val_if_fail(n, NULL);
-const GjsReflectedScriptBranchInfo **
-gjs_reflected_script_get_branches(GjsReflectedScript *script)
+ *n = info->branch_alternatives->len;
+ return (unsigned int *) info->branch_alternatives->data;
+}
+
+const GjsReflectedScriptFunctionInfo **
+gjs_reflected_script_get_functions(GjsReflectedScript *script)
{
g_return_val_if_fail(script, NULL);
@@ -163,12 +151,12 @@ gjs_reflected_script_get_branches(GjsReflectedScript *script)
ensure_script_reflected(script);
- g_assert(priv->all_branches);
- return (const GjsReflectedScriptBranchInfo **) priv->all_branches->data;\
+ g_assert(priv->all_functions);
+ return (const GjsReflectedScriptFunctionInfo **) priv->all_functions->data;
}
-const GjsReflectedScriptFunctionInfo **
-gjs_reflected_script_get_functions(GjsReflectedScript *script)
+const GjsReflectedScriptBranchInfo **
+gjs_reflected_script_get_branches(GjsReflectedScript *script)
{
g_return_val_if_fail(script, NULL);
@@ -176,8 +164,8 @@ gjs_reflected_script_get_functions(GjsReflectedScript *script)
ensure_script_reflected(script);
- g_assert(priv->all_function_names);
- return (const GjsReflectedScriptFunctionInfo **) priv->all_function_names->data;
+ g_assert(priv->all_branches);
+ return (const GjsReflectedScriptBranchInfo **) priv->all_branches->data;\
}
const unsigned int *
@@ -206,8 +194,8 @@ static gboolean
get_array_from_js_value(JSContext *context,
jsval *value,
size_t array_element_size,
- GDestroyNotify element_clear_func,
ConvertAndInsertJSVal inserter,
+ GDestroyNotify element_clear_func,
GArray **out_array)
{
g_return_val_if_fail(out_array != NULL, FALSE);
@@ -254,33 +242,19 @@ get_array_from_js_value(JSContext *context,
return TRUE;
}
-static GArray *
-call_js_function_for_array_return(JSContext *context,
- JSObject *object,
- size_t array_element_size,
- GDestroyNotify element_clear_func,
- ConvertAndInsertJSVal inserter,
- const char *function_name,
- jsval *ast)
+static gboolean
+convert_and_insert_unsigned_int(GArray *array,
+ JSContext *context,
+ jsval *element)
{
- GArray *array = NULL;
- jsval rval;
- if (!JS_CallFunctionName(context, object, function_name, 1, ast, &rval)) {
- gjs_log_exception(context);
- return NULL;
- }
-
- if (!get_array_from_js_value(context,
- &rval,
- array_element_size,
- element_clear_func,
- inserter,
- &array)) {
- gjs_log_exception(context);
- return NULL;
+ if (!JSVAL_IS_INT(*element)) {
+ g_critical("Array element is not an integer");
+ return FALSE;
}
- return array;
+ unsigned int element_integer = JSVAL_TO_INT(*element);
+ g_array_append_val(array, element_integer);
+ return TRUE;
}
static void
@@ -292,7 +266,7 @@ clear_reflected_script_function_info(gpointer info_location)
}
static gboolean
-convert_and_insert_function_decl(GArray *array,
+convert_and_insert_function_info(GArray *array,
JSContext *context,
jsval *element)
{
@@ -355,65 +329,8 @@ convert_and_insert_function_decl(GArray *array,
return TRUE;
}
-static GArray *
-get_script_functions_from_reflection(JSContext *context,
- JSObject *global,
- jsval *ast)
-{
- return call_js_function_for_array_return(context,
- global,
- sizeof(GjsReflectedScriptFunctionInfo *),
- clear_reflected_script_function_info,
- convert_and_insert_function_decl,
- "functionsForAST",
- ast);
-}
-
-static gboolean
-convert_and_insert_unsigned_int(GArray *array,
- JSContext *context,
- jsval *element)
-{
- if (!JSVAL_IS_INT(*element)) {
- g_critical("Array element is not an integer");
- return FALSE;
- }
-
- unsigned int element_integer = JSVAL_TO_INT(*element);
- g_array_append_val(array, element_integer);
- return TRUE;
-}
-
-static int
-uint_compare(gconstpointer left,
- gconstpointer right)
-{
- unsigned int *left_int = (unsigned int *) left;
- unsigned int *right_int = (unsigned int *) right;
-
- return *left_int - *right_int;
-}
-
-static GArray *
-get_all_lines_with_executable_expressions_from_reflection(JSContext *context,
- JSObject *global,
- jsval *ast)
-{
- GArray *all_expressions = call_js_function_for_array_return(context,
- global,
- sizeof(unsigned int),
- NULL,
- convert_and_insert_unsigned_int,
- "expressionLinesForAST",
- ast);
-
- /* Sort, just to be sure */
- g_array_sort(all_expressions, uint_compare);
- return all_expressions;
-}
-
static void
-gjs_reflected_script_branch_info_clear(gpointer branch_info_location)
+clear_reflected_script_branch_info(gpointer branch_info_location)
{
GjsReflectedScriptBranchInfo **info_ptr = (GjsReflectedScriptBranchInfo **) branch_info_location;
gjs_reflected_script_branch_info_destroy(*info_ptr);
@@ -456,12 +373,8 @@ convert_and_insert_branch_info(GArray *array,
return FALSE;
}
- if (!get_array_from_js_value(context,
- &branch_exits_value,
- sizeof(unsigned int),
- NULL,
- convert_and_insert_unsigned_int,
- &branch_exists_array)) {
+ if (!get_array_from_js_value(context, &branch_exits_value, sizeof(unsigned int),
+ convert_and_insert_unsigned_int, NULL, &branch_exists_array)) {
/* Already logged the exception, no need to do anything here */
return FALSE;
}
@@ -474,20 +387,6 @@ convert_and_insert_branch_info(GArray *array,
return TRUE;
}
-static GArray *
-get_script_branches_from_reflection(JSContext *context,
- JSObject *global,
- jsval *ast)
-{
- return call_js_function_for_array_return(context,
- global,
- sizeof(GjsReflectedScriptBranchInfo *),
- gjs_reflected_script_branch_info_clear,
- convert_and_insert_branch_info,
- "branchesForAST",
- ast);
-}
-
static unsigned int
count_lines_in_script(const char *data)
{
@@ -545,14 +444,13 @@ load_script_for_reflection(GjsContext *context,
}
static gboolean
-perform_reflection_within_compartment(GjsContext *internal_context,
- GjsReflectedScript *script)
+perform_reflection(GjsContext *internal_context,
+ GjsReflectedScript *script)
{
GjsReflectedScriptPrivate *priv = (GjsReflectedScriptPrivate *)
gjs_reflected_script_get_instance_private(script);
- JSContext *js_context = (JSContext *) gjs_context_get_native_context(internal_context);
- JSObject *global = JS_GetGlobalObject(js_context);
-
- JSAutoCompartment ac(js_context, global);
+ JSContext *context = (JSContext *) gjs_context_get_native_context(internal_context);
+ JSObject *global = JS_GetGlobalObject(context);
+ JSAutoCompartment ac(context, global);
int start_line_number = 1;
unsigned int script_n_lines;
@@ -565,42 +463,47 @@ perform_reflection_within_compartment(GjsContext *internal_context,
if (!str)
return FALSE;
- jsval reflect_object_value;
- if (!JS_GetProperty(js_context, global, "Reflect", &reflect_object_value) ||
- !JSVAL_IS_OBJECT(reflect_object_value)) {
- gjs_throw(js_context, "'Reflect' object not found in context");
+ jsval reflectScript;
+ if (!gjs_eval_with_scope(context, NULL,
+ "imports.infoReflect.reflectScript", -1,
+ "<reflect>", &reflectScript))
+ return FALSE;
+
+ jsval reflectScriptArgs[] = {
+ STRING_TO_JSVAL(str),
+ INT_TO_JSVAL(start_line_number),
+ };
+ jsval reflectScriptRetval;
+ if (!JS_CallFunctionValue(context, NULL, reflectScript,
+ G_N_ELEMENTS(reflectScriptArgs), reflectScriptArgs,
+ &reflectScriptRetval))
return FALSE;
- }
- JSObject *reflect_object = JSVAL_TO_OBJECT(reflect_object_value);
- JSObject *reflect_options_object = JS_NewObject(js_context, NULL, NULL, NULL);
+ g_assert(reflectScriptRetval.isObject());
- jsval loc_value = BOOLEAN_TO_JSVAL(JS_TRUE);
- jsval line_value = INT_TO_JSVAL(start_line_number);
+ JSObject *reflectScriptObj = &reflectScriptRetval.toObject();
- JS_SetProperty(js_context, reflect_options_object, "loc", &loc_value);
- JS_SetProperty(js_context, reflect_options_object, "line", &line_value);
+ jsval functions;
+ if (!JS_GetProperty(context, reflectScriptObj, "functions", &functions))
+ return FALSE;
+ if (!get_array_from_js_value(context, &functions, sizeof(GjsReflectedScriptFunctionInfo *),
+ convert_and_insert_function_info, clear_reflected_script_function_info,
&priv->all_functions))
+ return FALSE;
- jsval parseArgv[] = {
- STRING_TO_JSVAL(str),
- OBJECT_TO_JSVAL(reflect_options_object)
- };
- jsval ast_value;
+ jsval branches;
+ if (!JS_GetProperty(context, reflectScriptObj, "branches", &branches))
+ return FALSE;
+ if (!get_array_from_js_value(context, &branches, sizeof(GjsReflectedScriptBranchInfo *),
+ convert_and_insert_branch_info, clear_reflected_script_branch_info,
&priv->all_branches))
+ return FALSE;
- if (!JS_CallFunctionName(js_context, reflect_object, "parse", 2, parseArgv, &ast_value)) {
- gjs_throw(js_context, "Failed to call Reflect.parse");
+ jsval expressionLines;
+ if (!JS_GetProperty(context, reflectScriptObj, "expressionLines", &expressionLines))
+ return FALSE;
+ if (!get_array_from_js_value(context, &expressionLines, sizeof(unsigned int),
+ convert_and_insert_unsigned_int, NULL, &priv->all_expression_lines))
return FALSE;
- }
- priv->all_function_names = get_script_functions_from_reflection(js_context,
- global,
- &ast_value);
- priv->all_branches = get_script_branches_from_reflection(js_context,
- global,
- &ast_value);
- priv->all_expression_lines = get_all_lines_with_executable_expressions_from_reflection(js_context,
- global,
- &ast_value);
priv->n_lines = script_n_lines;
return TRUE;
@@ -614,12 +517,12 @@ ensure_script_reflected(GjsReflectedScript *script)
if (priv->reflection_performed)
return;
- if (!perform_reflection_within_compartment(priv->reflection_context, script)) {
+ if (!perform_reflection(priv->context, script)) {
g_warning("Reflecting script %s failed", priv->script_filename);
/* If the reflection failed, we should make sure that the the reflection
* details have sane defaults */
+ priv->all_functions = g_array_new(TRUE, TRUE, sizeof(GjsReflectedScriptFunctionInfo));
priv->all_branches = g_array_new(TRUE, TRUE, sizeof(GjsReflectedScriptBranchInfo));
- priv->all_function_names = g_array_new(TRUE, TRUE, sizeof(GjsReflectedScriptFunctionInfo));
priv->all_expression_lines = g_array_new(TRUE, TRUE, sizeof(unsigned int));
priv->n_lines = 0;
}
@@ -627,26 +530,6 @@ ensure_script_reflected(GjsReflectedScript *script)
priv->reflection_performed = TRUE;
}
-GjsContext *
-gjs_reflected_script_create_reflection_context()
-{
- static const char *resource_path = "resource:///org/gnome/gjs/modules/infoReflect.js";
-
- GjsContext *context = gjs_context_new();
-
- if (!gjs_context_eval_file(context,
- resource_path,
- NULL,
- NULL)) {
- g_object_unref(context);
- return NULL;
- }
-
- gjs_context_pop();
-
- return context;
-}
-
unsigned int
gjs_reflected_script_get_n_lines(GjsReflectedScript *script)
{
@@ -664,8 +547,8 @@ gjs_reflected_script_init(GjsReflectedScript *script)
{
GjsReflectedScriptPrivate *priv = (GjsReflectedScriptPrivate *)
gjs_reflected_script_get_instance_private(script);
+ priv->all_functions = NULL;
priv->all_branches = NULL;
- priv->all_function_names = NULL;
priv->all_expression_lines = NULL;
}
@@ -682,7 +565,7 @@ gjs_reflected_script_dispose(GObject *object)
GjsReflectedScript *script = GJS_REFLECTED_SCRIPT(object);
GjsReflectedScriptPrivate *priv = (GjsReflectedScriptPrivate *)
gjs_reflected_script_get_instance_private(script);
- g_clear_object(&priv->reflection_context);
+ g_clear_object(&priv->context);
G_OBJECT_CLASS(gjs_reflected_script_parent_class)->dispose(object);
}
@@ -693,8 +576,8 @@ gjs_reflected_script_finalize(GObject *object)
GjsReflectedScript *script = GJS_REFLECTED_SCRIPT(object);
GjsReflectedScriptPrivate *priv = (GjsReflectedScriptPrivate *)
gjs_reflected_script_get_instance_private(script);
+ unref_array_if_nonnull(priv->all_functions);
unref_array_if_nonnull(priv->all_branches);
- unref_array_if_nonnull(priv->all_function_names);
unref_array_if_nonnull(priv->all_expression_lines);
g_free(priv->script_filename);
@@ -715,8 +598,8 @@ gjs_reflected_script_set_property(GObject *object,
case PROP_SCRIPT_FILENAME:
priv->script_filename = g_value_dup_string(value);
break;
- case PROP_REFLECTION_CONTEXT:
- priv->reflection_context = (GjsContext *) g_value_dup_object(value);
+ case PROP_CONTEXT:
+ priv->context = (GjsContext *) g_value_dup_object(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -737,26 +620,23 @@ gjs_reflected_script_class_init(GjsReflectedScriptClass *klass)
"Script Filename",
"Valid path to script",
NULL,
- (GParamFlags) (G_PARAM_CONSTRUCT_ONLY |
G_PARAM_WRITABLE));
- properties[PROP_REFLECTION_CONTEXT] = g_param_spec_object("reflection-context",
- "Reflection Context",
- "Context to perform reflection in. "
- "This must have been initialized with
infoReflect.js loaded ",
- GJS_TYPE_CONTEXT,
- (GParamFlags) (G_PARAM_CONSTRUCT_ONLY |
G_PARAM_WRITABLE));
+ (GParamFlags) (G_PARAM_CONSTRUCT_ONLY |
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+ properties[PROP_CONTEXT] = g_param_spec_object("context", "", "",
+ GJS_TYPE_CONTEXT,
+ (GParamFlags) (G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE
| G_PARAM_STATIC_STRINGS));
g_object_class_install_properties(object_class,
PROP_N,
properties);
}
GjsReflectedScript *
-gjs_reflected_script_new(const char *filename,
- GjsContext *reflection_context)
+gjs_reflected_script_new(GjsContext *context,
+ const char *filename)
{
GjsReflectedScript *script =
GJS_REFLECTED_SCRIPT(g_object_new(GJS_TYPE_REFLECTED_SCRIPT,
+ "context", context,
"filename", filename,
- "reflection-context", reflection_context,
NULL));
return script;
}
diff --git a/gjs/reflected-script.h b/gjs/reflected-script.h
index 9e2ea17..2eeaa13 100644
--- a/gjs/reflected-script.h
+++ b/gjs/reflected-script.h
@@ -79,14 +79,8 @@ unsigned int gjs_reflected_script_get_n_lines(GjsReflectedScript *script);
GType gjs_reflected_script_get_type(void);
-GjsReflectedScript * gjs_reflected_script_new(const char *filename,
- GjsContext *reflection_context);
-
-/* Creates a "reflection context" that can be passed to the constructor of
- * gjs_reflected_script_new. This context will have the script
- * containing the functions which permit reflection pre-defined and can
- * be shared across all reflections */
-GjsContext * gjs_reflected_script_create_reflection_context();
+GjsReflectedScript * gjs_reflected_script_new(GjsContext *context,
+ const char *filename);
G_END_DECLS
diff --git a/installed-tests/gjs-unit.cpp b/installed-tests/gjs-unit.cpp
index ad7b415..27e1e22 100644
--- a/installed-tests/gjs-unit.cpp
+++ b/installed-tests/gjs-unit.cpp
@@ -76,8 +76,7 @@ setup(GjsTestJSFixture *fix,
g_error("GJS_UNIT_COVERAGE_OUTPUT is required when using GJS_UNIT_COVERAGE_PATHS");
}
- fix->coverage = gjs_coverage_new(gjs_context_get_debug_hooks(fix->context),
- (const char **) data->coverage_paths);
+ fix->coverage = gjs_coverage_new(fix->context, (const char **) data->coverage_paths);
}
}
diff --git a/modules/infoReflect.js b/modules/infoReflect.js
index b1d5cab..ddd8320 100644
--- a/modules/infoReflect.js
+++ b/modules/infoReflect.js
@@ -333,6 +333,17 @@ function deduplicate(list) {
function expressionLinesForAST(ast) {
let allExpressions = collectForSubNodes(ast.body, expressionLinesForNode);
allExpressions = deduplicate(allExpressions);
-
+ allExpressions = allExpressions.sort(function(a, b) {
+ return a - b;
+ });
return allExpressions;
}
+
+function reflectScript(script, startLine) {
+ let ast = Reflect.parse(script, { line: startLine, loc: true });
+ return {
+ functions: functionsForAST(ast),
+ branches: branchesForAST(ast),
+ expressionLines: expressionLinesForAST(ast),
+ };
+}
diff --git a/test/gjs-test-coverage.cpp b/test/gjs-test-coverage.cpp
index 465ac4e..aec1656 100644
--- a/test/gjs-test-coverage.cpp
+++ b/test/gjs-test-coverage.cpp
@@ -31,14 +31,11 @@
#include <glib.h>
#include <gio/gio.h>
#include <gjs/gjs.h>
-#include <gjs/debug-hooks.h>
-#include <gjs/debug-hooks-private.h>
#include <gjs/reflected-script-private.h>
#include <gjs/coverage.h>
typedef struct _GjsCoverageFixture {
GjsContext *context;
- GjsDebugHooks *debug_hooks;
GjsCoverage *coverage;
char *temporary_js_script_directory_name;
char *temporary_js_script_filename;
@@ -125,9 +122,7 @@ gjs_coverage_fixture_set_up(gpointer fixture_data,
};
fixture->context = gjs_context_new_with_search_path((char **) search_paths);
- fixture->debug_hooks = gjs_debug_hooks_new (fixture->context);
- fixture->coverage = gjs_coverage_new(fixture->debug_hooks,
- coverage_paths);
+ fixture->coverage = gjs_coverage_new(fixture->context, coverage_paths);
write_to_file(fixture->temporary_js_script_open_handle, js_script);
}
@@ -144,7 +139,6 @@ gjs_coverage_fixture_tear_down(gpointer fixture_data,
g_free(fixture->temporary_js_script_directory_name);
g_object_unref(fixture->coverage);
- g_object_unref(fixture->debug_hooks);
g_object_unref(fixture->context);
}
@@ -355,9 +349,7 @@ test_covered_file_is_duplicated_into_output_if_resource(gpointer fixture_da
};
g_object_unref(fixture->base_fixture.coverage);
- fixture->base_fixture.coverage =
- gjs_coverage_new(fixture->base_fixture.debug_hooks,
- coverage_scripts);
+ fixture->base_fixture.coverage = gjs_coverage_new(fixture->base_fixture.context, coverage_scripts);
gjs_context_eval_file(fixture->base_fixture.context,
mock_resource_filename,
@@ -1048,8 +1040,7 @@ gjs_coverage_multiple_source_files_to_single_output_fixture_set_up(gpointer fixt
};
g_object_unref(fixture->base_fixture.base_fixture.coverage);
- fixture->base_fixture.base_fixture.coverage =
gjs_coverage_new(fixture->base_fixture.base_fixture.debug_hooks,
- coverage_paths);
+ fixture->base_fixture.base_fixture.coverage =
gjs_coverage_new(fixture->base_fixture.base_fixture.context, coverage_paths);
char *base_name = g_path_get_basename(fixture->base_fixture.base_fixture.temporary_js_script_filename);
char *base_name_without_extension = g_strndup(base_name,
diff --git a/test/gjs-test-debug-hooks.cpp b/test/gjs-test-debug-hooks.cpp
index be669c4..407c892 100644
--- a/test/gjs-test-debug-hooks.cpp
+++ b/test/gjs-test-debug-hooks.cpp
@@ -292,9 +292,7 @@ test_interrupts_are_received_on_all_executable_lines_in_single_step_mode (gpoint
write_content_to_file_at_beginning(fixture->temporary_js_script_open_handle,
mock_script);
- GjsContext *reflection_context = gjs_reflected_script_create_reflection_context();
- GjsReflectedScript *reflected = gjs_reflected_script_new(fixture->temporary_js_script_filename,
- reflection_context);
+ GjsReflectedScript *reflected = gjs_reflected_script_new(fixture->context,
fixture->temporary_js_script_filename);
unsigned int n_executable_lines = 0;
const unsigned int *executable_lines =
gjs_reflected_script_get_expression_lines(reflected, &n_executable_lines);
@@ -311,7 +309,6 @@ test_interrupts_are_received_on_all_executable_lines_in_single_step_mode (gpoint
g_array_free(line_tracker, TRUE);
gjs_debug_hooks_remove_singlestep_hook(fixture->debug_hooks, connection);
g_object_unref(reflected);
- g_object_unref(reflection_context);
}
static void
diff --git a/test/gjs-test-reflected-script.cpp b/test/gjs-test-reflected-script.cpp
index de3ec1e..f723f78 100644
--- a/test/gjs-test-reflected-script.cpp
+++ b/test/gjs-test-reflected-script.cpp
@@ -28,9 +28,9 @@
#include <gjs/reflected-script.h>
typedef struct _GjsReflectedScriptTestFixture {
- char *temporary_js_script_filename;
- int temporary_js_script_open_handle;
- GjsContext *reflection_context;
+ GjsContext *context;
+ char *temporary_js_script_filename;
+ int temporary_js_script_open_handle;
} GjsReflectedScriptTestFixture;
static void
@@ -42,7 +42,7 @@ gjs_reflected_test_fixture_set_up(gpointer fixture_data,
fixture->temporary_js_script_open_handle = g_file_open_tmp("mock-js-XXXXXXX.js",
&fixture->temporary_js_script_filename,
NULL);
- fixture->reflection_context = gjs_reflected_script_create_reflection_context();
+ fixture->context = gjs_context_new();
g_free(current_dir);
}
@@ -56,7 +56,7 @@ gjs_reflected_test_fixture_tear_down(gpointer fixture_data,
g_free(fixture->temporary_js_script_filename);
close(fixture->temporary_js_script_open_handle);
- g_object_unref(fixture->reflection_context);
+ g_object_unref(fixture->context);
}
static void
@@ -70,8 +70,7 @@ test_reflect_creation_and_destruction(gpointer fixture_data,
if (write(fixture->temporary_js_script_open_handle, mock_script, strlen(mock_script) * sizeof(char)) ==
-1)
g_error("Failed to write to test script");
- GjsReflectedScript *script = gjs_reflected_script_new(fixture->temporary_js_script_filename,
- fixture->reflection_context);
+ GjsReflectedScript *script = gjs_reflected_script_new(fixture->context,
fixture->temporary_js_script_filename);
g_object_unref(script);
}
@@ -97,13 +96,12 @@ static GjsReflectedScript *
get_reflected_script_for(const char *script,
int file,
const char *filename,
- GjsContext *reflection_context)
+ GjsContext *context)
{
if (write(file, script, strlen(script) * sizeof(char)) == -1)
g_error("Failed to write to test script");
- GjsReflectedScript *reflected_script =
- gjs_reflected_script_new(filename, reflection_context);
+ GjsReflectedScript *reflected_script = gjs_reflected_script_new(context, filename);
return reflected_script;
}
@@ -121,7 +119,7 @@ test_reflect_get_all_executable_expression_lines(gpointer fixture_data,
GjsReflectedScript *script = get_reflected_script_for(mock_script,
fixture->temporary_js_script_open_handle,
fixture->temporary_js_script_filename,
- fixture->reflection_context);
+ fixture->context);
unsigned int n_executable_lines = 0;
const unsigned int *executable_lines = gjs_reflected_script_get_expression_lines(script,
&n_executable_lines);
@@ -206,7 +204,7 @@ test_reflect_finds_branches(gpointer fixture_data,
GjsReflectedScript *script = get_reflected_script_for(mock_script,
fixture->temporary_js_script_open_handle,
fixture->temporary_js_script_filename,
- fixture->reflection_context);
+ fixture->context);
const GjsReflectedScriptBranchInfo **branches =
gjs_reflected_script_get_branches(script);
@@ -289,7 +287,7 @@ test_reflect_finds_functions(gpointer fixture_data,
GjsReflectedScript *script = get_reflected_script_for(mock_script,
fixture->temporary_js_script_open_handle,
fixture->temporary_js_script_filename,
- fixture->reflection_context);
+ fixture->context);
const GjsReflectedScriptFunctionInfo **functions =
gjs_reflected_script_get_functions(script);
@@ -320,7 +318,7 @@ test_reflect_get_n_lines(gpointer fixture_data,
GjsReflectedScript *script = get_reflected_script_for(mock_script,
fixture->temporary_js_script_open_handle,
fixture->temporary_js_script_filename,
- fixture->reflection_context);
+ fixture->context);
unsigned int n_lines = gjs_reflected_script_get_n_lines(script);
g_assert(n_lines == 4);
@@ -342,8 +340,7 @@ test_reflect_on_nonexistent_script_returns_empty(gpointer fixture_data,
{
GjsReflectedScriptTestFixture *fixture =
(GjsReflectedScriptTestFixture *) fixture_data;
- GjsReflectedScript *script = gjs_reflected_script_new("doesnotexist://does_not_exist",
- fixture->reflection_context);
+ GjsReflectedScript *script = gjs_reflected_script_new(fixture->context, "doesnotexist://does_not_exist");
/* Make the handler shut up so that we don't get an assertion on
* raised warnings from bad scripts */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]