[valadoc] Improve { inheritDoc}



commit 81151dab07508e1657ddf252a11672c0b1868e7a
Author: Florian Brosch <flo brosch gmail com>
Date:   Tue Oct 2 01:50:26 2012 +0200

    Improve { inheritDoc}

 src/libvaladoc/content/blockcontent.vala     |    1 +
 src/libvaladoc/content/comment.vala          |   32 +++++-
 src/libvaladoc/content/contentelement.vala   |    4 +
 src/libvaladoc/content/embedded.vala         |   15 +++
 src/libvaladoc/content/headline.vala         |   16 ++-
 src/libvaladoc/content/inlinecontent.vala    |    1 +
 src/libvaladoc/content/inlinetaglet.vala     |    2 +
 src/libvaladoc/content/link.vala             |   14 ++
 src/libvaladoc/content/list.vala             |   14 ++
 src/libvaladoc/content/listitem.vala         |   12 ++
 src/libvaladoc/content/note.vala             |   12 ++
 src/libvaladoc/content/page.vala             |   14 ++
 src/libvaladoc/content/paragraph.vala        |   16 +++
 src/libvaladoc/content/run.vala              |   12 ++
 src/libvaladoc/content/sourcecode.vala       |   10 ++
 src/libvaladoc/content/symbollink.vala       |    6 +
 src/libvaladoc/content/table.vala            |   13 ++
 src/libvaladoc/content/tablecell.vala        |   18 +++
 src/libvaladoc/content/tablerow.vala         |   13 ++
 src/libvaladoc/content/taglet.vala           |    8 ++
 src/libvaladoc/content/text.vala             |    6 +
 src/libvaladoc/content/warning.vala          |   12 ++
 src/libvaladoc/content/wikilink.vala         |   23 +++-
 src/libvaladoc/taglets/tagletdeprecated.vala |   12 ++
 src/libvaladoc/taglets/tagletinheritdoc.vala |  175 ++++++++++++++++++++++++-
 src/libvaladoc/taglets/tagletlink.vala       |   14 ++
 src/libvaladoc/taglets/tagletparam.vala      |   29 +++++
 src/libvaladoc/taglets/tagletreturn.vala     |   20 +++
 src/libvaladoc/taglets/tagletsee.vala        |   11 ++-
 src/libvaladoc/taglets/tagletsince.vala      |   10 ++
 src/libvaladoc/taglets/tagletthrows.vala     |   28 ++++
 31 files changed, 557 insertions(+), 16 deletions(-)
---
diff --git a/src/libvaladoc/content/blockcontent.vala b/src/libvaladoc/content/blockcontent.vala
index d3d8a98..54d9e56 100644
--- a/src/libvaladoc/content/blockcontent.vala
+++ b/src/libvaladoc/content/blockcontent.vala
@@ -37,6 +37,7 @@ public abstract class Valadoc.Content.BlockContent : ContentElement {
 
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
 		foreach (Block element in _content) {
+			element.parent = this;
 			element.check (api_root, container, file_path, reporter, settings);
 		}
 	}
diff --git a/src/libvaladoc/content/comment.vala b/src/libvaladoc/content/comment.vala
index 0c6f449..6f036c0 100644
--- a/src/libvaladoc/content/comment.vala
+++ b/src/libvaladoc/content/comment.vala
@@ -21,12 +21,14 @@
  * 	Didier 'Ptitjes Villevalois <ptitjes free fr>
  */
 
