[valadoc] gir-importer: Process implicit parameters



commit 1eebb3a020b0a91f153cf313bd90b0600b94a56f
Author: Florian Brosch <flo brosch gmail com>
Date:   Thu Aug 9 04:15:01 2012 +0200

    gir-importer: Process implicit parameters

 src/libvaladoc/Makefile.am                         |    1 +
 src/libvaladoc/api/callable.vala                   |   51 +++++++
 src/libvaladoc/api/delegate.vala                   |   15 ++-
 src/libvaladoc/api/formalparameter.vala            |   24 +++
 src/libvaladoc/api/method.vala                     |   17 ++-
 src/libvaladoc/api/signal.vala                     |   16 ++-
 .../documentation/gtkdoccommentparser.vala         |   56 ++++++--
 src/libvaladoc/errorreporter.vala                  |   20 +++-
 .../importer/girdocumentationimporter.vala         |  149 ++++++++++++++++++--
 src/libvaladoc/taglets/tagletlink.vala             |    1 +
 src/libvaladoc/taglets/tagletparam.vala            |   31 ++++-
 src/libvaladoc/taglets/tagletreturn.vala           |    6 +-
 src/valadoc/valadoc.vala                           |    2 +
 13 files changed, 340 insertions(+), 49 deletions(-)
---
diff --git a/src/libvaladoc/Makefile.am b/src/libvaladoc/Makefile.am
index b54bbde..7ec0b65 100644
--- a/src/libvaladoc/Makefile.am
+++ b/src/libvaladoc/Makefile.am
@@ -55,6 +55,7 @@ libvaladoc_la_VALASOURCES = \
 	api/attributeargument.vala \
 	api/attribute.vala \
 	api/array.vala \
+	api/callable.vala \
 	api/childsymbolregistrar.vala \
 	api/class.vala \
 	api/constant.vala \
diff --git a/src/libvaladoc/api/callable.vala b/src/libvaladoc/api/callable.vala
new file mode 100644
index 0000000..60515ee
--- /dev/null
+++ b/src/libvaladoc/api/callable.vala
@@ -0,0 +1,51 @@
+/* callable.vala
+ *
+ * Copyright (C) 2012  Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ * 	Florian Brosch <flo brosch gmail com>
+ */
+
+
+using Valadoc;
+using GLib;
+using Gee;
+
+
+/**
+ * Used to translate imported C-documentation
+ */
+public interface Valadoc.Api.Callable : Symbol {
+	/**
+	 * The return type of this symbol.
+	 *
+	 * @return The return type of this symbol or null for void
+	 */
+	public abstract TypeReference? return_type {
+		set;
+		get;
+	}
+
+	/**
+	 * Used to avoid warnings for implicit parameters
+	 */
+	internal abstract string? implicit_array_length_cparameter_name {
+		get;
+		set;
+	}
+}
+
diff --git a/src/libvaladoc/api/delegate.vala b/src/libvaladoc/api/delegate.vala
index 2e43791..d57c80d 100644
--- a/src/libvaladoc/api/delegate.vala
+++ b/src/libvaladoc/api/delegate.vala
@@ -27,9 +27,18 @@ using Valadoc.Content;
 /**
  * Represents a Delegate.
  */
