[gobject-introspection] giscanner: add missing tests



commit 4b690b187bf8d0b7b571faaa050986b796e797a4
Author: Dieter Verfaillie <dieterv optionexplicit be>
Date:   Tue Aug 13 15:01:00 2013 +0200

    giscanner: add missing tests

 tests/scanner/Makefile.am                          |    3 +
 .../annotationparser/gi/annotation_allow_none.xml  |    7 +-
 .../annotationparser/gi/annotation_array.xml       |  133 +++++
 .../annotationparser/gi/annotation_attributes.xml  |   34 ++
 .../annotationparser/gi/annotation_closure.xml     |   48 ++
 .../annotationparser/gi/annotation_destroy.xml     |   48 ++
 .../gi/annotation_element_type.xml                 |  107 ++++
 .../scanner/annotationparser/gi/annotation_out.xml |   52 ++
 .../annotationparser/gi/annotation_skip.xml        |   31 ++
 tests/scanner/annotationparser/gi/annotations.xml  |  552 ++++++++++++++++++++
 .../annotationparser/gi/identifier_symbol.xml      |  111 ++++
 tests/scanner/annotationparser/gi/parameter.xml    |  182 +++++++
 tests/scanner/annotationparser/gi/syntax.xml       |  158 ++++++
 .../annotationparser/gi/syntax_indentation.xml     |   69 +++
 .../gi/syntax_multiline_annotations.xml            |   69 +++
 tests/scanner/annotationparser/gi/tag.xml          |  269 ++++++++++
 .../annotationparser/gi/tag_description.xml        |   76 +++
 tests/scanner/annotationparser/gi/tag_returns.xml  |  137 +++++
 tests/scanner/annotationparser/gi/tag_since.xml    |   52 ++
 .../scanner/annotationparser/gi/tag_stability.xml  |   27 +
 tests/scanner/annotationparser/test_patterns.py    |  142 +++++-
 21 files changed, 2298 insertions(+), 9 deletions(-)
---
diff --git a/tests/scanner/Makefile.am b/tests/scanner/Makefile.am
index 3eef89b..cf52eac 100644
--- a/tests/scanner/Makefile.am
+++ b/tests/scanner/Makefile.am
@@ -223,12 +223,15 @@ EXTRA_DIST += \
        annotationparser/gi/annotation_unref_func.xml           \
        annotationparser/gi/annotation_value.xml                \
        annotationparser/gi/annotation_virtual.xml              \
+       annotationparser/gi/annotations.xml                     \
        annotationparser/gi/identifier.xml                      \
        annotationparser/gi/identifier_section.xml              \
        annotationparser/gi/identifier_symbol.xml               \
        annotationparser/gi/parameter.xml                       \
        annotationparser/gi/parameter_varargs.xml               \
        annotationparser/gi/syntax.xml                          \
+       annotationparser/gi/syntax_indentation.xml              \
+       annotationparser/gi/syntax_multiline_annotations.xml    \
        annotationparser/gi/syntax_nested_tags.xml              \
        annotationparser/gi/syntax_paragraph_breaks.xml         \
        annotationparser/gi/syntax_whitespace.xml               \
diff --git a/tests/scanner/annotationparser/gi/annotation_allow_none.xml 
b/tests/scanner/annotationparser/gi/annotation_allow_none.xml
index 8b8ca3e..7c9c3b3 100644
--- a/tests/scanner/annotationparser/gi/annotation_allow_none.xml
+++ b/tests/scanner/annotationparser/gi/annotation_allow_none.xml
@@ -10,7 +10,7 @@
  *
  * This is a test for out arguments
  *
- * Return value: an int
+ * Return value: (allow-none): an int
  */</input>
   <parser>
     <docblock>
@@ -39,6 +39,11 @@
       <tags>
         <tag>
           <name>returns</name>
+          <annotations>
+            <annotation>
+              <name>allow-none</name>
+            </annotation>
+          </annotations>
           <description>an int</description>
         </tag>
       </tags>
diff --git a/tests/scanner/annotationparser/gi/annotation_array.xml 
b/tests/scanner/annotationparser/gi/annotation_array.xml
index b821dcf..bf00191 100644
--- a/tests/scanner/annotationparser/gi/annotation_array.xml
+++ b/tests/scanner/annotationparser/gi/annotation_array.xml
@@ -288,4 +288,137 @@ are zero-terminated</description>
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * annotation_string_zero_terminated:
+ * @data: (array invalid fixed-size=2): a third value
+ *
+ * Return value: (transfer full) (array zero-terminated=1): The return value
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_string_zero_terminated</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>data</name>
+          <annotations>
+            <annotation>
+              <name>array</name>
+              <options>
+                <option>
+                  <name>invalid</name>
+                </option>
+                <option>
+                  <name>fixed-size</name>
+                  <value>2</value>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>a third value</description>
+        </parameter>
+      </parameters>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <annotations>
+            <annotation>
+              <name>transfer</name>
+              <options>
+                <option>
+                  <name>full</name>
+                </option>
+              </options>
+            </annotation>
+            <annotation>
+              <name>array</name>
+              <options>
+                <option>
+                  <name>zero-terminated</name>
+                  <value>1</value>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>The return value</description>
+        </tag>
+      </tags>
+    </docblock>
+    <messages>
+      <message>3: Warning: Test: invalid "array" annotation option: "invalid"</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * g_app_launch_context_get_environment:
+ * @arg1: (array zero-terminated): ...
+ * @arg2: (array length): ...
+ *
+ * Returns: (array zero-terminated=yes): the child's environment
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>g_app_launch_context_get_environment</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>arg1</name>
+          <annotations>
+            <annotation>
+              <name>array</name>
+              <options>
+                <option>
+                  <name>zero-terminated</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>...</description>
+        </parameter>
+        <parameter>
+          <name>arg2</name>
+          <annotations>
+            <annotation>
+              <name>array</name>
+              <options>
+                <option>
+                  <name>length</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>...</description>
+        </parameter>
+      </parameters>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <annotations>
+            <annotation>
+              <name>array</name>
+              <options>
+                <option>
+                  <name>zero-terminated</name>
+                  <value>yes</value>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>the child's environment</description>
+        </tag>
+      </tags>
+    </docblock>
+    <messages>
+      <message>3: Warning: Test: "array" annotation option "zero-terminated" needs a value</message>
+      <message>4: Warning: Test: "array" annotation option "length" needs a value</message>
+      <message>6: Warning: Test: invalid "array" annotation option "zero-terminated" value "yes", must be an 
integer</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/annotation_attributes.xml 
b/tests/scanner/annotationparser/gi/annotation_attributes.xml
index e7c4689..04372e4 100644
--- a/tests/scanner/annotationparser/gi/annotation_attributes.xml
+++ b/tests/scanner/annotationparser/gi/annotation_attributes.xml
@@ -82,6 +82,40 @@
 
 <test>
   <!--
+  Variation of "Attributes:" tag
+  -->
+  <input>/**
+ * AnnotationObject:
+ *
+ * This is an object used to test annotations.
+ *
+ * Attributes: (org.example.test1 horses))
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>AnnotationObject</name>
+      </identifier>
+      <description>This is an object used to test annotations.</description>
+    </docblock>
+    <messages>
+      <message>6: Warning: Test: GObject-Introspection specific GTK-Doc tag "Attributes" has been 
deprecated, please use annotations on the identifier instead:
+ * Attributes: (org.example.test1 horses))
+   ^</message>
+      <message>6: Error: Test: unbalanced parentheses, annotations will be ignored:
+Attributes: (org.example.test1 horses))
+                             ^</message>
+    </messages>
+  </parser>
+  <output>/**
+ * AnnotationObject:
+ *
+ * This is an object used to test annotations.
+ */</output>
+</test>
+
+<test>
+  <!--
   (attributes) annotation on the identifier together with a
   deprecated "Attributes:" tag.
   -->
