diff options
author | Johan Dahlin <johan@gnome.org> | 2010-09-20 17:17:20 -0300 |
---|---|---|
committer | Johan Dahlin <johan@gnome.org> | 2010-09-20 17:19:21 -0300 |
commit | 635b6ec35fbb1c2355e9b8b336f1a9164cc44034 (patch) | |
tree | 3b2b1ddfdc620082e5b3125fde1101e243dd4b08 | |
parent | 84aa7defdb1a3082021bd28a61803a1e140cf8ca (diff) | |
download | gobject-introspection-635b6ec35fbb1c2355e9b8b336f1a9164cc44034.tar.gz |
[scanner] Add a Position class
Add a position class which will make it easier to
send filename/line/column information to the message
class.
-rw-r--r-- | giscanner/annotationparser.py | 14 | ||||
-rw-r--r-- | giscanner/ast.py | 7 | ||||
-rw-r--r-- | giscanner/maintransformer.py | 4 | ||||
-rw-r--r-- | giscanner/message.py | 103 | ||||
-rw-r--r-- | giscanner/sourcescanner.py | 7 |
5 files changed, 72 insertions, 63 deletions
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py index ba70c3ea..aad17e89 100644 --- a/giscanner/annotationparser.py +++ b/giscanner/annotationparser.py @@ -22,6 +22,7 @@ import re +from .message import Position from .odict import odict # All gtk-doc comments needs to start with this: @@ -75,8 +76,6 @@ class DocBlock(object): 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) @@ -93,8 +92,6 @@ class DocTag(object): self.options = {} self.comment = None self.value = '' - self.filename = None - self.lineno = -1 def __repr__(self): return '<DocTag %r %r>' % (self.name, self.options) @@ -179,8 +176,7 @@ class AnnotationParser(object): if cpos: block_name = block_name[:cpos] block = DocBlock(block_name) - block.lineno = lineno - block.filename = filename + block.position = Position(filename, lineno) if cpos: block.options = self.parse_options(block, block_header[cpos+2:]) comment_lines = [] @@ -227,8 +223,7 @@ class AnnotationParser(object): else: argname = TAG_RETURNS tag = DocTag(block, argname) - tag.filename = block.filename - tag.lineno = block.lineno + lineno + tag.position = block.position.offset(lineno) second_colon_index = line.rfind(':') found_options = False if second_colon_index > first_colonspace_index: @@ -268,8 +263,7 @@ class AnnotationParser(object): tag_name = tag_name.lower() tag = DocTag(block, tag_name) tag.value = line[first_colonspace_index+2:] - tag.filename = block.filename - tag.lineno = block.lineno + lineno + tag.filename = block.position.offset(lineno) block.tags[tag_name] = tag else: comment_lines.append(line) diff --git a/giscanner/ast.py b/giscanner/ast.py index 8ff61e1d..08129cb1 100644 --- a/giscanner/ast.py +++ b/giscanner/ast.py @@ -19,6 +19,7 @@ # Boston, MA 02111-1307, USA. # +from .message import Position from .odict import odict from .utils import to_underscores @@ -487,12 +488,12 @@ GIName. It's possible for nodes to contain or point to other nodes.""" def inherit_file_positions(self, node): self.file_positions.update(node.file_positions) - def add_file_position(self, filename, line, column): - self.file_positions.add((filename, line, column)) + def add_file_position(self, position): + self.file_positions.add(position) def add_symbol_reference(self, symbol): if symbol.source_filename: - self.add_file_position(symbol.source_filename, symbol.line, -1) + self.add_file_position(Position(symbol.source_filename, symbol.line)) def walk(self, callback, chain): res = callback(self, chain) diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py index 533db8f7..47014eff 100644 --- a/giscanner/maintransformer.py +++ b/giscanner/maintransformer.py @@ -544,7 +544,7 @@ usage is void (*_gtk_reserved1)(void);""" message.warn( "Invalid scope %r for parameter %r" % (scope, param.argname), - [(tag.filename, tag.lineno, -1)]) + tag.position) else: param.scope = scope param.transfer = ast.PARAM_TRANSFER_NONE @@ -616,7 +616,7 @@ usage is void (*_gtk_reserved1)(void);""" message.warn( '%s: unknown parameter %r in documentation comment%s' % ( block.name, doc_name, text), - [(block.filename, tag.lineno, -1)]) + tag.position) def _apply_annotations_callable(self, node, chain, block): self._apply_annotations_annotated(node, block) diff --git a/giscanner/message.py b/giscanner/message.py index 3db31e33..baac0365 100644 --- a/giscanner/message.py +++ b/giscanner/message.py @@ -23,13 +23,41 @@ import os import sys -from . import ast from . import utils (WARNING, ERROR, FATAL) = range(3) + +class Position(object): + """Represents a position in the source file which we + want to inform about. + """ + def __init__(self, filename=None, line=None, column=None): + self.filename = filename + self.line = line + self.column = column + + def __cmp__(self, other): + return cmp((self.filename, self.line, self.column), + (other.filename, other.line, other.column)) + + def format(self, cwd): + filename = self.filename + if filename.startswith(cwd): + filename = filename[len(cwd):] + if self.column is not None: + return '%s:%d:%d' % (filename, self.line, self.column) + elif self.line is not None: + return '%s:%d' % (filename, self.line, ) + else: + return '%s:' % (filename, ) + + def offset(self, offset): + return Position(self.filename, self.line+offset, self.column) + + class MessageLogger(object): _instance = None @@ -54,7 +82,7 @@ class MessageLogger(object): def did_warn(self): return self._warned - def log(self, log_type, text, file_positions=None, prefix=None): + def log(self, log_type, text, positions=None, prefix=None): """Log a warning, using optional file positioning information. If the warning is related to a ast.Node type, see log_node_warning().""" utils.break_on_debug_flag('warning') @@ -66,26 +94,17 @@ If the warning is related to a ast.Node type, see log_node_warning().""" self._warned = True - if file_positions is None or len(file_positions) == 0: - target_file_positions = [('<unknown>', -1, -1)] - else: - target_file_positions = file_positions - - position_strings = [] - for (filename, line, column) in target_file_positions: - if filename.startswith(self._cwd): - filename = filename[len(self._cwd):] - if column != -1: - position = '%s:%d:%d' % (filename, line, column) - elif line != -1: - position = '%s:%d' % (filename, line, ) - else: - position = '%s:' % (filename, ) - position_strings.append(position) - - for position in position_strings[:-1]: - self._output.write("%s:\n" % (position, )) - last_position = position_strings[-1] + if type(positions) == set: + positions = list(positions) + if isinstance(positions, Position): + positions = [positions] + + if not positions: + positions = [Position('<unknown>')] + + for position in positions[:-1]: + self._output.write("%s:\n" % (position.format(cwd=self._cwd), )) + last_position = positions[-1].format(cwd=self._cwd) if log_type == WARNING: error_type = "Warning" @@ -111,45 +130,35 @@ the given node. The optional context argument, if given, should be another ast.Node type which will also be displayed. If no file position information is available from the node, the position data from the context will be used.""" - if hasattr(node, 'file_positions'): - if (len(node.file_positions) == 0 and - (context is not None) and len(context.file_positions) > 0): - file_positions = context.file_positions - else: - file_positions = node.file_positions + if getattr(node, 'file_positions', None): + positions = node.file_positions + elif context and context.file_positions: + positions = context.file_positions else: - file_positions = [] + positions = [] if not context: text = "context=%r %s" % (node, text) if context: - if isinstance(context, ast.Function): - name = context.symbol - else: - name = context.name - text = "%s: %s" % (name, text) - elif len(file_positions) == 0 and hasattr(node, 'name'): + text = "%s: %s" % (getattr(context, 'symbol', context.name), text) + elif not positions and hasattr(node, 'name'): text = "(%s)%s: %s" % (node.__class__.__name__, node.name, text) - self.log(log_type, text, file_positions) + self.log(log_type, text, positions) - def log_symbol(self, log_type, symbol, text, **kwargs): + def log_symbol(self, log_type, symbol, text): """Log a warning in the context of the given symbol.""" - if symbol.source_filename: - file_positions = [(symbol.source_filename, symbol.line, -1)] - else: - file_positions = None - prefix = "symbol=%r" % (symbol.ident, ) - self.log(log_type, text, file_positions, prefix=prefix, **kwargs) + self.log(log_type, text, symbol.position, + prefix="symbol=%r" % (symbol.ident, )) def log_node(log_type, node, text, context=None): ml = MessageLogger.get() ml.log_node(log_type, node, text, context=context) -def warn(text, file_positions=None, prefix=None): +def warn(text, positions=None, prefix=None): ml = MessageLogger.get() - ml.log(WARNING, text, file_positions, prefix) + ml.log(WARNING, text, positions, prefix) def warn_node(node, text, context=None): log_node(WARNING, node, text, context=context) @@ -158,6 +167,6 @@ def warn_symbol(symbol, text): ml = MessageLogger.get() ml.log_symbol(WARNING, symbol, text) -def fatal(text, file_positions=None, prefix=None): +def fatal(text, positions=None, prefix=None): ml = MessageLogger.get() - ml.log(FATAL, text, file_positions, prefix) + ml.log(FATAL, text, positions, prefix) diff --git a/giscanner/sourcescanner.py b/giscanner/sourcescanner.py index a2db2e74..e4c670b0 100644 --- a/giscanner/sourcescanner.py +++ b/giscanner/sourcescanner.py @@ -24,7 +24,7 @@ import subprocess import tempfile from .libtoolimporter import LibtoolImporter - +from .message import Position (CSYMBOL_TYPE_INVALID, CSYMBOL_TYPE_ELLIPSIS, @@ -198,6 +198,11 @@ class SourceSymbol(object): def line(self): return self._symbol.line + @property + def position(self): + return Position(self._symbol.source_filename, + self._symbol.line) + class SourceScanner(object): |