Class: JsDuck::Class
- Inherits:
-
Object
- Object
- JsDuck::Class
- Defined in:
- lib/jsduck/class.rb
Overview
Encapsulates class documentation and provides some commonly needed methods on it. Otherwise it acts like Hash, providing the [] method.
Instance Attribute Summary collapse
-
#relations ⇒ Object
Returns the value of attribute relations.
Class Method Summary collapse
-
.default_members_hash ⇒ Object
Returns default hash that has empty array for each member type.
-
.package_name(name) ⇒ Object
Utility method that given a package or class name finds the name of its parent package.
-
.short_name(name) ⇒ Object
Utility method that given full package or class name extracts the “class”-part of the name.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Accessor to internal hash.
-
#[]=(key, value) ⇒ Object
Assignment to internal hash keys.
-
#all_local_members ⇒ Object
Returns all local members of class.
-
#all_members ⇒ Object
Returns all members of class, including the inherited and mixed in ones.
-
#constructor_first(ms) ⇒ Object
If methods list contains constructor, rename it with class name and move into beginning of methods list.
-
#deps(type) ⇒ Object
Returns an array of class instances this class directly depends on.
-
#full_name ⇒ Object
A way to access full class name with similar syntax to package_name and short_name.
-
#get_members(name, type_name = nil, static = false) ⇒ Object
Returns members by name.
-
#icon ⇒ Object
Returns CSS icons class for the class.
-
#inherits_from?(class_name) ⇒ Boolean
Returns true when this class inherits from the specified class.
-
#initialize(doc, class_exists = true) ⇒ Class
constructor
Creates JSDuck class.
-
#internal_doc ⇒ Object
Accessors for internal doc object.
- #internal_doc=(doc) ⇒ Object
-
#local_members_hash(type, context) ⇒ Object
Helper method to get the direct members of this class.
-
#lookup(classname) ⇒ Object
Looks up class object by name When not found, prints warning message.
-
#members(type, context = :members) ⇒ Object
Returns array of all public members of particular type in a class, sorted by name.
-
#members_hash(type, context = :members) ⇒ Object
Returns hash of all members in class (and of parent classes and mixin classes).
-
#merge!(hash1, hash2, skip_overrides = false) ⇒ Object
merges second members hash into first one.
-
#mixins ⇒ Object
Returns all direct mixins of this class.
-
#package_name ⇒ Object
Returns package name of the class.
-
#parent ⇒ Object
Returns instance of parent class, or nil if there is none.
-
#parent_deps(type) ⇒ Object
Same ase #deps, but pulls out the dependencies from all parent classes.
-
#short_name ⇒ Object
Returns last part of full class name.
-
#store_overrides(old, new) ⇒ Object
Invoked when merge! finds two members with the same name.
-
#superclasses ⇒ Object
Returns array of ancestor classes.
-
#to_hash ⇒ Object
Returns copy of @doc hash.
- #to_json(*a) ⇒ Object
Constructor Details
#initialize(doc, class_exists = true) ⇒ Class
Creates JSDuck class.
Pass true as second parameter to create a placeholder class.
14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/jsduck/class.rb', line 14 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] = Class.default_members_hash if !@doc[:members] @doc[:statics] = Class.default_members_hash if !@doc[:statics] @relations = nil end |
Instance Attribute Details
#relations ⇒ Object
Returns the value of attribute relations.
9 10 11 |
# File 'lib/jsduck/class.rb', line 9 def relations @relations end |
Class Method Details
.default_members_hash ⇒ Object
Returns default hash that has empty array for each member type
339 340 341 342 343 344 345 346 347 348 |
# File 'lib/jsduck/class.rb', line 339 def self.default_members_hash return { :cfg => [], :property => [], :method => [], :event => [], :css_var => [], :css_mixin => [], } end |
.package_name(name) ⇒ Object
Utility method that given a package or class name finds the name of its parent package.
320 321 322 |
# File 'lib/jsduck/class.rb', line 320 def self.package_name(name) name.slice(0, name.length - self.short_name(name).length - 1) || "" end |
.short_name(name) ⇒ Object
Utility method that given full package or class name extracts the “class”-part of the name.
Because we try to emulate ext-doc, it’s not as simple as just taking the last part. See class_spec.rb for details.
329 330 331 332 333 334 335 336 |
# File 'lib/jsduck/class.rb', line 329 def self.short_name(name) parts = name.split(/\./) short = parts.pop while parts.length > 1 && parts.last =~ /^[A-Z]/ short = parts.pop + "." + short end short end |
Instance Method Details
#[](key) ⇒ Object
Accessor to internal hash
37 38 39 |
# File 'lib/jsduck/class.rb', line 37 def [](key) @doc[key] end |
#[]=(key, value) ⇒ Object
Assignment to internal hash keys
42 43 44 |
# File 'lib/jsduck/class.rb', line 42 def []=(key, value) @doc[key] = value end |
#all_local_members ⇒ Object
Returns all local members of class
273 274 275 276 277 278 279 280 281 |
# File 'lib/jsduck/class.rb', line 273 def all_local_members all = [] [:members, :statics].each do |group| @doc[group].each_value do |ms| all += ms end end all end |
#all_members ⇒ Object
Returns all members of class, including the inherited and mixed in ones
262 263 264 265 266 267 268 269 270 |
# File 'lib/jsduck/class.rb', line 262 def all_members all = [] [:members, :statics].each do |group| @doc[group].each_key do |type| all += members(type, group) end end all end |
#constructor_first(ms) ⇒ Object
If methods list contains constructor, rename it with class name and move into beginning of methods list.
131 132 133 134 135 136 137 138 |
# File 'lib/jsduck/class.rb', line 131 def constructor_first(ms) constr = ms.find {|m| m[:name] == "constructor" } if constr ms.delete(constr) ms.unshift(constr) end ms end |
#deps(type) ⇒ Object
Returns an array of class instances this class directly depends on. Possible types are:
-
:mixins
-
:requires
-
:uses
73 74 75 |
# File 'lib/jsduck/class.rb', line 73 def deps(type) @doc[type] ? @doc[type].collect {|classname| lookup(classname) } : [] end |
#full_name ⇒ Object
A way to access full class name with similar syntax to package_name and short_name
285 286 287 |
# File 'lib/jsduck/class.rb', line 285 def full_name @doc[:name] end |
#get_members(name, type_name = nil, static = false) ⇒ Object
Returns members by name. An array of one or more members, or empty array when nothing matches.
Optionally one can also specify type name to differenciate between different types of members.
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/jsduck/class.rb', line 242 def get_members(name, type_name=nil, static=false) # build hash of all members unless @members_map @members_map = {} [:members, :statics].each do |group| @doc[group].each_key do |type| members_hash(type, group).each_pair do |key, member| @members_map[key] = (@members_map[key] || []) + [member] end end end end ms = @members_map[name] || [] ms = ms.find_all {|m| m[:tagname] == type_name } if type_name ms = ms.find_all {|m| m[:meta][:static] } if static return ms end |
#icon ⇒ Object
Returns CSS icons class for the class
306 307 308 309 310 311 312 313 314 |
# File 'lib/jsduck/class.rb', line 306 def icon if @doc[:singleton] "icon-singleton" elsif inherits_from?("Ext.Component") "icon-component" else "icon-class" end end |
#inherits_from?(class_name) ⇒ Boolean
Returns true when this class inherits from the specified class. Also returns true when the class itself is the one we are asking about.
113 114 115 |
# File 'lib/jsduck/class.rb', line 113 def inherits_from?(class_name) return full_name == class_name || (parent ? parent.inherits_from?(class_name) : false) end |
#internal_doc ⇒ Object
Accessors for internal doc object. These are used to run ClassFormatter on the internal doc object and then assign it back.
29 30 31 |
# File 'lib/jsduck/class.rb', line 29 def internal_doc @doc end |
#internal_doc=(doc) ⇒ Object
32 33 34 |
# File 'lib/jsduck/class.rb', line 32 def internal_doc=(doc) @doc = doc end |
#local_members_hash(type, context) ⇒ Object
Helper method to get the direct members of this class
229 230 231 232 233 234 235 |
# File 'lib/jsduck/class.rb', line 229 def local_members_hash(type, context) local_members = {} (@doc[context][type] || []).each do |m| local_members[m[:name]] = m end local_members end |
#lookup(classname) ⇒ Object
Looks up class object by name When not found, prints warning message.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/jsduck/class.rb', line 84 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 context = @doc[:files][0] Logger.instance.warn(:extend, "Class #{classname} not found", context[:filename], context[:linenr]) # Create placeholder class Class.new({:name => classname}, false) end end |
#members(type, context = :members) ⇒ Object
Returns array of all public members of particular type in a class, sorted by name.
For methods the the constructor is listed first.
See members_hash for details.
123 124 125 126 127 |
# File 'lib/jsduck/class.rb', line 123 def members(type, context=:members) ms = members_hash(type, context).values #.find_all {|m| !m[:private] } ms.sort! {|a,b| a[:name] <=> b[:name] } type == :method ? constructor_first(ms) : ms end |
#members_hash(type, context = :members) ⇒ Object
Returns hash of all members in class (and of parent classes and mixin classes). Members are methods, properties, cfgs, events (member type is specified through ‘type’ parameter).
When parent and child have members with same name, member from child overrides tha parent member.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/jsduck/class.rb', line 146 def members_hash(type, context=:members) # Singletons have no static members if @doc[:singleton] && context == :statics # Warn if singleton has static members if @doc[context][type].length > 0 Logger.instance.warn(:sing_static, "Singleton class #{@doc[:name]} can't have static members, remove the @static tag.") end return {} end ms = parent ? parent.members_hash(type, context) : {} mixins.each do |mix| merge!(ms, mix.members_hash(type, context)) end # For static members, exclude everything not explicitly marked as inheritable if context == :statics ms.delete_if {|key, member| !member[:inheritable] } end merge!(ms, local_members_hash(type, context)) # If singleton has static members, include them as if they were # instance members. Otherwise they will be completely excluded # from the docs, as the static members block is not created for # singletons. if @doc[:singleton] && @doc[:statics][type].length > 0 merge!(ms, local_members_hash(type, :statics)) end ms end |
#merge!(hash1, hash2, skip_overrides = false) ⇒ Object
merges second members hash into first one
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/jsduck/class.rb', line 181 def merge!(hash1, hash2, skip_overrides=false) hash2.each_pair do |name, m| if m[:meta] && m[:meta][:hide] if hash1[name] hash1.delete(name) else ctx = m[:files][0] Logger.instance.warn(:hide, "@hide used but #{m[:tagname]} #{m[:name]} not found in parent class", ctx[:filename], ctx[:linenr]) end else if hash1[name] store_overrides(hash1[name], m) end hash1[name] = m end end end |
#mixins ⇒ Object
Returns all direct mixins of this class. Same as #deps(:mixins).
62 63 64 |
# File 'lib/jsduck/class.rb', line 62 def mixins deps(:mixins) end |
#package_name ⇒ Object
Returns package name of the class.
That is the namespace part of full class name.
For example “My.package” is package_name of “My.package.Class”
294 295 296 |
# File 'lib/jsduck/class.rb', line 294 def package_name Class.package_name(@doc[:name]) end |
#parent ⇒ Object
Returns instance of parent class, or nil if there is none
47 48 49 |
# File 'lib/jsduck/class.rb', line 47 def parent @doc[:extends] ? lookup(@doc[:extends]) : nil end |
#parent_deps(type) ⇒ Object
Same ase #deps, but pulls out the dependencies from all parent classes.
78 79 80 |
# File 'lib/jsduck/class.rb', line 78 def parent_deps(type) parent ? parent.deps(type) + parent.parent_deps(type) : [] end |
#short_name ⇒ Object
Returns last part of full class name
For example for “My.package.Class” it is “Class”
301 302 303 |
# File 'lib/jsduck/class.rb', line 301 def short_name Class.short_name(@doc[:name]) end |
#store_overrides(old, new) ⇒ Object
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.
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/jsduck/class.rb', line 207 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], :id => old[:id], } end end end |
#superclasses ⇒ Object
Returns array of ancestor classes. Example result when asking ancestors of MyPanel might be:
[Ext.util.Observable, Ext.Component, Ext.Panel]
56 57 58 59 |
# File 'lib/jsduck/class.rb', line 56 def superclasses p = parent p ? p.superclasses + [p] : [] end |
#to_hash ⇒ Object
Returns copy of @doc hash
103 104 105 |
# File 'lib/jsduck/class.rb', line 103 def to_hash @doc.clone end |
#to_json(*a) ⇒ Object
107 108 109 |
# File 'lib/jsduck/class.rb', line 107 def to_json(*a) to_hash.to_json(*a) end |