class JsDuck::MembersIndex
Helper for JsDuck::Class
for indexing its members.
While indexing the members of a class it accesses the MembersIndex
instances of parent and mixins of that class through the members_index accessor. This isn't the nicest approach, but better than having all of this functionality inside the JsDuck::Class
itself.
Public Class Methods
# File lib/jsduck/members_index.rb, line 13 def initialize(cls) @cls = cls @map_by_id = nil @global_map_by_id = nil @global_map_by_name = nil end
Public Instance Methods
Returns array of all members (including inherited ones)
# File lib/jsduck/members_index.rb, line 35 def all_global global_by_id.values end
Returns array of all local members (excludes inherited ones)
# File lib/jsduck/members_index.rb, line 40 def all_local local_by_id.values.reject {|m| m[:hide] } end
Returns hash of all members by name (including inherited ones)
# File lib/jsduck/members_index.rb, line 21 def global_by_name unless @global_map_by_name @global_map_by_name = {} global_by_id.each_pair do |id, m| @global_map_by_name[m[:name]] = [] unless @global_map_by_name[m[:name]] @global_map_by_name[m[:name]] << m end end @global_map_by_name end
Clears the search cache.
Using this degrades performance. It's currently triggered just once after InheritDoc process is run. Avoid using it in other places.
# File lib/jsduck/members_index.rb, line 49 def invalidate! @map_by_id = nil @global_map_by_id = nil @global_map_by_name = nil end
Protected Instance Methods
Returns hash of all members by ID (including inherited ones)
# File lib/jsduck/members_index.rb, line 58 def global_by_id unless @global_map_by_id # Make copy of parent class members. # Otherwise we'll be merging directly into parent class. @global_map_by_id = @cls.parent ? @cls.parent.members_index.global_by_id.clone : {} @cls.mixins.each do |mix| merge!(@global_map_by_id, mix.members_index.global_by_id) end # Exclude all non-inheritable static members @global_map_by_id.delete_if {|id, m| m[:static] && !m[:inheritable] } merge!(@global_map_by_id, local_by_id) end @global_map_by_id end
Returns hash of local members by ID (no inherited members)
# File lib/jsduck/members_index.rb, line 78 def local_by_id unless @map_by_id @map_by_id = {} @cls[:members].each do |m| @map_by_id[m[:id]] = m end end @map_by_id end
Private Instance Methods
merges second members hash into first one
# File lib/jsduck/members_index.rb, line 93 def merge!(hash1, hash2) hash2.each_pair do |name, m| if m[:hide] if hash1[name] hash1.delete(name) else msg = "@hide used but #{m[:tagname]} #{m[:name]} not found in parent class" Logger.warn(:hide, msg, m[:files][0]) end else if hash1[name] store_overrides(hash1[name], m) end hash1[name] = m end end end
Invoked when merge! finds two members with the same name. New member always overrides the old, but inside new we keep a list of members it overrides. Normally one member will override one other member, but a member from mixin can override multiple members - although there's not a single such case in ExtJS, we have to handle it.
Every overridden member is listed just once.
# File lib/jsduck/members_index.rb, line 119 def store_overrides(old, new) # Sometimes a class is included multiple times (like Ext.Base) # resulting in its members overriding themselves. Because of # this, ignore overriding itself. if new[:owner] != old[:owner] new[:overrides] = [] unless new[:overrides] unless new[:overrides].any? {|m| m[:owner] == old[:owner] } # Make a copy of the important properties for us. We can't # just push the actual `old` member itself, because there # can be circular overrides (notably with Ext.Base), which # will result in infinite loop when we try to convert our # class into JSON. new[:overrides] << { :name => old[:name], :owner => old[:owner], } end end end