[valadoc] add gir documentation importer
- From: Florian Brosch <flobrosch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [valadoc] add gir documentation importer
- Date: Thu, 2 Sep 2010 03:35:05 +0000 (UTC)
commit 76f8fb19dc8cd090bd69fe0abfd62ac2f2f3fada
Author: Florian Brosch <flo brosch gmail com>
Date: Fri Aug 20 00:04:48 2010 +0200
add gir documentation importer
src/libvaladoc/Makefile.am | 5 +-
src/libvaladoc/api/package.vala | 5 +-
src/libvaladoc/api/tree.vala | 105 ++--
src/libvaladoc/{importer => }/ctyperesolver.vala | 2 +-
.../documentation/documentationparser.vala | 536 +++++++++++++++-
.../documentation/girdocumentationscanner.vala | 610 +++++++++++++++++
src/libvaladoc/html/htmlrenderer.vala | 20 +-
src/libvaladoc/importer/documentationimporter.vala | 9 +-
.../importer/girdocumentationbuilder.vala | 56 ++
.../importer/girdocumentationimporter.vala | 687 ++++++++++++++++++++
src/libvaladoc/parser/tokentype.vala | 118 ++++-
src/libvaladoc/settings.vala | 1 -
src/libvaladoc/taglets/tagletlink.vala | 15 +-
src/libvaladoc/taglets/tagletparam.vala | 2 +-
src/libvaladoc/taglets/tagletsee.vala | 13 +-
src/valadoc/valadoc.vala | 26 +-
16 files changed, 2110 insertions(+), 100 deletions(-)
---
diff --git a/src/libvaladoc/Makefile.am b/src/libvaladoc/Makefile.am
index b769576..d95cd94 100644
--- a/src/libvaladoc/Makefile.am
+++ b/src/libvaladoc/Makefile.am
@@ -30,13 +30,16 @@ libvaladoc_la_VALASOURCES = \
settings.vala \
markupwriter.vala \
devhelp-markupwriter.vala \
+ ctyperesolver.vala \
+ documentation/girdocumentationscanner.vala \
documentation/commentscanner.vala \
documentation/documentation.vala \
documentation/documentationparser.vala \
documentation/wiki.vala \
documentation/wikiscanner.vala \
+ importer/girdocumentationimporter.vala \
importer/documentationimporter.vala \
- importer/ctyperesolver.vala \
+ importer/girdocumentationbuilder.vala \
api/array.vala \
api/class.vala \
api/constant.vala \
diff --git a/src/libvaladoc/api/package.vala b/src/libvaladoc/api/package.vala
index 16ddd3c..031ad40 100644
--- a/src/libvaladoc/api/package.vala
+++ b/src/libvaladoc/api/package.vala
@@ -22,6 +22,7 @@
using Gee;
using Valadoc.Content;
+using Valadoc.Importer;
public class Valadoc.Api.Package : Node {
private ArrayList<Vala.SourceFile> vfiles = new ArrayList<Vala.SourceFile> ();
@@ -110,10 +111,6 @@ public class Valadoc.Api.Package : Node {
.get ();
}
- internal void import_documentation (string path, Settings settings, DocumentationImporter importer) {
- importer.process (path, settings, this);
- }
-
internal Namespace get_namespace (Tree root, Vala.Symbol symbol) {
Vala.Symbol namespace_symbol = symbol;
while (!(namespace_symbol is Vala.Namespace)) {
diff --git a/src/libvaladoc/api/tree.vala b/src/libvaladoc/api/tree.vala
index 3a90dd5..7a3d698 100644
--- a/src/libvaladoc/api/tree.vala
+++ b/src/libvaladoc/api/tree.vala
@@ -31,23 +31,18 @@ public class Valadoc.Api.Tree {
private ArrayList<Package> packages = new ArrayList<Package>();
private Package source_package = null;
private Settings settings;
- private Vala.CodeContext context;
private ErrorReporter reporter;
private Package sourcefiles = null;
private CTypeResolver _cresolver = null;
- public WikiPageTree? wikitree {
+ internal Vala.CodeContext context {
private set;
get;
}
- public CTypeResolver cresolver {
- get {
- if (_cresolver == null) {
- _cresolver = new CTypeResolver (this);
- }
- return _cresolver;
- }
+ public WikiPageTree? wikitree {
+ private set;
+ get;
}
public Collection<Package> get_package_list () {
@@ -117,6 +112,14 @@ public class Valadoc.Api.Tree {
return null;
}
+ public Node? search_symbol_cstr (string cname) {
+ if (_cresolver == null) {
+ _cresolver = new CTypeResolver (this);
+ }
+
+ return _cresolver.resolve_symbol (cname);
+ }
+
public Node? search_symbol_str (Node? element, string symname) {
string[] path = split_name (symname);
@@ -208,6 +211,25 @@ public class Valadoc.Api.Tree {
}
}
+ private void add_deps (string file_path, string pkg_name) {
+ if (FileUtils.test (file_path, FileTest.EXISTS)) {
+ try {
+ string deps_content;
+ ulong deps_len;
+ FileUtils.get_contents (file_path, out deps_content, out deps_len);
+ foreach (string dep in deps_content.split ("\n")) {
+ dep.strip ();
+ if (dep != "") {
+ if (!add_package (dep)) {
+ Vala.Report.error (null, "%s, dependency of %s, not found in specified Vala API directories".printf (dep, pkg_name));
+ }
+ }
+ }
+ } catch (FileError e) {
+ Vala.Report.error (null, "Unable to read dependency file: %s".printf (e.message));
+ }
+ }
+ }
private bool add_package (string pkg) {
if (context.has_package (pkg)) {
@@ -216,7 +238,6 @@ public class Valadoc.Api.Tree {
}
var package_path = context.get_package_path (pkg, settings.vapi_directories);
-
if (package_path == null) {
return false;
}
@@ -230,30 +251,12 @@ public class Valadoc.Api.Tree {
Package vdpkg = new Package (vfile, pkg, true);
this.packages.add (vdpkg);
- var deps_filename = Path.build_filename (Path.get_dirname (package_path), "%s.deps".printf (pkg));
- if (FileUtils.test (deps_filename, FileTest.EXISTS)) {
- try {
- string deps_content;
- ulong deps_len;
- FileUtils.get_contents (deps_filename, out deps_content, out deps_len);
- foreach (string dep in deps_content.split ("\n")) {
- dep.strip ();
- if (dep != "") {
- if (!add_package (dep)) {
- Vala.Report.error (null, "%s, dependency of %s, not found in specified Vala API directories".printf (dep, pkg));
- }
- }
- }
- } catch (FileError e) {
- Vala.Report.error (null, "Unable to read dependency file: %s".printf (e.message));
- }
- }
-
+ add_deps (Path.build_filename (Path.get_dirname (package_path), "%s.deps".printf (pkg)), pkg);
return true;
}
// copied from valacodecontext.vala
- private string? get_file_path (string basename, string data_dir, string[] directories) {
+ private string? get_file_path (string basename, string[] directories) {
string filename = null;
if (directories != null) {
@@ -266,7 +269,7 @@ public class Valadoc.Api.Tree {
}
foreach (string dir in Environment.get_system_data_dirs ()) {
- filename = Path.build_filename (dir, data_dir, basename);
+ filename = Path.build_filename (dir, basename);
if (FileUtils.test (filename, FileTest.EXISTS)) {
return filename;
}
@@ -275,21 +278,6 @@ public class Valadoc.Api.Tree {
return null;
}
- // copied from valacodecontext.vala
- private string? get_external_documentation_path (string pkg) {
- var path = get_file_path (Path.build_filename (pkg, "documentation.xml"), "vala/vapi/documentation", settings.docu_directories);
-
- if (path == null) {
- /* last chance: try the package compiled-in vapi dir */
- var filename = Path.build_filename (Config.vapi_dir, "vapi", "documentation", pkg, "documentation.xml");
- if (FileUtils.test (filename, FileTest.EXISTS)) {
- path = filename;
- }
- }
-
- return path;
- }
-
public void add_depencies (string[] packages) {
foreach (string package in packages) {
if (!add_package (package)) {
@@ -332,12 +320,13 @@ public class Valadoc.Api.Tree {
context.add_source_file (source_file);
} else if (source.has_suffix (".vapi")) {
string file_name = Path.get_basename (source);
- file_name = file_name.ndup ( file_name.size() - ".vapi".size() );
+ file_name = file_name.ndup (file_name.size() - ".vapi".size());
var vfile = new Vala.SourceFile (context, rpath, true);
Package vdpkg = new Package (vfile, file_name);
context.add_source_file (vfile);
this.packages.add (vdpkg);
+ add_deps (Path.build_filename (Path.get_dirname (source), "%s.deps".printf (file_name)), file_name);
} else if (source.has_suffix (".c")) {
context.add_c_source_file (rpath);
} else {
@@ -376,6 +365,15 @@ public class Valadoc.Api.Tree {
return true;
}
+ private Package? find_package_by_name (string name) {
+ foreach (Package pkg in packages) {
+ if (name == pkg.name) {
+ return pkg;
+ }
+ }
+ return null;
+ }
+
private Package? find_package_for_file (Vala.SourceFile vfile) {
foreach (Package pkg in this.packages) {
if (pkg.is_package_for_file (vfile))
@@ -426,15 +424,16 @@ public class Valadoc.Api.Tree {
}
}
- public void import_documentation (DocumentationImporter importer) {
- foreach (Package pkg in this.packages) {
- string? path = (pkg.is_package)? get_external_documentation_path (pkg.name) : null;
+ public void import_documentation (DocumentationImporter importer, string[] packages, string[] import_directories) {
+ foreach (string pkg_name in packages) {
+ string? path = get_file_path ("%s.%s".printf (pkg_name, importer.file_extension), import_directories);
- if (pkg.is_browsable (settings) && path != null) {
- pkg.import_documentation (path, settings, importer);
+ if (path == null) {
+ Vala.Report.error (null, "%s not found in specified import directories".printf (pkg_name));
+ } else {
+ importer.process (path);
}
}
-
}
internal Symbol? search_vala_symbol (Vala.Symbol symbol) {
diff --git a/src/libvaladoc/importer/ctyperesolver.vala b/src/libvaladoc/ctyperesolver.vala
similarity index 98%
rename from src/libvaladoc/importer/ctyperesolver.vala
rename to src/libvaladoc/ctyperesolver.vala
index 83af779..b9641bf 100644
--- a/src/libvaladoc/importer/ctyperesolver.vala
+++ b/src/libvaladoc/ctyperesolver.vala
@@ -24,7 +24,7 @@
using Valadoc.Api;
using Gee;
-public class Valadoc.Importer.CTypeResolver : Visitor {
+public class Valadoc.CTypeResolver : Visitor {
private Map<string, Api.Node> nodes = new HashMap<string, Api.Node> ();
public CTypeResolver (Api.Tree tree) {
diff --git a/src/libvaladoc/documentation/documentationparser.vala b/src/libvaladoc/documentation/documentationparser.vala
index 869c5e0..0c735c9 100644
--- a/src/libvaladoc/documentation/documentationparser.vala
+++ b/src/libvaladoc/documentation/documentationparser.vala
@@ -21,6 +21,7 @@
*/
using Valadoc.Content;
+using Valadoc.Importer;
using Gee;
@@ -42,7 +43,16 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
_comment_parser = new Parser (_settings, _comment_scanner, _reporter);
_comment_scanner.set_parser (_comment_parser);
- init_rules ();
+ _gir_scanner = new GirDocumentationScanner (_settings);
+ _gir_parser = new Parser (_settings, _gir_scanner, _reporter);
+ _gir_scanner.set_parser (_gir_parser);
+
+ _gir_taglet_scanner = new GirDocumentationScanner (_settings);
+ _gir_taglet_parser = new Parser (_settings, _gir_taglet_scanner, _reporter);
+ _gir_taglet_scanner.set_parser (_gir_taglet_parser);
+
+ init_valadoc_rules ();
+ init_girdoc_rules ();
}
private Settings _settings;
@@ -51,13 +61,17 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
private ModuleLoader _modules;
private ContentFactory _factory;
+ private GirDocumentationScanner _gir_taglet_scanner;
+ private GirDocumentationScanner _gir_scanner;
private WikiScanner _wiki_scanner;
private CommentScanner _comment_scanner;
+ private Parser _gir_parser;
+ private Parser _gir_taglet_parser;
private Parser _wiki_parser;
private Parser _comment_parser;
private Parser _parser;
- private WikiScanner _scanner;
+ private Scanner _scanner;
public Comment? parse (Api.Node element, Vala.Comment source_comment) {
weak string content = source_comment.content;
@@ -71,6 +85,48 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
}
}
+ public Comment? parse_gir_comment (Api.Node element, GirDocumentationBuilder doc) {
+ try {
+ _stack.clear ();
+
+ if (doc.content != null) {
+ _parser = _gir_parser;
+ _scanner = _gir_scanner;
+ _gir_parser.parse (doc.content, doc.source_reference.file.filename, doc.source_reference.first_line, doc.source_reference.first_column);
+ } else {
+ push (_factory.create_comment ());
+ }
+
+
+ _parser = _gir_taglet_parser;
+ _scanner = _gir_taglet_scanner;
+
+ if (doc.return_value != null && !(element is Api.Method && ((Api.Method) element).is_constructor)) {
+ push (_factory.create_taglet ("return"));
+ _gir_taglet_parser.parse (doc.return_value.content, doc.return_value.source_reference.file.filename, doc.return_value.source_reference.first_line, doc.return_value.source_reference.first_column);
+ }
+
+ var iter = doc.parameters.map_iterator ();
+ for (iter.next (); iter.has_next (); iter.next ()) {
+ var val = iter.get_value ();
+ var key = iter.get_key ();
+ if (key != "self") {
+ var param = _factory.create_taglet ("param") as Taglets.Param;
+ param.parameter_name = key;
+ push (param);
+ _gir_taglet_parser.parse (val.content, val.source_reference.file.filename, val.source_reference.first_line, val.source_reference.first_column);
+ }
+ }
+
+ var doc_comment = (Comment) pop ();
+ doc_comment.check (_tree, element, _reporter, _settings);
+
+ return doc_comment;
+ } catch (ParserError error) {
+ return null;
+ }
+ }
+
public Page? parse_wikipage (WikiPage page, Api.Package pkg) {
if (page.documentation != null) {
return page.documentation;
@@ -216,7 +272,465 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
text.content += str;
}
- private void init_rules () {
+ private void gir_append_link (Token token) throws ParserError {
+ var taglet = _factory.create_taglet ("link") as Taglets.Link;
+ if (!(taglet is Inline)) {
+ _parser.error ("Invalid taglet in this context: link");
+ }
+ taglet.symbol_name = "c::"+token.to_string ();
+ push (taglet);
+ }
+
+ private bool _gir_is_first_paragraph = true;
+
+ private void init_girdoc_rules () {
+ StubRule run = new StubRule ();
+ run.set_name ("Run");
+
+ TokenType.Action add_text = (token) => {
+ add_content_string (token.to_string ());
+ };
+
+ TokenType dot = TokenType.GTKDOC_DOT.action ((token) => { add_content_string ("."); });
+ TokenType word = TokenType.GTKDOC_ANY_WORD.action (add_text);
+ TokenType space = TokenType.GTKDOC_SPACE.action (add_text);
+ TokenType newline = TokenType.GTKDOC_EOL.action ((token) => { add_content_string (" "); });
+ Rule unprinted_space = Rule.one_of ({ space.action ((token) => {}), newline.action ((token) => {}) });
+ Rule unprinted_spaces = Rule.many ({ unprinted_space });
+ Rule optional_unprinted_spaces = Rule.option ({ unprinted_spaces });
+
+ Rule raw_text = Rule.many ({
+ Rule.one_of ({
+ word, space, newline, dot
+ })
+ .set_reduce (() => { ((InlineContent) peek ()).content.add ((Inline) pop ()); })
+ })
+ .set_name ("RawText");
+
+ Rule run_with_dot = Rule.many ({
+ Rule.one_of ({
+ run, dot
+ })
+ .set_reduce (() => { ((InlineContent) peek ()).content.add ((Inline) pop ()); })
+ })
+ .set_name ("FormatedText");
+
+ Rule xml_comment_raw = Rule.seq ({
+ TokenType.GTKDOC_XML_COMMENT_START,
+ Rule.option ({
+ Rule.many ({
+ Rule.one_of ({
+ word.action ((token) => {}),
+ space.action ((token) => {}),
+ newline.action ((token) => {}),
+ dot.action ((token) => {})
+ //TODO
+ })
+ })
+ }),
+ TokenType.GTKDOC_XML_COMMENT_END
+ });
+
+
+ Rule xml_comment = Rule.seq ({
+ xml_comment_raw
+ })
+ .set_name ("XmlComment")
+ .set_start (() => { push (_factory.create_text ("")); });
+
+
+ Rule word_or_function = Rule.seq ({
+ TokenType.GTKDOC_ANY_WORD.action ((token) => { push (token); }),
+ Rule.option ({
+ Rule.many ({
+ Rule.one_of ({
+ space.action ((token) => {
+ if (((Token) peek ()).is_word) {
+ push (token);
+ }
+ }),
+ xml_comment_raw
+ })
+ })
+ }),
+ Rule.option ({
+ TokenType.GTKDOC_FUNCTION_BRACKETS.action ((token) => {
+ var last_token = (Token) pop ();
+ if (!last_token.is_word) {
+ last_token = (Token) pop ();
+ }
+
+ gir_append_link (last_token);
+ })
+ }).set_skip (() => {
+ var last_token = (Token) pop ();
+ if (last_token.is_word) {
+ add_content_string (last_token.to_string ());
+ } else {
+ add_content_string (((Token) pop ()).to_string ());
+ add_content_string (last_token.to_string ());
+ }
+ })
+ });
+
+ Rule node_link = Rule.one_of ({
+ Rule.seq ({
+ TokenType.GTKDOC_SYMBOL,
+ word.action ((token) => {
+ switch (token.to_string ()) {
+ case "FALSE":
+ case "TRUE":
+ case "NULL":
+ var myrun = _factory.create_run (Run.Style.MONOSPACED);
+ var mytext = _factory.create_text ();
+ mytext.content = token.to_string ().down ();
+ myrun.content.add (mytext);
+ push (myrun);
+ break;
+
+ default:
+ gir_append_link (token);
+ break;
+ }
+ })
+ })
+ })
+ .set_name ("TypeLink");
+
+ Rule link_element = Rule.seq ({
+ TokenType.GTKDOC_LINK_ELEMENT_OPEN,
+ run_with_dot,
+ TokenType.GTKDOC_LINK_ELEMENT_CLOSE
+ })
+ .set_name ("Link")
+ .set_start (() => { push (_factory.create_run (Run.Style.NONE)); });
+
+ Rule filename_element = Rule.seq ({
+ TokenType.GTKDOC_FILENAME_ELEMENT_OPEN,
+ raw_text,
+ TokenType.GTKDOC_FILENAME_ELEMENT_CLOSE
+ })
+ .set_name ("Filename")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); });
+
+ Rule envar_element = Rule.seq ({
+ TokenType.GTKDOC_ENVAR_ELEMENT_OPEN,
+ run_with_dot,
+ TokenType.GTKDOC_ENVAR_ELEMENT_CLOSE
+ })
+ .set_name ("Envar")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); });
+
+ Rule emphasis_element = Rule.seq ({
+ TokenType.GTKDOC_EMPHASIS_ELEMENT_OPEN,
+ run_with_dot,
+ TokenType.GTKDOC_EMPHASIS_ELEMENT_CLOSE
+ })
+ .set_name ("Emphasis")
+ .set_start (() => { push (_factory.create_run (Run.Style.ITALIC)); });
+
+ Rule option_element = Rule.seq ({
+ TokenType.GTKDOC_OPTION_ELEMENT_OPEN,
+ run_with_dot,
+ TokenType.GTKDOC_OPTION_ELEMENT_CLOSE
+ })
+ .set_name ("Option")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); });
+
+ Rule term_element = Rule.seq ({
+ TokenType.GTKDOC_TERM_ELEMENT_OPEN,
+ run_with_dot,
+ TokenType.GTKDOC_TERM_ELEMENT_CLOSE
+ })
+ .set_name ("Term")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); });
+
+ Rule literal_element = Rule.seq ({
+ TokenType.GTKDOC_LITERAL_ELEMENT_OPEN,
+ run_with_dot,
+ TokenType.GTKDOC_LITERAL_ELEMENT_CLOSE
+ })
+ .set_name ("Literal")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); });
+
+ Rule replaceable_element = Rule.seq ({
+ TokenType.GTKDOC_REPLACEABLE_ELEMENT_OPEN,
+ raw_text,
+ TokenType.GTKDOC_REPLACEABLE_ELEMENT_CLOSE
+ })
+ .set_name ("Replaceable")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); });
+
+ Rule guimenuitem_element = Rule.seq ({
+ TokenType.GTKDOC_GUI_MENU_ITEM_ELEMENT_OPEN,
+ raw_text,
+ TokenType.GTKDOC_GUI_MENU_ITEM_ELEMENT_CLOSE
+ })
+ .set_name ("GuiMenuItem")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); });
+
+ Rule struct_name_element = Rule.seq ({
+ TokenType.GTKDOC_STRUCTNAME_ELEMENT_OPEN,
+ word.action ((token) => {
+ gir_append_link (token);
+ }),
+ TokenType.GTKDOC_STRUCTNAME_ELEMENT_CLOSE
+ })
+ .set_name ("Structname");
+
+ Rule param = Rule.one_of ({
+ Rule.seq ({
+ TokenType.GTKDOC_PARAM,
+ word
+ })
+ })
+ .set_name ("Parameter")
+ .set_start (() => { push (_factory.create_run (Run.Style.MONOSPACED)); })
+ .set_reduce (() => { ((InlineContent) peek ()).content.add ((Inline) pop ()); });
+
+ run.set_rule (
+ Rule.many ({
+ Rule.one_of ({
+ newline, space, word_or_function, node_link, param, struct_name_element, link_element, xml_comment,
+ literal_element, guimenuitem_element, replaceable_element, envar_element, emphasis_element,
+ option_element, term_element, filename_element
+ })
+ })
+ .set_name ("Run")
+ );
+
+ Rule paragraph_element = Rule.seq ({
+ TokenType.GTKDOC_PARA_ELEMENT_OPEN,
+ run_with_dot,
+ TokenType.GTKDOC_PARA_ELEMENT_CLOSE,
+ Rule.option ({
+ Rule.many({
+ Rule.one_of ({
+ space.action ((token) => {}),
+ newline.action ((token) => {})
+ })
+ })
+ })
+ })
+ .set_name ("ParagraphElement")
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+ Rule source = Rule.seq ({
+ TokenType.GTKDOC_SOURCE_OPEN.action ((token) => { ((GirDocumentationScanner) _scanner).set_code_escape_mode (true); }),
+ Rule.many ({
+ word.action ((token) => { ((SourceCode) peek ()).code = token.to_string (); })
+ })
+ .set_start (() => { push (_factory.create_source_code ()); })
+ .set_reduce (() => { ((Paragraph) peek ()).content.add ((Inline) pop ()); }),
+ TokenType.GTKDOC_SOURCE_CLOSE.action ((token) => { ((GirDocumentationScanner) _scanner).set_code_escape_mode (false); }),
+ optional_unprinted_spaces
+ })
+ .set_name ("Source")
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+ Rule program_listing_element = Rule.seq ({
+ TokenType.GTKDOC_PROGRAMLISTING_ELEMENT_OPEN.action ((token) => { ((GirDocumentationScanner) _scanner).set_code_element_escape_mode (true); }),
+ Rule.many ({
+ word.action ((token) => { ((SourceCode) peek ()).code = token.to_string (); })
+ })
+ .set_start (() => { push (_factory.create_source_code ()); })
+ .set_reduce (() => { ((Paragraph) peek ()).content.add ((Inline) pop ()); }),
+ TokenType.GTKDOC_PROGRAMLISTING_ELEMENT_CLOSE.action ((token) => { ((GirDocumentationScanner) _scanner).set_code_element_escape_mode (false); }),
+ optional_unprinted_spaces
+ })
+ .set_name ("ProgramListing")
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+ Rule example_element = Rule.seq ({
+ Rule.one_of ({
+ program_listing_element,
+ Rule.seq ({
+ TokenType.GTKDOC_EXAMPLE_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ Rule.option ({
+ TokenType.GTKDOC_TITLE_ELEMENT_OPEN,
+ Rule.many ({
+ Rule.one_of ({ word.action ((token) => {}) })
+ }),
+ TokenType.GTKDOC_TITLE_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ }),
+ program_listing_element,
+ TokenType.GTKDOC_EXAMPLE_ELEMENT_CLOSE
+ })
+ }),
+ optional_unprinted_spaces
+ })
+ .set_name ("SourceElement");
+
+ Rule paragraph = Rule.seq ({
+ run_with_dot
+ })
+ .set_name ("Paragraph")
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+ Rule note_element = Rule.seq ({
+ TokenType.GTKDOC_NOTE_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ Rule.option ({
+ paragraph
+ }),
+ Rule.option ({
+ Rule.many ({
+ paragraph_element,
+ Rule.option ({ paragraph })
+ })
+ }),
+ TokenType.GTKDOC_NOTE_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ })
+ .set_name ("Note");
+
+ Rule warning_element = Rule.seq ({
+ TokenType.GTKDOC_WARNING_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ Rule.option ({
+ paragraph
+ }),
+ Rule.option ({
+ Rule.many ({
+ paragraph_element,
+ Rule.option ({ paragraph })
+ })
+ }),
+ TokenType.GTKDOC_WARNING_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ })
+ .set_name ("Warning");
+
+ Rule variable_list_element = Rule.seq ({
+ TokenType.GTKDOC_VARIABLE_LIST_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ Rule.many ({
+ Rule.seq ({
+ TokenType.GTKDOC_VARIABLE_LIST_ENTRY_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+
+ TokenType.GTKDOC_TERM_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ run_with_dot,
+ TokenType.GTKDOC_TERM_ELEMENT_CLOSE.action ((token) => { add_content_string (": "); }),
+ optional_unprinted_spaces,
+
+ TokenType.GTKDOC_LIST_ITEM_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ run_with_dot,
+ TokenType.GTKDOC_LIST_ITEM_ELEMENT_CLOSE,
+ optional_unprinted_spaces,
+
+ TokenType.GTKDOC_VARIABLE_LIST_ENTRY_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ })
+ .set_start (() => { push (_factory.create_list_item ()); })
+ .set_reduce (() => { ((Content.List) peek ()).items.add ((Content.ListItem) pop ()); })
+ }),
+ TokenType.GTKDOC_VARIABLE_LIST_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ })
+ .set_name ("VariableList")
+ .set_start (() => { push (_factory.create_list ()); })
+ .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+ Rule list_element = Rule.seq ({
+ TokenType.GTKDOC_ITEMIZED_LIST_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ Rule.many ({
+ Rule.seq ({
+ TokenType.GTKDOC_LIST_ITEM_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ run_with_dot,
+ TokenType.GTKDOC_LIST_ITEM_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ })
+ .set_start (() => { push (_factory.create_list_item ()); })
+ .set_reduce (() => { ((Content.List) peek ()).items.add ((Content.ListItem) pop ()); })
+ }),
+ TokenType.GTKDOC_ITEMIZED_LIST_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ })
+ .set_name ("ItemizedList")
+ .set_start (() => { push (_factory.create_list ()); })
+ .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+ Rule simple_list_element = Rule.seq ({
+ TokenType.GTKDOC_SIMPLELIST_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ Rule.many ({
+ Rule.seq ({
+ TokenType.GTKDOC_MEMBER_ELEMENT_OPEN,
+ optional_unprinted_spaces,
+ run_with_dot,
+ TokenType.GTKDOC_MEMBER_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ })
+ .set_start (() => { push (_factory.create_list_item ()); })
+ .set_reduce (() => { ((Content.List) peek ()).items.add ((Content.ListItem) pop ()); })
+ }),
+ TokenType.GTKDOC_SIMPLELIST_ELEMENT_CLOSE,
+ optional_unprinted_spaces
+ })
+ .set_name ("SimpleList")
+ .set_start (() => { push (_factory.create_list ()); })
+ .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+ Rule block_element = Rule.one_of ({
+ paragraph_element, list_element, note_element, warning_element, source,
+ example_element, variable_list_element, simple_list_element
+ })
+ .set_name ("Block");
+
+ // TODO: find out why the clean version does not work ...
+ Rule first_paragraph = Rule.many ({
+ Rule.one_of ({
+ Rule.seq ({ run }).set_reduce (() => { ((InlineContent) peek ()).content.add ((Inline) pop ()); }),
+ TokenType.GTKDOC_DOT.action ((token) => {
+ ((InlineContent) peek ()).content.add (_factory.create_text ("."));
+ if (_gir_is_first_paragraph) {
+ ((BlockContent) peek ()).content.add ((Block) pop ());
+ push (_factory.create_paragraph ());
+ _gir_is_first_paragraph = false;
+ }
+ })
+ })
+ })
+ .set_name ("BriefDescription")
+ .set_start (() => { push (_factory.create_paragraph ()); })
+ .set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); _gir_is_first_paragraph = true; });
+
+ Rule comment = Rule.seq ({
+ Rule.option ({
+ first_paragraph
+ }),
+ Rule.option ({
+ Rule.many ({
+ block_element,
+ Rule.option ({ paragraph })
+ })
+ })
+ })
+ .set_name ("Comment")
+ .set_start (() => { push (_factory.create_comment ()); });
+
+ Rule taglet = Rule.many ({
+ run_with_dot
+ })
+ .set_name ("Taglet")
+ .set_reduce (() => { ((Comment) peek ()).taglets.add ((Taglet) pop ()); });
+
+ _gir_taglet_parser.set_root_rule (taglet);
+ _gir_parser.set_root_rule (comment);
+ }
+
+ private void init_valadoc_rules () {
// Inline rules
StubRule run = new StubRule ();
@@ -311,35 +825,35 @@ public class Valadoc.DocumentationParser : Object, ResourceLocator {
Rule embedded =
Rule.seq ({
- TokenType.DOUBLE_OPEN_BRACE.action (() => { _scanner.set_url_escape_mode (true); }),
+ TokenType.DOUBLE_OPEN_BRACE.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (true); }),
TokenType.any_word ().action ((token) => { ((Embedded) peek ()).url = token.to_string (); }),
Rule.option ({
- TokenType.PIPE.action (() => { _scanner.set_url_escape_mode (false); }),
+ TokenType.PIPE.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (false); }),
text
})
.set_reduce (() => { var caption = pop () as Text; ((Embedded) peek ()).caption = caption.content; }),
- TokenType.DOUBLE_CLOSED_BRACE.action (() => { _scanner.set_url_escape_mode (false); })
+ TokenType.DOUBLE_CLOSED_BRACE.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (false); })
})
.set_name ("Embedded")
.set_start (() => { push (_factory.create_embedded ()); });
Rule link =
Rule.seq ({
- TokenType.DOUBLE_OPEN_BRACKET.action (() => { _scanner.set_url_escape_mode (true); }),
+ TokenType.DOUBLE_OPEN_BRACKET.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (true); }),
TokenType.any_word ().action ((token) => { ((Link) peek ()).url = token.to_string (); }),
Rule.option ({
- TokenType.PIPE.action (() => { _scanner.set_url_escape_mode (false); }),
+ TokenType.PIPE.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (false); }),
run
}),
- TokenType.DOUBLE_CLOSED_BRACKET.action (() => { _scanner.set_url_escape_mode (false); })
+ TokenType.DOUBLE_CLOSED_BRACKET.action (() => { ((WikiScanner) _scanner).set_url_escape_mode (false); })
})
.set_name ("Link")
.set_start (() => { push (_factory.create_link ()); });
Rule source_code =
Rule.seq ({
- TokenType.TRIPLE_OPEN_BRACE.action ((token) => { _scanner.set_code_escape_mode (true); }),
+ TokenType.TRIPLE_OPEN_BRACE.action ((token) => { ((WikiScanner) _scanner).set_code_escape_mode (true); }),
TokenType.any_word ().action ((token) => { ((SourceCode) peek ()).code = token.to_string (); }),
- TokenType.TRIPLE_CLOSED_BRACE.action ((token) => { _scanner.set_code_escape_mode (false); })
+ TokenType.TRIPLE_CLOSED_BRACE.action ((token) => { ((WikiScanner) _scanner).set_code_escape_mode (false); })
})
.set_name ("SourceCode")
.set_start (() => { push (_factory.create_source_code ()); });
diff --git a/src/libvaladoc/documentation/girdocumentationscanner.vala b/src/libvaladoc/documentation/girdocumentationscanner.vala
new file mode 100644
index 0000000..aed78db
--- /dev/null
+++ b/src/libvaladoc/documentation/girdocumentationscanner.vala
@@ -0,0 +1,610 @@
+/* girdocuscanner.vala
+ *
+ * Copyright (C) 2010 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;
+
+public class Valadoc.Importer.GirDocumentationScanner : Object, Scanner {
+
+ public GirDocumentationScanner (Settings settings) {
+ _settings = settings;
+ }
+
+ private Settings _settings;
+ private Parser _parser;
+
+ private string _content;
+ private int _index;
+ private bool _stop;
+ private int _last_index;
+ private int _last_line;
+ private int _last_column;
+ private int _line;
+ private int _column;
+ private bool _code_element_escape_mode;
+ private bool _code_escape_mode;
+ private bool _node_name;
+ private unichar _last_char;
+ private int _skip;
+ private StringBuilder _current_string = new StringBuilder ();
+
+ public void set_parser (Parser parser) {
+ _parser = parser;
+ }
+
+ public void reset () {
+ _stop = false;
+ _last_index = 0;
+ _last_line = 0;
+ _last_column = 0;
+ _line = 0;
+ _column = 0;
+ _code_element_escape_mode = false;
+ _code_escape_mode = false;
+ _node_name = false;
+ _last_char = 0;
+ _skip = 0;
+ _current_string.erase (0, -1);
+ }
+
+ public void scan (string _content) throws ParserError {
+ this._content = _content;
+ for (_index = 0; !_stop && _index < _content.length; _index++) {
+ unichar c = _content[_index];
+ accept (c);
+ }
+ }
+
+ public void end () throws ParserError {
+ emit_token (TokenType.GTKDOC_EOF);
+ }
+
+ public void stop () {
+ _stop = true;
+ }
+
+ public void set_code_element_escape_mode (bool escape_mode) {
+ _code_element_escape_mode = escape_mode;
+ }
+
+ public void set_code_escape_mode (bool escape_mode) {
+ _code_escape_mode = escape_mode;
+ }
+
+ public int get_line () {
+ return _line;
+ }
+
+ public virtual string get_line_content () {
+ int i = _index;
+ while (i > 0 && _content[i-1] != '\n') {
+ i--;
+ }
+ StringBuilder builder = new StringBuilder ();
+ while (i < _content.length && _content[i] != '\n') {
+ unichar c = _content[i++];
+ if (c == '\t') {
+ builder.append (" ");
+ } else {
+ builder.append_unichar (c);
+ }
+ }
+ return builder.str;
+ }
+
+ protected unichar get_next_char (int offset = 1) {
+ return _content[_index + offset];
+ }
+
+ private void emit_xml_node_open_token (string name, int offset) throws ParserError {
+ switch (name) {
+ case "structname":
+ emit_token (TokenType.GTKDOC_STRUCTNAME_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "link":
+ emit_token (TokenType.GTKDOC_LINK_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "literal":
+ emit_token (TokenType.GTKDOC_LITERAL_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "guimenuitem":
+ emit_token (TokenType.GTKDOC_GUI_MENU_ITEM_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "replaceable":
+ emit_token (TokenType.GTKDOC_REPLACEABLE_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "para":
+ emit_token (TokenType.GTKDOC_PARA_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "note":
+ emit_token (TokenType.GTKDOC_NOTE_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "itemizedlist":
+ emit_token (TokenType.GTKDOC_ITEMIZED_LIST_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "listitem":
+ emit_token (TokenType.GTKDOC_LIST_ITEM_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "warning":
+ emit_token (TokenType.GTKDOC_WARNING_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "programlisting":
+ emit_token (TokenType.GTKDOC_PROGRAMLISTING_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "informalexample":
+ emit_token (TokenType.GTKDOC_EXAMPLE_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "variablelist":
+ emit_token (TokenType.GTKDOC_VARIABLE_LIST_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "varlistentry":
+ emit_token (TokenType.GTKDOC_VARIABLE_LIST_ENTRY_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "term":
+ emit_token (TokenType.GTKDOC_TERM_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "envar":
+ emit_token (TokenType.GTKDOC_ENVAR_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "option":
+ emit_token (TokenType.GTKDOC_OPTION_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "emphasis":
+ emit_token (TokenType.GTKDOC_EMPHASIS_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "filename":
+ emit_token (TokenType.GTKDOC_FILENAME_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "simplelist":
+ emit_token (TokenType.GTKDOC_SIMPLELIST_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ case "member":
+ emit_token (TokenType.GTKDOC_MEMBER_ELEMENT_OPEN);
+ _skip = offset;
+ break;
+
+ default:
+ append_char ('<');
+ break;
+ }
+ }
+
+ private void emit_xml_node_close_token (string name, int offset) throws ParserError {
+ switch (name) {
+ case "structname":
+ emit_token (TokenType.GTKDOC_STRUCTNAME_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "link":
+ emit_token (TokenType.GTKDOC_LINK_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "literal":
+ emit_token (TokenType.GTKDOC_LITERAL_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "guimenuitem":
+ emit_token (TokenType.GTKDOC_GUI_MENU_ITEM_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "replaceable":
+ emit_token (TokenType.GTKDOC_REPLACEABLE_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "para":
+ emit_token (TokenType.GTKDOC_PARA_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "note":
+ emit_token (TokenType.GTKDOC_NOTE_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "itemizedlist":
+ emit_token (TokenType.GTKDOC_ITEMIZED_LIST_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "listitem":
+ emit_token (TokenType.GTKDOC_LIST_ITEM_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "warning":
+ emit_token (TokenType.GTKDOC_WARNING_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "programlisting":
+ emit_token (TokenType.GTKDOC_PROGRAMLISTING_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "informalexample":
+ emit_token (TokenType.GTKDOC_EXAMPLE_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "variablelist":
+ emit_token (TokenType.GTKDOC_VARIABLE_LIST_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "varlistentry":
+ emit_token (TokenType.GTKDOC_VARIABLE_LIST_ENTRY_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "term":
+ emit_token (TokenType.GTKDOC_TERM_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "envar":
+ emit_token (TokenType.GTKDOC_ENVAR_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "option":
+ emit_token (TokenType.GTKDOC_OPTION_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "emphasis":
+ emit_token (TokenType.GTKDOC_EMPHASIS_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "filename":
+ emit_token (TokenType.GTKDOC_FILENAME_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "simplelist":
+ emit_token (TokenType.GTKDOC_SIMPLELIST_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ case "member":
+ emit_token (TokenType.GTKDOC_MEMBER_ELEMENT_CLOSE);
+ _skip = offset;
+ break;
+
+ default:
+ append_char ('<');
+ break;
+ }
+ }
+
+ private inline bool is_numeric (unichar c) {
+ return c >= '0' && c <= '9';
+ }
+
+ private inline bool is_letter (unichar c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+ }
+
+ private void emmit_qualified_function_name (int offset) throws ParserError {
+ unichar c = get_next_char (offset);
+
+ if (!is_letter (c) && c != '_') {
+ emit_current_word ();
+ return;
+ }
+
+ append_char (c);
+
+ for (offset++; ; offset++) {
+ c = get_next_char (offset);
+
+ if (!is_letter (c) && c != '_' && !is_numeric (c) && c != '\0') {
+ break;
+ }
+
+ append_char (c);
+ }
+
+ unichar nc = get_next_char (offset+1);
+
+ if (c == '\0' || !((c == ':' && nc == ':' && is_letter (get_next_char (offset+2))) || (c == ':' && is_letter (nc)))) {
+ emit_current_word ();
+ _skip = offset-1;
+ return;
+ }
+
+ append_char (c);
+
+ if (nc == ':') {
+ append_char (nc);
+ offset++;
+ }
+
+ for (offset++; ; offset++) {
+ c = get_next_char (offset);
+
+ if (!is_letter (c) && c != '_' && !is_numeric (c)&& c != '-' && c != '\0') {
+ break;
+ }
+
+ append_char (c);
+ }
+
+ emit_current_word ();
+ _skip = offset-1;
+ }
+
+ protected void accept (unichar c) throws ParserError {
+ _column++;
+
+ if (_skip == 0) {
+ if (_code_element_escape_mode == true) {
+ switch (c) {
+ case '<':
+ if (get_next_char (1) == '/' && get_next_char (2) == 'p' &&
+ get_next_char (3) == 'r' && get_next_char (4) == 'o' &&
+ get_next_char (5) == 'g' && get_next_char (6) == 'r' &&
+ get_next_char (7) == 'a' && get_next_char (8) == 'm' &&
+ get_next_char (9) == 'l' && get_next_char (10) == 'i' &&
+ get_next_char (11) == 's' && get_next_char (12) == 't' &&
+ get_next_char (13) == 'i' && get_next_char (14) == 'n' &&
+ get_next_char (15) == 'g' && get_next_char (16) == '>') {
+
+ _code_element_escape_mode = false;
+ emit_token (TokenType.GTKDOC_PROGRAMLISTING_ELEMENT_CLOSE);
+ _skip = 16;
+ } else {
+ append_char (c);
+ }
+ return;
+ default:
+ append_char (c);
+ return;
+ }
+ } else if (_code_escape_mode == true) {
+ switch (c) {
+ case ']':
+ if (get_next_char (1) == '|') {
+ _code_escape_mode = false;
+ emit_token (TokenType.GTKDOC_SOURCE_CLOSE);
+ _skip = 2;
+ } else {
+ append_char (c);
+ }
+ return;
+ default:
+ append_char (c);
+ return;
+ }
+ } else {
+ switch (c) {
+ case '#':
+ case '%':
+ unichar nc = get_next_char (1);
+ if (is_letter (nc) || nc == '_') {
+ emit_token (TokenType.GTKDOC_SYMBOL);
+ emmit_qualified_function_name (1);
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '@':
+ if (_last_char.isspace ()) {
+ emit_token (TokenType.GTKDOC_PARAM);
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '-':
+ if (get_next_char (1) == '-' && get_next_char (2) == '>') {
+ emit_token (TokenType.GTKDOC_XML_COMMENT_END);
+ _skip = 2;
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '(': // "(<spaces>?)"
+ int i = 1;
+
+ for (; get_next_char(i).isspace (); i++);
+ if (get_next_char(i) == ')') {
+ emit_token (TokenType.GTKDOC_FUNCTION_BRACKETS);
+ _skip = i;
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '<':
+ if (get_next_char(1) == '!' && get_next_char(2) == '-' && get_next_char(3) == '-') {
+ emit_token (TokenType.GTKDOC_XML_COMMENT_START);
+ _skip = 3;
+ break;
+ }
+
+ var name = new StringBuilder ();
+ bool is_end_tag = false;
+ int i = 1;
+
+ if (get_next_char(i) == '/') {
+ is_end_tag = true;
+ i++;
+ }
+
+
+ for (; get_next_char(i) != '>' && !get_next_char(i).isspace (); i++) {
+ name.append_unichar (get_next_char(i));
+ }
+
+ if (name.len == 0) {
+ append_char (c);
+ break;
+ }
+
+ if (is_end_tag) {
+ if (get_next_char(i) != '>') {
+ append_char (c);
+ break;
+ }
+ emit_xml_node_close_token (name.str, i);
+ } else {
+ for (; get_next_char(i) != '>' && get_next_char(i) != '\0'; i++);
+ if (get_next_char(i) == '\0') {
+ append_char (c);
+ break;
+ }
+ emit_xml_node_open_token (name.str, i);
+ }
+ break;
+
+ case '|':
+ if (get_next_char (1) == '[') {
+ emit_token (TokenType.GTKDOC_SOURCE_OPEN);
+ _skip = 1;
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case ']':
+ if (get_next_char (1) == '|') {
+ emit_token (TokenType.GTKDOC_SOURCE_CLOSE);
+ _skip = 1;
+ } else {
+ append_char (c);
+ }
+ break;
+
+ case '\r':
+ break;
+
+ case '\n':
+ emit_token (TokenType.GTKDOC_EOL);
+ _line++;
+ _column = 0;
+ _last_column = 0;
+ break;
+
+ case '\t':
+ case ' ':
+ emit_token (TokenType.GTKDOC_SPACE);
+ break;
+
+ case '.':
+ emit_token (TokenType.GTKDOC_DOT);
+ break;
+
+ default:
+ append_char (c);
+ break;
+ }
+ }
+ } else {
+ _skip--;
+ }
+ _last_char = c;
+ }
+
+ private void append_char (unichar c) {
+ _current_string.append_unichar (c);
+ }
+
+ public int get_line_start_column () {
+ return 0;
+ }
+
+ private SourceLocation get_begin () {
+ return SourceLocation (_last_line, get_line_start_column () + _last_column);
+ }
+
+ private SourceLocation get_end (int offset = 0) {
+ return SourceLocation (_line, get_line_start_column () + _column + offset);
+ }
+
+ private void emit_current_word () throws ParserError {
+ if (_current_string.len > 0) {
+ _parser.accept_token (new Token.from_word (_current_string.str, get_begin (), get_end (-1)));
+ _current_string.erase (0, -1);
+
+ _last_index = _index;
+ _last_line = _line;
+ _last_column = _column - 1;
+ }
+ }
+
+ private void emit_token (TokenType type) throws ParserError {
+ emit_current_word ();
+
+ _parser.accept_token (new Token.from_type (type, get_begin (), get_end (_skip)));
+
+ _last_index = _index;
+ _last_line = _line;
+ _last_column = _column;
+ }
+}
diff --git a/src/libvaladoc/html/htmlrenderer.vala b/src/libvaladoc/html/htmlrenderer.vala
index 322dd61..66ef4d4 100755
--- a/src/libvaladoc/html/htmlrenderer.vala
+++ b/src/libvaladoc/html/htmlrenderer.vala
@@ -57,11 +57,17 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
return linker.get_relative_link (_container, symbol, _doclet.settings);
}
- private void write_symbol_link (Api.Node symbol, string? label) {
- var url = get_url (symbol);
- writer.link (url,
- (label == null || label == "") ? symbol.get_full_name () : label,
- cssresolver.resolve (symbol));
+ private void write_symbol_link (Api.Node? symbol, string? label) {
+ if (symbol == null && label != null) {
+ writer.start_tag ("code");
+ writer.text (label);
+ writer.end_tag ("code");
+ } else if (symbol != null) {
+ var url = get_url (symbol);
+ writer.link (url,
+ (label == null || label == "") ? symbol.get_full_name () : label,
+ cssresolver.resolve (symbol));
+ }
}
private delegate void Write ();
@@ -230,10 +236,12 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
}
public override void visit_symbol_link (SymbolLink element) {
- if (element.symbol == _container
+ if (element.symbol == null || element.symbol == _container
|| !element.symbol.is_browsable (_doclet.settings)
|| !element.symbol.package.is_browsable (_doclet.settings)) {
+ writer.start_tag ("code");
writer.text (element.label);
+ writer.end_tag ("code");
} else {
write_symbol_link (element.symbol, element.label);
}
diff --git a/src/libvaladoc/importer/documentationimporter.vala b/src/libvaladoc/importer/documentationimporter.vala
index d19f019..9cdf7b0 100644
--- a/src/libvaladoc/importer/documentationimporter.vala
+++ b/src/libvaladoc/importer/documentationimporter.vala
@@ -24,19 +24,18 @@
using Gee;
-public abstract class Valadoc.DocumentationImporter : Object, ResourceLocator {
- protected ErrorReporter errorreporter;
+public abstract class Valadoc.Importer.DocumentationImporter : Object, ResourceLocator {
protected ModuleLoader modules;
protected Settings settings;
protected Api.Tree tree;
protected Content.ContentFactory factory;
+ public abstract string file_extension { get; }
- public DocumentationImporter (Api.Tree tree, ModuleLoader modules, Settings settings, ErrorReporter errorreporter) {
+ public DocumentationImporter (Api.Tree tree, ModuleLoader modules, Settings settings) {
factory = new Content.ContentFactory (settings, this, modules);
- this.errorreporter = errorreporter;
this.settings = settings;
this.modules = null;
this.tree = tree;
@@ -46,7 +45,7 @@ public abstract class Valadoc.DocumentationImporter : Object, ResourceLocator {
return path;
}
- public abstract bool process (string filename, Settings settings, Api.Package package);
+ public abstract void process (string filename);
}
diff --git a/src/libvaladoc/importer/girdocumentationbuilder.vala b/src/libvaladoc/importer/girdocumentationbuilder.vala
new file mode 100644
index 0000000..d502cf3
--- /dev/null
+++ b/src/libvaladoc/importer/girdocumentationbuilder.vala
@@ -0,0 +1,56 @@
+/* DocumentationBuilderimporter.vala
+ *
+ * Copyright (C) 2010 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 Gee;
+
+
+/**
+ * A documentation comment used by valadoc
+ */
+public class Valadoc.Importer.GirDocumentationBuilder : Vala.Comment {
+ private HashMap<string, Vala.Comment> _parameters = new HashMap<string, Vala.Comment> ();
+
+ public Map<string, Vala.Comment> parameters { owned get { return _parameters.read_only_view; } }
+
+ public Vala.Comment? return_value { get; internal set; }
+
+ public GirDocumentationBuilder.empty (Vala.SourceReference _source_reference) {
+ base ("", _source_reference);
+ return_value = null;
+ }
+
+ public GirDocumentationBuilder (Vala.Comment comment) {
+ base (comment.content, comment.source_reference);
+ return_value = null;
+ }
+
+ internal void add_parameter (string name, Vala.Comment comment) {
+ _parameters.set (name, comment);
+ }
+
+ public bool is_empty () {
+ return return_value == null && (content == null || content == "") && parameters.is_empty;
+ }
+}
+
diff --git a/src/libvaladoc/importer/girdocumentationimporter.vala b/src/libvaladoc/importer/girdocumentationimporter.vala
new file mode 100644
index 0000000..a76215b
--- /dev/null
+++ b/src/libvaladoc/importer/girdocumentationimporter.vala
@@ -0,0 +1,687 @@
+/* DocumentationBuilderimporter.vala
+ *
+ * Copyright (C) 2010 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>
+ */
+
+// based on valagirparser.vala
+
+using Gee;
+
+public class Valadoc.Importer.GirDocumentationImporter : DocumentationImporter {
+ DocumentationParser docparser;
+ Vala.MarkupReader reader;
+
+ Vala.SourceFile current_source_file;
+ Vala.SourceLocation begin;
+ Vala.SourceLocation end;
+ Vala.MarkupTokenType current_token;
+
+ Vala.DataType dummy_type;
+
+ LinkedList<string> type_cname_stack = new LinkedList<string> ();
+
+ int anonymous_param_count = 0;
+
+ public override string file_extension { get { return "gir"; } }
+
+ public GirDocumentationImporter (Api.Tree tree, DocumentationParser docparser, ModuleLoader modules, Settings settings) {
+ base (tree, modules, settings);
+ this.dummy_type = new Vala.StructValueType (new Vala.Struct ("Dummy"));
+ this.docparser = docparser;
+ }
+
+ public override void process (string filename) {
+ parse_file (filename);
+ }
+
+ void parse_file (string gir_file) {
+ reader = new Vala.MarkupReader (gir_file);
+ this.current_source_file = new Vala.SourceFile (tree.context, GLib.Path. get_basename (gir_file));
+
+ // xml prolog
+ next ();
+ next ();
+
+ next ();
+ parse_repository ();
+ this.current_source_file = null;
+ }
+
+ Vala.Comment? parse_doc () {
+ start_element ("doc");
+
+ Vala.Comment comment = null;
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.TEXT) {
+ comment = new Vala.Comment (reader.content, get_current_src ());
+ next ();
+ }
+
+ end_element ("doc");
+ return comment;
+ }
+
+ void next () {
+ current_token = reader.read_token (out begin, out end);
+ }
+
+ void start_element (string name) {
+ if (current_token != Vala.MarkupTokenType.START_ELEMENT || reader.name != name) {
+ // error
+ Vala.Report.error (get_current_src (), "expected start element of `%s' instead of `%s'".printf (name, reader.name));
+ }
+ }
+
+ void end_element (string name) {
+ if (current_token != Vala.MarkupTokenType.END_ELEMENT || reader.name != name) {
+ // error
+ Vala.Report.error (get_current_src (), "expected end element of `%s' instead of `%s'".printf (name, reader.name));
+ }
+ next ();
+ }
+
+ Vala.SourceReference get_current_src () {
+ return new Vala.SourceReference (this.current_source_file, begin.line, begin.column, end.line, end.column);
+ }
+
+ void parse_repository () {
+ start_element ("repository");
+ next ();
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.name == "namespace") {
+ parse_namespace ();
+ } else if (reader.name == "include") {
+ parse_include ();
+ } else if (reader.name == "package") {
+ parse_package ();
+ } else if (reader.name == "c:include") {
+ parse_c_include ();
+ } else {
+ // error
+ Vala.Report.error (get_current_src (), "unknown child element `%s' in `repository'".printf (reader.name));
+ break;
+ }
+ }
+ end_element ("repository");
+ }
+
+ void parse_include () {
+ start_element ("include");
+ next ();
+ end_element ("include");
+ }
+
+ void parse_package () {
+ start_element ("package");
+ next ();
+ end_element ("package");
+ }
+
+ void parse_c_include () {
+ start_element ("c:include");
+ next ();
+ end_element ("c:include");
+ }
+
+ void skip_element () {
+ next ();
+
+ int level = 1;
+ while (level > 0) {
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ level++;
+ } else if (current_token == Vala.MarkupTokenType.END_ELEMENT) {
+ level--;
+ } else if (current_token == Vala.MarkupTokenType.EOF) {
+ Vala.Report.error (get_current_src (), "unexpected end of file");
+ break;
+ }
+ next ();
+ }
+ }
+
+ void parse_namespace () {
+ start_element ("namespace");
+ next ();
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.get_attribute ("introspectable") == "0") {
+ skip_element ();
+ continue;
+ }
+
+ if (reader.name == "alias") {
+ parse_alias ();
+ } else if (reader.name == "enumeration") {
+ parse_enumeration ();
+ } else if (reader.name == "bitfield") {
+ parse_bitfield ();
+ } else if (reader.name == "function") {
+ parse_method ("function");
+ } else if (reader.name == "callback") {
+ parse_callback ();
+ } else if (reader.name == "record") {
+ if (reader.get_attribute ("glib:get-type") != null) {
+ parse_boxed ();
+ } else {
+ parse_record ();
+ }
+ } else if (reader.name == "class") {
+ parse_class ();
+ } else if (reader.name == "interface") {
+ parse_interface ();
+ } else if (reader.name == "glib:boxed") {
+ parse_boxed ();
+ } else if (reader.name == "union") {
+ parse_union ();
+ } else if (reader.name == "constant") {
+ parse_constant ();
+ } else {
+ // error
+ Vala.Report.error (get_current_src (), "unknown child element `%s' in `namespace'".printf (reader.name));
+ break;
+ }
+ }
+ end_element ("namespace");
+ }
+
+ void parse_alias () {
+ start_element ("alias");
+ next ();
+ end_element ("alias");
+ }
+
+ void parse_enumeration () {
+ start_element ("enumeration");
+ string cname = reader.get_attribute ("c:type");
+ type_cname_stack.add (cname);
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.get_attribute ("introspectable") == "0") {
+ skip_element ();
+ continue;
+ }
+
+ if (reader.name == "member") {
+ parse_enumeration_member ();
+ } else {
+ // error
+ break;
+ }
+ }
+
+ type_cname_stack.poll_head ();
+ end_element ("enumeration");
+ }
+
+ void parse_bitfield () {
+ start_element ("bitfield");
+ string cname = reader.get_attribute ("c:type");
+ type_cname_stack.add (cname);
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.get_attribute ("introspectable") == "0") {
+ skip_element ();
+ continue;
+ }
+
+ if (reader.name == "member") {
+ parse_enumeration_member ();
+ } else {
+ // error
+ break;
+ }
+ }
+
+ type_cname_stack.poll_head ();
+ end_element ("bitfield");
+ }
+
+ void parse_enumeration_member () {
+ start_element ("member");
+ string cname = reader.get_attribute ("c:identifier");
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ end_element ("member");
+ }
+
+ void parse_return_value (GirDocumentationBuilder doc) {
+ start_element ("return-value");
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ doc.return_value = parse_doc ();
+ }
+
+ parse_type ();
+
+ end_element ("return-value");
+ }
+
+ void parse_parameter (GirDocumentationBuilder doc) {
+ start_element ("parameter");
+ string name = reader.get_attribute ("name");
+
+ if (name == null) {
+ name = "param%d".printf (anonymous_param_count);
+ anonymous_param_count++;
+ }
+
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ doc.add_parameter (name, parse_doc ());
+ }
+
+ if (reader.name == "varargs") {
+ start_element ("varargs");
+ next ();
+ end_element ("varargs");
+ } else {
+ parse_type ();
+ }
+
+ end_element ("parameter");
+ }
+
+ void parse_type () {
+ if (reader.name == "array" || reader.name == "callback" || reader.name == "type") {
+ skip_element ();
+ }
+ }
+
+ void parse_record () {
+ start_element ("record");
+ string glib_is_gtype_struct_for = reader.get_attribute ("glib:is-gtype-struct-for");
+ string cname = reader.get_attribute ("c:type");
+ type_cname_stack.add (cname);
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.get_attribute ("introspectable") == "0") {
+ skip_element ();
+ continue;
+ }
+
+ if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "callback") {
+ if (glib_is_gtype_struct_for != null) {
+ parse_method ("callback");
+ } else {
+ parse_callback ();
+ }
+ } else if (reader.name == "constructor") {
+ parse_constructor ();
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "union") {
+ parse_union ();
+ } else {
+ // error
+ Vala.Report.error (get_current_src (), "unknown child element `%s' in `record'".printf (reader.name));
+ break;
+ }
+ }
+
+ type_cname_stack.poll_head ();
+ end_element ("record");
+ }
+
+ void parse_class () {
+ start_element ("class");
+ string cname = reader.get_attribute ("c:type");
+ type_cname_stack.add (cname);
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.get_attribute ("introspectable") == "0") {
+ skip_element ();
+ continue;
+ }
+
+ if (reader.name == "implements") {
+ start_element ("implements");
+ next ();
+ end_element ("implements");
+ } else if (reader.name == "constant") {
+ parse_constant ();
+ } else if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "property") {
+ parse_property ();
+ } else if (reader.name == "constructor") {
+ parse_constructor (cname);
+ } else if (reader.name == "function") {
+ parse_method ("function");
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "virtual-method") {
+ parse_method ("virtual-method");
+ } else if (reader.name == "union") {
+ parse_union ();
+ } else if (reader.name == "glib:signal") {
+ parse_signal ();
+ } else {
+ // error
+ Vala.Report.error (get_current_src (), "unknown child element `%s' in `class'".printf (reader.name));
+ break;
+ }
+ }
+
+ type_cname_stack.poll_head ();
+ end_element ("class");
+ }
+
+ void parse_interface () {
+ start_element ("interface");
+ string cname = reader.get_attribute ("c:type");
+ type_cname_stack.add (cname);
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.get_attribute ("introspectable") == "0") {
+ skip_element ();
+ continue;
+ }
+
+ if (reader.name == "prerequisite") {
+ start_element ("prerequisite");
+ next ();
+ end_element ("prerequisite");
+ } else if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "property") {
+ parse_property ();
+ } else if (reader.name == "virtual-method") {
+ parse_method ("virtual-method");
+ } else if (reader.name == "function") {
+ parse_method ("function");
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "glib:signal") {
+ parse_signal ();
+ } else {
+ // error
+ Vala.Report.error (get_current_src (), "unknown child element `%s' in `interface'".printf (reader.name));
+ break;
+ }
+ }
+
+ type_cname_stack.poll_head ();
+ end_element ("interface");
+ }
+
+ void parse_field () {
+ start_element ("field");
+ string cname = reader.get_attribute ("name");
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc" && cname != null) {
+ string real_cname = type_cname_stack.peek();
+ real_cname = (real_cname == null)? cname : real_cname+"."+cname;
+ process_documentation (real_cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ parse_type ();
+
+ end_element ("field");
+ }
+
+ void parse_property () {
+ start_element ("property");
+ string cname = reader.get_attribute ("name");
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc" && cname != null) {
+ process_documentation (type_cname_stack.peek()+":"+cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ parse_type ();
+
+ end_element ("property");
+ }
+
+ void parse_callback () {
+ this.parse_function ("callback");
+ }
+
+ void parse_constructor (string? parent_ctype = null) {
+ start_element ("constructor");
+ string cname = reader.get_attribute ("c:identifier");
+ next ();
+
+ GirDocumentationBuilder doc;
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ doc = new GirDocumentationBuilder (parse_doc ());
+ } else {
+ doc = new GirDocumentationBuilder.empty (get_current_src ());
+ }
+
+ parse_return_value (doc);
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
+ start_element ("parameters");
+ next ();
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ parse_parameter (doc);
+ }
+ end_element ("parameters");
+ }
+
+ if (!doc.is_empty ()) {
+ process_documentation (cname, doc);
+ }
+
+ end_element ("constructor");
+ }
+
+ void parse_function (string element_name) {
+ start_element (element_name);
+ string cname = reader.get_attribute ("c:identifier");
+ next ();
+
+ GirDocumentationBuilder doc;
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ doc = new GirDocumentationBuilder (parse_doc ());
+ } else {
+ doc = new GirDocumentationBuilder.empty (get_current_src ());
+ }
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "return-value") {
+ parse_return_value (doc);
+ }
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
+ start_element ("parameters");
+ next ();
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ parse_parameter (doc);
+ }
+
+ end_element ("parameters");
+ }
+
+ if (!doc.is_empty ()) {
+ process_documentation (cname, doc);
+ }
+
+ end_element (element_name);
+ }
+
+ void parse_method (string element_name) {
+ this.parse_function (element_name);
+ }
+
+ void parse_signal () {
+ start_element ("glib:signal");
+ string cname = reader.get_attribute ("name");
+ next ();
+
+ GirDocumentationBuilder doc;
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ doc = new GirDocumentationBuilder (parse_doc ());
+ } else {
+ doc = new GirDocumentationBuilder.empty (get_current_src ());
+ }
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "return-value") {
+ parse_return_value (doc);
+ }
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
+ start_element ("parameters");
+ next ();
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ parse_parameter (doc);
+ }
+ end_element ("parameters");
+ }
+ if (!doc.is_empty ()) {
+ process_documentation (type_cname_stack.peek()+"::"+cname, doc);
+ }
+ end_element ("glib:signal");
+ }
+
+ void parse_boxed () {
+ string cname = reader.get_attribute ("c:type");
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.get_attribute ("introspectable") == "0") {
+ skip_element ();
+ continue;
+ }
+
+ if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "constructor") {
+ parse_constructor ();
+ } else if (reader.name == "union") {
+ parse_union ();
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else {
+ // error
+ Vala.Report.error (get_current_src (), "unknown child element `%s' in `class'".printf (reader.name));
+ break;
+ }
+ }
+
+ if (current_token != Vala.MarkupTokenType.END_ELEMENT) {
+ // error
+ Vala.Report.error (get_current_src (), "expected end element");
+ }
+ next ();
+ }
+
+ void parse_union () {
+ start_element ("union");
+ string cname = reader.get_attribute ("c:type");
+ type_cname_stack.add (cname);
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (cname, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ while (current_token == Vala.MarkupTokenType.START_ELEMENT) {
+ if (reader.get_attribute ("introspectable") == "0") {
+ skip_element ();
+ continue;
+ }
+
+ if (reader.name == "field") {
+ parse_field ();
+ } else if (reader.name == "constructor") {
+ parse_constructor ();
+ } else if (reader.name == "method") {
+ parse_method ("method");
+ } else if (reader.name == "record") {
+ parse_record ();
+ }
+ }
+
+ type_cname_stack.poll_head ();
+ end_element ("union");
+ }
+
+ void parse_constant () {
+ start_element ("constant");
+ string name = reader.get_attribute ("name");
+ next ();
+
+ if (current_token == Vala.MarkupTokenType.START_ELEMENT && reader.name == "doc") {
+ process_documentation (name, new GirDocumentationBuilder (parse_doc ()));
+ }
+
+ parse_type ();
+
+ end_element ("constant");
+ }
+
+ void process_documentation (string? cname, GirDocumentationBuilder? doc) {
+ if (cname == null || doc == null) {
+ return;
+ }
+
+ var node = tree.search_symbol_cstr (cname);
+
+ if (node != null) {
+ node.documentation = docparser.parse_gir_comment (node, doc);
+ }
+ }
+}
+
diff --git a/src/libvaladoc/parser/tokentype.vala b/src/libvaladoc/parser/tokentype.vala
index 86f87dc..bd53da9 100644
--- a/src/libvaladoc/parser/tokentype.vala
+++ b/src/libvaladoc/parser/tokentype.vala
@@ -23,7 +23,7 @@
using Gee;
public class Valadoc.TokenType : Object {
-
+ // valadoc-comments:
public static TokenType ANY;
public static TokenType ANY_WORD;
public static TokenType ANY_NUMBER;
@@ -60,6 +60,64 @@ public class Valadoc.TokenType : Object {
public static TokenType ALIGN_RIGHT;
public static TokenType ALIGN_CENTER;
+ // Gir, doc-nodes:
+ public static TokenType GTKDOC_FUNCTION_BRACKETS;
+ public static TokenType GTKDOC_XML_COMMENT_START;
+ public static TokenType GTKDOC_XML_COMMENT_END;
+ public static TokenType GTKDOC_PARAM;
+ public static TokenType GTKDOC_SYMBOL;
+ public static TokenType GTKDOC_ANY_WORD;
+ public static TokenType GTKDOC_SPACE;
+ public static TokenType GTKDOC_EOF;
+ public static TokenType GTKDOC_EOL;
+ public static TokenType GTKDOC_STRUCTNAME_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_STRUCTNAME_ELEMENT_OPEN;
+ public static TokenType GTKDOC_LINK_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_LINK_ELEMENT_OPEN;
+ public static TokenType GTKDOC_ITEMIZED_LIST_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_ITEMIZED_LIST_ELEMENT_OPEN;
+ public static TokenType GTKDOC_LIST_ITEM_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_LIST_ITEM_ELEMENT_OPEN;
+ public static TokenType GTKDOC_NOTE_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_NOTE_ELEMENT_OPEN;
+ public static TokenType GTKDOC_PARA_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_PARA_ELEMENT_OPEN;
+ public static TokenType GTKDOC_LITERAL_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_LITERAL_ELEMENT_OPEN;
+ public static TokenType GTKDOC_GUI_MENU_ITEM_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_GUI_MENU_ITEM_ELEMENT_OPEN;
+ public static TokenType GTKDOC_REPLACEABLE_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_REPLACEABLE_ELEMENT_OPEN;
+ public static TokenType GTKDOC_WARNING_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_WARNING_ELEMENT_OPEN;
+ public static TokenType GTKDOC_SOURCE_CLOSE;
+ public static TokenType GTKDOC_SOURCE_OPEN;
+ public static TokenType GTKDOC_EXAMPLE_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_EXAMPLE_ELEMENT_OPEN;
+ public static TokenType GTKDOC_TITLE_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_TITLE_ELEMENT_OPEN;
+ public static TokenType GTKDOC_PROGRAMLISTING_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_PROGRAMLISTING_ELEMENT_OPEN;
+ public static TokenType GTKDOC_VARIABLE_LIST_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_VARIABLE_LIST_ELEMENT_OPEN;
+ public static TokenType GTKDOC_VARIABLE_LIST_ENTRY_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_VARIABLE_LIST_ENTRY_ELEMENT_OPEN;
+ public static TokenType GTKDOC_TERM_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_TERM_ELEMENT_OPEN;
+ public static TokenType GTKDOC_ENVAR_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_ENVAR_ELEMENT_OPEN;
+ public static TokenType GTKDOC_OPTION_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_OPTION_ELEMENT_OPEN;
+ public static TokenType GTKDOC_EMPHASIS_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_EMPHASIS_ELEMENT_OPEN;
+ public static TokenType GTKDOC_FILENAME_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_FILENAME_ELEMENT_OPEN;
+ public static TokenType GTKDOC_SIMPLELIST_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_SIMPLELIST_ELEMENT_OPEN;
+ public static TokenType GTKDOC_MEMBER_ELEMENT_CLOSE;
+ public static TokenType GTKDOC_MEMBER_ELEMENT_OPEN;
+ public static TokenType GTKDOC_DOT;
+
private static bool initialized = false;
internal static void init_token_types () {
@@ -99,6 +157,64 @@ public class Valadoc.TokenType : Object {
DOUBLE_PIPE = new TokenType.basic ("||");
ALIGN_RIGHT = new TokenType.basic ("))");
ALIGN_CENTER = new TokenType.basic (")(");
+
+ GTKDOC_FUNCTION_BRACKETS = new TokenType.basic ("()");
+ GTKDOC_XML_COMMENT_START = new TokenType.basic ("<!--");
+ GTKDOC_XML_COMMENT_END = new TokenType.basic ("-->");
+ GTKDOC_PARAM = new TokenType.basic ("<c-parameter>");
+ GTKDOC_SYMBOL = new TokenType.basic ("<symbol>");
+ GTKDOC_STRUCTNAME_ELEMENT_CLOSE = new TokenType.basic ("</structname>");
+ GTKDOC_STRUCTNAME_ELEMENT_OPEN = new TokenType.basic ("<structname>");
+ GTKDOC_LINK_ELEMENT_CLOSE = new TokenType.basic ("</link>");
+ GTKDOC_LINK_ELEMENT_OPEN = new TokenType.basic ("<link>");
+ GTKDOC_ITEMIZED_LIST_ELEMENT_CLOSE = new TokenType.basic ("</itemizedlist>");
+ GTKDOC_ITEMIZED_LIST_ELEMENT_OPEN = new TokenType.basic ("<itemizedlist>");
+ GTKDOC_LIST_ITEM_ELEMENT_CLOSE = new TokenType.basic ("</listitem>");
+ GTKDOC_LIST_ITEM_ELEMENT_OPEN = new TokenType.basic ("<listitem>");
+ GTKDOC_NOTE_ELEMENT_CLOSE = new TokenType.basic ("</note>");
+ GTKDOC_NOTE_ELEMENT_OPEN = new TokenType.basic ("<note>");
+ GTKDOC_PARA_ELEMENT_CLOSE = new TokenType.basic ("</para>");
+ GTKDOC_PARA_ELEMENT_OPEN = new TokenType.basic ("<para>");
+ GTKDOC_LITERAL_ELEMENT_CLOSE = new TokenType.basic ("</literal>");
+ GTKDOC_LITERAL_ELEMENT_OPEN = new TokenType.basic ("<literal>");
+ GTKDOC_GUI_MENU_ITEM_ELEMENT_CLOSE = new TokenType.basic ("</guimenuitem>");
+ GTKDOC_GUI_MENU_ITEM_ELEMENT_OPEN = new TokenType.basic ("<guimenuitem>");
+ GTKDOC_REPLACEABLE_ELEMENT_CLOSE = new TokenType.basic ("</replaceable>");
+ GTKDOC_REPLACEABLE_ELEMENT_OPEN = new TokenType.basic ("<replaceable>");
+ GTKDOC_WARNING_ELEMENT_CLOSE = new TokenType.basic ("</warning>");
+ GTKDOC_WARNING_ELEMENT_OPEN = new TokenType.basic ("<warning>");
+ GTKDOC_SOURCE_CLOSE = new TokenType.basic ("|]");
+ GTKDOC_SOURCE_OPEN = new TokenType.basic ("[|");
+ GTKDOC_EXAMPLE_ELEMENT_CLOSE = new TokenType.basic ("</example>");
+ GTKDOC_EXAMPLE_ELEMENT_OPEN = new TokenType.basic ("<example>");
+ GTKDOC_TITLE_ELEMENT_CLOSE = new TokenType.basic ("</title>");
+ GTKDOC_TITLE_ELEMENT_OPEN = new TokenType.basic ("<title>");
+ GTKDOC_PROGRAMLISTING_ELEMENT_CLOSE = new TokenType.basic ("</programlisting>");
+ GTKDOC_PROGRAMLISTING_ELEMENT_OPEN = new TokenType.basic ("<programlisting>");
+ GTKDOC_VARIABLE_LIST_ELEMENT_CLOSE = new TokenType.basic ("</variablelist>");
+ GTKDOC_VARIABLE_LIST_ELEMENT_OPEN = new TokenType.basic ("<variablelist>");
+ GTKDOC_VARIABLE_LIST_ENTRY_ELEMENT_CLOSE = new TokenType.basic ("</varlistentry>");
+ GTKDOC_VARIABLE_LIST_ENTRY_ELEMENT_OPEN = new TokenType.basic ("<varlistentry>");
+ GTKDOC_TERM_ELEMENT_CLOSE = new TokenType.basic ("</term>");
+ GTKDOC_TERM_ELEMENT_OPEN = new TokenType.basic ("<term>");
+ GTKDOC_ENVAR_ELEMENT_CLOSE = new TokenType.basic ("</envar>");
+ GTKDOC_ENVAR_ELEMENT_OPEN = new TokenType.basic ("<envar>");
+ GTKDOC_OPTION_ELEMENT_CLOSE = new TokenType.basic ("</option>");
+ GTKDOC_OPTION_ELEMENT_OPEN = new TokenType.basic ("<option>");
+ GTKDOC_EMPHASIS_ELEMENT_CLOSE = new TokenType.basic ("</emphasis>");
+ GTKDOC_EMPHASIS_ELEMENT_OPEN = new TokenType.basic ("<emphasis>");
+ GTKDOC_FILENAME_ELEMENT_CLOSE = new TokenType.basic ("</filename>");
+ GTKDOC_FILENAME_ELEMENT_OPEN = new TokenType.basic ("<filename>");
+ GTKDOC_SIMPLELIST_ELEMENT_CLOSE = new TokenType.basic ("</simplelist>");
+ GTKDOC_SIMPLELIST_ELEMENT_OPEN = new TokenType.basic ("<simplelist>");
+ GTKDOC_MEMBER_ELEMENT_CLOSE = new TokenType.basic ("</member>");
+ GTKDOC_MEMBER_ELEMENT_OPEN = new TokenType.basic ("<member>");
+ GTKDOC_DOT = new TokenType.basic (".");
+ GTKDOC_ANY_WORD = ANY_WORD;
+ GTKDOC_EOL = TokenType.EOL;
+ GTKDOC_SPACE = SPACE;
+ GTKDOC_EOF = EOF;
+
initialized = true;
}
}
diff --git a/src/libvaladoc/settings.vala b/src/libvaladoc/settings.vala
index eca9f1c..f531136 100755
--- a/src/libvaladoc/settings.vala
+++ b/src/libvaladoc/settings.vala
@@ -46,7 +46,6 @@ public class Valadoc.Settings : Object {
public string[] defines;
public string[] vapi_directories;
- public string[] docu_directories;
}
diff --git a/src/libvaladoc/taglets/tagletlink.vala b/src/libvaladoc/taglets/tagletlink.vala
index a25976d..ad77b4c 100755
--- a/src/libvaladoc/taglets/tagletlink.vala
+++ b/src/libvaladoc/taglets/tagletlink.vala
@@ -25,7 +25,7 @@ using Valadoc.Content;
public class Valadoc.Taglets.Link : InlineTaglet {
- public string symbol_name { private set; get; }
+ public string symbol_name { internal set; get; }
private Api.Node _symbol;
@@ -36,10 +36,19 @@ public class Valadoc.Taglets.Link : InlineTaglet {
}
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_name.has_prefix ("c::")) {
+ _symbol_name = _symbol_name.offset (3);
+ _symbol = api_root.search_symbol_cstr (symbol_name);
+ if (_symbol != null) {
+ symbol_name = _symbol.name;
+ }
+ } else {
+ _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));
+ reporter.simple_warning ("%s does not exist".printf (symbol_name));
}
base.check (api_root, container, reporter, settings);
diff --git a/src/libvaladoc/taglets/tagletparam.vala b/src/libvaladoc/taglets/tagletparam.vala
index a4f1694..d0c7eff 100755
--- a/src/libvaladoc/taglets/tagletparam.vala
+++ b/src/libvaladoc/taglets/tagletparam.vala
@@ -25,7 +25,7 @@ using Valadoc.Content;
public class Valadoc.Taglets.Param : InlineContent, Taglet, Block {
- public string parameter_name { private set; get; }
+ public string parameter_name { internal set; get; }
public Rule? get_parser_rule (Rule run_rule) {
return Rule.seq ({
diff --git a/src/libvaladoc/taglets/tagletsee.vala b/src/libvaladoc/taglets/tagletsee.vala
index 6610d98..e1b3dc5 100755
--- a/src/libvaladoc/taglets/tagletsee.vala
+++ b/src/libvaladoc/taglets/tagletsee.vala
@@ -35,10 +35,19 @@ public class Valadoc.Taglets.See : ContentElement, Taglet, Block {
}
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_name.has_prefix ("c::")) {
+ symbol_name = symbol_name.offset (3);
+ symbol = api_root.search_symbol_cstr (symbol_name);
+ if (symbol != null) {
+ symbol_name = _symbol.name;
+ }
+ } else {
+ 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));
+ reporter.simple_warning ("%s does not exist".printf (symbol_name));
}
}
diff --git a/src/valadoc/valadoc.vala b/src/valadoc/valadoc.vala
index 2bdeb5c..8946dba 100755
--- a/src/valadoc/valadoc.vala
+++ b/src/valadoc/valadoc.vala
@@ -21,6 +21,7 @@
*/
using GLib.Path;
+using Valadoc.Importer;
using Valadoc;
using Config;
using Gee;
@@ -54,9 +55,10 @@ public class ValaDoc : Object {
private static bool experimental_non_null = false;
private static bool disable_dbus_transformation;
private static string profile;
-
[CCode (array_length = false, array_null_terminated = true)]
- private static string[] docu_directories;
+ private static string[] import_packages;
+ [CCode (array_length = false, array_null_terminated = true)]
+ private static string[] import_directories;
[CCode (array_length = false, array_null_terminated = true)]
private static string[] vapi_directories;
[CCode (array_length = false, array_null_terminated = true)]
@@ -73,11 +75,11 @@ public class ValaDoc : Object {
{ "enable-experimental-non-null", 0, 0, OptionArg.NONE, ref experimental_non_null, "Enable experimental enhancements for non-null types", null },
{ "disable-dbus-transformation", 0, 0, OptionArg.NONE, ref disable_dbus_transformation, "Disable transformation of D-Bus member names", null },
{ "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, ref vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
- { "docudir", 0, 0, OptionArg.FILENAME_ARRAY, ref docu_directories, "Look for external documentation in DIRECTORY", "DIRECTORY..." },
+ { "importdir", 0, 0, OptionArg.FILENAME_ARRAY, ref import_directories, "Look for external documentation in DIRECTORY", "DIRECTORY..." },
{ "profile", 0, 0, OptionArg.STRING, ref profile, "Use the given profile instead of the default", "PROFILE" },
-
{ "pkg", 0, 0, OptionArg.STRING_ARRAY, ref packages, "Include binding for PACKAGE", "PACKAGE..." },
+ { "import", 0, 0, OptionArg.STRING_ARRAY, ref import_packages, "Include binding for PACKAGE", "PACKAGE..." },
{ "directory", 'o', 0, OptionArg.FILENAME, ref directory, "Output directory", "DIRECTORY" },
{ "wiki", 0, 0, OptionArg.FILENAME, ref wikidirectory, "Wiki directory", "DIRECTORY" },
@@ -155,7 +157,6 @@ public class ValaDoc : Object {
settings.basedir = basedir;
settings.directory = directory;
settings.vapi_directories = vapi_directories;
- settings.docu_directories = docu_directories;
settings.profile = profile;
settings.defines = defines;
@@ -163,19 +164,16 @@ public class ValaDoc : Object {
string fulldirpath = "";
if (pluginpath == null) {
fulldirpath = build_filename (Config.plugin_dir, "html");
- }
- else if ( is_absolute (pluginpath ) == false) {
+ } else if (is_absolute (pluginpath ) == false) {
// Test to see if the plugin exists in the expanded path and then fallback
// to using the configured plugin directory
string local_path = build_filename (Environment.get_current_dir(), pluginpath);
if ( FileUtils.test(local_path, FileTest.EXISTS)) {
fulldirpath = local_path;
- }
- else {
+ } else {
fulldirpath = build_filename (Config.plugin_dir, pluginpath);
}
- }
- else {
+ } else {
fulldirpath = pluginpath;
}
@@ -211,6 +209,12 @@ public class ValaDoc : Object {
return quit (reporter);
}
+ var gir_importer = new GirDocumentationImporter (doctree, docparser, modules, settings);
+ doctree.import_documentation (gir_importer, import_packages, import_directories);
+ if (reporter.errors > 0) {
+ return quit (reporter);
+ }
+
modules.doclet.process (settings, doctree);
return quit (reporter);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]