[gobject-introspection] annotationparser: cleanup and add tests for the new warnings we now emit



commit c87ef59b4b4e57f7704144c2098b5ab0bf37976e
Author: Dieter Verfaillie <dieterv optionexplicit be>
Date:   Tue Apr 17 22:23:14 2012 +0200

    annotationparser: cleanup and add tests for the new warnings we now emit
    
    Including:
    - handle things in the logical order encountered (first colon,
      then annotations)
    - correctly report column when missing a colon on the identifier part
    - small type fixes
    - remove no longer useful "parameter/tag expected" warnings

 giscanner/annotationparser.py   |   51 +++++------
 giscanner/annotationpatterns.py |    2 +-
 tests/warn/Makefile.am          |    2 +-
 tests/warn/annotationparser.h   |  191 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 214 insertions(+), 32 deletions(-)
---
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 82fc9ee..2ac1b0e 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -27,7 +27,7 @@ import re
 
 from . import message
 from .annotationpatterns import (COMMENT_START_RE, COMMENT_END_RE,
-                                 COMMENT_STAR_RE, EMPTY_LINE_RE,
+                                 COMMENT_ASTERISK_RE, EMPTY_LINE_RE,
                                  SECTION_RE, SYMBOL_RE, PROPERTY_RE, SIGNAL_RE,
                                  PARAMETER_RE, DESCRIPTION_TAG_RE, TAG_RE,
                                  MULTILINE_ANNOTATION_CONTINUATION_RE)
@@ -616,7 +616,7 @@ class AnnotationParser(object):
             column_offset = 0
 
             # Get rid of ' * ' at start of the line.
-            result = COMMENT_STAR_RE.match(line)
+            result = COMMENT_ASTERISK_RE.match(line)
             if result:
                 column_offset = result.end(0)
                 line = line[result.end(0):]
@@ -672,17 +672,18 @@ class AnnotationParser(object):
                     comment_block = DocBlock(identifier_name)
                     comment_block.set_position(position)
 
-                    if 'annotations' in result.groupdict():
-                        comment_block.options = self.parse_options(comment_block,
-                                                                   result.group('annotations'))
-
                     if 'colon' in result.groupdict() and result.group('colon') != ':':
                         colon_start = result.start('colon')
                         colon_column = column_offset + colon_start
                         marker = ' '*colon_column + '^'
                         message.warn("missing ':' at column %s:\n%s\n%s" %
-                                     (colon_start, original_line, marker),
+                                     (colon_column + 1, original_line, marker),
                                      position)
+
+                    if 'annotations' in result.groupdict():
+                        comment_block.options = self.parse_options(comment_block,
+                                                                   result.group('annotations'))
+
                     continue
                 else:
                     # If we get here, the identifier was not recognized, so
@@ -812,7 +813,7 @@ class AnnotationParser(object):
                         if tag_name.lower() == TAG_ATTRIBUTES:
                             tag.options = self.parse_options(tag, tag_annotations)
                         else:
