Merge: expanded the nit_env.sh script to register nit within .bash_profile and .bashrc
authorJean Privat <jean@pryen.org>
Mon, 28 Dec 2015 21:21:57 +0000 (16:21 -0500)
committerJean Privat <jean@pryen.org>
Mon, 28 Dec 2015 21:21:57 +0000 (16:21 -0500)
When running `source misc/nit_env.sh install` I noticed that it resulted in the following error:

`grep: User/user .profile: No such file or directory`

The `nit_env.sh` script created a `.profile` file in the home directory despite an existing `.bash_profile`. The `nit` command won't work since the shell will read the `.bash_profile` instead of the `profile`.

This PR checks for the existance and writes to a `.profile` or `.bashrc` or `.bash_profile`, if it finds none of those it creates a `.profile` and writes to that one.

If the PR is accepted the documentation will have to be updated.

Pull-Request: #1913
Reviewed-by: Jean Privat <jean@pryen.org>

27 files changed:
src/doc/doc_base.nit
src/doc/doc_phases/doc_concerns.nit
src/doc/doc_phases/doc_console.nit
src/doc/doc_phases/doc_extract.nit [deleted file]
src/doc/doc_phases/doc_html.nit
src/doc/doc_phases/doc_indexing.nit
src/doc/doc_phases/doc_intros_redefs.nit
src/doc/doc_phases/doc_pages.nit
src/doc/doc_phases/doc_readme.nit
src/doc/vim_autocomplete.nit
src/metrics/mclasses_metrics.nit
src/metrics/mendel_metrics.nit
src/metrics/nullables_metrics.nit
src/model/model_base.nit
src/model/model_collect.nit
src/nitdoc.nit
src/nituml.nit
src/nitx.nit
src/uml/uml_base.nit
src/uml/uml_class.nit
src/uml/uml_module.nit
src/web/model_html.nit
src/web/web_actions.nit
src/web/web_base.nit
src/web/web_views.nit
tests/sav/nitdoc_args3.res
tests/sav/nituml_args4.res

index c6dabf8..c77c332 100644 (file)
@@ -17,6 +17,7 @@ module doc_base
 
 import toolcontext
 import model_ext
+import model::model_views
 
 # The model of a Nitdoc documentation.
 #
@@ -25,6 +26,7 @@ import model_ext
 # The model is populated through `DocPhase` to be constructed.
 # It is a placeholder to share data between each phase.
 class DocModel
+       super ModelView
 
        # `DocPage` composing the documentation associated to their ids.
        #
@@ -33,9 +35,6 @@ class DocModel
        # See `add_page`.
        var pages: Map[String, DocPage] = new HashMap[String, DocPage]
 
-       # Nit `Model` from which we extract the documentation.
-       var model: Model is writable
-
        # The entry point of the `model`.
        var mainmodule: MModule is writable
 
@@ -144,6 +143,7 @@ abstract class DocComposite
 
        # Depth of `self` in the composite tree.
        fun depth: Int do
+               var parent = self.parent
                if parent == null then return 0
                return parent.depth + 1
        end
@@ -320,6 +320,7 @@ redef class MModule
 
        # Avoid id conflict with group
        redef fun nitdoc_id do
+               var mgroup = self.mgroup
                if mgroup == null then return super
                return "{mgroup.full_name}::{full_name}".to_cmangle
        end
index 5c9b2e9..a84adb2 100644 (file)
@@ -63,7 +63,7 @@ redef class MGroupPage
                        for mclass in mmodule.intro_mclasses do
                                if doc.mclasses.has(mclass) then intros.add mclass
                        end
-                       for mclass in mmodule.collect_redef_mclasses(v.ctx.min_visibility) do
+                       for mclass in mmodule.collect_redef_mclasses(v.doc) do
                                if doc.mclasses.has(mclass) then redefs.add mclass
                        end
                end
index b118019..070b86b 100644 (file)
@@ -20,7 +20,6 @@ module doc_console
 
 import semantize
 import doc_commands
-import doc_extract
 import doc_poset
 import doc::console_templates
 
diff --git a/src/doc/doc_phases/doc_extract.nit b/src/doc/doc_phases/doc_extract.nit
deleted file mode 100644 (file)
index fcca4ea..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Extract data mentities of Model that will be documented.
-#
-# ExtractionPhase populates the DocModel that is the base for all other phases.
-# No DocPages are created at this level.
-#
-# TODO build a model instead?
-module doc_extract
-
-import doc_base
-
-redef class ToolContext
-
-       # Do not generate documentation for attributes.
-       var opt_no_attributes = new OptionBool("Ignore the attributes", "--no-attributes")
-
-       # Do not generate documentation for private properties.
-       var opt_private = new OptionBool("Also generate private API", "--private")
-
-       redef init do
-               super
-               option_context.add_option(opt_no_attributes, opt_private)
-       end
-
-       # Minimum visibility displayed.
-       #
-       # See `opt_private`.
-       var min_visibility: MVisibility is lazy do
-               if opt_private.value then return none_visibility
-               return protected_visibility
-       end
-end
-
-# ExtractionPhase populates the DocModel.
-class ExtractionPhase
-       super DocPhase
-
-       private var new_model: Model is noinit
-
-       # Populates the given DocModel.
-       redef fun apply do
-               doc.populate(self)
-       end
-
-       # Should we exclude this `mpackage` from the documentation?
-       fun ignore_mentity(mentity: MEntity): Bool do
-               if mentity isa MModule then
-                       return mentity.is_fictive or mentity.is_test_suite
-               else if mentity isa MClass then
-                       return mentity.visibility < ctx.min_visibility
-               else if mentity isa MClassDef then
-                       return ignore_mentity(mentity.mclass)
-               else if mentity isa MProperty then
-                       return ignore_mentity(mentity.intro_mclassdef) or
-                               mentity.visibility < ctx.min_visibility or
-                               (ctx.opt_no_attributes.value and mentity isa MAttribute) or
-                               mentity isa MInnerClass
-               else if mentity isa MPropDef then
-                       return ignore_mentity(mentity.mclassdef) or
-                               ignore_mentity(mentity.mproperty)
-               end
-               return false
-       end
-end
-
-# TODO Should I rebuild a new Model from filtered data?
-redef class DocModel
-
-       # MPackages that will be documented.
-       var mpackages = new HashSet[MPackage]
-
-       # MGroups that will be documented.
-       var mgroups = new HashSet[MGroup]
-
-       # MModules that will be documented.
-       var mmodules = new HashSet[MModule]
-
-       # MClasses that will be documented.
-       var mclasses = new HashSet[MClass]
-
-       # MClassDefs that will be documented.
-       var mclassdefs = new HashSet[MClassDef]
-
-       # MProperties that will be documented.
-       var mproperties = new HashSet[MProperty]
-
-       # MPropdefs that will be documented.
-       var mpropdefs = new HashSet[MPropDef]
-
-       # Populate `self` from internal `model`.
-       fun populate(v: ExtractionPhase) do
-               populate_mpackages(v)
-               populate_mclasses(v)
-               populate_mproperties(v)
-       end
-
-       # Populates the `mpackages` set.
-       private fun populate_mpackages(v: ExtractionPhase) do
-               for mpackage in model.mpackages do
-                       if v.ignore_mentity(mpackage) then continue
-                       self.mpackages.add mpackage
-                       for mgroup in mpackage.mgroups do
-                               if v.ignore_mentity(mgroup) then continue
-                               self.mgroups.add mgroup
-                               for mmodule in mgroup.mmodules do
-                                       if v.ignore_mentity(mmodule) then continue
-                                       self.mmodules.add mmodule
-                               end
-                       end
-               end
-       end
-
-       # Populates the `mclasses` set.
-       private fun populate_mclasses(v: ExtractionPhase) do
-               for mclass in model.mclasses do
-                       if v.ignore_mentity(mclass) then continue
-                       self.mclasses.add mclass
-                       for mclassdef in mclass.mclassdefs do
-                               if v.ignore_mentity(mclassdef) then continue
-                               self.mclassdefs.add mclassdef
-                       end
-               end
-       end
-
-       # Populates the `mproperties` set.
-       private fun populate_mproperties(v: ExtractionPhase) do
-               for mproperty in model.mproperties do
-                       if v.ignore_mentity(mproperty) then continue
-                       self.mproperties.add mproperty
-                       for mpropdef in mproperty.mpropdefs do
-                               if v.ignore_mentity(mpropdef) then continue
-                               self.mpropdefs.add mpropdef
-                       end
-               end
-       end
-
-       # Lists all MEntities in the model.
-       #
-       # FIXME invalidate cache if `self` is modified.
-       var mentities: Collection[MEntity] is lazy do
-               var res = new HashSet[MEntity]
-               res.add_all mpackages
-               res.add_all mgroups
-               res.add_all mmodules
-               res.add_all mclasses
-               res.add_all mclassdefs
-               res.add_all mproperties
-               res.add_all mpropdefs
-               return res
-       end
-
-       # Searches MEntities that match `name`.
-       fun mentities_by_name(name: String): Array[MEntity] do
-               var res = new Array[MEntity]
-               for mentity in mentities do
-                       if mentity.name != name then continue
-                       res.add mentity
-               end
-               return res
-       end
-
-       # Looks up a MEntity by its `namespace`.
-       #
-       # Usefull when `mentities_by_name` by return conflicts.
-       #
-       # Path can be the shortest possible to disambiguise like `Class::property`.
-       # In case of larger conflicts, a more complex namespace can be given like
-       # `package::module::Class::prop`.
-       fun mentities_by_namespace(namespace: String): Array[MEntity] do
-               var res = new Array[MEntity]
-               for mentity in mentities do
-                       mentity.mentities_by_namespace(namespace, res)
-               end
-               return res
-       end
-end
-
-redef class MEntity
-       # Looks up a MEntity by its `namespace` from `self`.
-       private fun mentities_by_namespace(namespace: String, res: Array[MEntity]) do end
-
-       private fun lookup_in(mentities: Collection[MEntity], namespace: String, res: Array[MEntity]) do
-               var parts = namespace.split_once_on("::")
-               var name = parts.shift
-               for mentity in mentities do
-                       if mentity.name != name then continue
-                       if parts.is_empty then
-                               res.add mentity
-                       else
-                               mentity.mentities_by_namespace(parts.first, res)
-                       end
-               end
-       end
-end
-
-redef class MPackage
-       redef fun mentities_by_namespace(namespace, res) do lookup_in(mgroups, namespace, res)
-end
-
-redef class MGroup
-       redef fun mentities_by_namespace(namespace, res) do lookup_in(mmodules, namespace, res)
-end
-
-redef class MModule
-       redef fun mentities_by_namespace(namespace, res) do lookup_in(mclassdefs, namespace, res)
-end
-
-redef class MClassDef
-       redef fun mentities_by_namespace(namespace, res) do lookup_in(mpropdefs, namespace, res)
-end
index 623b241..c2ed988 100644 (file)
@@ -339,8 +339,8 @@ redef class MModulePage
                # TODO filter here?
                super
                var mclasses = new HashSet[MClass]
