+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2008 Jean Privat <jean@pryen.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.
-
-# Model exploration and traversing facilities
-module model_utils
-
-import model
-
-redef class MGroup
- # Collect nested modules
- fun collect_mmodules: Set[MModule] do
- var res = new HashSet[MModule]
- res.add_all mmodules
- for mgroup in in_nesting.direct_smallers do
- res.add_all mgroup.collect_mmodules
- end
- return res
- end
-end
-
-redef class MModule
-
- # The list of intro mclassdef in the module.
- # with visibility >= to min_visibility
- fun intro_mclassdefs(min_visibility: MVisibility): 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
- res.add mclassdef
- end
- return res
- end
-
- # The list of redef mclassdef in the module.
- # with visibility >= to min_visibility
- fun redef_mclassdefs(min_visibility: MVisibility): 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
- res.add mclassdef
- end
- return res
- end
-
- # The list of intro mclass in the module.
- # with visibility >= to min_visibility
- fun filter_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- for mclass in intro_mclasses do
- if mclass.visibility < min_visibility then continue
- res.add mclass
- end
- return res
- end
-
- # Get the list of mclasses refined in 'self'.
- fun redef_mclasses: Set[MClass] do
- var mclasses = new HashSet[MClass]
- for c in mclassdefs do
- if not c.is_intro then mclasses.add(c.mclass)
- end
- return mclasses
- end
-
- # Get the list of mclasses refined in 'self'.
- fun filter_redef_mclasses(min_visibility: MVisibility): 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)
- end
- return mclasses
- end
-
- # Find all mmodules nested in `self` if `self` is the default module of a `MGroup`.
- fun nested_mmodules: Array[MModule] do
- var res = new Array[MModule]
- var mgroup = mgroup
- if mgroup == null or self != mgroup.default_mmodule then return res
- for mmodule in mgroup.mmodules do
- if mmodule == self then continue
- res.add mmodule
- end
- for nested in mgroup.in_nesting.direct_smallers do
- var default = nested.default_mmodule
- if default == null then continue
- res.add default
- end
- return res
- end
-end
-
-redef class MClass
-
- # Get direct parents of 'self'.
- fun parents: Set[MClass] do
- var ret = new HashSet[MClass]
- for mclassdef in mclassdefs do
- for mclasstype in mclassdef.supertypes do
- ret.add(mclasstype.mclass)
- end
- end
- return ret
- end
-
- # Get all ancestors of 'self'.
- fun ancestors: Set[MClass] do
- var lst = 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
- lst.add(super_mclassdef.mclass)
- end
- end
- return lst
- end
-
- # Get direct children of 'self'.
- fun children: Set[MClass] do
- var lst = 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
- lst.add(sub_mclassdef.mclass)
- end
- end
- return lst
- end
-
- # Get all children of 'self'.
- fun descendants: Set[MClass] do
- var lst = 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
- lst.add(sub_mclassdef.mclass)
- end
- end
- return lst
- end
-
- # Get the list of constructors available for 'self'.
- fun constructors: Set[MMethod] do
- var res = new HashSet[MMethod]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MMethodDef then
- if mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
- end
- end
- end
- return res
- end
-
- # Get the list of methods introduced in 'self'.
- fun intro_methods: Set[MMethod] do
- var res = new HashSet[MMethod]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MMethodDef then
- if mpropdef.is_intro and not mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
- end
- end
- end
- return res
- end
-
- # the set of properties introduced in 'self'.
- fun intro_mproperties(min_visibility: MVisibility): 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
- set.add(mprop)
- end
- end
- return set
- end
-
- fun intro_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
- var set = new HashSet[MPropDef]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if not mpropdef.is_intro then continue
- if mpropdef.mproperty.visibility < min_visibility then continue
- set.add(mpropdef)
- end
- end
- return set
- end
-
- # the set of locally refined properties in 'self'.
- fun redef_mproperties(min_visibility: MVisibility): 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)
- end
- end
- return set
- end
-
- fun redef_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
- var set = new HashSet[MPropDef]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef.is_intro then continue
- if mpropdef.mproperty.visibility < min_visibility then continue
- set.add(mpropdef)
- end
- end
- return set
- end
-
- # the set of methods inherited by 'self'.
- fun inherited_mproperties(mainmodule: MModule, min_visibility: MVisibility): Set[MProperty] do
- var set = new HashSet[MProperty]
- for parent in in_hierarchy(mainmodule).direct_greaters do
- set.add_all(parent.intro_mproperties(min_visibility))
- set.add_all(parent.inherited_mproperties(mainmodule, min_visibility))
- end
- return set
- end
-
- # the set of introduced and redefined mproperties
- fun local_mproperties(min_visibility: MVisibility): Set[MProperty] do
- var set = new HashSet[MProperty]
- set.add_all(intro_mproperties(min_visibility))
- set.add_all(redef_mproperties(min_visibility))
- return set
- end
-
- # the set of all accessible mproperties for this class
- fun all_mproperties(mainmodule: MModule, min_visibility: MVisibility): Set[MProperty] do
- var set = new HashSet[MProperty]
- set.add_all(local_mproperties(min_visibility))
- set.add_all(inherited_mproperties(mainmodule, min_visibility))
- return set
- end
-
- # the set of all accessible mattributes for this class
- fun all_mattributes(mainmodule: MModule, min_visibility: MVisibility): Set[MAttribute] do
- var set = new HashSet[MAttribute]
- for mprop in all_mproperties(mainmodule, min_visibility) do
- if mprop isa MAttribute then set.add(mprop)
- end
- return set
- end
-
- # Get the list of locally refined methods in 'self'.
- fun redef_methods: Set[MMethod] do
- var res = new HashSet[MMethod]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MMethodDef then
- if not mpropdef.is_intro and not mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
- end
- end
- end
- return res
- end
-
- fun inherited_methods: Set[MMethod] do
- var res = new HashSet[MMethod]
- for s in ancestors do
- for m in s.intro_methods do
- if not self.intro_methods.has(m) and not self.redef_methods.has(m) then res.add(m)
- end
- end
- return res
- end
-
- # Get the list of all virtual types available in 'self'.
- fun virtual_types: Set[MVirtualTypeProp] do
- var res = new HashSet[MVirtualTypeProp]
- for mclassdef in mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MVirtualTypeDef then
- res.add(mpropdef.mproperty)
- end
- end
- end
- for ancestor in ancestors do
- for mclassdef in ancestor.mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef isa MVirtualTypeDef then
- res.add(mpropdef.mproperty)
- end
- end
- end
- end
- return res
- end
-
- # Get the list of all parameter types in 'self'.
- fun parameter_types: Map[String, MType] do
- var res = new HashMap[String, MType]
- for p in mparameters do
- res[p.name] = p
- end
- return res
- end
-end
-
-redef class MAttribute
- # Is this attribute nullable for sure?
- #
- # This mean that its introduction is declarred with a nullable static type
- # since attributes are invariant this will work on most cases
- # attributes with static type anchored with a virtual type are not "nullable for-sure"
- # because this type can be redefined in subclasses
- fun is_nullable: Bool do return intro.static_mtype isa MNullableType
-end
-
-redef class MClassDef
- # modifiers are keywords like redef, private etc.
- fun modifiers: Array[String] 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
-
- fun collect_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
- var res = new HashSet[MPropDef]
- for mpropdef in mpropdefs do
- if mpropdef.mproperty.visibility < min_visibility then continue
- res.add mpropdef
- end
- return res
- end
-
- fun collect_intro_mpropdefs(min_visibility: MVisibility): 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
- res.add mpropdef
- end
- return res
- end
-
- fun collect_redef_mpropdefs(min_visibility: MVisibility): 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
- res.add mpropdef
- end
- return res
- end
-end
-
-redef class MPropDef
- # modifiers are keywords like redef, private etc.
- fun modifiers: Array[String] 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