[glibmm/gmmproc-refactor] Use new conversions system.



commit 94061ac345644ae821e871861f297a3712e0d9d3
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Wed Jun 6 04:08:15 2012 +0200

    Use new conversions system.

 tools/pm/Common/CFunctionInfo.pm |    6 +-
 tools/pm/Common/CallableInfo.pm  |  226 +++++++++++++++++++++++++++++++++++++-
 tools/pm/Common/Gmmproc.pm       |   58 +++-------
 tools/pm/Common/Output/Ctor.pm   |    4 +-
 tools/pm/Common/Output/Method.pm |    4 +-
 tools/pm/Common/Output/Shared.pm |    4 +-
 tools/pm/Common/Output/Signal.pm |   12 +-
 tools/pm/Common/Output/VFunc.pm  |   10 +-
 tools/pm/Common/Scanner.pm       |   51 ++++-----
 tools/pm/Common/SignalInfo.pm    |  168 ++++------------------------
 tools/pm/Common/TokensStore.pm   |   27 +----
 tools/pm/Common/WrapParser.pm    |   41 ++++---
 tools/pm/TODO                    |   10 ++
 13 files changed, 343 insertions(+), 278 deletions(-)
---
diff --git a/tools/pm/Common/CFunctionInfo.pm b/tools/pm/Common/CFunctionInfo.pm
index 4d27479..eae6e78 100644
--- a/tools/pm/Common/CFunctionInfo.pm
+++ b/tools/pm/Common/CFunctionInfo.pm
@@ -32,11 +32,11 @@ sub _get_name_from_gir ($$)
   return $gir_function->get_a_c_identifier;
 }
 