-               mclasses.add_all mentity.collect_intro_mclasses(v.ctx.min_visibility)
-               mclasses.add_all mentity.collect_redef_mclasses(v.ctx.min_visibility)
+               mclasses.add_all mentity.collect_intro_mclasses(v.doc)
+               mclasses.add_all mentity.collect_redef_mclasses(v.doc)
                if mclasses.is_empty then return
                var list = new UnorderedList
                list.css_classes.add "list-unstyled list-labeled"
@@ -447,8 +447,8 @@ redef class MClassPage
 
        private fun mclass_inherited_mprops(v: RenderHTMLPhase, doc: DocModel): Set[MProperty] do
                var res = new HashSet[MProperty]
-               var local = mentity.collect_local_mproperties(v.ctx.min_visibility)
-               for mprop in mentity.collect_inherited_mproperties(v.ctx.min_visibility) do
+               var local = mentity.collect_local_mproperties(v.doc)
+               for mprop in mentity.collect_inherited_mproperties(v.doc) 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
index 1e74138..5d0b9c3 100644 (file)
@@ -15,7 +15,7 @@
 # Manage indexing of Nit model for Nitdoc QuickSearch.
 module doc_indexing
 
-import doc_extract
+import doc_base
 import html_templates::html_model # FIXME maybe this phase should depend on `html_render`
 private import json::static
 
index abc4f1d..605d2e1 100644 (file)
@@ -58,10 +58,10 @@ redef class DefinitionArticle
                var section = new TabbedGroup("{mentity.nitdoc_id}.intros_redefs")
                section.toc_title = "Intros / Redefs"
                var group = new PanelGroup("list.group", "List")
-               var intros = mmodule.collect_intro_mclassdefs(v.ctx.min_visibility).to_a
+               var intros = mmodule.collect_intro_mclassdefs(v.doc).to_a
                doc.mainmodule.linearize_mclassdefs(intros)
                group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.intros", "Introduces", intros)
-               var redefs = mmodule.collect_redef_mclassdefs(v.ctx.min_visibility).to_a
+               var redefs = mmodule.collect_redef_mclassdefs(v.doc).to_a
                doc.mainmodule.linearize_mclassdefs(redefs)
                group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.redefs", "Redefines", redefs)
                section.add_child group
@@ -73,11 +73,11 @@ redef class DefinitionArticle
                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
+               var intros = mclassdef.collect_intro_mpropdefs(v.doc).to_a
                # FIXME avoid diff changes
                # v.ctx.mainmodule.linearize_mpropdefs(intros)
                group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.intros", "Introduces", intros)
-               var redefs = mclassdef.collect_redef_mpropdefs(v.ctx.min_visibility).to_a
+               var redefs = mclassdef.collect_redef_mpropdefs(v.doc).to_a
                # FIXME avoid diff changes
                # v.ctx.mainmodule.linearize_mpropdefs(redefs)
                group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.redefs", "Redefines", redefs)
index e08a385..1f7148f 100644 (file)
@@ -15,7 +15,7 @@
 # Create DocPage instances for each documentated Mentity.
 module doc_pages
 
-import doc_extract
+import doc_base
 
 # ExtractionPhase populates the DocModel with DocPage.
 class MakePagePhase
index 605ddac..b34fc7f 100644 (file)
@@ -258,7 +258,7 @@ redef class ListCommand
                if mentity isa MModule then
                        v.add_article new MEntitiesListArticle("Classes", null, mentity.mclassdefs)
                else if mentity isa MClass then
-                       var mprops = mentity.collect_intro_mproperties(public_visibility)
+                       var mprops = mentity.collect_intro_mproperties(mentity.public_view)
                        v.add_article new MEntitiesListArticle("Methods", null, mprops.to_a)
                else if mentity isa MClassDef then
                        v.add_article new MEntitiesListArticle("Methods", null, mentity.mpropdefs)
index 4f19dbc..3d632c6 100644 (file)
@@ -49,6 +49,16 @@ redef class ToolContext
        end
 end
 
+redef class Model
+
+       # Get a custom view for vimautocomplete.
+       private fun vim_view: ModelView do
+               var view = new ModelView(self)
+               view.min_visibility = protected_visibility
+               return view
+       end
+end
+
 redef class MEntity
        private fun field_separator: String do return "#====#"
        private fun line_separator: String do return "#nnnn#"
@@ -198,7 +208,7 @@ redef class MClassType
                stream.write line_separator*2
                stream.write "## Properties"
                stream.write line_separator
-               var props = mclass.collect_accessible_mproperties(protected_visibility).to_a
+               var props = mclass.collect_accessible_mproperties(model.protected_view).to_a
                alpha_comparator.sort props
                for prop in props do
                        if mclass.name == "Object" or prop.intro.mclassdef.mclass.name != "Object" then
@@ -243,7 +253,7 @@ private class AutocompletePhase
                        # Can it be instantiated?
                        if mclass.kind != interface_kind and mclass.kind != abstract_kind then
 
-                               for prop in mclass.collect_accessible_mproperties(public_visibility) do
+                               for prop in mclass.collect_accessible_mproperties(model.public_view) do
                                        if prop isa MMethod and prop.is_init then
                                                mclass_intro.target_constructor = prop.intro
                                                mclass_intro.write_doc(mainmodule, constructors_stream)
@@ -292,7 +302,7 @@ redef class MModule
        redef fun write_extra_doc(mainmodule, stream)
        do
                # Introduced classes
-               var class_intros = collect_intro_mclasses(protected_visibility).to_a
+               var class_intros = collect_intro_mclasses(model.protected_view).to_a
                if class_intros.not_empty then
                        alpha_comparator.sort class_intros
                        stream.write line_separator*2
@@ -309,7 +319,7 @@ redef class MModule
                # Introduced properties
                var prop_intros = new Array[MPropDef]
                for c in mclassdefs do
-                       prop_intros.add_all c.collect_intro_mpropdefs(protected_visibility)
+                       prop_intros.add_all c.collect_intro_mpropdefs(model.protected_view)
                end
 
                if prop_intros.not_empty then
@@ -345,7 +355,10 @@ redef class MProperty
                if self isa MMethod then
                        var intro = intro
                        assert intro isa MMethodDef
-                       stream.write intro.msignature.to_s
+                       var msignature = intro.msignature
+                       if msignature != null then
+                               stream.write msignature.to_s
+                       end
                end
 
                var mdoc = intro.mdoc
index 69b5b40..89467b2 100644 (file)
@@ -34,26 +34,26 @@ private class MClassesMetricsPhase
                var out = "{toolcontext.opt_dir.value or else "metrics"}/mclasses"
                out.mkdir
 
+               var model = toolcontext.modelbuilder.model
+               var model_view = model.private_view
 
                print toolcontext.format_h1("\n# MClasses metrics")
 
                var metrics = new MetricSet
-               var min_vis = private_visibility
                metrics.register(new CNOA(mainmodule))
                metrics.register(new CNOP(mainmodule))
                metrics.register(new CNOC(mainmodule))
                metrics.register(new CNOD(mainmodule))
                metrics.register(new CDIT(mainmodule))
-               metrics.register(new CNBP(mainmodule, min_vis))
-               metrics.register(new CNBA(mainmodule, min_vis))
-               metrics.register(new CNBIP(mainmodule, min_vis))
-               metrics.register(new CNBRP(mainmodule, min_vis))
-               metrics.register(new CNBHP(mainmodule, min_vis))
+               metrics.register(new CNBP(mainmodule, model_view))
+               metrics.register(new CNBA(mainmodule, model_view))
+               metrics.register(new CNBIP(mainmodule, model_view))
+               metrics.register(new CNBRP(mainmodule, model_view))
+               metrics.register(new CNBHP(mainmodule, model_view))
                #TODO metrics.register(new CNBI) # nb init
                #TODO metrics.register(new CNBM) # nb methods
                #TODO metrics.register(new CNBV) # nb vtypes
 
-               var model = toolcontext.modelbuilder.model
                var mclasses = new HashSet[MClass]
                for mpackage in model.mpackages do
 
@@ -184,16 +184,16 @@ class CNBP
        redef fun desc do return "number of accessible properties (inherited + local)"
 
        var mainmodule: MModule
-       var min_visibility: MVisibility
+       var model_view: ModelView
 
-       init(mainmodule: MModule, min_visibility: MVisibility) do
+       init(mainmodule: MModule, model_view: ModelView) do
                self.mainmodule = mainmodule
