+# Search in class or module hierarchy of a `MEntity`.
+#
+# It actually searches for pages about the mentity and extracts the
+# pre-calculated hierarchies by the `doc_post` phase.
+abstract class HierarchiesQuery
+ super DocQuery
+
+ redef fun make_results(nitx, results) do
+ var page = new DocPage("hierarchy", "Hierarchy")
+ for result in results do
+ if not result isa PageMatch then continue
+ var rpage = result.page
+ if not rpage isa MClassPage then continue
+ page.root.add_child build_article(rpage)
+ end
+ return page
+ end
+
+ # Build an article containing the hierarchy list depending on subclasses.
+ private fun build_article(page: MClassPage): DocArticle is abstract
+end
+
+# List all parents of a `MClass`.
+class AncestorsQuery
+ super HierarchiesQuery
+
+ redef fun build_article(page) do
+ return new MEntitiesListArticle(
+ "ancerstors",
+ "Ancestors for {page.mentity.name}",
+ page.ancestors.to_a)
+ end
+end
+
+# List direct parents of a `MClass`.
+class ParentsQuery
+ super HierarchiesQuery
+
+ redef fun build_article(page) do
+ return new MEntitiesListArticle(
+ "parents",
+ "Parents for {page.mentity.name}",
+ page.parents.to_a)
+ end
+end
+
+# List direct children of a `MClass`.
+class ChildrenQuery
+ super HierarchiesQuery
+
+ redef fun build_article(page) do
+ return new MEntitiesListArticle(
+ "children",
+ "Children for {page.mentity.name}",
+ page.children.to_a)
+ end
+end
+
+# List all descendants of a `MClass`.
+class DescendantsQuery
+ super HierarchiesQuery
+
+ redef fun build_article(page) do
+ return new MEntitiesListArticle(
+ "descendants",
+ "Descendants for {page.mentity.name}",
+ page.children.to_a)
+ end
+end
+
+# A query to search source code from a file name.
+class CodeQuery
+ super MetaQuery
+
+ # FIXME refactor this!
+ redef fun perform(nitx, doc) do
+ var res = new Array[NitxMatch]
+ var name = args.first
+ # if name is an existing sourcefile, opens it
+ if name.file_exists then
+ var fr = new FileReader.open(name)
+ var content = fr.read_all
+ fr.close
+ res.add new CodeMatch(self, name, content)
+ return res
+ end
+ # else, lookup the model by name
+ for mentity in doc.mentities_by_name(name) do
+ if mentity isa MClass then continue
+ if mentity isa MProperty then continue
+ res.add new CodeMatch(self, mentity.cs_location, mentity.cs_source_code)
+ end
+ return res
+ end
+
+ redef fun make_results(nitx, results) do
+ var page = new DocPage("results", "Code Results")
+ for res in results do
+ page.add new CodeQueryArticle("results.article", "Results", self, res.as(CodeMatch))
+ end
+ return page
+ end
+end
+
+# A match between a piece of code and a string.
+class CodeMatch
+ super NitxMatch
+
+ # Location of the code match.
+ var location: String
+
+ # Piece of code matched.
+ var content: String
+
+ redef fun make_list_item do return "* {location}"
+end
+
+