-public class Valadoc.Api.Delegate : TypeSymbol {
+public class Valadoc.Api.Delegate : TypeSymbol, Callable {
 	private string? cname;
 
+	/**
+	 * { inheritDoc}
+	 */
+	internal string? implicit_array_length_cparameter_name {
+		get;
+		set;
+	}
+
+
 	public Delegate (Node parent, SourceFile file, string name, SymbolAccessibility accessibility, SourceComment? comment, string? cname, bool is_static, void* data) {
 		base (parent, file, name, accessibility, comment, false, data);
 
@@ -45,9 +54,7 @@ public class Valadoc.Api.Delegate : TypeSymbol {
 	}
 
 	/**
-	 * The return type of this callback.
-	 *
-	 * @return The return type of this callback or null for void
+	 * { inheritDoc}
 	 */
 	public TypeReference? return_type {
 		set;
diff --git a/src/libvaladoc/api/formalparameter.vala b/src/libvaladoc/api/formalparameter.vala
index 0a781e3..82ed872 100644
--- a/src/libvaladoc/api/formalparameter.vala
+++ b/src/libvaladoc/api/formalparameter.vala
@@ -32,6 +32,30 @@ public class Valadoc.Api.FormalParameter : Symbol {
 		set;
 	}
 
+	/**
+	 * Used to translate imported C-documentation
+	 */
+	internal string? implicit_array_length_cparameter_name {
+		get;
+		set;
+	}
+
+	/**
+	 * Used to translate imported C-documentation
+	 */
+	internal string? implicit_closure_cparameter_name {
+		get;
+		set;
+	}
+
+	/**
+	 * Used to translate imported C-documentation
+	 */
+	internal string? implicit_destroy_cparameter_name {
+		get;
+		set;
+	}
+
 	private FormalParameterType type;
 
 	public FormalParameter (Node parent, SourceFile file, string? name, SymbolAccessibility accessibility, FormalParameterType type, bool ellipsis, void* data) {
diff --git a/src/libvaladoc/api/method.vala b/src/libvaladoc/api/method.vala
index 0a142e3..d222bf0 100644
--- a/src/libvaladoc/api/method.vala
+++ b/src/libvaladoc/api/method.vala
@@ -20,14 +20,14 @@
  * 	Florian Brosch <flo brosch gmail com>
  */
 
-using Gee;
 using Valadoc.Content;
+using Gee;
 
 
 /**
  * Represents a function or a method.
  */
-public class Valadoc.Api.Method : Member {
+public class Valadoc.Api.Method : Member, Callable {
 	private string? finish_function_cname;
 	private string? dbus_result_name;
 	private string? dbus_name;
@@ -35,6 +35,15 @@ public class Valadoc.Api.Method : Member {
 
 	private MethodBindingType binding_type;
 
+	/**
+	 * { inheritDoc}
+	 */
+	internal string? implicit_array_length_cparameter_name {
+		get;
+		set;
+	}
+
+
 	public Method (Node parent, SourceFile file, string name, SymbolAccessibility accessibility, SourceComment? comment, string? cname, string? dbus_name, string? dbus_result_name, string? finish_function_cname, MethodBindingType binding_type, bool is_yields, bool is_dbus_visible, bool is_constructor, void* data) {
 		base (parent, file, name, accessibility, comment, data);
 
@@ -83,9 +92,7 @@ public class Valadoc.Api.Method : Member {
 	}
 
 	/**
-	 * The return type of this method.
-	 *
-	 * @return The return type of this method or null for void
+	 * { inheritDoc}
 	 */
 	public TypeReference? return_type {
 		set;
diff --git a/src/libvaladoc/api/signal.vala b/src/libvaladoc/api/signal.vala
index 87a380c..0e21dfb 100644
--- a/src/libvaladoc/api/signal.vala
+++ b/src/libvaladoc/api/signal.vala
@@ -27,10 +27,20 @@ using Valadoc.Content;
 /**
  * Represents an signal.
  */
-public class Valadoc.Api.Signal : Member {
+public class Valadoc.Api.Signal : Member, Callable {
 	private string? dbus_name;
 	private string? cname;
 
+
+	/**
+	 * { inheritDoc}
+	 */
+	internal string? implicit_array_length_cparameter_name {
+		get;
+		set;
+	}
+
+
 	public Signal (Node parent, SourceFile file, string name, SymbolAccessibility accessibility, SourceComment? comment, string? cname, string? dbus_name, bool is_dbus_visible, bool is_virtual, void* data) {
 		base (parent, file, name, accessibility, comment, data);
 
@@ -56,9 +66,7 @@ public class Valadoc.Api.Signal : Member {
 	}
 
 	/**
-	 * The return type of this signal.
-	 *
-	 * @return The return type of this signal or null for void
+	 * { inheritDoc}
 	 */
 	public TypeReference? return_type {
 		set;
diff --git a/src/libvaladoc/documentation/gtkdoccommentparser.vala b/src/libvaladoc/documentation/gtkdoccommentparser.vala
index 7939216..eb154ad 100644
--- a/src/libvaladoc/documentation/gtkdoccommentparser.vala
+++ b/src/libvaladoc/documentation/gtkdoccommentparser.vala
@@ -1537,15 +1537,13 @@ public class Valadoc.Gtkdoc.Parser : Object, ResourceLocator {
 			}
 		}
 
-		return null;
+		return {id};
 	}
 
-	private string? resolve_parameter_ctype (string parameter_name, out string? param_name) {
-		string[]? parts = split_type_name (current.content);
-		param_name = null;
-		if (parts == null) {
-			return null;
-		}
+	private string? resolve_parameter_ctype (string parameter_name, out string? param_name, out string? param_array_name, out bool is_return_type_len) {
+		string[]? parts = split_type_name (parameter_name);
+		is_return_type_len = false;
+		param_array_name = null;
 
 		Api.FormalParameter? param = null; // type parameter or formal parameter
 		foreach (Api.Node node in this.element.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false)) {
@@ -1553,10 +1551,31 @@ public class Valadoc.Gtkdoc.Parser : Object, ResourceLocator {
 				param = node as Api.FormalParameter;
 				break;
 			}
+
+			if (((Api.FormalParameter) node).implicit_array_length_cparameter_name == parts[0]) {
+				param_array_name = ((Api.FormalParameter) node).name;
+				break;
+			}
 		}
 
+		if (this.element is Api.Callable && ((Api.Callable) this.element).implicit_array_length_cparameter_name == parts[0]) {
+			is_return_type_len = true;
+		}
+
+		if (parts.length == 1) {
+			param_name = parameter_name;
+			return null;
+		}
+
+
+		Api.Item? inner = null;
+
+		if (param_array_name != null || is_return_type_len) {
+			inner = tree.search_symbol_str (null, "int");
+		} else if (param != null) {
+			inner = param.parameter_type;
+		}
 
-		Api.Item? inner = param.parameter_type;
 		while (inner != null) {
 			if (inner is Api.TypeReference) {
 				inner = ((Api.TypeReference) inner).data_type;
@@ -1571,6 +1590,7 @@ public class Valadoc.Gtkdoc.Parser : Object, ResourceLocator {
 
 
 		if (inner == null) {
+			param_name = parameter_name;
 			return null;
 		}
 
@@ -1671,17 +1691,27 @@ public class Valadoc.Gtkdoc.Parser : Object, ResourceLocator {
 				run.content.add (this.create_type_link (current.content));
 				next ();
 			} else if (current.type == TokenType.GTKDOC_PARAM) {
+				string? param_array_name;
+				bool is_return_type_len;
 				string? param_name;
-				string? cname = resolve_parameter_ctype (current.content, out param_name);
+
+				string? cname = resolve_parameter_ctype (current.content, out param_name, out param_array_name, out is_return_type_len);
 				Run current_run = factory.create_run (Run.Style.MONOSPACED);
+				run.content.add (current_run);
 
-				if (cname == null) {
-					current_run.content.add (factory.create_text (current.content));
-					run.content.add (current_run);
+				if (is_return_type_len) {
+					Run keyword_run = factory.create_run (Run.Style.LANG_KEYWORD);
+					keyword_run.content.add (factory.create_text ("return"));
+					current_run.content.add (keyword_run);
+
+					current_run.content.add (factory.create_text (".length"));
+				} else if (param_array_name != null) {
+					current_run.content.add (factory.create_text (param_array_name + ".length"));
 				} else {
 					current_run.content.add (factory.create_text (param_name));
-					run.content.add (current_run);
+				}
 
+				if (cname != null) {
 					run.content.add (factory.create_text ("."));
 
 					Taglets.Link link = factory.create_taglet ("link") as Taglets.Link;
diff --git a/src/libvaladoc/errorreporter.vala b/src/libvaladoc/errorreporter.vala
index 073eb4b..b735982 100644
--- a/src/libvaladoc/errorreporter.vala
+++ b/src/libvaladoc/errorreporter.vala
@@ -42,8 +42,9 @@ public class Valadoc.ErrorReporter : Object {
 		set;
 	}
 
-	public ErrorReporter () {
-		this.stream = GLib.stderr;
+	public Settings? settings {
+		get;
+		set;
 	}
 
 	public int errors {
@@ -58,6 +59,12 @@ public class Valadoc.ErrorReporter : Object {
 		}
 	}
 
+
+	public ErrorReporter (Settings? settings = null) {
+		this.stream = GLib.stderr;
+		this.settings = settings;
+	}
+
 	private inline void msg (string type, string file, long line, long startpos, long endpos, string errline, string msg_format, va_list args) {
 		this.stream.printf ("%s:%lu.%lu-%lu.%lu: %s: ", file, line, startpos, line, endpos, type);
 		this.stream.vprintf (msg_format, args);
@@ -92,6 +99,15 @@ public class Valadoc.ErrorReporter : Object {
 		this._errors++;
 	}
 
+	public void simple_note (string msg_format, ...) {
+		if (_settings == null || _settings.verbose) {
+			var args = va_list();
+			this.stream.vprintf (msg_format, args);
+			this.stream.putc ('\n');
+			this._warnings++;
+		}
+	}
+
 	public void error (string file, long line, long startpos, long endpos, string errline, string msg_format, ...) {
 		var args = va_list();
 		this.msg ("error", file, line, startpos, endpos, errline, msg_format, args);
diff --git a/src/libvaladoc/importer/girdocumentationimporter.vala b/src/libvaladoc/importer/girdocumentationimporter.vala
index 789409b..d097e26 100644
--- a/src/libvaladoc/importer/girdocumentationimporter.vala
+++ b/src/libvaladoc/importer/girdocumentationimporter.vala
@@ -1,8 +1,8 @@
 /* girdocumentationimporter.vala
  *
  * Copyright (C) 2008-2010  JÃrg Billeter
- * Copyright (C) 2011  Luca Bruno
- * Copyright (C) 2011  Florian Brosch
+ * Copyright (C) 2011       Luca Bruno
+ * Copyright (C) 2011-2012  Florian Brosch
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
 
 using Valadoc;
 using GLib;
-
+using Gee;
 
 
 public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
@@ -44,6 +44,16 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 
 	private string parent_c_identifier;
 
+	private struct ImplicitParameterPos {
+		public int parameter;
+		public int position;
+
+		public ImplicitParameterPos (int parameter, int position) {
+			this.parameter = parameter;
+			this.position = position;
+		}
+	}
+
 	public GirDocumentationImporter (Api.Tree tree, DocumentationParser parser, ModuleLoader modules, Settings settings, ErrorReporter reporter) {
 		base (tree, modules, settings);
 		this.reporter = reporter;
@@ -65,7 +75,26 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 		file = null;
 	}
 
-	private void attach_comment (string cname, Api.GirSourceComment? comment) {
+	private Api.FormalParameter? find_parameter (Api.Node node, string name) {
+		Gee.List<Api.Node> parameters = node.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false);
+		foreach (Api.Node param in parameters) {
+			if (((Api.FormalParameter) param).name == name) {
+				return (Api.FormalParameter) param;
+			}
+		}
+
+		return null;
+	}
+
+	private inline string? get_cparameter_name (string[] param_names, int length_pos) {
+		if (length_pos < 0 || param_names.length < length_pos) {
+			return null;
+		}
+
+		return param_names[length_pos];
+	}
+
+	private void attach_comment (string cname, Api.GirSourceComment? comment, string[]? param_names = null, ImplicitParameterPos[]? destroy_notifies = null, ImplicitParameterPos[]? closures = null, ImplicitParameterPos[]? array_lengths = null, int array_length_ret = -1) {
 		if (comment == null) {
 			return ;
 		}
@@ -75,6 +104,39 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 			return;
 		}
 
+		if (param_names != null) {
+			foreach (ImplicitParameterPos pos in destroy_notifies) {
+				Api.FormalParameter? param = find_parameter (node, param_names[pos.parameter]);
+				if (param == null) {
+					continue ;
+				}
+
+				param.implicit_destroy_cparameter_name = get_cparameter_name (param_names, pos.position);
+			}
+
+			foreach (ImplicitParameterPos pos in closures) {
+				Api.FormalParameter? param = find_parameter (node, param_names[pos.parameter]);
+				if (param == null) {
+					continue ;
+				}
+
+				param.implicit_closure_cparameter_name = get_cparameter_name (param_names, pos.position);
+			}
+
+			foreach (ImplicitParameterPos pos in array_lengths) {
+				Api.FormalParameter? param = find_parameter (node, param_names[pos.parameter]);
+				if (param == null) {
+					continue ;
+				}
+
+				param.implicit_array_length_cparameter_name = get_cparameter_name (param_names, pos.position);
+			}
+
+			if (node is Api.Callable) {
+				((Api.Callable) node).implicit_array_length_cparameter_name = get_cparameter_name (param_names, array_length_ret);
+			}
+		}
+
 		Content.Comment? content = this.parser.parse (node, comment);
 		if (content == null) {
 			return;
@@ -83,6 +145,10 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 		node.documentation = content;
 	}
 
+	private void warning (string message) {
+		reporter.warning (this.file.relative_path, this.begin.line, this.begin.column, this.end.column, this.reader.get_line_content (this.begin.line), message);
+	}
+
 	private void error (string message) {
 		reporter.error (this.file.relative_path, this.begin.line, this.begin.column, this.end.column, this.reader.get_line_content (this.begin.line), message);
 	}
@@ -299,20 +365,39 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 		end_element ("member");
 	}
 
-	private void parse_return_value (out Api.SourceComment? comment = null) {
+	private void parse_return_value (out Api.SourceComment? comment, out int array_length_ret) {
 		start_element ("return-value");
 		next ();
 
 		comment = parse_doc ();
 
-		parse_type ();
+		parse_type (out array_length_ret);
 
 		end_element ("return-value");
 	}
 
-	private void parse_parameter (out Api.SourceComment? comment, out string param_name) {
+	private void parse_parameter (out Api.SourceComment? comment, out string param_name, out int destroy_pos, out int closure_pos, out int array_length_pos) {
 		start_element ("parameter");
 		param_name = reader.get_attribute ("name");
+		array_length_pos = -1;
+		destroy_pos = -1;
+		closure_pos = -1;
+
+		string? closure = reader.get_attribute ("closure");
+		if (closure != null) {
+			closure_pos = int.parse (closure);
+			if (closure_pos < 0) {
+				warning ("invalid closure position");
+			}
+		}
+
+		string? destroy = reader.get_attribute ("destroy");
+		if (destroy != null) {
+			destroy_pos = int.parse (destroy);
+			if (destroy_pos < 0) {
+				warning ("invalid destroy position");
+			}
+		}
 		next ();
 
 		comment = parse_doc ();
@@ -324,14 +409,28 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 
 			end_element ("varargs");
 		} else {
-			parse_type ();
+			parse_type (out array_length_pos);
 		}
 
 		end_element ("parameter");
 	}
 
-	private void parse_type () {
-		skip_element ();
+	private void parse_type (out int array_length_pos = null) {
+		array_length_pos = -1;
+
+		if (reader.name == "array") {
+			string? length = reader.get_attribute ("length");
+			if (length != null) {
+				array_length_pos = int.parse (length);
+				if (array_length_pos < 0) {
+					warning ("invalid array lenght position");
+				}
+			}
+
+			skip_element ();
+		} else {
+			skip_element ();
+		}
 	}
 
 	private void parse_record () {
@@ -508,9 +607,15 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 
 		Api.GirSourceComment? comment = parse_symbol_doc ();
 
+		ImplicitParameterPos[] destroy_notifies = new ImplicitParameterPos[0];
+		ImplicitParameterPos[] array_lengths = new ImplicitParameterPos[0];
+		ImplicitParameterPos[] closures = new ImplicitParameterPos[0];
+		string[] param_names = new string[0];
+		int array_length_ret = -1;
+
 		if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "return-value") {
 			Api.SourceComment? return_comment;
-			parse_return_value (out return_comment);
+			parse_return_value (out return_comment, out array_length_ret);
 			if (return_comment != null) {
 				if (comment == null) {
 					comment = new Api.GirSourceComment ("", file, begin.line, begin.column, end.line, end.column);
@@ -524,11 +629,27 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 			start_element ("parameters");
 			next ();
 
-			while (current_token == MarkupTokenType.START_ELEMENT) {
+			for (int pcount = 0; current_token == MarkupTokenType.START_ELEMENT; pcount++) {
 				Api.SourceComment? param_comment;
+				int array_length_pos;
+				int destroy_pos;
+				int closure_pos;
 				string? param_name;
 
-				parse_parameter (out param_comment, out param_name);
+				parse_parameter (out param_comment, out param_name, out destroy_pos, out closure_pos, out array_length_pos);
+				param_names += param_name;
+
+				if (destroy_pos >= 0 && pcount != destroy_pos) {
+					destroy_notifies += ImplicitParameterPos (pcount, destroy_pos);
+				}
+
+				if (closure_pos >= 0 && pcount != closure_pos) {
+					closures += ImplicitParameterPos (pcount, closure_pos);
+				}
+
+				if (array_length_pos >= 0 && pcount != destroy_pos) {
+					array_lengths += ImplicitParameterPos (pcount, array_length_pos);
+				}
 
 				if (param_comment != null) {
 					if (comment == null) {
@@ -541,7 +662,7 @@ public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
 			end_element ("parameters");
 		}
 
-		attach_comment (c_identifier, comment);
+		attach_comment (c_identifier, comment, param_names, destroy_notifies, closures, array_lengths, array_length_ret);
 		end_element (element_name);
 	}
 
diff --git a/src/libvaladoc/taglets/tagletlink.vala b/src/libvaladoc/taglets/tagletlink.vala
index 49699a5..d49aa4b 100644
--- a/src/libvaladoc/taglets/tagletlink.vala
+++ b/src/libvaladoc/taglets/tagletlink.vala
@@ -84,6 +84,7 @@ public class Valadoc.Taglets.Link : InlineTaglet {
 		link.symbol = _symbol;
 		link.label = symbol_name;
 
+		// TODO: move typeof () to gtkdoc-importer
 		switch (_context) {
 		case SymbolContext.TYPE:
 			Content.Run content = new Content.Run (Run.Style.MONOSPACED);
diff --git a/src/libvaladoc/taglets/tagletparam.vala b/src/libvaladoc/taglets/tagletparam.vala
index 36a21eb..78e9d16 100644
--- a/src/libvaladoc/taglets/tagletparam.vala
+++ b/src/libvaladoc/taglets/tagletparam.vala
@@ -21,8 +21,8 @@
  * 	Didier 'Ptitjes Villevalois <ptitjes free fr>
  */
 
-using Gee;
 using Valadoc.Content;
+using Gee;
 
 
 public class Valadoc.Taglets.Param : InlineContent, Taglet, Block {
@@ -40,11 +40,21 @@ public class Valadoc.Taglets.Param : InlineContent, Taglet, Block {
 		});
 	}
 
-
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
 		// Check for the existence of such a parameter
+		unowned string? implicit_return_array_length = null;
+		bool is_implicit = false;
 		this.parameter = null;
 
+		if (container is Api.Callable) {
+			implicit_return_array_length = ((Api.Callable) container).implicit_array_length_cparameter_name;
+		} else {
+			reporter.simple_warning ("%s: %s: @param: warning: @param used outside method/delegate/signal context", file_path, container.get_full_name ());
+			base.check (api_root, container, file_path, reporter, settings);
+			return ;
+		}
+
+
 		if (parameter_name == "...") {
 			Gee.List<Api.Node> params = container.get_children_by_type (Api.NodeType.FORMAL_PARAMETER, false);
 			foreach (Api.Node param in params) {
@@ -65,12 +75,27 @@ public class Valadoc.Taglets.Param : InlineContent, Taglet, Block {
 					break;
 				}
 
+				Api.FormalParameter formalparam = param as Api.FormalParameter;
+				if (formalparam != null && (formalparam.implicit_array_length_cparameter_name == parameter_name || formalparam.implicit_closure_cparameter_name == parameter_name || formalparam.implicit_destroy_cparameter_name == parameter_name)) {
+					is_implicit = true;
+					break;
+				}
+
 				pos++;
 			}
+
+			if (this.parameter == null && (parameter_name == "error" && container.has_children ({Api.NodeType.ERROR_DOMAIN, Api.NodeType.CLASS})
+			   || parameter_name == implicit_return_array_length)) {
+				is_implicit = true;
+			}
 		}
 
 		if (this.parameter == null) {
-			reporter.simple_warning ("%s: %s: @param: warning: Unknown parameter `%s'", file_path, container.get_full_name (), parameter_name);
+			if (is_implicit) {
+				reporter.simple_note ("%s: %s: @param: warning: Implicit parameter `%s' exposed in documentation", file_path, container.get_full_name (), parameter_name);
+			} else {
+				reporter.simple_warning ("%s: %s: @param: warning: Unknown parameter `%s'", file_path, container.get_full_name (), parameter_name);
+			}
 		}
 
 		base.check (api_root, container, file_path, reporter, settings);
diff --git a/src/libvaladoc/taglets/tagletreturn.vala b/src/libvaladoc/taglets/tagletreturn.vala
index 655fb7a..e616791 100644
--- a/src/libvaladoc/taglets/tagletreturn.vala
+++ b/src/libvaladoc/taglets/tagletreturn.vala
@@ -37,10 +37,8 @@ public class Valadoc.Taglets.Return : InlineContent, Taglet, Block {
 		if (container is Api.Method) {
 			creation_method = ((Api.Method) container).is_constructor;
 			type_ref = ((Api.Method) container).return_type;
-		} else if (container is Api.Delegate) {
-			type_ref = ((Api.Delegate) container).return_type;
-		} else if (container is Api.Signal) {
-			type_ref = ((Api.Signal) container).return_type;
+		} else if (container is Api.Callable) {
+			type_ref = ((Api.Callable) container).return_type;
 		} else {
 			reporter.simple_warning ("%s: %s: @return: warning: @return used outside method/delegate/signal context", file_path, container.get_full_name ());
 		}
diff --git a/src/valadoc/valadoc.vala b/src/valadoc/valadoc.vala
index 7c6bdba..cca16b1 100644
--- a/src/valadoc/valadoc.vala
+++ b/src/valadoc/valadoc.vala
@@ -198,6 +198,8 @@ public class ValaDoc : Object {
 	private int run (ErrorReporter reporter) {
 		// settings:
 		var settings = new Valadoc.Settings ();
+		reporter.settings = settings;
+
 		settings.pkg_name = this.get_pkg_name ();
 		settings.gir_namespace = this.gir_namespace;
 		settings.gir_version = this.gir_version;



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