-sub new_from_gir ($$)
+sub new_from_gir ($$$)
 {
-  my ($type, $gir_function) = @_;
+  my ($type, $gir_function, $wrap_parser) = @_;
   my $class = (ref $type or $type or 'Common::CFunctionInfo');
-  my $self = $class->SUPER::new_from_gir ($gir_function);
+  my $self = $class->SUPER::new_from_gir ($gir_function, $wrap_parser);
   my $throws = $gir_function->get_a_throws;
 
   $self->{'throws'} = $throws;
diff --git a/tools/pm/Common/CallableInfo.pm b/tools/pm/Common/CallableInfo.pm
index 1d5ae63..52b51ba 100644
--- a/tools/pm/Common/CallableInfo.pm
+++ b/tools/pm/Common/CallableInfo.pm
@@ -23,6 +23,206 @@ package Common::CallableInfo;
 use strict;
 use warnings;
 
+sub _get_wrap_parser ($)
+{
+  my ($self) = @_;
+
+  return $self->{'wrap_parser'};
+}
+
+sub _c_type_from_name ($$)
+{
+  my ($self, $name) = @_;
+  my $wrap_parser = $self->_get_wrap_parser;
+
+  if ($name eq 'utf8' or $name eq 'filename')
+  {
+    return 'gchar*';
+  }
+  else
+  {
+    my $namespace = undef;
+    my $stuff = undef;
+
+    if ($name =~ /^(\w)\.(\w)$/)
+    {
+      $namespace = $1;
+      $stuff = $2;
+    }
+    elsif ($name =~ /^[A-Z]/)
+    {
+      $namespace = $wrap_parser->get_module;
+      $stuff = $name;
+    }
+    else # probably something like gint or gboolean
+    {
+      return $name;
+    }
+
+    my $repositories = $wrap_parser->get_repositories;
+    my $gir_repository = $repositories->get_repository ($namespace);
+    my $gir_namespace = $gir_repository->get_g_namespace_by_name ($namespace);
+    my @gir_symbol_prefixes = split ',', $gir_namespace->get_a_c_symbol_prefixes;
+    my @gir_namespace_methods =
+    (
+      \&Gir::Api::Namespace::get_g_alias_by_name,
+      \&Gir::Api::Namespace::get_g_class_by_name,
+      \&Gir::Api::Namespace::get_g_interface_by_name,
+      \&Gir::Api::Namespace::get_g_glib_boxed_by_name,
+      \&Gir::Api::Namespace::get_g_record_by_name,
+      \&Gir::Api::Namespace::get_g_enumeration_by_name,
+      \&Gir::Api::Namespace::get_g_bitfield_by_name,
+      \&Gir::Api::Namespace::get_g_union_by_name
+    );
+
+    foreach my $symbol_prefix (@gir_symbol_prefixes)
+    {
+      my $maybe_c_name = $symbol_prefix . $stuff;
+
+      foreach my $method (@gir_namespace_methods)
+      {
+        my $gir_stuff = $gir_namespace->$method ($maybe_c_name);
+
+        if (defined ($gir_stuff))
+        {
+          # Meh, glib:boxed is special
+          if ($gir_stuff->isa ('Gir::Api::GlibBoxed'))
+          {
+            return $gir_stuff->get_a_glib_type_name;
+          }
+          else
+          {
+            return $gir_stuff->get_a_c_type;
+          }
+        }
+      }
+    }
+# Argh, probably our guess at C name was just wrong.
+# Taking longer route at guessing the C type.
+    @gir_namespace_methods =
+    (
+      [
+        \&Gir::Api::Namespace::get_g_alias_count,
+        \&Gir::Api::Namespace::get_g_alias_by_index,
+      ],
+      [
+        \&Gir::Api::Namespace::get_g_class_count,
+        \&Gir::Api::Namespace::get_g_class_by_index
+      ],
+      [
+        \&Gir::Api::Namespace::get_g_interface_count,
+        \&Gir::Api::Namespace::get_g_interface_by_index
+      ],
+      [
+        \&Gir::Api::Namespace::get_g_glib_boxed_count,
+        \&Gir::Api::Namespace::get_g_glib_boxed_by_index
+      ],
+      [
+        \&Gir::Api::Namespace::get_g_record_count,
+        \&Gir::Api::Namespace::get_g_record_by_index
+      ],
+      [
+        \&Gir::Api::Namespace::get_g_enumeration_count,
+        \&Gir::Api::Namespace::get_g_enumeration_by_index
+      ],
+      [
+        \&Gir::Api::Namespace::get_g_bitfield_count,
+        \&Gir::Api::Namespace::get_g_bitfield_by_index
+      ],
+      [
+        \&Gir::Api::Namespace::get_g_union_count,
+        \&Gir::Api::Namespace::get_g_union_by_index
+      ]
+    );
+
+    foreach my $method_pair (@gir_namespace_methods)
+    {
+      my $count_method = $method_pair->[0];
+      my $index_method = $method_pair->[1];
+      my $count = $gir_namespace->$count_method;
+
+      for (my $iter = 0; $iter < $count; ++$iter)
+      {
+        my $gir_stuff = $gir_namespace->$index_method ($iter);
+
+        if (defined ($gir_stuff))
+        {
+          # Meh, glib:boxed is special
+          if ($gir_stuff->isa('Gir::Api::GlibBoxed'))
+          {
+            my $gir_name = $gir_stuff->get_a_glib_name;
+
+            if ($gir_name eq $stuff)
+            {
+              return $gir_stuff->get_a_glib_type_name;
+            }
+          }
+          else
+          {
+            my $gir_name = $gir_stuff->get_a_name;
+
+            if ($gir_name eq $stuff)
+            {
+              return $gir_stuff->get_a_c_type;
+            }
+          }
+        }
+      }
+    }
+  }
+  return undef;
+}
+
+sub _get_imbue_type ($$)
+{
+  my ($self, $gir_type) = @_;
+  my $sub_type_count = $gir_type->get_g_type_count;
+  my $imbue_type = undef;
+
+  # sub_type_count is greater than 0 only for container types
+  # like GList, GSList and else.
+  if ($sub_type_count > 0)
+  {
+    my @sub_types = ();
+    my $incorrect = 0;
+    my $wrap_parser = $self->_get_wrap_parser;
+
+    for (my $index = 0; $index < $sub_type_count; ++$index)
+    {
+      my $gir_sub_type = $gir_type->get_g_type_by_index ($index);
+      my $gir_sub_c_type = $gir_sub_type->get_a_c_type;
+
+      if (defined ($gir_sub_c_type))
+      {
+        push @sub_types, $gir_sub_c_type;
+      }
+      else
+      {
+        my $gir_sub_name = $gir_sub_type->get_a_name;
+        my @gir_sub_name_parts = split /\./, $gir_sub_name;
+        my $sub_c_type = $self->_c_type_from_name ($gir_sub_name);
+
+        if (defined ($sub_c_type))
+        {
+          push @sub_types, $sub_c_type;
+        }
+        else
+        {
+          $incorrect = 1;
+          last;
+        }
+      }
+    }
+
+    unless ($incorrect)
+    {
+      $imbue_type = '`' . join (', ', @sub_types) . '\'';
+    }
+  }
+
+  return $imbue_type;
+}
+
 sub _parse_typed ($$)
 {
   my ($self, $gir_typed) = @_;
@@ -30,8 +230,22 @@ sub _parse_typed ($$)
   if ($gir_typed->get_g_type_count > 0)
   {
     my $gir_type = $gir_typed->get_g_type_by_index (0);
+    my $c_type = $gir_type->get_a_c_type;
+
+    if (defined $c_type and $c_type =~ /^(\w+)/)
+    {
+      my $pure_c_type = $1;
+      my $sub_type_count = $gir_type->get_g_type_count;
+      my $imbue_type = $self->_get_imbue_type ($gir_type);
+
+      if (defined ($imbue_type))
+      {
+        my $imbued_c_type = $pure_c_type . $imbue_type;
 
-    return $gir_type->get_a_c_type;
+        $c_type =~ s/$pure_c_type/$imbued_c_type/;
+      }
+    }
+    return $c_type;
   }
   elsif ($gir_typed->get_g_array_count > 0)
   {
@@ -66,7 +280,7 @@ sub _parse_parameters ($$)
       my $gir_parameter = $gir_parameters->get_g_parameter_by_index ($iter);
       my $name = $gir_parameter->get_a_name;
       my $gir_transfer = $gir_parameter->get_a_transfer_ownership;
-      my $transfer = Common::ConversionsStore::transfer_from_string $gir_transfer;
+      my $transfer = Common::TypeInfo::Common::transfer_from_string ($gir_transfer);
       my $type = $self->_parse_parameter ($gir_parameter);
 
 # TODO: error.
@@ -93,16 +307,16 @@ sub _parse_return_value ($$)
   return $self->_parse_typed ($gir_return_value);
 }
 
-sub new_from_gir ($$)
+sub new_from_gir ($$$)
 {
-  my ($type, $gir_callable) = @_;
+  my ($type, $gir_callable, $wrap_parser) = @_;
   my $class = (ref $type or $type or 'Common::CallableInfo');
   # Bless now, so we can use virtual methods.
-  my $self = bless {}, $class;
+  my $self = bless {'wrap_parser' => $wrap_parser}, $class;
   my $gir_return = $gir_callable->get_g_return_value_by_index (0);
   my $ret = $self->_parse_return_value ($gir_return);
   my $gir_ret_transfer = $gir_return->get_a_transfer_ownership;
-  my $ret_transfer = Common::ConversionsStore::transfer_from_string $gir_ret_transfer;
+  my $ret_transfer = Common::TypeInfo::Common::transfer_from_string ($gir_ret_transfer);
   my $name = $self->_get_name_from_gir ($gir_callable);
   my ($param_types, $param_names, $param_transfers) = $self->_parse_parameters ($gir_callable);
 
diff --git a/tools/pm/Common/Gmmproc.pm b/tools/pm/Common/Gmmproc.pm
index 19d5bf4..c8dabfb 100644
--- a/tools/pm/Common/Gmmproc.pm
+++ b/tools/pm/Common/Gmmproc.pm
@@ -29,7 +29,7 @@ use Common::Scanner;
 use Common::Sections;
 use Common::SectionManager;
 use Common::TokensStore;
-use Common::TypeInfoStore;
+use Common::TypeInfo::Global;
 use Common::WrapParser;
 use Common::Variables;
 
@@ -61,11 +61,9 @@ sub _tokenize_contents_ ($)
 sub _prepare ($)
 {
   my ($self) = @_;
-  my $conversions_store = $self->get_conversions_store;
-  my $type_info_store = $self->get_type_info_store;
+  my $type_info_global = $self->get_type_info_global;
 
-  $conversions_store->add_from_file ('conversions');
-  $type_info_store->add_from_file ('mappings');
+  $type_info_global->add_infos_from_file ('type_infos');
 }
 
 sub _read_all_bases ($)
@@ -124,31 +122,23 @@ sub _scan_all_bases ($)
     my $scanner = Common::Scanner->new ($tokens_hg, $tokens_ccg);
 
     $scanner->scan;
-    $tokens_store->set_pairs ($scanner->get_pairs);
-    $tokens_store->set_conversions ($scanner->get_conversions);
+    $tokens_store->set_tuples ($scanner->get_tuples);
   }
 
-  my $type_info_store = $self->get_type_info_store;
-  my $conversions_store = $self->get_conversions_store;
+  my $type_info_global = $self->get_type_info_global;
 
   foreach my $base (@bases_keys)
   {
     my $tokens_store = $bases->{$base};
-    my $pairs = $tokens_store->get_pairs;
+    my $tuples = $tokens_store->get_tuples;
 
-    foreach my $pair (@{$pairs})
+    foreach my $tuple (@{$tuples})
     {
-      my $c_stuff = $pair->[0];
-      my $cpp_stuff = $pair->[1];
+      my $c_stuff = $tuple->[0];
+      my $cxx_stuff = $tuple->[1];
+      my $macro_type = $tuple->[2];
 
-      $type_info_store->add_new ($c_stuff, $cpp_stuff);
-    }
-
-    my $conversions = $tokens_store->get_conversions;
-
-    foreach my $conversion (@{$conversions})
-    {
-      $conversions_store->add_new_generated (@{$conversion});
+      $type_info_global->add_generated_info ($c_stuff, $cxx_stuff, $macro_type);
     }
   }
 }
@@ -157,9 +147,8 @@ sub _parse_all_bases ($)
 {
   my ($self) = @_;
   my $bases = $self->get_bases;
-  my $type_info_store = $self->get_type_info_store;
+  my $type_info_global = $self->get_type_info_global ();
   my $repositories = $self->get_repositories;
-  my $conversions_store = $self->get_conversions_store;
   my $mm_module = $self->get_mm_module;
 
   # parallelize
@@ -170,9 +159,8 @@ sub _parse_all_bases ($)
     my $tokens_ccg = $tokens_store->get_ccg_tokens;
     my $wrap_parser = Common::WrapParser->new ($tokens_hg,
                                                $tokens_ccg,
-                                               $type_info_store,
+                                               $type_info_global,
                                                $repositories,
-                                               $conversions_store,
                                                $mm_module,
                                                $base);
 
@@ -205,11 +193,9 @@ sub _generate_all_bases ($)
 sub _finish ($)
 {
   my ($self) = @_;
-  my $conversions_store = $self->get_conversions_store;
-  my $type_info_store = $self->get_type_info_store;
+  my $type_info_global = $self->get_type_info_global ();
 
-  $conversions_store->write_to_file ('conversions');
-  $type_info_store->write_to_file ('mappings');
+  $type_info_global->write_generated_infos_to_file ();
 }
 
 sub new ($$$$)
@@ -222,8 +208,7 @@ sub new ($$$$)
     'bases' => {},
     'source_dir' => '.',
     'destination_dir' => '.',
-    'type_info_store' => Common::TypeInfoStore->new ($mm_module, $include_paths),
-    'conversions_store' => Common::ConversionsStore->new_global ($mm_module, $include_paths),
+    'type_info_global' => Common::TypeInfo::Global->new ($mm_module, $include_paths),
     'mm_module' => $mm_module,
     'include_paths' => $include_paths
   };
@@ -301,18 +286,11 @@ sub get_repositories ($)
   return $self->{'repositories'};
 }
 
