From 0b013d3cdd26d4a5f048e4df2cc17ffe177bdb21 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 24 Feb 2013 03:55:18 -0500 Subject: scanner: internals cleanup: Key more things off Namespace The .gir format has a weird legacy where stuff like the includes are outside of the . But conceptually they're tied together, so let's start reflecting this in the code. This way we can just pass around and look at a Namespace object instead of a 4-tuple of (namespace, includes, c_includes, pkg_config). https://bugzilla.gnome.org/show_bug.cgi?id=694593 --- giscanner/ast.py | 1 + giscanner/girparser.py | 7 ++----- giscanner/girwriter.py | 10 ++++------ giscanner/scannermain.py | 3 +-- giscanner/transformer.py | 31 ++++++++++++++----------------- tests/scanner/Bar-1.0-expected.gir | 1 - tests/scanner/GetType-1.0-expected.gir | 1 - tests/scanner/GtkFrob-1.0-expected.gir | 1 - tests/scanner/Regress-1.0-expected.gir | 2 -- tests/scanner/SLetter-1.0-expected.gir | 2 -- tests/scanner/Utility-1.0-expected.gir | 1 - tests/scanner/WarnLib-1.0-expected.gir | 2 -- 12 files changed, 22 insertions(+), 40 deletions(-) diff --git a/giscanner/ast.py b/giscanner/ast.py index 09616f65..d9f23539 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -372,6 +372,7 @@ class Namespace(object): self.type_names = {} # Maps from GTName -> node self.ctypes = {} # Maps from CType -> node self.symbols = {} # Maps from function symbols -> Function + self.includes = set() # Include def type_from_name(self, name, ctype=None): """Backwards compatibility method for older .gir files, which diff --git a/giscanner/girparser.py b/giscanner/girparser.py index 4cba5065..f2908bff 100644 --- a/giscanner/girparser.py +++ b/giscanner/girparser.py @@ -47,7 +47,6 @@ class GIRParser(object): def __init__(self, types_only=False): self._types_only = types_only self._shared_libraries = [] - self._includes = set() self._pkgconfig_packages = set() self._namespace = None self._filename_stack = [] @@ -62,10 +61,10 @@ class GIRParser(object): self._filename_stack.pop() def parse_tree(self, tree): - self._includes.clear() self._namespace = None self._shared_libraries = [] self._pkgconfig_packages = set() + self._includes = set() self._c_includes = set() self._c_prefix = None self._parse_api(tree.getroot()) @@ -76,9 +75,6 @@ class GIRParser(object): def get_shared_libraries(self): return self._shared_libraries - def get_includes(self): - return self._includes - def get_c_includes(self): return self._c_includes @@ -146,6 +142,7 @@ class GIRParser(object): if 'shared-library' in ns.attrib: self._shared_libraries.extend( ns.attrib['shared-library'].split(',')) + self._namespace.includes = self._includes parser_methods = { _corens('alias'): self._parse_alias, diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index ea9305cd..73b58772 100644 --- a/giscanner/girwriter.py +++ b/giscanner/girwriter.py @@ -30,19 +30,17 @@ COMPATIBLE_GIR_VERSION = '1.2' class GIRWriter(XMLWriter): - def __init__(self, namespace, shlibs, includes, pkgs, c_includes): + def __init__(self, namespace, shlibs, pkgs, c_includes): super(GIRWriter, self).__init__() self.write_comment( '''This file was automatically generated from C sources - DO NOT EDIT! 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, + self._write_repository(namespace, shlibs, pkgs, c_includes) - def _write_repository(self, namespace, shlibs, includes=None, + def _write_repository(self, namespace, shlibs, packages=None, c_includes=None): - if includes is None: - includes = frozenset() if packages is None: packages = frozenset() if c_includes is None: @@ -54,7 +52,7 @@ and/or use gtk-doc annotations. ''') ('xmlns:glib', 'http://www.gtk.org/introspection/glib/1.0'), ] with self.tagcontext('repository', attrs): - for include in sorted(includes): + for include in sorted(namespace.includes): self._write_include(include) for pkg in sorted(set(packages)): self._write_pkgconfig_pkg(pkg) diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py index 56d73f8c..9ca45a2f 100755 --- a/giscanner/scannermain.py +++ b/giscanner/scannermain.py @@ -195,7 +195,6 @@ def passthrough_gir(path, f): writer = GIRWriter(parser.get_namespace(), parser.get_shared_libraries(), - parser.get_includes(), parser.get_pkgconfig_packages(), parser.get_c_includes()) f.write(writer.get_xml()) @@ -473,7 +472,7 @@ def scanner_main(args): else: exported_packages = options.packages - writer = Writer(transformer.namespace, shlibs, transformer.get_includes(), + writer = Writer(transformer.namespace, shlibs, exported_packages, options.c_includes) data = writer.get_xml() diff --git a/giscanner/transformer.py b/giscanner/transformer.py index e05249c3..4c008da1 100644 --- a/giscanner/transformer.py +++ b/giscanner/transformer.py @@ -54,15 +54,11 @@ class Transformer(object): self._namespace = namespace self._pkg_config_packages = set() self._typedefs_ns = {} - self._includes = {} # Namespace> - self._include_names = set() # string namespace + self._parsed_includes = {} # Namespace> self._includepaths = [] self._passthrough_mode = False self._annotations = {} - def get_includes(self): - return self._include_names - def get_pkgconfig_packages(self): return self._pkg_config_packages @@ -125,11 +121,11 @@ class Transformer(object): self._includepaths = list(paths) def register_include(self, include): - if include in self._include_names: + if include in self._namespace.includes: return + self._namespace.includes.add(include) filename = self._find_include(include) self._parse_include(filename) - self._include_names.add(include) def register_include_uninstalled(self, include_path): basename = os.path.basename(include_path) @@ -138,10 +134,10 @@ class Transformer(object): "Include path %r must be a filename path ending in .gir" % (include_path, )) girname = basename[:-4] include = ast.Include.from_string(girname) - if include in self._include_names: + if include in self._namespace.includes: return + self._namespace.includes.add(include) self._parse_include(include_path, uninstalled=True) - self._include_names.add(include) def lookup_giname(self, name): """Given a name of the form Foo or Bar.Foo, @@ -155,11 +151,11 @@ namespaces.""" if ns == self._namespace.name: return self._namespace.get(giname) # Fallback to the main namespace if not a dependency and matches a prefix - if ns in self._namespace.identifier_prefixes and not ns in self._includes: + if ns in self._namespace.identifier_prefixes and not ns in self._parsed_includes: message.warn(("Deprecated reference to identifier " + "prefix %s in GIName %s") % (ns, name)) return self._namespace.get(giname) - include = self._includes[ns] + include = self._parsed_includes[ns] return include.get(giname) def lookup_typenode(self, typeobj): @@ -196,7 +192,7 @@ None.""" self._parse_include(filename) parser = self._cachestore.load(filename) self._namespace = parser.get_namespace() - del self._includes[self._namespace.name] + del self._parsed_includes[self._namespace.name] return self def _parse_include(self, filename, uninstalled=False): @@ -209,20 +205,21 @@ None.""" if self._cachestore is not None: self._cachestore.store(filename, parser) - for include in parser.get_includes(): - self.register_include(include) + for include in parser.get_namespace().includes: + dep_filename = self._find_include(include) + self._parse_include(dep_filename) if not uninstalled: for pkg in parser.get_pkgconfig_packages(): self._pkg_config_packages.add(pkg) namespace = parser.get_namespace() - self._includes[namespace.name] = namespace + self._parsed_includes[namespace.name] = namespace def _iter_namespaces(self): """Return an iterator over all included namespaces; the currently-scanned namespace is first.""" yield self._namespace - for ns in self._includes.itervalues(): + for ns in self._parsed_includes.itervalues(): yield ns def _sort_matches(self, x, y): @@ -899,7 +896,7 @@ Note that type resolution may not succeed.""" # which has nominal namespace of "Meta", but a few classes are # "Mutter". We don't export that data in introspection currently. # Basically the library should be fixed, but we'll hack around it here. - for namespace in self._includes.itervalues(): + for namespace in self._parsed_includes.itervalues(): target = namespace.get_by_ctype(pointer_stripped) if target: typeval.target_giname = '%s.%s' % (namespace.name, target.name) diff --git a/tests/scanner/Bar-1.0-expected.gir b/tests/scanner/Bar-1.0-expected.gir index ef92fcc4..245adfff 100644 --- a/tests/scanner/Bar-1.0-expected.gir +++ b/tests/scanner/Bar-1.0-expected.gir @@ -6,7 +6,6 @@ and/or use gtk-doc annotations. --> xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> - xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> - diff --git a/tests/scanner/GtkFrob-1.0-expected.gir b/tests/scanner/GtkFrob-1.0-expected.gir index c8758472..a4e39ef1 100644 --- a/tests/scanner/GtkFrob-1.0-expected.gir +++ b/tests/scanner/GtkFrob-1.0-expected.gir @@ -6,7 +6,6 @@ and/or use gtk-doc annotations. --> xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> - xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> - - diff --git a/tests/scanner/SLetter-1.0-expected.gir b/tests/scanner/SLetter-1.0-expected.gir index 0c438609..a98ebb27 100644 --- a/tests/scanner/SLetter-1.0-expected.gir +++ b/tests/scanner/SLetter-1.0-expected.gir @@ -6,8 +6,6 @@ and/or use gtk-doc annotations. --> xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> - - xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> - diff --git a/tests/scanner/WarnLib-1.0-expected.gir b/tests/scanner/WarnLib-1.0-expected.gir index e4a9a9b4..0fc0d846 100644 --- a/tests/scanner/WarnLib-1.0-expected.gir +++ b/tests/scanner/WarnLib-1.0-expected.gir @@ -6,8 +6,6 @@ and/or use gtk-doc annotations. --> xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> - -