-                            message.warn("annotations not supported for tag '%s'." %
+                            message.warn("annotations not supported for tag '%s:'." %
                                          (tag_name),
                                          position)
                     comment_block.tags[tag_name.lower()] = tag
@@ -823,7 +824,7 @@ class AnnotationParser(object):
             # If we get here, we must be in the middle of a multiline
             # comment block, parameter or tag description.
             ####################################################################
-            if in_part == PART_DESCRIPTION:
+            if in_part == PART_DESCRIPTION or in_part == PART_IDENTIFIER:
                 if not comment_block.comment:
                     # Backwards compatibility with old style GTK-Doc
                     # comment blocks where Description used to be a comment
@@ -834,30 +835,20 @@ class AnnotationParser(object):
                     comment_block.comment += '\n' + line
                 continue
             elif in_part == PART_PARAMETERS:
-                if not current_param:
-                    message.warn('parameter expected:\n%s' %
-                                 (line),
-                                 position)
-                else:
-                    self._validate_multiline_annotation_continuation(line, original_line,
-                                                                     column_offset, position)
+                self._validate_multiline_annotation_continuation(line, original_line,
+                                                                 column_offset, position)
 
-                    # Append to parameter description.
-                    current_param.comment += ' ' + line.strip()
+                # Append to parameter description.
+                current_param.comment += ' ' + line.strip()
             elif in_part == PART_TAGS:
-                if not current_tag:
-                    message.warn('tag expected:\n%s' %
-                                 (line),
-                                 position)
-                else:
-                    self._validate_multiline_annotation_continuation(line, original_line,
-                                                                     column_offset, position)
+                self._validate_multiline_annotation_continuation(line, original_line,
+                                                                 column_offset, position)
 
-                    # Append to tag description.
-                    if current_tag.name.lower() in [TAG_RETURNS, TAG_RETURNVALUE]:
-                        current_tag.comment += ' ' + line.strip()
-                    else:
-                        current_tag.value += ' ' + line.strip()
+                # Append to tag description.
+                if current_tag.name.lower() in [TAG_RETURNS, TAG_RETURNVALUE]:
+                    current_tag.comment += ' ' + line.strip()
+                else:
+                    current_tag.value += ' ' + line.strip()
 
         ########################################################################
         # Finished parsing this comment block.
diff --git a/giscanner/annotationpatterns.py b/giscanner/annotationpatterns.py
index 80b9da4..a403005 100644
--- a/giscanner/annotationpatterns.py
+++ b/giscanner/annotationpatterns.py
@@ -61,7 +61,7 @@ COMMENT_END_RE = re.compile(r'''
 # line inside a comment block.
 #
 # Results in 0 symbolic groups.
-COMMENT_STAR_RE = re.compile(r'''
+COMMENT_ASTERISK_RE = re.compile(r'''
     ^                                        # start
     [^\S\n\r]*                               # 0 or more whitespace characters
     \*                                       # 1 asterisk character
diff --git a/tests/warn/Makefile.am b/tests/warn/Makefile.am
index 5ca3d82..c435422 100644
--- a/tests/warn/Makefile.am
+++ b/tests/warn/Makefile.am
@@ -1,6 +1,7 @@
 include $(top_srcdir)/common.mk
 
 TESTS = \
+	annotationparser.h \
 	callback-invalid-scope.h \
 	callback-missing-scope.h \
 	return-gobject.h \
@@ -19,4 +20,3 @@ TESTS = \
 EXTRA_DIST = warningtester.py common.h $(TESTS)
 
 TESTS_ENVIRONMENT = PYTHONPATH=$(top_builddir):$(top_srcdir) TOP_BUILDDIR=$(top_builddir) UNINSTALLED_INTROSPECTION_SRCDIR=$(top_srcdir) $(PYTHON) $(srcdir)/warningtester.py
-
diff --git a/tests/warn/annotationparser.h b/tests/warn/annotationparser.h
new file mode 100644
index 0000000..1897b2f
--- /dev/null
+++ b/tests/warn/annotationparser.h
@@ -0,0 +1,191 @@
+#include "common.h"
+
+/**
+ * test_symbol_twice_documented:
+ *
+ * Documenting the same thing multiple times can lead to subtle bugs.
+ * For example, one comment block might have correct annotations...
+ **/
+void test_symbol_twice_documented();
+
+/**
+ * test_symbol_twice_documented:
+ *
+ * ...and a different comment block (out of sync with the above) might have
+ * no annotations at all. The last comment block seen by the parser "wins".
+ **/
+
+// EXPECT:12: Warning: Test: multiple comment blocks documenting 'test_symbol_twice_documented:' identifier.
+
+
+/**
+ * test_symbol_missing_colon
+ *
+ * Forgotten colon above will result in a warning.
+ **/
+
+// EXPECT:22: Warning: Test: missing ':' at column 29:
+//+ * test_symbol_missing_colon
+//+                            ^
+
+
+/**
+ * GtkWidget:test_property_missing_colon
+ *
+ * Forgotten colon above will result in a warning.
+ **/
+
+// EXPECT:33: Warning: Test: missing ':' at column 41:
+//+ * GtkWidget:test_property_missing_colon
+//+                                        ^
+
+
+/**
+ * GtkWidget::test_signal_missing_colon
+ *
+ * Forgotten colon above will result in a warning.
+ **/
+
+// EXPECT:44: Warning: Test: missing ':' at column 40:
+//+ * GtkWidget::test_signal_missing_colon
+//+                                       ^
+
+
+/**
+ * This is not a valid section identifier
+ * SECTION:test_invalid_section_idetifier
+ *
+ * Above identifier will result in a warning.
+ **/
+
+// EXPECT:55: Warning: Test: ignoring unrecognized GTK-Doc comment block, identifier not found:
+//+ * This is not a valid section identifier
+//+   ^
+
+
+/**
+ * test_unexpected_parameter:
+ * @param1: first parameter
+ *
+ * Parameters should come before the comment block description
+ *
+ * Returns: something
+ * @param2: second parameter
+ **/
+
+// EXPECT:73: Warning: Test: '@param2' parameter unexpected at this location:
+//+ * @param2: second parameter
+//+    ^
+
+
+/**
+ * test_multiple_returns_tag_and_parameter:
+ *
+ * Multiple return value warnings are checked for when a returns
+ * parameter is encountered.
+ *
+ * Return Value: something
+ * @returns: something
+ */
+
+// EXPECT:88: Warning: Test: '@returns' parameter unexpected at this location:
+//+ * @returns: something
+//+    ^
+// EXPECT:88: Warning: Test: encountered multiple 'Returns' parameters or tags for 'test_multiple_returns_tag_and_parameter'.
+
+
+/**
+ * test_multiple_parameters:
+ * @param1: first parameter
+ * @param1: first parameter
+ **/
+
+// EXPECT:100: Warning: Test: multiple '@param1' parameters for identifier 'test_multiple_parameters':
+//+ * @param1: first parameter
+//+    ^
+
+
+/**
+ * test_unexpected_tag:
+ * @param1: first parameter
+ * Returns: something
+ *
+ * Tags should go after the comment block description
+ **/
+
+// EXPECT:111: Warning: Test: 'Returns:' tag unexpected at this location:
+//+ * Returns: something
+//+   ^
+
+
+/**
+ * test_multiple_returns_tag:
+ * @returns: something
+ *
+ * Multiple return value warnings are checked for when returns tag is used
+ *
+ * Returns: anything
+ * Return value: whatever
+ **/
+
+// EXPECT:127: Warning: Test: encountered multiple 'Returns' parameters or tags for 'test_multiple_returns_tag'.
+// EXPECT:128: Warning: Test: encountered multiple 'Returns' parameters or tags for 'test_multiple_returns_tag'.
+
+
+/**
+ * test_multiple_tags:
+ *
+ * Since: 3.0
+ * Since: 3.0
+ **/
+
+// EXPECT:139: Warning: Test: multiple 'Since:' tags for identifier 'test_multiple_tags':
+//+ * Since: 3.0
+//+   ^
+
+
+/**
+ * test_tag_annotatable:
+ *
+ * There's currently 2 tags that can be annotated, so these don't emit warnings
+ *
+ * Returns: (allow-none): something
+ * Attributes: (free) (form) (annotations)
+ **/
+
+/**
+ * test_tag_not_annotatable:
+ *
+ * Tags (except Returns: and Attributes:) don't have annotations
+ *
+ * Since: (allow-none): 2.24
+ **/
+
+// EXPECT:161: Warning: Test: annotations not supported for tag 'Since:'.
+
+
+/**
+ * test_multiline_annotations_on_parameter:
+ * @param1: (allow-none)
+ * (transfer full): first parameter
+ *
+ * Annotations spanning multiple lines are not valid
+ **/
+
+// EXPECT:170: Warning: Test: ignoring invalid multiline annotation continuation:
+//+ * (transfer full): first parameter
+//+   ^
+
+
+/**
+ * test_multiline_annotations_on_tag:
+ *
+ * Annotations spanning multiple lines are not valid
+ *
+ * Returns: (allow-none)
+ * (transfer full): something
+ **/
+
+// EXPECT:186: Warning: Test: ignoring invalid multiline annotation continuation:
+//+ * (transfer full): something
+//+   ^



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]