[vala/wip/transform: 98/100] Load plugins with GModule
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/transform: 98/100] Load plugins with GModule
- Date: Sun, 9 Feb 2014 10:49:10 +0000 (UTC)
commit 7600d23e6f95056adbeb33956479e9f4d742d23e
Author: Luca Bruno <lucabru src gnome org>
Date: Tue Feb 4 22:25:08 2014 +0100
Load plugins with GModule
compiler/valacompiler.vala | 11 ++++-
configure.ac | 1 +
vala/Makefile.am | 5 ++-
vala/valacodecontext.vala | 83 ++++++++++++++++++++++++++++++++++++++++
vala/valacodetransformer.vala | 85 +++++++++++++++++++++++++++++++++++-----
vapi/config.vapi | 1 +
6 files changed, 171 insertions(+), 15 deletions(-)
---
diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala
index 4621f05..a9e6a47 100644
--- a/compiler/valacompiler.vala
+++ b/compiler/valacompiler.vala
@@ -36,6 +36,8 @@ class Vala.Compiler {
static string[] gir_directories;
[CCode (array_length = false, array_null_terminated = true)]
static string[] metadata_directories;
+ [CCode (array_length = false, array_null_terminated = true)]
+ static string[] plugin_directories;
static string vapi_filename;
static string library;
static string gir;
@@ -93,6 +95,7 @@ class Vala.Compiler {
{ "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, ref vapi_directories, "Look for package bindings
in DIRECTORY", "DIRECTORY..." },
{ "girdir", 0, 0, OptionArg.FILENAME_ARRAY, ref gir_directories, "Look for .gir files in
DIRECTORY", "DIRECTORY..." },
{ "metadatadir", 0, 0, OptionArg.FILENAME_ARRAY, ref metadata_directories, "Look for GIR
.metadata files in DIRECTORY", "DIRECTORY..." },
+ { "plugindir", 0, 0, OptionArg.FILENAME_ARRAY, ref plugin_directories, "Look for Vala
compiler plugins in DIRECTORY", "DIRECTORY..." },
{ "pkg", 0, 0, OptionArg.STRING_ARRAY, ref packages, "Include binding for PACKAGE",
"PACKAGE..." },
{ "vapi", 0, 0, OptionArg.FILENAME, ref vapi_filename, "Output VAPI file name", "FILE" },
{ "library", 0, 0, OptionArg.STRING, ref library, "Library name", "NAME" },
@@ -208,6 +211,7 @@ class Vala.Compiler {
context.vapi_directories = vapi_directories;
context.gir_directories = gir_directories;
context.metadata_directories = metadata_directories;
+ context.plugin_directories = plugin_directories;
context.debug = debug;
context.thread = thread;
context.mem_profiler = mem_profiler;
@@ -329,9 +333,10 @@ class Vala.Compiler {
}
}
- var transformer = new GDBusServerTransformer ();
- transformer.head = transformer;
- transformer.transform (context);
+ context.register_transformer (new GDBusServerTransformer ());
+ context.load_plugins ();
+
+ context.transformer.transform (context);
if (context.report.get_errors () > 0 || (fatal_warnings && context.report.get_warnings () >
0)) {
return quit ();
diff --git a/configure.ac b/configure.ac
index 4fcda23..00cc9f4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,6 +18,7 @@ AC_DEFINE_UNQUOTED(PACKAGE_SUFFIX, "$PACKAGE_SUFFIX", [Define to the suffix of t
program_transform_name="s,\$\$,${PACKAGE_SUFFIX},"
AC_SUBST(pkgdatadir, [${datadir}/vala${PACKAGE_SUFFIX}])
+AC_SUBST(pkglibdir, [${libdir}/vala${PACKAGE_SUFFIX}])
# Checks for programs.
AC_PROG_CC
diff --git a/vala/Makefile.am b/vala/Makefile.am
index c917a2f..c664677 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -4,7 +4,9 @@ AM_CPPFLAGS = \
$(COVERAGE_CFLAGS) \
-I$(top_srcdir)/gee \
$(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
-DPACKAGE_DATADIR=\"$(pkgdatadir)\" \
+ -DPACKAGE_LIBDIR=\"$(pkglibdir)\" \
$(NULL)
BUILT_SOURCES = vala.vala.stamp
@@ -176,12 +178,13 @@ valainclude_HEADERS = \
$(NULL)
vala.vapi vala.vala.stamp: $(libvalacore_la_VALASOURCES)
- $(VALA_V)$(VALAC) $(COVERAGE_VALAFLAGS) $(VALAFLAGS) -C --vapidir $(srcdir)/../vapi --pkg gobject-2.0
--vapidir $(srcdir)/../gee --pkg gee --pkg config -H vala.h --library vala $^
+ $(VALA_V)$(VALAC) $(COVERAGE_VALAFLAGS) $(VALAFLAGS) -C --vapidir $(srcdir)/../vapi --pkg gobject-2.0
--pkg gmodule-2.0 --vapidir $(srcdir)/../gee --pkg gee --pkg config -H vala.h --library vala $^
@touch $@
libvalacore_la_LIBADD = \
$(COVERAGE_LIBS) \
$(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
../gee/libgee.la \
$(NULL)
diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala
index afad107..e7fad9c 100644
--- a/vala/valacodecontext.vala
+++ b/vala/valacodecontext.vala
@@ -119,6 +119,11 @@ public class Vala.CodeContext {
public string[] metadata_directories;
/**
+ * List of directories where to find plugins.
+ */
+ public string[] plugin_directories;
+
+ /**
* Produce debug information.
*/
public bool debug { get; set; }
@@ -216,6 +221,11 @@ public class Vala.CodeContext {
public FlowAnalyzer flow_analyzer { get; private set; }
/**
+ * The head of the transformers chain.
+ */
+ public CodeTransformer transformer { get; set; }
+
+ /**
* The selected code generator.
*/
public CodeGenerator codegen { get; set; }
@@ -471,6 +481,77 @@ public class Vala.CodeContext {
flow_analyzer.analyze (this);
}
+ public void load_plugins () {
+ if (!Module.supported ()) {
+ return;
+ }
+
+ if (plugin_directories != null) {
+ foreach (string dir in plugin_directories) {
+ load_plugins_in_directory (dir);
+ }
+ }
+
+ load_plugins_in_directory (Config.PACKAGE_LIBDIR);
+ }
+
+ public void load_plugins_in_directory (string dirname) {
+ Dir dir;
+ try {
+ dir = Dir.open (dirname, 0);
+ } catch (Error e) {
+ return;
+ }
+
+ string? name = null;
+
+ while ((name = dir.read_name ()) != null) {
+ string path = Path.build_filename (dirname, name);
+ if (FileUtils.test (path, FileTest.IS_DIR)) {
+ continue;
+ }
+ if (!name.has_prefix ("valaplugin")) {
+ continue;
+ }
+
+ var mod = Module.open (path, ModuleFlags.BIND_LOCAL);
+
+ if (mod == null) {
+ if (verbose_mode) {
+ stdout.printf ("Could not load module: %s\n", path);
+ }
+ continue;
+ } else {
+ if (verbose_mode) {
+ stdout.printf ("Loaded module: %s\n", path);
+ }
+ }
+
+ void* function;
+ if (!mod.symbol ("vala_plugin_register", out function) || function == null) {
+ if (verbose_mode) {
+ stdout.printf ("Could not load entry point for module %s\n", path);
+ }
+ continue;
+ }
+
+ unowned RegisterPluginFunction register_plugin = (RegisterPluginFunction) function;
+ register_plugin (this);
+
+ mod.make_resident ();
+ }
+ }
+
+ /**
+ * Set the given transformer as the head transformer
+ */
+ public void register_transformer (CodeTransformer transformer) {
+ transformer.next = this.transformer;
+ // Setting .head, will recursively set the head for the next transformers
+ transformer.head = transformer;
+ this.transformer = transformer;
+ }
+
public void add_define (string define) {
defines.add (define);
}
@@ -643,3 +724,5 @@ public class Vala.CodeContext {
return rpath;
}
}
+
+public delegate void Vala.RegisterPluginFunction (Vala.CodeContext context);
\ No newline at end of file
diff --git a/vala/valacodetransformer.vala b/vala/valacodetransformer.vala
index 785e6b8..c5e1ad5 100644
--- a/vala/valacodetransformer.vala
+++ b/vala/valacodetransformer.vala
@@ -24,17 +24,81 @@
* Code visitor for transforming the code tree.
*/
public class Vala.CodeTransformer : CodeVisitor {
- public CodeContext context;
+ public CodeContext context {
+ get {
+ return _head._context;
+ }
+ set {
+ _head._context = value;
+ }
+ }
+ CodeContext _context;
- public CodeBuilder b;
- public ArrayList<CodeBuilder> builder_stack = new ArrayList<CodeBuilder> ();
- public HashMap<string, CodeNode> wrapper_cache;
+ public CodeBuilder b {
+ get {
+ return _head._b;
+ }
+ set {
+ _head._b = value;
+ }
+ }
+ CodeBuilder _b;
+
+ public ArrayList<CodeBuilder> builder_stack {
+ get {
+ return _head._builder_stack;
+ }
+ set {
+ _head._builder_stack = value;
+ }
+ }
+ ArrayList<CodeBuilder> _builder_stack;
+
+ public HashMap<string, CodeNode> wrapper_cache {
+ get {
+ return _head._wrapper_cache;
+ }
+ set {
+ _head._wrapper_cache = value;
+ }
+ }
+ HashMap<string, CodeNode> _wrapper_cache;
+
/* Keep tracks of generated stuff to avoid cycles */
- public HashSet<CodeNode> unit_generated = new HashSet<CodeNode> ();
+ public HashSet<CodeNode> unit_generated {
+ get {
+ return _head._unit_generated;
+ }
+ set {
+ _head._unit_generated = value;
+ }
+ }
+ HashSet<CodeNode> _unit_generated;
- public Namespace current_namespace = null;
+ public Namespace current_namespace {
+ get {
+ return _head._current_namespace;
+ }
+ set {
+ _head._current_namespace = value;
+ }
+ }
+ Namespace _current_namespace;
- public weak CodeTransformer head;
+ public weak CodeTransformer head {
+ get {
+ return _head;
+ }
+
+ set {
+ _head = value;
+ if (next != null) {
+ next.head = value;
+ }
+ }
+ }
+ private CodeTransformer _head;
+
public CodeTransformer next;
public void push_builder (CodeBuilder builder) {
@@ -108,6 +172,9 @@ public class Vala.CodeTransformer : CodeVisitor {
*/
public void transform (CodeContext context) {
this.context = context;
+ builder_stack = new ArrayList<CodeBuilder> ();
+ unit_generated = new HashSet<CodeNode> ();
+
/* we're only interested in non-pkg source files */
var source_files = context.get_source_files ();
foreach (SourceFile file in source_files) {
@@ -329,10 +396,6 @@ public class Vala.CodeTransformer : CodeVisitor {
next.visit_block (b);
}
- public override void visit_empty_statement (EmptyStatement stmt) {
- next.visit_empty_statement (stmt);
- }
-
public override void visit_declaration_statement (DeclarationStatement stmt) {
next.visit_declaration_statement (stmt);
}
diff --git a/vapi/config.vapi b/vapi/config.vapi
index 2c6df9e..e4afb86 100644
--- a/vapi/config.vapi
+++ b/vapi/config.vapi
@@ -25,5 +25,6 @@ namespace Config {
[CCode (cheader_filename = "version.h")]
public const string BUILD_VERSION;
public const string PACKAGE_DATADIR;
+ public const string PACKAGE_LIBDIR;
public const string PACKAGE_SUFFIX;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]