diff --git a/tests/scanner/annotationparser/gi/annotation_closure.xml 
b/tests/scanner/annotationparser/gi/annotation_closure.xml
index cd431f0..c778e6a 100644
--- a/tests/scanner/annotationparser/gi/annotation_closure.xml
+++ b/tests/scanner/annotationparser/gi/annotation_closure.xml
@@ -75,4 +75,52 @@ detection, and fixing it via annotations.</description>
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * annotation_custom_destroy:
+ * @callback: (destroy destroy) (closure data=invalid): Destroy notification
+ *
+ * Test messing up the heuristic of closure/destroy-notification
+ * detection, and fixing it via annotations.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_custom_destroy</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>callback</name>
+          <annotations>
+            <annotation>
+              <name>destroy</name>
+              <options>
+                <option>
+                  <name>destroy</name>
+                </option>
+              </options>
+            </annotation>
+            <annotation>
+              <name>closure</name>
+              <options>
+                <option>
+                  <name>data=invalid</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>Destroy notification</description>
+        </parameter>
+      </parameters>
+      <description>Test messing up the heuristic of closure/destroy-notification
+detection, and fixing it via annotations.</description>
+    </docblock>
+    <messages>
+      <message>3: Warning: Test: invalid annotation options: expected a "list" but received "key=value 
pairs":
+ * @callback: (destroy destroy) (closure data=invalid): Destroy notification
+                                             ^</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/annotation_destroy.xml 
b/tests/scanner/annotationparser/gi/annotation_destroy.xml
index 9fd8a26..bb81220 100644
--- a/tests/scanner/annotationparser/gi/annotation_destroy.xml
+++ b/tests/scanner/annotationparser/gi/annotation_destroy.xml
@@ -45,4 +45,52 @@ detection, and fixing it via annotations.</description>
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * annotation_custom_destroy:
+ * @callback: (destroy destroy=invalid) (closure data): Destroy notification
+ *
+ * Test messing up the heuristic of closure/destroy-notification
+ * detection, and fixing it via annotations.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_custom_destroy</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>callback</name>
+          <annotations>
+            <annotation>
+              <name>destroy</name>
+              <options>
+                <option>
+                  <name>destroy=invalid</name>
+                </option>
+              </options>
+            </annotation>
+            <annotation>
+              <name>closure</name>
+              <options>
+                <option>
+                  <name>data</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>Destroy notification</description>
+        </parameter>
+      </parameters>
+      <description>Test messing up the heuristic of closure/destroy-notification
+detection, and fixing it via annotations.</description>
+    </docblock>
+    <messages>
+      <message>3: Warning: Test: invalid annotation options: expected a "list" but received "key=value 
pairs":
+ * @callback: (destroy destroy=invalid) (closure data): Destroy notification
+                              ^</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/annotation_element_type.xml 
b/tests/scanner/annotationparser/gi/annotation_element_type.xml
index 84337b7..2e1f945 100644
--- a/tests/scanner/annotationparser/gi/annotation_element_type.xml
+++ b/tests/scanner/annotationparser/gi/annotation_element_type.xml
@@ -5,6 +5,8 @@
 <test>
   <input>/**
  * foo_test_array:
+ * @a: (element-type):
+ * @b: (element-type x y z):
  *
  * Returns: (element-type utf8) (transfer container): returns %NULL.
  */</input>
@@ -13,6 +15,35 @@
       <identifier>
         <name>foo_test_array</name>
       </identifier>
+      <parameters>
+        <parameter>
+          <name>a</name>
+          <annotations>
+            <annotation>
+              <name>element-type</name>
+            </annotation>
+          </annotations>
+        </parameter>
+        <parameter>
+          <name>b</name>
+          <annotations>
+            <annotation>
+              <name>element-type</name>
+              <options>
+                <option>
+                  <name>x</name>
+                </option>
+                <option>
+                  <name>y</name>
+                </option>
+                <option>
+                  <name>z</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+        </parameter>
+      </parameters>
       <tags>
         <tag>
           <name>returns</name>
@@ -38,6 +69,10 @@
         </tag>
       </tags>
     </docblock>
+    <messages>
+      <message>3: Warning: Test: "element-type" annotation takes at least one option, none given</message>
+      <message>4: Warning: Test: "element-type" annotation takes at most 2 options, 3 given</message>
+    </messages>
   </parser>
 </test>
 
@@ -129,4 +164,76 @@ element-type annotation.</description>
   </parser>
 </test>
 