+using Valadoc.Taglets;
 using Gee;
 
 
 public class Valadoc.Content.Comment : BlockContent {
-	public Gee.List<Taglet> taglets { get { return _taglets; } }
+	private Gee.LinkedList<InheritDoc> inheritdocs = new Gee.LinkedList<InheritDoc> ();
 
+	public Gee.List<Taglet> taglets { get { return _taglets; } }
 	private Gee.List<Taglet> _taglets;
 
 	internal Comment () {
@@ -34,6 +36,10 @@ public class Valadoc.Content.Comment : BlockContent {
 		_taglets = new ArrayList<Taglet> ();
 	}
 
+	internal void register_inheritdoc (InheritDoc taglet) {
+		inheritdocs.add (taglet);
+	}
+
 	public override void configure (Settings settings, ResourceLocator locator) {
 	}
 
@@ -41,8 +47,13 @@ public class Valadoc.Content.Comment : BlockContent {
 		base.check (api_root, container, file_path, reporter, settings);
 
 		foreach (Taglet element in _taglets) {
+			element.parent = this;
 			element.check (api_root, container, file_path, reporter, settings);
 		}
+
+		foreach (InheritDoc element in inheritdocs) {
+			element.transform (api_root, container, file_path, reporter, settings);
+		}
 	}
 
 	public override void accept (ContentVisitor visitor) {
@@ -70,5 +81,24 @@ public class Valadoc.Content.Comment : BlockContent {
 
 		return selected_taglets;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		assert (new_parent == null);
+
+		Comment comment = new Comment ();
+		comment.parent = new_parent;
+
+		foreach (Block element in content) {
+			Block copy = element.copy (comment) as Block;
+			comment.content.add (copy);
+		}
+
+		foreach (Taglet taglet in _taglets) {
+			Taglet copy = taglet.copy (comment) as Taglet;
+			comment.taglets.add (copy);
+		}
+
+		return comment;
+	}
 }
 
diff --git a/src/libvaladoc/content/contentelement.vala b/src/libvaladoc/content/contentelement.vala
index be15e5b..dbec72d 100644
--- a/src/libvaladoc/content/contentelement.vala
+++ b/src/libvaladoc/content/contentelement.vala
@@ -25,6 +25,10 @@ using GLib;
 
 
 public abstract class Valadoc.Content.ContentElement : Object {
+	public ContentElement parent { get; internal set; }
+
+	public abstract ContentElement copy (ContentElement? new_parent = null);
+
 
 	public virtual void configure (Settings settings, ResourceLocator locator) {
 	}
diff --git a/src/libvaladoc/content/embedded.vala b/src/libvaladoc/content/embedded.vala
index d287ca7..bdfdbb6 100644
--- a/src/libvaladoc/content/embedded.vala
+++ b/src/libvaladoc/content/embedded.vala
@@ -70,4 +70,19 @@ public class Valadoc.Content.Embedded : ContentElement, Inline, StyleAttributes
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Embedded embedded = new Embedded ();
+		embedded.parent = new_parent;
+
+		embedded.horizontal_align = horizontal_align;
+		embedded.vertical_align = vertical_align;
+		embedded._locator = _locator;
+		embedded.caption = caption;
+		embedded.package = package;
+		embedded.style = style;
+		embedded.url = url;
+
+		return embedded;
+	}
 }
diff --git a/src/libvaladoc/content/headline.vala b/src/libvaladoc/content/headline.vala
index 36b19c2..3f7150c 100644
--- a/src/libvaladoc/content/headline.vala
+++ b/src/libvaladoc/content/headline.vala
@@ -24,7 +24,7 @@
 using Gee;
 
 
-public class Valadoc.Content.Headline : Block, InlineContent {
+public class Valadoc.Content.Headline : InlineContent, Block {
 	public int level { get; set; }
 
 	internal Headline () {
@@ -44,9 +44,21 @@ public class Valadoc.Content.Headline : Block, InlineContent {
 		visitor.visit_headline (this);
 	}
 
-
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Headline headline = new Headline ();
+		headline.parent = new_parent;
+		headline.level = level;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (headline) as Inline;
+			headline.content.add (copy);
+		}
+
+		return headline;
+	}
 }
 
diff --git a/src/libvaladoc/content/inlinecontent.vala b/src/libvaladoc/content/inlinecontent.vala
index 119f056..f3c47f1 100644
--- a/src/libvaladoc/content/inlinecontent.vala
+++ b/src/libvaladoc/content/inlinecontent.vala
@@ -38,6 +38,7 @@ public abstract class Valadoc.Content.InlineContent : ContentElement {
 
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
 		foreach (Inline element in _content) {
+			element.parent = this;
 			element.check (api_root, container, file_path, reporter, settings);
 		}
 	}
diff --git a/src/libvaladoc/content/inlinetaglet.vala b/src/libvaladoc/content/inlinetaglet.vala
index 1513950..6b7e817 100644
--- a/src/libvaladoc/content/inlinetaglet.vala
+++ b/src/libvaladoc/content/inlinetaglet.vala
@@ -51,6 +51,8 @@ public abstract class Valadoc.Content.InlineTaglet : ContentElement, Taglet, Inl
 
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
 		ContentElement element = get_content ();
+		element.parent = this;
+
 		element.check (api_root, container, file_path, reporter, settings);
 	}
 
