>From 86771dc64a118f872dfdcb509d4d31101e53c648 Mon Sep 17 00:00:00 2001 From: Sam Wilson Date: Sun, 11 Jul 2010 17:27:37 -0400 Subject: [PATCH] Added belongs_to --- vapigen/valagidlparser.vala | 128 ++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 126 insertions(+), 2 deletions(-) diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala index adcaedd..252f9c8 100644 --- a/vapigen/valagidlparser.vala +++ b/vapigen/valagidlparser.vala @@ -24,6 +24,18 @@ using GLib; +private class Vala.DelayedAdd +{ + public DelayedAdd(Symbol sym, string target) + { + symbol = sym; + this.target = target; + } + + public Symbol symbol { get; private set; } + public string target { get; private set; } +} + /** * Code visitor parsing all GIDL files. */ @@ -41,6 +53,8 @@ public class Vala.GIdlParser : CodeVisitor { private Set current_type_symbol_set; private Map cname_type_map; + + private ArrayList delayed_nodes; /** * Parse all source files in the specified code context and build a @@ -140,7 +154,9 @@ public class Vala.GIdlParser : CodeVisitor { current_source_reference = new SourceReference (source_file); foreach (weak IdlModule module in modules) { + delayed_nodes = new ArrayList(); var ns = parse_module (module); + process_delayed_symbols(); if (ns != null) { context.root.add_namespace (ns); } @@ -1677,6 +1693,10 @@ public class Vala.GIdlParser : CodeVisitor { bool add_ellipsis = false; bool suppress_throws = false; + + string? super_class = null; + bool clear_data_type = false; + bool is_instance = false; var attributes = get_attributes (symbol); if (attributes != null) { @@ -1766,6 +1786,28 @@ public class Vala.GIdlParser : CodeVisitor { // force async function, even if it doesn't end in _async m.coroutine = true; } + } else if (nv[0] == "belongs_to") { + super_class = eval (nv[1]); + if (current_data_type == null) + { + clear_data_type = true; + current_data_type = new Struct(super_class, + current_source_reference, + new Comment("Fake reference", + current_source_reference)); + ((Struct)current_data_type).set_cname(super_class); + + if (m.name.has_prefix(super_class)) + { + m.set_cname(m.name); + m.name = m.name.substring(super_class.length); + } + } + } else if (nv[0] == "is_instance") { + if (eval (nv[1]) == "1") + { + is_instance = true; + } } } } @@ -1780,7 +1822,10 @@ public class Vala.GIdlParser : CodeVisitor { if (first) { first = false; - if (!(m is CreationMethod) && + if (is_instance) { + m.binding = MemberBinding.INSTANCE; + continue; // Force instance even if its not + } else if (!(m is CreationMethod) && current_data_type != null && param.type.is_interface && (param_node.name == "self" || @@ -2003,7 +2048,86 @@ public class Vala.GIdlParser : CodeVisitor { m.add_parameter (new FormalParameter.with_ellipsis ()); } - return m; + if (super_class == null) + return m; + + else + { + delay_symbol(m, super_class); + + if (clear_data_type) + current_data_type = null; + + return null; + } + } + + private void delay_symbol(Symbol m, string new_class) + { + stdout.printf("Delaying: %s.%s\n", new_class, m.name); + delayed_nodes.add(new DelayedAdd(m, new_class)); + } + + private void process_delayed_symbols() + { + foreach (DelayedAdd add in delayed_nodes) + { + TypeSymbol? sym = cname_type_map[add.target]; + + if (sym == null) + { + stdout.printf("WARNING: Could not find type '%s' for belongs_to of '%s'\n", add.target, add.symbol.name); + continue; + } + + + if (sym is Class) + { + add_symbol_class((Class)sym, add.symbol); + } + if (sym is Struct) + { + add_symbol_struct((Struct)sym, add.symbol); + } + } + + delayed_nodes.clear(); + } + + private void add_symbol_class(Class c, Symbol s) + { + if (s is Method) { + c.add_method((Method)s); + } else if (s is Class) { + c.add_class((Class)s); + } else if (s is Constant) { + c.add_constant((Constant)s); + } else if (s is Delegate) { + c.add_delegate((Delegate)s); + } else if (s is Enum) { + c.add_enum((Enum)s); + } else if (s is Field) { + c.add_field((Field)s); + } else if (s is Property) { + c.add_property((Property)s); + } else if (s is Signal) { + c.add_signal((Signal)s); + } else if (s is Struct) { + c.add_struct((Struct)s); + } + } + + private void add_symbol_struct(Struct c, Symbol s) + { + if (s is Method) { + c.add_method((Method)s); + } else if (s is Constant) { + c.add_constant((Constant)s); + } else if (s is Field) { + c.add_field((Field)s); + } else if (s is Property) { + c.add_property((Property)s); + } } private bool param_is_exception (IdlNodeParam param) { -- 1.7.0.4