[vala/switch-to-gir] girparser: Support reparenting symbols
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/switch-to-gir] girparser: Support reparenting symbols
- Date: Thu, 26 Aug 2010 20:22:07 +0000 (UTC)
commit 4398462ba04f7cd802f09fdea44316dce01927c2
Author: Luca Bruno <lethalman88 gmail com>
Date: Thu Aug 26 21:56:24 2010 +0200
girparser: Support reparenting symbols
vala/valagirparser.vala | 218 +++++++++++++++++++++++++++++++++++++++++-----
vapigen/valavapigen.vala | 19 +++--
2 files changed, 205 insertions(+), 32 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 8347503..ed71a54 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -29,7 +29,9 @@ using GLib;
* 1) Parse metadata
* 2) Parse GIR with metadata, track unresolved GIR symbols, create symbol mappings
* 3) Reconciliate the tree by mapping tracked symbols
- * 4) Do post-parsing/symbol-resolving operations on the reconciliated tree
+ * 4) Reparent nodes
+ * 5) Process callbacks/virtual
+ * 6) Process aliases
*/
public class Vala.GirParser : CodeVisitor {
enum MetadataType {
@@ -44,7 +46,8 @@ public class Vala.GirParser : CodeVisitor {
CHEADER_FILENAME,
NAME,
OWNED,
- UNOWNED;
+ UNOWNED,
+ PARENT;
public static ArgumentType? from_string (string name) {
var enum_class = (EnumClass) typeof(ArgumentType).class_ref ();
@@ -143,7 +146,6 @@ public class Vala.GirParser : CodeVisitor {
if (lit != null) {
return lit.eval ();
}
-
return null;
}
@@ -173,9 +175,16 @@ public class Vala.GirParser : CodeVisitor {
if (lit != null) {
return lit.value;
}
-
return false;
}
+
+ public SourceReference? get_source_reference (ArgumentType arg) {
+ var val = args.get (arg);
+ if (val != null) {
+ return val.source_reference;
+ }
+ return null;
+ }
}
class MetadataParser {
@@ -457,6 +466,7 @@ public class Vala.GirParser : CodeVisitor {
HashMap<UnresolvedSymbol,Symbol> symbols_map = new HashMap<UnresolvedSymbol,Symbol> (unresolved_symbol_hash, unresolved_symbol_equal);
ArrayList<UnresolvedSymbol> unresolved_gir_symbols = new ArrayList<UnresolvedSymbol> ();
+ HashMap<UnresolvedSymbol,ArrayList<Symbol>> symbol_reparent_map = new HashMap<UnresolvedSymbol,ArrayList<Symbol>> (unresolved_symbol_hash, unresolved_symbol_equal);
HashMap<CallbackScope,ArrayList<Delegate>> gtype_callbacks = new HashMap<CallbackScope,ArrayList<Delegate>> (callback_scope_hash, callback_scope_equal);
ArrayList<Alias> aliases = new ArrayList<Alias> ();
@@ -474,6 +484,7 @@ public class Vala.GirParser : CodeVisitor {
resolve_gir_symbols ();
+ postprocess_reparenting ();
postprocess_gtype_callbacks ();
postprocess_aliases ();
}
@@ -511,7 +522,9 @@ public class Vala.GirParser : CodeVisitor {
string metadata_filename = "%s.metadata".printf (source_file.filename.ndup (source_file.filename.length - ".gir".length));
if (FileUtils.test (metadata_filename, FileTest.EXISTS)) {
var metadata_parser = new MetadataParser ();
- metadata = metadata_parser.parse_metadata (new SourceFile (context, metadata_filename, true));
+ var metadata_file = new SourceFile (context, metadata_filename, source_file.external_package);
+ context.add_source_file (metadata_file);
+ metadata = metadata_parser.parse_metadata (metadata_file);
}
reader = new MarkupReader (source_file.filename);
@@ -737,8 +750,7 @@ public class Vala.GirParser : CodeVisitor {
}
if (metadata.has_argument (arg_type)) {
- var src = metadata.args.get (arg_type).expression.source_reference;
- var new_type = parse_type_from_string (metadata.get_string (arg_type), owned_by_default, src);
+ var new_type = parse_type_from_string (metadata.get_string (arg_type), owned_by_default, metadata.get_source_reference (arg_type));
if (&changed != null) {
changed = true;
}
@@ -773,6 +785,25 @@ public class Vala.GirParser : CodeVisitor {
return str;
}
+ void element_reparent (Symbol symbol) {
+ if (metadata.has_argument (ArgumentType.PARENT)) {
+ var target_symbol = parse_symbol_from_string (metadata.get_string (ArgumentType.PARENT), metadata.get_source_reference (ArgumentType.PARENT));
+ var reparent_list = symbol_reparent_map[target_symbol];
+ if (reparent_list == null) {
+ reparent_list = new ArrayList<Symbol>();
+ symbol_reparent_map[target_symbol] = reparent_list;
+ }
+ reparent_list.add (symbol);
+ }
+ }
+
+ bool element_can_add () {
+ if (metadata.has_argument (ArgumentType.PARENT) || metadata.get_bool (ArgumentType.HIDDEN)) {
+ return false;
+ }
+ return true;
+ }
+
void parse_repository () {
start_element ("repository");
next ();
@@ -942,22 +973,24 @@ public class Vala.GirParser : CodeVisitor {
skip_element ();
}
- if (sym is Class) {
- ns.add_class ((Class) sym);
- } else if (sym is Interface) {
- ns.add_interface ((Interface) sym);
- } else if (sym is Struct) {
- ns.add_struct ((Struct) sym);
- } else if (sym is Enum) {
- ns.add_enum ((Enum) sym);
- } else if (sym is ErrorDomain) {
- ns.add_error_domain ((ErrorDomain) sym);
- } else if (sym is Delegate) {
- ns.add_delegate ((Delegate) sym);
- } else if (sym is Method) {
- ns.add_method ((Method) sym);
- } else if (sym is Constant) {
- ns.add_constant ((Constant) sym);
+ if (sym != null && element_can_add ()) {
+ if (sym is Class) {
+ ns.add_class ((Class) sym);
+ } else if (sym is Interface) {
+ ns.add_interface ((Interface) sym);
+ } else if (sym is Struct) {
+ ns.add_struct ((Struct) sym);
+ } else if (sym is Enum) {
+ ns.add_enum ((Enum) sym);
+ } else if (sym is ErrorDomain) {
+ ns.add_error_domain ((ErrorDomain) sym);
+ } else if (sym is Delegate) {
+ ns.add_delegate ((Delegate) sym);
+ } else if (sym is Method) {
+ ns.add_method ((Method) sym);
+ } else if (sym is Constant) {
+ ns.add_constant ((Constant) sym);
+ }
}
pop_metadata ();
@@ -2042,6 +2075,7 @@ public class Vala.GirParser : CodeVisitor {
var c = new Constant (name, type, null, get_current_src ());
c.access = SymbolAccessibility.PUBLIC;
c.external = true;
+ element_reparent (c);
end_element ("constant");
return c;
}
@@ -2098,11 +2132,147 @@ public class Vala.GirParser : CodeVisitor {
return null;
}
+ private void add_symbol_to_container (Symbol container, Symbol sym) {
+ if (container is Class) {
+ unowned Class cl = (Class) container;
+
+ if (sym is Class) {
+ cl.add_class ((Class) sym);
+ } else if (sym is Constant) {
+ cl.add_constant ((Constant) sym);
+ } else if (sym is Enum) {
+ cl.add_enum ((Enum) sym);
+ } else if (sym is Field) {
+ cl.add_field ((Field) sym);
+ } else if (sym is Method) {
+ cl.add_method ((Method) sym);
+ } else if (sym is Property) {
+ cl.add_property ((Property) sym);
+ } else if (sym is Signal) {
+ cl.add_signal ((Signal) sym);
+ } else if (sym is Struct) {
+ cl.add_struct ((Struct) sym);
+ }
+ } else if (container is Enum) {
+ unowned Enum en = (Enum) container;
+
+ if (sym is EnumValue) {
+ en.add_value ((EnumValue) sym);
+ } else if (sym is Constant) {
+ en.add_constant ((Constant) sym);
+ } else if (sym is Method) {
+ en.add_method ((Method) sym);
+ }
+ } else if (container is Interface) {
+ unowned Interface iface = (Interface) container;
+
+ if (sym is Class) {
+ iface.add_class ((Class) sym);
+ } else if (sym is Constant) {
+ iface.add_constant ((Constant) sym);
+ } else if (sym is Enum) {
+ iface.add_enum ((Enum) sym);
+ } else if (sym is Field) {
+ iface.add_field ((Field) sym);
+ } else if (sym is Method) {
+ iface.add_method ((Method) sym);
+ } else if (sym is Property) {
+ iface.add_property ((Property) sym);
+ } else if (sym is Signal) {
+ iface.add_signal ((Signal) sym);
+ } else if (sym is Struct) {
+ iface.add_struct ((Struct) sym);
+ }
+ } else if (container is Namespace) {
+ unowned Namespace ns = (Namespace) container;
+
+ if (sym is Namespace) {
+ ns.add_namespace ((Namespace) sym);
+ } else if (sym is Class) {
+ ns.add_class ((Class) sym);
+ } else if (sym is Constant) {
+ ns.add_constant ((Constant) sym);
+ } else if (sym is Delegate) {
+ ns.add_delegate ((Delegate) sym);
+ } else if (sym is Enum) {
+ ns.add_enum ((Enum) sym);
+ } else if (sym is ErrorDomain) {
+ ns.add_error_domain ((ErrorDomain) sym);
+ } else if (sym is Field) {
+ ns.add_field ((Field) sym);
+ } else if (sym is Interface) {
+ ns.add_interface ((Interface) sym);
+ } else if (sym is Method) {
+ ns.add_method ((Method) sym);
+ } else if (sym is Namespace) {
+ ns.add_namespace ((Namespace) sym);
+ } else if (sym is Struct) {
+ ns.add_struct ((Struct) sym);
+ }
+ } else if (container is Struct) {
+ unowned Struct st = (Struct) container;
+
+ if (sym is Constant) {
+ st.add_constant ((Constant) sym);
+ } else if (sym is Field) {
+ st.add_field ((Field) sym);
+ } else if (sym is Method) {
+ st.add_method ((Method) sym);
+ } else if (sym is Property) {
+ st.add_property ((Property) sym);
+ }
+ } else {
+ Report.error (sym.source_reference, "impossible to add to container `%s'".printf (container.name));
+ }
+ }
+
+ void postprocess_reparenting () {
+ foreach (UnresolvedSymbol target_unresolved_symbol in symbol_reparent_map.get_keys ()) {
+ var target_symbol = resolve_symbol (context.root.scope, target_unresolved_symbol);
+ if (target_symbol == null) {
+ // create namespaces backward
+ var sym = target_unresolved_symbol;
+ var ns = new Namespace (sym.name, sym.source_reference);
+ var result = ns;
+ sym = sym.inner;
+ while (sym != null) {
+ var res = resolve_symbol (context.root.scope, sym);
+ if (res != null && !(res is Namespace)) {
+ result = null;
+ break;
+ }
+ var parent = res as Namespace;
+ if (res == null) {
+ parent = new Namespace (sym.name, sym.source_reference);
+ }
+ if (parent.scope.lookup (ns.name) == null) {
+ parent.add_namespace (ns);
+ }
+ ns = parent;
+ sym = sym.inner;
+ }
+ if (result != null && sym == null && context.root.scope.lookup (ns.name) == null) {
+ // a new root namespace, helpful for a possible non-gobject gir?
+ context.root.add_namespace (ns);
+ }
+ target_symbol = result;
+ }
+ if (target_symbol == null) {
+ Report.error (null, "unable to reparent into `%s'".printf (target_unresolved_symbol.to_string ()));
+ continue;
+ }
+ var symbols = symbol_reparent_map[target_unresolved_symbol];
+ foreach (var symbol in symbols) {
+ add_symbol_to_container (target_symbol, symbol);
+ }
+ }
+ }
+
void postprocess_gtype_callbacks () {
foreach (CallbackScope callback_scope in gtype_callbacks.get_keys ()) {
var gtype = resolve_symbol (callback_scope.parent_namespace.scope, callback_scope.gtype_struct_for) as ObjectTypeSymbol;
if (gtype == null) {
- Report.error (null, "unknown symbol %s".printf (callback_scope.gtype_struct_for.to_string ()));
+ Report.error (null, "unknown symbol `%s'".printf (callback_scope.gtype_struct_for.to_string ()));
continue;
}
ArrayList<Delegate> callbacks = gtype_callbacks.get (callback_scope);
diff --git a/vapigen/valavapigen.vala b/vapigen/valavapigen.vala
index f0a4697..3dd19fe 100644
--- a/vapigen/valavapigen.vala
+++ b/vapigen/valavapigen.vala
@@ -119,18 +119,13 @@ class Vala.VAPIGen : Object {
return quit ();
}
- /* source files to be later unmarked as external_package */
- var source_files = new ArrayList<SourceFile> ();
foreach (string source in sources) {
if (FileUtils.test (source, FileTest.EXISTS)) {
- var source_file = new SourceFile (context, source, true);
- source_files.add (source_file);
- context.add_source_file (source_file);
+ context.add_source_file (new SourceFile (context, source, true));
} else {
Report.error (null, "%s not found".printf (source));
}
}
- sources = null;
if (context.report.get_errors () > 0) {
return quit ();
@@ -172,9 +167,17 @@ class Vala.VAPIGen : Object {
}
// interface writer ignores external packages
- foreach (SourceFile file in source_files) {
- if (!file.filename.has_suffix (".vapi")) {
+ foreach (SourceFile file in context.get_source_files ()) {
+ if (file.filename.has_suffix (".vapi")) {
+ continue;
+ }
+ if (file.filename in sources) {
file.external_package = false;
+ } else if (file.filename.has_suffix (".metadata")) {
+ string gir_filename = "%s.gir".printf (file.filename.ndup (file.filename.length - ".metadata".length));
+ if (gir_filename in sources) {
+ file.external_package = false;
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]