diff --git a/src/libvaladoc/content/link.vala b/src/libvaladoc/content/link.vala
index e264898..20fd095 100644
--- a/src/libvaladoc/content/link.vala
+++ b/src/libvaladoc/content/link.vala
@@ -35,6 +35,7 @@ public class Valadoc.Content.Link : InlineContent, Inline {
 	}
 
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
+		base.check (api_root, container, file_path, reporter, settings);
 		//TODO: check url
 	}
 
@@ -45,4 +46,17 @@ public class Valadoc.Content.Link : InlineContent, Inline {
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Link link = new Link ();
+		link.parent = new_parent;
+		link.url = url;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (link) as Inline;
+			link.content.add (copy);
+		}
+
+		return link;
+	}
 }
diff --git a/src/libvaladoc/content/list.vala b/src/libvaladoc/content/list.vala
index e55489f..0b04c03 100644
--- a/src/libvaladoc/content/list.vala
+++ b/src/libvaladoc/content/list.vala
@@ -112,6 +112,7 @@ public class Valadoc.Content.List : ContentElement, Block {
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
 		// Check individual list items
 		foreach (ListItem element in _items) {
+			element.parent = this;
 			element.check (api_root, container, file_path, reporter, settings);
 		}
 	}
@@ -129,4 +130,17 @@ public class Valadoc.Content.List : ContentElement, Block {
 	public override bool is_empty () {
 		return _items.size == 0;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Content.List list = new Content.List ();
+		list.parent = new_parent;
+		list.bullet = bullet;
+
+		foreach (ListItem item in items) {
+			ListItem copy = item.copy (list) as ListItem;
+			list.items.add (copy);
+		}
+
+		return list;
+	}
 }
diff --git a/src/libvaladoc/content/listitem.vala b/src/libvaladoc/content/listitem.vala
index 98104b7..00a112a 100644
--- a/src/libvaladoc/content/listitem.vala
+++ b/src/libvaladoc/content/listitem.vala
@@ -42,4 +42,16 @@ public class Valadoc.Content.ListItem : BlockContent {
 	public override void accept_children (ContentVisitor visitor) {
 		base.accept_children (visitor);
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		ListItem item = new ListItem ();
+		item.parent = new_parent;
+
+		foreach (Block block in content) {
+			Block copy = block.copy (item) as Block;
+			item.content.add (copy);
+		}
+
+		return item;
+	}
 }
diff --git a/src/libvaladoc/content/note.vala b/src/libvaladoc/content/note.vala
index 40bb930..c8b24e4 100644
--- a/src/libvaladoc/content/note.vala
+++ b/src/libvaladoc/content/note.vala
@@ -37,5 +37,17 @@ public class Valadoc.Content.Note : BlockContent, Block {
 	public override void accept (ContentVisitor visitor) {
 		visitor.visit_note (this);
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Note note = new Note ();
+		note.parent = new_parent;
+
+		foreach (Block block in content) {
+			Block copy = block.copy (note) as Block;
+			note.content.add (copy);
+		}
+
+		return note;
+	}
 }
 
diff --git a/src/libvaladoc/content/page.vala b/src/libvaladoc/content/page.vala
index c01bd88..662ee89 100644
--- a/src/libvaladoc/content/page.vala
+++ b/src/libvaladoc/content/page.vala
@@ -31,5 +31,19 @@ public class Valadoc.Content.Page : BlockContent {
 	public override void accept (ContentVisitor visitor) {
 		visitor.visit_page (this);
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		assert (new_parent == null);
+
+		Content.Page page = new Content.Page ();
+		page.parent = new_parent;
+
+		foreach (Block block in content) {
+			Block copy = block.copy (page) as Block;
+			page.content.add (copy);
+		}
+
+		return page;
+	}
 }
 
