Merge: nitweb: list linearized definitions
authorJean Privat <jean@pryen.org>
Tue, 7 Jun 2016 19:11:09 +0000 (15:11 -0400)
committerJean Privat <jean@pryen.org>
Tue, 7 Jun 2016 19:11:09 +0000 (15:11 -0400)
Display linearization lists:

* Mclass linearize all the class definitions
   * linearization of `core::Array` mclassdefs: http://nitweb.moz-code.org/class/core::Array

* MProperty linearize all the prop definitions
    * linearization of `core::Object::hash`: http://nitweb.moz-code.org/property/core::Object::hash

* MClassDef linearize to intro
    * linearization of `core::flat$Array`: http://nitweb.moz-code.org/classdef/core::flat$Array

* MPropdef linearize to intro
    * linearization of `core$Array$Object::SELF`: http://nitweb.moz-code.org/propdef/core$Array$Object::SELF

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

share/nitweb/directives/entity/defcard.html [new file with mode: 0644]
share/nitweb/directives/entity/linearization.html [new file with mode: 0644]
share/nitweb/javascripts/entities.js
share/nitweb/javascripts/model.js
share/nitweb/views/class.html
share/nitweb/views/classdef.html
share/nitweb/views/propdef.html
share/nitweb/views/property.html
src/model/model_collect.nit
src/nitweb.nit
src/web/model_api.nit

diff --git a/share/nitweb/directives/entity/defcard.html b/share/nitweb/directives/entity/defcard.html
new file mode 100644 (file)
index 0000000..2c0b9c8
--- /dev/null
@@ -0,0 +1,26 @@
+<div class='card card-xl' ng-class='{active: focus.full_name == definition.full_name}'>
+       <div class='card-body'>
+               <h5 class='text-muted'>
+                       <span ng-if='definition.is_intro'>
+                               <span class='glyphicon glyphicon-plus' /> Introduction</span>
+                       </span>
+                       <span ng-if='!definition.is_intro'>
+                               <span class='glyphicon glyphicon-asterisk' /> Redefinition</span>
+                       </span>
+                       <span ng-if='definition.mclass'>
+                               of <entity-link mentity='definition.mclass' />
+                       </span>
+                       <span ng-if='definition.mproperty'>
+                               of <entity-link mentity='definition.mproperty' />
+                       </span>
+                       <span ng-if='definition.mclassdef'>
+                               in <entity-link mentity='definition.mmodule' />
+                               :: <entity-link mentity='definition.mclassdef' />
+                       </span>
+                       <span ng-if='!definition.mclassdef'>
+                               in <entity-link mentity='definition.mmodule' />
+                       </span>
+               </h5>
+               <entity-location mentity='definition' />
+       </div>
+</div>
diff --git a/share/nitweb/directives/entity/linearization.html b/share/nitweb/directives/entity/linearization.html
new file mode 100644 (file)
index 0000000..afdde43
--- /dev/null
@@ -0,0 +1,11 @@
+<div class='entity-list' ng-if='listEntities.length'>
+       <h3>{{listTitle}}</h3>
+       <div class='card-list'>
+               <div ng-repeat='def in listEntities'>
+                       <entity-def definition='def' focus='listFocus' />
+                       <h4 ng-if='!$last' class='text-muted text-center'>
+                               <span class='glyphicon glyphicon-chevron-up'></span>
+                       </h4>
+               </div>
+       </div>
+</div>
index 9d9a452..d1cad5f 100644 (file)
                .module('entities', ['ui', 'model'])
 
                .controller('EntityCtrl', ['Model', '$routeParams', '$scope', function(Model, $routeParams, $scope) {
+                       this.loadEntityLinearization = function() {
+                               Model.loadEntityLinearization($routeParams.id,
+                                       function(data) {
+                                               $scope.linearization = data;
+                                       }, function(err) {
+                                               $scope.error = err;
+                                       });
+                       };
+
                        Model.loadEntity($routeParams.id,
                                function(data) {
                                        $scope.mentity = data;
                                }
                        };
                })
+
+               .directive('entityLinearization', function() {
+                       return {
+                               restrict: 'E',
+                               scope: {
+                                       listEntities: '=',
+                                       listTitle: '@',
+                                       listFocus: '='
+                               },
+                               templateUrl: '/directives/entity/linearization.html'
+                       };
+               })
+
+               .directive('entityDef', ['Model', function(Model, Code) {
+                       return {
+                               restrict: 'E',
+                               scope: {
+                                       definition: '=',
+                                       focus: '='
+                               },
+                               link: function ($scope, element, attrs) {
+                                       $scope.$watch("definition", function() {
+                                               /*.loadEntityDefs($scope.definition.full_name,
+                                                       function(data) {
+                                                               $scope.mentity = data;
+                                                       }, function(err) {
+                                                               $scope.error = err;
+                                                       });
+                                               Model.loadEntityCode($scope.definition.full_name,
+                                                       function(data) {
+                                                               $scope.code = data;
+                                                       }, function(err) {
+                                                               $scope.error = err;
+                                                       });*/
+                                       });
+                               },
+                               templateUrl: '/directives/entity/defcard.html'
+                       };
+               }])
 })();
