summaryrefslogtreecommitdiff
path: root/giscanner
diff options
context:
space:
mode:
authorJohan Dahlin <johan@gnome.org>2010-06-12 18:08:56 -0300
committerJohan Dahlin <johan@gnome.org>2010-07-09 10:15:45 -0300
commit1e9822c7817062a9b853269b9418fd78782090b5 (patch)
tree684a6bc8520db45c9d126d954d7b82921cb2a753 /giscanner
parent017727630d09a854b1c1a4767066fb675b139de9 (diff)
downloadgobject-introspection-1e9822c7817062a9b853269b9418fd78782090b5.tar.gz
Add support for non-GObject fundamental objects
This patch adds support for instantiable fundamental object types, which are not GObject based. This is mostly interesting for being able to support GstMiniObject's which are extensivly used in GStreamer. Includes a big test case to the Everything module (inspired by GstMiniObject) which should be used by language bindings who wishes to test this functionallity. This patch increases the size of the typelib and breaks compatibility with older typelibs. https://bugzilla.gnome.org/show_bug.cgi?id=568913
Diffstat (limited to 'giscanner')
-rw-r--r--giscanner/annotationparser.py15
-rw-r--r--giscanner/girwriter.py11
-rw-r--r--giscanner/glibast.py5
-rw-r--r--giscanner/glibtransformer.py32
4 files changed, 63 insertions, 0 deletions
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 03ffb546..c642d56e 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -52,6 +52,10 @@ TAG_ATTRIBUTES = 'attributes'
TAG_RENAME_TO = 'rename to'
TAG_TYPE = 'type'
TAG_TRANSFER = 'transfer'
+TAG_UNREF_FUNC = 'unref func'
+TAG_REF_FUNC = 'ref func'
+TAG_SET_VALUE_FUNC = 'set value func'
+TAG_GET_VALUE_FUNC = 'get value func'
# Options - annotations for parameters and return values
OPT_ALLOW_NONE = 'allow-none'
@@ -361,6 +365,7 @@ class AnnotationApplier(object):
self._parse_fields(class_, class_.fields)
if block:
class_.doc = block.comment
+ self._parse_type_instance_tags(class_, block)
def _parse_interface(self, interface):
block = self._blocks.get(interface.type_name)
@@ -911,6 +916,16 @@ class AnnotationApplier(object):
if OPT_FOREIGN in block.options:
node.foreign = True
+ def _parse_type_instance_tags(self, node, block):
+ tag = self._get_tag(block, TAG_UNREF_FUNC)
+ node.unref_func = tag.value if tag else None
+ tag = self._get_tag(block, TAG_REF_FUNC)
+ node.ref_func = tag.value if tag else None
+ tag = self._get_tag(block, TAG_SET_VALUE_FUNC)
+ node.set_value_func = tag.value if tag else None
+ tag = self._get_tag(block, TAG_GET_VALUE_FUNC)
+ node.get_value_func = tag.value if tag else None
+
def _parse_rename_to_func(self, node, block):
rename_to_tag = self._get_tag(block, TAG_RENAME_TO)
if rename_to_tag is None:
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 5e29d067..2e0a6cdc 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -348,6 +348,17 @@ and/or use gtk-doc annotations. ''')
attrs.append(('glib:get-type', node.get_type))
if node.glib_type_struct:
attrs.append(('glib:type-struct', node.glib_type_struct.name))
+ if isinstance(node, GLibObject):
+ if node.fundamental:
+ attrs.append(('glib:fundamental', '1'))
+ if node.ref_func:
+ attrs.append(('glib:ref-func', node.ref_func))
+ if node.unref_func:
+ attrs.append(('glib:unref-func', node.unref_func))
+ if node.set_value_func:
+ attrs.append(('glib:set-value-func', node.set_value_func))
+ if node.get_value_func:
+ attrs.append(('glib:get-value-func', node.get_value_func))
with self.tagcontext(tag_name, attrs):
self._write_generic(node)
if isinstance(node, GLibObject):
diff --git a/giscanner/glibast.py b/giscanner/glibast.py
index fb1ef208..c7129883 100644
--- a/giscanner/glibast.py
+++ b/giscanner/glibast.py
@@ -120,6 +120,11 @@ class GLibObject(Class):
Class.__init__(self, name, parent, is_abstract)
self.type_name = type_name
self.get_type = get_type
+ self.fundamental = False
+ self.unref_func = None
+ self.ref_func = None
+ self.set_value_func = None
+ self.get_value_func = None
self.signals = []
self.ctype = ctype or type_name
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 3b088bcb..1178c5fa 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -689,6 +689,8 @@ class GLibTransformer(object):
self._introspect_interface(xmlnode)
elif xmlnode.tag == 'boxed':
self._introspect_boxed(xmlnode)
+ elif xmlnode.tag == 'fundamental':
+ self._introspect_fundamental(xmlnode)
else:
raise ValueError("Unhandled introspection XML tag %s", xmlnode.tag)
@@ -808,6 +810,36 @@ class GLibTransformer(object):
node.signals.append(signal)
node.signals = sorted(node.signals)
+ def _introspect_fundamental(self, xmlnode):
+ # We only care about types that can be instantiatable, other
+ # fundamental types such as the Clutter.Fixed/CoglFixed registers
+ # are not yet interesting from an introspection perspective and
+ # are ignored
+ if not xmlnode.attrib.get('instantiatable', False):
+ return
+
+ type_name = xmlnode.attrib['name']
+
+ # Get a list of parents here; some of them may be hidden, and what
+ # we really want to do is use the most-derived one that we know of.
+ if 'parents' in xmlnode.attrib:
+ parent_type_names = xmlnode.attrib['parents'].split(',')
+ parent_gitype = self._resolve_gtypename_chain(parent_type_names)
+ else:
+ parent_gitype = None
+ is_abstract = bool(xmlnode.attrib.get('abstract', False))
+ node = GLibObject(
+ self._transformer.remove_prefix(type_name),
+ parent_gitype,
+ type_name,
+ xmlnode.attrib['get-type'], is_abstract)
+ node.fundamental = True
+ self._introspect_implemented_interfaces(node, xmlnode)
+
+ self._add_record_fields(node)
+ self._add_attribute(node, replace=True)
+ self._register_internal_type(type_name, node)
+
def _add_record_fields(self, node):
# add record fields
record = self._get_attribute(node.name)