diff --git a/src/libvaladoc/content/paragraph.vala b/src/libvaladoc/content/paragraph.vala
index 4998952..d50859d 100644
--- a/src/libvaladoc/content/paragraph.vala
+++ b/src/libvaladoc/content/paragraph.vala
@@ -41,5 +41,21 @@ public class Valadoc.Content.Paragraph : InlineContent, Block, StyleAttributes {
 	public override void accept (ContentVisitor visitor) {
 		visitor.visit_paragraph (this);
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Paragraph p = new Paragraph ();
+		p.parent = new_parent;
+
+		p.horizontal_align = horizontal_align;
+		p.vertical_align = vertical_align;
+		p.style = style;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (p) as Inline;
+			p.content.add (copy);
+		}
+
+		return p;
+	}
 }
 
diff --git a/src/libvaladoc/content/run.vala b/src/libvaladoc/content/run.vala
index 146d9c2..15a9501 100644
--- a/src/libvaladoc/content/run.vala
+++ b/src/libvaladoc/content/run.vala
@@ -126,5 +126,17 @@ public class Valadoc.Content.Run : InlineContent, Inline {
 	public override void accept (ContentVisitor visitor) {
 		visitor.visit_run (this);
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Run run = new Run (style);
+		run.parent = new_parent;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (run) as Inline;
+			run.content.add (copy);
+		}
+
+		return run;
+	}
 }
 
diff --git a/src/libvaladoc/content/sourcecode.vala b/src/libvaladoc/content/sourcecode.vala
index 70851d3..86ad66f 100644
--- a/src/libvaladoc/content/sourcecode.vala
+++ b/src/libvaladoc/content/sourcecode.vala
@@ -154,4 +154,14 @@ public class Valadoc.Content.SourceCode : ContentElement, Inline {
 		// empty source blocks are visible as well
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		SourceCode source_code = new SourceCode ();
+		source_code.parent = new_parent;
+
+		source_code.language = language;
+		source_code.code = code;
+
+		return source_code;
+	}
 }
diff --git a/src/libvaladoc/content/symbollink.vala b/src/libvaladoc/content/symbollink.vala
index aff9476..a73b488 100644
--- a/src/libvaladoc/content/symbollink.vala
+++ b/src/libvaladoc/content/symbollink.vala
@@ -47,5 +47,11 @@ public class Valadoc.Content.SymbolLink : ContentElement, Inline {
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		SymbolLink link = new SymbolLink (symbol, label);
+		link.parent = new_parent;
+		return link;
+	}
 }
 
diff --git a/src/libvaladoc/content/table.vala b/src/libvaladoc/content/table.vala
index 17fa589..962b063 100644
--- a/src/libvaladoc/content/table.vala
+++ b/src/libvaladoc/content/table.vala
@@ -39,6 +39,7 @@ public class Valadoc.Content.Table : ContentElement, Block {
 
 		// Check individual rows
 		foreach (var row in _rows) {
+			row.parent = this;
 			row.check (api_root, container, file_path, reporter, settings);
 		}
 	}
@@ -56,5 +57,17 @@ public class Valadoc.Content.Table : ContentElement, Block {
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Table table = new Table ();
+		table.parent = new_parent;
+
+		foreach (var row in _rows) {
+			TableRow copy = row.copy (table) as TableRow;
+			table.rows.add (copy);
+		}
+
+		return table;
+	}
 }
 
diff --git a/src/libvaladoc/content/tablecell.vala b/src/libvaladoc/content/tablecell.vala
index 733aad1..bf83e7d 100644
--- a/src/libvaladoc/content/tablecell.vala
+++ b/src/libvaladoc/content/tablecell.vala
@@ -50,5 +50,23 @@ public class Valadoc.Content.TableCell : InlineContent, StyleAttributes {
 		// empty cells are displayed as well
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		TableCell cell = new TableCell ();
+		cell.parent = new_parent;
+
+		cell.horizontal_align = horizontal_align;
+		cell.vertical_align = vertical_align;
+		cell.colspan = colspan;
+		cell.rowspan = rowspan;
+		cell.style = style;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (cell) as Inline;
+			cell.content.add (copy);
+		}
+
+		return cell;
+	}
 }
 
