[gobject-introspection/transformer] g-ir-scanner --passthrough-gir basically works
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection/transformer] g-ir-scanner --passthrough-gir basically works
- Date: Wed, 7 Jul 2010 20:40:52 +0000 (UTC)
commit 5ebd93da24adfced551d476935b0c9eda47b8700
Author: Colin Walters <walters verbum org>
Date: Thu Jun 17 15:55:37 2010 -0400
g-ir-scanner --passthrough-gir basically works
docs/g-ir-scanner.1 | 3 -
gir/Makefile.am | 7 +-
giscanner/annotationparser.py | 4 +-
giscanner/ast.py | 399 +++++++++++++++++---------------
giscanner/girparser.py | 298 +++++++++++++++--------
giscanner/girwriter.py | 123 +++++-----
giscanner/glibast.py | 14 +-
giscanner/glibtransformer.py | 525 +++++++++++++----------------------------
giscanner/scannermain.py | 76 ++-----
giscanner/sourcescanner.py | 10 +-
giscanner/transformer.py | 302 +++++------------------
11 files changed, 736 insertions(+), 1025 deletions(-)
---
diff --git a/docs/g-ir-scanner.1 b/docs/g-ir-scanner.1
index b43d3f1..750660a 100644
--- a/docs/g-ir-scanner.1
+++ b/docs/g-ir-scanner.1
@@ -106,9 +106,6 @@ several pkg-config packages.
.B \--verbose
Be verbose, include some debugging information.
.TP
-.B \--noclosure
-Do not delete unknown types from the resulting format.
-.TP
.B \--typelib-xml
Convert the resulting xml to only output the types relevant
to the typelib compiler. This is mainly useful for verifying the
diff --git a/gir/Makefile.am b/gir/Makefile.am
index 8fa02b0..2300297 100644
--- a/gir/Makefile.am
+++ b/gir/Makefile.am
@@ -31,7 +31,7 @@ GLIB_LIBRARY=glib-2.0
endif
GLib_2_0_gir_LIBS = $(GLIB_LIBRARY)
-GLib_2_0_gir_SCANNERFLAGS = --noclosure --strip-prefix=g --c-include="glib.h"
+GLib_2_0_gir_SCANNERFLAGS = --strip-prefix=g --c-include="glib.h"
GLib_2_0_gir_PACKAGES = glib-2.0
GLib_2_0_gir_CFLAGS = \
-I$(GLIB_INCLUDEDIR) \
@@ -61,7 +61,7 @@ endif
GObject-2.0.gir: GLib-2.0.gir
GObject_2_0_gir_LIBS = $(GOBJECT_LIBRARY)
-GObject_2_0_gir_SCANNERFLAGS = --noclosure --strip-prefix=g --c-include="glib-object.h" --add-include-path=.
+GObject_2_0_gir_SCANNERFLAGS = --strip-prefix=g --c-include="glib-object.h" --add-include-path=.
GObject_2_0_gir_PACKAGES = gobject-2.0
GObject_2_0_gir_INCLUDES = GLib-2.0
GObject_2_0_gir_CFLAGS = \
@@ -87,7 +87,7 @@ endif
GModule-2.0.gir: GLib-2.0.gir
GModule_2_0_gir_LIBS = $(GMODULE_LIBRARY)
-GModule_2_0_gir_SCANNERFLAGS = --noclosure --strip-prefix=g --c-include="gmodule.h" --add-include-path=.
+GModule_2_0_gir_SCANNERFLAGS = --strip-prefix=g --c-include="gmodule.h" --add-include-path=.
GModule_2_0_gir_PACKAGES = gmodule-2.0
GModule_2_0_gir_INCLUDES = GLib-2.0
GModule_2_0_gir_CFLAGS = \
@@ -137,7 +137,6 @@ GIRepository-2.0.gir: GObject-2.0.gir $(top_builddir)/girepository/libgireposito
GIRepository_2_0_gir_LIBS = girepository-1.0
GIRepository_2_0_gir_SCANNERFLAGS = \
- --noclosure \
--strip-prefix=g \
--c-include="girepository.h" \
--pkg-export gobject-introspection-1.0 \
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 03ffb54..4af6c03 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -323,7 +323,7 @@ class AnnotationApplier(object):
def parse(self, namespace):
self._namespace = namespace
- for node in namespace.nodes[:]:
+ for node in namespace:
self._parse_node(node)
del self._namespace
@@ -779,7 +779,7 @@ class AnnotationApplier(object):
element_type is None):
# FIXME: unsigned char/guchar should be uint8
container_type.element_type = Type('int8')
- container_type.size = array_values.get(OPT_ARRAY_FIXED_SIZE)
+ container_type.size = int(array_values.get(OPT_ARRAY_FIXED_SIZE))
return container_type
def _resolve(self, type_str, orig_node=None):
diff --git a/giscanner/ast.py b/giscanner/ast.py
index a70f2d8..53e0b68 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -19,6 +19,8 @@
# Boston, MA 02111-1307, USA.
#
+from .odict import odict
+
"""AST nodes
This file descbribes abstract data type nodes independent on the
implementation language.
@@ -168,21 +170,136 @@ default_out_types = (TYPE_SHORT, TYPE_USHORT, TYPE_INT, TYPE_UINT,
def type_name_from_ctype(ctype):
return type_names.get(ctype, ctype)
+class Namespace(object):
+ names = property(lambda self: self._names)
+ aliases = property(lambda self: self._aliases)
+ type_names = property(lambda self: self._type_names)
+ ctypes = property(lambda self: self._ctypes)
-class Node(object):
+ def __init__(self, name, version, c_prefix=None):
+ self.name = name
+ self.version = version
+ self.c_prefix = c_prefix
+ self._names = odict() # Maps from GIName -> node
+ self._aliases = {} # Maps from GIName -> GIName
+ self._type_names = {} # Maps from GTName -> node
+ self._ctypes = {} # Maps from CType -> node
+
+ def type_from_name(self, name, ctype=None):
+ """Backwards compatibility method for older .gir files, which
+only use the 'name' attribute. If name refers to a fundamental type,
+create a Type object referncing it. If name is already a
+fully-qualified GIName like 'Foo.Bar', returns a Type targeting it .
+Otherwise a Type targeting name qualififed with the namespace name is
+returned."""
+ if name in GIR_TYPES:
+ return Type(target_fundamental=name, ctype=ctype)
+ if '.' in name:
+ target = name
+ else:
+ target = '%s.%s' % (self.name, name)
+ return Type(target_giname=target, ctype=ctype)
+
+ def append(self, node, replace=False):
+ previous = self._names.get(node.name)
+ if previous is not None:
+ if not replace:
+ raise SystemExit(
+ "transformer: conflict: ns=%r orig=%r new=%r" %
+ (self.name, previous, node))
+ self.remove(previous)
+ # A layering violation...but oh well.
+ from .glibast import GLibBoxed
+ if isinstance(node, Alias):
+ self._aliases[node.name] = node
+ elif isinstance(node, (GLibBoxed, Interface, Class)):
+ self._type_names[node.type_name] = node
+ assert isinstance(node, Node)
+ assert node.namespace is None
+ node.namespace = self
+ self._names[node.name] = node
+ if hasattr(node, 'ctype'):
+ self._ctypes[node.ctype] = node
+ elif hasattr(node, 'symbol'):
+ self._ctypes[node.symbol] = node
+
+ def remove(self, node):
+ from .glibast import GLibBoxed
+ if isinstance(node, Alias):
+ del self._aliases[node.name]
+ elif isinstance(node, (GLibBoxed, Interface, Class)):
+ del self._type_names[node.type_name]
+ node.namespace = None
+ if hasattr(node, 'ctype'):
+ del self._ctypes[node.ctype]
+ if hasattr(node, 'symbol'):
+ del self._ctypes[node.symbol]
+
+ def __iter__(self):
+ return iter(self._names)
+
+ def iteritems(self):
+ return self._names.iteritems()
+
+ def itervalues(self):
+ return self._names.itervalues()
+
+ def get(self, name):
+ return self._names.get(name)
+
+
+class Include(object):
- def __init__(self, name=None):
+ def __init__(self, name, version):
self.name = name
+ self.version = version
+
+ @classmethod
+ def from_string(self, string):
+ return Include(*string.split('-', 1))
+
+ def __cmp__(self, other):
+ if not isinstance(other, Include):
+ return cmp(self, other)
+ namecmp = cmp(self.name, other.name)
+ if namecmp != 0:
+ return namecmp
+ return cmp(self.version, other.version)
+
+ def __hash__(self):
+ return hash((self.name, self.version))
+
+ def __str__(self):
+ return '%s-%s' % (self.name, self.version)
+
+class Annotated(object):
+ """An object which has a few generic metadata
+properties."""
+ def __init__(self):
+ self.version = None
self.skip = False
self.introspectable = True
self.attributes = [] # (key, value)*
self.deprecated = None
self.deprecated_version = None
- self.version = None
+ self.doc = None
+
+class Node(Annotated):
+ """A node is a type of object which is uniquely identified by its
+(namespace, name) pair. When combined with a ., this is called a
+GIName. It's possible for nodes to contain or point to other nodes."""
+
+ def __init__(self, name=None):
+ Annotated.__init__(self)
+ self.namespace = None # Should be set later by Namespace.append()
+ self.name = name
self.foreign = False
self.file_positions = set()
def __cmp__(self, other):
+ nscmp = cmp(self.namespace, other.namespace)
+ if nscmp != 0:
+ return nscmp
return cmp(self.name, other.name)
def __repr__(self):
@@ -201,49 +318,6 @@ class Node(object):
if symbol.source_filename:
self.add_file_position(symbol.source_filename, symbol.line, -1)
-class Namespace(Node):
-
- def __init__(self, name, version):
- Node.__init__(self, name)
- self.version = version
- self.nodes = []
-
- def __repr__(self):
- return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name,
- self.version, self.nodes)
-
- def remove_matching(self, pred):
-
- def recursive_pred(node):
- node.remove_matching_children(pred)
- return pred(node)
-
- self.nodes = filter(recursive_pred, self.nodes)
-
-class Include(Node):
-
- def __init__(self, name, version):
- Node.__init__(self, 'include')
- self.name = name
- self.version = version
-
- @classmethod
- def from_string(self, string):
- return Include(*string.split('-', 1))
-
- def __cmp__(self, other):
- if not isinstance(other, Include):
- return cmp(self, other)
- namecmp = cmp(self.name, other.name)
- if namecmp != 0:
- return namecmp
- return cmp(self.version, other.version)
-
- def __hash__(self):
- return hash((self.name, self.version))
-
- def __str__(self):
- return '%s-%s' % (self.name, self.version)
class Callable(Node):
@@ -252,20 +326,24 @@ class Callable(Node):
self.retval = retval
self.parameters = parameters
self.throws = not not throws
- self.doc = None
- def __repr__(self):
- return '%s(%r, %r, %r)' % (self.__class__.__name__,
- self.name, self.retval,
- self.parameters)
+ def get_parameter_index(self, name):
+ for i, parameter in enumerate(self.parameters):
+ if parameter.name == name:
+ return i
+
+ def get_parameter(self, name):
+ for parameter in self.parameters:
+ if parameter.name == name:
+ return parameter
+
class Function(Callable):
- def __init__(self, name, retval, parameters, symbol, throws=None):
+ def __init__(self, name, retval, parameters, throws, symbol):
Callable.__init__(self, name, retval, parameters, throws)
self.symbol = symbol
self.is_method = False
- self.doc = None
def get_parameter_index(self, name):
for i, parameter in enumerate(self.parameters):
@@ -291,59 +369,78 @@ class VFunction(Callable):
return obj
-class Type(Node):
-
- def __init__(self, name, ctype=None):
- Node.__init__(self, name)
+class Type(object):
+ """A Type can be either:
+* A reference to a node (target_giname)
+* A reference to a "fundamental" type like 'utf8'
+* A "foreign" type - this can be any string."
+If none are specified, then it's in an "unresolved" state.
+In this case, the ctype must be specified.
+"""
+ def __init__(self,
+ ctype=None,
+ target_fundamental=None,
+ target_giname=None,
+ target_foreign=None,
+ is_const=False):
+ if target_fundamental:
+ assert target_giname is None
+ assert target_foreign is None
+ self.resolved = True
+ elif target_giname:
+ assert target_fundamental is None
+ assert target_foreign is None
+ self.resolved = True
+ elif target_foreign:
+ assert ctype is not None
+ assert target_giname is None
+ assert target_fundamental is None
+ self.resolved = True
+ else:
+ assert ctype is not None
+ self.resolved = False
self.ctype = ctype
- self.resolved = False
- self.is_const = False
- self.canonical = None
- self.derefed_canonical = None
+ self.target_fundamental = target_fundamental
+ self.target_giname = target_giname
+ self.target_foreign = target_foreign
+ self.is_const = is_const
class Varargs(Type):
def __init__(self):
- Type.__init__(self, '<varargs>')
+ Type.__init__(self, '<varargs>', target_fundamental='<varargs>')
class Array(Type):
- def __init__(self, name, ctype, element_type):
- if name is None:
- name = '<carray>'
- Type.__init__(self, name, ctype)
+ def __init__(self, name, element_type, **kwargs):
+ Type.__init__(self, target_fundamental='<array>',
+ **kwargs)
+ self.name = name
self.element_type = element_type
self.zeroterminated = True
self.length_param_index = -1
self.length_param_name = None
self.size = None
- def __repr__(self):
- return 'Array(%r, %r)' % (self.name, self.element_type, )
-
class List(Type):
- def __init__(self, name, ctype, element_type):
- Type.__init__(self, name, ctype)
+ def __init__(self, name, element_type, **kwargs):
+ Type.__init__(self, target_fundamental='<list>',
+ **kwargs)
+ self.name = name
self.element_type = element_type
- def __repr__(self):
- return 'List(%r of %r)' % (self.name, self.element_type, )
-
class Map(Type):
- def __init__(self, name, ctype, key_type, value_type):
- Type.__init__(self, name, ctype)
+ def __init__(self, ctype, key_type, value_type, **kwargs):
+ Type.__init__(self, ctype=ctype, target_fundamental='<map>')
self.key_type = key_type
self.value_type = value_type
- def __repr__(self):
- return 'Map(%r <%r,%r>)' % (self.name, self.key_type, self.value_type)
-
class Alias(Node):
@@ -352,14 +449,12 @@ class Alias(Node):
self.target = target
self.ctype = ctype
- def __repr__(self):
- return 'Alias(%r, %r)' % (self.name, self.target)
+class TypeContainer(Annotated):
+ """A fundamental base class for Return and Parameter."""
-class TypeContainer(Node):
-
- def __init__(self, name, typenode, transfer):
- Node.__init__(self, name)
+ def __init__(self, typenode, transfer):
+ Annotated.__init__(self)
self.type = typenode
if transfer in [PARAM_TRANSFER_NONE, PARAM_TRANSFER_CONTAINER,
PARAM_TRANSFER_FULL]:
@@ -369,25 +464,32 @@ class TypeContainer(Node):
class Parameter(TypeContainer):
+ """An argument to a function."""
- def __init__(self, name, typenode, direction=None,
- transfer=None, allow_none=False, scope=None):
- TypeContainer.__init__(self, name, typenode, transfer)
+ def __init__(self, argname, typenode, direction=None,
+ transfer=None, allow_none=False, scope=None,
+ caller_allocates=False):
+ TypeContainer.__init__(self, typenode, transfer)
+ self.argname = argname
if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT,
PARAM_DIRECTION_INOUT, None]:
self.direction = direction
else:
self.direction = PARAM_DIRECTION_IN
- self.caller_allocates = False
+ self.caller_allocates = caller_allocates
self.allow_none = allow_none
self.scope = scope
self.closure_index = -1
self.destroy_index = -1
- self.doc = None
- def __repr__(self):
- return 'Parameter(%r, %r)' % (self.name, self.type)
+
+class Return(TypeContainer):
+ """A return value from a function."""
+
+ def __init__(self, rtype, transfer=None):
+ TypeContainer.__init__(self, rtype, transfer)
+ self.direction = PARAM_DIRECTION_OUT
class Enum(Node):
@@ -396,10 +498,6 @@ class Enum(Node):
Node.__init__(self, name)
self.symbol = symbol
self.members = members
- self.doc = None
-
- def __repr__(self):
- return 'Enum(%r, %r)' % (self.name, self.members)
class Bitfield(Node):
@@ -408,22 +506,15 @@ class Bitfield(Node):
Node.__init__(self, name)
self.symbol = symbol
self.members = members
- self.doc = None
-
- def __repr__(self):
- return 'Bitfield(%r, %r)' % (self.name, self.members)
-class Member(Node):
+class Member(object):
def __init__(self, name, value, symbol):
- Node.__init__(self, name)
+ self.name = name
self.value = value
self.symbol = symbol
- def __repr__(self):
- return 'Member(%r, %r)' % (self.name, self.value)
-
class Record(Node):
@@ -433,7 +524,6 @@ class Record(Node):
self.constructors = []
self.symbol = symbol
self.disguised = disguised
- self.doc = None
self.methods = []
def remove_matching_children(self, pred):
@@ -441,36 +531,18 @@ class Record(Node):
self.constructors = filter(pred, self.constructors)
self.methods = filter(pred, self.methods)
-# BW compat, remove
-Struct = Record
+class Field(Annotated):
-class Field(Node):
-
- def __init__(self, name, typenode, symbol, readable, writable, bits=None):
- Node.__init__(self, name)
+ def __init__(self, name, typenode, readable, writable, bits=None,
+ anonymous_node=None):
+ Annotated.__init__(self)
+ self.name = name
self.type = typenode
- self.symbol = symbol
self.readable = readable
self.writable = writable
self.bits = bits
-
- def __repr__(self):
- if self.bits:
- return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
- else:
- return 'Field(%r, %r)' % (self.name, self.type)
-
-
-class Return(TypeContainer):
-
- def __init__(self, rtype, transfer=None):
- TypeContainer.__init__(self, None, rtype, transfer)
- self.direction = PARAM_DIRECTION_OUT
- self.doc = None
-
- def __repr__(self):
- return 'Return(%r)' % (self.type, )
+ self.anonymous_node = anonymous_node
class Class(Node):
@@ -488,7 +560,6 @@ class Class(Node):
self.constructors = []
self.properties = []
self.fields = []
- self.doc = None
def remove_matching_children(self, pred):
self.methods = filter(pred, self.methods)
@@ -496,10 +567,6 @@ class Class(Node):
self.properties = filter(pred, self.properties)
self.fields = filter(pred, self.fields)
- def __repr__(self):
- return '%s(%r, %r, %r)' % (
- self.__class__.__name__,
- self.name, self.parent, self.methods)
class Interface(Node):
@@ -513,70 +580,34 @@ class Interface(Node):
self.properties = []
self.fields = []
self.prerequisites = []
- self.doc = None
-
- def __repr__(self):
- return '%s(%r, %r)' % (
- self.__class__.__name__,
- self.name, self.methods)
class Constant(Node):
- def __init__(self, name, type_name, value):
+ def __init__(self, name, value_type, value):
Node.__init__(self, name)
- self.type = Type(type_name)
+ self.value_type = value_type
self.value = value
- def __repr__(self):
- return 'Constant(%r, %r, %r)' % (
- self.name, self.type, self.value)
+class Property(Node):
-class Property(TypeContainer):
-
- def __init__(self, name, type_name, readable, writable,
- construct, construct_only, ctype=None, transfer=None):
- self.type = Type(type_name, ctype)
- TypeContainer.__init__(self, name, self.type, transfer)
+ def __init__(self, name, typeobj, readable, writable,
+ construct, construct_only, transfer=None):
+ Node.__init__(self, name)
+ self.type = typeobj
self.readable = readable
self.writable = writable
self.construct = construct
self.construct_only = construct_only
- self.doc = None
-
- def __repr__(self):
- return '%s(%r, %r)' % (
- self.__class__.__name__,
- self.name, self.type)
-
-
-# FIXME: Inherit from Function
+ self.transfer = PARAM_TRANSFER_NONE
-class Callback(Node):
+class Callback(Callable):
- def __init__(self, name, retval, parameters, ctype=None):
- Node.__init__(self, name)
- self.retval = retval
- self.parameters = parameters
+ def __init__(self, name, retval, parameters, throws, ctype=None):
+ Callable.__init__(self, name, retval, parameters, throws)
self.ctype = ctype
- self.throws = False
- self.doc = None
-
- def get_parameter_index(self, name):
- for i, parameter in enumerate(self.parameters):
- if parameter.name == name:
- return i
-
- def get_parameter(self, name):
- for parameter in self.parameters:
- if parameter.name == name:
- return parameter
-
- def __repr__(self):
- return 'Callback(%r, %r, %r)' % (
- self.name, self.retval, self.parameters)
class Union(Node):
@@ -587,7 +618,3 @@ class Union(Node):
self.constructors = []
self.methods = []
self.symbol = symbol
- self.doc = None
-
- def __repr__(self):
- return 'Union(%r, %r)' % (self.name, self.fields, )
diff --git a/giscanner/girparser.py b/giscanner/girparser.py
index 17cf630..1d87b0e 100644
--- a/giscanner/girparser.py
+++ b/giscanner/girparser.py
@@ -23,11 +23,11 @@ import os
from xml.etree.cElementTree import parse
from .ast import (Alias, Array, Callback, Constant, Enum, Function, Field,
- Namespace, Parameter, Property, Return, Union, Struct, Type,
- Varargs, Include)
+ Namespace, Parameter, Property, Return, Union, Type, List,
+ VFunction, Record, Varargs, Include, PARAM_DIRECTION_IN)
from .glibast import (GLibEnum, GLibEnumMember, GLibFlags,
GLibInterface, GLibObject, GLibBoxedStruct,
- GLibBoxedUnion, GLibBoxedOther)
+ GLibBoxedUnion, GLibBoxedOther, GLibRecord)
from .girwriter import COMPATIBLE_GIR_VERSION
@@ -51,7 +51,6 @@ def _cns(tag):
class GIRParser(object):
def __init__(self):
- self._include_parsing = False
self._shared_libraries = []
self._includes = set()
self._pkgconfig_packages = set()
@@ -72,6 +71,8 @@ class GIRParser(object):
self._namespace = None
self._shared_libraries = []
self._pkgconfig_packages = set()
+ self._c_includes = set()
+ self._c_prefix = None
self._parse_api(tree.getroot())
def get_namespace(self):
@@ -83,6 +84,12 @@ class GIRParser(object):
def get_includes(self):
return self._includes
+ def get_c_includes(self):
+ return self._c_includes
+
+ def get_c_prefix(self):
+ return self._c_prefix
+
def get_pkgconfig_packages(self):
if not hasattr(self, '_pkgconfig_packages'):
self._pkgconfig_packages = []
@@ -91,11 +98,21 @@ class GIRParser(object):
def get_doc(self):
return parse(self._filename)
- def set_include_parsing(self, include_parsing):
- self._include_parsing = include_parsing
-
# Private
+ def _find_first_child(self, node, name):
+ for child in node.getchildren():
+ if child.tag == name:
+ return child
+ return None
+
+ def _find_children(self, node, name):
+ result = []
+ for child in node.getchildren():
+ if child.tag == name:
+ result.append(child)
+ return result
+
def _get_current_file(self):
if not self._filename_stack:
return None
@@ -105,9 +122,6 @@ class GIRParser(object):
return curfile[len(cwd):]
return curfile
- def _add_node(self, node):
- self._namespace.nodes.append(node)
-
def _parse_api(self, root):
assert root.tag == _corens('repository')
version = root.attrib['version']
@@ -121,11 +135,14 @@ class GIRParser(object):
self._parse_include(node)
elif node.tag == _corens('package'):
self._parse_pkgconfig_package(node)
+ elif node.tag == _cns('include'):
+ self._parse_c_include(node)
ns = root.find(_corens('namespace'))
assert ns is not None
self._namespace = Namespace(ns.attrib['name'],
- ns.attrib['version'])
+ ns.attrib['version'],
+ ns.attrib.get(_cns('prefix')))
if 'shared-library' in ns.attrib:
self._shared_libraries.extend(
ns.attrib['shared-library'].split(','))
@@ -155,19 +172,40 @@ class GIRParser(object):
self._includes.add(include)
def _parse_pkgconfig_package(self, node):
- if not hasattr(self, '_pkgconfig_packages'):
- self._pkgconfig_packages = []
self._pkgconfig_packages.add(node.attrib['name'])
+ def _parse_c_include(self, node):
+ self._c_includes.add(node.attrib['name'])
+
def _parse_alias(self, node):
alias = Alias(node.attrib['name'],
node.attrib['target'],
node.attrib.get(_cns('type')))
- self._add_node(alias)
+ self._namespace.append(alias)
+
+ def _parse_generic_attribs(self, node, obj):
+ doc = node.attrib.get('doc')
+ if doc:
+ obj.doc = doc
+ version = node.attrib.get('version')
+ if version:
+ obj.version = version
+ deprecated = node.attrib.get('deprecated')
+ if deprecated:
+ obj.deprecated = deprecated
+ introspectable = node.attrib.get('introspectable')
+ if introspectable:
+ obj.introspectable = int(introspectable) > 0
def _parse_object_interface(self, node):
+ parent = node.attrib.get('parent')
+ if parent:
+ parent_type = Type(target_giname=parent)
+ else:
+ parent_type = None
+
ctor_args = [node.attrib['name'],
- node.attrib.get('parent'),
+ parent_type,
node.attrib[_glibns('type-name')],
node.attrib[_glibns('get-type')]]
if node.tag == _corens('interface'):
@@ -181,38 +219,49 @@ class GIRParser(object):
raise AssertionError(node)
obj = klass(*ctor_args)
- self._add_node(obj)
+ self._parse_generic_attribs(node, obj)
+ type_struct = node.attrib.get(_glibns('type-struct'))
+ if type_struct:
+ obj.glib_type_struct = Type(target_giname=type_struct)
+ self._namespace.append(obj)
- if self._include_parsing:
- return
ctor_args.append(node.attrib.get(_cns('type')))
- for iface in node.findall(_corens('implements')):
- obj.interfaces.append(iface.attrib['name'])
- for iface in node.findall(_corens('prerequisites')):
- obj.prerequisities.append(iface.attrib['name'])
- for method in node.findall(_corens('method')):
+ for iface in self._find_children(node, _corens('implements')):
+ obj.interfaces.append(Type(target_giname=iface.attrib['name']))
+ for iface in self._find_children(node, _corens('prerequisites')):
+ obj.prerequisities.append(Type(target_giname=iface.attrib['name']))
+ for func_node in self._find_children(node, _corens('function')):
+ func = self._parse_function_common(func_node, Function)
+ obj.static_methods.append(func)
+ for method in self._find_children(node, _corens('method')):
func = self._parse_function_common(method, Function)
func.is_method = True
obj.methods.append(func)
- for ctor in node.findall(_corens('constructor')):
+ for method in self._find_children(node, _corens('virtual-method')):
+ func = self._parse_function_common(method, VFunction)
+ self._parse_generic_attribs(method, func)
+ func.is_method = True
+ func.invoker = method.get('invoker')
+ obj.virtual_methods.append(func)
+ for ctor in self._find_children(node, _corens('constructor')):
obj.constructors.append(
self._parse_function_common(ctor, Function))
- for callback in node.findall(_corens('callback')):
+ for callback in self._find_children(node, _corens('callback')):
obj.fields.append(self._parse_function_common(callback, Callback))
- for field in node.findall(_corens('field')):
+ for field in self._find_children(node, _corens('field')):
obj.fields.append(self._parse_field(field))
- for prop in node.findall(_corens('property')):
+ for prop in self._find_children(node, _corens('property')):
obj.properties.append(self._parse_property(prop))
- for signal in node.findall(_glibns('signal')):
+ for signal in self._find_children(node, _glibns('signal')):
obj.signals.append(self._parse_function_common(signal, Function))
def _parse_callback(self, node):
callback = self._parse_function_common(node, Callback)
- self._add_node(callback)
+ self._namespace.append(callback)
def _parse_function(self, node):
function = self._parse_function_common(node, Function)
- self._add_node(function)
+ self._namespace.append(function)
def _parse_function_common(self, node, klass):
name = node.attrib['name']
@@ -221,29 +270,43 @@ class GIRParser(object):
raise ValueError('node %r has no return-value' % (name, ))
transfer = returnnode.attrib.get('transfer-ownership')
retval = Return(self._parse_type(returnnode), transfer)
+ self._parse_generic_attribs(returnnode, retval)
parameters = []
+ throws = (node.attrib.get('throws') == '1')
+
if klass is Callback:
- func = klass(name, retval, parameters,
+ func = klass(name, retval, parameters, throws,
node.attrib.get(_cns('type')))
- else:
+ elif klass is Function:
identifier = node.attrib.get(_cns('identifier'))
- throws = (node.attrib.get('throws') == '1')
- func = klass(name, retval, parameters, identifier, throws)
-
- if self._include_parsing:
- return func
+ func = klass (name, retval, parameters, throws, identifier)
+ elif klass is VFunction:
+ func = klass(name, retval, parameters, throws)
+ else:
+ assert False
parameters_node = node.find(_corens('parameters'))
if (parameters_node is not None):
- for paramnode in parameters_node.findall(_corens('parameter')):
+ for paramnode in self._find_children(parameters_node, _corens('parameter')):
param = Parameter(paramnode.attrib.get('name'),
self._parse_type(paramnode),
- paramnode.attrib.get('direction'),
+ paramnode.attrib.get('direction') or PARAM_DIRECTION_IN,
paramnode.attrib.get('transfer-ownership'),
- paramnode.attrib.get('allow-none') == '1')
+ paramnode.attrib.get('allow-none') == '1',
+ paramnode.attrib.get('scope'),
+ paramnode.attrib.get('caller-allocates') == '1')
+ closure = paramnode.attrib.get('closure')
+ if closure:
+ param.closure_index = int(closure)
+ destroy = paramnode.attrib.get('destroy')
+ if destroy:
+ param.destroy_index = int(destroy)
+ self._parse_generic_attribs(paramnode, param)
parameters.append(param)
+ self._parse_generic_attribs(node, func)
+
return func
def _parse_record(self, node):
@@ -252,24 +315,26 @@ class GIRParser(object):
node.attrib[_glibns('type-name')],
node.attrib[_glibns('get-type')],
node.attrib.get(_cns('type')))
+ elif _glibns('is-gtype-struct-for') in node.attrib:
+ struct = GLibRecord(node.attrib['name'],
+ node.attrib.get(_cns('type')),
+ disguised=node.attrib.get('disguised') == '1')
+ is_gtype_struct_for = node.attrib[_glibns('is-gtype-struct-for')]
+ struct.is_gtype_struct_for = Type(target_giname=is_gtype_struct_for)
else:
- disguised = node.attrib.get('disguised') == '1'
- struct = Struct(node.attrib['name'],
+ struct = Record(node.attrib['name'],
node.attrib.get(_cns('type')),
- disguised=disguised)
- self._add_node(struct)
-
- if self._include_parsing:
- return
- for field in node.findall(_corens('field')):
- struct.fields.append(self._parse_field(field))
- for callback in node.findall(_corens('callback')):
- struct.fields.append(
- self._parse_function_common(callback, Callback))
- for method in node.findall(_corens('method')):
- struct.fields.append(
+ disguised=node.attrib.get('disguised') == '1')
+ self._parse_generic_attribs(node, struct)
+ self._namespace.append(struct)
+
+ for field in self._find_children(node, _corens('field')):
+ fieldobj = self._parse_field(field)
+ struct.fields.append(fieldobj)
+ for method in self._find_children(node, _corens('method')):
+ struct.methods.append(
self._parse_function_common(method, Function))
- for ctor in node.findall(_corens('constructor')):
+ for ctor in self._find_children(node, _corens('constructor')):
struct.constructors.append(
self._parse_function_common(ctor, Function))
@@ -282,50 +347,71 @@ class GIRParser(object):
else:
union = Union(node.attrib['name'],
node.attrib.get(_cns('type')))
- self._add_node(union)
+ self._namespace.append(union)
- if self._include_parsing:
- return
- for callback in node.findall(_corens('callback')):
+ for callback in self._find_children(node, _corens('callback')):
union.fields.append(
self._parse_function_common(callback, Callback))
- for field in node.findall(_corens('field')):
+ for field in self._find_children(node, _corens('field')):
union.fields.append(self._parse_field(field))
- for method in node.findall(_corens('method')):
+ for method in self._find_children(node, _corens('method')):
union.fields.append(
self._parse_function_common(method, Function))
- for ctor in node.findall(_corens('constructor')):
+ for ctor in self._find_children(node, _corens('constructor')):
union.constructors.append(
self._parse_function_common(ctor, Function))
def _parse_type(self, node):
- typenode = node.find(_corens('type'))
+ # Fields can contain inline callbacks
+ typenode = node.find(_corens('callback'))
if typenode is not None:
- return Type(typenode.attrib['name'],
- typenode.attrib.get(_cns('type')))
+ return Type(target_giname=typenode.attrib['name'],
+ ctype=typenode.attrib.get(_cns('type')))
+ # Arrays have their own toplevel XML
typenode = node.find(_corens('array'))
if typenode is not None:
-
- array_type = typenode.attrib.get(_cns('type'))
- if array_type.startswith('GArray*') or \
- array_type.startswith('GPtrArray*') or \
- array_type.startswith('GByteArray*'):
- element_type = None
+ array_name = typenode.attrib.get('name')
+ if array_name in ('GLib.PtrArray', 'GLib.Array',
+ 'GLib.ByteArray'):
+ element_type = Type(target_fundamental='any', ctype='gpointer')
else:
element_type = self._parse_type(typenode)
-
- ret = Array(None, array_type, element_type)
+ array_ctype = typenode.attrib.get(_cns('type'))
+ ret = Array(array_name, element_type, ctype=array_ctype)
+ # zero-terminated defaults to true...
+ zero = typenode.attrib.get('zero-terminated')
+ if zero and zero == '0':
+ ret.zeroterminated = False
+ fixed_size = typenode.attrib.get('fixed-size')
+ if fixed_size:
+ ret.size = int(fixed_size)
lenidx = typenode.attrib.get('length')
if lenidx:
ret.length_param_index = int(lenidx)
return ret
+ # Dispsense with varargs
typenode = node.find(_corens('varargs'))
if typenode is not None:
return Varargs()
+ # Okay now...could be a list, let's see.
+ typenode = self._find_first_child(node, _corens('type'))
+ if typenode is not None:
+ name = typenode.attrib['name']
+ ctype = typenode.attrib.get(_cns('type'))
+ if name in ['GLib.List', 'GLib.SList']:
+ subchild = self._find_first_child(typenode, _corens('type'))
+ if subchild is not None:
+ element_type = self._parse_type(typenode)
+ else:
+ element_type = Type(target_fundamental='any')
+ return List(name, element_type, ctype=ctype)
+ else:
+ return self._namespace.type_from_name(name, ctype)
+
raise ValueError("Couldn't parse type of node %r; children=%r",
node, list(node))
@@ -333,51 +419,62 @@ class GIRParser(object):
obj = GLibBoxedOther(node.attrib[_glibns('name')],
node.attrib[_glibns('type-name')],
node.attrib[_glibns('get-type')])
- self._add_node(obj)
- if self._include_parsing:
- return
- for method in node.findall(_corens('method')):
+ self._parse_generic_attribs(node, obj)
+ self._namespace.append(obj)
+ for method in self._find_children(node, _corens('method')):
func = self._parse_function_common(method, Function)
func.is_method = True
obj.methods.append(func)
- for ctor in node.findall(_corens('constructor')):
+ for ctor in self._find_children(node, _corens('constructor')):
obj.constructors.append(
self._parse_function_common(ctor, Function))
- for callback in node.findall(_corens('callback')):
+ for callback in self._find_children(node, _corens('callback')):
obj.fields.append(
self._parse_function_common(callback, Callback))
def _parse_field(self, node):
- type_node = self._parse_type(node)
- return Field(node.attrib['name'],
- type_node,
- type_node.ctype,
- node.attrib.get('readable') != '0',
- node.attrib.get('writable') == '1',
- node.attrib.get('bits'))
+ callback_node = self._find_first_child(node, _corens('callback'))
+ if callback_node:
+ anonymous_node = self._parse_function_common(callback_node, Callback)
+ type_node = None
+ else:
+ anonymous_node = None
+ type_node = self._parse_type(node)
+ field = Field(node.attrib['name'],
+ type_node,
+ node.attrib.get('readable') != '0',
+ node.attrib.get('writable') == '1',
+ node.attrib.get('bits'),
+ anonymous_node=anonymous_node)
+ self._parse_generic_attribs(node, field)
+ return field
def _parse_property(self, node):
- type_node = self._parse_type(node)
- return Property(node.attrib['name'],
- type_node.name,
+ prop = Property(node.attrib['name'],
+ self._parse_type(node),
node.attrib.get('readable') != '0',
node.attrib.get('writable') == '1',
node.attrib.get('construct') == '1',
- node.attrib.get('construct-only') == '1',
- type_node.ctype)
+ node.attrib.get('construct-only') == '1')
+ self._parse_generic_attribs(node, prop)
+ return prop
def _parse_member(self, node):
- return GLibEnumMember(node.attrib['name'],
- node.attrib['value'],
- node.attrib.get(_cns('identifier')),
- node.attrib.get(_glibns('nick')))
+ member = GLibEnumMember(node.attrib['name'],
+ node.attrib['value'],
+ node.attrib.get(_cns('identifier')),
+ node.attrib.get(_glibns('nick')))
+ self._parse_generic_attribs(node, member)
+ return member
+
def _parse_constant(self, node):
type_node = self._parse_type(node)
constant = Constant(node.attrib['name'],
- type_node.name,
+ type_node,
node.attrib['value'])
- self._add_node(constant)
+ self._parse_generic_attribs(node, constant)
+ self._namespace.append(constant)
def _parse_enumeration_bitfield(self, node):
name = node.attrib.get('name')
@@ -398,9 +495,8 @@ class GIRParser(object):
else:
obj = klass(name, type_name, members, get_type)
obj.ctype = ctype
- self._add_node(obj)
+ self._parse_generic_attribs(node, obj)
+ self._namespace.append(obj)
- if self._include_parsing:
- return
- for member in node.findall(_corens('member')):
+ for member in self._find_children(node, _corens('member')):
members.append(self._parse_member(member))
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 59b4b49..ed836eb 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -22,8 +22,8 @@
from __future__ import with_statement
from .ast import (Alias, Array, Bitfield, Callback, Class, Constant, Enum,
- Function, Interface, List, Map, Member, Struct, Union,
- Varargs)
+ Function, Interface, List, Map, Member, Union, Record,
+ Varargs, Type)
from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember,
GLibFlags, GLibObject, GLibInterface,
GLibRecord)
@@ -42,10 +42,10 @@ class GIRWriter(XMLWriter):
To affect the contents of this file, edit the original C definitions,
and/or use gtk-doc annotations. ''')
self._write_repository(namespace, shlibs, includes, pkgs,
- c_includes, cprefix)
+ c_includes)
def _write_repository(self, namespace, shlibs, includes=None,
- packages=None, c_includes=None, cprefix=None):
+ packages=None, c_includes=None):
if includes is None:
includes = frozenset()
if packages is None:
@@ -65,7 +65,9 @@ and/or use gtk-doc annotations. ''')
self._write_pkgconfig_pkg(pkg)
for c_include in sorted(set(c_includes)):
self._write_c_include(c_include)
- self._write_namespace(namespace, shlibs, cprefix)
+ self._namespace = namespace
+ self._write_namespace(namespace, shlibs)
+ self._namespace = None
def _write_include(self, include):
attrs = [('name', include.name), ('version', include.version)]
@@ -79,11 +81,11 @@ and/or use gtk-doc annotations. ''')
attrs = [('name', c_include)]
self.write_tag('c:include', attrs)
- def _write_namespace(self, namespace, shlibs, cprefix):
+ def _write_namespace(self, namespace, shlibs):
attrs = [('name', namespace.name),
('version', namespace.version),
('shared-library', ','.join(shlibs)),
- ('c:prefix', cprefix)]
+ ('c:prefix', namespace.c_prefix)]
with self.tagcontext('namespace', attrs):
# We define a custom sorting function here because
# we want aliases to be first. They're a bit
@@ -98,7 +100,7 @@ and/or use gtk-doc annotations. ''')
return 1
else:
return cmp(a, b)
- for node in sorted(namespace.nodes, cmp=nscmp):
+ for node in sorted(namespace.itervalues(), cmp=nscmp):
self._write_node(node)
def _write_node(self, node):
@@ -112,7 +114,7 @@ and/or use gtk-doc annotations. ''')
self._write_class(node)
elif isinstance(node, Callback):
self._write_callback(node)
- elif isinstance(node, Struct):
+ elif isinstance(node, Record):
self._write_record(node)
elif isinstance(node, Union):
self._write_union(node)
@@ -169,7 +171,9 @@ and/or use gtk-doc annotations. ''')
self._write_parameters(callable.parameters)
def _write_function(self, func, tag_name='function'):
- attrs = [('c:identifier', func.symbol)]
+ attrs = []
+ if hasattr(func, 'symbol'):
+ attrs.append(('c:identifier', func.symbol))
self._write_callable(func, tag_name, attrs)
def _write_method(self, method):
@@ -206,8 +210,8 @@ and/or use gtk-doc annotations. ''')
assert parameter.transfer is not None, parameter
attrs = []
- if parameter.name is not None:
- attrs.append(('name', parameter.name))
+ if parameter.argname is not None:
+ attrs.append(('name', parameter.argname))
if parameter.direction != 'in':
attrs.append(('direction', parameter.direction))
attrs.append(('caller-allocates',
@@ -228,55 +232,54 @@ and/or use gtk-doc annotations. ''')
self._write_attributes(parameter)
self._write_type(parameter.type)
- def _type_to_string(self, ntype):
- if isinstance(ntype, basestring):
- return ntype
- return ntype.name
-
def _write_type(self, ntype, relation=None):
- if isinstance(ntype, basestring):
- typename = ntype
- type_cname = None
- else:
- typename = ntype.name
- type_cname = ntype.ctype
+ assert isinstance(ntype, Type)
+ attrs = []
+ if ntype.ctype:
+ attrs.append(('c:type', ntype.ctype))
if isinstance(ntype, Varargs):
with self.tagcontext('varargs', []):
pass
- return
- if isinstance(ntype, Array):
- attrs = []
+ elif isinstance(ntype, Array):
if not ntype.zeroterminated:
attrs.append(('zero-terminated', '0'))
if ntype.length_param_index >= 0:
attrs.append(('length', '%d' % (ntype.length_param_index, )))
- if ntype.name in ['GLib.Array', 'GLib.PtrArray', 'GLib.ByteArray']:
- attrs.append(('name', ntype.name))
- attrs.append(('c:type', ntype.ctype))
if ntype.size is not None:
- attrs.append(('fixed-size', ntype.size))
+ attrs.append(('fixed-size', '%d' % (ntype.size, )))
with self.tagcontext('array', attrs):
if ntype.element_type is not None:
self._write_type(ntype.element_type)
- return
- attrs = [('name', self._type_to_string(ntype))]
- # FIXME: figure out if type references a basic type
- # or a boxed/class/interface etc. and skip
- # writing the ctype if the latter.
- if type_cname is not None:
- attrs.append(('c:type', type_cname))
- if isinstance(ntype, List) and ntype.element_type:
+ elif isinstance(ntype, List):
+ if ntype.name:
+ attrs.insert(0, ('name', ntype.name))
with self.tagcontext('type', attrs):
self._write_type(ntype.element_type)
- return
- if isinstance(ntype, Map) and ntype.key_type:
+ elif isinstance(ntype, Map):
+ if ntype.name:
+ attrs.insert(0, ('name', name))
with self.tagcontext('type', attrs):
self._write_type(ntype.key_type)
self._write_type(ntype.value_type)
- return
- # Not a special type, just write it out
- self.write_tag('type', attrs)
+ else:
+ # REWRITEFIXME - enable this for 1.2
+ if ntype.target_giname:
+ # attrs.insert(0, ('ref', ntype.target_giname))
+ prefix = self._namespace.name + '.'
+ if ntype.target_giname.startswith(prefix):
+ attrs.insert(0, ('name', ntype.target_giname[len(prefix):]))
+ else:
+ attrs.insert(0, ('name', ntype.target_giname))
+ elif ntype.target_fundamental:
+ # attrs = [('fundamental', ntype.target_fundamental)]
+ attrs.insert(0, ('name', ntype.target_fundamental))
+ elif ntype.target_foreign:
+ attrs.insert(0, ('foreign', '1'))
+ else:
+ raise AssertionError("Caught unresolved type %r" % (ntype, ))
+ # Not a special type, just write it out
+ self.write_tag('type', attrs)
def _write_enum(self, enum):
attrs = [('name', enum.name)]
@@ -324,10 +327,9 @@ and/or use gtk-doc annotations. ''')
self.write_tag('member', attrs)
def _write_constant(self, constant):
- attrs = [('name', constant.name),
- ('value', str(constant.value))]
+ attrs = [('name', constant.name), ('value', constant.value)]
with self.tagcontext('constant', attrs):
- self._write_type(constant.type)
+ self._write_type(constant.value_type)
def _write_class(self, node):
attrs = [('name', node.name),
@@ -339,7 +341,7 @@ and/or use gtk-doc annotations. ''')
if isinstance(node, Class):
tag_name = 'class'
if node.parent is not None:
- attrs.append(('parent', node.parent))
+ attrs.append(('parent', node.parent.target_giname))
if node.is_abstract:
attrs.append(('abstract', '1'))
else:
@@ -349,15 +351,15 @@ and/or use gtk-doc annotations. ''')
if node.get_type:
attrs.append(('glib:get-type', node.get_type))
if node.glib_type_struct:
- attrs.append(('glib:type-struct', node.glib_type_struct.name))
+ attrs.append(('glib:type-struct', node.glib_type_struct.target_giname))
with self.tagcontext(tag_name, attrs):
self._write_attributes(node)
if isinstance(node, GLibObject):
for iface in node.interfaces:
- self.write_tag('implements', [('name', iface)])
+ self.write_tag('implements', [('name', iface.target_giname)])
if isinstance(node, Interface):
for iface in node.prerequisites:
- self.write_tag('prerequisite', [('name', iface)])
+ self.write_tag('prerequisite', [('name', iface.target_giname)])
if isinstance(node, Class):
for method in node.constructors:
self._write_constructor(method)
@@ -410,7 +412,7 @@ and/or use gtk-doc annotations. ''')
def _write_vfunc(self, vf):
attrs = []
if vf.invoker:
- attrs.append(('invoker', vf.invoker.name))
+ attrs.append(('invoker', vf.invoker))
self._write_callable(vf, 'virtual-method', attrs)
def _write_callback(self, callback):
@@ -436,7 +438,7 @@ and/or use gtk-doc annotations. ''')
if record.is_gtype_struct_for:
is_gtype_struct = True
attrs.append(('glib:is-gtype-struct-for',
- record.is_gtype_struct_for))
+ record.is_gtype_struct_for.target_giname))
if record.doc:
attrs.append(('doc', record.doc))
self._append_version(record, attrs)
@@ -476,20 +478,16 @@ and/or use gtk-doc annotations. ''')
self._write_method(method)
def _write_field(self, field, is_gtype_struct=False):
- if isinstance(field, Function):
- self._write_method(field)
- return
-
- if isinstance(field, Callback):
+ if field.anonymous_node:
attrs = [('name', field.name)]
with self.tagcontext('field', attrs):
self._write_attributes(field)
- if is_gtype_struct:
- self._write_callback(field)
+ if isinstance(field.anonymous_node, Callback):
+ self._write_callback(field.anonymous_node)
else:
- attrs = [('name', 'any'), ('c:type', 'pointer')]
- self.write_tag('type', attrs)
- elif isinstance(field, Struct):
+ raise AssertionError("Unknown field anonymous: %r" \
+ % (field.anonymous_node, ))
+ elif isinstance(field, Record):
self._write_record(field)
elif isinstance(field, Union):
self._write_union(field)
@@ -504,7 +502,6 @@ and/or use gtk-doc annotations. ''')
if field.bits:
attrs.append(('bits', str(field.bits)))
with self.tagcontext('field', attrs):
- self._write_attributes(field)
self._write_type(field.type)
def _write_signal(self, signal):
diff --git a/giscanner/glibast.py b/giscanner/glibast.py
index fb1ef20..e2457d6 100644
--- a/giscanner/glibast.py
+++ b/giscanner/glibast.py
@@ -19,7 +19,7 @@
#
from .ast import (Bitfield, Class, Enum, Interface, Member, Node,
- Property, Struct, Union, Record)
+ Property, Union, Record)
from .ast import (
type_names, default_array_types,
TYPE_STRING, TYPE_INT8, TYPE_UINT8, TYPE_SHORT, TYPE_USHORT,
@@ -68,7 +68,7 @@ class GLibRecord(Record):
@classmethod
def from_record(cls, record):
- obj = cls(record.name, record.symbol)
+ obj = cls(record.namespace, record.name, record.symbol)
obj.fields = record.fields
obj.constructors = record.constructors
obj.disguised = record.disguised
@@ -122,6 +122,8 @@ class GLibObject(Class):
self.get_type = get_type
self.signals = []
self.ctype = ctype or type_name
+ # Unresolved state
+ self.parent_gtype_names = []
class GLibBoxed:
@@ -131,10 +133,10 @@ class GLibBoxed:
self.get_type = get_type
-class GLibBoxedStruct(Struct, GLibBoxed):
+class GLibBoxedStruct(Record, GLibBoxed):
def __init__(self, name, type_name, get_type, ctype=None):
- Struct.__init__(self, name, ctype or type_name)
+ Record.__init__(self, name, ctype or type_name)
GLibBoxed.__init__(self, type_name, get_type)
@@ -170,10 +172,10 @@ class GLibProperty(Property):
pass
-class GLibSignal(Node):
+class GLibSignal(object):
def __init__(self, name, retval):
- Node.__init__(self, name)
+ self.name = name
self.retval = retval
self.parameters = []
self.doc = None
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 3b088bc..d42480f 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -31,7 +31,6 @@ from .ast import (Alias, Bitfield, Callable, Callback, Class, Constant, Enum,
Field, VFunction, type_name_from_ctype, default_array_types,
TYPE_UINT8, PARAM_TRANSFER_FULL, Array, List,
Map, Varargs)
-from .transformer import Names
from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
GLibInterface, GLibObject, GLibSignal, GLibBoxedStruct,
GLibBoxedUnion, GLibBoxedOther, GLibRecord,
@@ -50,18 +49,6 @@ G_PARAM_STATIC_NAME = 1 << 5
G_PARAM_STATIC_NICK = 1 << 6
G_PARAM_STATIC_BLURB = 1 << 7
-SYMBOL_BLACKLIST = [
- # These ones break GError conventions
- 'g_simple_async_result_new_from_error',
- 'g_simple_async_result_set_from_error',
- 'g_simple_async_result_propagate_error',
- 'g_simple_async_result_report_error_in_idle',
- 'gtk_print_operation_get_error',
-]
-
-SYMBOL_BLACKLIST_RE = [re.compile(x) for x in \
- [r'\w+_marshal_[A-Z]+__', ]]
-
GET_TYPE_OVERRIDES = {
# this is a special case, from glibtransforer.py:create_gobject
'intern': 'g_object_get_type',
@@ -97,11 +84,9 @@ class UnknownTypeError(Exception):
class GLibTransformer(object):
- def __init__(self, transformer, noclosure=False):
+ def __init__(self, transformer):
self._transformer = transformer
- self._noclosure = noclosure
- self._namespace_name = None
- self._names = Names()
+ self._namespace = transformer.namespace
self._uscore_type_names = {}
self._binary = None
self._get_type_functions = []
@@ -110,7 +95,6 @@ class GLibTransformer(object):
self._failed_types = {}
self._boxed_types = {}
self._private_internal_types = {}
- self._validating = False
# Public API
@@ -121,18 +105,22 @@ class GLibTransformer(object):
"""
- namespace = self._transformer.parse()
- self._namespace_name = namespace.name
- self._namespace_version = namespace.version
+ self._transformer.parse()
# First pass: parsing
- for node in namespace.nodes:
- self._parse_node(node)
+ for node in self._namespace.itervalues():
+ if isinstance(node, Function):
+ print "doing initparse of %r" % (node, )
+ self._initparse_function(node)
+ if self._namespace.name == 'GObject':
+ for node in self._namespace.itervalues():
+ if isinstance(node, Record):
+ self._initparse_gobject_record(node)
# We don't want an alias for this - it's handled specially in
# the typelib compiler.
- if namespace.name == 'GObject':
- del self._names.aliases['Type']
+ if self._namespace.name == 'GObject':
+ del self._namespace.aliases['Type']
def get_get_type_functions(self):
return self._get_type_functions
@@ -144,74 +132,41 @@ class GLibTransformer(object):
"""Do remaining parsing steps requiring introspection binary"""
# Get all the GObject data by passing our list of get_type
- # functions to the compiled binary
-
- self._execute_binary()
-
- # Introspection is done from within parsing
+ # functions to the compiled binary, returning an XML blob.
+ tree = self._execute_binary_get_tree()
+ root = tree.getroot()
+ for child in root:
+ self._gtype_data[child.attrib['name']] = child
+ for child in root:
+ self._introspect_type(child)
- # Second pass: pair boxed structures
+ # Pair boxed structures; doesn't depend on anything else.
for boxed in self._boxed_types.itervalues():
self._pair_boxed_type(boxed)
- # Third pass: delete class structures, resolve
- # all types we now know about
- nodes = list(self._names.names.itervalues())
- for (ns, node) in nodes:
- try:
- self._resolve_node(node)
- except KeyError, e:
- self._transformer.log_node_warning(node,
-"""Unresolvable entry %r""" % (e, ))
- self._remove_attribute(node.name)
- # Another pass, since we need to have the methods parsed
- # in order to correctly modify them after class/record
- # pairing
- for (ns, node) in nodes:
- # associate GtkButtonClass with GtkButton
+
+ # In this first pass, we're just looking at functions and
+ # objects; try to match those up.
+ for node in self._namespace:
+ if isinstance(node, Function):
+ self._resolve_function_toplevel(node)
+ elif isinstance(node, GLibObject):
+ self._resolve_glib_object(node)
+ elif isinstance(node, GLibInterface):
+ self._resolve_glib_interface(node)
+
+ # Second pass; a variety of things happen here
+ for node in self._namespace:
if isinstance(node, Record):
- self._pair_class_record(node)
- for (ns, alias) in self._names.aliases.itervalues():
- self._resolve_alias(alias)
+ self._pass2_pair_class_record(node)
+ elif isinstance(node, Callable):
+ self._pass2_callable(node)
self._resolve_quarks()
- # Our final pass replacing types
- self._resolve_types(nodes)
-
- # Create a new namespace with what we found
- namespace = Namespace(self._namespace_name, self._namespace_version)
- namespace.nodes = map(lambda x: x[1], self._names.aliases.itervalues())
- for (ns, x) in self._names.names.itervalues():
- namespace.nodes.append(x)
- return namespace
+ return self._namespace
# Private
- def _add_attribute(self, node, replace=False):
- node_name = node.name
- if (not replace) and node_name in self._names.names:
- return
- self._names.names[node_name] = (None, node)
-
- def _remove_attribute(self, name):
- del self._names.names[name]
-
- def _get_attribute(self, name):
- node = self._names.names.get(name)
- if node:
- return node[1]
- return None
-
- def _lookup_node(self, name):
- if name in type_names:
- return None
- node = self._get_attribute(name)
- if node is None:
- node = self._transformer.get_names().names.get(name)
- if node:
- return node[1]
- return node
-
def _get_no_uscore_prefixed_name(self, type_name):
# Besides the straight underscore conversion, we also try
# removing the underscores from the namespace as a possible C
@@ -240,7 +195,9 @@ class GLibTransformer(object):
# but only covers enums that are registered as GObject enums.
# Create a fallback mapping based on all known enums in this module.
uscore_enums = {}
- for enum in self._transformer.iter_enums():
+ for enum in self._namespace.itervalues():
+ if not isinstance(enum, Enum):
+ continue
type_name = enum.symbol
uscored = to_underscores(type_name).lower()
@@ -285,7 +242,11 @@ class GLibTransformer(object):
continue
return Unresolved(gtype_names[0])
- def _execute_binary(self):
+ def _execute_binary_get_tree(self):
+ """Load the library (or executable), returning an XML
+blob containing data gleaned from GObject's primitive introspection."""
+ from xml.etree.cElementTree import parse
+
in_path = os.path.join(self._binary.tmpdir, 'types.txt')
f = open(in_path, 'w')
# TODO: Introspect GQuark functions
@@ -301,22 +262,14 @@ class GLibTransformer(object):
# Invoke the binary, having written our get_type functions to types.txt
try:
- subprocess.check_call(args, stdout=sys.stdout, stderr=sys.stderr)
- except subprocess.CalledProcessError, e:
- raise SystemExit(e)
- self._read_introspect_dump(out_path)
-
- # Clean up temporaries
- shutil.rmtree(self._binary.tmpdir)
-
- def _read_introspect_dump(self, xmlpath):
- from xml.etree.cElementTree import parse
- tree = parse(xmlpath)
- root = tree.getroot()
- for child in root:
- self._gtype_data[child.attrib['name']] = child
- for child in root:
- self._introspect_type(child)
+ try:
+ subprocess.check_call(args, stdout=sys.stdout, stderr=sys.stderr)
+ except subprocess.CalledProcessError, e:
+ # Clean up temporaries
+ raise SystemExit(e)
+ return parse(out_path)
+ finally:
+ shutil.rmtree(self._binary.tmpdir)
def _create_gobject(self, node):
type_name = 'G' + node.name
@@ -324,8 +277,7 @@ class GLibTransformer(object):
parent_gitype = None
symbol = 'intern'
elif type_name == 'GInitiallyUnowned':
- parent_type_name = 'GObject'
- parent_gitype = self._resolve_gtypename(parent_type_name)
+ parent_gitype = 'GLib.Object'
symbol = 'g_initially_unowned_get_type'
else:
assert False
@@ -341,69 +293,25 @@ class GLibTransformer(object):
# GInitiallyUnowned so that struct offset computation
# works correctly.
gnode.fields = self._names.names['Object'][1].fields
- self._add_attribute(gnode)
+ self._namespace.append(gnode, replace=True)
self._register_internal_type(type_name, gnode)
# Parser
- def _parse_node(self, node):
- if isinstance(node, Enum):
- self._parse_enum(node)
- elif isinstance(node, Bitfield):
- self._parse_bitfield(node)
- elif isinstance(node, Function):
- self._parse_function(node)
- elif isinstance(node, Record):
- self._parse_record(node)
- elif isinstance(node, Callback):
- self._parse_callback(node)
- elif isinstance(node, Alias):
- self._parse_alias(node)
- elif isinstance(node, Member):
- # FIXME: atk_misc_instance singletons
- pass
- elif isinstance(node, Union):
- self._parse_union(node)
- elif isinstance(node, Constant):
- self._parse_constant(node)
- else:
- print 'GLIB Transformer: Unhandled node:', node
-
- def _parse_alias(self, alias):
- self._names.aliases[alias.name] = (None, alias)
-
- def _parse_enum(self, enum):
- self._add_attribute(enum)
-
- def _parse_bitfield(self, enum):
- self._add_attribute(enum)
-
- def _parse_constant(self, constant):
- self._add_attribute(constant)
-
- def _parse_function(self, func):
- if func.symbol in SYMBOL_BLACKLIST:
- return
- if func.symbol.startswith('_'):
- return
- for regexp in SYMBOL_BLACKLIST_RE:
- if regexp.match(func.symbol):
- return
- if self._parse_get_type_function(func):
- return
- if self._parse_error_quark_function(func):
+ def _initparse_function(self, func):
+ symbol = func.symbol
+ if symbol.startswith('_'):
return
+ elif symbol.endswith('_get_type'):
+ self._initparse_get_type_function(func)
+ elif symbol.endswith('_error_quark'):
+ self._initparse_error_quark_function(func)
- self._add_attribute(func)
-
- def _parse_get_type_function(self, func):
- symbol = func.symbol
- if not symbol.endswith('_get_type'):
- return False
- if self._namespace_name == 'GLib':
+ def _initparse_get_type_function(self, func):
+ if self._namespace.name == 'GLib':
# No GObjects in GLib
return False
- if (self._namespace_name == 'GObject' and
+ if (self._namespace.name == 'GObject' and
symbol in ('g_object_get_type', 'g_initially_unowned_get_type')):
# We handle these internally, see _create_gobject
return True
@@ -421,13 +329,10 @@ class GLibTransformer(object):
self._get_type_functions.append(symbol)
return True
- def _parse_error_quark_function(self, func):
- if not func.symbol.endswith('_error_quark'):
- return False
+ def _initparse_error_quark_function(self, func):
if func.parameters:
return False
- if (func.retval.type.name != 'GLib.Quark' and
- func.retval.type.ctype != 'GQuark'):
+ if func.retval.type.target_giname != 'GLib.Quark':
return False
self._error_quark_functions.append(func)
@@ -457,7 +362,7 @@ class GLibTransformer(object):
target_klass = None
if not target_klass:
return None
- self._remove_attribute(func.name)
+ self._namespace.remove(func)
func.name = methname
target_klass.static_methods.append(func)
func.is_method = True
@@ -491,7 +396,7 @@ class GLibTransformer(object):
name = self._transformer.remove_prefix(argtype)
name_uscore = to_underscores_noprefix(name).lower()
# prefer the prefix of the _get_type method, if there is one
- if argtype in self._names.type_names:
+ if argtype in self._namespace.type_names:
node = self._names.type_names[argtype][1]
if hasattr(node, 'get_type'):
name_uscore = GET_TYPE_OVERRIDES.get(node.get_type,
@@ -550,7 +455,7 @@ class GLibTransformer(object):
name = self._transformer.remove_prefix(remove_prefix)
func.retval.type = Type(name, func.retval.type.ctype)
- self._remove_attribute(func.name)
+ self._namespace.remove(func)
# Strip namespace and object prefix: gtk_window_new -> new
func.name = func.symbol[len(prefix)+1:]
if is_method:
@@ -562,38 +467,15 @@ class GLibTransformer(object):
klass.constructors.append(func)
return func
- def _parse_record(self, record):
- # This is a hack, but GObject is a rather fundamental piece so.
- internal_names = ["Object", 'InitiallyUnowned']
- g_internal_names = ["G" + x for x in internal_names]
- if (self._namespace_name == 'GObject' and
- record.name in internal_names):
+ def _initparse_gobject_record(self, record):
+ # Special handling for when we're parsing GObject
+ internal_names = ("Object", 'InitiallyUnowned')
+ if record.name in internal_names:
self._create_gobject(record)
return
- elif record.name in g_internal_names:
- # Avoid duplicates
- return
if record.name == 'InitiallyUnownedClass':
record.fields = self._names.names['ObjectClass'][1].fields
- node = self._names.names.get(record.name)
- if node is None:
- self._add_attribute(record, replace=True)
- self._register_internal_type(record.symbol, record)
- return
- (ns, node) = node
- node.fields = record.fields[:]
-
- def _parse_union(self, union):
- node = self._names.names.get(union.name)
- if node is None:
- self._add_attribute(union, replace=True)
- self._register_internal_type(union.symbol, union)
- return
- (ns, node) = node
- node.fields = union.fields[:]
-
- def _parse_callback(self, callback):
- self._add_attribute(callback)
+ self._namespace.append(record, replace=True)
def _strip_class_suffix(self, name):
if (name.endswith('Class') or
@@ -612,7 +494,7 @@ class GLibTransformer(object):
return True
return False
- def _pair_class_record(self, maybe_class):
+ def _pass2_pair_class_record(self, maybe_class):
name = self._strip_class_suffix(maybe_class.name)
if name == maybe_class.name:
return
@@ -672,13 +554,13 @@ class GLibTransformer(object):
vfunc.invoker = method
gclass_struct = GLibRecord.from_record(class_struct)
- self._remove_attribute(class_struct.name)
- self._add_attribute(gclass_struct, True)
+ self._namespace.append(gclass_struct, replace=True)
pair_class.glib_type_struct = gclass_struct
pair_class.inherit_file_positions(class_struct)
gclass_struct.is_gtype_struct_for = name
- # Introspection
+ # Introspection over the data we get from the dynamic
+ # GObject/GType system out of the binary
def _introspect_type(self, xmlnode):
if xmlnode.tag in ('enum', 'flags'):
@@ -707,8 +589,7 @@ class GLibTransformer(object):
type_name = node.attrib['name']
enum_name = self._transformer.remove_prefix(type_name)
node = klass(enum_name, type_name, members, node.attrib['get-type'])
- self._add_attribute(node, replace=True)
- self._register_internal_type(type_name, node)
+ self._namespace.append(node, replace=True)
def _introspect_object(self, xmlnode):
type_name = xmlnode.attrib['name']
@@ -720,28 +601,24 @@ class GLibTransformer(object):
# 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.
#
- parent_type_names = xmlnode.attrib['parents'].split(',')
- parent_gitype = self._resolve_gtypename_chain(parent_type_names)
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 = GLibObject(self._transformer.remove_prefix(type_name),
+ None,
+ type_name,
+ xmlnode.attrib['get-type'], is_abstract)
+ node.parent_gtype_names = xmlnode.attrib['parents'].split(',')
self._introspect_properties(node, xmlnode)
self._introspect_signals(node, xmlnode)
self._introspect_implemented_interfaces(node, xmlnode)
self._add_record_fields(node)
- self._add_attribute(node, replace=True)
- self._register_internal_type(type_name, node)
+ self._namespace.append(node, replace=True)
def _introspect_interface(self, xmlnode):
type_name = xmlnode.attrib['name']
- node = GLibInterface(
- self._transformer.remove_prefix(type_name),
- None,
- type_name, xmlnode.attrib['get-type'])
+ node = GLibInterface(self._transformer.remove_prefix(type_name),
+ None,
+ type_name, xmlnode.attrib['get-type'])
self._introspect_properties(node, xmlnode)
self._introspect_signals(node, xmlnode)
for child in xmlnode.findall('prerequisite'):
@@ -751,11 +628,9 @@ class GLibTransformer(object):
# GtkFileChooserEmbed is an example of a private interface, we
# just filter them out
if xmlnode.attrib['get-type'].startswith('_'):
- print "NOTICE: Marking %s as internal type" % (type_name, )
self._private_internal_types[type_name] = node
else:
- self._add_attribute(node, replace=True)
- self._register_internal_type(type_name, node)
+ self._namespace.append(node, replace=True)
def _introspect_boxed(self, xmlnode):
type_name = xmlnode.attrib['name']
@@ -782,7 +657,7 @@ class GLibTransformer(object):
construct_only = (flags & G_PARAM_CONSTRUCT_ONLY) != 0
node.properties.append(Property(
pspec.attrib['name'],
- type_name_from_ctype(ctype),
+ self._transformer._create_type(ctype),
readable, writable, construct, construct_only,
ctype,
))
@@ -791,9 +666,8 @@ class GLibTransformer(object):
def _introspect_signals(self, node, xmlnode):
for signal_info in xmlnode.findall('signal'):
rctype = signal_info.attrib['return']
- rtype = Type(self._transformer.parse_ctype(rctype), rctype)
- return_ = Return(rtype, signal_info.attrib['return'])
- return_.transfer = PARAM_TRANSFER_FULL
+ rtype = self._transformer.create_type(rctype)
+ return_ = Return(rtype, PARAM_TRANSFER_FULL)
signal = GLibSignal(signal_info.attrib['name'], return_)
for i, parameter in enumerate(signal_info.findall('param')):
if i == 0:
@@ -801,8 +675,8 @@ class GLibTransformer(object):
else:
name = 'p%s' % (i-1, )
pctype = parameter.attrib['type']
- ptype = Type(self._transformer.parse_ctype(pctype), pctype)
- param = Parameter(name, ptype)
+ ptype = self._transformer.create_type(pctype)
+ param = Parameter(name, ptype, PARAM_TRANSFER_NONE)
param.transfer = 'none'
signal.parameters.append(param)
node.signals.append(signal)
@@ -838,30 +712,18 @@ class GLibTransformer(object):
boxed_item.fields = pair_node.fields
else:
return False
- self._add_attribute(boxed_item, replace=True)
+ self._namespace.append(boxed_item, replace=True)
# Node walking
- def _walk(self, node, callback, chain):
- if not isinstance(node, Node):
- return
+ def walk_node(self, node, callback, chain):
+ assert isinstance(node, Node)
if not callback(node, chain):
return
chain.append(node)
def _subwalk(subnode):
self._walk(subnode, callback, chain)
- if isinstance(node, (Callback, Callable)):
- _subwalk(node.retval)
- for parameter in node.parameters:
- _subwalk(parameter)
- elif isinstance(node, (Array, List)):
- _subwalk(node.element_type)
- elif isinstance(node, Map):
- _subwalk(node.key_type)
- _subwalk(node.value_type)
- elif isinstance(node, Bitfield):
- pass
- elif isinstance(node, Record):
+ if isinstance(node, Record):
for ctor in node.constructors:
_subwalk(ctor)
for func in node.methods:
@@ -877,21 +739,11 @@ class GLibTransformer(object):
_subwalk(meth)
for ctor in node.constructors:
_subwalk(ctor)
- for prop in node.properties:
- _subwalk(prop)
- for field in node.fields:
- _subwalk(field)
elif isinstance(node, Interface):
for meth in node.methods:
_subwalk(meth)
for meth in node.virtual_methods:
_subwalk(meth)
- for prop in node.properties:
- _subwalk(prop)
- for field in node.fields:
- _subwalk(field)
- elif isinstance(node, Constant):
- _subwalk(node.type)
elif isinstance(node, Union):
for ctor in node.constructors:
_subwalk(ctor)
@@ -903,52 +755,8 @@ class GLibTransformer(object):
for meth in node.methods:
_subwalk(meth)
- if isinstance(node, (GLibObject, GLibInterface)):
- for sig in node.signals:
- _subwalk(sig)
-
chain.pop()
- # Resolver
-
- def _resolve_type_name(self, type_name, ctype=None):
- # Workaround glib bug #548689, to be included in 2.18.0
- if type_name == "GParam":
- type_name = "GObject.ParamSpec"
- res = self._transformer.resolve_type_name_full
- try:
- return res(type_name, ctype, self._names)
- except KeyError, e:
- return self._transformer.resolve_type_name(type_name, ctype)
-
- def _resolve_param_type(self, ptype, **kwargs):
- # Workaround glib bug #548689, to be included in 2.18.0
- if ptype.name == "GParam":
- ptype.name = "GObject.ParamSpec"
- elif ptype.name == "GObject.Strv":
- return Array(None, ptype.ctype, Type('utf8'))
-
- return self._transformer.resolve_param_type_full(ptype,
- self._names,
- **kwargs)
-
- def _resolve_node(self, node):
- if isinstance(node, Function):
- self._resolve_function_toplevel(node)
-
- elif isinstance(node, Callback):
- self._resolve_function(node)
- elif isinstance(node, GLibObject):
- self._resolve_glib_object(node)
- elif isinstance(node, GLibInterface):
- self._resolve_glib_interface(node)
- elif isinstance(node, Record):
- self._resolve_record(node)
- elif isinstance(node, Union):
- self._resolve_union(node)
- elif isinstance(node, Alias):
- self._resolve_alias(node)
-
def _resolve_function_toplevel(self, func):
for parser in [self._parse_constructor,
self._parse_method,
@@ -987,9 +795,6 @@ class GLibTransformer(object):
def _resolve_glib_interface(self, node):
node.parent = self._force_resolve(node.parent)
- self._resolve_methods(node.methods)
- self._resolve_properties(node.properties, node)
- self._resolve_signals(node.signals)
node.prerequisites = filter(None,
[self._force_resolve(x, allow_unknown=True)
for x in node.prerequisites])
@@ -1009,13 +814,6 @@ class GLibTransformer(object):
node.interfaces = filter(None,
[self._force_resolve(x, allow_unknown=True)
for x in node.interfaces])
- self._resolve_constructors(node.constructors)
- self._resolve_methods(node.methods)
- self._resolve_methods(node.static_methods)
- self._resolve_properties(node.properties, node)
- self._resolve_signals(node.signals)
- for field in node.fields:
- self._resolve_field(field)
def _resolve_glib_boxed(self, node):
self._resolve_constructors(node.constructors)
@@ -1048,12 +846,58 @@ class GLibTransformer(object):
def _resolve_property(self, prop):
prop.type = self._resolve_param_type(prop.type, allow_invalid=False)
- def _adjust_throws(self, func):
- if func.parameters == []:
- return
- last_param = func.parameters.pop()
+ def _handle_closure(self, param, closure_idx, closure_param):
+ if (closure_param.type.name == 'any' and
+ closure_param.name.endswith('data')):
+ param.closure_name = closure_param.name
+ param.closure_index = closure_idx
+ return True
+ return False
+
+ def _handle_destroy(self, param, destroy_idx, destroy_param):
+ if (destroy_param.type.name == 'GLib.DestroyNotify' or
+ destroy_param.type.ctype == 'GDestroyNotify'):
+ param.destroy_name = destroy_param.name
+ param.destroy_index = destroy_idx
+ return True
+ return False
+
+ def _pass2_callable(self, node):
+ """Some analysis of a callable type.
+* Check to see if we have anything that looks like a callback+user_data+GDestroyNotify set.
+* Look for GError **.
+"""
+ for i, param in enumerate(node.params):
+ node = self._transformer.lookup_typenode(param.type)
+ if not isinstance(node, Callback):
+ continue
+
+ # set a default scope
+ if param.scope is None:
+ param.scope = 'call'
+
+ # j is the index where we look for closure/destroy to
+ # group with the callback param
+ j = i + 1
+ if j == len(params):
+ continue # no more args -> nothing to group
+ # look at the param directly following for either a
+ # closure or a destroy; only one of these will fire
+ had_closure = self._handle_closure(param, j, params[j])
+ had_destroy = self._handle_destroy(param, j, params[j])
+ j += 1
+ # are we out of params, or did we find neither?
+ if j == len(params) or (not had_closure and not had_destroy):
+ continue
+ # we found either a closure or a destroy; check the
+ # parameter following for the other
+ if not had_closure:
+ self._handle_closure(param, j, params[j])
+ if not had_destroy:
+ self._handle_destroy(param, j, params[j])
+ last_param = func.parameters.pop()
# Checking type.name=='GLib.Error' generates false positives
# on methods that take a 'GError *'
if last_param.type.ctype == 'GError**':
@@ -1061,47 +905,6 @@ class GLibTransformer(object):
else:
func.parameters.append(last_param)
- def _resolve_function(self, func):
- self._resolve_parameters(func.parameters)
- func.retval.type = self._resolve_param_type(func.retval.type)
- self._adjust_throws(func)
-
- def _resolve_parameters(self, parameters):
- for parameter in parameters:
- parameter.type = self._resolve_param_type(parameter.type)
-
- def _resolve_field(self, field):
- if isinstance(field, Callback):
- self._resolve_function(field)
- elif isinstance(field, Record): # non-typedef'd struct
- self._resolve_record(field)
- elif isinstance(field, Union): # non-typedef'd union
- self._resolve_union(field)
- else:
- field.type = self._resolve_param_type(field.type)
-
- def _resolve_alias(self, alias):
- alias.target = self._resolve_type_name(alias.target, alias.target)
-
- def _resolve_types(self, nodes):
- nodes = list(self._names.names.itervalues())
- i = 0
- self._validating = True
- while True:
- initlen = len(nodes)
-
- nodes = list(self._names.names.itervalues())
- for node in nodes:
- try:
- self._resolve_node(node)
- except UnknownTypeError, e:
- print "WARNING: %s: Deleting %r" % (e, node)
- self._remove_attribute(node.name)
- if len(nodes) == initlen:
- break
- i += 1
- self._validating = False
-
# Validation
def _interface_vfunc_check(self, node, stack):
@@ -1118,9 +921,7 @@ class GLibTransformer(object):
if isinstance(node.type, Varargs):
parent.introspectable = False
elif not isinstance(node.type, List) and \
- (node.type.name == 'GLib.List' or
- (self._transformer._namespace.name == 'GLib'
- and node.type.name == 'List')):
+ (node.type.target_giname == 'GLib.List'):
if isinstance(node, Parameter):
self._transformer.log_node_warning(parent,
"""Missing (element-type) annotation on argument %r""" % (node.name, ),
@@ -1130,24 +931,24 @@ class GLibTransformer(object):
"""Missing (element-type) annotation on return value""", context=parent)
parent.introspectable = False
- def _analyze_node(self, node, stack):
- if node.skip:
+ def _analyze_node(self, obj, stack):
+ if isinstance(obj, Node) and obj.skip:
return False
# Combine one-pass checks here
- self._interface_vfunc_check(node, stack)
+ self._interface_vfunc_check(obj, stack)
# Our first pass for scriptability
- self._introspectable_analysis(node, stack)
+ self._introspectable_analysis(obj, stack)
return True
- def _introspectable_pass2(self, node, stack):
- if node.skip:
+ def _introspectable_pass2(self, obj, stack):
+ if isinstance(obj, Node) and obj.skip:
return False
# In the second introspectable pass, we propagate introspectablity;
# for example, a varargs callback as an argument to a function
# makes the whole function unintrospectable
- if isinstance(node, TypeContainer):
+ if isinstance(obj, TypeContainer):
parent = stack[-1]
- target = self._lookup_node(node.type.name)
+ target = self._transformer.lookup_typenode(obj.type)
if target and not target.introspectable:
parent.introspectable = False
return True
@@ -1155,7 +956,7 @@ class GLibTransformer(object):
# This function is called at the very end, before we hand back the
# completed namespace to the writer. Add static analysis checks here.
def final_analyze(self):
- for (ns, node) in self._names.names.itervalues():
- self._walk(node, self._analyze_node, [])
- for (ns, node) in self._names.names.itervalues():
- self._walk(node, self._introspectable_pass2, [])
+ for node in self._namespace.itervalues():
+ self.walk_node(node, self._analyze_node, [])
+ for node in self._namespace.itervalues():
+ self.walk_node(node, self._introspectable_pass2, [])
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index 363f6f6..d543451 100644
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -34,6 +34,8 @@ from giscanner.minixpath import myxpath, xpath_assert
from giscanner.sourcescanner import SourceScanner
from giscanner.shlibs import resolve_shlibs
from giscanner.transformer import Transformer
+from giscanner.girparser import GIRParser
+from giscanner.girwriter import GIRWriter
def _get_option_parser():
parser = optparse.OptionParser('%prog [options] sources')
@@ -49,6 +51,9 @@ def _get_option_parser():
parser.add_option("-i", "--include",
action="append", dest="includes", default=[],
help="include types for other gidls")
+ parser.add_option('', "--passthrough-gir",
+ action="store", dest="passthrough_gir", default=None,
+ help="Parse and re-output the specified GIR")
parser.add_option("", "--add-include-path",
action="append", dest="include_paths", default=[],
help="include paths for other GIR files")
@@ -101,15 +106,9 @@ def _get_option_parser():
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose",
help="be verbose")
- parser.add_option("", "--noclosure",
- action="store_true", dest="noclosure",
- help="do not delete unknown types")
parser.add_option("", "--typelib-xml",
action="store_true", dest="typelib_xml",
help="Just convert GIR to typelib XML")
- parser.add_option("", "--inject",
- action="store_true", dest="inject",
- help="Inject additional components into GIR XML")
parser.add_option("", "--xpath-assertions",
action="store", dest="xpath_assertions",
help="Use given file to create assertions on GIR content")
@@ -136,54 +135,18 @@ def _get_option_parser():
def _error(msg):
raise SystemExit('ERROR: %s' % (msg, ))
-def typelib_xml_strip(path):
- from giscanner.girparser import GIRParser
- from giscanner.girwriter import GIRWriter
- from giscanner.girparser import C_NS
- from xml.etree.cElementTree import parse
-
- c_ns_key = '{%s}' % (C_NS, )
-
- tree = parse(path)
- root = tree.getroot()
- for node in root.getiterator():
- for attrib in list(node.attrib):
- if attrib.startswith(c_ns_key):
- del node.attrib[attrib]
+def passthrough_gir(path):
parser = GIRParser()
- parser.parse_tree(tree)
+ parser.parse(path)
writer = GIRWriter(parser.get_namespace(),
parser.get_shared_libraries(),
- parser.get_includes())
+ parser.get_includes(),
+ parser.get_pkgconfig_packages(),
+ parser.get_c_includes(),
+ parser.get_c_prefix())
sys.stdout.write(writer.get_xml())
- return 0
-
-def inject(path, additions, outpath):
- from giscanner.girparser import GIRParser
- from giscanner.girwriter import GIRWriter
- from xml.etree.cElementTree import parse
-
- tree = parse(path)
- root = tree.getroot()
- injectDoc = parse(open(additions))
- for node in injectDoc.getroot():
- injectPath = node.attrib['path']
- target = myxpath(root, injectPath)
- if not target:
- raise ValueError("Couldn't find path %r" % (injectPath, ))
- for child in node:
- target.append(child)
-
- parser = GIRParser()
- parser.parse_tree(tree)
- writer = GIRWriter(parser.get_namespace(),
- parser.get_shared_libraries(),
- parser.get_includes())
- outf = open(outpath, 'w')
- outf.write(writer.get_xml())
- outf.close()
- return 0
+ sys.exit(0)
def validate(assertions, path):
from xml.etree.cElementTree import parse
@@ -237,18 +200,12 @@ def scanner_main(args):
parser = _get_option_parser()
(options, args) = parser.parse_args(args)
+ if options.passthrough_gir:
+ return passthrough_gir(options.passthrough_gir)
+
if len(args) <= 1:
_error('Need at least one filename')
- if options.typelib_xml:
- return typelib_xml_strip(args[1])
-
- if options.inject:
- if len(args) != 4:
- _error('Need three filenames; e.g. g-ir-scanner '
- '--inject Source.gir Additions.xml SourceOut.gir')
- return inject(*args[1:4])
-
if options.xpath_assertions:
return validate(options.xpath_assertions, args[1])
@@ -314,8 +271,7 @@ def scanner_main(args):
# Transform the C AST nodes into higher level
# GLib/GObject nodes
- glibtransformer = GLibTransformer(transformer,
- noclosure=options.noclosure)
+ glibtransformer = GLibTransformer(transformer)
# Do enough parsing that we have the get_type() functions to reference
# when creating the introspection binary
diff --git a/giscanner/sourcescanner.py b/giscanner/sourcescanner.py
index acfc048..b024baf 100644
--- a/giscanner/sourcescanner.py
+++ b/giscanner/sourcescanner.py
@@ -154,10 +154,16 @@ class SourceSymbol(object):
self._symbol = symbol
def __repr__(self):
- return '<%s type=%r ident=%r>' % (
+ src = self.source_filename
+ if src:
+ line = self.line
+ if line:
+ src += ':%r' % (line,)
+ return '<%s type=%r ident=%r src=%r>' % (
self.__class__.__name__,
symbol_type_name(self.type),
- self.ident)
+ self.ident,
+ src)
@property
def const_int(self):
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index 319e43c..85ea657 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -22,12 +22,11 @@ import os
import sys
from .ast import (Bitfield, Callback, Enum, Function, Namespace, Member,
- Parameter, Return, Struct, Field,
+ Parameter, Return, Record, Field,
Type, Array, Alias, Interface, Class, Node, Union,
Varargs, Constant, type_name_from_ctype,
- type_names, TYPE_STRING, BASIC_GIR_TYPES)
+ type_names, default_array_types, TYPE_STRING, BASIC_GIR_TYPES)
from .config import DATADIR, GIR_DIR, GIR_SUFFIX
-from .glibast import GLibBoxed
from .girparser import GIRParser
from .odict import odict
from .sourcescanner import (
@@ -43,46 +42,25 @@ from .utils import to_underscores
_xdg_data_dirs = [x for x in os.environ.get('XDG_DATA_DIRS', '').split(':') \
+ [DATADIR, '/usr/share'] if x]
-
-class SkipError(Exception):
- pass
-
-
-class Names(object):
- names = property(lambda self: self._names)
- aliases = property(lambda self: self._aliases)
- type_names = property(lambda self: self._type_names)
- ctypes = property(lambda self: self._ctypes)
-
- def __init__(self):
- super(Names, self).__init__()
- self._names = odict() # Maps from GIName -> (namespace, node)
- self._aliases = {} # Maps from GIName -> GIName
- self._type_names = {} # Maps from GTName -> (namespace, node)
- self._ctypes = {} # Maps from CType -> (namespace, node)
-
-
class Transformer(object):
+ namespace = property(lambda self: self._namespace)
def __init__(self, cachestore, namespace_name, namespace_version):
self._cwd = os.getcwd() + os.sep
self._cachestore = cachestore
self.generator = None
self._namespace = Namespace(namespace_name, namespace_version)
- self._names = Names()
self._pkg_config_packages = set()
self._typedefs_ns = {}
self._strip_prefix = ''
self._enable_warnings = False
self._warned = False
- self._includes = set()
+ self._includes = {}
+ self._include_names = set()
self._includepaths = []
- def get_names(self):
- return self._names
-
def get_includes(self):
- return self._includes
+ return self._include_names
def set_strip_prefix(self, strip_prefix):
self._strip_prefix = strip_prefix
@@ -105,22 +83,42 @@ class Transformer(object):
def parse(self):
nodes = []
for symbol in self.generator.get_symbols():
- try:
- node = self._traverse_one(symbol)
- except SkipError:
+ if symbol.ident.startswith('_'):
continue
- self._add_node(node)
- return self._namespace
+ node = self._traverse_one(symbol)
+ if node:
+ self._namespace.append(node)
def set_include_paths(self, paths):
self._includepaths = list(paths)
def register_include(self, include):
- if include in self._includes:
+ if include in self._include_names:
return
filename = self._find_include(include)
self._parse_include(filename)
- self._includes.add(include)
+ self._include_names.add(include)
+
+ def lookup_giname(self, name):
+ """Given a name of the form Foo or Bar.Foo,
+return the corresponding Node, or None if none
+available. Will throw KeyError however for unknown
+namespaces."""
+ if '.' not in name:
+ return self._namespace.get(name)
+ else:
+ (ns, name) = name.split('.', 1)
+ include = self._includes[ns]
+ return include.get(name)
+
+ def lookup_typenode(self, typeobj):
+ """Given a Type object, if it points to a giname,
+calls lookup_giname() on the name. Otherwise return
+None."""
+ if typeobj.target_giname:
+ return self.lookup_giname(typeobj.target_giname)
+ return None
+
# Private
@@ -205,26 +203,7 @@ context will be used."""
for pkg in parser.get_pkgconfig_packages():
self._pkg_config_packages.add(pkg)
namespace = parser.get_namespace()
- nsname = namespace.name
- for node in namespace.nodes:
- if isinstance(node, Alias):
- self._names.aliases[node.name] = (nsname, node)
- elif isinstance(node, (GLibBoxed, Interface, Class)):
- self._names.type_names[node.type_name] = (nsname, node)
- giname = '%s.%s' % (nsname, node.name)
- self._names.names[giname] = (nsname, node)
- if hasattr(node, 'ctype'):
- self._names.ctypes[node.ctype] = (nsname, node)
- elif hasattr(node, 'symbol'):
- self._names.ctypes[node.symbol] = (nsname, node)
-
- def _add_node(self, node):
- if node is None:
- return
- if node.name.startswith('_'):
- return
- self._namespace.nodes.append(node)
- self._names.names[node.name] = (None, node)
+ self._includes[namespace.name] = namespace
def _strip_namespace_func(self, name):
prefix = self._namespace.name.lower() + '_'
@@ -263,17 +242,16 @@ context will be used."""
return self._create_struct(symbol)
elif stype == CSYMBOL_TYPE_ENUM:
return self._create_enum(symbol)
- elif stype == CSYMBOL_TYPE_OBJECT:
- return self._create_object(symbol)
elif stype == CSYMBOL_TYPE_MEMBER:
return self._create_member(symbol)
elif stype == CSYMBOL_TYPE_UNION:
return self._create_union(symbol)
- elif stype == CSYMBOL_TYPE_CONST:
- return self._create_const(symbol)
+ # FIXME - we should require an annotation on
+ # #defines to have them be constants, really
+ #elif stype == CSYMBOL_TYPE_CONST:
+ # return self._create_const(symbol)
else:
- raise NotImplementedError(
- 'Transformer: unhandled symbol: %r' % (symbol, ))
+ print 'transformer: unhandled symbol: %r' % (symbol, )
def _enum_common_prefix(self, symbol):
def common_prefix(a, b):
@@ -323,72 +301,11 @@ context will be used."""
klass = Enum
node = klass(enum_name, symbol.ident, members)
node.add_symbol_reference(symbol)
- self._names.type_names[symbol.ident] = (None, node)
return node
- def _create_object(self, symbol):
- node = Member(symbol.ident, symbol.base_type.name,
- symbol.ident)
- node.add_symbol_reference(symbol)
- return node
-
- def _type_is_callback(self, type):
- if isinstance(type, Callback):
- return True
- node = self._names.names.get(type.name)
- if node and isinstance(node[1], Callback):
- return True
- return False
-
- def _handle_closure(self, param, closure_idx, closure_param):
- if (closure_param.type.name == 'any' and
- closure_param.name.endswith('data')):
- param.closure_name = closure_param.name
- param.closure_index = closure_idx
- return True
- return False
-
- def _handle_destroy(self, param, destroy_idx, destroy_param):
- if (destroy_param.type.name == 'GLib.DestroyNotify' or
- destroy_param.type.ctype == 'GDestroyNotify'):
- param.destroy_name = destroy_param.name
- param.destroy_index = destroy_idx
- return True
- return False
-
- def _augment_callback_params(self, params):
- for i, param in enumerate(params):
- if not self._type_is_callback(param.type):
- continue
-
- # set a default scope
- if param.scope is None:
- param.scope = 'call'
-
- # j is the index where we look for closure/destroy to
- # group with the callback param
- j = i + 1
- if j == len(params):
- continue # no more args -> nothing to group
- # look at the param directly following for either a
- # closure or a destroy; only one of these will fire
- had_closure = self._handle_closure(param, j, params[j])
- had_destroy = self._handle_destroy(param, j, params[j])
- j += 1
- # are we out of params, or did we find neither?
- if j == len(params) or (not had_closure and not had_destroy):
- continue
- # we found either a closure or a destroy; check the
- # parameter following for the other
- if not had_closure:
- self._handle_closure(param, j, params[j])
- if not had_destroy:
- self._handle_destroy(param, j, params[j])
-
def _create_function(self, symbol):
parameters = list(self._create_parameters(symbol.base_type))
return_ = self._create_return(symbol.base_type.base_type)
- self._augment_callback_params(parameters)
name = self._strip_namespace_func(symbol.ident)
func = Function(name, return_, parameters, symbol.ident)
func.add_symbol_reference(symbol)
@@ -412,7 +329,6 @@ context will be used."""
return value
def _create_parameters(self, base_type):
-
# warn if we see annotations for unknown parameters
param_names = set(child.ident for child in base_type.child_list)
for child in base_type.child_list:
@@ -438,20 +354,17 @@ context will be used."""
else:
derefed_name = canonical_ctype
derefed_name = self.resolve_param_type(derefed_name)
- ftype = Array(None, ctype, self.parse_ctype(derefed_name))
+ ftype = Array(ctype, self.parse_ctype(derefed_name))
child_list = list(symbol.base_type.child_list)
ftype.zeroterminated = False
if child_list:
- ftype.size = '%d' % (child_list[0].const_int, )
+ ftype.size = child_list[0].const_int
else:
- ftype = self._create_type(symbol.base_type,
- is_param=False, is_retval=False)
- ftype = self.resolve_param_type(ftype)
+ ftype = self._create_type_from_base(symbol.base_type)
# Fields are assumed to be read-write
# (except for Objects, see also glibtransformer.py)
- node = Field(symbol.ident, ftype, ftype.name,
+ node = Field(symbol.ident, ftype, symbol.ident,
readable=True, writable=True, bits=symbol.const_int)
- node.add_symbol_reference(symbol)
return node
def _create_typedef(self, symbol):
@@ -527,47 +440,33 @@ context will be used."""
else:
return derefed_typename
- def _create_type(self, source_type, is_param, is_retval):
+ def _create_type_from_base(self, source_type):
ctype = self._create_source_type(source_type)
- if ctype.startswith('va_list'):
- raise SkipError()
- # FIXME: FILE* should not be skipped, it should be handled
- # properly instead
- elif ctype == 'FILE*':
- raise SkipError
-
- is_member = not (is_param or is_retval)
- # Here we handle basic type parsing; most of the heavy lifting
- # and inference comes in annotationparser.py when we merge
- # in annotation data.
- derefed_name = self.parse_ctype(ctype, is_member)
- rettype = Type(derefed_name, ctype)
- rettype.canonical = self._canonicalize_ctype(ctype)
- derefed_ctype = ctype.replace('*', '')
- rettype.derefed_canonical = self._canonicalize_ctype(derefed_ctype)
-
- canontype = type_name_from_ctype(ctype)
- # Is it a const char * or a const gpointer?
- if ((canontype == TYPE_STRING or source_type.type == CTYPE_POINTER) and
- (source_type.base_type.type_qualifier & TYPE_QUALIFIER_CONST)):
- rettype.is_const = True
- return rettype
+ const = ((source_type.type == CTYPE_POINTER) and
+ (source_type.base_type.type_qualifier & TYPE_QUALIFIER_CONST))
+ return self.create_type(ctype, is_const=const)
+
+ def create_type(self, ctype, is_const=False):
+ canonical = self._canonicalize_ctype(ctype)
+
+ if canonical in type_names:
+ return Type(target_fundamental=canonical, ctype=canonical,
+ is_const=is_const)
+ elif canonical in default_array_types:
+ element_type = canonical[:-1]
+ return Array(element_type, canonical, is_const=is_const)
+
+ return Type(ctype=ctype)
def _create_parameter(self, symbol):
if symbol.type == CSYMBOL_TYPE_ELLIPSIS:
ptype = Varargs()
else:
- ptype = self._create_type(symbol.base_type,
- is_param=True, is_retval=False)
- ptype = self.resolve_param_type(ptype)
+ ptype = self._create_type_from_base(symbol.base_type)
return Parameter(symbol.ident, ptype)
def _create_return(self, source_type):
- rtype = self._create_type(source_type,
- is_param=False, is_retval=True)
- rtype = self.resolve_param_type(rtype)
- return_ = Return(rtype)
- return return_
+ return Return(self._create_type_from_base(source_type))
def _create_const(self, symbol):
# Don't create constants for non-public things
@@ -594,7 +493,7 @@ context will be used."""
def _create_typedef_struct(self, symbol, disguised=False):
name = self.remove_prefix(symbol.ident)
- struct = Struct(name, symbol.ident, disguised)
+ struct = Record(name, symbol.ident, disguised)
struct.add_symbol_reference(symbol)
self._typedefs_ns[symbol.ident] = struct
self._create_struct(symbol)
@@ -643,7 +542,7 @@ context will be used."""
return compound
def _create_struct(self, symbol, anonymous=False):
- return self._create_compound(Struct, symbol, anonymous)
+ return self._create_compound(Record, symbol, anonymous)
def _create_union(self, symbol, anonymous=False):
return self._create_compound(Union, symbol, anonymous)
@@ -654,15 +553,15 @@ context will be used."""
# Mark the 'user_data' arguments
for i, param in enumerate(parameters):
- if (param.type.name == 'any' and
- param.name == 'user_data'):
+ if (param.type.target_fundamental == 'any' and
+ param.argname == 'user_data'):
param.closure_index = i
if symbol.ident.find('_') > 0:
name = self.remove_prefix(symbol.ident, True)
else:
name = self.remove_prefix(symbol.ident)
- callback = Callback(name, retval, parameters, symbol.ident)
+ callback = Callback(name, retval, parameters)
callback.add_symbol_reference(symbol)
return callback
@@ -673,53 +572,6 @@ context will be used."""
return item.name
return '%s.%s' % (nsname, item.name)
- def _resolve_type_name_1(self, type_name, ctype, names):
- # First look using the built-in names
- if ctype:
- try:
- return type_names[ctype]
- except KeyError, e:
- pass
- try:
- return type_names[type_name]
- except KeyError, e:
- pass
-
- if ctype:
- ctype = ctype.replace('*', '')
- resolved = names.ctypes.get(ctype)
- if resolved:
- return self._typepair_to_str(resolved)
- type_name = self.remove_prefix(type_name)
- resolved = names.aliases.get(type_name)
- if resolved:
- return self._typepair_to_str(resolved)
- resolved = names.names.get(type_name)
- if resolved:
- return self._typepair_to_str(resolved)
- resolved = names.type_names.get(type_name)
- if resolved:
- return self._typepair_to_str(resolved)
- raise KeyError("failed to find %r" % (type_name, ))
-
- def resolve_type_name_full(self, type_name, ctype,
- names, allow_invalid=True):
- try:
- return self._resolve_type_name_1(type_name, ctype, names)
- except KeyError, e:
- try:
- return self._resolve_type_name_1(type_name, ctype, self._names)
- except KeyError, e:
- if not allow_invalid:
- raise
- return type_name
-
- def resolve_type_name(self, type_name, ctype=None):
- try:
- return self.resolve_type_name_full(type_name, ctype, self._names)
- except KeyError, e:
- return type_name
-
def gtypename_to_giname(self, gtname, names):
resolved = names.type_names.get(gtname)
if resolved:
@@ -737,23 +589,6 @@ context will be used."""
else:
return None
- def resolve_param_type_full(self, ptype, names, **kwargs):
- if isinstance(ptype, Node):
- ptype.name = self.resolve_type_name_full(ptype.name,
- self.ctype_of(ptype),
- names, **kwargs)
- elif isinstance(ptype, basestring):
- return self.resolve_type_name_full(ptype, ptype, names, **kwargs)
- else:
- raise AssertionError("Unhandled param: %r" % (ptype, ))
- return ptype
-
- def resolve_param_type(self, ptype):
- try:
- return self.resolve_param_type_full(ptype, self._names)
- except KeyError, e:
- return ptype
-
def follow_aliases(self, type_name, names):
while True:
resolved = names.aliases.get(type_name)
@@ -763,8 +598,3 @@ context will be used."""
else:
break
return type_name
-
- def iter_enums(self):
- for node in self._namespace.nodes:
- if isinstance(node, Enum):
- yield node
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]