-               self.min_visibility = min_visibility
+               self.model_view = model_view
        end
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       values[mclass] = mclass.collect_accessible_mproperties(min_visibility).length
+                       values[mclass] = mclass.collect_accessible_mproperties(model_view).length
                end
        end
 end
@@ -206,16 +206,16 @@ class CNBA
        redef fun desc do return "number of accessible attributes (inherited + local)"
 
        var mainmodule: MModule
-       var min_visibility: MVisibility
+       var model_view: ModelView
 
-       init(mainmodule: MModule, min_visibility: MVisibility) do
+       init(mainmodule: MModule, model_view: ModelView) do
                self.mainmodule = mainmodule
-               self.min_visibility = min_visibility
+               self.model_view = model_view
        end
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       values[mclass] = mclass.collect_accessible_mattributes(min_visibility).length
+                       values[mclass] = mclass.collect_accessible_mattributes(model_view).length
                end
        end
 end
@@ -228,16 +228,16 @@ class CNBIP
        redef fun desc do return "number of introduced properties"
 
        var mainmodule: MModule
-       var min_visibility: MVisibility
+       var model_view: ModelView
 
-       init(mainmodule: MModule, min_visibility: MVisibility) do
+       init(mainmodule: MModule, model_view: ModelView) do
                self.mainmodule = mainmodule
-               self.min_visibility = min_visibility
+               self.model_view = model_view
        end
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       values[mclass] = mclass.collect_intro_mproperties(min_visibility).length
+                       values[mclass] = mclass.collect_intro_mproperties(model_view).length
                end
        end
 end
@@ -250,16 +250,16 @@ class CNBRP
        redef fun desc do return "number of redefined properties"
 
        var mainmodule: MModule
-       var min_visibility: MVisibility
+       var model_view: ModelView
 
-       init(mainmodule: MModule, min_visibility: MVisibility) do
+       init(mainmodule: MModule, model_view: ModelView) do
                self.mainmodule = mainmodule
-               self.min_visibility = min_visibility
+               self.model_view = model_view
        end
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       values[mclass] = mclass.collect_redef_mproperties(min_visibility).length
+                       values[mclass] = mclass.collect_redef_mproperties(model_view).length
                end
        end
 end
@@ -272,16 +272,16 @@ class CNBHP
        redef fun desc do return "number of inherited properties"
 
        var mainmodule: MModule
-       var min_visibility: MVisibility
+       var model_view: ModelView
 
-       init(mainmodule: MModule, min_visibility: MVisibility) do
+       init(mainmodule: MModule, model_view: ModelView) do
                self.mainmodule = mainmodule
-               self.min_visibility = min_visibility
+               self.model_view = model_view
        end
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       values[mclass] = mclass.collect_inherited_mproperties(min_visibility).length
+                       values[mclass] = mclass.collect_inherited_mproperties(model_view).length
                end
        end
 end
@@ -294,16 +294,16 @@ class CNBLP
        redef fun desc do return "number of local properties (intro + redef)"
 
        var mainmodule: MModule
-       var min_visibility: MVisibility
+       var model_view: ModelView
 
-       init(mainmodule: MModule, min_visibility: MVisibility) do
+       init(mainmodule: MModule, model_view: ModelView) do
                self.mainmodule = mainmodule
-               self.min_visibility = min_visibility
+               self.model_view = model_view
        end
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       values[mclass] = mclass.collect_local_mproperties(min_visibility).length
+                       values[mclass] = mclass.collect_local_mproperties(model_view).length
                end
        end
 end
index 81201a2..2709ef9 100644 (file)
@@ -66,17 +66,16 @@ private class MendelMetricsPhase
 
                print toolcontext.format_h1("\n# Mendel metrics")
 
-               var vis = protected_visibility
                var model = toolcontext.modelbuilder.model
+               var model_view = model.protected_view
 
                var mclasses = new HashSet[MClass]
-               for mclass in model.mclasses do
-                       if mclass.visibility < vis then continue
+               for mclass in model_view.mclasses do
                        if mclass.is_interface then continue
                        mclasses.add(mclass)
                end
 
-               var cnblp = new CNBLP(mainmodule, vis)
+               var cnblp = new CNBLP(mainmodule, model_view)
                var cnvi = new CNVI(mainmodule)
                var cnvs = new CNVS(mainmodule)
 
@@ -114,15 +113,15 @@ private class MendelMetricsPhase
                        csvh.format = new CsvFormat('"', ';', "\n")
                        csvh.header = ["povr", "ovr", "pext", "ext", "pspe", "spe", "prep", "rep", "eq"]
                        for mclass in mclasses do
-                               var povr = mclass.is_pure_overrider(vis).object_id
-                               var ovr = mclass.is_overrider(vis).object_id
-                               var pext = mclass.is_pure_extender(vis).object_id
-                               var ext = mclass.is_extender(vis).object_id
-                               var pspe = mclass.is_pure_specializer(vis).object_id
-                               var spe = mclass.is_pure_specializer(vis).object_id
-                               var prep = mclass.is_pure_replacer(vis).object_id
-                               var rep = mclass.is_replacer(vis).object_id
-                               var eq = mclass.is_equal(vis).object_id
+                               var povr = mclass.is_pure_overrider(model_view).object_id
+                               var ovr = mclass.is_overrider(model_view).object_id
+                               var pext = mclass.is_pure_extender(model_view).object_id
+                               var ext = mclass.is_extender(model_view).object_id
+                               var pspe = mclass.is_pure_specializer(model_view).object_id
+                               var spe = mclass.is_pure_specializer(model_view).object_id
+                               var prep = mclass.is_pure_replacer(model_view).object_id
+                               var rep = mclass.is_replacer(model_view).object_id
+                               var eq = mclass.is_equal(model_view).object_id
                                csvh.add_record(povr, ovr, pext, ext, pspe, spe, prep, rep, eq)
                        end
                        csvh.save("{out}/inheritance_behaviour.csv")
@@ -140,10 +139,11 @@ class CBMS
 
        # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
+       private var protected_view: ModelView = mainmodule.model.protected_view is lateinit
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       var totc = mclass.collect_accessible_mproperties(protected_visibility).length
+                       var totc = mclass.collect_accessible_mproperties(protected_view).length
                        var ditc = mclass.in_hierarchy(mainmodule).depth
                        values[mclass] = totc.to_f / (ditc + 1).to_f
                end
@@ -160,8 +160,8 @@ class MBMS
 
        redef fun collect(mmodules) do
                for mmodule in mmodules do
-                       var totc = mmodule.collect_intro_mclassdefs(protected_visibility).length
-                       totc += mmodule.collect_redef_mclassdefs(protected_visibility).length
+                       var totc = mmodule.collect_intro_mclassdefs(mmodule.protected_view).length
+                       totc += mmodule.collect_redef_mclassdefs(mmodule.protected_view).length
                        var ditc = mmodule.in_importation.depth
                        values[mmodule] = totc.to_f / (ditc + 1).to_f
                end
@@ -178,6 +178,7 @@ class CNVI
 
        # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
+       private var protected_view: ModelView = mainmodule.model.protected_view is lateinit
 
        redef fun collect(mclasses) do
                var cbms = new CBMS(mainmodule)
@@ -188,7 +189,7 @@ class CNVI
                                cbms.clear
                                cbms.collect(new HashSet[MClass].from(parents))
                                # compute class novelty index
-                               var locc = mclass.collect_accessible_mproperties(protected_visibility).length
+                               var locc = mclass.collect_accessible_mproperties(protected_view).length
                                values[mclass] = locc.to_f / cbms.avg
                        else
                                values[mclass] = 0.0
@@ -214,8 +215,8 @@ class MNVI
                                mbms.clear
                                mbms.collect(new HashSet[MModule].from(parents))
                                # compute module novelty index
-                               var locc = mmodule.collect_intro_mclassdefs(protected_visibility).length
-                               locc += mmodule.collect_redef_mclassdefs(protected_visibility).length
+                               var locc = mmodule.collect_intro_mclassdefs(mmodule.protected_view).length
+                               locc += mmodule.collect_redef_mclassdefs(mmodule.protected_view).length
                                values[mmodule] = locc.to_f / mbms.avg
                        else
                                values[mmodule] = 0.0
@@ -234,12 +235,13 @@ class CNVS
 
        # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
+       private var protected_view: ModelView = mainmodule.model.protected_view is lateinit
 
        redef fun collect(mclasses) do
                var cnvi = new CNVI(mainmodule)
                cnvi.collect(mclasses)
                for mclass in mclasses do
-                       var locc = mclass.collect_local_mproperties(protected_visibility).length
+                       var locc = mclass.collect_local_mproperties(protected_view).length
                        values[mclass] = cnvi.values[mclass] * locc.to_f
                end
        end
@@ -257,8 +259,8 @@ class MNVS
                var mnvi = new MNVI
                mnvi.collect(mmodules)
                for mmodule in mmodules do
-                       var locc = mmodule.collect_intro_mclassdefs(protected_visibility).length
-                       locc += mmodule.collect_redef_mclassdefs(protected_visibility).length
+                       var locc = mmodule.collect_intro_mclassdefs(mmodule.protected_view).length
+                       locc += mmodule.collect_redef_mclassdefs(mmodule.protected_view).length
                        values[mmodule] = mnvi.values[mmodule] * locc.to_f
                end
        end
@@ -266,11 +268,11 @@ end
 
 redef class MClass
        # the set of redefition that call to super
-       fun extended_mproperties(min_visibility: MVisibility): Set[MProperty] do
+       fun extended_mproperties(view: ModelView): Set[MProperty] do
                var set = new HashSet[MProperty]
                for mclassdef in mclassdefs do
                        for mpropdef in mclassdef.mpropdefs do