-sub get_type_info_store ($)
-{
-  my ($self) = @_;
-
-  return $self->{'type_info_store'};
-}
-
-sub get_conversions_store ($)
+sub get_type_info_global ($)
 {
   my ($self) = @_;
 
-  return $self->{'conversions_store'};
+  return $self->{'type_info_global'};
 }
 
 sub get_mm_module ($)
diff --git a/tools/pm/Common/Output/Ctor.pm b/tools/pm/Common/Output/Ctor.pm
index 194f963..3090542 100644
--- a/tools/pm/Common/Output/Ctor.pm
+++ b/tools/pm/Common/Output/Ctor.pm
@@ -96,8 +96,8 @@ sub wrap_ctor ($$$$$$)
   my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
   my $base_member = (lc $cpp_class_type) . '_';
   my $conditional = initially_unowned_sink $wrap_parser;
-  my $conversions_store = $wrap_parser->get_conversions_store;
-  my $ctor_params_str = join ', ', '', (map { join '', '"', $c_prop_names->[$_], '", ', ($conversions_store->get_conversion ($cpp_param_types->[$_], $c_param_types->[$_], $c_param_transfers->[$_], $cpp_param_names->[$_])) } 0 .. (@{$cpp_param_types} - 1)), 'static_cast<char*>(0)';
+  my $type_info_local = $wrap_parser->get_type_info_local ();
+  my $ctor_params_str = join ', ', '', (map { join '', '"', $c_prop_names->[$_], '", ', ($type_info_local->get_conversion ($cpp_param_types->[$_], $c_param_types->[$_], $c_param_transfers->[$_], $cpp_param_names->[$_])) } 0 .. (@{$cpp_param_types} - 1)), 'static_cast<char*>(0)';
 
   $section_manager->append_string_to_section ($code_string, $main_section);
   $code_string = (nl $full_cpp_type, '::', $cpp_type, '(', $cpp_params_str, ')') .
diff --git a/tools/pm/Common/Output/Method.pm b/tools/pm/Common/Output/Method.pm
index 95317e4..c87f934 100644
--- a/tools/pm/Common/Output/Method.pm
+++ b/tools/pm/Common/Output/Method.pm
@@ -116,7 +116,7 @@ sub _output_cc ($$$$$$$$$$$$$$$$)
 
     push @params, $this_param;
 