diff --git a/src/libvaladoc/content/tablerow.vala b/src/libvaladoc/content/tablerow.vala
index 5cd59fd..1ab62cc 100644
--- a/src/libvaladoc/content/tablerow.vala
+++ b/src/libvaladoc/content/tablerow.vala
@@ -37,6 +37,7 @@ public class Valadoc.Content.TableRow : ContentElement {
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
 		// Check individual cells
 		foreach (var cell in _cells) {
+			cell.parent = this;
 			cell.check (api_root, container, file_path, reporter, settings);
 		}
 	}
@@ -54,5 +55,17 @@ public class Valadoc.Content.TableRow : ContentElement {
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		TableRow row = new TableRow ();
+		row.parent = new_parent;
+
+		foreach (TableCell cell in _cells) {
+			TableCell copy = cell.copy (row) as TableCell;
+			row.cells.add (copy);
+		}
+
+		return row;
+	}
 }
 
diff --git a/src/libvaladoc/content/taglet.vala b/src/libvaladoc/content/taglet.vala
index 503cb7c..a8fc4f1 100644
--- a/src/libvaladoc/content/taglet.vala
+++ b/src/libvaladoc/content/taglet.vala
@@ -26,5 +26,13 @@ using Gee;
 public interface Valadoc.Content.Taglet : ContentElement {
 
 	public abstract Rule? get_parser_rule (Rule run_rule);
+
+	public virtual Gee.List<Inline>? get_inheritable_documentation () {
+		return null;
+	}
+
+	public virtual bool inheritable (Taglet taglet) {
+		return false;
+	}
 }
 
diff --git a/src/libvaladoc/content/text.vala b/src/libvaladoc/content/text.vala
index 6d3877e..d163939 100644
--- a/src/libvaladoc/content/text.vala
+++ b/src/libvaladoc/content/text.vala
@@ -48,5 +48,11 @@ public class Valadoc.Content.Text : ContentElement, Inline {
 	public override bool is_empty () {
 		return content == "";
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Text text = new Text (content);
+		text.parent = new_parent;
+		return text;
+	}
 }
 
diff --git a/src/libvaladoc/content/warning.vala b/src/libvaladoc/content/warning.vala
index 3ab9b3c..d98fbd7 100644
--- a/src/libvaladoc/content/warning.vala
+++ b/src/libvaladoc/content/warning.vala
@@ -37,5 +37,17 @@ public class Valadoc.Content.Warning : BlockContent, Block {
 	public override void accept (ContentVisitor visitor) {
 		visitor.visit_warning (this);
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Warning warning = new Warning ();
+		warning.parent = new_parent;
+
+		foreach (Block block in content) {
+			Block copy = block.copy (warning) as Block;
+			warning.content.add (copy);
+		}
+
+		return warning;
+	}
 }
 
diff --git a/src/libvaladoc/content/wikilink.vala b/src/libvaladoc/content/wikilink.vala
index 5d0d22c..2592b87 100644
--- a/src/libvaladoc/content/wikilink.vala
+++ b/src/libvaladoc/content/wikilink.vala
@@ -25,17 +25,16 @@ using Gee;
 
 
 public class Valadoc.Content.WikiLink : InlineContent, Inline {
-	public WikiPage page { get; private set; }
+	public WikiPage page { get; internal set; }
 	public string name { get; set; }
 
 	internal WikiLink () {
 		base ();
 	}
 
-	public override void configure (Settings settings, ResourceLocator locator) {
-	}
-
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
+		base.check (api_root, container, file_path, reporter, settings);
+
 		page = api_root.wikitree.search (name);
 		if (page == null) {
 			string node_segment = (container is Api.Package)? "" : container.get_full_name () + ": ";
@@ -48,8 +47,22 @@ public class Valadoc.Content.WikiLink : InlineContent, Inline {
 		visitor.visit_wiki_link (this);
 	}
 
-
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		WikiLink link = new WikiLink ();
+		link.parent = new_parent;
+
+		link.page = page;
+		link.name = name;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (link) as Inline;
+			link.content.add (copy);
+		}
+
+		return link;
+	}
 }