-                               if mpropdef.mproperty.visibility < min_visibility then continue
+                               if not view.accept_mentity(mpropdef) then continue
                                if not mpropdef.has_supercall then continue
                                if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
                        end
@@ -279,11 +281,11 @@ redef class MClass
        end
 
        # the set of redefition that do not call to super
-       fun overriden_mproperties(min_visibility: MVisibility): Set[MProperty] do
+       fun overriden_mproperties(view: ModelView): Set[MProperty] do
                var set = new HashSet[MProperty]
                for mclassdef in mclassdefs do
                        for mpropdef in mclassdef.mpropdefs do
-                               if mpropdef.mproperty.visibility < min_visibility then continue
+                               if not view.accept_mentity(mpropdef) then continue
                                if mpropdef.has_supercall then continue
                                if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
                        end
@@ -292,78 +294,78 @@ redef class MClass
        end
 
        # pure overriders contain only redefinitions
-       private fun is_pure_overrider(min_visibility: MVisibility): Bool do
-               var news = collect_intro_mproperties(min_visibility).length
-               var locs = collect_local_mproperties(min_visibility).length
+       private fun is_pure_overrider(view: ModelView): Bool do
+               var news = collect_intro_mproperties(view).length
+               var locs = collect_local_mproperties(view).length
                if news == 0 and locs > 0 then return true
                return false
        end
 
        # overriders contain more definitions than introductions
-       private fun is_overrider(min_visibility: MVisibility): Bool do
-               var rdfs = collect_redef_mproperties(min_visibility).length
-               var news = collect_intro_mproperties(min_visibility).length
-               var locs = collect_local_mproperties(min_visibility).length
+       private fun is_overrider(view: ModelView): Bool do
+               var rdfs = collect_redef_mproperties(view).length
+               var news = collect_intro_mproperties(view).length
+               var locs = collect_local_mproperties(view).length
                if rdfs >= news and locs > 0 then return true
                return false
        end
 
        # pure extenders contain only introductions
-       private fun is_pure_extender(min_visibility: MVisibility): Bool do
-               var rdfs = collect_redef_mproperties(min_visibility).length
-               var locs = collect_local_mproperties(min_visibility).length
+       private fun is_pure_extender(view: ModelView): Bool do
+               var rdfs = collect_redef_mproperties(view).length
+               var locs = collect_local_mproperties(view).length
                if rdfs == 0 and locs > 0 then return true
                return false
        end
 
        # extenders contain more introduction than redefinitions
-       private fun is_extender(min_visibility: MVisibility): Bool do
-               var rdfs = collect_redef_mproperties(min_visibility).length
-               var news = collect_intro_mproperties(min_visibility).length
-               var locs = collect_local_mproperties(min_visibility).length
+       private fun is_extender(view: ModelView): Bool do
+               var rdfs = collect_redef_mproperties(view).length
+               var news = collect_intro_mproperties(view).length
+               var locs = collect_local_mproperties(view).length
                if news > rdfs and locs > 0 then return true
                return false
        end
 
        # pure specializers always call to super in its redefinitions
-       private fun is_pure_specializer(min_visibility: MVisibility): Bool do
-               var ovrs = overriden_mproperties(min_visibility).length
-               var rdfs = collect_redef_mproperties(min_visibility).length
+       private fun is_pure_specializer(view: ModelView): Bool do
+               var ovrs = overriden_mproperties(view).length
+               var rdfs = collect_redef_mproperties(view).length
                if ovrs == 0 and rdfs > 0 then return true
                return false
        end
 
        # specializers have more redefinitions that call super than not calling it
-       private fun is_specializer(min_visibility: MVisibility): Bool do
-               var spcs = extended_mproperties(min_visibility).length
-               var ovrs = overriden_mproperties(min_visibility).length
-               var rdfs = collect_redef_mproperties(min_visibility).length
+       private fun is_specializer(view: ModelView): Bool do
+               var spcs = extended_mproperties(view).length
+               var ovrs = overriden_mproperties(view).length
+               var rdfs = collect_redef_mproperties(view).length
                if spcs > ovrs and rdfs > 0 then return true
                return false
        end
 
        # pure replacers never call to super in its redefinitions
-       private fun is_pure_replacer(min_visibility: MVisibility): Bool do
-               var spcs = extended_mproperties(min_visibility).length
-               var rdfs = collect_redef_mproperties(min_visibility).length
+       private fun is_pure_replacer(view: ModelView): Bool do
+               var spcs = extended_mproperties(view).length
+               var rdfs = collect_redef_mproperties(view).length
                if spcs == 0 and rdfs > 0 then return true
                return false
        end
 
        # replacers have less redefinitions that call super than not calling it
-       private fun is_replacer(min_visibility: MVisibility): Bool do
-               var spcs = extended_mproperties(min_visibility).length
-               var ovrs = overriden_mproperties(min_visibility).length
-               var rdfs = collect_redef_mproperties(min_visibility).length
+       private fun is_replacer(view: ModelView): Bool do
+               var spcs = extended_mproperties(view).length
+               var ovrs = overriden_mproperties(view).length
+               var rdfs = collect_redef_mproperties(view).length
                if ovrs > spcs and rdfs > 0 then return true
                return false
        end
 
        # equals contain as redifinition than introduction
-       private fun is_equal(min_visibility: MVisibility): Bool do
-               var spcs = extended_mproperties(min_visibility).length
-               var ovrs = overriden_mproperties(min_visibility).length
-               var rdfs = collect_redef_mproperties(min_visibility).length
+       private fun is_equal(view: ModelView): Bool do
+               var spcs = extended_mproperties(view).length
+               var ovrs = overriden_mproperties(view).length
+               var rdfs = collect_redef_mproperties(view).length
                if spcs == ovrs and rdfs > 0 then return true
                return false
        end
index 6e9d7ff..6992ff8 100644 (file)
@@ -37,12 +37,13 @@ private class NullablesMetricsPhase
 
                print toolcontext.format_h1("\n# Nullable metrics")
 
+               var model = toolcontext.modelbuilder.model
+               var model_view = model.private_view
+
                var metrics = new MetricSet
-               var min_vis = private_visibility
-               metrics.register(new CNBA(mainmodule, min_vis))
-               metrics.register(new CNBNA(mainmodule, min_vis))
+               metrics.register(new CNBA(mainmodule, model_view))
+               metrics.register(new CNBNA(mainmodule, model_view))
 
-               var model = toolcontext.modelbuilder.model
                var mclasses = new HashSet[MClass]
                for mpackage in model.mpackages do
 
@@ -84,16 +85,16 @@ class CNBNA
        redef fun desc do return "number of accessible nullable attributes (inherited + local)"
 
        var mainmodule: MModule
-       var min_visibility: MVisibility
+       var model_view: ModelView
 
-       init(mainmodule: MModule, min_visibility: MVisibility) do
+       init(mainmodule: MModule, model_view: ModelView) do
                self.mainmodule = mainmodule
-               self.min_visibility = min_visibility
+               self.model_view = model_view
        end
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       var all = mclass.collect_accessible_mattributes(min_visibility)
+                       var all = mclass.collect_accessible_mattributes(model_view)
                        for mattr in all do
                                if mattr.is_nullable then values.inc(mclass)
                        end
index 2d2dfa0..5cfe9b2 100644 (file)
@@ -21,6 +21,8 @@ module model_base
 # A model knows modules, classes and properties and can retrieve them.
 class Model
        super MEntity
+
+       redef fun model do return self
 end
 
 # A named and possibly documented entity in the model.
index e6260c6..41352eb 100644 (file)
 # entities could not be reachable depending on the modules really imported.
 module model_collect
 
-import model
-
-redef class MEntity
-
-       # Collect mentities with a fully qualified `namespace`.
-       fun collect_by_namespace(namespace: String): Array[MEntity] is abstract
-
-       private fun lookup_in(mentities: Collection[MEntity], namespace: String, res: Array[MEntity]) do
-               var parts = namespace.split_once_on("::")
-               var name = parts.shift
-               for mentity in mentities do
-                       if mentity.name != name then continue
-                       if parts.is_empty then
-                               res.add mentity
-                       else
-                               res.add_all mentity.collect_by_namespace(parts.first)
-                       end
-               end
-       end
-end
-
-redef class Model
-       redef fun collect_by_namespace(namespace) do
-               var res = new Array[MEntity]
-               var parts = namespace.split_once_on("::")
-               var name = parts.shift
-               for mentity in mpackages do
-                       if mentity.name != name then continue
-                       if parts.is_empty then
-                               res.add mentity
-                       else
-                               res.add_all mentity.collect_by_namespace(parts.first)
-                       end
-               end
-               return res
-       end
-end
-
-redef class MPackage
-       redef fun collect_by_namespace(namespace) do
-               var res = new Array[MEntity]
-               var root = self.root
-               if root == null then return res
-               lookup_in([root], namespace, res)
-               return res
-       end
-end
-
-redef class MGroup
-       redef fun collect_by_namespace(namespace) do
-               var res = new Array[MEntity]
-               lookup_in(in_nesting.direct_smallers, namespace, res)
-               lookup_in(mmodules, namespace, res)
-               return res
-       end
-end
+import model_views
 
 redef class MModule
 
-       redef fun collect_by_namespace(namespace) do
-               var res = new Array[MEntity]
-               lookup_in(mclassdefs, namespace, res)
-               return res
-       end
-
        # Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
-       fun collect_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+       fun collect_intro_mclassdefs(view: ModelView): Set[MClassDef] do
                var res = new HashSet[MClassDef]
                for mclassdef in mclassdefs do
                        if not mclassdef.is_intro then continue