-    my $conversions_store = $wrap_parser->get_conversions_store;
+    my $type_info_local = $wrap_parser->get_type_info_local ();
     my $convs_str = Common::Output::Shared::convzipstr $wrap_parser, $cpp_param_types, $c_param_types, $c_param_transfers, $cpp_param_names;
 
     if ($convs_str)
@@ -134,7 +134,7 @@ sub _output_cc ($$$$$$$$$$$$$$$$)
 
     unless ($ret_void)
     {
-      $ret_convert = $conversions_store->get_conversion ($c_ret_type, $cpp_ret_type, $ret_transfer, $c_func_invocation);
+      $ret_convert = $type_info_local->get_conversion ($c_ret_type, $cpp_ret_type, $ret_transfer, $c_func_invocation);
     }
 
     if ($errthrow)
diff --git a/tools/pm/Common/Output/Shared.pm b/tools/pm/Common/Output/Shared.pm
index 4c77d9e..7f41ada 100644
--- a/tools/pm/Common/Output/Shared.pm
+++ b/tools/pm/Common/Output/Shared.pm
@@ -592,7 +592,7 @@ sub get_parent_from_object ($$)
 sub convzipstr ($$$$$)
 {
   my ($wrap_parser, $from_types, $to_types, $transfers, $from_names) = @_;
-  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $type_info_local = $wrap_parser->get_type_info_local ();
   my $from_types_count = @{$from_types};
   my $to_types_count = @{$to_types};
   my $transfers_count = @{$transfers};
@@ -600,7 +600,7 @@ sub convzipstr ($$$$$)
 
 # TODO: throw runtime error or internal error or whatever.
   die if $from_types_count != $to_types_count or $to_types_count != $transfers_count or $transfers_count != $from_names_count;
-  return join ', ', map { $conversions_store->get_conversion ($from_types->[$_], $to_types->[$_], $transfers->[$_], $from_names->[$_]) } 0 .. $from_types_count - 1;
+  return join ', ', map { $type_info_local->get_conversion ($from_types->[$_], $to_types->[$_], $transfers->[$_], $from_names->[$_]) } 0 .. $from_types_count - 1;
 }
 
 sub deprecate_start ($)
diff --git a/tools/pm/Common/Output/Signal.pm b/tools/pm/Common/Output/Signal.pm
index b53f742..eff8ad2 100644
--- a/tools/pm/Common/Output/Signal.pm
+++ b/tools/pm/Common/Output/Signal.pm
@@ -85,7 +85,7 @@ sub _output_cc ($$$$$$$$$$$$$$)
   my $proxy_info = $signal_prefix . '_signal_' . $cpp_signal_name . '_info';
   my $ret_void = ($c_return_type eq 'void');
   my $cpp_param_types_str = join ', ', @cpp_param_types;
-  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $type_info_local = $wrap_parser->get_type_info_local ();
   my $code_string = Common::Output::Shared::ifdef $ifdef;
 
   if ($ret_void and not @{$c_param_types} and $cpp_return_type eq 'void' and not @{$cpp_param_types})
@@ -122,12 +122,12 @@ sub _output_cc ($$$$$$$$$$$$$$)
 
       unless ($ret_void)
       {
-        if ($c_return_transfer == Common::ConversionsStore and $c_return_type =~ /\*$/)
+        if ($c_return_transfer == Common::TypeInfo::Common::TRANSFER_NONE and $c_return_type =~ /\*$/)
         {
 # TODO: print a warning - pointers returned from signals ought to have ownership transferred fully.
 # TODO continued: need warning or error with fixed line number for this.
         }
-        my $conv = $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $return_string);
+        my $conv = $type_info_local->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $return_string);
 
         $return_string = 'return ' . $conv;
         $last_return = nl () .
@@ -237,7 +237,7 @@ sub _output_cc ($$$$$$$$$$$$$$)
     }
     else
     {
-      my $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, $c_func_invocation);
+      my $conv = $type_info_local->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, $c_func_invocation);
 
       $code_string .= nl ('    return ' . $conv . ';');
       $last_return = nl () .
@@ -273,7 +273,7 @@ sub _output_p_cc ($$$$$$$$$$$$$)
 
     my $c_params_str = Common::Output::Shared::zupstr $c_param_types, $c_param_names, ' ', ', ';
     my $ret_void = ($c_return_type eq 'void');
-    my $conversions_store = $wrap_parser->get_conversions_store;
+    my $type_info_local = $wrap_parser->get_type_info_local ();
     my $convs_str = Common::Output::Shared::convzipstr $c_param_types, $cpp_param_types, $c_param_transfers, $c_param_names;
     my $vfunc_call = 'obj->on_' . $cpp_signal_name . '(' . $convs_str . ')';
     my $c_callback_call = '(*base->' . $c_signal_name . '(self, ' . (join ', ', @{$c_param_names}) . ')';
@@ -281,7 +281,7 @@ sub _output_p_cc ($$$$$$$$$$$$$)
 
     unless ($ret_void)
     {
-      $vfunc_call = 'return ' . $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $vfunc_call);
+      $vfunc_call = 'return ' . $type_info_local->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $vfunc_call);
       $c_callback_call = 'return ' . $c_callback_call;
       $last_return = nl () .
                      nl ('  typedef ' . $c_return_type . ' RType;') .
diff --git a/tools/pm/Common/Output/VFunc.pm b/tools/pm/Common/Output/VFunc.pm
index 8b79c4b..aa4f298 100644
--- a/tools/pm/Common/Output/VFunc.pm
+++ b/tools/pm/Common/Output/VFunc.pm
@@ -76,7 +76,7 @@ sub _output_cc ($$$$$$$$$$$$$)
   my $cpp_to_c_params_str = (Common::Output::Shared::convzipstr $wrap_parser, $cpp_param_types, $c_param_types, $c_param_transfers, $cpp_param_names) . ($errthrow ? ', &temp_error' : '');
   my $c_func_invocation = join '', '(*base->', $c_vfunc_name, ')(', $gobj, ', ', $cpp_to_c_params_str . ')';
   my $last_return = '';