diff --git a/src/libvaladoc/taglets/tagletdeprecated.vala b/src/libvaladoc/taglets/tagletdeprecated.vala
index 0d3c192..49636ca 100644
--- a/src/libvaladoc/taglets/tagletdeprecated.vala
+++ b/src/libvaladoc/taglets/tagletdeprecated.vala
@@ -41,5 +41,17 @@ public class Valadoc.Taglets.Deprecated : InlineContent, Taglet, Block {
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Deprecated deprecated = new Deprecated ();
+		deprecated.parent = new_parent;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (deprecated) as Inline;
+			deprecated.content.add (copy);
+		}
+
+		return deprecated;
+	}
 }
 
diff --git a/src/libvaladoc/taglets/tagletinheritdoc.vala b/src/libvaladoc/taglets/tagletinheritdoc.vala
index 653a448..e2e7fdd 100644
--- a/src/libvaladoc/taglets/tagletinheritdoc.vala
+++ b/src/libvaladoc/taglets/tagletinheritdoc.vala
@@ -25,12 +25,37 @@ using Gee;
 using Valadoc.Content;
 
 public class Valadoc.Taglets.InheritDoc : InlineTaglet {
+	private Taglet? parent_taglet = null;
 	private Api.Node? _inherited;
 
+	private Comment root {
+		get {
+			ContentElement pos;
+			for (pos = this; pos.parent != null; pos = pos.parent);
+			// inheritDoc is only allowed in source comments
+			assert (pos is Comment);
+			return (Comment) pos;
+		}
+	}
+
 	public override Rule? get_parser_rule (Rule run_rule) {
 		return null;
 	}
 
+	private Taglet? find_parent_taglet () {
+		if (_inherited == null || _inherited.documentation == null) {
+			return null;
+		}
+
+		ContentElement pos;
+		for (pos = this.parent; pos != null && pos is Taglet == false; pos = pos.parent);
+		if (pos is Taglet) {
+			return (Taglet) pos;
+		}
+
+		return null;
+	}
+
 	public override void check (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
 		// TODO Check that the container is an override of an abstract symbol
 		// Also retrieve that abstract symbol _inherited
@@ -49,6 +74,12 @@ public class Valadoc.Taglets.InheritDoc : InlineTaglet {
 			api_root.push_unbrowsable_documentation_dependency (_inherited);
 		}
 
+		parent_taglet = find_parent_taglet ();
+		if (parent_taglet == null) {
+			root.register_inheritdoc (this);
+		}
+
+
 		// TODO report error if inherited is null
 
 		// TODO postpone check after complete parse of the api tree comments
@@ -56,15 +87,133 @@ public class Valadoc.Taglets.InheritDoc : InlineTaglet {
 		//base.check (api_root, container, reporter);
 	}
 
-	public override ContentElement produce_content () {
-		if (_inherited != null && _inherited.documentation != null) {
-			Paragraph inherited_paragraph = _inherited.documentation.content.get (0) as Paragraph;
+	private Run[]? split_run (Inline? separator) {
+		if (separator == null) {
+			return null;
+		}
 
-			Run paragraph = new Run (Run.Style.NONE);
-			foreach (var element in inherited_paragraph.content) {
-				paragraph.content.add (element);
+		ContentElement parent = separator.parent;
+		Gee.List<Inline> parent_content = null;
+
+		if (parent is Run && ((Run) parent).style == Run.Style.NONE) {
+			parent_content = ((Run) parent).content;
+		} else if (parent is Paragraph) {
+			parent_content = ((Paragraph) parent).content;
+		}
+
+		if (parent_content != null) {
+			Run right_run = new Run (Run.Style.NONE);
+			Run left_run = new Run (Run.Style.NONE);
+			bool separated = false;
+
+			foreach (var current in parent_content) {
+				if (current == separator) {
+					separated = true;
+				} else if (separated) {
+					right_run.content.add (current);
+					current.parent = right_run;
+				} else {
+					left_run.content.add (current);
+					current.parent = left_run;
+				}
+			}
+
+			return { left_run, right_run };
+		}
+
+		return null;
+	}
+
+	internal void transform (Api.Tree api_root, Api.Node container, string file_path, ErrorReporter reporter, Settings settings) {
+		ContentElement separator = this;
+		Run right_run = null;
+		Run left_run = null;
+		Run[]? parts;
+
+		while ((parts = split_run (separator as Inline)) != null) {
+			if (left_run != null) {
+				parts[0].content.add (left_run);
+				left_run.parent = parts[0];
+			}
+
+			if (right_run != null) {
+				parts[1].content.insert (0, right_run);
+				right_run.parent = parts[1];
+			}
+
+			separator = separator.parent;
+			right_run = parts[1];
+			left_run = parts[0];
+		}
+
+		if (separator is Paragraph == false || separator.parent is Comment == false) {
+			reporter.simple_error ("%s: %s: @inheritDoc: error: Parent documentation can't be copied to this location.", file_path, container.get_full_name ());
+			return ;
+		}
+
+		Comment comment = separator.parent as Comment;
+		assert (comment != null);
+
+		int insert_pos = comment.content.index_of ((Paragraph) separator);
+		int start_pos = insert_pos;
+		assert (insert_pos >= 0);
+
+		foreach (Block block in _inherited.documentation.content) {
+			comment.content.insert (insert_pos, (Block) block.copy (comment));
+			insert_pos++;
+		}
+
+		if (right_run != null) {
+			if (comment.content[insert_pos - 1] is Paragraph) {
+				((Paragraph) comment.content[insert_pos - 1]).content.add (right_run);
+				right_run.parent = comment.content[insert_pos - 1];
+			} else {
+				Paragraph p = new Paragraph ();
+				p.content.add (right_run);
+				right_run.parent = p;
+				p.parent = comment;
+				comment.content.insert (insert_pos, p);
+			}
+		}
+
+		if (left_run != null) {
+			if (comment.content[start_pos] is Paragraph) {
+				((Paragraph) comment.content[start_pos]).content.insert (0, left_run);
+				left_run.parent = comment.content[start_pos];
+			} else {
+				Paragraph p = new Paragraph ();
+				p.content.add (left_run);
+				left_run.parent = p;
+				p.parent = comment;
+				comment.content.insert (start_pos, p);
+			}
+		}
+
+		comment.content.remove ((Paragraph) separator);
+	}
+
+	private Run content_copy (Gee.List<Inline>? content) {
+		Run run = new Run (Run.Style.NONE);
+		run.parent = this;
+
+		if (content != null) {
+			foreach (Inline item in content) {
+				run.content.add ((Inline) item.copy (this));
+			}
+		}
+
+		return run;
+	}
+
+	public override ContentElement produce_content () {
+		if (_inherited != null && _inherited.documentation != null && parent_taglet != null) {
+			Gee.List<Taglet> parent_taglets = _inherited.documentation.find_taglets (null, parent_taglet.get_type ());
+			foreach (Taglet parent in parent_taglets) {
+				// we only care about the first match:
+				if (parent.inheritable (parent_taglet)) {
+					return content_copy (parent.get_inheritable_documentation ());
+				}
 			}
-			return paragraph;
 		}
 		return new Text ("");
 	}
@@ -72,4 +221,16 @@ public class Valadoc.Taglets.InheritDoc : InlineTaglet {
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		InheritDoc doc = new InheritDoc ();
+		doc.parent = new_parent;
+
+		doc.settings = settings;
+		doc.locator = locator;
+
+		doc._inherited = _inherited;
+
+		return doc;
+	}
 }
diff --git a/src/libvaladoc/taglets/tagletlink.vala b/src/libvaladoc/taglets/tagletlink.vala
index d49aa4b..39e4948 100644
--- a/src/libvaladoc/taglets/tagletlink.vala
+++ b/src/libvaladoc/taglets/tagletlink.vala
@@ -106,4 +106,18 @@ public class Valadoc.Taglets.Link : InlineTaglet {
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Link link = new Link ();
+		link.parent = new_parent;
+
+		link.settings = settings;
+		link.locator = locator;
+
+		link.symbol_name = symbol_name;
+		link._context = _context;
+		link._symbol = _symbol;
+
+		return link;
+	}
 }
diff --git a/src/libvaladoc/taglets/tagletparam.vala b/src/libvaladoc/taglets/tagletparam.vala
index 78e9d16..277d9b6 100644
--- a/src/libvaladoc/taglets/tagletparam.vala
+++ b/src/libvaladoc/taglets/tagletparam.vala
@@ -104,4 +104,33 @@ public class Valadoc.Taglets.Param : InlineContent, Taglet, Block {
 	public override void accept (ContentVisitor visitor) {
 		visitor.visit_taglet (this);
 	}
+
+	public Gee.List<ContentElement>? get_inheritable_documentation () {
+		return content;
+	}
+
+	public bool inheritable (Taglet taglet) {
+		if (taglet is Taglets.Param == false) {
+			return false;
+		}
+
+		Taglets.Param t = (Taglets.Param) taglet;
+		return (parameter == t.parameter || parameter_name == t.parameter_name);
+	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Param param = new Param ();
+		param.parent = new_parent;
+
+		param.parameter_name = parameter_name;
+		param.parameter = parameter;
+		param.position = position;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (param) as Inline;
+			param.content.add (copy);
+		}
+
+		return param;
+	}
 }
diff --git a/src/libvaladoc/taglets/tagletreturn.vala b/src/libvaladoc/taglets/tagletreturn.vala
index e616791..d447e6e 100644
--- a/src/libvaladoc/taglets/tagletreturn.vala
+++ b/src/libvaladoc/taglets/tagletreturn.vala
@@ -53,4 +53,24 @@ public class Valadoc.Taglets.Return : InlineContent, Taglet, Block {
 	public override void accept (ContentVisitor visitor) {
 		visitor.visit_taglet (this);
 	}
+
+	public Gee.List<ContentElement>? get_inheritable_documentation () {
+		return content;
+	}
+
+	public bool inheritable (Taglet taglet) {
+		return taglet is Taglets.Return;
+	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Return ret = new Return ();
+		ret.parent = new_parent;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (ret) as Inline;
+			ret.content.add (copy);
+		}
+
+		return ret;
+	}
 }
diff --git a/src/libvaladoc/taglets/tagletsee.vala b/src/libvaladoc/taglets/tagletsee.vala
index fe8f799..2d01998 100644
--- a/src/libvaladoc/taglets/tagletsee.vala
+++ b/src/libvaladoc/taglets/tagletsee.vala
@@ -63,4 +63,13 @@ public class Valadoc.Taglets.See : ContentElement, Taglet, Block {
 	public override bool is_empty () {
 		return false;
 	}
-}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		See see = new See ();
+		see.parent = new_parent;
+
+		see.symbol_name = symbol_name;
+		see.symbol = symbol;
+
+		return see;
+	}}
diff --git a/src/libvaladoc/taglets/tagletsince.vala b/src/libvaladoc/taglets/tagletsince.vala
index 49acafb..10b87b9 100644
--- a/src/libvaladoc/taglets/tagletsince.vala
+++ b/src/libvaladoc/taglets/tagletsince.vala
@@ -48,4 +48,14 @@ public class Valadoc.Taglets.Since : ContentElement, Taglet, Block {
 	public override bool is_empty () {
 		return false;
 	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Since since = new Since ();
+		since.parent = new_parent;
+
+		since.version = version;
+
+		return since;
+	}
 }