-                       if mclassdef.mclass.visibility < min_visibility then continue
+                       if not view.accept_mentity(mclassdef) then continue
                        res.add mclassdef
                end
                return res
        end
 
        # Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
-       fun collect_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+       fun collect_redef_mclassdefs(view: ModelView): Set[MClassDef] do
                var res = new HashSet[MClassDef]
                for mclassdef in mclassdefs do
                        if mclassdef.is_intro then continue
-                       if mclassdef.mclass.visibility < min_visibility then continue
+                       if not view.accept_mentity(mclassdef) then continue
                        res.add mclassdef
                end
                return res
        end
 
        # Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
-       fun collect_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
+       fun collect_intro_mclasses(view: ModelView): Set[MClass] do
                var res = new HashSet[MClass]
                for mclass in intro_mclasses do
-                       if mclass.visibility < min_visibility then continue
+                       if not view.accept_mentity(mclass) then continue
                        res.add mclass
                end
                return res
        end
 
        # Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
-       fun collect_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
+       fun collect_redef_mclasses(view: ModelView): Set[MClass] do
                var mclasses = new HashSet[MClass]
-               for c in mclassdefs do
-                       if c.mclass.visibility < min_visibility then continue
-                       if not c.is_intro then mclasses.add(c.mclass)
+               for mclassdef in mclassdefs do
+                       if not view.accept_mentity(mclassdef) then continue
+                       if not mclassdef.is_intro then mclasses.add(mclassdef.mclass)
                end
                return mclasses
        end
@@ -140,12 +79,12 @@ end
 redef class MClass
 
        # Collect direct parents of `self` with `visibility >= to min_visibility`.
-       fun collect_parents(min_visibility: MVisibility): Set[MClass] do
+       fun collect_parents(view: ModelView): Set[MClass] do
                var res = new HashSet[MClass]
                for mclassdef in mclassdefs do
                        for mclasstype in mclassdef.supertypes do
                                var mclass = mclasstype.mclass
-                               if mclass.visibility < min_visibility then continue
+                               if not view.accept_mentity(mclass) then continue
                                res.add(mclass)
                        end
                end
@@ -153,13 +92,13 @@ redef class MClass
        end
 
        # Collect all ancestors of `self` with `visibility >= to min_visibility`.
-       fun collect_ancestors(min_visibility: MVisibility): Set[MClass] do
+       fun collect_ancestors(view: ModelView): Set[MClass] do
                var res = new HashSet[MClass]
                for mclassdef in self.mclassdefs do
                        for super_mclassdef in mclassdef.in_hierarchy.greaters do
                                if super_mclassdef == mclassdef then continue  # skip self
                                var mclass = super_mclassdef.mclass
-                               if mclass.visibility < min_visibility then continue
+                               if not view.accept_mentity(mclass) then continue
                                res.add(mclass)
                        end
                end
@@ -167,13 +106,13 @@ redef class MClass
        end
 
        # Collect direct children of `self` with `visibility >= to min_visibility`.
-       fun collect_children(min_visibility: MVisibility): Set[MClass] do
+       fun collect_children(view: ModelView): Set[MClass] do
                var res = new HashSet[MClass]
                for mclassdef in self.mclassdefs do
                        for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
                                if sub_mclassdef == mclassdef then continue  # skip self
                                var mclass = sub_mclassdef.mclass
-                               if mclass.visibility < min_visibility then continue
+                               if not view.accept_mentity(mclass) then continue
                                res.add(mclass)
                        end
                end
@@ -181,13 +120,13 @@ redef class MClass
        end
 
        # Collect all descendants of `self` with `visibility >= to min_visibility`.
-       fun descendants(min_visibility: MVisibility): Set[MClass] do
+       fun collect_descendants(view: ModelView): Set[MClass] do
                var res = new HashSet[MClass]
                for mclassdef in self.mclassdefs do
                        for sub_mclassdef in mclassdef.in_hierarchy.smallers do
                                if sub_mclassdef == mclassdef then continue  # skip self
                                var mclass = sub_mclassdef.mclass
-                               if mclass.visibility < min_visibility then continue
+                               if not view.accept_mentity(mclass) then continue
                                res.add(mclass)
                        end
                end
@@ -195,11 +134,11 @@ redef class MClass
        end
 
        # Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
-       fun collect_intro_mproperties(min_visibility: MVisibility): Set[MProperty] do
+       fun collect_intro_mproperties(view: ModelView): Set[MProperty] do
                var set = new HashSet[MProperty]
                for mclassdef in mclassdefs do
                        for mprop in mclassdef.intro_mproperties do
-                               if mprop.visibility < min_visibility then continue
+                               if not view.accept_mentity(mprop) then continue
                                set.add(mprop)
                        end
                end
@@ -207,31 +146,32 @@ redef class MClass
        end
 
        # Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
-       fun collect_redef_mproperties(min_visibility: MVisibility): Set[MProperty] do
+       fun collect_redef_mproperties(view: ModelView): Set[MProperty] do
                var set = new HashSet[MProperty]
                for mclassdef in mclassdefs do
                        for mpropdef in mclassdef.mpropdefs do
-                               if mpropdef.mproperty.visibility < min_visibility then continue
-                               if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
+                               if mpropdef.mproperty.intro_mclassdef.mclass == self then continue
+                               if not view.accept_mentity(mpropdef) then continue
+                               set.add(mpropdef.mproperty)
                        end
                end
                return set
        end
 
        # Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
-       fun collect_local_mproperties(min_visibility: MVisibility): Set[MProperty] do
+       fun collect_local_mproperties(view: ModelView): Set[MProperty] do
                var set = new HashSet[MProperty]
-               set.add_all collect_intro_mproperties(min_visibility)
-               set.add_all collect_redef_mproperties(min_visibility)
+               set.add_all collect_intro_mproperties(view)
+               set.add_all collect_redef_mproperties(view)
                return set
        end
 
        # Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
-       fun collect_inherited_mproperties(min_visibility: MVisibility): Set[MProperty] do
+       fun collect_inherited_mproperties(view: ModelView): Set[MProperty] do
                var set = new HashSet[MProperty]
-               for parent in collect_parents(min_visibility) do
-                       set.add_all(parent.collect_intro_mproperties(min_visibility))
-                       set.add_all(parent.collect_inherited_mproperties(min_visibility))
+               for parent in collect_parents(view) do
+                       set.add_all(parent.collect_intro_mproperties(view))
+                       set.add_all(parent.collect_inherited_mproperties(view))
                end
                return set
        end
@@ -239,70 +179,70 @@ redef class MClass
        # Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
        #
        # This include introduced, redefined, inherited mproperties.
-       fun collect_accessible_mproperties(min_visibility: MVisibility): Set[MProperty] do
+       fun collect_accessible_mproperties(view: ModelView): Set[MProperty] do
                var set = new HashSet[MProperty]
-               set.add_all(collect_intro_mproperties(min_visibility))
-               set.add_all(collect_redef_mproperties(min_visibility))
-               set.add_all(collect_inherited_mproperties(min_visibility))
+               set.add_all(collect_intro_mproperties(view))
+               set.add_all(collect_redef_mproperties(view))
+               set.add_all(collect_inherited_mproperties(view))
                return set
        end
 
        # Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
-       fun collect_intro_mmethods(min_visibility: MVisibility): Set[MMethod] do
+       fun collect_intro_mmethods(view: ModelView): Set[MMethod] do
                var res = new HashSet[MMethod]
-               for mproperty in collect_intro_mproperties(min_visibility) do
+               for mproperty in collect_intro_mproperties(view) do
                        if mproperty isa MMethod then res.add(mproperty)
                end
                return res
        end
 
        # Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
-       fun collect_redef_mmethods(min_visibility: MVisibility): Set[MMethod] do
+       fun collect_redef_mmethods(view: ModelView): Set[MMethod] do
                var res = new HashSet[MMethod]
-               for mproperty in collect_redef_mproperties(min_visibility) do
+               for mproperty in collect_redef_mproperties(view) do
                        if mproperty isa MMethod then res.add(mproperty)
                end
                return res
        end
 
        # Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
-       fun collect_local_mmethods(min_visibility: MVisibility): Set[MMethod] do
+       fun collect_local_mmethods(view: ModelView): Set[MMethod] do
                var set = new HashSet[MMethod]
-               set.add_all collect_intro_mmethods(min_visibility)
-               set.add_all collect_redef_mmethods(min_visibility)
+               set.add_all collect_intro_mmethods(view)
+               set.add_all collect_redef_mmethods(view)
                return set
        end
 
        # Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
-       fun collect_intro_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+       fun collect_intro_mattributes(view: ModelView): Set[MAttribute] do
                var res = new HashSet[MAttribute]
-               for mproperty in collect_intro_mproperties(min_visibility) do
+               for mproperty in collect_intro_mproperties(view) do
                        if mproperty isa MAttribute then res.add(mproperty)
                end
                return res
        end
 
        # Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
-       fun collect_redef_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+       fun collect_redef_mattributes(view: ModelView): Set[MAttribute] do
                var res = new HashSet[MAttribute]
-               for mproperty in collect_redef_mproperties(min_visibility) do
+               for mproperty in collect_redef_mproperties(view) do
                        if mproperty isa MAttribute then res.add(mproperty)
                end
                return res
        end
 
        # Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
-       fun collect_local_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+       fun collect_local_mattributes(view: ModelView): Set[MAttribute] do
                var set = new HashSet[MAttribute]
-               set.add_all collect_intro_mattributes(min_visibility)
-               set.add_all collect_redef_mattributes(min_visibility)
+               set.add_all collect_intro_mattributes(view)
+               set.add_all collect_redef_mattributes(view)
                return set
        end
 
        # Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
-       fun collect_inherited_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+       fun collect_inherited_mattributes(view: ModelView): Set[MAttribute] do
                var res = new HashSet[MAttribute]