-  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $type_info_local = $wrap_parser->get_type_info_local ();
   my $error_init_string = (nl '    GError* temp_error(0);');
   my $errthrow_string = (nl '    if (temp_error)') .
                         (nl '    {') .
@@ -112,11 +112,11 @@ sub _output_cc ($$$$$$$$$$$$$)
                       (nl) .
                       $errthrow_string .
                       (nl);
-      $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, 'temp_retval');
+      $conv = $type_info_local->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, 'temp_retval');
     }
     else
     {
-      $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, $c_func_invocation);
+      $conv = $type_info_local->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, $c_func_invocation);
     }
     $code_string .= nl ('    return ' . $conv . ';');
     $last_return = (nl) .
@@ -147,7 +147,7 @@ sub _output_p_cc ($$$$$$$$$$$$)
 
   my $c_params_str = (Common::Output::Shared::paramzipstr $c_param_types, $c_param_names) . ($errthrow ? ', GError** gerror' : '');
   my $ret_void = ($c_return_type eq 'void');
-  my $conversions_store = $wrap_parser->get_conversions_store;
+  my $type_info_local = $wrap_parser->get_type_info_local ();
   my $convs_str = Common::Output::Shared::convzipstr $wrap_parser, $c_param_types, $cpp_param_types, $c_param_transfers, $c_param_names;
   my $vfunc_call = 'obj->' . $cpp_vfunc_name . '(' . $convs_str . ')';
   my $c_callback_call = '(*base->' . $c_vfunc_name . '(self, ' . (join ', ', @{$c_param_names}) . ($errthrow ? ', gerror' : '') . ')';
@@ -156,7 +156,7 @@ sub _output_p_cc ($$$$$$$$$$$$)
 
   unless ($ret_void)
   {
-    $vfunc_call = 'return ' . $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $vfunc_call);
+    $vfunc_call = 'return ' . $type_info_local->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $vfunc_call);
     $c_callback_call = 'return ' . $c_callback_call;
     $after_catch_return = (nl) .
                           (nl '      typedef ', $c_return_type, ' RType;') .
diff --git a/tools/pm/Common/Scanner.pm b/tools/pm/Common/Scanner.pm
index eee7a37..5c65c5e 100644
--- a/tools/pm/Common/Scanner.pm
+++ b/tools/pm/Common/Scanner.pm
@@ -181,12 +181,12 @@ sub _make_full_type ($$)
   }
 }
 
-sub _append ($$$)
+sub _append ($$$$)
 {
-  my ($self, $c_stuff, $cpp_stuff) = @_;
-  my $pairs = $self->get_pairs;
+  my ($self, $c_stuff, $cxx_stuff, $macro_type) = @_;
+  my $tuples = $self->get_tuples;
 
-  push @{$pairs}, [$c_stuff, $cpp_stuff];
+  push @{$tuples}, [$c_stuff, $cxx_stuff, $macro_type];
 }
 
 sub _get_params ($)
@@ -208,7 +208,7 @@ sub _on_wrap_func_generic ($$)
   my $cpp_function = Common::Shared::parse_function_declaration ($args->[0])->[2];
   my $c_function = $args->[1];
 
-  $self->_append ($c_function, $self->_make_full_type ($cpp_function));
+  $self->_append ($c_function, $self->_make_full_type ($cpp_function), 'FUNC');
 }
 
 sub _on_wrap_enum_generic ($$)
@@ -217,19 +217,21 @@ sub _on_wrap_enum_generic ($$)
   my $cpp_enum = $args->[0];
   my $c_enum = $args->[1];
 
-  $self->_append ($c_enum, $self->_make_full_type ($cpp_enum));
+  $self->_append ($c_enum, $self->_make_full_type ($cpp_enum), 'ENUM');
 }
 
-sub _on_wrap_class_generic ($$)
+sub _on_wrap_class_generic ($$$)
 {
-  my ($self, $args) = @_;
+  my ($self, $args, $macro_type) = @_;
   my $classes = $self->_get_classes;
   my $cpp_class = $args->[0];
   my $c_class = $args->[1];
 
   if (@{$classes} > 0 and $classes->[-1] eq $cpp_class)
   {
-    $self->_append ($c_class, $self->_make_full_type (undef));
+    my $cxx_full_type = $self->_make_full_type (undef);
+
+    $self->_append ($c_class, $self->_make_full_type (undef), $macro_type);
   }
 }
 
@@ -614,7 +616,6 @@ sub _on_wrap_enum ($)
   if (defined $args)
   {
     $self->_on_wrap_enum_generic ($args);
-    $self->_on_convert_enum ($args);
   }
 }
 
@@ -626,7 +627,6 @@ sub _on_wrap_gerror ($)
   if (defined $args)
   {
     $self->_on_wrap_enum_generic ($args);
-    $self->_on_convert_enum ($args);
   }
 }
 
@@ -637,8 +637,8 @@ sub _on_class_generic ($)
 
   if (defined $args)
   {
-    $self->_on_wrap_class_generic ($args);
     # no conversion generation possible - it have to be provided manually.
+    $self->_on_wrap_class_generic ($args, 'MANUAL');
   }
 }
 
@@ -649,8 +649,7 @@ sub _on_class_g_object ($)
 
   if (defined $args)
   {
-    $self->_on_wrap_class_generic ($args);
-    $self->_on_convert_reffed_class ($args);
+    $self->_on_wrap_class_generic ($args, 'REFFED');
   }
 }
 
@@ -661,8 +660,7 @@ sub _on_class_gtk_object ($)
 
   if (defined $args)
   {
-    $self->_on_wrap_class_generic ($args);
-    $self->_on_convert_class ($args); # Glib::wrap and Glib::unwrap
+    $self->_on_wrap_class_generic ($args, 'NORMAL');
   }
 }
 
@@ -673,8 +671,7 @@ sub _on_class_boxed_type ($)
 
   if (defined $args)
   {
-    $self->_on_wrap_class_generic ($args);
-    $self->_on_convert_class ($args); # Glib::wrap and Glib::unwrap
+    $self->_on_wrap_class_generic ($args, 'NORMAL');
   }
 }
 