+<test>
+  <input> /**
+  * foo_test_array:
+  *
+  * Returns: (element-type invalid utf8=invalid GLib.HashTable(utf8,utf8)): returns %NULL.
+  */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>foo_test_array</name>
+      </identifier>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <annotations>
+            <annotation>
+              <name>element-type</name>
+              <options>
+                <option>
+                  <name>invalid utf8=invalid GLib.HashTable(utf8,utf8)</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>returns %NULL.</description>
+        </tag>
+      </tags>
+    </docblock>
+      <messages>
+        <message>4: Warning: Test: invalid annotation options: expected a "list" but received "key=value 
pairs":
+  * Returns: (element-type invalid utf8=invalid GLib.HashTable(utf8,utf8)): returns %NULL.
+                                       ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input> /**
+  * foo_test_array:
+  *
+  * Returns: (element-type utf8=invalid GLib.HashTable(utf8,utf8) invalid): returns %NULL.
+  */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>foo_test_array</name>
+      </identifier>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <annotations>
+            <annotation>
+              <name>element-type</name>
+              <options>
+                <option>
+                  <name>utf8=invalid GLib.HashTable(utf8,utf8) invalid</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>returns %NULL.</description>
+        </tag>
+      </tags>
+    </docblock>
+      <messages>
+        <message>4: Warning: Test: invalid annotation options: expected a "list" but received "key=value 
pairs":
+  * Returns: (element-type utf8=invalid GLib.HashTable(utf8,utf8) invalid): returns %NULL.
+                               ^</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/annotation_out.xml 
b/tests/scanner/annotationparser/gi/annotation_out.xml
index 7b7c1e1..b5d08d5 100644
--- a/tests/scanner/annotationparser/gi/annotation_out.xml
+++ b/tests/scanner/annotationparser/gi/annotation_out.xml
@@ -113,4 +113,56 @@
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * regress_test_struct_a_clone:
+ * @a: (out invalid): the structure
+ * @a_out: (out callee-allocates=invalid): the cloned structure
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>regress_test_struct_a_clone</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>a</name>
+          <annotations>
+            <annotation>
+              <name>out</name>
+              <options>
+                <option>
+                  <name>invalid</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>the structure</description>
+        </parameter>
+        <parameter>
+          <name>a_out</name>
+          <annotations>
+            <annotation>
+              <name>out</name>
+              <options>
+                <option>
+                  <name>callee-allocates=invalid</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>the cloned structure</description>
+        </parameter>
+      </parameters>
+    </docblock>
+    <messages>
+      <message>4: Warning: Test: invalid annotation options: expected a "list" but received "key=value 
pairs":
+ * @a_out: (out callee-allocates=invalid): the cloned structure
+                                ^</message>
+      <message>3: Warning: Test: invalid "out" annotation option: "invalid"</message>
+      <message>4: Warning: Test: invalid "out" annotation option: "callee-allocates=invalid"</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/annotation_skip.xml 
b/tests/scanner/annotationparser/gi/annotation_skip.xml
index 396a495..ed8e75b 100644
--- a/tests/scanner/annotationparser/gi/annotation_skip.xml
+++ b/tests/scanner/annotationparser/gi/annotation_skip.xml
@@ -42,4 +42,35 @@ annotation_object_watch_full().</description>
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * annotation_object_watch: (skip yes)
+ *
+ * This is here just for the sake of being overriden by its
+ * annotation_object_watch_full().
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_object_watch</name>
+        <annotations>
+          <annotation>
+            <name>skip</name>
+            <options>
+              <option>
+                <name>yes</name>
+              </option>
+            </options>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>This is here just for the sake of being overriden by its
+annotation_object_watch_full().</description>
+    </docblock>
+    <messages>
+      <message>2: Warning: Test: "skip" annotation needs no options, 1 given</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/annotations.xml 
b/tests/scanner/annotationparser/gi/annotations.xml
new file mode 100644
index 0000000..0134abc
--- /dev/null
+++ b/tests/scanner/annotationparser/gi/annotations.xml
@@ -0,0 +1,552 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<tests xmlns="http://schemas.gnome.org/gobject-introspection/2013/test";>
+
+<test>
+  <input>/**
+ * annotation_test: (skip) (skip)
+ *
+ * Oops.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+        <annotations>
+          <annotation>
+            <name>skip</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Oops.</description>
+    </docblock>
+    <messages>
+      <message>2: Error: Test: multiple "skip" annotations:
+ * annotation_test: (skip) (skip)
+                                ^</message>
+    </messages>
+  </parser>
+  <output>/**
+ * annotation_test: (skip)
+ *
+ * Oops.
+ */</output>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (hello) (world)
+ * @param: (invalid-annotation-option): sizeof (x) == 1
+ *
+ * Test unknown annotations without options.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+        <annotations>
+          <annotation>
+            <name>hello</name>
+          </annotation>
+          <annotation>
+            <name>world</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>param</name>
+          <annotations>
+            <annotation>
+              <name>invalid-annotation-option</name>
+            </annotation>
+          </annotations>
+          <description>sizeof (x) == 1</description>
+        </parameter>
+      </parameters>
+      <description>Test unknown annotations without options.</description>
+    </docblock>
+    <messages>
+      <message>2: Warning: Test: unknown annotation: hello</message>
+      <message>2: Warning: Test: unknown annotation: world</message>
+      <message>3: Warning: Test: unknown annotation: invalid-annotation-option</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: some data: (foo bar)
+ *
+ * Oops.
+ */</input>
+  <parser>
+    <messages>
+      <message>2: Error: Test: identifier not found on the first line:
+ * annotation_test: some data: (foo bar)
+   ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotationtest some data (foo bar)
+ * @object: some data (foo bar)
+ *
+ * Oops.
+ */</input>
+  <parser>
+    <messages>
+      <message>2: Error: Test: identifier not found on the first line:
+ * annotationtest some data (foo bar)
+   ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotationtest
+ * @object: some data (foo bar)
+ *
+ * Oops.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotationtest</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>object</name>
+          <description>some data (foo bar)</description>
+        </parameter>
+      </parameters>
+      <description>Oops.</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: )skip)
+ *
+ * Oops.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <description>Oops.</description>
+    </docblock>
+    <messages>
+      <message>2: Error: Test: unbalanced parentheses, annotations will be ignored:
+ * annotation_test: )skip)
+                    ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (hello)(world)
+ *
+ * Test unknown annotations without options.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+        <annotations>
+          <annotation>
+            <name>hello</name>
+          </annotation>
+          <annotation>
+            <name>world</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Test unknown annotations without options.</description>
+    </docblock>
+    <messages>
+      <message>2: Warning: Test: unknown annotation: hello</message>
+      <message>2: Warning: Test: unknown annotation: world</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (hello   x=y    z   ) (world something else)
+ *
+ * Test unknown annotations with options.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+        <annotations>
+          <annotation>
+            <name>hello</name>
+            <options>
+              <option>
+                <name>x=y    z</name>
+              </option>
+            </options>
+          </annotation>
+          <annotation>
+            <name>world</name>
+            <options>
+              <option>
+                <name>something else</name>
+              </option>
+            </options>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Test unknown annotations with options.</description>
+    </docblock>
+    <messages>
+      <message>2: Warning: Test: unknown annotation: hello</message>
+      <message>2: Warning: Test: unknown annotation: world</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test:
+ * @test: (element-type gint gint) (transfer none) 
+ *
+ * Test multiple identical option names.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>test</name>
+          <annotations>
+            <annotation>
+              <name>element-type</name>
+              <options>
+                <option>
+                  <name>gint</name>
+                </option>
+                <option>
+                  <name>gint</name>
+                </option>
+              </options>
+            </annotation>
+            <annotation>
+              <name>transfer</name>
+              <options>
+                <option>
+                  <name>none</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+        </parameter>
+      </parameters>
+      <description>Test multiple identical option names.</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (type GLib.HashTable(utf8,gint8)) (attributes x=1 y=2)
+ *
+ * Test nested parentheses.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+        <annotations>
+          <annotation>
+            <name>type</name>
+            <options>
+              <option>
+                <name>GLib.HashTable(utf8,gint8)</name>
+              </option>
+            </options>
+          </annotation>
+          <annotation>
+            <name>attributes</name>
+            <options>
+              <option>
+                <name>x</name>
+                <value>1</value>
+              </option>
+              <option>
+                <name>y</name>
+                <value>2</value>
+              </option>
+            </options>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Test nested parentheses.</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (type GLib.HashTable(utf8,GLib.HashTable(utf8,gint8))) (attributes x=1 y=2)
+ *
+ * Test nested parentheses.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+        <annotations>
+          <annotation>
+            <name>type</name>
+            <options>
+              <option>
+                <name>GLib.HashTable(utf8,GLib.HashTable(utf8,gint8))</name>
+              </option>
+            </options>
+          </annotation>
+          <annotation>
+            <name>attributes</name>
+            <options>
+              <option>
+                <name>x</name>
+                <value>1</value>
+              </option>
+              <option>
+                <name>y</name>
+                <value>2</value>
+              </option>
+            </options>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Test nested parentheses.</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input><![CDATA[/**
+ * annotation_test: (type GLib.HashTable<utf8,GLib.HashTable<utf8,gint8>>) (attributes x=1 y=2)
+ *
+ * Test deprecated angled brackets.
+ */]]></input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+        <annotations>
+          <annotation>
+            <name>type</name>
+            <options>
+              <option>
+                <name>GLib.HashTable(utf8,GLib.HashTable(utf8,gint8))</name>
+              </option>
+            </options>
+          </annotation>
+          <annotation>
+            <name>attributes</name>
+            <options>
+              <option>
+                <name>x</name>
+                <value>1</value>
+              </option>
+              <option>
+                <name>y</name>
+                <value>2</value>
+              </option>
+            </options>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Test deprecated angled brackets.</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: ((skip)
+ *
+ * Test too many '('.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <description>Test too many '('.</description>
+    </docblock>
+    <messages>
+      <message>2: Error: Test: unexpected parentheses, annotations will be ignored:
+ * annotation_test: ((skip)
+                     ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (skip) element-type (int))
+ *
+ * Test missing '('.
+ */</input>
+  <parser>
+    <messages>
+      <message>2: Error: Test: identifier not found on the first line:
+ * annotation_test: (skip) element-type (int))
+   ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: ()
+ *
+ * Closing should not follow an opening parentheses.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <description>Closing should not follow an opening parentheses.</description>
+    </docblock>
+    <messages>
+      <message>2: Error: Test: unexpected parentheses, annotations will be ignored:
+ * annotation_test: ()
+                     ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (hello()) (world(())) (foo)
+ *
+ * Closing should not follow an opening parentheses.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <description>Closing should not follow an opening parentheses.</description>
+    </docblock>
+    <messages>
+      <message>2: Error: Test: unexpected parentheses, annotations will be ignored:
+ * annotation_test: (hello()) (world(())) (foo)
+                           ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (skip)) (type uint))
+ *
+ * Test too many ')'.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <description>Test too many ')'.</description>
+    </docblock>
+    <messages>
+      <message>2: Error: Test: unbalanced parentheses, annotations will be ignored:
+ * annotation_test: (skip)) (type uint))
+                          ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input><![CDATA[/**
+ * annotation_test:
+ * @test: (type GLib.HashTableutf8,gint8)) (element-type <int>)
+ *
+ * Test missing '('.
+ */]]></input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>test</name>
+        </parameter>
+      </parameters>
+      <description>Test missing '('.</description>
+    </docblock>
+    <messages>
+      <message><![CDATA[3: Error: Test: unbalanced parentheses, annotations will be ignored:
+ * @test: (type GLib.HashTableutf8,gint8)) (element-type <int>)
+                                         ^]]></message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * annotation_test: (skip (element-type (int))
+ *
+ * Test missing ')'.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <description>Test missing ')'.</description>
+    </docblock>
+    <messages>
+      <message>2: Error: Test: unbalanced parentheses, annotations will be ignored:
+ * annotation_test: (skip (element-type (int))
+                                             ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input><![CDATA[/**
+ * annotation_test:
+ * @test: (type GLib.HashTable(utf8,gint8) (element-type <int>)
+ *
+ * Test missing ')'.
+ */]]></input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_test</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>test</name>
+        </parameter>
+      </parameters>
+      <description>Test missing ')'.</description>
+    </docblock>
+    <messages>
+      <message><![CDATA[3: Error: Test: unbalanced parentheses, annotations will be ignored:
+ * @test: (type GLib.HashTable(utf8,gint8) (element-type <int>)
+                                                              ^]]></message>
+    </messages>
+  </parser>
+</test>
+
+</tests>
diff --git a/tests/scanner/annotationparser/gi/identifier_symbol.xml 
b/tests/scanner/annotationparser/gi/identifier_symbol.xml
index 4a97936..2f27975 100644
--- a/tests/scanner/annotationparser/gi/identifier_symbol.xml
+++ b/tests/scanner/annotationparser/gi/identifier_symbol.xml
@@ -83,6 +83,27 @@
 
 <test>
   <input>/**
+ * test_malformed_symbol: (skip):
+ *
+ * Malformed symbol identifier.
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>test_malformed_symbol</name>
+        <annotations>
+          <annotation>
+            <name>skip</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Malformed symbol identifier.</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
  * GtkWidget:test_property
  *
  * Some property.
@@ -162,6 +183,27 @@
 
 <test>
   <input>/**
+ * GtkWidget:test_malformed_property: (skip):
+ *
+ * Malformed property identifier.
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>GtkWidget:test_malformed_property</name>
+        <annotations>
+          <annotation>
+            <name>skip</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Malformed property identifier.</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
  * GtkWidget::test_signal
  *
  * Some signal.
@@ -239,4 +281,73 @@
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * GtkWidget::test_malformed_signal: (skip):
+ *
+ * Malformed signal identifier.
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>GtkWidget::test_malformed_signal</name>
+        <annotations>
+          <annotation>
+            <name>skip</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>Malformed signal identifier.</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * test_multiline_annotations_on_identifier: (skip)
+ * (foreign)
+ * @param1: (allow-none) (transfer full): first parameter
+ *
+ * Annotations spanning multiple lines are not valid
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>test_multiline_annotations_on_identifier</name>
+        <annotations>
+          <annotation>
+            <name>skip</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>param1</name>
+          <annotations>
+            <annotation>
+              <name>allow-none</name>
+            </annotation>
+            <annotation>
+              <name>transfer</name>
+              <options>
+                <option>
+                  <name>full</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>first parameter</description>
+        </parameter>
+      </parameters>
+      <description>(foreign)
+Annotations spanning multiple lines are not valid</description>
+    </docblock>
+    <messages>
+      <message>3: Error: Test: ignoring invalid multiline annotation continuation:
+ * (foreign)
+   ^</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/parameter.xml b/tests/scanner/annotationparser/gi/parameter.xml
index e17f590..fcf9ee4 100644
--- a/tests/scanner/annotationparser/gi/parameter.xml
+++ b/tests/scanner/annotationparser/gi/parameter.xml
@@ -4,6 +4,39 @@
 
 <test>
   <input>/**
+ * test_parameter_missing_colon:
+ * @param1: (allow-none) first parameter
+ *
+ * Forgotten colon above will result in a warning.
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>test_parameter_missing_colon</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>param1</name>
+          <annotations>
+            <annotation>
+              <name>allow-none</name>
+            </annotation>
+          </annotations>
+          <description>first parameter</description>
+        </parameter>
+      </parameters>
+      <description>Forgotten colon above will result in a warning.</description>
+    </docblock>
+    <messages>
+      <message>3: Warning: Test: missing ":" at column 25:
+ * @param1: (allow-none) first parameter
+                        ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
  * test_unexpected_parameter:
  *
  * Parameters should go before the comment block description.
@@ -132,4 +165,153 @@
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * anjuta_async_notify_get_error:
+ *
+ * @self: An #AnjutaAsyncNotify object
+ * @error: Return location for the error set by the called interface to which 
+ *                 this object was passed. If no error is set, @error is set to NULL.
+ *
+ * Gets the error set on @self.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>anjuta_async_notify_get_error</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>self</name>
+          <description>An #AnjutaAsyncNotify object</description>
+        </parameter>
+        <parameter>
+          <name>error</name>
+          <description>Return location for the error set by the called interface to which
+                this object was passed. If no error is set, @error is set to NULL.</description>
+        </parameter>
+      </parameters>
+      <description>Gets the error set on @self.</description>
+    </docblock>
+    <messages>
+      <message>4: Warning: Test: "@self" parameter unexpected at this location:
+ * @self: An #AnjutaAsyncNotify object
+    ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>  /**
+   * GtkPrintOperation::done
+   * @operation: the #GtkPrintOperation on which the signal was emitted
+   * @result: the result of the print operation
+   *
+   * Emitted when the print operation run has finished doing
+   * everything required for printing.
+   *
+   * @result gives you information about what happened during the run.
+   * If @result is %GTK_PRINT_OPERATION_RESULT_ERROR then you can call
+   * gtk_print_operation_get_error() for more information.
+   *
+   * If you enabled print status tracking then
+   * gtk_print_operation_is_finished() may still return %FALSE
+   * after #GtkPrintOperation::done was emitted.
+   *
+   * Since: 2.10
+   */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>GtkPrintOperation::done</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>operation</name>
+          <description>the #GtkPrintOperation on which the signal was emitted</description>
+        </parameter>
+        <parameter>
+          <name>result</name>
+          <description>the result of the print operation</description>
+        </parameter>
+      </parameters>
+      <description>Emitted when the print operation run has finished doing
+everything required for printing.
+
+ result gives you information about what happened during the run.
+If @result is %GTK_PRINT_OPERATION_RESULT_ERROR then you can call
+gtk_print_operation_get_error() for more information.
+
+If you enabled print status tracking then
+gtk_print_operation_is_finished() may still return %FALSE
+after #GtkPrintOperation::done was emitted.</description>
+      <tags>
+        <tag>
+          <name>since</name>
+          <value>2.10</value>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * TrackerDirectoryFlags:
+ * @TRACKER_DIRECTORY_FLAG_NONE: No flags.
+ * @TRACKER_DIRECTORY_FLAG_RECURSE: Should recurse in the directory.
+ * @TRACKER_DIRECTORY_FLAG_CHECK_MTIME: Should check mtimes of items in the directory.
+ * @TRACKER_DIRECTORY_FLAG_MONITOR: Should setup monitors in the items found in the directory.
+ * @TRACKER_DIRECTORY_FLAG_IGNORE: Should ignore the directory contents.
+ * @TRACKER_DIRECTORY_FLAG_PRESERVE: Should preserve items in the directory even if the directory gets 
removed.
+ *
+ * Flags used when adding a new directory to be indexed in the #TrackerIndexingTree.
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>TrackerDirectoryFlags</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>TRACKER_DIRECTORY_FLAG_NONE</name>
+          <description>No flags.</description>
+        </parameter>
+        <parameter>
+          <name>TRACKER_DIRECTORY_FLAG_RECURSE</name>
+          <description>Should recurse in the directory.</description>
+        </parameter>
+        <parameter>
+          <name>TRACKER_DIRECTORY_FLAG_CHECK_MTIME</name>
+          <description>Should check mtimes of items in the directory.</description>
+        </parameter>
+        <parameter>
+          <name>TRACKER_DIRECTORY_FLAG_MONITOR</name>
+          <description>Should setup monitors in the items found in the directory.</description>
+        </parameter>
+        <parameter>
+          <name>TRACKER_DIRECTORY_FLAG_IGNORE</name>
+          <description>Should ignore the directory contents.</description>
+        </parameter>
+        <parameter>
+          <name>TRACKER_DIRECTORY_FLAG_PRESERVE</name>
+          <description>Should preserve items in the directory even if the directory gets 
removed.</description>
+        </parameter>
+      </parameters>
+      <description>Flags used when adding a new directory to be indexed in the 
#TrackerIndexingTree.</description>
+    </docblock>
+  </parser>
+  <output>/**
+ * TrackerDirectoryFlags:
+ * @TRACKER_DIRECTORY_FLAG_NONE: No flags.
+ * @TRACKER_DIRECTORY_FLAG_RECURSE: Should recurse in the directory.
+ * @TRACKER_DIRECTORY_FLAG_CHECK_MTIME: Should check mtimes of items in the directory.
+ * @TRACKER_DIRECTORY_FLAG_MONITOR: Should setup monitors in the items found in the directory.
+ * @TRACKER_DIRECTORY_FLAG_IGNORE: Should ignore the directory contents.
+ * @TRACKER_DIRECTORY_FLAG_PRESERVE: Should preserve items in the directory even if the directory gets 
removed.
+ *
+ * Flags used when adding a new directory to be indexed in the #TrackerIndexingTree.
+ */</output>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/syntax.xml b/tests/scanner/annotationparser/gi/syntax.xml
index 6f63dff..2ea2c6f 100644
--- a/tests/scanner/annotationparser/gi/syntax.xml
+++ b/tests/scanner/annotationparser/gi/syntax.xml
@@ -227,4 +227,162 @@ something */ code goes here
   </parser>
 </test>
 
+<test>
+  <!--
+  identifier not on the first line.
+  -->
+  <input>/**
+
+ *
+
+ * regress_test_invalid_comment:
+ * @foo: a param
+
+ * comment having lines without ' * '
+ * https://bugzilla.gnome.org/show_bug.cgi?id=673806
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>regress_test_invalid_comment</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>foo</name>
+          <description>a param</description>
+        </parameter>
+      </parameters>
+      <description>comment having lines without ' * '
+https://bugzilla.gnome.org/show_bug.cgi?id=673806</description>
+    </docblock>
+    <messages>
+      <message>2: Error: Test: identifier not found on the first line:
+
+^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <!-- Confusing but well formed mixing of lines starting with and without * -->
+  <input>/**
+ * atk_hyperlink_is_inline:
+ * @link_: an #AtkHyperlink
+ *
+ * Indicates whether the link currently displays some or all of its
+ *           content inline.  Ordinary HTML links will usually return
+ *           %FALSE, but an inline &lt;src&gt; HTML element will return
+ *           %TRUE.
+a *
+ * Returns: whether or not this link displays its content inline.
+ *
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>atk_hyperlink_is_inline</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>link_</name>
+          <description>an #AtkHyperlink</description>
+        </parameter>
+      </parameters>
+      <description>Indicates whether the link currently displays some or all of its
+          content inline.  Ordinary HTML links will usually return
+          %FALSE, but an inline &lt;src&gt; HTML element will return
+          %TRUE.
+a *</description>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <description>whether or not this link displays its content inline.</description>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * gtk_tooltip_set_custom:
+ *
+ * Replaces the widget packed into the tooltip with
+ * @custom_widget. @custom_widget does not get destroyed when the tooltip goes
+ * away.
+ * By default a box with a #GtkImage and #GtkLabel is embedded in
+ * the tooltip, which can be configured using gtk_tooltip_set_markup()
+ * and gtk_tooltip_set_icon().
+
+ *
+ * Since: 2.12
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>gtk_tooltip_set_custom</name>
+      </identifier>
+      <description>Replaces the widget packed into the tooltip with
+ custom_widget  @custom_widget does not get destroyed when the tooltip goes
+away.
+By default a box with a #GtkImage and #GtkLabel is embedded in
+the tooltip, which can be configured using gtk_tooltip_set_markup()
+and gtk_tooltip_set_icon().</description>
+      <tags>
+        <tag>
+          <name>since</name>
+          <value>2.12</value>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * clutter_text_coords_to_position:
+ * @self: a #ClutterText
+ * Return: the position of the character
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>clutter_text_coords_to_position</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>self</name>
+          <description>a #ClutterText</description>
+        </parameter>
+      </parameters>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <description>the position of the character</description>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * clutter_text_coords_to_position:
+ * Return: the position of the character
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>clutter_text_coords_to_position</name>
+      </identifier>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <description>the position of the character</description>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/syntax_indentation.xml 
b/tests/scanner/annotationparser/gi/syntax_indentation.xml
new file mode 100644
index 0000000..21fd1d8
--- /dev/null
+++ b/tests/scanner/annotationparser/gi/syntax_indentation.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<tests xmlns="http://schemas.gnome.org/gobject-introspection/2013/test";>
+
+<test>
+  <input>  /**
+   * SECTION:test
+   *
+   * Describe section here
+   */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>SECTION:test</name>
+      </identifier>
+      <description>Describe section here</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>      /**
+       * SECTION:test
+       *
+       * Describe section here
+       */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>SECTION:test</name>
+      </identifier>
+      <description>Describe section here</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>      /**
+       * SECTION:test
+       *
+       * Describe section here
+       */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>SECTION:test</name>
+      </identifier>
+      <description>Describe section here</description>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>    /**
+     * SECTION:test
+     *
+     * Describe section here
+     */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>SECTION:test</name>
+      </identifier>
+      <description>Describe section here</description>
+    </docblock>
+  </parser>
+</test>
+
+</tests>
diff --git a/tests/scanner/annotationparser/gi/syntax_multiline_annotations.xml 
b/tests/scanner/annotationparser/gi/syntax_multiline_annotations.xml
new file mode 100644
index 0000000..0f5efa1
--- /dev/null
+++ b/tests/scanner/annotationparser/gi/syntax_multiline_annotations.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<tests xmlns="http://schemas.gnome.org/gobject-introspection/2013/test";>
+
+<test>
+  <input>/**
+ * regress_forced_method: (skip)
+ * (method)
+ * @obj: A #RegressTestObj
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>regress_forced_method</name>
+        <annotations>
+          <annotation>
+            <name>skip</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>obj</name>
+          <description>A #RegressTestObj</description>
+        </parameter>
+      </parameters>
+      <description>(method)</description>
+    </docblock>
+    <messages>
+      <message>3: Error: Test: ignoring invalid multiline annotation continuation:
+ * (method)
+   ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * regress_forced_method: (skip)
+ *     (method)
+ * @obj: A #RegressTestObj
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>regress_forced_method</name>
+        <annotations>
+          <annotation>
+            <name>skip</name>
+          </annotation>
+        </annotations>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>obj</name>
+          <description>A #RegressTestObj</description>
+        </parameter>
+      </parameters>
+      <description>(method)</description>
+    </docblock>
+    <messages>
+      <message>3: Error: Test: ignoring invalid multiline annotation continuation:
+ *     (method)
+       ^</message>
+    </messages>
+  </parser>
+</test>
+
+</tests>
diff --git a/tests/scanner/annotationparser/gi/tag.xml b/tests/scanner/annotationparser/gi/tag.xml
index d116841..c91ec0f 100644
--- a/tests/scanner/annotationparser/gi/tag.xml
+++ b/tests/scanner/annotationparser/gi/tag.xml
@@ -4,6 +4,151 @@
 
 <test>
   <input>/**
+ * test_tag_missing_colon:
+ *
+ * Forgotten colon below will result in a warning.
+ *
+ * Returns: (allow-none) return value
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>test_tag_missing_colon</name>
+      </identifier>
+      <description>Forgotten colon below will result in a warning.</description>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <annotations>
+            <annotation>
+              <name>allow-none</name>
+            </annotation>
+          </annotations>
+          <description>return value</description>
+        </tag>
+      </tags>
+    </docblock>
+    <messages>
+      <message>6: Warning: Test: missing ":" at column 25:
+ * Returns: (allow-none) return value
+                        ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * test_unexpected_tag:
+ *
+ * @param1: first parameter
+ * does something
+ * Returns: something
+ * returning something
+ *
+ * Probably intended as the comment block description part but in reality belongs to
+ * the "Returns:"" tag description field.
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>test_unexpected_tag</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>param1</name>
+          <description>first parameter
+does something</description>
+        </parameter>
+      </parameters>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <description>something
+returning something
+
+Probably intended as the comment block description part but in reality belongs to
+the "Returns:"" tag description field.</description>
+        </tag>
+      </tags>
+    </docblock>
+    <messages>
+      <message>4: Warning: Test: "@param1" parameter unexpected at this location:
+ * @param1: first parameter
+    ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * test_unknown_tag:
+ *
+ * Foo: something
+ *
+ * Returns: True
+ * Moo: anything
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>test_unknown_tag</name>
+      </identifier>
+      <description>Foo: something</description>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <description>True
+Moo: anything</description>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+  <output>/**
+ * test_unknown_tag:
+ *
+ * Foo: something
+ *
+ * Returns: True
+ * Moo: anything
+ */</output>
+</test>
+
+<test>
+  <input>/**
+ * test_multiline_tag:
+ *
+ * Returns:
+ * True
+ * Since:
+ * 1.0: yeah
+ */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>test_multiline_tag</name>
+      </identifier>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <description>True</description>
+        </tag>
+        <tag>
+          <name>since</name>
+          <description>1.0: yeah</description>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+  <output>/**
+ * test_multiline_tag:
+ *
+ * Returns: True
+ * Since: 1.0: yeah
+ */</output>
+</test>
+
+<test>
+  <input>/**
  * test_multiline_annotations_on_tag:
  *
  * Annotations spanning multiple lines are not valid
@@ -69,4 +214,128 @@
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * gdk_device_list_axes:
+ * @device: a pointer #GdkDevice
+ *
+ * Returns a #GList of #GdkAtom<!-- -->s, containing the labels for
+ * the axes that @device currently has.
+ *
+ * Returns: (transfer container) (element-type GdkAtom):
+ *     A #GList of #GdkAtom<!-- -->s, free
+ *     with g_list_free().
+ *
+ * Since: 3.0
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>gdk_device_list_axes</name>
+      </identifier>
+      <parameters>
+        <parameter>
+          <name>device</name>
+          <description>a pointer #GdkDevice</description>
+        </parameter>
+      </parameters>
+      <description>Returns a #GList of #GdkAtom<!-- -->s, containing the labels for
+the axes that @device currently has.</description>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <annotations>
+            <annotation>
+              <name>transfer</name>
+              <options>
+                <option>
+                  <name>container</name>
+                </option>
+              </options>
+            </annotation>
+            <annotation>
+              <name>element-type</name>
+              <options>
+                <option>
+                  <name>GdkAtom</name>
+                </option>
+              </options>
+            </annotation>
+          </annotations>
+          <description>
+    A #GList of #GdkAtom<!-- -->s, free
+    with g_list_free().</description>
+        </tag>
+        <tag>
+          <name>since</name>
+          <value>3.0</value>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+   * FsSession:codec-preferences:
+   *
+   * Type: GLib.List(FsCodec)
+   * Transfer: full
+   *
+   * This is the current preferences list for the local codecs. It is
+   * set by the user to specify the codec options and priorities. The user may
+   * change its value with fs_session_set_codec_preferences() at any time
+   * during a session. It is a #GList of #FsCodec.
+   * The user must free this codec list using fs_codec_list_destroy() when done.
+   *
+   * The payload type may be a valid dynamic PT (96-127), %FS_CODEC_ID_DISABLE
+   * or %FS_CODEC_ID_ANY. If the encoding name is "reserve-pt", then the
+   * payload type of the codec will be "reserved" and not be used by any
+   * dynamically assigned payload type.
+   */</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>FsSession:codec-preferences</name>
+        <annotations>
+          <annotation>
+            <name>type</name>
+            <options>
+              <option>
+                <name>GLib.List(FsCodec)</name>
+              </option>
+            </options>
+          </annotation>
+          <annotation>
+            <name>transfer</name>
+            <options>
+              <option>
+                <name>full</name>
+              </option>
+            </options>
+          </annotation>
+        </annotations>
+      </identifier>
+      <description>This is the current preferences list for the local codecs. It is
+set by the user to specify the codec options and priorities. The user may
+change its value with fs_session_set_codec_preferences() at any time
+during a session. It is a #GList of #FsCodec.
+The user must free this codec list using fs_codec_list_destroy() when done.
+
+The payload type may be a valid dynamic PT (96-127), %FS_CODEC_ID_DISABLE
+or %FS_CODEC_ID_ANY. If the encoding name is "reserve-pt", then the
+payload type of the codec will be "reserved" and not be used by any
+dynamically assigned payload type.</description>
+    </docblock>
+    <messages>
+      <message>4: Warning: Test: GObject-Introspection specific GTK-Doc tag "Type" has been deprecated, 
please use annotations on the identifier instead:
+   * Type: GLib.List(FsCodec)
+     ^</message>
+     <message>5: Warning: Test: GObject-Introspection specific GTK-Doc tag "Transfer" has been deprecated, 
please use annotations on the identifier instead:
+   * Transfer: full
+     ^</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/tag_description.xml 
b/tests/scanner/annotationparser/gi/tag_description.xml
index eb6c166..99245c8 100644
--- a/tests/scanner/annotationparser/gi/tag_description.xml
+++ b/tests/scanner/annotationparser/gi/tag_description.xml
@@ -25,4 +25,80 @@
   </parser>
 </test>
 
+<test>
+  <input>/**
+ * shiny_function:
+ * Description: This is a callback with a 'closure' argument that is not named
+ * 'user_data' and hence has to be annotated.
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>shiny_function</name>
+      </identifier>
+      <description>This is a callback with a 'closure' argument that is not named
+'user_data' and hence has to be annotated.</description>
+    </docblock>
+    <messages>
+      <message>3: Warning: Test: GTK-Doc tag "Description:" has been deprecated:
+ * Description: This is a callback with a 'closure' argument that is not named
+   ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * shiny_function:
+ *
+ * Some description here, but also below...
+ *
+ * Description: This is a callback with a 'closure' argument that is not named
+ * 'user_data' and hence has to be annotated.
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>shiny_function</name>
+      </identifier>
+      <description>Some description here, but also below...
+
+This is a callback with a 'closure' argument that is not named
+'user_data' and hence has to be annotated.</description>
+    </docblock>
+    <messages>
+      <message>6: Warning: Test: GTK-Doc tag "Description:" has been deprecated:
+ * Description: This is a callback with a 'closure' argument that is not named
+   ^</message>
+    </messages>
+  </parser>
+</test>
+
+<test>
+  <input>/**
+ * shiny_function:
+ *
+ * Description: This is a callback with a 'closure' argument that is not named
+ * 'user_data' and hence has to be annotated.
+ *
+ *   etc...  
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>shiny_function</name>
+      </identifier>
+      <description>This is a callback with a 'closure' argument that is not named
+'user_data' and hence has to be annotated.
+
+  etc...</description>
+    </docblock>
+    <messages>
+      <message>4: Warning: Test: GTK-Doc tag "Description:" has been deprecated:
+ * Description: This is a callback with a 'closure' argument that is not named
+   ^</message>
+    </messages>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/gi/tag_returns.xml 
b/tests/scanner/annotationparser/gi/tag_returns.xml
index ea8c012..8396320 100644
--- a/tests/scanner/annotationparser/gi/tag_returns.xml
+++ b/tests/scanner/annotationparser/gi/tag_returns.xml
@@ -33,6 +33,41 @@
 
 <test>
   <input>/**
+ * annotation_object_string_out:
+ *
+ * Test returning a string as an out parameter
+ *
+ * Returns: (allow-none)): some boolean
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_object_string_out</name>
+      </identifier>
+      <description>Test returning a string as an out parameter</description>
+      <tags>
+        <tag>
+          <name>returns</name>
+        </tag>
+      </tags>
+    </docblock>
+    <messages>
+      <message>6: Error: Test: unbalanced parentheses, annotations will be ignored:
+ * Returns: (allow-none)): some boolean
+                        ^</message>
+    </messages>
+  </parser>
+  <output>/**
+ * annotation_object_string_out:
+ *
+ * Test returning a string as an out parameter
+ *
+ * Returns:
+ */</output>
+</test>
+
+<test>
+  <input>/**
  * test_unexpected_tag:
  * @param1: first parameter
  * Returns: something
@@ -127,6 +162,75 @@ Tags should go after the comment block description</description>
 
 <test>
   <!--
+  Variation of "@returns" as a parameter
+  -->
+  <input>/**
+ * annotation_object_string_out:
+ * @returns: (allow-none)): some boolean
+ *
+ * Test returning a string as an out parameter
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_object_string_out</name>
+      </identifier>
+      <description>Test returning a string as an out parameter</description>
+      <tags>
+        <tag>
+          <name>returns</name>
+        </tag>
+      </tags>
+    </docblock>
+    <messages>
+      <message>3: Error: Test: unbalanced parentheses, annotations will be ignored:
+ * @returns: (allow-none)): some boolean
+                         ^</message>
+    </messages>
+  </parser>
+  <output>/**
+ * annotation_object_string_out:
+ *
+ * Test returning a string as an out parameter
+ *
+ * Returns:
+ */</output>
+</test>
+
+<test>
+  <!--
+  Variation of "@returns" as a parameter
+  -->
+  <input>/**
+ * annotation_object_string_out:
+ * @returns:
+ *
+ * Test returning a string as an out parameter
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_object_string_out</name>
+      </identifier>
+      <description>Test returning a string as an out parameter</description>
+      <tags>
+        <tag>
+          <name>returns</name>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+  <output>/**
+ * annotation_object_string_out:
+ *
+ * Test returning a string as an out parameter
+ *
+ * Returns:
+ */</output>
+</test>
+
+<test>
+  <!--
   Variation of multiple "Returns:" notations
   -->
   <input>/**
@@ -228,6 +332,39 @@ parameter is encountered.</description>
 </test>
 
 <test>
+  <input><![CDATA[/**
+ * gtk_rc_get_im_module_path:
+ * @returns: a newly-allocated string containing the path in which to 
+ *    look for IM modules.
+ *
+ * Obtains the path in which to look for IM modules. See the documentation
+ * of the <link linkend="im-module-path"><envar>GTK_PATH</envar></link>
+ * environment variable for more details about looking up modules. This
+ * function is useful solely for utilities supplied with GTK+ and should
+ * not be used by applications under normal circumstances.
+ */]]></input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>gtk_rc_get_im_module_path</name>
+      </identifier>
+      <description><![CDATA[Obtains the path in which to look for IM modules. See the documentation
+of the <link linkend="im-module-path"><envar>GTK_PATH</envar></link>
+environment variable for more details about looking up modules. This
+function is useful solely for utilities supplied with GTK+ and should
+not be used by applications under normal circumstances.]]></description>
+      <tags>
+        <tag>
+          <name>returns</name>
+          <description>a newly-allocated string containing the path in which to
+   look for IM modules.</description>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
+<test>
   <!--
   Technically not a valid Returns: tag, but we need to support this for backwards compatibility
   with the old annotationparser.
diff --git a/tests/scanner/annotationparser/gi/tag_since.xml b/tests/scanner/annotationparser/gi/tag_since.xml
index 048cb4d..e854545 100644
--- a/tests/scanner/annotationparser/gi/tag_since.xml
+++ b/tests/scanner/annotationparser/gi/tag_since.xml
@@ -27,6 +27,36 @@
   <input>/**
  * annotation_versioned:
  *
+ * Since: (invalid)): 0.6
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_versioned</name>
+      </identifier>
+      <tags>
+        <tag>
+          <name>since</name>
+        </tag>
+      </tags>
+    </docblock>
+    <messages>
+      <message>4: Error: Test: unbalanced parentheses, annotations will be ignored:
+ * Since: (invalid)): 0.6
+                   ^</message>
+    </messages>
+  </parser>
+  <output>/**
+ * annotation_versioned:
+ *
+ * Since:
+ */</output>
+</test>
+
+<test>
+  <input>/**
+ * annotation_versioned:
+ *
  * Since: this function is available since version 0.6
  **/</input>
   <parser>
@@ -46,6 +76,28 @@
 
 <test>
   <input>/**
+ * annotation_versioned:
+ *
+ * Since: 0.6: this function is available since version 0.6
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>annotation_versioned</name>
+      </identifier>
+      <tags>
+        <tag>
+          <name>since</name>
+          <value>0.6</value>
+          <description>this function is available since version 0.6</description>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
+<test>
+  <input>/**
  * test_tag_not_annotatable:
  *
  * Tags (except Returns:) don't have annotations
diff --git a/tests/scanner/annotationparser/gi/tag_stability.xml 
b/tests/scanner/annotationparser/gi/tag_stability.xml
index ad3ca68..a82d19c 100644
--- a/tests/scanner/annotationparser/gi/tag_stability.xml
+++ b/tests/scanner/annotationparser/gi/tag_stability.xml
@@ -143,4 +143,31 @@
   </parser>
 </test>
 
+<test>
+  <!--
+  "Stability:" description
+  -->
+  <input>/**
+ * test_stability_description:
+ *
+ * Stability: Unstable: maybe one day this will work
+ *                      correctly...
+ **/</input>
+  <parser>
+    <docblock>
+      <identifier>
+        <name>test_stability_description</name>
+      </identifier>
+      <tags>
+        <tag>
+          <name>stability</name>
+          <value>Unstable</value>
+          <description>maybe one day this will work
+                     correctly...</description>
+        </tag>
+      </tags>
+    </docblock>
+  </parser>
+</test>
+
 </tests>
diff --git a/tests/scanner/annotationparser/test_patterns.py b/tests/scanner/annotationparser/test_patterns.py
index 207fdc6..3362458 100644
--- a/tests/scanner/annotationparser/test_patterns.py
+++ b/tests/scanner/annotationparser/test_patterns.py
@@ -289,6 +289,10 @@ identifier_symbol_tests = [
          {'delimiter': ':',
           'symbol_name': 'gtk_widget_show',
           'fields': ''}),
+    (SYMBOL_RE, 'gtk_widget_show:(skip):',
+         {'delimiter': ':',
+          'symbol_name': 'gtk_widget_show',
+          'fields': '(skip)'}),
     (SYMBOL_RE, 'gtk_widget_show (skip)',
          {'delimiter': '',
           'symbol_name': 'gtk_widget_show',
@@ -419,7 +423,28 @@ identifier_symbol_tests = [
     (SYMBOL_RE, 'Something:',
          {'delimiter': ':',
           'symbol_name': 'Something',
-          'fields': ''})]
+          'fields': ''}),
+    # annotations with multiple closing parentheses
+    (SYMBOL_RE, 'FooWidget: (transfer full) (type GLib.List(utf8))',
+         {'delimiter': ':',
+          'symbol_name': 'FooWidget',
+          'fields': '(transfer full) (type GLib.List(utf8))'}),
+    (SYMBOL_RE, 'FooWidget: (transfer full) (type GLib.List((utf8)))',
+         {'delimiter': ':',
+          'symbol_name': 'FooWidget',
+          'fields': '(transfer full) (type GLib.List((utf8)))'}),
+    (SYMBOL_RE, 'FooWidget: (transfer full) (type GLib.List(GLib.List(utf8)))',
+         {'delimiter': ':',
+          'symbol_name': 'FooWidget',
+          'fields': '(transfer full) (type GLib.List(GLib.List(utf8)))'}),
+    (SYMBOL_RE, 'FooWidget: (type GLib.List(GLib.List(utf8))) (transfer full)',
+         {'delimiter': ':',
+          'symbol_name': 'FooWidget',
+          'fields': '(type GLib.List(GLib.List(utf8))) (transfer full)'}),
+    (SYMBOL_RE, 'FooWidget: (type GLib.List(GLib.List(utf8)))(transfer full)(type 
GLib.List(GLib.List(utf8)))',
+         {'delimiter': ':',
+          'symbol_name': 'FooWidget',
+          'fields': '(type GLib.List(GLib.List(utf8)))(transfer full)(type GLib.List(GLib.List(utf8)))'})]
 
 identifier_property_tests = [
     # simple property name
@@ -487,7 +512,7 @@ identifier_property_tests = [
           'property_name': 'handle',
           'delimiter': ':',
           'fields': ''}),