+
diff --git a/src/libvaladoc/taglets/tagletthrows.vala b/src/libvaladoc/taglets/tagletthrows.vala
index 2ba7fa0..2423287 100644
--- a/src/libvaladoc/taglets/tagletthrows.vala
+++ b/src/libvaladoc/taglets/tagletthrows.vala
@@ -81,5 +81,33 @@ public class Valadoc.Taglets.Throws : InlineContent, Taglet, Block {
 	public override void accept (ContentVisitor visitor) {
 		visitor.visit_taglet (this);
 	}
+
+	public Gee.List<ContentElement>? get_inheritable_documentation () {
+		return content;
+	}
+
+	public bool inheritable (Taglet taglet) {
+		if (taglet is Taglets.Throws == false) {
+			return false;
+		}
+
+		Taglets.Throws t = (Taglets.Throws) taglet;
+		return (error_domain == t.error_domain || error_domain_name == t.error_domain_name);
+	}
+
+	public override ContentElement copy (ContentElement? new_parent = null) {
+		Throws tr = new Throws ();
+		tr.parent = new_parent;
+
+		tr.error_domain_name = error_domain_name;
+		tr.error_domain = error_domain;
+
+		foreach (Inline element in content) {
+			Inline copy = element.copy (tr) as Inline;
+			tr.content.add (copy);
+		}
+
+		return tr;
+	}
 }
 



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