@@ -685,8 +682,7 @@ sub _on_class_boxed_type_static ($)
 
   if (defined $args)
   {
-    $self->_on_wrap_class_generic ($args);
-    $self->_on_convert_class ($args); # Glib::wrap and Glib::unwrap
+    $self->_on_wrap_class_generic ($args, 'NORMAL');
   }
 }
 
@@ -697,8 +693,8 @@ sub _on_class_interface ($)
 
   if (defined $args)
   {
-    $self->_on_wrap_class_generic ($args);
 # TODO: which convert? reffed or not? probably both. probably manual.
+    $self->_on_wrap_class_generic ($args, 'MANUAL');
   }
 }
 
@@ -709,8 +705,7 @@ sub _on_class_opaque_copyable ($)
 
   if (defined $args)
   {
-    $self->_on_wrap_class_generic ($args);
-    $self->_on_convert_class ($args); # Glib::wrap and Glib::unwrap
+    $self->_on_wrap_class_generic ($args, 'NORMAL');
   }
 }
 
@@ -721,8 +716,7 @@ sub _on_class_opaque_refcounted ($)
 
   if (defined $args)
   {
-    $self->_on_wrap_class_generic ($args);
-    $self->_on_convert_reffed_class ($args);
+    $self->_on_wrap_class_generic ($args, 'REFFED');
   }
 }
 
@@ -858,8 +852,7 @@ sub new ($$$)
   my $self =
   {
     'tokens' => undef,
-    'pairs' => [],
-    'conversions' => [],
+    'tuples' => [],
     'stages' =>
     {
       STAGE_HG () => \ tokens_hg_copy,
@@ -942,11 +935,11 @@ sub scan ($)
   }
 }
 
-sub get_pairs ($)
+sub get_tuples ($)
 {
   my ($self) = @_;
 
-  return $self->{'pairs'};
+  return $self->{'tuples'};
 }
 
 sub get_conversions ($)
diff --git a/tools/pm/Common/SignalInfo.pm b/tools/pm/Common/SignalInfo.pm
index b0624fb..a41692b 100644
--- a/tools/pm/Common/SignalInfo.pm
+++ b/tools/pm/Common/SignalInfo.pm
@@ -27,158 +27,43 @@ use parent qw (Common::CallableInfo);
 
 sub _guess_typed ($$)
 {
-  my ($gir_typed, $wrap_parser) = @_;
-  my $name = '';
+  my ($self, $gir_typed) = @_;
+  my $name = undef;
+  my $imbue_type = undef;
 
   if ($gir_typed->get_g_type_count > 0)
   {
     my $gir_type = $gir_typed->get_g_type_by_index (0);
 
     $name = $gir_type->get_a_name;
+    $imbue_type = $self->_get_imbue_type ($gir_type);
   }
   elsif ($gir_typed->get_g_array_count > 0)
   {
-    return _guess_typed $gir_typed->get_g_array_by_index(0);
+    return $self->_guess_typed ($gir_typed->get_g_array_by_index (0));
   }
 
-  if ($name eq 'utf8' or $name eq 'filename')
-  {
-    return 'gchar*';
-  }
-  else
+  die unless (defined ($name));
+
+  my $c_type = $self->_c_type_from_name ($name);
+
+  die unless (defined ($c_type));
+
+  if (defined ($imbue_type) and $c_type =~ /^(\w+)/)
   {
-    my $namespace = undef;
-    my $stuff = undef;
-
-    if ($name =~ /^(\w)\.(\w)$/)
-    {
-      $namespace = $1;
-      $stuff = $2;
-    }
-    elsif ($name =~ /^[A-Z]/)
-    {
-      $namespace = $wrap_parser->get_module;
-      $stuff = $name;
-    }
-    else # probably something like gint or gboolean
-    {
-      return $name;
-    }
-
-    my $repositories = $wrap_parser->get_repositories;
-    my $gir_repository = $repositories->get_repository ($namespace);
-    my $gir_namespace = $gir_repository->get_g_namespace_by_name ($namespace);
-    my @gir_symbol_prefixes = split ',', $gir_namespace->get_a_c_symbol_prefixes;
-    my @gir_namespace_methods =
-    (
-      \&Gir::Api::Namespace::get_g_class_by_name,
-      \&Gir::Api::Namespace::get_g_interface_by_name,
-      \&Gir::Api::Namespace::get_g_glib_boxed_by_name,
-      \&Gir::Api::Namespace::get_g_record_by_name,
-      \&Gir::Api::Namespace::get_g_enumeration_by_name,
-      \&Gir::Api::Namespace::get_g_bitfield_by_name,
-      \&Gir::Api::Namespace::get_g_union_by_name
-    );
-
-    foreach my $symbol_prefix (@gir_symbol_prefixes)
-    {
-      my $maybe_c_name = $symbol_prefix . $stuff;
-
-      foreach my $method (@gir_namespace_methods)
-      {
-        my $gir_stuff = $gir_namespace->$method ($maybe_c_name);
-
-        if ($gir_stuff)
-        {
-          # Meh, glib:boxed is special
-          if ($gir_stuff->isa ('Gir::Api::GlibBoxed'))
-          {
-            return $gir_stuff->get_a_glib_type_name;
-          }
-          else
-          {
-            return $gir_stuff->get_a_c_type;
-          }
-        }
-      }
-    }
-# Argh, probably our guess at C name was just wrong.
-# Taking longer route at guessing the C type.
-    @gir_namespace_methods =
-    (
-      [
-        \&Gir::Api::Namespace::get_g_class_count,
-        \&Gir::Api::Namespace::get_g_class_by_index
-      ],
-      [
-        \&Gir::Api::Namespace::get_g_interface_count,
-        \&Gir::Api::Namespace::get_g_interface_by_index
-      ],
-      [
-        \&Gir::Api::Namespace::get_g_glib_boxed_count,
-        \&Gir::Api::Namespace::get_g_glib_boxed_by_index
-      ],
-      [
-        \&Gir::Api::Namespace::get_g_record_count,
-        \&Gir::Api::Namespace::get_g_record_by_index
-      ],
-      [
-        \&Gir::Api::Namespace::get_g_enumeration_count,
-        \&Gir::Api::Namespace::get_g_enumeration_by_index
-      ],
-      [
-        \&Gir::Api::Namespace::get_g_bitfield_count,
-        \&Gir::Api::Namespace::get_g_bitfield_by_index
-      ],
-      [
-        \&Gir::Api::Namespace::get_g_union_count,
-        \&Gir::Api::Namespace::get_g_union_by_index
-      ]
-    );
-
-    foreach my $method_pair (@gir_namespace_methods)
-    {
-      my $count_method = $method_pair->[0];
-      my $index_method = $method_pair->[1];
-      my $count = $gir_namespace->$count_method;
-
-      for (my $iter = 0; $iter < $count; ++$iter)
-      {
-        my $gir_stuff = $gir_namespace->$index_method ($iter);
-
-        if ($gir_stuff)
-        {
-          # Meh, glib:boxed is special
-          if ($gir_stuff->isa('Gir::Api::GlibBoxed'))
-          {
-            my $gir_name = $gir_stuff->get_a_glib_name;
-
-            if ($gir_name eq $stuff)
-            {
-              return $gir_stuff->get_a_glib_type_name;
-            }
-          }
-          else
-          {
-            my $gir_name = $gir_stuff->get_a_name;
-
-            if ($gir_name eq $stuff)
-            {
-              return $gir_stuff->get_a_c_type;
-            }
-          }
-        }
-      }
-    }
-    # Huh, got nothing?
-    die;
+    my $pure_c_type = $1;
+    my $imbued_c_type = $pure_c_type . $imbue_type;
+
+    $c_type =~ s/$pure_c_type/$imbued_c_type/;
   }
+
+  return $c_type;
 }
 
 sub _guess_parameter ($$)
 {
-  my ($gir_parameter, $wrap_parser) = @_;
-  my $c_type = _guess_typed $gir_parameter, $wrap_parser;
+  my ($self, $gir_parameter) = @_;
+  my $c_type = $self->_guess_typed ($gir_parameter);
   my $gir_direction = $gir_parameter->get_a_direction;
 
   # out parameters in C have to be pointers.
@@ -190,13 +75,6 @@ sub _guess_parameter ($$)
   return $c_type;
 }
 
