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
-
#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) ⇒ 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
322 323 324 325 326 327 328 329 330 331 |
# File 'lib/jsduck/class.rb', line 322 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.
303 304 305 |
# File 'lib/jsduck/class.rb', line 303 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.
312 313 314 315 316 317 318 319 |
# File 'lib/jsduck/class.rb', line 312 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
36 37 38 |
# File 'lib/jsduck/class.rb', line 36 def [](key) @doc[key] end |
#all_local_members ⇒ Object
Returns all local members of class
256 257 258 259 260 261 262 263 264 |
# File 'lib/jsduck/class.rb', line 256 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
245 246 247 248 249 250 251 252 253 |
# File 'lib/jsduck/class.rb', line 245 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.
125 126 127 128 129 130 131 132 |
# File 'lib/jsduck/class.rb', line 125 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
67 68 69 |
# File 'lib/jsduck/class.rb', line 67 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
268 269 270 |
# File 'lib/jsduck/class.rb', line 268 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.
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/jsduck/class.rb', line 225 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
289 290 291 292 293 294 295 296 297 |
# File 'lib/jsduck/class.rb', line 289 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.
107 108 109 |
# File 'lib/jsduck/class.rb', line 107 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
212 213 214 215 216 217 218 |
# File 'lib/jsduck/class.rb', line 212 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.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/jsduck/class.rb', line 78 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.
117 118 119 120 121 |
# File 'lib/jsduck/class.rb', line 117 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.
140 141 142 143 144 145 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 |
# File 'lib/jsduck/class.rb', line 140 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) ⇒ Object
merges second members hash into first one
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/jsduck/class.rb', line 175 def merge!(hash1, hash2) 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).
56 57 58 |
# File 'lib/jsduck/class.rb', line 56 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”
277 278 279 |
# File 'lib/jsduck/class.rb', line 277 def package_name Class.package_name(@doc[:name]) end |
#parent ⇒ Object
Returns instance of parent class, or nil if there is none
41 42 43 |
# File 'lib/jsduck/class.rb', line 41 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.
72 73 74 |
# File 'lib/jsduck/class.rb', line 72 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”
284 285 286 |
# File 'lib/jsduck/class.rb', line 284 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.
201 202 203 204 205 206 207 208 209 |
# File 'lib/jsduck/class.rb', line 201 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] new[:overrides] << old unless new[:overrides].any? {|m| m[:owner] == old[:owner] } 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]
50 51 52 53 |
# File 'lib/jsduck/class.rb', line 50 def superclasses p = parent p ? p.superclasses + [p] : [] end |
#to_hash ⇒ Object
Returns copy of @doc hash
97 98 99 |
# File 'lib/jsduck/class.rb', line 97 def to_hash @doc.clone end |
#to_json(*a) ⇒ Object
101 102 103 |
# File 'lib/jsduck/class.rb', line 101 def to_json(*a) to_hash.to_json(*a) end |