Class: TypeProf::Core::ModuleEntity
- Inherits:
-
Object
- Object
- TypeProf::Core::ModuleEntity
- Defined in:
- lib/typeprof/core/env/module_entity.rb
Instance Attribute Summary collapse
-
#child_modules ⇒ Object
readonly
Returns the value of attribute child_modules.
-
#consts ⇒ Object
readonly
Returns the value of attribute consts.
-
#cpath ⇒ Object
readonly
Returns the value of attribute cpath.
-
#cvar_reads ⇒ Object
readonly
Returns the value of attribute cvar_reads.
-
#cvars ⇒ Object
readonly
Returns the value of attribute cvars.
-
#included_modules ⇒ Object
readonly
Returns the value of attribute included_modules.
-
#inner_modules ⇒ Object
readonly
Returns the value of attribute inner_modules.
-
#ivar_reads ⇒ Object
readonly
Returns the value of attribute ivar_reads.
-
#ivars ⇒ Object
readonly
Returns the value of attribute ivars.
-
#methods ⇒ Object
readonly
Returns the value of attribute methods.
-
#module_decls ⇒ Object
readonly
Returns the value of attribute module_decls.
-
#module_defs ⇒ Object
readonly
Returns the value of attribute module_defs.
-
#outer_module ⇒ Object
readonly
Returns the value of attribute outer_module.
-
#prepended_modules ⇒ Object
readonly
Returns the value of attribute prepended_modules.
-
#self_types ⇒ Object
readonly
Returns the value of attribute self_types.
-
#static_reads ⇒ Object
readonly
Returns the value of attribute static_reads.
-
#subclass_checks ⇒ Object
readonly
Returns the value of attribute subclass_checks.
-
#superclass ⇒ Object
readonly
Returns the value of attribute superclass.
-
#superclass_type_args ⇒ Object
readonly
Returns the value of attribute superclass_type_args.
-
#type_aliases ⇒ Object
readonly
Returns the value of attribute type_aliases.
-
#type_params ⇒ Object
readonly
Returns the value of attribute type_params.
Instance Method Summary collapse
- #add_include_decl(genv, node) ⇒ Object
- #add_include_def(genv, node) ⇒ Object
- #add_module_decl(genv, decl) ⇒ Object
- #add_module_def(genv, node) ⇒ Object
- #add_prepend_decl(genv, node) ⇒ Object
- #add_prepend_def(genv, node) ⇒ Object
- #each_descendant(base_mod = nil) {|_self| ... } ⇒ Object
- #exist? ⇒ Boolean
- #find_superclass_const_read ⇒ Object
- #get_cname ⇒ Object
- #get_const(cname) ⇒ Object
- #get_cvar(name) ⇒ Object
- #get_ivar(singleton, name) ⇒ Object
- #get_method(singleton, mid) ⇒ Object
- #get_type_alias(name) ⇒ Object
- #get_vertexes(vtxs) ⇒ Object
-
#initialize(cpath, outer_module = self) ⇒ ModuleEntity
constructor
A new instance of ModuleEntity.
- #interface? ⇒ Boolean
- #module? ⇒ Boolean
- #on_ancestors_updated(genv, base_mod) ⇒ Object
- #on_inner_modules_changed(genv, changed_cname) ⇒ Object
- #on_module_added(genv) ⇒ Object
- #on_module_removed(genv) ⇒ Object
- #on_parent_modules_changed(genv) ⇒ Object
- #pretty_print(q) ⇒ Object
- #remove_include_decl(genv, node) ⇒ Object
- #remove_include_def(genv, node) ⇒ Object
- #remove_module_decl(genv, decl) ⇒ Object
- #remove_module_def(genv, node) ⇒ Object
- #remove_prepend_decl(genv, node) ⇒ Object
- #remove_prepend_def(genv, node) ⇒ Object
- #show_cpath ⇒ Object
- #update_parent(genv, origin, old_parent, new_parent_cpath) ⇒ Object
- #update_type_params ⇒ Object
Constructor Details
#initialize(cpath, outer_module = self) ⇒ ModuleEntity
Returns a new instance of ModuleEntity.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/typeprof/core/env/module_entity.rb', line 3 def initialize(cpath, outer_module = self) @cpath = cpath @module_decls = Set[] @module_defs = Set[] @include_decls = Set[] @include_defs = Set[] @prepend_decls = [] @prepend_defs = [] @inner_modules = {} @outer_module = outer_module # parent modules (superclass and all modules that I include) @superclass = nil @self_types = {} @included_modules = {} @prepended_modules = {} @basic_object = @cpath == [:BasicObject] # child modules (subclasses and all modules that include me) @child_modules = {} # class Foo[X, Y, Z] < Bar[A, B, C] @superclass_type_args = nil # A, B, C @type_params = [] # X, Y, Z @consts = {} @methods = { true => {}, false => {} } @ivars = { true => {}, false => {} } @cvars = {} @type_aliases = {} @static_reads = {} @subclass_checks = Set[] @ivar_reads = Set[] # should be handled in @ivars ?? @cvar_reads = Set[] end |
Instance Attribute Details
#child_modules ⇒ Object (readonly)
Returns the value of attribute child_modules.
53 54 55 |
# File 'lib/typeprof/core/env/module_entity.rb', line 53 def child_modules @child_modules end |
#consts ⇒ Object (readonly)
Returns the value of attribute consts.
58 59 60 |
# File 'lib/typeprof/core/env/module_entity.rb', line 58 def consts @consts end |
#cpath ⇒ Object (readonly)
Returns the value of attribute cpath.
42 43 44 |
# File 'lib/typeprof/core/env/module_entity.rb', line 42 def cpath @cpath end |
#cvar_reads ⇒ Object (readonly)
Returns the value of attribute cvar_reads.
67 68 69 |
# File 'lib/typeprof/core/env/module_entity.rb', line 67 def cvar_reads @cvar_reads end |
#cvars ⇒ Object (readonly)
Returns the value of attribute cvars.
61 62 63 |
# File 'lib/typeprof/core/env/module_entity.rb', line 61 def cvars @cvars end |
#included_modules ⇒ Object (readonly)
Returns the value of attribute included_modules.
51 52 53 |
# File 'lib/typeprof/core/env/module_entity.rb', line 51 def included_modules @included_modules end |
#inner_modules ⇒ Object (readonly)
Returns the value of attribute inner_modules.
46 47 48 |
# File 'lib/typeprof/core/env/module_entity.rb', line 46 def inner_modules @inner_modules end |
#ivar_reads ⇒ Object (readonly)
Returns the value of attribute ivar_reads.
66 67 68 |
# File 'lib/typeprof/core/env/module_entity.rb', line 66 def ivar_reads @ivar_reads end |
#ivars ⇒ Object (readonly)
Returns the value of attribute ivars.
60 61 62 |
# File 'lib/typeprof/core/env/module_entity.rb', line 60 def ivars @ivars end |
#methods ⇒ Object (readonly)
Returns the value of attribute methods.
59 60 61 |
# File 'lib/typeprof/core/env/module_entity.rb', line 59 def methods @methods end |
#module_decls ⇒ Object (readonly)
Returns the value of attribute module_decls.
43 44 45 |
# File 'lib/typeprof/core/env/module_entity.rb', line 43 def module_decls @module_decls end |
#module_defs ⇒ Object (readonly)
Returns the value of attribute module_defs.
44 45 46 |
# File 'lib/typeprof/core/env/module_entity.rb', line 44 def module_defs @module_defs end |
#outer_module ⇒ Object (readonly)
Returns the value of attribute outer_module.
47 48 49 |
# File 'lib/typeprof/core/env/module_entity.rb', line 47 def outer_module @outer_module end |
#prepended_modules ⇒ Object (readonly)
Returns the value of attribute prepended_modules.
52 53 54 |
# File 'lib/typeprof/core/env/module_entity.rb', line 52 def prepended_modules @prepended_modules end |
#self_types ⇒ Object (readonly)
Returns the value of attribute self_types.
50 51 52 |
# File 'lib/typeprof/core/env/module_entity.rb', line 50 def self_types @self_types end |
#static_reads ⇒ Object (readonly)
Returns the value of attribute static_reads.
64 65 66 |
# File 'lib/typeprof/core/env/module_entity.rb', line 64 def static_reads @static_reads end |
#subclass_checks ⇒ Object (readonly)
Returns the value of attribute subclass_checks.
65 66 67 |
# File 'lib/typeprof/core/env/module_entity.rb', line 65 def subclass_checks @subclass_checks end |
#superclass ⇒ Object (readonly)
Returns the value of attribute superclass.
49 50 51 |
# File 'lib/typeprof/core/env/module_entity.rb', line 49 def superclass @superclass end |
#superclass_type_args ⇒ Object (readonly)
Returns the value of attribute superclass_type_args.
55 56 57 |
# File 'lib/typeprof/core/env/module_entity.rb', line 55 def superclass_type_args @superclass_type_args end |
#type_aliases ⇒ Object (readonly)
Returns the value of attribute type_aliases.
62 63 64 |
# File 'lib/typeprof/core/env/module_entity.rb', line 62 def type_aliases @type_aliases end |
#type_params ⇒ Object (readonly)
Returns the value of attribute type_params.
56 57 58 |
# File 'lib/typeprof/core/env/module_entity.rb', line 56 def type_params @type_params end |
Instance Method Details
#add_include_decl(genv, node) ⇒ Object
179 180 181 182 |
# File 'lib/typeprof/core/env/module_entity.rb', line 179 def add_include_decl(genv, node) @include_decls << node genv.add_static_eval_queue(:parent_modules_changed, self) end |
#add_include_def(genv, node) ⇒ Object
189 190 191 192 |
# File 'lib/typeprof/core/env/module_entity.rb', line 189 def add_include_def(genv, node) @include_defs << node genv.add_static_eval_queue(:parent_modules_changed, self) end |
#add_module_decl(genv, decl) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/typeprof/core/env/module_entity.rb', line 112 def add_module_decl(genv, decl) on_module_added(genv) @module_decls << decl if @type_params update_type_params if @type_params != decl.params else @type_params = decl.params end if decl.is_a?(AST::SigClassNode) && !@superclass_type_args @superclass_type_args = decl.superclass_args end ce = @outer_module.get_const(get_cname) ce.add_decl(decl) ce end |
#add_module_def(genv, node) ⇒ Object
165 166 167 168 169 170 171 |
# File 'lib/typeprof/core/env/module_entity.rb', line 165 def add_module_def(genv, node) on_module_added(genv) @module_defs << node ce = @outer_module.get_const(get_cname) ce.add_def(node) ce end |
#add_prepend_decl(genv, node) ⇒ Object
199 200 201 202 |
# File 'lib/typeprof/core/env/module_entity.rb', line 199 def add_prepend_decl(genv, node) @prepend_decls << node genv.add_static_eval_queue(:parent_modules_changed, self) end |
#add_prepend_def(genv, node) ⇒ Object
209 210 211 212 |
# File 'lib/typeprof/core/env/module_entity.rb', line 209 def add_prepend_def(genv, node) @prepend_defs << node genv.add_static_eval_queue(:parent_modules_changed, self) end |
#each_descendant(base_mod = nil) {|_self| ... } ⇒ Object
419 420 421 422 423 424 425 |
# File 'lib/typeprof/core/env/module_entity.rb', line 419 def each_descendant(base_mod = nil, &blk) return if base_mod == self yield self @child_modules.each_key do |child_mod| child_mod.each_descendant(base_mod || self, &blk) end end |
#exist? ⇒ Boolean
81 82 83 |
# File 'lib/typeprof/core/env/module_entity.rb', line 81 def exist? !@module_decls.empty? || !@module_defs.empty? end |
#find_superclass_const_read ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'lib/typeprof/core/env/module_entity.rb', line 249 def find_superclass_const_read return nil if @basic_object if @module_decls.empty? @module_defs.each do |mdef| case mdef when AST::ClassNode if mdef.superclass_cpath const_read = mdef.superclass_cpath.static_ret return const_read ? const_read.cpath : [] end when AST::SingletonClassNode next when AST::ModuleNode return nil else raise end end else @module_decls.each do |mdecl| case mdecl when AST::SigClassNode if mdecl.superclass_cpath const_read = mdecl.static_ret[:superclass_cpath].last return const_read ? const_read.cpath : [] end when AST::SigModuleNode, AST::SigInterfaceNode return nil end end end return [] end |
#get_cname ⇒ Object
77 78 79 |
# File 'lib/typeprof/core/env/module_entity.rb', line 77 def get_cname @cpath.empty? ? :Object : @cpath.last end |
#get_const(cname) ⇒ Object
427 428 429 |
# File 'lib/typeprof/core/env/module_entity.rb', line 427 def get_const(cname) @consts[cname] ||= ValueEntity.new end |
#get_cvar(name) ⇒ Object
439 440 441 |
# File 'lib/typeprof/core/env/module_entity.rb', line 439 def get_cvar(name) @cvars[name] ||= ValueEntity.new end |
#get_ivar(singleton, name) ⇒ Object
435 436 437 |
# File 'lib/typeprof/core/env/module_entity.rb', line 435 def get_ivar(singleton, name) @ivars[singleton][name] ||= ValueEntity.new end |
#get_method(singleton, mid) ⇒ Object
431 432 433 |
# File 'lib/typeprof/core/env/module_entity.rb', line 431 def get_method(singleton, mid) @methods[singleton][mid] ||= MethodEntity.new end |
#get_type_alias(name) ⇒ Object
443 444 445 |
# File 'lib/typeprof/core/env/module_entity.rb', line 443 def get_type_alias(name) @type_aliases[name] ||= TypeAliasEntity.new end |
#get_vertexes(vtxs) ⇒ Object
447 448 449 450 451 452 453 454 455 |
# File 'lib/typeprof/core/env/module_entity.rb', line 447 def get_vertexes(vtxs) @inner_modules.each_value do |mod| next if self.equal?(mod) # for Object mod.get_vertexes(vtxs) end @consts.each_value do |cdef| vtxs << cdef.vtx end end |
#interface? ⇒ Boolean
73 74 75 |
# File 'lib/typeprof/core/env/module_entity.rb', line 73 def interface? @cpath.last && @cpath.last.start_with?("_") end |
#module? ⇒ Boolean
69 70 71 |
# File 'lib/typeprof/core/env/module_entity.rb', line 69 def module? !@superclass && !@basic_object end |
#on_ancestors_updated(genv, base_mod) ⇒ Object
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/typeprof/core/env/module_entity.rb', line 401 def on_ancestors_updated(genv, base_mod) @child_modules.each_key {|child_mod| child_mod.on_ancestors_updated(genv, base_mod || self) } @static_reads.each_value do |static_reads| static_reads.each do |static_read| genv.add_static_eval_queue(:static_read_changed, static_read) end end @methods.each do |_, methods| methods.each_value do |me| me.method_call_boxes.each do |box| genv.add_run(box) end end end @ivar_reads.each {|ivar_read| genv.add_run(ivar_read) } @cvar_reads.each {|cvar_read| genv.add_run(cvar_read) } end |
#on_inner_modules_changed(genv, changed_cname) ⇒ Object
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/typeprof/core/env/module_entity.rb', line 85 def on_inner_modules_changed(genv, changed_cname) @child_modules.each_key do |child_mod| child_mod.on_inner_modules_changed(genv, changed_cname) end if @static_reads[changed_cname] @static_reads[changed_cname].each do |static_read| genv.add_static_eval_queue(:static_read_changed, static_read) end end end |
#on_module_added(genv) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/typeprof/core/env/module_entity.rb', line 96 def on_module_added(genv) return if @cpath.empty? unless exist? genv.add_static_eval_queue(:inner_modules_changed, [@outer_module, get_cname]) end genv.add_static_eval_queue(:parent_modules_changed, self) end |
#on_module_removed(genv) ⇒ Object
104 105 106 107 108 109 110 |
# File 'lib/typeprof/core/env/module_entity.rb', line 104 def on_module_removed(genv) return if @cpath.empty? genv.add_static_eval_queue(:parent_modules_changed, self) unless exist? genv.add_static_eval_queue(:inner_modules_changed, [@outer_module, get_cname]) end end |
#on_parent_modules_changed(genv) ⇒ Object
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/typeprof/core/env/module_entity.rb', line 285 def on_parent_modules_changed(genv) any_updated = false unless @basic_object new_superclass_cpath = find_superclass_const_read new_superclass, updated = update_parent(genv, :superclass, @superclass, new_superclass_cpath) if updated @superclass = new_superclass any_updated = true end end @module_decls.each do |mdecl| case mdecl when AST::SigModuleNode mdecl.static_ret[:self_types].each_with_index do |const_reads, i| key = [mdecl, i] new_parent_cpath = const_reads.last.cpath new_self_type, updated = update_parent(genv, key, @self_types[key], new_parent_cpath) if updated if new_self_type @self_types[key] = new_self_type else @self_types.delete(key) || raise end any_updated = true end end end end @self_types.delete_if do |(origin_mdecl, origin_idx), old_mod| if @module_decls.include?(origin_mdecl) false else _new_self_type, updated = update_parent(genv, [origin_mdecl, origin_idx], old_mod, nil) any_updated ||= updated true end end @include_decls.each do |idecl| new_parent_cpath = idecl.static_ret.last.cpath new_parent, updated = update_parent(genv, idecl, @included_modules[idecl], new_parent_cpath) if updated if new_parent @included_modules[idecl] = new_parent else @included_modules.delete(idecl) || raise end any_updated = true end end @include_defs.each do |idef| new_parent_cpath = idef.static_ret ? idef.static_ret.cpath : nil new_parent, updated = update_parent(genv, idef, @included_modules[idef], new_parent_cpath) if updated if new_parent @included_modules[idef] = new_parent else @included_modules.delete(idef) || raise end any_updated = true end end @prepend_decls.each do |pdecl| new_parent_cpath = pdecl.static_ret.last.cpath new_parent, updated = update_parent(genv, pdecl, @prepended_modules[pdecl], new_parent_cpath) if updated if new_parent @prepended_modules[pdecl] = new_parent else @prepended_modules.delete(pdecl) || raise end any_updated = true end end @prepend_defs.each do |pdef| new_parent_cpath = pdef.static_ret ? pdef.static_ret.cpath : nil new_parent, updated = update_parent(genv, pdef, @prepended_modules[pdef], new_parent_cpath) if updated if new_parent @prepended_modules[pdef] = new_parent else @prepended_modules.delete(pdef) || raise end any_updated = true end end @included_modules.delete_if do |origin, old_mod| if @include_decls.include?(origin) || @include_defs.include?(origin) false else _new_parent, updated = update_parent(genv, origin, old_mod, nil) any_updated ||= updated true end end @prepended_modules.delete_if do |origin, old_mod| if @prepend_decls.include?(origin) || @prepend_defs.include?(origin) false else _new_parent, updated = update_parent(genv, origin, old_mod, nil) any_updated ||= updated true end end if any_updated @subclass_checks.each do |mcall_box| genv.add_run(mcall_box) end on_ancestors_updated(genv, nil) end end |
#pretty_print(q) ⇒ Object
461 462 463 |
# File 'lib/typeprof/core/env/module_entity.rb', line 461 def pretty_print(q) q.text "#<ModuleEntity[::#{ @cpath.empty? ? "Object" : @cpath.join("::") }]>" end |
#remove_include_decl(genv, node) ⇒ Object
184 185 186 187 |
# File 'lib/typeprof/core/env/module_entity.rb', line 184 def remove_include_decl(genv, node) @include_decls.delete(node) || raise genv.add_static_eval_queue(:parent_modules_changed, self) end |
#remove_include_def(genv, node) ⇒ Object
194 195 196 197 |
# File 'lib/typeprof/core/env/module_entity.rb', line 194 def remove_include_def(genv, node) @include_defs.delete(node) || raise genv.add_static_eval_queue(:parent_modules_changed, self) end |
#remove_module_decl(genv, decl) ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/typeprof/core/env/module_entity.rb', line 132 def remove_module_decl(genv, decl) @outer_module.get_const(get_cname).remove_decl(decl) @module_decls.delete(decl) || raise update_type_params if @type_params == decl.params if decl.is_a?(AST::SigClassNode) && @superclass_type_args == decl.superclass_args @superclass_type_args = nil @module_decls.each do |decl| if decl.superclass_args @superclass_type_args = decl.superclass_args break end end end on_module_removed(genv) end |
#remove_module_def(genv, node) ⇒ Object
173 174 175 176 177 |
# File 'lib/typeprof/core/env/module_entity.rb', line 173 def remove_module_def(genv, node) @outer_module.get_const(get_cname).remove_def(node) @module_defs.delete(node) || raise on_module_removed(genv) end |
#remove_prepend_decl(genv, node) ⇒ Object
204 205 206 207 |
# File 'lib/typeprof/core/env/module_entity.rb', line 204 def remove_prepend_decl(genv, node) @prepend_decls.delete(node) || raise genv.add_static_eval_queue(:parent_modules_changed, self) end |
#remove_prepend_def(genv, node) ⇒ Object
214 215 216 217 |
# File 'lib/typeprof/core/env/module_entity.rb', line 214 def remove_prepend_def(genv, node) @prepend_defs.delete(node) || raise genv.add_static_eval_queue(:parent_modules_changed, self) end |
#show_cpath ⇒ Object
457 458 459 |
# File 'lib/typeprof/core/env/module_entity.rb', line 457 def show_cpath @cpath.empty? ? "Object" : @cpath.join("::" ) end |
#update_parent(genv, origin, old_parent, new_parent_cpath) ⇒ Object
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/typeprof/core/env/module_entity.rb', line 219 def update_parent(genv, origin, old_parent, new_parent_cpath) new_parent = new_parent_cpath ? genv.resolve_cpath(new_parent_cpath) : nil if old_parent != new_parent # check circular inheritance mod = new_parent while mod if mod == self # TODO: report an "circular inheritance" error new_parent = nil break end mod = mod.superclass end if old_parent != new_parent if old_parent set = old_parent.child_modules[self] set.delete(origin) old_parent.child_modules.delete(self) if set.empty? end if new_parent set = new_parent.child_modules[self] ||= Set[] set << origin end return [new_parent, true] end end return [new_parent, false] end |
#update_type_params ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/typeprof/core/env/module_entity.rb', line 150 def update_type_params @type_params = nil @module_decls.each do |decl| params = decl.params next unless params if @type_params @type_params = params if (@type_params <=> params) > 0 else @type_params = params end end @type_params ||= [] # TODO: report an error if there are multiple inconsistent declarations end |