[valadoc] libvaladoc: documentation importer
- From: Florian Brosch <flobrosch src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [valadoc] libvaladoc: documentation importer
- Date: Wed, 10 Feb 2010 01:14:35 +0000 (UTC)
commit f8e77a81fb42796078106cf891332d06f31ff8c1
Author: Florian Brosch <flo brosch gmail com>
Date: Wed Feb 10 01:25:36 2010 +0100
libvaladoc: documentation importer
src/libvaladoc/content/contentelement.vala | 2 +-
src/libvaladoc/content/taglet.vala | 2 +
src/libvaladoc/importer/documentationimporter.vala | 52 ++
.../importer/valadocdocumentationimporter.vala | 674 ++++++++++++++++++++
src/libvaladoc/importer/valamarkupreader.vala | 269 ++++++++
src/libvaladoc/taglets/tagletdeprecated.vala | 15 +-
src/libvaladoc/taglets/tagletinheritdoc.vala | 13 +-
src/libvaladoc/taglets/tagletlink.vala | 16 +-
src/libvaladoc/taglets/tagletparam.vala | 16 +-
src/libvaladoc/taglets/tagletreturn.vala | 15 +-
src/libvaladoc/taglets/tagletsee.vala | 14 +-
src/libvaladoc/taglets/tagletsince.vala | 14 +-
src/libvaladoc/taglets/tagletthrows.vala | 16 +-
src/vapi/config.vapi | 3 +
14 files changed, 1107 insertions(+), 14 deletions(-)
---
diff --git a/src/libvaladoc/content/contentelement.vala b/src/libvaladoc/content/contentelement.vala
index bddbef3..1cecf85 100755
--- a/src/libvaladoc/content/contentelement.vala
+++ b/src/libvaladoc/content/contentelement.vala
@@ -28,7 +28,7 @@ public abstract class Valadoc.Content.ContentElement : Object {
public virtual void configure (Settings settings, ResourceLocator locator) {
}
- public abstract void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter);
+ public abstract void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings);
public abstract void accept (ContentVisitor visitor);
diff --git a/src/libvaladoc/content/taglet.vala b/src/libvaladoc/content/taglet.vala
index 503cb7c..b8b1f15 100755
--- a/src/libvaladoc/content/taglet.vala
+++ b/src/libvaladoc/content/taglet.vala
@@ -25,6 +25,8 @@ using Gee;
public interface Valadoc.Content.Taglet : ContentElement {
+ public abstract void xml_importer_parer_rule (Xml.DocumentationImporter importer);
+
public abstract Rule? get_parser_rule (Rule run_rule);
}
diff --git a/src/libvaladoc/importer/documentationimporter.vala b/src/libvaladoc/importer/documentationimporter.vala
new file mode 100644
index 0000000..d19f019
--- /dev/null
+++ b/src/libvaladoc/importer/documentationimporter.vala
@@ -0,0 +1,52 @@
+/* resourcelocator.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * 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 Gee;
+
+
+public abstract class Valadoc.DocumentationImporter : Object, ResourceLocator {
+ protected ErrorReporter errorreporter;
+ protected ModuleLoader modules;
+ protected Settings settings;
+ protected Api.Tree tree;
+
+ protected Content.ContentFactory factory;
+
+
+ public DocumentationImporter (Api.Tree tree, ModuleLoader modules, Settings settings, ErrorReporter errorreporter) {
+ factory = new Content.ContentFactory (settings, this, modules);
+
+ this.errorreporter = errorreporter;
+ this.settings = settings;
+ this.modules = null;
+ this.tree = tree;
+ }
+
+ public virtual string resolve (string path) {
+ return path;
+ }
+
+ public abstract bool process (string filename, Settings settings, Api.Package package);
+}
+
+
diff --git a/src/libvaladoc/importer/valadocdocumentationimporter.vala b/src/libvaladoc/importer/valadocdocumentationimporter.vala
new file mode 100644
index 0000000..2321d12
--- /dev/null
+++ b/src/libvaladoc/importer/valadocdocumentationimporter.vala
@@ -0,0 +1,674 @@
+/* resourcelocator.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * 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 Gee;
+
+
+
+public class Valadoc.Xml.DocumentationImporter : Valadoc.DocumentationImporter {
+ public Valadoc.MarkupReader reader { get; private set; }
+ private Vala.MarkupTokenType current_token;
+ private Vala.SourceLocation begin;
+ private Vala.SourceLocation end;
+ private string filename;
+
+ public DocumentationImporter (Api.Tree tree, ModuleLoader modules, Settings settings, ErrorReporter errorreporter) {
+ base (tree, modules, settings, errorreporter);
+ }
+
+ public override bool process (string filename, Settings settings, Api.Package package) {
+ this.filename = filename;
+
+ reader = new Valadoc.MarkupReader (filename);
+ skip_xml_header ();
+
+ flush_and_init (package);
+ process_package ();
+ return true;
+ }
+
+
+ // error:
+ public void error (string msg) {
+ string line = reader.get_line_str ();
+ errorreporter.error (reader.filename, reader.line, 0, line.len ()+1, line, msg);
+ }
+
+ public bool node_types_contains (Api.NodeType[] node_types, Api.NodeType node_type) {
+ foreach (var entry in node_types) {
+ if (node_type == entry) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ // Api-Tree helpers:
+ private ArrayList<Object> docstack = new ArrayList<Object> ();
+
+ public void push (Object element) {
+ docstack.add (element);
+ }
+
+ public Object peek (int offset = -1) {
+ assert (docstack.size >= - offset);
+ return docstack.get (docstack.size + offset);
+ }
+
+ public Object pop () {
+ Object node = peek ();
+ docstack.remove_at (docstack.size - 1);
+ return node;
+ }
+
+ private string serialize_api_stack () {
+ var stack = new StringBuilder ();
+ bool first = true;
+
+ foreach (Object obj in docstack) {
+ if (first == false) {
+ stack.append_c ('.');
+ }
+ var name = ((Api.Node)obj).name;
+ stack.append ((name == null)? "(null)" : name);
+ first = false;
+ }
+
+ return stack.str;
+ }
+
+ public bool push_node (string? name, Api.NodeType[] node_types) {
+ if (name == null) {
+ name = "";
+ }
+
+ Api.Node last_node = (Api.Node) peek ();
+
+ var node = last_node.find_by_name (name);
+ if (node == null) {
+ error ("The referenced node `%s.%s' does not exist".printf (serialize_api_stack (), name));
+ return false;
+ }
+
+ if (!node_types_contains (node_types, node.node_type)) {
+ error ("The referenced node has the wrong type");
+ return false;
+ }
+
+ push (node);
+ return true;
+ }
+
+ public void flush_and_init (Valadoc.Api.Package pkg) {
+ docstack.clear ();
+ push (pkg);
+ }
+
+
+
+ // XML-Helpers:
+ public inline void skip_xml_header () {
+ next ();
+ next ();
+ next ();
+ }
+
+ public string get_text () {
+ if (current_token == Vala.MarkupTokenType.TEXT) {
+ string? text = reader.text;
+ next ();
+ return text;
+ }
+
+ return "";
+ }
+
+ public void next () {
+ current_token = reader.read_token (out begin, out end);
+ }
+
+ public void start_element (string name) {
+ if (current_token != Vala.MarkupTokenType.START_ELEMENT || reader.name != name) {
+ error ("expected start element of `%s'\n".printf (name));
+ }
+ }
+
+ public void end_element (string name) {
+ if (current_token != Vala.MarkupTokenType.END_ELEMENT || reader.name != name) {
+ error ("expected end element of `%s'\n".printf (name));
+ }
+ next ();
+ }
+
+ public void process_unknown_element () {
+ error ("unknown element `%s'\n".printf (reader.name));
+ next ();
+ }
+
+
+
+ // parse api:
+ public void process_node (string name, Valadoc.Api.NodeType[] node_types) {
+ start_element (name);
+
+ var tmp = push_node (reader.get_attribute ("name"), node_types);
+ next ();
+
+ if (!tmp) {
+ return ;
+ }
+
+
+ int documentation = 0;
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "documentation" && documentation == 0) {
+ process_documentation ();
+ documentation++;
+ } else if (reader.name == "method") {
+ process_method ();
+ } else if (reader.name == "class") {
+ process_class ();
+ } else if (reader.name == "field") {
+ process_field ();
+ } else if (reader.name == "constant") {
+ process_constant ();
+ } else if (reader.name == "signal") {
+ process_signal ();
+ } else if (reader.name == "delegate") {
+ process_delegate ();
+ } else if (reader.name == "struct") {
+ process_struct ();
+ } else if (reader.name == "interface") {
+ process_interface ();
+ } else if (reader.name == "error-domain") {
+ process_error_domain ();
+ } else if (reader.name == "enum") {
+ process_enum ();
+ } else if (reader.name == "namespace") {
+ process_namespace ();
+ } else if (reader.name == "property") {
+ process_property ();
+ } else if (reader.name == "enum-value") {
+ process_enum_value ();
+ } else if (reader.name == "error-code") {
+ process_error_code ();
+ } else {
+ process_unknown_element ();
+ break;
+ }
+ }
+
+ end_element (name);
+ pop ();
+ }
+
+ public void process_package () {
+ start_element ("package");
+ next ();
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "namespace") {
+ process_namespace ();
+ } else {
+ process_unknown_element ();
+ break;
+ }
+ }
+
+ end_element ("package");
+ }
+
+ public void process_namespace () {
+ process_node ("namespace", {Api.NodeType.NAMESPACE});
+ }
+
+ public void process_interface () {
+ process_node ("interface", {Api.NodeType.INTERFACE});
+ }
+
+ public void process_class () {
+ process_node ("class", {Api.NodeType.CLASS});
+ }
+
+ public void process_struct () {
+ process_node ("struct", {Api.NodeType.STRUCT});
+ }
+
+ public void process_property () {
+ process_node ("property", {Api.NodeType.PROPERTY});
+ }
+
+ public void process_field () {
+ process_node ("field", {Api.NodeType.FIELD});
+ }
+
+ public void process_constant () {
+ process_node ("constant", {Api.NodeType.CONSTANT});
+ }
+
+ public void process_delegate () {
+ process_node ("delegate", {Api.NodeType.DELEGATE});
+ }
+
+ public void process_signal () {
+ process_node ("signal", {Api.NodeType.SIGNAL});
+ }
+
+ public void process_method () {
+ process_node ("method", {Api.NodeType.METHOD, Api.NodeType.STATIC_METHOD, Api.NodeType.CREATION_METHOD});
+ }
+
+ public void process_error_domain () {
+ process_node ("error-domain", {Api.NodeType.ERROR_DOMAIN});
+ }
+
+ public void process_error_code () {
+ process_node ("error-code", {Api.NodeType.ERROR_CODE});
+ }
+
+ public void process_enum () {
+ process_node ("enum", {Api.NodeType.ENUM});
+ }
+
+ public void process_enum_value () {
+ process_node ("enum-value", {Api.NodeType.ENUM_VALUE});
+ }
+
+
+ // parse documentation:
+ public void process_text () {
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT || current_token == Vala.MarkupTokenType.TEXT) {
+ if (current_token == Vala.MarkupTokenType.TEXT) {
+ ((Content.InlineContent) peek ()).content.add (factory.create_text (get_text ()));
+ continue;
+ }
+
+ if (reader.name == "inline-taglet") {
+ process_inline_taglet ();
+ } else if (reader.name == "source-code") {
+ process_source_code ();
+ } else if (reader.name == "embedded") {
+ process_embedded ();
+ } else if (reader.name == "link") {
+ process_link ();
+ } else if (reader.name == "run") {
+ process_run ();
+ } else if (reader.name == "br") {
+ ((Content.InlineContent) peek ()).content.add (factory.create_text (get_text ()));
+ ((Content.InlineContent) peek ()).content.add (factory.create_text ("\n"));
+ next ();
+ } else {
+ process_unknown_element ();
+ break;
+ }
+ }
+ }
+
+
+ public void process_source_code () {
+ start_element ("source-code");
+
+ var src = factory.create_source_code ();
+ ((Content.InlineContent) peek ()).content.add (src);
+
+ string? langstr = reader.get_attribute ("language");
+ if (langstr != null) {
+ var lang = Content.SourceCode.Language.from_string (langstr);
+ if (lang != null) {
+ src.language = lang;
+ } else {
+ error ("missing language-attribute in `source-code'");
+ }
+ }
+
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.TEXT) {
+ src.code = get_text ();
+ } else {
+ src.code = "\n";
+ }
+
+ end_element ("source-code");
+ }
+
+ public void process_embedded () {
+ start_element ("embedded");
+ string? caption = reader.get_attribute ("caption");
+ string? url = reader.get_attribute ("url");
+ if (url != null) {
+ var embedded = factory.create_embedded ();
+ embedded.url = Path.build_filename (Path.get_dirname (this.filename), url);
+ embedded.caption = caption;
+
+ ((Content.InlineContent) peek ()).content.add (embedded);
+ } else {
+ error ("missing url-attribute in `embedded'");
+ }
+
+ next ();
+ end_element ("embedded");
+ }
+
+
+ public void process_link () {
+ start_element ("link");
+
+ string? url = reader.get_attribute ("url");
+ if (url == null) {
+ error ("missing url-attribute in `link'");
+ }
+
+ next ();
+
+ var link = factory.create_link ();
+ ((Content.InlineContent) peek ()).content.add (link);
+ link.url = url;
+ push (link);
+
+ process_text ();
+
+ pop ();
+ end_element ("link");
+ }
+
+
+ public void process_run () {
+ start_element ("run");
+
+
+ Content.Run.Style? style = null;
+
+ var stylestr = reader.get_attribute ("style");
+ if (stylestr == null || (style = Content.Run.Style.from_string (stylestr)) == null) {
+ error ("invalid style attribute 'style' in `run'");
+ }
+
+ var run = factory.create_run (style);
+ ((Content.InlineContent) peek ()).content.add (run);
+ push (run);
+
+ next ();
+
+ process_text ();
+
+ pop ();
+ end_element ("run");
+ }
+
+
+ public void process_paragraph () {
+ start_element ("paragraph");
+ next ();
+
+ var paragraph = factory.create_paragraph ();
+ ((Content.BlockContent) peek ()).content.add (paragraph);
+ push (paragraph);
+
+ process_text ();
+
+ pop ();
+ end_element ("paragraph");
+ }
+
+
+ public void process_headline () {
+ start_element ("headline");
+
+ string levelstr = reader.get_attribute ("level");
+ int level = (levelstr != null)? levelstr.to_int () : 1;
+ next ();
+
+ string text = get_text ();
+
+
+ end_element ("headline");
+
+ if (level > 1 && text != null && text != "") {
+ var headline = factory.create_headline ();
+ headline.content.add (factory.create_text (text));
+ headline.level = level;
+
+ ((Content.BlockContent) peek ()).content.add (headline);
+ }
+ }
+
+ public void process_inline_taglet () {
+ start_element ("inline-taglet");
+ var tagname = reader.get_attribute ("name");
+ var tag = factory.create_taglet (tagname);
+ if (tag != null && tag is Content.InlineTaglet) {
+ ((Content.InlineContent) peek ()).content.add ((Content.InlineTaglet) tag);
+ tag.xml_importer_parer_rule (this);
+ } else {
+ error ("Inline-Taglet not found: %s".printf (tagname));
+ next ();
+ }
+ }
+
+ public void process_taglet () {
+ start_element ("taglet");
+ var tagname = reader.get_attribute ("name");
+ var tag = factory.create_taglet (tagname);
+
+ if (tag != null) {
+ ((Content.Comment) peek ()).taglets.add (tag);
+ tag.xml_importer_parer_rule (this);
+ } else {
+ error ("Taglet not found: %s\n".printf (tagname));
+ next ();
+ }
+ }
+
+ public void process_taglets () {
+ start_element ("taglets");
+ next ();
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "taglet") {
+ process_taglet ();
+ } else {
+ process_unknown_element ();
+ break;
+ }
+ }
+
+ end_element ("taglets");
+ }
+
+
+ public void process_table_cell () {
+ start_element ("table-cell");
+
+ var cell = factory.create_table_cell ();
+ ((Content.TableRow) peek ()).cells.add (cell);
+ push (cell);
+
+ string tmpstr = reader.get_attribute ("colspan");
+ int colspan = (tmpstr == null) ? 1 : tmpstr.to_int ();
+ if (colspan >= 1) {
+ cell.colspan = colspan;
+ } else {
+ colspan = 1;
+ }
+
+ tmpstr = reader.get_attribute ("rowspan");
+ int rowspan = (tmpstr == null) ? 1 : tmpstr.to_int ();
+ if (rowspan >= 1) {
+ cell.rowspan = rowspan;
+ } else {
+ cell.rowspan = 1;
+ }
+
+ tmpstr = reader.get_attribute ("horizontal-align");
+ if (tmpstr != null) {
+ var horizontal_align = Content.HorizontalAlign.from_string (tmpstr);
+ if (horizontal_align != null) {
+ cell.horizontal_align = horizontal_align;
+ } else {
+ error ("missing attribute horizontal-align in `table-cell'");
+ }
+ }
+
+ tmpstr = reader.get_attribute ("vertical-align");
+ if (tmpstr != null) {
+ var vertical_align = Content.VerticalAlign.from_string (tmpstr);
+ if (vertical_align != null) {
+ cell.vertical_align = vertical_align;
+ } else {
+ error ("missing attribute vertical-align in `table-cell'");
+ }
+ }
+
+ next ();
+
+ process_text ();
+
+ pop ();
+ end_element ("table-cell");
+ }
+
+
+ public void process_table_row () {
+ start_element ("table-row");
+ next ();
+
+ var row = factory.create_table_row ();
+ ((Content.Table) peek ()).rows.add (row);
+ push (row);
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "table-cell") {
+ process_table_cell ();
+ } else {
+ process_unknown_element ();
+ break;
+ }
+ }
+
+ pop ();
+ end_element ("table-row");
+ }
+
+
+ public void process_table () {
+ start_element ("table");
+ next ();
+
+ var table = factory.create_table ();
+ ((Content.BlockContent) peek ()).content.add (table);
+ push (table);
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "table-row") {
+ process_table_row ();
+ } else {
+ process_unknown_element ();
+ break;
+ }
+ }
+
+ pop ();
+ end_element ("table");
+ }
+
+
+ public void process_list_item () {
+ start_element ("list-item");
+ next ();
+
+ var item = factory.create_list_item ();
+ ((Content.List) peek ()).items.add (item);
+ push (item);
+
+ process_text ();
+
+ pop ();
+ end_element ("list-item");
+ }
+
+
+ public void process_list () {
+ start_element ("list");
+
+ var list = factory.create_list ();
+ ((Content.BlockContent) peek ()).content.add (list);
+ push (list);
+
+ var att = reader.get_attribute ("bullet-type");
+ if (att != null) {
+ var bullet = Content.List.Bullet.from_string (att);
+ if (bullet != null) {
+ list.bullet = bullet;
+ }
+ }
+
+ next ();
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "list-item") {
+ process_list_item ();
+ } else {
+ process_unknown_element ();
+ break;
+ }
+ }
+
+ pop ();
+ end_element ("list");
+ }
+
+ public void process_documentation () {
+ start_element ("documentation");
+ next ();
+
+ var comment = factory.create_comment ();
+ ((Api.Node) peek ()).documentation = comment;
+ push (comment);
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "paragraph") {
+ process_paragraph ();
+ } else if (reader.name == "headline") {
+ process_headline ();
+ } else if (reader.name == "taglets") {
+ process_taglets ();
+ } else if (reader.name == "table") {
+ process_table ();
+ } else if (reader.name == "list") {
+ process_list ();
+ } else {
+ process_unknown_element ();
+ break;
+ }
+ }
+
+ pop ();
+ comment.check (tree, (Api.Node) peek (), errorreporter, settings);
+ end_element ("documentation");
+ }
+}
+
+
diff --git a/src/libvaladoc/importer/valamarkupreader.vala b/src/libvaladoc/importer/valamarkupreader.vala
new file mode 100644
index 0000000..142100a
--- /dev/null
+++ b/src/libvaladoc/importer/valamarkupreader.vala
@@ -0,0 +1,269 @@
+/* valamarkupreader.vala
+ *
+ * Copyright (C) 2008-2009 Jürg Billeter
+ *
+ * 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:
+ * Jürg Billeter <j bitron ch>
+ */
+
+using Vala;
+using GLib;
+
+// (not completely) Modified version of vala's MarkupReader
+
+/**
+ * Simple reader for a subset of XML.
+ */
+
+public class Valadoc.MarkupReader : Object {
+ public string filename { get; private set; }
+
+ public string name { get; private set; }
+
+ public string text { get; private set; }
+
+ public int column { get; private set; }
+
+ public int line { get; private set; }
+
+ public string get_line_str () {
+ char* pos = line_start+1;
+
+ for (; pos < end && pos[1] != '\n'; pos++);
+
+ return ((string) line_start).substring (1, (long) (pos-line_start));
+ }
+
+ MappedFile mapped_file;
+
+ char* line_start;
+ char* begin;
+ char* current;
+ char* end;
+
+ //int line;
+ //int column;
+
+
+ Map<string,string> attributes = new HashMap<string,string> (str_hash, str_equal);
+ bool empty_element;
+
+ public MarkupReader (string filename) {
+ this.filename = filename;
+
+ try {
+ mapped_file = new MappedFile (filename, false);
+ begin = mapped_file.get_contents ();
+ end = begin + mapped_file.get_length ();
+
+ line_start = begin;
+ current = begin;
+
+ line = 1;
+ column = 1;
+ } catch (FileError e) {
+ Report.error (null, "Unable to map file `%s': %s".printf (filename, e.message));
+ }
+ }
+
+ public string? get_attribute (string attr) {
+ return attributes[attr];
+ }
+
+ string read_name () {
+ char* begin = current;
+ while (current < end) {
+ if (current[0] == ' ' || current[0] == '>'
+ || current[0] == '/' || current[0] == '=') {
+ break;
+ }
+ unichar u = ((string) current).get_char_validated ((long) (end - current));
+ if (u != (unichar) (-1)) {
+ current += u.to_utf8 (null);
+ } else {
+ Report.error (null, "invalid UTF-8 character");
+ }
+ }
+ if (current == begin) {
+ // syntax error: invalid name
+ }
+ return ((string) begin).ndup (current - begin);
+ }
+
+ public MarkupTokenType read_token (out Vala.SourceLocation token_begin, out Vala.SourceLocation token_end) {
+ attributes.clear ();
+
+ if (empty_element) {
+ empty_element = false;
+ return MarkupTokenType.END_ELEMENT;
+ }
+
+ char* start_pos = current;
+ space ();
+
+ MarkupTokenType type = MarkupTokenType.NONE;
+ char* begin = current;
+ token_begin.pos = begin;
+ token_begin.line = line;
+ token_begin.column = column;
+
+ if (current >= end) {
+ type = MarkupTokenType.EOF;
+ } else if (current[0] == '<') {
+ current++;
+ if (current >= end) {
+ // error
+ } else if (current[0] == '?') {
+ // processing instruction
+ } else if (current[0] == '!') {
+ // comment or doctype
+ current++;
+ if (current < end - 1 && current[0] == '-' && current[1] == '-') {
+ // comment
+ current += 2;
+ while (current < end - 2) {
+ if (current[0] == '-' && current[1] == '-' && current[2] == '>') {
+ // end of comment
+ current += 3;
+ break;
+ }
+ current++;
+ }
+
+ // ignore comment, read next token
+ return read_token (out token_begin, out token_end);
+ }
+ } else if (current[0] == '/') {
+ type = MarkupTokenType.END_ELEMENT;
+ current++;
+ name = read_name ();
+ if (current >= end || current[0] != '>') {
+ // error
+ }
+ current++;
+ } else {
+ type = MarkupTokenType.START_ELEMENT;
+ name = read_name ();
+ space ();
+ while (current < end && current[0] != '>' && current[0] != '/') {
+ string attr_name = read_name ();
+ if (current >= end || current[0] != '=') {
+ // error
+ }
+ current++;
+ // FIXME allow single quotes
+ if (current >= end || current[0] != '"') {
+ // error
+ }
+ current++;
+ char* attr_begin = current;
+ while (current < end && current[0] != '"') {
+ unichar u = ((string) current).get_char_validated ((long) (end - current));
+ if (u != (unichar) (-1)) {
+ current += u.to_utf8 (null);
+ } else {
+ Report.error (null, "invalid UTF-8 character");
+ }
+ }
+ // TODO process & > < " '
+ string attr_value = ((string) attr_begin).ndup (current - attr_begin);
+ if (current >= end || current[0] != '"') {
+ // error
+ }
+ current++;
+ attributes.set (attr_name, attr_value);
+ space ();
+ }
+ if (current[0] == '/') {
+ empty_element = true;
+ current++;
+ space ();
+ } else {
+ empty_element = false;
+ }
+ if (current >= end || current[0] != '>') {
+ // error
+ }
+ current++;
+ }
+ } else {
+ var str = new StringBuilder ();
+ char* text_begin = start_pos;
+ while (current < end && current[0] != '<') {
+ unichar u = ((string) current).get_char_validated ((long) (end - current));
+ if (u != (unichar) (-1)) {
+ current += u.to_utf8 (null);
+ } else {
+ Report.error (null, "invalid UTF-8 character");
+ }
+
+ if (u == '&') {
+ str.append_len ((string) text_begin, (long) (current - text_begin - 1));
+ if (((string) current).has_prefix ("apos;")) {
+ str.append_c ('\'');
+ current += 5;
+ } else if (((string) current).has_prefix ("quot;")) {
+ str.append_c ('"');
+ current += 5;
+ } else if (((string) current).has_prefix ("amp;")) {
+ str.append_c ('&');
+ current += 4;
+ } else if (((string) current).has_prefix ("gt;")) {
+ str.append_c ('>');
+ current += 3;
+ } else if (((string) current).has_prefix ("lt;")) {
+ str.append_c ('<');
+ current += 3;
+ } else {
+ str.append_c ('&');
+ }
+ text_begin = current;
+ }
+ }
+ if (text_begin == current && str.len == 0) {
+ // no text
+ // read next token
+ return read_token (out token_begin, out token_end);
+ }
+ str.append_len ((string) text_begin, (long) (current - text_begin));
+ type = MarkupTokenType.TEXT;
+ text = str.str;
+ }
+
+ column += (int) (current - begin);
+
+ token_end.pos = current;
+ token_end.line = line;
+ token_end.column = column - 1;
+
+ return type;
+ }
+
+ void space () {
+ while (current < end && current[0].isspace ()) {
+ if (current[0] == '\n') {
+ line_start = current;
+ line++;
+ column = 0;
+ }
+ current++;
+ column++;
+ }
+ }
+}
+
+
diff --git a/src/libvaladoc/taglets/tagletdeprecated.vala b/src/libvaladoc/taglets/tagletdeprecated.vala
index c627b0e..cdbbdfb 100755
--- a/src/libvaladoc/taglets/tagletdeprecated.vala
+++ b/src/libvaladoc/taglets/tagletdeprecated.vala
@@ -28,8 +28,19 @@ public class Valadoc.Taglets.Deprecated : InlineContent, Taglet, Block {
return run_rule;
}
- public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
- base.check (api_root, container, reporter);
+ public void xml_importer_parer_rule (Xml.DocumentationImporter importer) {
+ importer.start_element ("taglet");
+ importer.push (this);
+ importer.next ();
+
+ importer.process_text ();
+
+ importer.pop ();
+ importer.end_element ("taglet");
+ }
+
+ public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings) {
+ base.check (api_root, container, reporter, settings);
}
public override void accept (ContentVisitor visitor) {
diff --git a/src/libvaladoc/taglets/tagletinheritdoc.vala b/src/libvaladoc/taglets/tagletinheritdoc.vala
index 0e422cc..dd8ab99 100755
--- a/src/libvaladoc/taglets/tagletinheritdoc.vala
+++ b/src/libvaladoc/taglets/tagletinheritdoc.vala
@@ -30,7 +30,18 @@ public class Valadoc.Taglets.InheritDoc : InlineTaglet {
return null;
}
- public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
+ public override void xml_importer_parer_rule (Xml.DocumentationImporter importer) {
+ importer.start_element ("taglet");
+ importer.push (this);
+ importer.next ();
+
+ importer.process_text ();
+
+ importer.pop ();
+ importer.end_element ("taglet");
+ }
+
+ public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings) {
// TODO Check that the container is an override of an abstract symbol
// Also retrieve that abstract symbol _inherited
diff --git a/src/libvaladoc/taglets/tagletlink.vala b/src/libvaladoc/taglets/tagletlink.vala
index dc4f7aa..79005e4 100755
--- a/src/libvaladoc/taglets/tagletlink.vala
+++ b/src/libvaladoc/taglets/tagletlink.vala
@@ -35,14 +35,26 @@ public class Valadoc.Taglets.Link : InlineTaglet {
});
}
- public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
+ public override void xml_importer_parer_rule (Xml.DocumentationImporter importer) {
+ importer.start_element ("inline-taglet");
+ symbol_name = importer.reader.get_attribute ("type");
+ importer.push (this);
+ importer.next ();
+
+ importer.process_text ();
+
+ importer.pop ();
+ importer.end_element ("inline-taglet");
+ }
+
+ public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings) {
_symbol = api_root.search_symbol_str (container, symbol_name);
if (_symbol == null) {
// TODO use ContentElement's source reference
reporter.simple_error ("%s does not exist".printf (symbol_name));
}
- base.check (api_root, container, reporter);
+ base.check (api_root, container, reporter, settings);
}
public override ContentElement produce_content () {
diff --git a/src/libvaladoc/taglets/tagletparam.vala b/src/libvaladoc/taglets/tagletparam.vala
index e6c267a..95719a7 100755
--- a/src/libvaladoc/taglets/tagletparam.vala
+++ b/src/libvaladoc/taglets/tagletparam.vala
@@ -35,10 +35,22 @@ public class Valadoc.Taglets.Param : InlineContent, Taglet, Block {
});
}
- public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
+ public void xml_importer_parer_rule (Xml.DocumentationImporter importer) {
+ importer.start_element ("taglet");
+ parameter_name = importer.reader.get_attribute ("parameter");
+ importer.push (this);
+ importer.next ();
+
+ importer.process_text ();
+
+ importer.pop ();
+ importer.end_element ("taglet");
+ }
+
+ public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings) {
// TODO check for the existence of such a parameter
- base.check (api_root, container, reporter);
+ base.check (api_root, container, reporter, settings);
}
public override void accept (ContentVisitor visitor) {
diff --git a/src/libvaladoc/taglets/tagletreturn.vala b/src/libvaladoc/taglets/tagletreturn.vala
index 52ad502..dbf8de6 100755
--- a/src/libvaladoc/taglets/tagletreturn.vala
+++ b/src/libvaladoc/taglets/tagletreturn.vala
@@ -29,10 +29,21 @@ public class Valadoc.Taglets.Return : InlineContent, Taglet, Block {
return run_rule;
}
- public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
+ public void xml_importer_parer_rule (Xml.DocumentationImporter importer) {
+ importer.start_element ("taglet");
+ importer.push (this);
+ importer.next ();
+
+ importer.process_text ();
+
+ importer.pop ();
+ importer.end_element ("taglet");
+ }
+
+ public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings) {
// TODO check for the existence of a return type
- base.check (api_root, container, reporter);
+ base.check (api_root, container, reporter, settings);
}
public override void accept (ContentVisitor visitor) {
diff --git a/src/libvaladoc/taglets/tagletsee.vala b/src/libvaladoc/taglets/tagletsee.vala
index cce2fc9..62b7a26 100755
--- a/src/libvaladoc/taglets/tagletsee.vala
+++ b/src/libvaladoc/taglets/tagletsee.vala
@@ -34,7 +34,19 @@ public class Valadoc.Taglets.See : ContentElement, Taglet, Block {
});
}
- public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
+ public void xml_importer_parer_rule (Xml.DocumentationImporter importer) {
+ importer.start_element ("taglet");
+ symbol_name = importer.reader.get_attribute ("type");
+ importer.push (this);
+ importer.next ();
+
+ importer.process_text ();
+
+ importer.pop ();
+ importer.end_element ("taglet");
+ }
+
+ public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings) {
symbol = api_root.search_symbol_str (container, symbol_name);
if (symbol == null) {
// TODO use ContentElement's source reference
diff --git a/src/libvaladoc/taglets/tagletsince.vala b/src/libvaladoc/taglets/tagletsince.vala
index 18ea041..62f9bd3 100755
--- a/src/libvaladoc/taglets/tagletsince.vala
+++ b/src/libvaladoc/taglets/tagletsince.vala
@@ -33,7 +33,19 @@ public class Valadoc.Taglets.Since : ContentElement, Taglet, Block {
});
}
- public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
+ public void xml_importer_parer_rule (Xml.DocumentationImporter importer) {
+ importer.start_element ("taglet");
+ version = importer.reader.get_attribute ("version");
+ importer.push (this);
+ importer.next ();
+
+ importer.process_text ();
+
+ importer.pop ();
+ importer.end_element ("taglet");
+ }
+
+ public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings) {
}
public override void accept (ContentVisitor visitor) {
diff --git a/src/libvaladoc/taglets/tagletthrows.vala b/src/libvaladoc/taglets/tagletthrows.vala
index 7bed096..85cec29 100755
--- a/src/libvaladoc/taglets/tagletthrows.vala
+++ b/src/libvaladoc/taglets/tagletthrows.vala
@@ -35,14 +35,26 @@ public class Valadoc.Taglets.Throws : InlineContent, Taglet, Block {
});
}
- public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter) {
+ public void xml_importer_parer_rule (Xml.DocumentationImporter importer) {
+ importer.start_element ("taglet");
+ error_domain_name = importer.reader.get_attribute ("type");
+ importer.push (this);
+ importer.next ();
+
+ importer.process_text ();
+
+ importer.pop ();
+ importer.end_element ("taglet");
+ }
+
+ public override void check (Api.Tree api_root, Api.Node? container, ErrorReporter reporter, Settings settings) {
error_domain = api_root.search_symbol_str (container, error_domain_name);
if (error_domain == null) {
// TODO use ContentElement's source reference
reporter.simple_error ("%s does not exist".printf (error_domain_name));
}
- base.check (api_root, container, reporter);
+ base.check (api_root, container, reporter, settings);
}
public override void accept (ContentVisitor visitor) {
diff --git a/src/vapi/config.vapi b/src/vapi/config.vapi
index 32c2847..dea37b2 100644
--- a/src/vapi/config.vapi
+++ b/src/vapi/config.vapi
@@ -11,5 +11,8 @@ namespace Config {
[CCode (cname = "PACKAGE_DATADIR")]
public const string plugin_dir;
+
+ [CCode (cname = "PACKAGE_VAPIDIR")]
+ public const string vapi_dir;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]