summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Dahlin <johan@gnome.org>2010-09-20 17:17:20 -0300
committerJohan Dahlin <johan@gnome.org>2010-09-20 17:19:21 -0300
commit635b6ec35fbb1c2355e9b8b336f1a9164cc44034 (patch)
tree3b2b1ddfdc620082e5b3125fde1101e243dd4b08
parent84aa7defdb1a3082021bd28a61803a1e140cf8ca (diff)
downloadgobject-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.py14
-rw-r--r--giscanner/ast.py7
-rw-r--r--giscanner/maintransformer.py4
-rw-r--r--giscanner/message.py103
-rw-r--r--giscanner/sourcescanner.py7
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):