class JsDuck::Class
Encapsulates class documentation and provides some commonly needed methods on it. Otherwise it acts like Hash, providing the [] method.
Attributes
Used only by MembersIndex
class itself to access the MembersIndex
instances of parents and mixins.
Public Class Methods
True if the given member is a constructor method
# File lib/jsduck/class.rb, line 196 def self.constructor?(member) member[:tagname] == :method && member[:name] == "constructor" end
Generates member :id from member hash
# File lib/jsduck/class.rb, line 189 def self.member_id(m) # Sanitize $ in member names with something safer name = m[:name].gsub(/\$/, 'S-') "#{m[:static] ? 'static-' : ''}#{m[:tagname]}-#{name}" end
Creates JSDuck class.
Pass true as second parameter to create a placeholder class.
# File lib/jsduck/class.rb, line 19 def initialize(doc, class_exists=true) @doc = doc # Wrap classname into custom string class that allows # differenciating between existing and missing classes. @doc[:name] = ClassNameString.new(@doc[:name], class_exists) @doc[:members] = [] if !@doc[:members] @members_index = MembersIndex.new(self) @relations = nil end
Public Instance Methods
Accessor to internal hash
# File lib/jsduck/class.rb, line 60 def [](key) @doc[key] end
Assignment to internal hash keys
# File lib/jsduck/class.rb, line 65 def []=(key, value) @doc[key] = value end
Returns all local members of class
# File lib/jsduck/class.rb, line 182 def all_local_members @doc[:members] end
Returns an array of class instances this class directly depends on. Possible types are:
-
:mixins
-
:requires
-
:uses
# File lib/jsduck/class.rb, line 96 def deps(type) @doc[type] ? @doc[type].collect {|classname| lookup(classname) } : [] end
Returns list of members filtered by a query. Searches both local and inherited members.
The query hash can contain the following fields:
-
:name : String - the name of the member to find.
-
:tagname : Symbol - the member type to look for.
-
:static : Boolean - true to only return static members,
false to only return instance members. When nil or unspecified, both static and instance members are returned.
-
:local : Boolean - true to only return non-inherited members.
When called without arguments all members are returned.
When nothing found, an empty array is returned.
# File lib/jsduck/class.rb, line 149 def find_members(query={}) if query[:name] ms = @members_index.global_by_name[query[:name]] || [] ms = ms.find_all {|m| m[:owner] == @doc[:name]} if query[:local] elsif query[:local] ms = @members_index.all_local else ms = @members_index.all_global end if query[:tagname] ms = ms.find_all {|m| m[:tagname] == query[:tagname] } end if query[:static] == true ms = ms.find_all {|m| m[:static] } elsif query[:static] == false ms = ms.reject {|m| m[:static] } end ms end
Returns true when this class inherits from the specified class. Also returns true when the class itself is the one we are asking about.
# File lib/jsduck/class.rb, line 126 def inherits_from?(class_name) return @doc[:name] == class_name || (parent ? parent.inherits_from?(class_name) : false) end
Returns the internal doc object.
# File lib/jsduck/class.rb, line 34 def internal_doc @doc end
Sets the internal doc object.
The doc object is processed in parallel and then assigned back through this method. But because of parallel processing the assigned doc object will not be just a modified old @doc but a completely new. If we were to just assign to @doc the find_members
caches would still point to old @doc members resulting in mysterious errors further along…
# File lib/jsduck/class.rb, line 46 def internal_doc=(doc) @doc.merge!(doc) do |key, oldval, newval| if key == :members oldval.zip(newval) do |ms| ms[0].merge!(ms[1]) end oldval else newval end end end
Looks up class object by name When not found, prints warning message.
# File lib/jsduck/class.rb, line 107 def lookup(classname) if @relations[classname] @relations[classname] elsif @relations.ignore?(classname) || classname =~ /\*/ # Ignore explicitly ignored classes and classnames with # wildcards in them. We could expand the wildcard, but that # can result in a very long list of classes, like when # somebody requires 'Ext.form.*', so for now we do the # simplest thing and ignore it. Class.new({:name => classname}, false) else Logger.warn(:extend, "Class #{classname} not found", @doc[:files][0]) # Create placeholder class Class.new({:name => classname}, false) end end
Returns all direct mixins of this class. Same as deps
(:mixins).
# File lib/jsduck/class.rb, line 85 def mixins deps(:mixins) end
Returns instance of parent class, or nil if there is none
# File lib/jsduck/class.rb, line 70 def parent @doc[:extends] ? lookup(@doc[:extends]) : nil end
Same ase deps
, but pulls out the dependencies from all parent classes.
# File lib/jsduck/class.rb, line 101 def parent_deps(type) parent ? parent.deps(type) + parent.parent_deps(type) : [] end
This must be called whenever member hashes are changed. It updates the :id fields of members and clears the caches.
# File lib/jsduck/class.rb, line 174 def refresh_member_ids! @doc[:members].each do |m| m[:id] = Class.member_id(m) end @members_index.invalidate! end
Returns array of ancestor classes. Example result when asking ancestors of MyPanel might be:
[Ext.util.Observable, Ext.Component, Ext.Panel]
# File lib/jsduck/class.rb, line 79 def superclasses p = parent p ? p.superclasses + [p] : [] end