diff options
author | Johan Dahlin <johan@gnome.org> | 2010-09-19 12:05:08 -0300 |
---|---|---|
committer | Johan Dahlin <johan@gnome.org> | 2010-09-19 12:14:13 -0300 |
commit | 13713e7c99b825974668bd3b5f96b03a25e1986b (patch) | |
tree | d628784b67cc3161f3d0beed1a84c6391f694945 /giscanner | |
parent | cb61330eb495786bf8232ebcb51b0d6d9a753ce7 (diff) |
[annotationparser] Preserve line numbers
Make sure that the linenumbers of the documentation blocks
and tags are preserved and accurate so they can be used in
warning messages. Also:
* Rename Options to DocOptions for consistency
* Add a reference to the docblock a tag and an option belong to
Diffstat (limited to 'giscanner')
-rw-r--r-- | giscanner/annotationparser.py | 52 | ||||
-rw-r--r-- | giscanner/maintransformer.py | 2 |
2 files changed, 36 insertions, 18 deletions
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py index ea17578..ba70c3e 100644 --- a/giscanner/annotationparser.py +++ b/giscanner/annotationparser.py @@ -68,13 +68,15 @@ OPT_SCOPE_NOTIFIED = 'notified' class DocBlock(object): - def __init__(self, name, options): + def __init__(self, name): self.name = name - self.options = options + self.options = {} self.value = None self.tags = odict() self.comment = None self.params = [] + self.filename = None + self.lineno = -1 def __repr__(self): return '<DocBlock %r %r>' % (self.name, self.options) @@ -85,18 +87,22 @@ class DocBlock(object): class DocTag(object): - def __init__(self, name): + def __init__(self, block, name): + self.block = block self.name = name self.options = {} self.comment = None self.value = '' + self.filename = None + self.lineno = -1 def __repr__(self): return '<DocTag %r %r>' % (self.name, self.options) -class Option(object): +class DocOption(object): - def __init__(self, option): + def __init__(self, tag, option): + self.tag = tag self._array = [] self._dict = {} for p in option.split(' '): @@ -112,7 +118,7 @@ class Option(object): self._array.append((name, value)) def __repr__(self): - return '<Option %r>' % (self._array, ) + return '<DocOption %r>' % (self._array, ) def one(self): assert len(self._array) == 1 @@ -153,7 +159,7 @@ class AnnotationParser(object): # - signal: GtkWidget::destroy # - property: GtkWidget:visible # - comment, lineno = cmt + comment, filename, lineno = cmt comment = comment.lstrip() if not comment.startswith(_COMMENT_HEADER): return @@ -169,12 +175,14 @@ class AnnotationParser(object): block_header = comment[:pos] block_header = block_header.strip() cpos = block_header.find(': ') + block_name = block_header if cpos: - block_name = block_header[:cpos] - block_options = self.parse_options(block_header[cpos+2:]) - else: - block_name, block_options = block_header, {} - block = DocBlock(block_name, block_options) + block_name = block_name[:cpos] + block = DocBlock(block_name) + block.lineno = lineno + block.filename = filename + if cpos: + block.options = self.parse_options(block, block_header[cpos+2:]) comment_lines = [] parsing_parameters = True last_param_tag = None @@ -191,6 +199,10 @@ class AnnotationParser(object): # * Some documentation for the function. # * # * Returns: (transfer none): A value + + # offset of the first doctag in relation to the start of + # the docblock, we parsed /** and the xxx: lines already + lineno = 2 for line in comment[pos+1:].split('\n'): line = line.lstrip() if (not line.startswith('*') or @@ -198,6 +210,7 @@ class AnnotationParser(object): # As soon as we find a line that's just whitespace, # we're done parsing the parameters. parsing_parameters = False + lineno += 1 continue line = line[1:].lstrip() @@ -213,7 +226,9 @@ class AnnotationParser(object): argname = line[1:first_colonspace_index] else: argname = TAG_RETURNS - tag = DocTag(argname) + tag = DocTag(block, argname) + tag.filename = block.filename + tag.lineno = block.lineno + lineno second_colon_index = line.rfind(':') found_options = False if second_colon_index > first_colonspace_index: @@ -230,7 +245,7 @@ class AnnotationParser(object): # But that'd be a rather incompatible change. found_options = True tag.comment = line[second_colon_index+1:].strip() - tag.options = self.parse_options(value_line) + tag.options = self.parse_options(tag, value_line) if not found_options: # We didn't find any options, so just take the whole thing # as documentation. @@ -251,18 +266,21 @@ class AnnotationParser(object): tag_name = line[:first_colonspace_index] if self.ASCII_TEXT_RE.match(tag_name): tag_name = tag_name.lower() - tag = DocTag(tag_name) + tag = DocTag(block, tag_name) tag.value = line[first_colonspace_index+2:] + tag.filename = block.filename + tag.lineno = block.lineno + lineno block.tags[tag_name] = tag else: comment_lines.append(line) elif (not is_parameter): comment_lines.append(line) + lineno += 1 block.comment = '\n'.join(comment_lines) self._blocks[block.name] = block @classmethod - def parse_options(cls, value): + def parse_options(cls, tag, value): # (foo) # (bar opt1 opt2...) opened = -1 @@ -282,7 +300,7 @@ class AnnotationParser(object): else: raise AssertionError if option is not None: - option = Option(option) + option = DocOption(tag, option) options[name] = option last = i + 2 opened = -1 diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py index a2ac8ac..242cb46 100644 --- a/giscanner/maintransformer.py +++ b/giscanner/maintransformer.py @@ -514,7 +514,7 @@ usage is void (*_gtk_reserved1)(void);""" annos_tag = block.get(TAG_ATTRIBUTES) if annos_tag is not None: - options = AnnotationParser.parse_options(annos_tag.value) + options = AnnotationParser.parse_options(annos_tag, annos_tag.value) for key, value in options.iteritems(): if value: node.attributes.append((key, value.one())) |