index 3bf927c..aae3cae 100644 (file)
                                                .error(cbErr);
                                },
 
+                               loadEntityLinearization: function(id, cb, cbErr) {
+                                       $http.get(apiUrl + '/linearization/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
                                search: function(q, n, cb, cbErr) {
                                        $http.get(apiUrl + '/search?q=' + q + '&n=' + n)
                                                .success(cb)
index 52bd1e9..2585705 100644 (file)
@@ -5,15 +5,20 @@
        </div>
 
        <ul class='nav nav-tabs'>
-               <li class='active'>
+               <li role='presentation' class='active'>
                        <a data-toggle='tab' data-target='#doc'>
                                <span class='glyphicon glyphicon-book'/> Doc
                        </a>
                </li>
+               <li role='presentation'>
+                       <a data-toggle='tab' role='tab' data-target='#linearization' aria-controls='linearization' ng-click='entityCtrl.loadEntityLinearization()'>
+                               <span class='glyphicon glyphicon-arrow-down'/> Linearization
+                       </a>
+               </li>
        </ul>
 
        <div class='tab-content'>
-               <div class='tab-pane fade in active' id='doc'>
+               <div role='tabpanel' class='tab-pane fade in active' id='doc'>
                        <entity-doc mentity='mentity.intro'/>
 
                        <entity-list list-title='Parents'
                                list-entities='mentity.redef_mproperties'
                                list-object-filter='{is_init: "!true"}' />
                </div>
+               <div role='tabpanel' class='tab-pane fade' id='linearization'>
+                       <entity-linearization
+                               list-title='Class definitions'
+                               list-entities='linearization'
+                               list-focus='mentity.intro' />
+               </div>
        </div>
 </div>
index 50768ec..a028436 100644 (file)
@@ -1,4 +1,4 @@
-<div class='container-fluid'>
+<div class='container-fluid' ng-init='entityCtrl.loadEntityLinearization()'>
        <div class='page-header'>
                <h2><entity-signature mentity='mentity'/></h2>
                <entity-link mentity='mentity.mpackage' />
@@ -7,10 +7,24 @@
        </div>
 
        <ul class='nav nav-tabs' role='tablist'>
-               <li class='warning'>
+               <li role='presentation' class='warning'>
                        <a ng-href='{{mentity.mclass.web_url}}'>
                                <span class='glyphicon glyphicon-chevron-left'/> Go to class
                        </a>
                </li>
+               <li role='presentation' class='active'>
+                       <a data-toggle='tab' role='tab' data-target='#linearization' aria-controls='linearization'>
+                               <span class='glyphicon glyphicon-arrow-down'/> Linearization
+                       </a>
+               </li>
        </ul>
+
+       <div class='tab-content'>
+               <div role='tabpanel' class='tab-pane fade in active' id='linearization'>
+                       <entity-linearization
+                               list-title='Class definitions'
+                               list-entities='linearization'
+                               list-focus='mentity' />
+               </div>
+       </div>
 </div>
index 2692c9c..30d0397 100644 (file)
@@ -1,5 +1,4 @@
-<div class='container-fluid'>
-
+<div class='container-fluid' ng-init='entityCtrl.loadEntityLinearization()'>
        <div class='page-header'>
                <h2><entity-signature mentity='mentity'/></h2>
                <entity-link mentity='mentity.mpackage' />
@@ -9,10 +8,24 @@
        </div>
 
        <ul class='nav nav-tabs'>
-               <li class='warning'>
+               <li role='presentation' class='warning'>
                        <a href='{{mentity.mproperty.web_url}}'>
                                <span class='glyphicon glyphicon-chevron-left'/> Go to property
                        </a>
                </li>
+               <li role='presentation' class='active'>
+                       <a data-toggle='tab' role='tab' data-target='#linearization' aria-controls='linearization'>
+                               <span class='glyphicon glyphicon-arrow-down'/> Linearization
+                       </a>
+               </li>
        </ul>
+
+       <div class='tab-content'>
+               <div role='tabpanel' class='tab-pane fade in active' id='linearization'>
+                       <entity-linearization
+                               list-title='Class definitions'
+                               list-entities='linearization'
+                               list-focus='mentity' />
+               </div>
+       </div>
 </div>
index d5e7352..fea0da7 100644 (file)
@@ -8,16 +8,27 @@
        </div>
 
        <ul class='nav nav-tabs'>
-               <li class='active'>
+               <li role='presentation' class='active'>
                        <a data-toggle='tab' data-target='#doc'>
                                <span class='glyphicon glyphicon-book'/> Doc
                        </a>
                </li>
+               <li role='presentation'>
+                       <a data-toggle='tab' role='tab' data-target='#linearization' aria-controls='linearization' ng-click='entityCtrl.loadEntityLinearization()'>
+                               <span class='glyphicon glyphicon-arrow-down'/> Linearization
+                       </a>
+               </li>
        </ul>
 
        <div class='tab-content'>
                <div role='tabpanel' class='tab-pane fade in active' id='doc'>
                        <entity-doc mentity='mentity.intro'/>
                </div>
+               <div role='tabpanel' class='tab-pane fade' id='linearization'>
+                       <entity-linearization
+                               list-title='Class definitions'
+                               list-entities='linearization'
+                               list-focus='mentity.intro' />
+               </div>
        </div>
 </div>
index 79970e5..bd7d12c 100644 (file)
@@ -37,6 +37,11 @@ redef class MEntity
        fun collect_modifiers: Array[String] do
                return new Array[String]
        end
+
+       # Collect `self` linearization anchored on `mainmodule`.
+       fun collect_linearization(mainmodule: MModule): nullable Array[MEntity] do
+               return null
+       end
 end
 
 redef class MPackage
@@ -163,6 +168,12 @@ redef class MClass
 
        redef fun collect_modifiers do return intro.collect_modifiers
 
+       redef fun collect_linearization(mainmodule) do
+               var mclassdefs = self.mclassdefs.to_a
+               mainmodule.linearize_mclassdefs(mclassdefs)
+               return mclassdefs
+       end
+
        # Collect direct parents of `self` with `visibility >= to min_visibility`.
        fun collect_parents(view: ModelView): Set[MClass] do
                var res = new HashSet[MClass]
@@ -411,6 +422,15 @@ end
 
 redef class MClassDef
 
+       redef fun collect_linearization(mainmodule) do
+               var mclassdefs = new Array[MClassDef]
+               for mclassdef in in_hierarchy.as(not null).greaters do
+                       if mclassdef.mclass == self.mclass then mclassdefs.add mclassdef
+               end
+               mainmodule.linearize_mclassdefs(mclassdefs)
+               return mclassdefs
+       end
+
        # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
        fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
                var res = new HashSet[MPropDef]
@@ -457,6 +477,12 @@ end
 
 redef class MProperty
        redef fun collect_modifiers do return intro.collect_modifiers
+
+       redef fun collect_linearization(mainmodule) do
+               var mpropdefs = self.mpropdefs.to_a
+               mainmodule.linearize_mpropdefs(mpropdefs)
+               return mpropdefs
+       end
 end
 
 redef class MPropDef
@@ -486,4 +512,16 @@ redef class MPropDef
                end
                return res
        end
+
+       redef fun collect_linearization(mainmodule) do
+               var mpropdefs = new Array[MPropDef]
+               var mentity = self
+               while not mentity.is_intro do
+                       mpropdefs.add mentity
+                       mentity = mentity.lookup_next_definition(mainmodule, mentity.mclassdef.bound_mtype)
+               end
+               mpropdefs.add mentity
+               mainmodule.linearize_mpropdefs(mpropdefs)
+               return mpropdefs
+       end
 end
index 13e3dce..ef83fb6 100644 (file)
@@ -100,6 +100,7 @@ class APIRouter
                use("/entity/:id", new APIEntity(model, mainmodule))
                use("/code/:id", new APIEntityCode(model, mainmodule, modelbuilder))
                use("/uml/:id", new APIEntityUML(model, mainmodule))
+               use("/linearization/:id", new APIEntityLinearization(model, mainmodule))
        end
 end
 
index 080dcb2..5b24282 100644 (file)
@@ -120,6 +120,26 @@ class APIEntity
        end
 end
 
+# Linearize super definitions of a MClassDef or a MPropDef if any.
+#
+# Example: `GET /entity/core::Array/linearization`
+class APIEntityLinearization
+       super APIHandler
+
+       redef fun get(req, res) do
+               var mentity = mentity_from_uri(req, res)
+               if mentity == null then
+                       res.error 404
+                       return
+               end
+               var lin = mentity.collect_linearization(mainmodule)
+               if lin == null then
+                       res.error 404
+                       return
+               end
+               res.json new JsonArray.from(lin)
+       end
+end
 
 # Return a UML representation of MEntity.
 #