-sub _get_wrap_parser ($)
-{
-  my ($self) = @_;
-
-  return $self->{'wrap_parser'};
-}
-
 sub _get_name_from_gir ($$)
 {
   my (undef, $gir_signal) = @_;
@@ -211,7 +89,7 @@ sub _parse_parameter ($$)
 
   unless ($type)
   {
-    $type = _guess_parameter $gir_parameter, $self->_get_wrap_parser;
+    $type = $self->_guess_parameter ($gir_parameter);
   }
 
   return $type;
@@ -224,7 +102,7 @@ sub _parse_return_value ($$)
 
   unless ($type)
   {
-    $type = _guess_typed $gir_return_value, $self->_get_wrap_parser;
+    $type = $self->_guess_typed ($gir_return_value);
   }
 
   return $type;
@@ -234,7 +112,7 @@ sub new_from_gir ($$$)
 {
   my ($type, $gir_function, $wrap_parser) = @_;
   my $class = (ref $type or $type or 'Common::SignalInfo');
-  my $self = $class->SUPER::new ($gir_function);
+  my $self = $class->SUPER::new ($gir_function, $wrap_parser);
 
   return bless $self, $class;
 }
diff --git a/tools/pm/Common/TokensStore.pm b/tools/pm/Common/TokensStore.pm
index 8772e67..078c1c1 100644
--- a/tools/pm/Common/TokensStore.pm
+++ b/tools/pm/Common/TokensStore.pm
@@ -29,8 +29,7 @@ sub new ($)
   my $class = (ref $type or $type or 'Common::TokensStore');
   my $self =
   {
-    'pairs' => [],
-    'conversions' => [],
+    'tuples' => [],
     'section_manager' => undef,
     'tokens_hg' => undef,
     'tokens_ccg' => undef
@@ -39,32 +38,18 @@ sub new ($)
   return bless $self, $class;
 }
 
-sub set_pairs ($$)
+sub set_tuples ($$)
 {
-  my ($self, $pairs) = @_;
+  my ($self, $tuples) = @_;
 
-  $self->{'pairs'} = $pairs;
+  $self->{'tuples'} = $tuples;
 }
 
-sub get_pairs ($)
+sub get_tuples ($)
 {
   my ($self) = @_;
 
-  return $self->{'pairs'};
-}
-
-sub set_conversions ($$)
-{
-  my ($self, $conversions) = @_;
-
-  $self->{'conversions'} = $conversions;
-}
-
-sub get_conversions ($)
-{
-  my ($self) = @_;
-
-  return $self->{'conversions'};
+  return $self->{'tuples'};
 }
 
 sub set_section_manager ($$)
diff --git a/tools/pm/Common/WrapParser.pm b/tools/pm/Common/WrapParser.pm
index 4d43994..c7030d2 100644
--- a/tools/pm/Common/WrapParser.pm
+++ b/tools/pm/Common/WrapParser.pm
@@ -32,7 +32,7 @@ use Common::Util;
 use Common::SectionManager;
 use Common::Shared;
 use Common::Output;
-use Common::ConversionsStore;
+use Common::TypeInfo::Local;
 use constant
 {
   'STAGE_HG' => 0,
@@ -681,11 +681,11 @@ sub _maybe_warn_about_refreturn ($$$)
 {
   my ($self, $ret_transfer, $refreturn) = @_;
 
-  if ($ret_transfer == Common::ConversionsStore::TRANSFER_FULL and $refreturn)
+  if ($ret_transfer == Common::TypeInfo::Common::TRANSFER_FULL and $refreturn)
   {
     $self->fixed_warning ('refreturn given but annotation says that transfer is already full - which is wrong? (refreturn is ignored anyway.)');
   }
-  elsif ($ret_transfer == Common::ConversionsStore::TRANSFER_NONE and not $refreturn)
+  elsif ($ret_transfer == Common::TypeInfo::Common::TRANSFER_NONE and not $refreturn)
   {
     $self->fixed_warning ('There is no refreturn, but annotation says that transfer is none - which is wrong? (refreturn would be ignored anyway.)');
   }
@@ -786,7 +786,7 @@ sub _on_wrap_method ($)
     }
   }
 
-  my $c_function = Common::CFunctionInfo->new_from_gir ($gir_func);
+  my $c_function = Common::CFunctionInfo->new_from_gir ($gir_func, $self);
   my $ret_transfer = $c_function->get_return_transfer;
   my $throws = $c_function->get_throws;
 
@@ -938,7 +938,7 @@ sub _on_wrap_signal ($)
     $self->fixed_error ('No such signal: ' . $c_signal_str);
   }
 