-               for mproperty in collect_inherited_mproperties(min_visibility) do
+               for mproperty in collect_inherited_mproperties(view) do
                        if mproperty isa MAttribute then res.add(mproperty)
                end
                return res
@@ -311,50 +251,44 @@ redef class MClass
        # Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
        #
        # This include introduced, redefined, inherited mattributes.
-       fun collect_accessible_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+       fun collect_accessible_mattributes(view: ModelView): Set[MAttribute] do
                var set = new HashSet[MAttribute]
-               set.add_all(collect_intro_mattributes(min_visibility))
-               set.add_all(collect_redef_mattributes(min_visibility))
-               set.add_all(collect_inherited_mattributes(min_visibility))
+               set.add_all(collect_intro_mattributes(view))
+               set.add_all(collect_redef_mattributes(view))
+               set.add_all(collect_inherited_mattributes(view))
                return set
        end
 end
 
 redef class MClassDef
 
-       redef fun collect_by_namespace(namespace) do
-               var res = new Array[MEntity]
-               lookup_in(mpropdefs, namespace, res)
-               return res
-       end
-
        # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
-       fun collect_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+       fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
                var res = new HashSet[MPropDef]
                for mpropdef in mpropdefs do
-                       if mpropdef.mproperty.visibility < min_visibility then continue
+                       if not view.accept_mentity(mpropdef) then continue
                        res.add mpropdef
                end
                return res
        end
 
        # Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
-       fun collect_intro_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+       fun collect_intro_mpropdefs(view: ModelView): Set[MPropDef] do
                var res = new HashSet[MPropDef]
                for mpropdef in mpropdefs do
                        if not mpropdef.is_intro then continue
-                       if mpropdef.mproperty.visibility < min_visibility then continue
+                       if not view.accept_mentity(mpropdef) then continue
                        res.add mpropdef
                end
                return res
        end
 
        # Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
-       fun collect_redef_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+       fun collect_redef_mpropdefs(view: ModelView): Set[MPropDef] do
                var res = new HashSet[MPropDef]
                for mpropdef in mpropdefs do
                        if mpropdef.is_intro then continue
-                       if mpropdef.mproperty.visibility < min_visibility then continue
+                       if not view.accept_mentity(mpropdef) then continue
                        res.add mpropdef
                end
                return res
index 2591863..801e715 100644 (file)
@@ -24,7 +24,16 @@ redef class ToolContext
        # Nitdoc generation phase.
        var docphase: Phase = new Nitdoc(self, null)
 
-       init do super # to fix ambiguous linearization
+       # Do not generate documentation for attributes.
+       var opt_no_attributes = new OptionBool("Ignore the attributes", "--no-attributes")
+
+       # Do not generate documentation for private properties.
+       var opt_private = new OptionBool("Also generate private API", "--private")
+
+       redef init do
+               super
+               option_context.add_option(opt_no_attributes, opt_private)
+       end
 end
 
 # Nitdoc phase explores the model and generate pages for each mentities found
@@ -33,9 +42,10 @@ private class Nitdoc
        redef fun process_mainmodule(mainmodule, mmodules)
        do
                var doc = new DocModel(mainmodule.model, mainmodule)
