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);
}
}
* 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 () {
_taglets = new ArrayList<Taglet> ();
}
+ internal void register_inheritdoc (InheritDoc taglet) {
+ inheritdocs.add (taglet);
+ }
+
public override void configure (Settings settings, ResourceLocator locator) {
}
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) {
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;
+ }
}
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) {
}
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;
+ }
}
using Gee;
-public class Valadoc.Content.Headline : Block, InlineContent {
+public class Valadoc.Content.Headline : InlineContent, Block {
public int level { get; set; }
internal Headline () {
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;
+ }
}
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);
}
}
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);
}
}
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
}
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;
+ }
}
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);
}
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
// 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;
+ }
}
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;
+ }
}
// Check individual rows
foreach (var row in _rows) {
+ row.parent = this;
row.check (api_root, container, file_path, reporter, settings);
}
}
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;
+ }
}
// 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;
+ }
}
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);
}
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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 () + ": ";
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;
+ }
}
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;
+ }
}
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
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
//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 ("");
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
+ }}
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;
+ }
}
+
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;
+ }
}