-  my $c_signal = Common::SignalInfo->new_from_gir ($gir_signal);
+  my $c_signal = Common::SignalInfo->new_from_gir ($gir_signal, $self);
   my $ret_transfer = $c_signal->get_return_transfer;
 
 # TODO: remove the ifs below after possible bugs in
@@ -1084,7 +1084,7 @@ sub _on_wrap_vfunc ($)
     $self->fixed_error ('No such virtual method: ' . $c_vfunc_name);
   }
 
-  my $c_vfunc = Common::CFunctionInfo->new_from_gir ($gir_vfunc);
+  my $c_vfunc = Common::CFunctionInfo->new_from_gir ($gir_vfunc, $self);
   my $ret_transfer = $c_vfunc->get_return_transfer;
   my $throws = $c_vfunc->get_throws;
 
@@ -1142,7 +1142,7 @@ sub _on_wrap_ctor ($)
     $self->fixed_error ('No such constructor: ' . $c_constructor_name);
   }
 
-  my $c_constructor = Common::CFunctionInfo->new_from_gir ($gir_constructor);
+  my $c_constructor = Common::CFunctionInfo->new_from_gir ($gir_constructor, $self);
   my $c_param_names = $c_constructor->get_param_names;
   my $cxx_param_names = $cxx_function->get_param_names;
   my $c_params_count = @{$c_param_names};
@@ -1554,10 +1554,11 @@ sub _on_class_g_object ($)
     }
   }
 
-  my $type_info_store = $self->get_type_info_store;
+  my $type_info_local = $self->get_type_info_local;
 # TODO: write an info about adding mapping when returned value
 # TODO continued: is undefined.
-  my $cpp_parent_type = $type_info_store->c_to_cpp ($c_parent_type);
+  my $cxx_parent_type = $type_info_local->c_to_cxx ($c_parent_type);
+
 
   $self->_push_gir_class ($gir_class);
   $self->_push_c_class ($c_type);
@@ -1569,7 +1570,7 @@ sub _on_class_g_object ($)
                                   $c_parent_class_type,
                                   $get_type_func,
                                   $cpp_type,
-                                  $cpp_parent_type;
+                                  $cxx_parent_type;
 }
 
 # TODO: set current gir_class.
@@ -1949,8 +1950,8 @@ sub _on_class_interface ($)
     }
   }
 
-  my $type_info_store = $self->get_type_info_store;
-  my $cpp_parent_name = $type_info_store->c_to_cpp ($c_parent_name);
+  my $type_info_local = $self->get_type_info_local;
+  my $cxx_parent_type = $type_info_local->c_to_cxx ($c_parent_name);
 
   $self->_push_gir_class ($gir_class);
 
@@ -1959,7 +1960,7 @@ sub _on_class_interface ($)
                                     $c_class_name,
                                     $c_parent_name,
                                     $cpp_name,
-                                    $cpp_parent_name,
+                                    $cxx_parent_type,
                                     $get_type_func;
 }
 
@@ -2565,9 +2566,9 @@ sub get_repositories ($)
 }
 
 # public
-sub new ($$$$$$$)
+sub new ($$$$$$)
 {
-  my ($type, $tokens_hg, $tokens_ccg, $type_info_store, $repositories, $conversions_store, $mm_module, $base) = @_;
+  my ($type, $tokens_hg, $tokens_ccg, $type_info_global, $repositories, $mm_module, $base) = @_;
   my $class = (ref $type or $type or 'Common::WrapParser');
   my $self =
   {
@@ -2594,9 +2595,8 @@ sub new ($$$$$$$)
       STAGE_CCG() => [Common::Sections::CC_CONTENTS, 'tokens_ccg', 'ccg'],
       STAGE_INVALID() => [Common::Sections::DEV_NULL, 'tokens_null', 'BAD']
     },
-    'type_info_store' => $type_info_store,
+    'type_info_local' => Common::TypeInfo::Local->new ($type_info_global),
     'counter' => 0,
-    'conversions_store' => Common::ConversionsStore->new_local ($conversions_store),
     'gir_stack' => [],
     'c_stack' => [],
     'mm_module' => $mm_module,
@@ -2660,6 +2660,13 @@ sub get_type_info_store ($)
   return $self->{'type_info_store'};
 }
 
+sub get_type_info_local ($)
+{
+  my ($self) = @_;
+
+  return $self->{'type_info_local'};
+}
+
 sub get_number ($)
 {
   my ($self) = @_;
diff --git a/tools/pm/TODO b/tools/pm/TODO
index 9e661eb..049b536 100644
--- a/tools/pm/TODO
+++ b/tools/pm/TODO
@@ -222,6 +222,16 @@
 - Gir::Config::get_girdir should return an array of paths.
   VERIFY.
 
+- Prepend keys in Common::TypeInfo::Global's general
+  conversions topmost layer with prefixes saying about
+  language of type (e.g. 'C##' or 'CXX##'). Another idea would
+  be to introduce new topmost layer with only two keys: 'C'
+  and 'CXX'. That way, we could easily determine whether we
+  are doing conversions from C to C++ or vice versa and we
+  could leave mappings to the role it was thought of at the
+  beginning - to provide mappings mostly for documentation.
+  DONE.
+
 - git grep -n 'TODO' tools/pm
 
 - Cleanup this TODO. :-)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]