Class: JsDuck::Aggregator
- Inherits:
-
Object
- Object
- JsDuck::Aggregator
- Defined in:
- lib/jsduck/aggregator.rb
Overview
Combines JavaScript Parser, DocParser and Merger. Produces array of classes as result.
Instance Method Summary collapse
-
#add_class(cls) ⇒ Object
When class exists, merge it with class node.
- #add_empty_class(name, doc = "") ⇒ Object
-
#add_member(node) ⇒ Object
Tries to place members into classes where they belong.
- #add_orphan(node) ⇒ Object
- #add_to_class(cls, member) ⇒ Object
-
#aggregate(file) ⇒ Object
Combines chunk of parsed JavaScript together with previously added chunks.
-
#append_ext4_event_options ⇒ Object
Appends Ext4 options parameter to each event parameter list.
-
#classify_orphans ⇒ Object
Creates classes for orphans that have :owner property defined, and then inserts orphans to these classes.
-
#create_accessors ⇒ Object
Creates accessor method for configs marked with @accessor.
-
#create_global_class ⇒ Object
Creates class with name “global” and inserts all the remaining orphans into it (but only if there are any orphans).
-
#ext4? ⇒ Boolean
Are we dealing with ExtJS 4? True if any of the classes is defined with Ext.define().
-
#initialize ⇒ Aggregator
constructor
A new instance of Aggregator.
-
#insert_orphans(cls) ⇒ Object
Inserts available orphans to class.
-
#merge_classes(old, new) ⇒ Object
Merges new class-doc into old one.
-
#register(node) ⇒ Object
Registers documentation node either as class or as member of some class.
-
#remove_ignored_classes ⇒ Object
Gets rid of classes marked with @ignore.
- #result ⇒ Object
- #warn_alt_name(cls) ⇒ Object
Constructor Details
#initialize ⇒ Aggregator
Returns a new instance of Aggregator.
10 11 12 13 14 15 16 |
# File 'lib/jsduck/aggregator.rb', line 10 def initialize @documentation = [] @classes = {} @alt_names = {} @orphans = [] @current_class = nil end |
Instance Method Details
#add_class(cls) ⇒ Object
When class exists, merge it with class node. Otherwise add as new class.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/jsduck/aggregator.rb', line 41 def add_class(cls) old_cls = @classes[cls[:name]] if !old_cls && @alt_names[cls[:name]] old_cls = @alt_names[cls[:name]] warn_alt_name(cls) end if old_cls merge_classes(old_cls, cls) @current_class = old_cls else @current_class = cls @documentation << cls @classes[cls[:name]] = cls # Register all alternate names of class for lookup too cls[:alternateClassNames].each do |altname| if cls[:name] == altname # A buggy documentation, warn. warn_alt_name(cls) else @alt_names[altname] = cls # When an alternate name has been used as a class name before, # then this is one crappy documentation, but attempt to handle # it by merging the class with alt-name into this class. if @classes[altname] merge_classes(cls, @classes[altname]) @documentation.delete(@classes[altname]) @classes.delete(altname) warn_alt_name(cls) end end end insert_orphans(cls) end end |
#add_empty_class(name, doc = "") ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/jsduck/aggregator.rb', line 182 def add_empty_class(name, doc = "") add_class({ :tagname => :class, :name => name, :doc => doc, :mixins => [], :alternateClassNames => [], :members => Class.default_members_hash, :statics => Class.default_members_hash, :aliases => {}, :meta => {}, :files => [{:filename => "", :linenr => 0, :href => ""}], }) end |
#add_member(node) ⇒ Object
Tries to place members into classes where they belong.
item with @member=Foo before we actually meet class Foo - in that case we register them as orphans. (Later when we finally meet class Foo, orphans are inserted into it.)
Items without @member belong by default to the preceding class. When no class precedes them - they too are orphaned.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/jsduck/aggregator.rb', line 120 def add_member(node) # Completely ignore member if @ignore used return if node[:meta][:ignore] if node[:owner] if @classes[node[:owner]] add_to_class(@classes[node[:owner]], node) else add_orphan(node) end elsif @current_class node[:owner] = @current_class[:name] add_to_class(@current_class, node) else add_orphan(node) end end |
#add_orphan(node) ⇒ Object
142 143 144 |
# File 'lib/jsduck/aggregator.rb', line 142 def add_orphan(node) @orphans << node end |
#add_to_class(cls, member) ⇒ Object
138 139 140 |
# File 'lib/jsduck/aggregator.rb', line 138 def add_to_class(cls, member) cls[member[:meta][:static] ? :statics : :members][member[:tagname]] << member end |
#aggregate(file) ⇒ Object
Combines chunk of parsed JavaScript together with previously added chunks. The resulting documentation is accumulated inside this class and can be later accessed through #result method.
-
file SoureFile class instance
24 25 26 27 |
# File 'lib/jsduck/aggregator.rb', line 24 def aggregate(file) @current_class = nil file.each {|doc| register(doc) } end |
#append_ext4_event_options ⇒ Object
Appends Ext4 options parameter to each event parameter list. But only when we are dealing with Ext4 codebase.
209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/jsduck/aggregator.rb', line 209 def return unless ext4? = { :tagname => :param, :name => "eOpts", :type => "Object", :doc => "The options object passed to {@link Ext.util.Observable#addListener}." } @classes.each_value do |cls| cls[:members][:event].each {|e| e[:params] << } end end |
#classify_orphans ⇒ Object
Creates classes for orphans that have :owner property defined, and then inserts orphans to these classes.
157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/jsduck/aggregator.rb', line 157 def classify_orphans @orphans.each do |orph| if orph[:owner] class_name = orph[:owner] if !@classes[class_name] # this will add the class and add all orphans to it add_empty_class(class_name) end end end end |
#create_accessors ⇒ Object
Creates accessor method for configs marked with @accessor
224 225 226 227 228 229 |
# File 'lib/jsduck/aggregator.rb', line 224 def create_accessors accessors = Accessors.new @classes.each_value do |cls| accessors.create(cls) end end |
#create_global_class ⇒ Object
Creates class with name “global” and inserts all the remaining orphans into it (but only if there are any orphans).
171 172 173 174 175 176 177 178 179 180 |
# File 'lib/jsduck/aggregator.rb', line 171 def create_global_class return if @orphans.length == 0 add_empty_class("global", "Global variables and functions.") @orphans.each do |orph| orph[:owner] = "global" add_member(orph) end @orphans = [] end |
#ext4? ⇒ Boolean
Are we dealing with ExtJS 4? True if any of the classes is defined with Ext.define()
233 234 235 |
# File 'lib/jsduck/aggregator.rb', line 233 def ext4? @documentation.any? {|cls| cls[:code_type] == :ext_define } end |
#insert_orphans(cls) ⇒ Object
Inserts available orphans to class
147 148 149 150 151 152 153 |
# File 'lib/jsduck/aggregator.rb', line 147 def insert_orphans(cls) members = @orphans.find_all {|node| node[:owner] == cls[:name] } members.each do |node| add_to_class(cls, node) @orphans.delete(node) end end |
#merge_classes(old, new) ⇒ Object
Merges new class-doc into old one.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/jsduck/aggregator.rb', line 86 def merge_classes(old, new) # Merge booleans [:extends, :singleton, :private].each do |tag| old[tag] = old[tag] || new[tag] end # Merge arrays [:mixins, :alternateClassNames, :files].each do |tag| old[tag] = old[tag] + new[tag] end # Merge meta hashes new[:meta].each_pair do |name, value| old[:meta][name] = old[:meta][name] || value end # Merge hashes of arrays [:aliases].each do |tag| new[tag].each_pair do |key, contents| old[tag][key] = (old[tag][key] || []) + contents end end old[:doc] = old[:doc].length > 0 ? old[:doc] : new[:doc] # Additionally the doc-comment can contain configs and constructor old[:members][:cfg] += new[:members][:cfg] old[:members][:method] += new[:members][:method] end |
#register(node) ⇒ Object
Registers documentation node either as class or as member of some class.
31 32 33 34 35 36 37 |
# File 'lib/jsduck/aggregator.rb', line 31 def register(node) if node[:tagname] == :class add_class(node) else add_member(node) end end |
#remove_ignored_classes ⇒ Object
Gets rid of classes marked with @ignore
198 199 200 201 202 203 204 205 |
# File 'lib/jsduck/aggregator.rb', line 198 def remove_ignored_classes @documentation.delete_if do |cls| if cls[:meta][:ignore] @classes.delete(cls["name"]) true end end end |
#result ⇒ Object
237 238 239 |
# File 'lib/jsduck/aggregator.rb', line 237 def result @documentation + @orphans end |
#warn_alt_name(cls) ⇒ Object
79 80 81 82 83 |
# File 'lib/jsduck/aggregator.rb', line 79 def warn_alt_name(cls) file = cls[:files][0][:filename] line = cls[:files][0][:linenr] Logger.instance.warn(:alt_name, "Name #{cls[:name]} used as both classname and alternate classname", file, line) end |