-    # property name that contains a dash
+    # properties: property name that contains a dash
     (PROPERTY_RE, 'GtkWidget:double-buffered (skip)',
          {'class_name': 'GtkWidget',
           'property_name': 'double-buffered',
@@ -551,10 +576,31 @@ identifier_property_tests = [
          {'class_name': 'GMemoryOutputStream',
           'property_name': 'realloc-function',
           'delimiter': ':',
-          'fields': '(skip)'})]
+          'fields': '(skip)'}),
+    # properties: data with multiple closing parentheses
+    (PROPERTY_RE, 'GMemoryOutputStream:realloc-function: (transfer full) (type GLib.List(utf8))',
+         {'class_name': 'GMemoryOutputStream',
+          'property_name': 'realloc-function',
+          'delimiter': ':',
+          'fields': '(transfer full) (type GLib.List(utf8))'}),
+    (PROPERTY_RE, 'GMemoryOutputStream:realloc-function: (transfer full) (type GLib.List((utf8)))',
+         {'class_name': 'GMemoryOutputStream',
+          'property_name': 'realloc-function',
+          'delimiter': ':',
+          'fields': '(transfer full) (type GLib.List((utf8)))'}),
+    (PROPERTY_RE, 'GMemoryOutputStream:realloc-function: (transfer full) (type GLib.List(GLib.List(utf8)))',
+         {'class_name': 'GMemoryOutputStream',
+          'property_name': 'realloc-function',
+          'delimiter': ':',
+          'fields': '(transfer full) (type GLib.List(GLib.List(utf8)))'}),
+    (PROPERTY_RE, 'GMemoryOutputStream:realloc-function: (type GLib.List(GLib.List(utf8))) (transfer full)',
+         {'class_name': 'GMemoryOutputStream',
+          'property_name': 'realloc-function',
+          'delimiter': ':',
+          'fields': '(type GLib.List(GLib.List(utf8))) (transfer full)'})]
 
 identifier_signal_tests = [
-    # simple property name
+    # simple signal name
     (SIGNAL_RE, 'GtkWidget::changed: (skip)',
          {'class_name': 'GtkWidget',
           'signal_name': 'changed',
@@ -574,7 +620,7 @@ identifier_signal_tests = [
          None),
     (SIGNAL_RE, 'really-weird_thing::changed:',
          None),
-    # signal name that contains a dash
+    # signals: signal name that contains a dash
     (SIGNAL_RE, 'GtkWidget::hierarchy-changed: (skip)',
          {'class_name': 'GtkWidget',
           'signal_name': 'hierarchy-changed',
@@ -593,7 +639,28 @@ identifier_signal_tests = [
     (SIGNAL_RE, 'Weird-thing::hierarchy-changed:',
          None),
     (SIGNAL_RE, 'really-weird_thing::hierarchy-changed:',
-         None)]
+         None),
+    # signals: data with multiple closing parentheses
+    (SIGNAL_RE, 'GtkWidget::hierarchy-changed: (transfer full) (type GLib.List(utf8))',
+         {'class_name': 'GtkWidget',
+          'signal_name': 'hierarchy-changed',
+          'delimiter': ':',
+          'fields': '(transfer full) (type GLib.List(utf8))'}),
+    (SIGNAL_RE, 'GtkWidget::hierarchy-changed: (transfer full) (type GLib.List((utf8)))',
+         {'class_name': 'GtkWidget',
+          'signal_name': 'hierarchy-changed',
+          'delimiter': ':',
+          'fields': '(transfer full) (type GLib.List((utf8)))'}),
+    (SIGNAL_RE, 'GtkWidget::hierarchy-changed: (transfer full) (type GLib.List(GLib.List(utf8)))',
+         {'class_name': 'GtkWidget',
+          'signal_name': 'hierarchy-changed',
+          'delimiter': ':',
+          'fields': '(transfer full) (type GLib.List(GLib.List(utf8)))'}),
+    (SIGNAL_RE, 'GtkWidget::hierarchy-changed: (type GLib.List(GLib.List(utf8))) (transfer full)',
+         {'class_name': 'GtkWidget',
+          'signal_name': 'hierarchy-changed',
+          'delimiter': ':',
+          'fields': '(type GLib.List(GLib.List(utf8))) (transfer full)'})]
 
 parameter_tests = [
     (PARAMETER_RE, '@Short_description: Base class for all widgets  ',
@@ -602,6 +669,9 @@ parameter_tests = [
     (PARAMETER_RE, '@...: the value of the first property, followed optionally by more',
          {'parameter_name': '...',
           'fields': 'the value of the first property, followed optionally by more'}),
+    (PARAMETER_RE, '@args...: list of arguments',
+         {'parameter_name': 'args...',
+          'fields': 'list of arguments'}),
     (PARAMETER_RE, '@widget: a #GtkWidget',
          {'parameter_name': 'widget',
           'fields': 'a #GtkWidget'}),
@@ -625,7 +695,33 @@ parameter_tests = [
           'fields': 'a #GSequenceIter'}),
     (PARAMETER_RE, '@keys: (array length=n_keys) (element-type GQuark) (allow-none):',
          {'parameter_name': 'keys',
-          'fields': '(array length=n_keys) (element-type GQuark) (allow-none):'})]
+          'fields': '(array length=n_keys) (element-type GQuark) (allow-none):'}),
+    # parentheses in description
+    (PARAMETER_RE, '@foo: This is a foo (be careful using it)',
+         {'parameter_name': 'foo',
+          'fields': 'This is a foo (be careful using it)'}),
+    (PARAMETER_RE, '@foo: This is a foo (be careful using it) and see also: bar',
+         {'parameter_name': 'foo',
+          'fields': 'This is a foo (be careful using it) and see also: bar'}),
+    (PARAMETER_RE, '@foo: This is a foo (be careful using it) and see also: bar and baz',
+         {'parameter_name': 'foo',
+          'fields': 'This is a foo (be careful using it) and see also: bar and baz'}),
+    # annotations with multiple closing parentheses, combined with parentheses in description
+    (PARAMETER_RE, '@foo: (transfer full) (element-type guint8): This is a foo (be careful using it) and see 
also: bar and baz',
+         {'parameter_name': 'foo',
+          'fields': '(transfer full) (element-type guint8): This is a foo (be careful using it) and see 
also: bar and baz'}),
+    (PARAMETER_RE, '@foo: (transfer full) (element-type GLib.List(utf8)): This is a foo (be careful using 
it) and see also: bar and baz',
+         {'parameter_name': 'foo',
+          'fields': '(transfer full) (element-type GLib.List(utf8)): This is a foo (be careful using it) and 
see also: bar and baz'}),
+    (PARAMETER_RE, '@foo: (transfer full) (element-type GLib.List((utf8))): This is a foo (be careful using 
it) and see also: bar and baz',
+         {'parameter_name': 'foo',
+          'fields': '(transfer full) (element-type GLib.List((utf8))): This is a foo (be careful using it) 
and see also: bar and baz'}),
+    (PARAMETER_RE, '@foo: (transfer full) (element-type GLib.List(GLib.List(utf8))): This is a foo (be 
careful using it) and see also: bar and baz',
+         {'parameter_name': 'foo',
+          'fields': '(transfer full) (element-type GLib.List(GLib.List(utf8))): This is a foo (be careful 
using it) and see also: bar and baz'}),
+    (PARAMETER_RE, '@foo: (element-type GLib.List(GLib.List(utf8))) (transfer full): This is a foo (be 
careful using it) and see also: bar and baz',
+         {'parameter_name': 'foo',
+          'fields': '(element-type GLib.List(GLib.List(utf8))) (transfer full): This is a foo (be careful 
using it) and see also: bar and baz'})]
 
 tag_tests = [
     (TAG_RE, 'Since 3.0',
@@ -662,7 +758,37 @@ tag_tests = [
     (TAG_RE, 'Return value: (type GLib.HashTable<utf8,GLib.HashTable<utf8,utf8>>) '
              '(transfer full):',
          {'tag_name': 'Return value',
-          'fields': '(type GLib.HashTable<utf8,GLib.HashTable<utf8,utf8>>) (transfer full):'})]
+          'fields': '(type GLib.HashTable<utf8,GLib.HashTable<utf8,utf8>>) (transfer full):'}),
+    # parentheses in description
+    (TAG_RE, 'Returns: Returns a foo (be careful using it)',
+         {'tag_name': 'Returns',
+          'fields': 'Returns a foo (be careful using it)'}),
+    (TAG_RE, 'Returns: Returns a foo (be careful using it) and see also: bar',
+         {'tag_name': 'Returns',
+          'fields': 'Returns a foo (be careful using it) and see also: bar'}),
+    (TAG_RE, 'Returns: Returns a foo (be careful using it) and see also: bar and baz',
+         {'tag_name': 'Returns',
+          'fields': 'Returns a foo (be careful using it) and see also: bar and baz'}),
+    # annotations with multiple closing parentheses, combined with parentheses in description
+    (TAG_RE, 'Returns: (transfer full) (element-type guint8): Returns a foo (be careful using it) and see 
also: bar and baz',
+         {'tag_name': 'Returns',
+          'fields': '(transfer full) (element-type guint8): Returns a foo (be careful using it) and see 
also: bar and baz'}),
+    (TAG_RE, 'Returns: (transfer full) (element-type GLib.List(utf8)): Returns a foo (be careful using it) 
and see also: bar and baz',
+         {'tag_name': 'Returns',
+          'fields': '(transfer full) (element-type GLib.List(utf8)): Returns a foo (be careful using it) and 
see also: bar and baz'}),
+    (TAG_RE, 'Returns: (transfer full) (element-type GLib.List((utf8))): Returns a foo (be careful using it) 
and see also: bar and baz',
+         {'tag_name': 'Returns',
+          'fields': '(transfer full) (element-type GLib.List((utf8))): Returns a foo (be careful using it) 
and see also: bar and baz'}),
+    (TAG_RE, 'Returns: (transfer full) (element-type GLib.List(GLib.List(utf8))): Returns a foo (be careful 
using it) and see also: bar and baz',
+         {'tag_name': 'Returns',
+          'fields': '(transfer full) (element-type GLib.List(GLib.List(utf8))): Returns a foo (be careful 
using it) and see also: bar and baz'}),
+    (TAG_RE, 'Returns: (element-type GLib.List(GLib.List(utf8))) (transfer full): Returns a foo (be careful 
using it) and see also: bar and baz',
+         {'tag_name': 'Returns',
+          'fields': '(element-type GLib.List(GLib.List(utf8))) (transfer full): Returns a foo (be careful 
using it) and see also: bar and baz'}),
+    (TAG_RE, 'Returns: (element-type utf8=invalid GLib.HashTable(utf8,utf8) invalid): returns %NULL.',
+         {'tag_name': 'Returns',
+          'fields': '(element-type utf8=invalid GLib.HashTable(utf8,utf8) invalid): returns %NULL.'})]
+
 
 tag_value_version_tests = [
     (TAG_VALUE_VERSION_RE, ' abc',


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