def test_incremental(self): param = ParameterSymbol( type_tokens=[Link(None, 'test-struct', 'test-struct')]) func = self.database.get_or_create_symbol( FunctionSymbol, unique_name='test-symbol', filename='text_b.x', parameters=[param]) func.resolve_links(self.link_resolver) self.assertEqual(param.get_type_link().get_link(self.link_resolver), None) struct = self.database.get_or_create_symbol( StructSymbol, unique_name='test-struct', filename='test_a.x') struct.resolve_links(self.link_resolver) func.resolve_links(self.link_resolver) # Not in a page but still self.assertEqual(param.get_type_link().get_link(self.link_resolver), 'test-struct') self.database.persist() self.database.close() self.database = Database() self.database.setup(self.__priv_dir) self.link_resolver = LinkResolver(self.database) param = ParameterSymbol( type_tokens=[Link(None, 'test-struct', 'test-struct')]) func = self.database.get_or_create_symbol( FunctionSymbol, unique_name='test-symbol', filename='text_b.x', parameters=[param]) func.resolve_links(self.link_resolver) self.assertEqual(param.get_type_link().get_link(self.link_resolver), 'test-struct')
def make_c_style_type_name(self, type_): tokens = [] while (type_.kind == cindex.TypeKind.POINTER): self.__apply_qualifiers(type_, tokens) tokens.append('*') type_ = type_.get_pointee() if type_.kind == cindex.TypeKind.TYPEDEF: d = type_.get_declaration() link = Link(None, d.displayname, d.displayname) tokens.append(link) self.__apply_qualifiers(type_, tokens) elif type_.kind == cindex.TypeKind.UNEXPOSED: d = type_.get_declaration() if d.spelling: tokens.append(Link(None, d.displayname, d.displayname)) else: tokens.append('__UNKNOWN__') if d.kind == cindex.CursorKind.STRUCT_DECL: tokens.append('struct ') elif d.kind == cindex.CursorKind.ENUM_DECL: tokens.append('enum ') else: tokens.append(type_.spelling + ' ') tokens.reverse() return tokens
def __create_signal_symbol(self, node, parent_name): unique_name, name, klass_name = get_symbol_names(node) parameters, retval = self.__create_parameters_and_retval(node) parent_node = node.getparent() parent_gi_name = get_gi_name(parent_node) parent_link = Link(None, parent_name, parent_name) instance_param = ParameterSymbol(argname='self', type_tokens=[parent_link, '*']) type_desc = SymbolTypeDesc([], parent_gi_name, None, 0) self.add_attrs(instance_param, type_desc=type_desc, direction='in') parameters.insert(0, instance_param) udata_link = Link(None, 'gpointer', 'gpointer') udata_param = ParameterSymbol(argname='user_data', type_tokens=[udata_link]) type_desc = SymbolTypeDesc([], 'gpointer', None, 0) self.add_attrs(udata_param, type_desc=type_desc, direction='in', is_closure=True) parameters.append(udata_param) res = self.create_symbol(SignalSymbol, node, parameters=parameters, return_value=retval, display_name=name, unique_name=unique_name, filename=self.__get_symbol_filename( klass_name, node), parent_name=parent_name) if res: flags = [] when = node.attrib.get('when') if when == "first": flags.append(RunFirstFlag()) elif when == "last": flags.append(RunLastFlag()) elif when == "cleanup": flags.append(RunCleanupFlag()) no_hooks = node.attrib.get('no-hooks') if no_hooks == '1': flags.append(NoHooksFlag()) # This is incorrect, it's not yet format time extra_content = self.formatter._format_flags(flags) res.extension_contents['Flags'] = extra_content self.__sort_parameters(res, retval, parameters) return res
def _inject_fundamentals(): # Working around https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/744 CLanguage.add_fundamental( "JackClient", Link("https://jackaudio.org/api/jack_8h.html", 'jack_client_t', None)) CLanguage.add_fundamental( "GrapheneMatrix", Link( "https://developer.gnome.org/graphene/stable/graphene-Matrix.html#graphene-matrix-t", 'graphen_matrix_t', 'GrapheneMatrix')) CLanguage.add_fundamental( "CairoContext", Link("https://www.cairographics.org/manual/cairo-cairo-t.html#cairo-t", 'cairo_t', 'CairoContext'))
def __create_pad_template_symbols(self, element, plugin_name): templates = element.get('pad-templates', {}) res = [] if not templates: return res for tname, template in templates.items(): name = tname.replace("%%", "%") unique_name = '%s!%s' % (element['hierarchy'][0], name) pagename = 'element-' + element['name'] gtype = self._remember_symbol_type(template.get("type", "GstPad"), pagename) link = Link(None, gtype, gtype, mandatory=True) object_type = QualifiedSymbol(type_tokens=[link]) res.append( self.create_symbol(GstPadTemplateSymbol, name=name, direction=template["direction"], presence=template["presence"], caps=template["caps"], filename=plugin_name, parent_name=None, object_type=object_type, display_name=name, unique_name=unique_name, extra={'gst-element-name': pagename})) return res
def __create_parameters_and_retval(self, node): gi_parameters = node.find( '{http://www.gtk.org/introspection/core/1.0}parameters') if gi_parameters is None: instance_param = None gi_parameters = [] else: instance_param = \ gi_parameters.find( '{http://www.gtk.org/introspection/core/1.0}instance-parameter') gi_parameters = gi_parameters.findall( '{http://www.gtk.org/introspection/core/1.0}parameter') parameters = [] closure_indices = set() destroy_indices = set() out_parameters = [] for gi_parameter in gi_parameters: param, direction = self.__create_parameter_symbol(gi_parameter) parameters.append(param) if 'destroy' in gi_parameter.attrib: destroy_indices.add(int(gi_parameter.attrib['destroy'])) if 'closure' in gi_parameter.attrib: closure_indices.add(int(gi_parameter.attrib['closure'])) if direction != 'in': out_parameters.append(param) for idx in destroy_indices: param = parameters[idx] self.add_attrs(param, is_destroy=True) for idx in closure_indices: param = parameters[idx] self.add_attrs(param, is_closure=True) # We add our instance parameter last in order not to mess with # the destroy indices if instance_param is not None: param, direction = self.__create_parameter_symbol(instance_param) parameters.insert(0, param) if node.attrib.get('throws') == '1': type_desc = SymbolTypeDesc( [Link(None, 'GError', 'GError'), '*', '*'], 'GLib.Error', 'GError**', 0) param = ParameterSymbol(argname='error', type_tokens=type_desc.type_tokens) parameters.append(param) self.add_attrs(param, type_desc=type_desc, direction='out') retval = node.find( '{http://www.gtk.org/introspection/core/1.0}return-value') retval = self.__create_return_value_symbol(retval, out_parameters) return (parameters, retval)
def test_modified_link(self): inp = u"this : #foo is a link !" ast, _ = self.assertOutputs( inp, '<p>this : <a href="here.com">foo</a> is a link !</p>\n') self.link_resolver.upsert_link(Link("there.com", "ze_foo", "foo"), overwrite_ref=True) out = cmark.ast_to_html(ast, self.link_resolver)[0] self.assertEqual( out, u'<p>this : <a href="there.com">ze_foo</a> is a link !</p>\n')
def __create_hierarchy(self, pagename, element_dict): hierarchy = [] for klass_name in element_dict["hierarchy"][1:]: self._remember_symbol_type(klass_name, pagename) link = Link(None, klass_name, klass_name, mandatory=True) sym = QualifiedSymbol(type_tokens=[link]) hierarchy.append(sym) hierarchy.reverse() return hierarchy
def __get_link_cb(self, link_resolver, name): url_components = urlparse.urlparse(name) page = self.__all_pages.get(url_components.path) if page: ref = page.link.get_link() if url_components.fragment: ref += '#%s' % url_components.fragment return Link(ref, page.link.get_title(), None) return None
def create_hierarchy(element_dict): hierarchy = [] for klass_name in element_dict["hierarchy"][1:]: link = Link(None, klass_name, klass_name) sym = QualifiedSymbol(type_tokens=[link]) hierarchy.append(sym) hierarchy.reverse() return hierarchy
def resolve_links(self, link_resolver): """ Banana banana """ if self.link is None: self.link = Link(self.unique_name, self._make_name(), self.unique_name) self.link = link_resolver.upsert_link(self.link, overwrite_ref=True) for sym in self.get_children_symbols(): if sym: sym.resolve_links(link_resolver)
def __get_link_cb(self, link_resolver, name): url_components = urlparse(name) page = self.__all_pages.get(url_components.path) if not page: return None ext = self.__extensions[page.extension_name] formatter = ext.formatter prefix = formatter.get_output_folder(page) ref = page.link.ref if url_components.fragment: ref += '#%s' % url_components.fragment return Link(os.path.join(prefix, ref), page.link.get_title(), None)
def __init__(self, source_file, ast, output_path, project_name, meta=None, raw_contents=None): "Banana banana" assert source_file basename = os.path.basename(source_file) name = os.path.splitext(basename)[0] ref = os.path.join(output_path, re.sub(r'\W+', '-', os.path.splitext(basename)[0])) pagename = '%s.html' % ref self.ast = ast self.extension_name = None self.source_file = source_file self.raw_contents = raw_contents self.comment = None self.generated = False self.pre_sorted = False self.output_attrs = None self.subpages = OrderedSet() self.symbols = [] self.typed_symbols = {} self.is_stale = True self.formatted_contents = None self.detailed_description = None self.build_path = None self.project_name = project_name self.cached_paths = OrderedSet() meta = meta or {} try: self.meta = Schema(Page.meta_schema).validate(meta) except SchemaError as _: warn('invalid-page-metadata', '%s: Invalid metadata: \n%s' % (self.source_file, str(_))) self.meta = meta self.symbol_names = OrderedSet(meta.get('symbols') or []) self.short_description = meta.get('short-description') self.render_subpages = meta.get('render-subpages', True) self.title = None self.__discover_title(meta) self.link = Link(pagename, self.title or name, ref)
def setUp(self): self.database = Database(None) self.link_resolver = LinkResolver(self.database) self.link_resolver.add_link(Link("here.com", "foo", "foo")) self.link_resolver.add_link(Link("there.org", "there", "Test::test")) self.link_resolver.add_link(Link("wherever.biz", "wherever", "bar")) self.link_resolver.add_link(Link("whenever.net", "whenever", "Test")) self.link_resolver.add_link( Link("somewhere.me", "somewhere", "Test.baz")) self.link_resolver.add_link( Link("elsewhere.co", "elsewhere", "org.dbus.func"))
def __init__(self, source_file, ast, output_path, project_name, meta=None, raw_contents=None): "Banana banana" assert source_file basename = os.path.basename(source_file) name = os.path.splitext(basename)[0] ref = os.path.join(output_path, re.sub(r'\W+', '-', os.path.splitext(basename)[0])) pagename = '%s.html' % ref self.ast = ast self.extension_name = None self.source_file = source_file self.raw_contents = raw_contents self.comment = None self.generated = False self.pre_sorted = False self.output_attrs = None self.subpages = OrderedSet() self.symbols = [] self.private_symbols = [] self.typed_symbols = OrderedDict() self.by_parent_symbols = OrderedDict() self.is_stale = True self.formatted_contents = None self.detailed_description = None self.build_path = None self.project_name = project_name self.cached_paths = OrderedSet() meta = meta or {} self.listed_symbols = [] self.symbol_names = [] self.short_description = None self.render_subpages = True self.title = '' self.meta = Schema(Page.meta_schema).validate({}) self.__update_meta(meta) self.__discover_title(meta) self.link = Link(pagename, self.title or name, ref)
def __init__(self, source_file, ast, meta=None, raw_contents=None): "Banana banana" assert source_file if os.path.isabs(source_file): basename = os.path.basename(source_file) else: basename = source_file.replace('/', '-') name = os.path.splitext(basename)[0] pagename = '%s.html' % name self.ast = ast self.extension_name = None self.source_file = source_file self.raw_contents = raw_contents self.comment = None self.generated = False self.output_attrs = None self.subpages = OrderedSet() self.symbols = [] self.typed_symbols = {} self.is_stale = True self.formatted_contents = None self.detailed_description = None meta = meta or {} try: self.meta = Schema(Page.meta_schema).validate(meta) except SchemaError as _: warn('invalid-page-metadata', '%s: Invalid metadata: \n%s' % (self.source_file, str(_))) self.meta = meta self.symbol_names = OrderedSet(meta.get('symbols') or []) self.short_description = meta.get('short-description') self.title = None self.__discover_title(meta) self.link = Link(pagename, self.title or name, name)
def __init__(self, link, title): Link.__init__(self) self.link = link self._title = title self.id_ = None
def type_tokens_from_type_name(type_name, python_lang): res = [Link(None, type_name, type_name)] if python_lang and not python_lang.get_fundamental(type_name): res.append('<span class="pointer-token">*</span>') return res
def _create_fundamentals(self): string_link = \ Link('https://developer.mozilla.org/en-US/docs/Web/' 'JavaScript/Reference/Global_Objects/String', 'String', None) boolean_link = \ Link('https://developer.mozilla.org/en-US/docs/Web/' 'JavaScript/Reference/Global_Objects/Boolean', 'Boolean', None) pointer_link = \ Link('https://developer.mozilla.org/en-US/docs/Web/' 'JavaScript/Reference/Global_Objects/Object', 'Object', None) true_link = \ Link('https://developer.mozilla.org/en-US/docs/Web/' 'JavaScript/Reference/Global_Objects/Boolean', 'true', None) false_link = \ Link('https://developer.mozilla.org/en-US/docs/Web/' 'JavaScript/Reference/Global_Objects/Boolean', 'false', None) number_link = \ Link('https://developer.mozilla.org/en-US/docs/Glossary/Number', 'Number', None) null_link = \ Link('https://developer.mozilla.org/en-US/docs/Web/' 'JavaScript/Reference/Global_Objects/null', 'null', None) gtype_link = \ Link('https://developer.gnome.org/gobject/stable/' 'gobject-Type-Information.html#GType', 'GObject.Type', None) self.fundamentals = { 'gchararray': string_link, 'gunichar': string_link, 'utf8': string_link, 'gchar': string_link, 'guchar': number_link, 'gint8': number_link, 'guint8': number_link, 'gint16': number_link, 'guint16': number_link, 'gint32': number_link, 'guint32': number_link, 'gint64': number_link, 'guint64': number_link, 'gshort': number_link, 'gint': number_link, 'guint': number_link, 'glong': number_link, 'gulong': number_link, 'gsize': number_link, 'gssize': number_link, 'gintptr': number_link, 'guintptr': number_link, 'gfloat': number_link, 'gdouble': number_link, 'gboolean': number_link, 'TRUE': true_link, 'FALSE': false_link, 'gpointer': pointer_link, 'GType': gtype_link, 'NULL': null_link, }
def __init__(self, name, generated, project_name, extension_name, source_file=None, ast=None, output_path='', raw_contents=None, comment=None, meta=None, pre_sorted=False, symbol_names=None): assert name if not generated: assert source_file is not None self.name = name basename = os.path.basename(name) name = os.path.splitext(basename)[0] ref = os.path.join(output_path, re.sub(r'\W+', '-', os.path.splitext(basename)[0])) pagename = '%s.html' % ref self.generated = generated self.project_name = project_name self.extension_name = extension_name self.source_file = source_file self.ast = ast self.raw_contents = raw_contents self.comment = comment self.pre_sorted = pre_sorted self.symbol_names = OrderedSet(symbol_names or []) self.output_attrs = None self.subpages = OrderedSet() self.symbols = [] self.private_symbols = [] self.typed_symbols = OrderedDict() self.by_parent_symbols = OrderedDict() self.formatted_contents = None self.detailed_description = None self.build_path = None self.cached_paths = OrderedSet() if comment: meta = comment.meta elif meta: meta = meta else: meta = {} self.meta = {} for key, value in meta.items(): try: self.meta.update(Schema(Page.meta_schema).validate({ key.replace('_', '-').lower(): value})) except SchemaError as err: warn('invalid-page-metadata', '%s: Invalid metadata: \n%s, discarding metadata' % (self.name, str(err))) if not self.meta.get('extra'): self.meta['extra'] = defaultdict() self.title = self.meta.get( 'title', cmark.title_from_ast(self.ast) if ast else '') self.thumbnail = self.meta.get('thumbnail') self.short_description = self.meta.get('short-description', None) self.render_subpages = self.meta.get('render-subpages', True) self.link = Link(pagename, self.title or name, ref)
def setUp(self): self.database = Database(None) self.link_resolver = LinkResolver(self.database) self.link_resolver.add_link(Link("here.com", "foo", "foo"))
class Symbol(Base): """ The base class for all symbols, there should be no reason for instantiating it directly. """ __tablename__ = 'symbols' id_ = Column(Integer, primary_key=True) comment = Column(PickleType) unique_name = Column(String) display_name = Column(String) filename = Column(String) lineno = Column(Integer) extent_start = Column(Integer) extent_end = Column(Integer) language = Column(String) extra = Column(MutableDict.as_mutable(PickleType)) _type_ = Column(String) extension_contents = Column(MutableDict.as_mutable(PickleType)) extension_attributes = Column(MutableDict.as_mutable(PickleType)) link = Column(Link.as_mutable(PickleType)) skip = Column(Boolean) project_name = Column(String) __mapper_args__ = { 'polymorphic_identity': 'symbol', 'polymorphic_on': _type_, } def __init__(self, **kwargs): self.extension_contents = {} self.extension_attributes = {} self.skip = False self.extra = {} Base.__init__(self, **kwargs) @classmethod def get_plural_name(cls): """Default implementation of the vmethod to retrieve Plurial form of the symbol name.""" return cls.__tablename__.replace("_", " ").title() # FIXME: this is a bit awkward to use. def add_extension_attribute(self, ext_name, key, value): """ Banana banana """ attributes = self.extension_attributes.pop(ext_name, {}) attributes[key] = value self.extension_attributes[ext_name] = attributes def get_extension_attribute(self, ext_name, key): """ Banana banana """ attributes = self.extension_attributes.get(ext_name) if not attributes: return None return attributes.get(key) # pylint: disable=no-self-use def get_children_symbols(self): """ Banana banana """ return [] # pylint: disable=unidiomatic-typecheck # pylint: disable=no-member def update_children_comments(self): """ Banana banana """ if self.comment is None: return for sym in self.get_children_symbols(): if type(sym) == ParameterSymbol: sym.comment = self.comment.params.get(sym.argname) elif type(sym) == FieldSymbol: if not sym.comment or not sym.comment.description: sym.comment = self.comment.params.get(sym.member_name) elif type(sym) == ReturnItemSymbol: tag = self.comment.tags.get('returns') sym.comment = comment_from_tag(tag) elif type(sym) == Symbol: sym.comment = self.comment.params.get(sym.display_name) def _make_name(self): return self.display_name def get_extra_links(self): """ Banana banana """ return [] def get_type_name(self): """ Banana banana """ return '' def resolve_links(self, link_resolver): """ Banana banana """ if self.link is None: self.link = Link(self.unique_name, self._make_name(), self.unique_name) self.link = link_resolver.upsert_link(self.link, overwrite_ref=True) for sym in self.get_children_symbols(): if sym: sym.resolve_links(link_resolver)
def __parse_plugin(self, plugin_name, plugin): elements = [] feature_names = list(plugin.get('elements', {}).keys()) \ + list(plugin.get('tracers', {}).keys()) \ + list(plugin.get('device-providers', {}).keys()) self.__other_types_pages = {} if self.plugin and len(feature_names) == 1: self.unique_feature = feature_names[0] for ename, tracer in plugin.get('tracers', {}).items(): tracer['name'] = ename self.__extract_feature_comment("tracer", tracer) other_types = [] for provider_name, provider in plugin.get('device-providers', {}).items(): provider['name'] = provider_name _, comment = self.__extract_feature_comment("provider", provider) comment.description += """\n\n# Provided device example""" other_types.append( self.__create_classed_type(provider_name, provider.get('device-example'))) for ename, element in plugin.get('elements', {}).items(): element['name'] = ename pagename, _ = self.__extract_feature_comment("element", element) interfaces = [] for interface in element.get("interfaces", []): self._remember_symbol_type(interface, pagename) interfaces.append( QualifiedSymbol(type_tokens=[ Link(None, interface, interface, mandatory=True) ])) aliases = [pagename, element['hierarchy'][0]] sym = self.create_symbol(GstElementSymbol, parent_name=None, display_name=element['name'], hierarchy=self.__create_hierarchy( pagename, element), unique_name=element['name'], filename=plugin_name, extra={'gst-element-name': pagename}, rank=str(element['rank']), author=element['author'], classification=element['klass'], plugin=plugin_name, aliases=aliases, package=plugin['package'], interfaces=interfaces) if not sym: continue self.__elements[element['name']] = sym sym.properties.extend( self.__create_property_symbols(element, element['name'], pagename)) sym.signals.extend( self.__create_signal_symbols(element, element['name'], pagename)) sym.pad_templates.extend( self.__create_pad_template_symbols(element, plugin_name)) elements.append(sym) types = list(plugin['other-types'].items()) while True: type_ = None for tmptype in types: if tmptype[0] in self.__other_types_pages: type_ = tmptype break if not type_: break types.remove(type_) other_types.append( self.__create_symbol(type_[0], type_[1], self.__other_types_pages[type_[0]])) for _type in types: self.warn( "no-location-indication", "Type %s has been marked with `gst_type_mark_as_plugin_api`" " but is not used in any of %s API (it might require to" " be manually removed from the cache in case of plugin" " move)" % (_type[0], plugin_name)) plugin = self.create_symbol( GstPluginSymbol, description=plugin['description'], display_name=plugin_name, unique_name='plugin-' + plugin_name, license=plugin['license'], package=plugin['package'], filename=plugin['filename'], elements=elements, other_types=other_types, extra={'gst-plugins': 'plugins-' + plugin['filename']}) if not plugin: return None self.__all_plugins_symbols.add(plugin) if self.plugin: self.__plugins = plugin return plugin
def search_online_links(resolver, name): href = GTKDOC_HREFS.get(name) if href: return Link(href, name, name) return None
def type_tokens_from_type_name(type_name): res = [Link(None, type_name, type_name)] if type_name not in FUNDAMENTALS['python']: res.append('<span class="pointer-token">*</span>') return res
def _create_fundamentals(self): string_link = \ Link('https://docs.python.org/3/library/functions.html#func-str', 'str', None) boolean_link = \ Link('https://docs.python.org/3/library/functions.html#bool', 'bool', None) true_link = \ Link('https://docs.python.org/3/library/constants.html#True', 'True', None) false_link = \ Link('https://docs.python.org/3/library/constants.html#False', 'False', None) pointer_link = \ Link('https://docs.python.org/3/library/functions.html#object', 'object', None) integer_link = \ Link('https://docs.python.org/3/library/functions.html#int', 'int', None) float_link = \ Link('https://docs.python.org/3/library/functions.html#float', 'float', None) none_link = \ Link('https://docs.python.org/3/library/constants.html#None', 'None', None) list_link = \ Link('https://docs.python.org/3/library/functions.html#func-list', 'list', None) gtype_link = \ Link('https://developer.gnome.org/gobject/stable/' 'gobject-Type-Information.html#GType', 'GObject.Type', None) gvariant_link = \ Link('https://developer.gnome.org/glib/stable/glib-GVariant.html', 'GLib.Variant', None) self.fundamentals = { "none": none_link, "gpointer": pointer_link, "gconstpointer": pointer_link, "gboolean": boolean_link, "gint8": integer_link, "guint8": integer_link, "gint16": integer_link, "guint16": integer_link, "gint32": integer_link, "guint32": integer_link, "gchar": integer_link, "guchar": integer_link, "gshort": integer_link, "gushort": integer_link, "gint": integer_link, "guint": integer_link, "gfloat": float_link, "gdouble": float_link, "GLib.List": list_link, "utf8": string_link, "gunichar": string_link, "filename": string_link, "gchararray": string_link, "GType": gtype_link, "GVariant": gvariant_link, "gsize": integer_link, "gssize": integer_link, "goffset": integer_link, "gintptr": integer_link, "guintptr": integer_link, "glong": integer_link, "gulong": integer_link, "gint64": integer_link, "guint64": integer_link, "long double": float_link, "long long": integer_link, "unsigned long long": integer_link, "TRUE": true_link, "FALSE": false_link, "NULL": none_link, }