+               if not toolcontext.opt_private.value then doc.min_visibility = protected_visibility
+               if not toolcontext.opt_no_attributes.value then doc.include_attribute = false
 
                var phases = [
-                       new ExtractionPhase(toolcontext, doc),
                        new IndexingPhase(toolcontext, doc),
                        new MakePagePhase(toolcontext, doc),
                        new POSetPhase(toolcontext, doc),
index 9ea9048..330370f 100644 (file)
@@ -20,12 +20,19 @@ import frontend
 import uml
 
 redef class ToolContext
+
+       # Phase that generates UML diagrams from model entities.
        var umlphase: Phase = new UMLPhase(self, null)
 
+       # What to generate?
        var opt_gen = new OptionEnum(["class", "package"], "Choose which type of uml diagram to generate", 0, "--diagram")
 
+       # Generate private?
+       var opt_privacy = new OptionBool("Generates private API", "-p", "--private")
+
        redef init do
                option_context.add_option opt_gen
+               option_context.add_option opt_privacy
                super
        end
 end
@@ -34,7 +41,12 @@ private class UMLPhase
        super Phase
        redef fun process_mainmodule(mainmodule, mmodules)
        do
-               var d = new UMLModel(mainmodule.model, mainmodule, toolcontext)
+               var view = new ModelView(mainmodule.model)
+               if not toolcontext.opt_privacy.value then
+                       view.min_visibility = protected_visibility
+               end
+
+               var d = new UMLModel(view, mainmodule)
                if toolcontext.opt_gen.value == 0 then
                        print d.generate_class_uml.write_to_string
                else if toolcontext.opt_gen.value == 1 then
index 1c8be5f..ff97784 100644 (file)
@@ -45,7 +45,6 @@ private class NitxPhase
                var doc = new DocModel(mainmodule.model, mainmodule)
 
                var phases = [
-                       new ExtractionPhase(toolcontext, doc),
                        new MakePagePhase(toolcontext, doc),
                        new ConcernsPhase(toolcontext, doc),
                        new StructurePhase(toolcontext, doc),
index 3cb5e92..2580d95 100644 (file)
 module uml_base
 
 import toolcontext
-import model
+import model::model_collect
 
-redef class ToolContext
-       # -p
-       var opt_privacy = new OptionBool("Generates private API", "-p", "--private")
-
-       # Shortcut for the value of `self.opt_privacy`
-       fun private_gen: Bool do return opt_privacy.value
+# UML model builder.
+class UMLModel
 
-       redef init do
-               option_context.add_option opt_privacy
-               super
-       end
-end
+       # Model view
+       var view: ModelView
 
-class UMLModel
-       var model: Model
+       # Main module used for linearization.
        var mainmodule: MModule
-       var ctx: ToolContext
 end
index aa93740..c6d4870 100644 (file)
@@ -35,35 +35,23 @@ redef class UMLModel
                                        fontname = "Bitstream Vera Sans"
                                        fontsize = 8
                                ]\n"""
-               tpl.add model.tpl_class(ctx, mainmodule)
+               for mclass in view.mclasses do
+                       tpl.add mclass.tpl_class(self)
+                       tpl.add "\n"
+               end
                tpl.add "\}"
                return tpl
        end
 end
 
-redef class Model
-
-       # Generates a UML Class diagram from the entities of a `Model`
-       redef fun tpl_class(ctx, main) do
-               var t = new Template
-               for i in mclasses do
-                       if not ctx.private_gen and i.visibility != public_visibility then continue
-                       t.add i.tpl_class(ctx, main)
-                       t.add "\n"
-               end
-               return t
-       end
-
-end
-
 redef class MEntity
        # Generates a dot-compatible `Writable` UML Class diagram from `self`
-       fun tpl_class(ctx: ToolContext, main: MModule): Writable is abstract
+       fun tpl_class(model: UMLModel): Writable is abstract
 end
 
 redef class MClass
 
-       redef fun tpl_class(ctx, main) do
+       redef fun tpl_class(model) do
                var t = new Template
                t.add "{name} [\n label = \"\{"
                if kind == abstract_kind then
@@ -83,33 +71,22 @@ redef class MClass
                        t.add "]"
                end
                t.add "|"
-               var props: Collection[MProperty]
-               if ctx.private_gen then
-                       props = collect_intro_mproperties(none_visibility)
-               else
-                       props = collect_intro_mproperties(public_visibility)
-               end
+               var props = collect_intro_mproperties(model.view)
                for i in props do
-                       if i isa MAttribute then
-                               t.add i.tpl_class(ctx, main)
-                               t.add "\\l"
-                       end
+                       if not i isa MAttribute then continue
+                       t.add i.tpl_class(model)
+                       t.add "\\l"
                end
                t.add "|"
-               var meths
-               if ctx.private_gen then
-                       meths = collect_intro_mmethods(none_visibility)
-               else
-                       meths = collect_intro_mmethods(public_visibility)
-               end
-               for i in meths do
-                       t.add i.tpl_class(ctx, main)
+               for i in props do
+                       if not i isa MMethod then continue
+                       t.add i.tpl_class(model)
                        t.add "\\l"
                end
                t.add "\}\"\n]\n"
-               var g = in_hierarchy(main).direct_greaters
+               var g = in_hierarchy(model.mainmodule).direct_greaters
                for i in g do
-                       if not ctx.private_gen and i.visibility != public_visibility then continue
+                       if not model.view.accept_mentity(i) then continue
                        t.add "{i.name} -> {name} [dir=back"
                        if i.kind == interface_kind then
                                t.add " arrowtail=open style=dashed"
@@ -124,19 +101,19 @@ redef class MClass
 end
 
 redef class MMethod
-       redef fun tpl_class(ctx, main) do
+       redef fun tpl_class(model) do
                var tpl = new Template
                tpl.add visibility.tpl_class
                tpl.add " "
                tpl.add name.escape_to_dot
-               tpl.add intro.msignature.tpl_class(ctx, main)
+               tpl.add intro.msignature.tpl_class(model)
                return tpl
        end
 end
 
 redef class MSignature
 
-       redef fun tpl_class(ctx, main) do
+       redef fun tpl_class(model) do
                var t = new Template
                t.add "("
                var params = new Array[MParameter]
@@ -146,31 +123,31 @@ redef class MSignature
                if params.length > 0 then
                        t.add params.first.name
                        t.add ": "
-                       t.add params.first.mtype.tpl_class(ctx, main)
+                       t.add params.first.mtype.tpl_class(model)
                        for i in [1 .. params.length [ do
                                t.add ", "
                                t.add params[i].name
                                t.add ": "
-                               t.add params[i].mtype.tpl_class(ctx, main)
+                               t.add params[i].mtype.tpl_class(model)
                        end
                end
                t.add ")"
                if return_mtype != null then
                        t.add ": "
-                       t.add return_mtype.tpl_class(ctx, main)
+                       t.add return_mtype.tpl_class(model)
                end
                return t
        end
 end
 
 redef class MAttribute
-       redef fun tpl_class(ctx, main) do
+       redef fun tpl_class(model) do
                var tpl = new Template
                tpl.add visibility.tpl_class
                tpl.add " "
                tpl.add name
                tpl.add ": "
-               tpl.add intro.static_mtype.tpl_class(ctx, main)
+               tpl.add intro.static_mtype.tpl_class(model)
                return tpl
        end
 end
@@ -194,20 +171,20 @@ redef class MVisibility
 end
 
 redef class MClassType
-       redef fun tpl_class(c, m) do
+       redef fun tpl_class(model) do
                return name
        end
 end
 
 redef class MGenericType
-       redef fun tpl_class(c, m) do
+       redef fun tpl_class(model) do
                var t = new Template
                t.add name.substring(0, name.index_of('['))
                t.add "["
-               t.add arguments.first.tpl_class(c, m)
+               t.add arguments.first.tpl_class(model)
                for i in [1 .. arguments.length[ do
                        t.add ", "
-                       t.add arguments[i].tpl_class(c, m)
+                       t.add arguments[i].tpl_class(model)
                end
                t.add "]"
                return t
@@ -215,22 +192,22 @@ redef class MGenericType
 end
 
 redef class MParameterType
-       redef fun tpl_class(c, m) do
+       redef fun tpl_class(model) do
                return name
        end
 end
 
 redef class MVirtualType
-       redef fun tpl_class(c, m) do
+       redef fun tpl_class(model) do
                return name
        end
 end
 
 redef class MNullableType
-       redef fun tpl_class(c, m) do
+       redef fun tpl_class(model) do
                var t = new Template
                t.add "nullable "
-               t.add mtype.tpl_class(c, m)
+               t.add mtype.tpl_class(model)
                return t
        end
 end
index eda98e3..1720ff0 100644 (file)
@@ -34,38 +34,31 @@ redef class UMLModel
                                fontname = "Bitstream Vera Sans"
                                fontsize = 8
                        ]\n"""
-               tpl.add model.tpl_module(ctx, mainmodule)
+               tpl.add mainmodule.tpl_module(self)
                tpl.add "\}"
                return tpl
        end
 end
 
-redef class Model
-       # Returns a UML package diagram of `main`
-       redef fun tpl_module(ctx, main) do
-               return main.tpl_module(ctx, main)
-       end
+redef class MEntity
+       # Builds a dot UML package diagram entity from `self`
+       fun tpl_module(model: UMLModel): Writable is abstract
 end
 
 redef class MModule
-       redef fun tpl_module(ctx, main) do
+       redef fun tpl_module(model) do
                var t = new Template
                t.add "subgraph cluster{name} \{\n"
                t.add "label = \"{name}\"\n"
                for i in mclassdefs do
-                       if not ctx.private_gen and i.mclass.visibility != public_visibility then continue
-                       t.add i.tpl_module(ctx, main)
+                       if not model.view.accept_mentity(i) then continue
+                       t.add i.tpl_module(model)
                end
                t.add "\}\n"
                return t
        end
 end
 
-redef class MEntity
-       # Builds a dot UML package diagram entity from `self`
-       fun tpl_module(ctx: ToolContext, main: MModule): Writable is abstract
-end
-
 redef class MClassDef
 
        # Colour for the border of a class when first introduced
@@ -78,7 +71,7 @@ redef class MClassDef
        # Defaults to a shade of red
        var redef_colour = "#B24758"
 
-       redef fun tpl_module(ctx, main) do
+       redef fun tpl_module(model) do
                var t = new Template
                t.add "{mmodule}{name} [\n\tlabel = \"\{"
                if mclass.kind == abstract_kind then
@@ -101,15 +94,15 @@ redef class MClassDef
                t.add "|"
                for i in mpropdefs do
                        if not i isa MAttributeDef then continue
-                       if not ctx.private_gen and i.mproperty.visibility != public_visibility then continue
-                       t.add i.tpl_module(ctx, main)
+                       if not model.view.accept_mentity(i) then continue
+                       t.add i.tpl_module(model)
                        t.add "\\l"
                end
                t.add "|"
                for i in mpropdefs do
                        if not i isa MMethodDef then continue
-                       if not ctx.private_gen and i.mproperty.visibility != public_visibility then continue
-                       t.add i.tpl_module(ctx, main)
+                       if not model.view.accept_mentity(i) then continue
+                       t.add i.tpl_module(model)
                        t.add "\\l"
                end
                t.add "\}\""
@@ -135,24 +128,24 @@ redef class MClassDef
 end
 
 redef class MMethodDef
-       redef fun tpl_module(ctx, main) do
+       redef fun tpl_module(model) do
                var t = new Template
                t.add mproperty.visibility.tpl_class
                t.add " "
                t.add name.escape_to_dot
-               t.add msignature.tpl_class(ctx, main)
+               t.add msignature.tpl_class(model)
                return t
        end
 end
 
 redef class MAttributeDef
-       redef fun tpl_module(ctx, main) do
+       redef fun tpl_module(model) do
                var t = new Template
                t.add mproperty.visibility.tpl_class
                t.add " "
                t.add name
                t.add ": "
-               t.add static_mtype.tpl_class(ctx, main)
+               t.add static_mtype.tpl_class(model)
                return t
        end
 end
index 157b1de..2b49b9e 100644 (file)
@@ -16,7 +16,6 @@
 module model_html
 
 import model
-import model::model_collect
 import doc::doc_down
 import html::bootstrap
 
@@ -105,40 +104,11 @@ redef class MEntity
        #
        # Mainly used for icons.
        var css_classes = new Array[String]
-
-       # HTML Tree containing all the nested element of `self`.
-       #
-       # The nested elements depend on the type of `self`:
-       # `MPackage`: root mgroup
-       # `MGroup`: directly nested mgroups, mmodules
-       # `MModule`: mclassdefs
-       # `MClassDef`: mpropdefs
-       fun html_tree: UnorderedList do
-               var list = new UnorderedList
-               list.add_li html_tree_li
-               return list
-       end
-
-       # HTML Tree list item used by `html_tree`.
-       private fun html_tree_li: ListItem do return new ListItem(html_link)
 end
 
-
 redef class MPackage
        redef fun html_raw_namespace do return html_name
 
-       redef fun html_tree_li do
-               var tpl = new Template
-               tpl.add html_link
-               var list = new UnorderedList
-               var root = self.root
-               if root != null then
-                       list.add_li root.html_tree_li
-               end
-               tpl.add list
-               return new ListItem(tpl)
-       end
-
        redef var html_modifiers = ["package"]
        redef fun html_namespace do return html_link
        redef var css_classes = ["public"]
@@ -170,20 +140,6 @@ redef class MGroup
        end
 
        redef var css_classes = ["public"]
-
-       redef fun html_tree_li do
-               var tpl = new Template
-               tpl.add html_link
-               var list = new UnorderedList
-               for mgroup in in_nesting.direct_smallers do
-                       list.add_li mgroup.html_tree_li
-               end
-               for mmodule in mmodules do
-                       list.add_li mmodule.html_tree_li
-               end
-               tpl.add list
-               return new ListItem(tpl)
-       end
 end
 
 redef class MModule
@@ -217,17 +173,6 @@ redef class MModule
        end
 
        redef var css_classes = ["public"]
-
-       redef fun html_tree_li do
-               var tpl = new Template
-               tpl.add html_link
-               var list = new UnorderedList
-               for mclassdef in mclassdefs do
-                       list.add_li mclassdef.html_tree_li
-               end
-               tpl.add list
-               return new ListItem(tpl)
-       end
 end
 
 redef class MClass
@@ -281,17 +226,6 @@ end
 redef class MClassDef
        redef fun html_raw_namespace do return "{mmodule.html_raw_namespace}::{html_name}"
 
-       redef fun html_tree_li do
-               var tpl = new Template
-               tpl.add html_link
-               var list = new UnorderedList
-               for mpropdef in mpropdefs do
-                       list.add_li mpropdef.html_tree_li
-               end
-               tpl.add list
-               return new ListItem(tpl)
-       end
-
        redef fun mdoc_or_fallback do return mdoc or else mclass.mdoc_or_fallback
 
        # Depends if `self` is an intro or not.
@@ -374,10 +308,23 @@ redef class MClassDef
        redef fun css_classes do
                var set = new HashSet[String]
                if is_intro then set.add "intro"
-               for m in mclass.intro.collect_modifiers do set.add m.to_cmangle
-               for m in collect_modifiers do set.add m.to_cmangle
+               for m in mclass.intro.modifiers do set.add m.to_cmangle
+               for m in modifiers do set.add m.to_cmangle
                return set.to_a
        end
+
+
+       # List of all modifiers like redef, private etc.
+       var modifiers: Array[String] is lazy do
+               var res = new Array[String]
+               if not is_intro then
+                       res.add "redef"
+               else
+                       res.add mclass.visibility.to_s
+               end
+               res.add mclass.kind.to_s
+               return res
+       end
 end
 
 redef class MProperty
@@ -464,10 +411,36 @@ redef class MPropDef
        redef fun css_classes do
                var set = new HashSet[String]
                if is_intro then set.add "intro"
-               for m in mproperty.intro.collect_modifiers do set.add m.to_cmangle
-               for m in collect_modifiers do set.add m.to_cmangle
+               for m in mproperty.intro.modifiers do set.add m.to_cmangle
+               for m in modifiers do set.add m.to_cmangle
                return set.to_a
        end
+
+       # List of all modifiers like redef, private, abstract, intern, fun etc.
+       var modifiers: Array[String] is lazy do
+               var res = new Array[String]
+               if not is_intro then
+                       res.add "redef"
+               else
+                       res.add mproperty.visibility.to_s
+               end
+               var mprop = self
+               if mprop isa MVirtualTypeDef then
+                       res.add "type"
+               else if mprop isa MMethodDef then
+                       if mprop.is_abstract then
+                               res.add "abstract"
+                       else if mprop.is_intern then
+                               res.add "intern"
+                       end
+                       if mprop.mproperty.is_init then
+                               res.add "init"
+                       else
+                               res.add "fun"
+                       end
+               end
+               return res
+       end
 end
 
 redef class MAttributeDef
@@ -688,3 +661,53 @@ redef class MParameter
                return tpl
        end
 end
+
+redef class MEntityTree
+       # Render `self` as a hierarchical UnorderedList.
+       fun html_list: UnorderedList do
+               var lst = new_unordered_list
+               for r in roots do
+                       var li = new_mentity_item(r)
+                       lst.add_li li
+                       build_html_list(r, li)
+               end
+               return lst
+       end
+
+       # Build the html list recursively.
+       private fun build_html_list(e: MEntity, li: ListItem) do
+               if not sub.has_key(e) then return
+               var subs = sub[e]
+               var lst = new_unordered_list
+               for e2 in subs do
+                       if e2 isa MGroup and e2.is_root then
+                               build_html_list(e2, li)
+                       else
+                               var sli = new_mentity_item(e2)
+                               lst.add_li sli
+                               build_html_list(e2, sli)
+                       end
+               end
+               var text = new Template
+               text.add li.text
+               if not lst.is_empty then text.add lst
+               li.text = text
+       end
+
+       # HTML unordered List used to compose the tree.
+       #
+       # Redefine this method to add custom CSS classes or other html attributes.
+       protected fun new_unordered_list: UnorderedList do return new UnorderedList
+
+       # Return a li element for `mconcern` that can be displayed in a concern list
+       protected fun new_mentity_item(mentity: MEntity): ListItem do
+               var tpl = new Template
+               tpl.add mentity.html_link
+               var comment = mentity.html_synopsis
+               if comment != null then
+                       tpl.add ": "
+                       tpl.add comment
+               end
+               return new ListItem(tpl)
+       end
+end
index 574e32e..1357d37 100644 (file)
 module web_actions
 
 import web_views
-import model::model_collect
 
 # Display the tree of all loaded mentities.
 class TreeAction
-       super NitAction
+       super ModelAction
 
-       # Model to explore and render.
-       var model: Model
-
-       # View to render.
-       var view = new HtmlHomePage(model) is lazy
-
-       redef fun answer(request, url) do return render_view(view)
+       redef fun answer(request, url) do
+               var model = init_model_view(request)
+               var view = new HtmlHomePage(model.to_tree)
+               return render_view(view)
+       end
 end
 
 # Display the list of mentities matching `namespace`.
 class SearchAction
-       super NitAction
-
-       # Model to explore and render.
-       var model: Model
+       super ModelAction
 
        # TODO handle more than full namespaces.
        redef fun answer(request, url) do
@@ -44,7 +38,8 @@ class SearchAction
                if namespace == null or namespace.is_empty then
                        return render_error(400, "Missing :namespace.")
                end
-               var mentities = model.collect_by_namespace(namespace)
+               var model = init_model_view(request)
+               var mentities = model.mentities_by_namespace(namespace)
                if request.is_json_asked then
                        var json = new JsonArray
                        for mentity in mentities do
@@ -59,10 +54,7 @@ end
 
 # Display a MEntity source code.
 class CodeAction
-       super NitAction
-
-       # Model to explore and render.
-       var model: Model
+       super ModelAction
 
        # Modelbuilder used to access sources.
        var modelbuilder: ModelBuilder
@@ -73,7 +65,8 @@ class CodeAction
                if namespace == null or namespace.is_empty then
                        return render_error(400, "Missing :namespace.")
                end
-               var mentities = model.collect_by_namespace(namespace)
+               var model = init_model_view(request)
+               var mentities = model.mentities_by_namespace(namespace)
                if mentities.is_empty then
                        return render_error(404, "No mentity matching this namespace.")
                end
@@ -84,10 +77,7 @@ end
 
 # Display the doc of a MEntity.
 class DocAction
-       super NitAction
-
-       # Model to explore and render.
-       var model: Model
+       super ModelAction
 
        # Modelbuilder used to access sources.
        var modelbuilder: ModelBuilder
@@ -98,7 +88,8 @@ class DocAction
                if namespace == null or namespace.is_empty then
                        return render_error(400, "Missing :namespace.")
                end
-               var mentities = model.collect_by_namespace(namespace)
+               var model = init_model_view(request)
+               var mentities = model.mentities_by_namespace(namespace)
                if mentities.is_empty then
                        return render_error(404, "No mentity matching this namespace.")
                end
@@ -109,28 +100,20 @@ end
 
 # Return a random list of MEntities.
 class RandomAction
-       super NitAction
-
-       # Model to explore and render.
-       var model: Model
+       super ModelAction
 
        # TODO handle more than full namespaces.
        redef fun answer(request, url) do
                var n = request.int_arg("n") or else 10
                var k = request.string_arg("k") or else "modules"
+               var model = init_model_view(request)
                var mentities: Array[MEntity]
                if k == "modules" then
                        mentities = model.mmodules.to_a
                else if k == "classdefs" then
-                       mentities = new Array[MClassDef]
-                       for mclass in model.mclasses do
-                               mentities.add_all(mclass.mclassdefs)
-                       end
+                       mentities = model.mclassdefs.to_a
                else
-                       mentities = new Array[MPropDef]
-                       for mprop in model.mproperties do
-                               mentities.add_all(mprop.mpropdefs)
-                       end
+                       mentities = model.mpropdefs.to_a
                end
                mentities.shuffle
                mentities = mentities.sub(0, n)
index 68d132c..ecf639e 100644 (file)
@@ -15,7 +15,7 @@
 # Base classes used by `nitweb`.
 module web_base
 
-import frontend
+import model::model_views
 import nitcorn
 import json
 
@@ -85,6 +85,29 @@ class NitAction
        end
 end
 
+# Specific nitcorn Action that uses a Model
+class ModelAction
+       super NitAction
+
+       # Model to use.
+       var model: Model
+
+       # Init the model view from the `req` uri parameters.
+       fun init_model_view(req: HttpRequest): ModelView do
+               var view = new ModelView(model)
+
+               var show_private = req.bool_arg("private") or else false
+               if not show_private then view.min_visibility = protected_visibility
+
+               view.include_fictive = req.bool_arg("fictive") or else false
+               view.include_empty_doc = req.bool_arg("empty-doc") or else true
+               view.include_test_suite = req.bool_arg("test-suite") or else false
+               view.include_attribute = req.bool_arg("attributes") or else true
+
+               return view
+       end
+end
+
 # A NitView is rendered by an action.
 interface NitView
        # Renders this view and returns something that can be written to a HTTP response.
index 0400bc7..5f49f84 100644 (file)
@@ -25,15 +25,12 @@ class HtmlHomePage
        super NitView
 
        # Loaded model to display.
-       var model: Model
+       var tree: MEntityTree
 
        redef fun render(srv) do
                var tpl = new Template
                tpl.add new Header(1, "Loaded model")
-               for mpackage in model.mpackages do
-                       tpl.add new Header(3, "Packages")
-                       tpl.add mpackage.html_tree
-               end
+               tpl.add tree.html_list
                return tpl
        end
 end
index 4d76b95..fd347db 100644 (file)
@@ -21,11 +21,8 @@ index.html
 js/
 less/
 module_base_attr_nullable-.html
-property_base_attr_nullable-__Bar___a3.html
 property_base_attr_nullable-__Bar__a3.html
 property_base_attr_nullable-__Bar__a3_61d.html
-property_base_attr_nullable-__Foo___a1.html
-property_base_attr_nullable-__Foo___a2.html
 property_base_attr_nullable-__Foo__a1.html
 property_base_attr_nullable-__Foo__a1_61d.html
 property_base_attr_nullable-__Foo__a2.html
@@ -35,7 +32,6 @@ property_base_attr_nullable-__Foo__run.html
 property_base_attr_nullable-__Foo__run_other.html
 property_base_attr_nullable-__Int___43d.html
 property_base_attr_nullable-__Int__output.html
-property_base_attr_nullable-__Integer___val.html
 property_base_attr_nullable-__Integer__init.html
 property_base_attr_nullable-__Integer__output.html
 property_base_attr_nullable-__Integer__val.html
index c846cb7..181046e 100644 (file)
@@ -78,7 +78,7 @@ Task [
 Object -> Task [dir=back arrowtail=open style=dashed];
 
 A [
- label = "{A||+ pubA(a: A)\l+ pubA2(): A\l+ vpubA(): nullable A\l+ vpubA=(vpubA: nullable A)\l+ vpubA2(): A\l+ vpubA2=(vpubA2: A)\l}"
+ label = "{A||+ pubA(a: A)\l# proA(a: A)\l+ pubA2(): A\l# proA2(): A\l+ vpubA(): nullable A\l+ vpubA=(vpubA: nullable A)\l# vproA(): nullable A\l# vproA=(vproA: nullable A)\l+ vpubA2(): A\l+ vpubA2=(vpubA2: A)\l# vproA2(): A\l# vproA2=(vproA2: A)\l}"
 ]
 Object -> A [dir=back arrowtail=open style=dashed];