[gobject-introspection/file-positions-wip] [scanner] Add a Position class
- From: Johan Dahlin <johan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection/file-positions-wip] [scanner] Add a Position class
- Date: Mon, 20 Sep 2010 20:18:28 +0000 (UTC)
commit 0ef7b5047fb8004ddd3ba4f977f386536d445ce6
Author: Johan Dahlin <johan gnome org>
Date: Mon Sep 20 17:17:20 2010 -0300
[scanner] Add a Position class
Add a position class which will make it easier to
send filename/line/column information to the message
class.
giscanner/annotationparser.py | 14 ++----
giscanner/ast.py | 7 ++-
giscanner/maintransformer.py | 4 +-
giscanner/message.py | 103 ++++++++++++++++++++++-------------------
giscanner/sourcescanner.py | 7 ++-
5 files changed, 72 insertions(+), 63 deletions(-)
---
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index ba70c3e..aad17e8 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 8ff61e1..08129cb 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 533db8f..47014ef 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 3db31e3..baac036 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 a2db2e7..e4c670b 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):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]