module doc_base
import toolcontext
- import model_utils
import model_ext
# The model of a Nitdoc documentation.
var root = new DocRoot
redef fun to_s do return title
+
+ # Pretty prints the content of this page.
+ fun pretty_print: Writable do
+ var res = new Template
+ res.addn "page: {title}"
+ res.addn ""
+ root.pretty_print_in(res)
+ return res
+ end
end
# `DocPage` elements that can be nested in another.
# Parent element.
var parent: nullable DocComposite = null is writable
+ # Element uniq id.
+ #
+ # The `id` is used as name for the generated element (if any).
+ # Because multiple elements can be generated in the same container
+ # it should be uniq.
+ #
+ # The `id` can also be used to establish links between elements
+ # (HTML links, HTML anchors, vim links, etc.).
+ var id: String is writable
+
+ # Item title if any.
+ var title: nullable String
+
# Does `self` have a `parent`?
fun is_root: Bool do return parent == null
# Children are ordered, this order can be changed by the `DocPhase`.
var children = new Array[DocComposite]
- # Does `self` have `children`?
- fun is_empty: Bool do return children.is_empty
+ # Is `self` not displayed in the page.
+ #
+ # By default, empty elements are hidden.
+ fun is_hidden: Bool do return children.is_empty
+
+ # Title used in table of content if any.
+ var toc_title: nullable String is writable, lazy do return title
+
+ # Is `self` hidden in the table of content?
+ var is_toc_hidden: Bool is writable, lazy do
+ return toc_title == null or is_hidden
+ end
# Add a `child` to `self`.
#
if parent == null then return 0
return parent.depth + 1
end
+
+ # Pretty prints this composite recursively.
+ fun pretty_print: Writable do
+ var res = new Template
+ pretty_print_in(res)
+ return res
+ end
+
+ # Appends the Pretty print of this composite in `res`.
+ private fun pretty_print_in(res: Template) do
+ res.add "#" * depth
+ res.addn " {id}"
+ for child in children do child.pretty_print_in(res)
+ end
end
# The `DocComposite` element that contains all the other.
# The root uses a specific subclass to provide different a different behavior
# than other `DocComposite` elements.
class DocRoot
+ noautoinit
super DocComposite
+ redef var id = "<root>"
+ redef var title = "<root>"
+
# No op for `RootSection`.
redef fun parent=(p) do end
end
# TODO filter here?
super
var mclasses = new HashSet[MClass]
- mclasses.add_all mentity.filter_intro_mclasses(v.ctx.min_visibility)
- mclasses.add_all mentity.filter_redef_mclasses(v.ctx.min_visibility)
+ mclasses.add_all mentity.collect_intro_mclasses(v.ctx.min_visibility)
+ mclasses.add_all mentity.collect_redef_mclasses(v.ctx.min_visibility)
if mclasses.is_empty then return
var list = new UnorderedList
list.css_classes.add "list-unstyled list-labeled"
if not mprop_is_local(mprop) then
classes.add "inherit"
var cls_url = mprop.intro.mclassdef.mclass.nitdoc_url
- var def_url = "{cls_url}#article:{mprop.nitdoc_id}.definition"
+ var def_url = "{cls_url}#{mprop.nitdoc_id}.definition"
var lnk = new Link(def_url, mprop.html_name)
var mdoc = mprop.intro.mdoc_or_fallback
if mdoc != null then lnk.title = mdoc.short_comment
end
var def = select_mpropdef(mprop)
var anc = def.html_link_to_anchor
- anc.href = "#article:{def.nitdoc_id}.definition"
+ anc.href = "#{def.nitdoc_id}.definition"
var lnk = new Template
lnk.add new DocHTMLLabel.with_classes(classes)
lnk.add anc
private fun mclass_inherited_mprops(v: RenderHTMLPhase, doc: DocModel): Set[MProperty] do
var res = new HashSet[MProperty]
- var local = mentity.local_mproperties(v.ctx.min_visibility)
- for mprop in mentity.inherited_mproperties(doc.mainmodule, v.ctx.min_visibility) do
+ var local = mentity.collect_local_mproperties(v.ctx.min_visibility)
+ for mprop in mentity.collect_inherited_mproperties(v.ctx.min_visibility) do
if local.has(mprop) then continue
#if mprop isa MMethod and mprop.is_init then continue
if mprop.intro.mclassdef.mclass.name == "Object" and
title.add mentity.html_signature
html_title = title
html_subtitle = mentity.html_namespace
- toc_title = mentity.html_name
+ html_toc_title = mentity.html_name
end
super
end
var mentity = self.mentity
if page isa MGroupPage then
html_title = null
- toc_title = mentity.html_name
+ html_toc_title = mentity.html_name
is_toc_hidden = false
else if page.mentity isa MModule and mentity isa MModule then
var title = new Template
if mentity == page.mentity then
title.add "in "
- toc_title = "in {mentity.html_name}"
+ html_toc_title = "in {mentity.html_name}"
else
title.add "from "
- toc_title = "from {mentity.html_name}"
+ html_toc_title = "from {mentity.html_name}"
end
title.add mentity.html_namespace
html_title = title
title.add "in "
title.add mentity.html_namespace
html_title = title
- toc_title = "in {mentity.html_name}"
+ html_toc_title = "in {mentity.html_name}"
end
super
end
title.add mentity.html_icon
title.add mentity.html_namespace
html_title = title
- toc_title = mentity.html_name
+ html_toc_title = mentity.html_name
if mentity isa MModule then
html_source_link = v.html_source_link(mentity.location)
end
title.add mentity.mmodule.html_namespace
html_title = mentity.html_declaration
html_subtitle = title
- toc_title = "in {mentity.html_name}"
+ html_toc_title = "in {mentity.html_name}"
html_source_link = v.html_source_link(mentity.location)
if page isa MEntityPage and mentity.is_intro and mentity.mmodule != page.mentity then
is_short_comment = true
title.add mentity.html_declaration
html_title = title
html_subtitle = mentity.html_namespace
- toc_title = mentity.html_name
+ html_toc_title = mentity.html_name
else
var title = new Template
title.add "in "
title.add mentity.mclassdef.html_link
html_title = title
- toc_title = "in {mentity.mclassdef.html_name}"
+ html_toc_title = "in {mentity.mclassdef.html_name}"
end
html_source_link = v.html_source_link(mentity.location)
end
redef fun init_html_render(v, doc, page) do
if v.ctx.opt_custom_title.value != null then
self.html_title = v.ctx.opt_custom_title.value.to_s
- self.toc_title = v.ctx.opt_custom_title.value.to_s
+ self.html_toc_title = v.ctx.opt_custom_title.value.to_s
end
self.content = v.ctx.opt_custom_intro.value
super
redef class GraphArticle
redef fun init_html_render(v, doc, page) do
var output_dir = v.ctx.output_dir
- var path = output_dir / id
+ var path = output_dir / graph_id
var path_sh = path.escape_to_sh
var file = new FileWriter.open("{path}.dot")
file.write(dot)
module doc_intros_redefs
import doc_structure
+ import model::model_collect
# Computes intro / redef mentity list for each DefinitionArticle.
class IntroRedefListPhase
# TODO this should move to MEntity?
private fun build_mmodule_list(v: IntroRedefListPhase, doc: DocModel, mmodule: MModule) do
- var section = new IntrosRedefsSection(mentity)
- var group = new PanelGroup("List")
+ var section = new TabbedGroup("{mentity.nitdoc_id}.intros_redefs")
+ section.toc_title = "Intros / Redefs"
+ var group = new PanelGroup("list.group", "List")
- var intros = mmodule.intro_mclassdefs(v.ctx.min_visibility).to_a
+ var intros = mmodule.collect_intro_mclassdefs(v.ctx.min_visibility).to_a
doc.mainmodule.linearize_mclassdefs(intros)
- group.add_child new IntrosRedefsListArticle(mentity, "Introduces", intros)
+ group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.intros", "Introduces", intros)
- var redefs = mmodule.redef_mclassdefs(v.ctx.min_visibility).to_a
+ var redefs = mmodule.collect_redef_mclassdefs(v.ctx.min_visibility).to_a
doc.mainmodule.linearize_mclassdefs(redefs)
- group.add_child new IntrosRedefsListArticle(mentity, "Redefines", redefs)
+ group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.redefs", "Redefines", redefs)
section.add_child group
add_child(section)
end
# TODO this should move to MEntity?
private fun build_mclassdef_list(v: IntroRedefListPhase, doc: DocModel, mclassdef: MClassDef) do
- var section = new IntrosRedefsSection(mentity)
- var group = new PanelGroup("List")
+ var section = new TabbedGroup("{mentity.nitdoc_id}.intros_redefs")
+ section.toc_title = "Intros / Redefs"
+ var group = new PanelGroup("list.group", "List")
var intros = mclassdef.collect_intro_mpropdefs(v.ctx.min_visibility).to_a
# FIXME avoid diff changes
# v.ctx.mainmodule.linearize_mpropdefs(intros)
- group.add_child new IntrosRedefsListArticle(mentity, "Introduces", intros)
+ group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.intros", "Introduces", intros)
var redefs = mclassdef.collect_redef_mpropdefs(v.ctx.min_visibility).to_a
# FIXME avoid diff changes
# v.ctx.mainmodule.linearize_mpropdefs(redefs)
- group.add_child new IntrosRedefsListArticle(mentity, "Redefines", redefs)
+ group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.redefs", "Redefines", redefs)
section.add_child group
add_child(section)
end
-
-end
-
-# Section that contains the intros and redefs lists.
-class IntrosRedefsSection
- super TabbedGroup
- super MEntitySection
-end
-
-# An article that displays a list of introduced / refined mentities.
-#
-# FIXME diff hack
-# This can merged with InheritanceListArticle in a more generic class.
-class IntrosRedefsListArticle
- super MEntityArticle
-
- # Title displayed as header of the list.
- var list_title: String
-
- # Intro mentities to list.
- var mentities: Array[MEntity]
end
module doc_poset
import doc_pages
+ import model::model_collect
# This phase computes importation and inheritance POSet for pages.
class POSetPhase
# Imported modules that should appear in the documentation.
var imports = new HashSet[MModule]
- # Clients modules that shjould appear in the documentation.
+ # Clients modules that should appear in the documentation.
var clients = new HashSet[MModule]
redef fun build_poset(v, doc) do
end
# make poset
var mmodules = new HashSet[MModule]
- mmodules.add_all mentity.nested_mmodules
+ var mgroup = mentity.mgroup
+ if mgroup != null and mgroup.default_mmodule == mentity then
+ mmodules.add_all mgroup.mmodules
+ end
mmodules.add_all imports
if clients.length < 10 then mmodules.add_all clients
mmodules.add mentity
redef class OverviewPage
redef fun apply_structure(v, doc) do
- var article = new HomeArticle
+ var article = new HomeArticle("home.article", "Home")
root.add_child article
# Projects list
var mprojects = doc.model.mprojects.to_a
var sorter = new MConcernRankSorter
sorter.sort mprojects
- var section = new ProjectsSection
+ var section = new DocSection("projects.section", "Projects")
for mproject in mprojects do
- section.add_child new DefinitionArticle(mproject)
+ section.add_child new DefinitionArticle("{mproject.nitdoc_id}.definition", mproject)
end
article.add_child section
end
v.name_sorter.sort(mclasses)
var mprops = doc.mproperties.to_a
v.name_sorter.sort(mprops)
- root.add_child new IndexArticle(mmodules, mclasses, mprops)
+ root.add_child new IndexArticle("index.article", mmodules, mclasses, mprops)
end
end
redef class MGroupPage
redef fun apply_structure(v, doc) do
- var section = new MEntitySection(mentity)
+ var section = new MEntitySection("{mentity.nitdoc_name}.section", mentity)
root.add_child section
if mentity.is_root then
- section.add_child new IntroArticle(mentity.mproject)
+ section.add_child new IntroArticle("{mentity.mproject.nitdoc_id}.intro", mentity.mproject)
else
- section.add_child new IntroArticle(mentity)
+ section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", mentity)
end
var concerns = self.concerns
if concerns == null or concerns.is_empty then return
concerns.sort_with(v.concerns_sorter)
mentity.mproject.booster_rank = 0
mentity.booster_rank = 0
- section.add_child new ConcernsArticle(mentity, concerns)
+ section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", mentity, concerns)
for mentity in concerns do
- var ssection = new ConcernSection(mentity)
+ var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", mentity)
if mentity isa MModule then
- ssection.add_child new DefinitionArticle(mentity)
+ ssection.add_child new DefinitionArticle("{mentity.nitdoc_id}.definition", mentity)
end
section.add_child ssection
end
redef class MModulePage
redef fun apply_structure(v, doc) do
- var section = new MEntitySection(mentity)
+ var section = new MEntitySection("{mentity.nitdoc_name}.section", mentity)
root.add_child section
- section.add_child new IntroArticle(mentity)
+ section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", mentity)
var concerns = self.concerns
if concerns == null or concerns.is_empty then return
# FIXME avoid diff
mentity.mgroup.mproject.booster_rank = 0
mentity.mgroup.booster_rank = 0
mentity.booster_rank = 0
- section.add_child new ConcernsArticle(mentity, concerns)
+ section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", mentity, concerns)
# reference list
for mentity in concerns do
- var ssection = new ConcernSection(mentity)
+ var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", mentity)
if mentity isa MModule then
var mclasses = mclasses_for_mmodule(mentity).to_a
v.name_sorter.sort(mclasses)
for mclass in mclasses do
- var article = new DefinitionListArticle(mclass)
+ var article = new DefinitionListArticle(
+ "{mclass.intro.nitdoc_id}.definition-list", mclass)
var mclassdefs = mclassdefs_for(mclass).to_a
if not mclassdefs.has(mclass.intro) then
- article.add_child(new DefinitionArticle(mclass.intro))
+ article.add_child(new DefinitionArticle(
+ "{mclass.intro.nitdoc_id}.definition", mclass.intro))
end
doc.mainmodule.linearize_mclassdefs(mclassdefs)
for mclassdef in mclassdefs do
- article.add_child(new DefinitionArticle(mclassdef))
+ article.add_child(new DefinitionArticle(
+ "{mclassdef.nitdoc_id}.definition", mclassdef))
end
ssection.add_child article
end
redef class MClassPage
redef fun apply_structure(v, doc) do
- var section = new MEntitySection(mentity)
+ var section = new MEntitySection("{mentity.nitdoc_name}.section", mentity)
root.add_child section
- section.add_child new IntroArticle(mentity)
+ section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", mentity)
var concerns = self.concerns
if concerns == null or concerns.is_empty then return
# FIXME diff hack
mentity.intro_mmodule.mgroup.mproject.booster_rank = 0
mentity.intro_mmodule.mgroup.booster_rank = 0
mentity.intro_mmodule.booster_rank = 0
- var constructors = new ConstructorsSection(mentity)
+ var constructors = new DocSection("{mentity.nitdoc_id}.constructors", "Constructors")
var minit = mentity.root_init
if minit != null then
- constructors.add_child new DefinitionArticle(minit)
+ constructors.add_child new DefinitionArticle("{minit.nitdoc_id}.definition", minit)
end
section.add_child constructors
- section.add_child new ConcernsArticle(mentity, concerns)
+ section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", mentity, concerns)
for mentity in concerns do
- var ssection = new ConcernSection(mentity)
+ var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", mentity)
if mentity isa MModule then
var mprops = mproperties_for(mentity)
var by_kind = new PropertiesByKind.with_elements(mprops)
for mpropdef in mpropdefs_for(mprop, mentity) do
if mpropdef isa MMethodDef and mpropdef.mproperty.is_init then
if mpropdef == minit then continue
- constructors.add_child new DefinitionArticle(mpropdef)
+ constructors.add_child new DefinitionArticle(
+ "{mpropdef.nitdoc_id}.definition", mpropdef)
else
- ssection.add_child new DefinitionArticle(mpropdef)
+ ssection.add_child new DefinitionArticle(
+ "{mpropdef.nitdoc_id}.definition", mpropdef)
end
end
end
redef class MPropertyPage
redef fun apply_structure(v, doc) do
- var section = new MEntitySection(mentity)
+ var section = new MEntitySection("{mentity.nitdoc_name}.section", mentity)
root.add_child section
- section.add_child new IntroArticle(mentity)
+ section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", mentity)
var concerns = self.concerns
if concerns == null or concerns.is_empty then return
# FIXME diff hack
mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = 0
mentity.intro.mclassdef.mmodule.mgroup.booster_rank = 0
mentity.intro.mclassdef.mmodule.booster_rank = 0
- section.add_child new ConcernsArticle(mentity, concerns)
+ section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", mentity, concerns)
for mentity in concerns do
- var ssection = new ConcernSection(mentity)
+ var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", mentity)
if mentity isa MModule then
# Add mproperties
var mpropdefs = mpropdefs_for(mentity).to_a
v.name_sorter.sort(mpropdefs)
for mpropdef in mpropdefs do
- ssection.add_child new DefinitionArticle(mpropdef)
+ ssection.add_child new DefinitionArticle(
+ "{mpropdef.nitdoc_id}.definition", mpropdef)
end
end
section.add_child ssection
# A group of sections that can be displayed together in a tab panel.
class PanelGroup
super DocSection
-
- # The title of this group.
- var group_title: String
end
# A DocComposite element about a MEntity.
class MEntityComposite
super DocComposite
+ redef fun title do return mentity.nitdoc_name
+
# MEntity documented by this page element.
var mentity: MEntity
end
-# A list of constructors.
-class ConstructorsSection
- super MEntitySection
-end
-
# A Section about a Concern.
#
# Those sections are used to build the page summary.
class ConcernSection
super MEntityComposite
super DocSection
+
+ redef fun is_toc_hidden do return is_hidden
end
# An article about a Mentity.
super DocArticle
end
+# An article that displays a list of mentities.
+class MEntitiesListArticle
+ super DocArticle
+
+ # MEntities to display.
+ var mentities: Array[MEntity]
+
+ redef fun is_hidden do return mentities.is_empty
+end
+
+
# A section about a Mentity.
#
# Used to regroup content about a MEntity.
class IntroArticle
super MEntityComposite
super DocArticle
+
+ redef var is_hidden = false
+ redef var is_toc_hidden = true
end
# An article that display a ConcernsTreee as a list.
# Concerns to list in this article.
var concerns: ConcernsTree
+
+ redef fun is_hidden do return concerns.is_empty
end
-# An article that displaus a list of definition belonging to a MEntity.
+# An article that displays a list of definition belonging to a MEntity.
class DefinitionListArticle
super TabbedGroup
super MEntityArticle
# An article that display the definition text of a MEntity.
class DefinitionArticle
super MEntityArticle
+
+ redef var is_hidden = false
end
# The main project article.
super DocArticle
end
-# The project list.
-class ProjectsSection
- super DocArticle
-end
-
# An article that display an index of mmodules, mclasses and mproperties.
class IndexArticle
super DocArticle
# List of mproperties to display.
var mprops: Array[MProperty]
+
+ redef fun is_hidden do
+ return mmodules.is_empty and mclasses.is_empty and mprops.is_empty
+ end
end
+
+ # Concerns ranking
+
+ # Sort MConcerns based on the module importation hierarchy ranking
+ # see also: `MConcern::concern_rank` and `MConcern::booster_rank`
+ #
+ # Comparison is made with the formula:
+ #
+ # ~~~nitish
+ # a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_ran
+ # ~~~
+ #
+ # If both `a` and `b` have the same ranking,
+ # ordering is based on lexicographic comparison of `a.name` and `b.name`
+ class MConcernRankSorter
+ super Comparator
+ redef type COMPARED: MConcern
+
+ redef fun compare(a, b) do
+ if a.concern_rank == b.concern_rank then
+ return a.name <=> b.name
+ end
+ return a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_rank
+ end
+ end
+
+ redef class MConcern
+
+ # Boost a MConcern rank
+ # see: `MConcernRankSorter`
+ # Use a positive booster to push down a result in the list
+ # A negative booster can be used to push up the result
+ var booster_rank: Int = 0 is writable
+
+ # Concern ranking used for ordering
+ # see: `MConcernRankSorter`
+ # Rank can be positive or negative
+ fun concern_rank: Int is abstract
+ end
+
+ redef class MProject
+ redef var concern_rank is lazy do
+ var max = 0
+ for mgroup in mgroups do
+ var mmax = mgroup.concern_rank
+ if mmax > max then max = mmax
+ end
+ return max + 1
+ end
+ end
+
+ redef class MGroup
+ redef var concern_rank is lazy do
+ var max = 0
+ for mmodule in mmodules do
+ var mmax = mmodule.concern_rank
+ if mmax > max then max = mmax
+ end
+ return max + 1
+ end
+ end
+
+ redef class MModule
+ redef var concern_rank is lazy do
+ var max = 0
+ for p in in_importation.direct_greaters do
+ var pmax = p.concern_rank
+ if pmax > max then max = pmax
+ end
+ return max + 1
+ end
+ end
import html_components
import html::bootstrap
import ordered_tree
+ import model::model_collect
redef class MEntity
# URL of this entity’s Nitdoc page.
redef fun css_classes do
var set = new HashSet[String]
if is_intro then set.add "intro"
- for m in mclass.intro.modifiers do set.add m.to_cmangle
- for m in modifiers do set.add m.to_cmangle
+ for m in mclass.intro.collect_modifiers do set.add m.to_cmangle
+ for m in collect_modifiers do set.add m.to_cmangle
return set.to_a
end
end
redef fun css_classes do
var set = new HashSet[String]
if is_intro then set.add "intro"
- for m in mproperty.intro.modifiers do set.add m.to_cmangle
- for m in modifiers do set.add m.to_cmangle
+ for m in mproperty.intro.collect_modifiers do set.add m.to_cmangle
+ for m in collect_modifiers do set.add m.to_cmangle
return set.to_a
end
end
private fun html_concern_item: ListItem do
var lnk = html_link
var tpl = new Template
- tpl.add new Link.with_title("#concern:{nitdoc_id}", lnk.text, lnk.title)
+ tpl.add new Link.with_title("#{nitdoc_id}.concern", lnk.text, lnk.title)
var comment = html_short_comment
if comment != null then
tpl.add ": "
redef fun collect(mclasses) do
for mclass in mclasses do
- var all = mclass.all_mattributes(mainmodule, min_visibility)
+ var all = mclass.collect_accessible_mattributes(min_visibility)
for mattr in all do
if mattr.is_nullable then values.inc(mclass)
end
end
end
+ redef class MAttribute
+ # Is this attribute nullable for sure?
+ #
+ # This mean that its introduction is declarred with a nullable static type
+ # since attributes are invariant this will work on most cases
+ # attributes with static type anchored with a virtual type are not "nullable for-sure"
+ # because this type can be redefined in subclasses
+ private fun is_nullable: Bool do return intro.static_mtype isa MNullableType
+ end
private class NullableSends
super Visitor
end
t = t.anchor_to(self.nclassdef.mclassdef.mmodule, self.nclassdef.mclassdef.bound_mtype)
if t isa MNullableType then
- var name = n.callsite.mproperty.name
- if name == "==" or name == "!=" or name == "is_same_instance" then
+ var p = n.callsite.mproperty
+ if p.is_null_safe then
self.nullable_eq_sends += 1
else
self.nullable_sends += 1
# The primitive type `Int`
var int_type: MClassType = self.get_primitive_class("Int").mclass_type is lazy
+ # The primitive type `Byte`
+ var byte_type: MClassType = self.get_primitive_class("Byte").mclass_type is lazy
+
# The primitive type `Char`
var char_type: MClassType = self.get_primitive_class("Char").mclass_type is lazy
# Is there a `new` factory to allow the pseudo instantiation?
var has_new_factory = false is writable
+
+ # Is `self` a standard or abstract class kind?
+ var is_class: Bool is lazy do return kind == concrete_kind or kind == abstract_kind
+
+ # Is `self` an interface kind?
+ var is_interface: Bool is lazy do return kind == interface_kind
+
+ # Is `self` an enum kind?
+ var is_enum: Bool is lazy do return kind == enum_kind
+
+ # Is `self` and abstract class?
+ var is_abstract: Bool is lazy do return kind == abstract_kind
end
do
return self.is_init
end
+
+ # A specific method that is safe to call on null.
+ # Currently, only `==`, `!=` and `is_same_instance` are safe
+ fun is_null_safe: Bool do return name == "==" or name == "!=" or name == "is_same_instance"
end
# A global attribute
import frontend
import rapid_type_analysis
- import model_utils
import template
# A Nit module
redef class MClassType
redef fun is_visible_from(mmodule) do
- return mmodule.is_visible(mclass.intro_mmodule, public_visibility)
+ return mmodule.is_visible(mclass.intro_mmodule, mclass.visibility)
end
end
fontsize = 8
]
Object [
- label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l}"
+ label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l+ init()\l}"
]
Sys [
Object -> Cloneable [dir=back arrowtail=open style=dashed];
Numeric [
- label = "{interface\nNumeric||+ +(i: OTHER): OTHER\l+ -(i: OTHER): OTHER\l+ unary -(): OTHER\l+ *(i: OTHER): OTHER\l+ /(i: OTHER): OTHER\l+ to_i(): Int\l+ to_f(): Float\l+ is_zero(): Bool\l+ zero(): OTHER\l+ value_of(val: Numeric): OTHER\l}"
+ label = "{interface\nNumeric||+ +(i: OTHER): OTHER\l+ -(i: OTHER): OTHER\l+ unary -(): OTHER\l+ *(i: OTHER): OTHER\l+ /(i: OTHER): OTHER\l+ to_i(): Int\l+ to_f(): Float\l+ to_b(): Byte\l+ is_zero(): Bool\l+ zero(): OTHER\l+ value_of(val: Numeric): OTHER\l}"
]
Comparable -> Numeric [dir=back arrowtail=open style=dashed];
]
Numeric -> Float [dir=back arrowtail=open style=dashed];
+Byte [
+ label = "{Byte||+ %(i: Byte): Byte\l+ lshift(i: Int): Byte\l+ \<\<(i: Int): Byte\l+ rshift(i: Int): Byte\l+ \>\>(i: Int): Byte\l}"
+]
+Discrete -> Byte [dir=back arrowtail=open style=dashed];
+Numeric -> Byte [dir=back arrowtail=open style=dashed];
+
Int [
label = "{Int||+ %(i: Int): Int\l+ lshift(i: Int): Int\l+ \<\<(i: Int): Int\l+ rshift(i: Int): Int\l+ \>\>(i: Int): Int\l+ ascii(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"
]
fontsize = 8
]
Object [
- label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l}"
+ label = "{interface\nObject||+ object_id(): Int\l+ is_same_type(other: Object): Bool\l+ is_same_instance(other: nullable Object): Bool\l+ ==(other: nullable Object): Bool\l+ !=(other: nullable Object): Bool\l+ output()\l+ output_class_name()\l+ hash(): Int\l+ sys(): Sys\l+ init()\l}"
]
Sys [
Object -> Cloneable [dir=back arrowtail=open style=dashed];
Numeric [
- label = "{interface\nNumeric||+ +(i: OTHER): OTHER\l+ -(i: OTHER): OTHER\l+ unary -(): OTHER\l+ *(i: OTHER): OTHER\l+ /(i: OTHER): OTHER\l+ to_i(): Int\l+ to_f(): Float\l+ is_zero(): Bool\l+ zero(): OTHER\l+ value_of(val: Numeric): OTHER\l}"
+ label = "{interface\nNumeric||+ +(i: OTHER): OTHER\l+ -(i: OTHER): OTHER\l+ unary -(): OTHER\l+ *(i: OTHER): OTHER\l+ /(i: OTHER): OTHER\l+ to_i(): Int\l+ to_f(): Float\l+ to_b(): Byte\l+ is_zero(): Bool\l+ zero(): OTHER\l+ value_of(val: Numeric): OTHER\l}"
]
Comparable -> Numeric [dir=back arrowtail=open style=dashed];
label = "{Float||+ is_approx(other: Float, precision: Float): Bool\l}"
]
Numeric -> Float [dir=back arrowtail=open style=dashed];
+
+Byte [
+ label = "{Byte||+ %(i: Byte): Byte\l+ lshift(i: Int): Byte\l+ \<\<(i: Int): Byte\l+ rshift(i: Int): Byte\l+ \>\>(i: Int): Byte\l}"
+]
+Discrete -> Byte [dir=back arrowtail=open style=dashed];
+Numeric -> Byte [dir=back arrowtail=open style=dashed];
Int [
label = "{Int||+ %(i: Int): Int\l+ lshift(i: Int): Int\l+ \<\<(i: Int): Int\l+ rshift(i: Int): Int\l+ \>\>(i: Int): Int\l+ ascii(): Char\l+ digit_count(b: Int): Int\l+ digit_count_base_10(): Int\l+ to_c(): Char\l+ abs(): Int\l}"