From 4eda1cb480808442a2840219c99cc93ee949a7a5 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 13 Jan 2009 21:13:00 +0000 Subject: =?UTF-8?q?Bug=20555036=20=E2=80=93=20put=20gtk-doc=20in=20GIR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2009-01-13 Johan Dahlin Bug 555036 – put gtk-doc in GIR * giscanner/annotationparser.py: * giscanner/ast.py: * giscanner/girwriter.py: * giscanner/glibast.py: * tests/scanner/annotation-1.0-expected.gir: * tests/scanner/annotation.h: * tests/scanner/foo-1.0-expected.gir: svn path=/trunk/; revision=1032 --- giscanner/annotationparser.py | 74 ++++++++++++++++++++++++++++++++++--------- giscanner/ast.py | 11 +++++++ giscanner/girwriter.py | 24 ++++++++++++++ giscanner/glibast.py | 3 +- 4 files changed, 96 insertions(+), 16 deletions(-) (limited to 'giscanner') diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py index 0e65ada8..3a628f87 100644 --- a/giscanner/annotationparser.py +++ b/giscanner/annotationparser.py @@ -20,8 +20,9 @@ # AnnotationParser - parses gtk-doc annotations -from .ast import (Array, Callback, Class, Enum, Field, Function, Interface, - List, Map, Parameter, Record, Return, Type, Union, Varargs, +from .ast import (Array, Bitfield, Callback, Class, Enum, Field, Function, + Interface, List, Map, Parameter, Record, Return, Type, Union, + Varargs, default_array_types, BASIC_GIR_TYPES, PARAM_DIRECTION_INOUT, @@ -71,6 +72,7 @@ class DocBlock(object): self.name = name self.value = None self.tags = odict() + self.comment = None def __repr__(self): return '' % (self.name, ) @@ -91,6 +93,7 @@ class DocTag(object): def __init__(self, name): self.name = name self.options = [] + self.comment = None class Option(object): @@ -164,34 +167,36 @@ class AnnotationParser(object): if not block_name.endswith(':'): return block = DocBlock(block_name[:-1]) - content = comment[pos+1:] - for line in content.split('\n'): + comment_lines = [] + for line in comment[pos+1:].split('\n'): line = line.lstrip() line = line[2:].strip() # Skip ' *' if not line: continue - if line.startswith('@'): line = line[1:] elif not ': ' in line: + comment_lines.append(line) continue tag = self._parse_tag(line) block.tags[tag.name] = tag - + block.comment = '\n'.join(comment_lines) self._blocks[block.name] = block - def _parse_tag(self, value): + def _parse_tag(self, raw): # Tag: bar # Tag: bar opt1 opt2 - parts = value.split(': ', 1) + parts = raw.split(': ', 1) if len(parts) == 1: tag_name = parts[0] - options = '' + value = '' else: - tag_name, options = parts + tag_name, value = parts + options, rest = self._parse_options(value) tag = DocTag(tag_name) - tag.value = options - tag.options = self._parse_options(options) + tag.value = value + tag.options = options + tag.comment = rest return tag def _parse_options(self, value): @@ -199,6 +204,7 @@ class AnnotationParser(object): # (bar opt1 opt2...) opened = -1 options = {} + last = None for i, c in enumerate(value): if c == '(' and opened == -1: opened = i+1 @@ -215,8 +221,14 @@ class AnnotationParser(object): if option is not None: option = Option(option) options[name] = option + last = i + 2 opened = -1 - return options + + if last is not None: + rest = value[last:].strip() + else: + rest = None + return options, rest class AnnotationApplier(object): @@ -242,6 +254,8 @@ class AnnotationApplier(object): self._parse_function(node) elif isinstance(node, Enum): self._parse_enum(node) + elif isinstance(node, Bitfield): + self._parse_bitfield(node) elif isinstance(node, Class): self._parse_class(node) elif isinstance(node, Interface): @@ -256,7 +270,7 @@ class AnnotationApplier(object): self._parse_boxed(node) def _parse_class(self, class_): - block = self._blocks.get(class_.name) + block = self._blocks.get(class_.type_name) self._parse_version(class_, block) self._parse_constructors(class_.constructors) self._parse_methods(class_.methods) @@ -264,14 +278,18 @@ class AnnotationApplier(object): self._parse_properties(class_, class_.properties) self._parse_signals(class_, class_.signals) self._parse_fields(class_, class_.fields) + if block: + class_.doc = block.comment def _parse_interface(self, interface): - block = self._blocks.get(interface.name) + block = self._blocks.get(interface.type_name) self._parse_version(interface, block) self._parse_methods(interface.methods) self._parse_properties(interface, interface.properties) self._parse_signals(interface, interface.signals) self._parse_fields(interface, interface.fields) + if block: + interface.doc = block.comment def _parse_record(self, record): block = self._blocks.get(record.symbol) @@ -280,12 +298,16 @@ class AnnotationApplier(object): self._parse_fields(record, record.fields) if isinstance(record, GLibBoxed): self._parse_methods(record.methods) + if block: + record.doc = block.comment def _parse_boxed(self, boxed): block = self._blocks.get(boxed.name) self._parse_version(boxed, block) self._parse_constructors(boxed.constructors) self._parse_methods(boxed.methods) + if block: + boxed.doc = block.comment def _parse_union(self, union): block = self._blocks.get(union.name) @@ -293,10 +315,20 @@ class AnnotationApplier(object): self._parse_constructors(union.constructors) if isinstance(union, GLibBoxed): self._parse_methods(union.methods) + if block: + union.doc = block.comment def _parse_enum(self, enum): block = self._blocks.get(enum.symbol) self._parse_version(enum, block) + if block: + enum.doc = block.comment + + def _parse_bitfield(self, bitfield): + block = self._blocks.get(bitfield.symbol) + self._parse_version(bitfield, block) + if block: + bitfield.doc = block.comment def _parse_constructors(self, constructors): for ctor in constructors: @@ -322,12 +354,16 @@ class AnnotationApplier(object): block = self._blocks.get('%s:%s' % (parent.type_name, prop.name)) self._parse_version(prop, block) self._parse_deprecated(prop, block) + if block: + prop.doc = block.comment def _parse_callback(self, callback): block = self._blocks.get(callback.ctype) self._parse_version(callback, block) self._parse_params(callback, callback.parameters, block) self._parse_return(callback, callback.retval, block) + if block: + callback.doc = block.comment def _parse_function(self, func): block = self._blocks.get(func.symbol) @@ -335,6 +371,8 @@ class AnnotationApplier(object): self._parse_deprecated(func, block) self._parse_params(func, func.parameters, block) self._parse_return(func, func.retval, block) + if block: + func.doc = block.comment def _parse_signal(self, parent, signal): block = self._blocks.get('%s::%s' % (parent.type_name, signal.name)) @@ -359,6 +397,8 @@ class AnnotationApplier(object): tag = None self._parse_param(signal, param, tag) self._parse_return(signal, signal.retval, block) + if block: + signal.doc = block.comment def _parse_field(self, parent, field): if isinstance(field, Callback): @@ -373,6 +413,8 @@ class AnnotationApplier(object): tag = self._get_tag(block, TAG_RETURNS) options = getattr(tag, 'options', {}) self._parse_param_ret_common(parent, return_, options) + if tag is not None and tag.comment is not None: + return_.doc = tag.comment def _parse_param(self, parent, param, tag): options = getattr(tag, 'options', {}) @@ -383,6 +425,8 @@ class AnnotationApplier(object): param.scope = scope.one() param.transfer = PARAM_TRANSFER_NONE self._parse_param_ret_common(parent, param, options) + if tag is not None and tag.comment is not None: + param.doc = tag.comment def _parse_param_ret_common(self, parent, node, options): node.direction = self._extract_direction(node, options) diff --git a/giscanner/ast.py b/giscanner/ast.py index b141691d..b3c1fff5 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -201,6 +201,7 @@ class Function(Node): self.symbol = symbol self.throws = not not throws self.is_method = False + self.doc = None def get_parameter_index(self, name): for i, parameter in enumerate(self.parameters): @@ -312,6 +313,7 @@ class Parameter(TypeContainer): 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) @@ -323,6 +325,7 @@ 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) @@ -334,6 +337,7 @@ 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) @@ -358,6 +362,7 @@ class Record(Node): self.constructors = [] self.symbol = symbol self.disguised = disguised + self.doc = None # BW compat, remove Struct = Record @@ -385,6 +390,7 @@ 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, ) @@ -403,6 +409,7 @@ class Class(Node): self.constructors = [] self.properties = [] self.fields = [] + self.doc = None def __repr__(self): return '%s(%r, %r, %r)' % ( @@ -419,6 +426,7 @@ class Interface(Node): self.properties = [] self.fields = [] self.prerequisites = [] + self.doc = None def __repr__(self): return '%s(%r, %r)' % ( @@ -448,6 +456,7 @@ class Property(Node): self.writable = writable self.construct = construct self.construct_only = construct_only + self.doc = None def __repr__(self): return '%s(%r, %r)' % ( @@ -466,6 +475,7 @@ class Callback(Node): self.parameters = parameters self.ctype = ctype self.throws = False + self.doc = None def __repr__(self): return 'Callback(%r, %r, %r)' % ( @@ -479,6 +489,7 @@ class Union(Node): self.fields = [] self.constructors = [] self.symbol = symbol + self.doc = None def __repr__(self): return 'Union(%r, %r)' % (self.name, self.fields, ) diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index e72b0289..a5d1637a 100644 --- a/giscanner/girwriter.py +++ b/giscanner/girwriter.py @@ -119,6 +119,8 @@ class GIRWriter(XMLWriter): def _write_function(self, func, tag_name='function'): attrs = [('name', func.name), ('c:identifier', func.symbol)] + if func.doc: + attrs.append(('doc', func.doc)) self._append_version(func, attrs) self._append_deprecated(func, attrs) self._append_throws(func, attrs) @@ -143,6 +145,8 @@ class GIRWriter(XMLWriter): attrs = [] attrs.append(('transfer-ownership', return_.transfer)) + if return_.doc: + attrs.append(('doc', return_.doc)) with self.tagcontext('return-value', attrs): self._write_type(return_.type) @@ -171,6 +175,8 @@ class GIRWriter(XMLWriter): attrs.append(('closure', '%d' % parameter.closure_index)) if parameter.destroy_index >= 0: attrs.append(('destroy', '%d' % parameter.destroy_index)) + if parameter.doc: + attrs.append(('doc', parameter.doc)) with self.tagcontext('parameter', attrs): self._write_type(parameter.type) @@ -222,6 +228,8 @@ class GIRWriter(XMLWriter): def _write_enum(self, enum): attrs = [('name', enum.name)] + if enum.doc: + attrs.append(('doc', enum.doc)) self._append_version(enum, attrs) self._append_deprecated(enum, attrs) if isinstance(enum, GLibEnum): @@ -236,6 +244,8 @@ class GIRWriter(XMLWriter): def _write_bitfield(self, bitfield): attrs = [('name', bitfield.name)] + if bitfield.doc: + attrs.append(('doc', bitfield.doc)) self._append_version(bitfield, attrs) self._append_deprecated(bitfield, attrs) if isinstance(bitfield, GLibFlags): @@ -265,6 +275,8 @@ class GIRWriter(XMLWriter): def _write_class(self, node): attrs = [('name', node.name), ('c:type', node.ctype)] + if node.doc: + attrs.append(('doc', node.doc)) self._append_version(node, attrs) self._append_deprecated(node, attrs) if isinstance(node, Class): @@ -303,6 +315,8 @@ class GIRWriter(XMLWriter): def _write_boxed(self, boxed): attrs = [('c:type', boxed.ctype), ('glib:name', boxed.name)] + if boxed.doc: + attrs.append(('doc', boxed.doc)) attrs.extend(self._boxed_attrs(boxed)) with self.tagcontext('glib:boxed', attrs): self._write_boxed_ctors_methods(boxed) @@ -320,12 +334,16 @@ class GIRWriter(XMLWriter): attrs.append(('construct', '1')) if prop.construct_only: attrs.append(('construct-only', '1')) + if prop.doc: + attrs.append(('doc', prop.doc)) with self.tagcontext('property', attrs): self._write_type(prop.type) def _write_callback(self, callback): # FIXME: reuse _write_function attrs = [('name', callback.name), ('c:type', callback.ctype)] + if callback.doc: + attrs.append(('doc', callback.doc)) self._append_version(callback, attrs) self._append_deprecated(callback, attrs) self._append_throws(callback, attrs) @@ -348,6 +366,8 @@ class GIRWriter(XMLWriter): ('c:type', record.symbol)] if record.disguised: attrs.append(('disguised', '1')) + if record.doc: + attrs.append(('doc', record.doc)) self._append_version(record, attrs) self._append_deprecated(record, attrs) if isinstance(record, GLibBoxed): @@ -362,6 +382,8 @@ class GIRWriter(XMLWriter): def _write_union(self, union): attrs = [('name', union.name), ('c:type', union.symbol)] + if union.doc: + attrs.append(('doc', union.doc)) self._append_version(union, attrs) self._append_deprecated(union, attrs) if isinstance(union, GLibBoxed): @@ -396,6 +418,8 @@ class GIRWriter(XMLWriter): def _write_signal(self, signal): attrs = [('name', signal.name)] + if signal.doc: + attrs.append(('doc', signal.doc)) self._append_version(signal, attrs) self._append_deprecated(signal, attrs) with self.tagcontext('glib:signal', attrs): diff --git a/giscanner/glibast.py b/giscanner/glibast.py index a804f620..60f214b7 100644 --- a/giscanner/glibast.py +++ b/giscanner/glibast.py @@ -136,7 +136,7 @@ class GLibBoxedOther(Node, GLibBoxed): Node.__init__(self, name) GLibBoxed.__init__(self, type_name, get_type) self.ctype = type_name - + self.doc = None class GLibInterface(Interface): @@ -159,3 +159,4 @@ class GLibSignal(Node): Node.__init__(self, name) self.retval = retval self.parameters = [] + self.doc = None -- cgit v1.2.1