jsduck 0.3 → 0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -195,6 +195,12 @@ JsDuck was developed by [Rene Saarsoo](http://triin.net).
195
195
  Changelog
196
196
  ---------
197
197
 
198
+ * 0.4 - Ext4 support
199
+ * Support for Ext.define() syntax from ExtJS 4.
200
+ * Showing @xtype and @author information on generated pages.
201
+ * Showing filename and line number in warnings.
202
+ * Fix for event showing the same doc as method with same name.
203
+
198
204
  * 0.3 - Performance improvements
199
205
  * Significant peed improvements - most importantly utilizing
200
206
  multiple CPU-s (if available) to speed things up. On my 4-core
data/jsduck.gemspec CHANGED
@@ -2,8 +2,8 @@ Gem::Specification.new do |s|
2
2
  s.required_rubygems_version = ">= 1.3.7"
3
3
 
4
4
  s.name = 'jsduck'
5
- s.version = '0.3'
6
- s.date = '2011-02-08'
5
+ s.version = '0.4'
6
+ s.date = '2011-02-28'
7
7
  s.summary = "Simple JavaScript Duckumentation generator"
8
8
  s.description = "Better ext-doc like JavaScript documentation generator for ExtJS"
9
9
  s.homepage = "https://github.com/nene/jsduck"
@@ -24,21 +24,28 @@ module JsDuck
24
24
  def aggregate(input, filename="", html_filename="")
25
25
  @current_class = nil
26
26
  input.each do |docset|
27
- doc = docset[:comment]
28
- code = docset[:code]
29
- href = html_filename + "#line-" + docset[:linenr].to_s
30
- register(add_href(@merger.merge(doc, code), href, filename))
27
+ doc = @merger.merge(docset[:comment], docset[:code])
28
+
29
+ add_source_data(doc, {
30
+ :filename => filename,
31
+ :html_filename => html_filename,
32
+ :linenr => docset[:linenr],
33
+ })
34
+
35
+ register(doc)
31
36
  end
32
37
  end
33
38
 
34
- # Tags doc-object with link to source code where it came from.
35
- # For class we also store the name of the JavaScript file.
36
- def add_href(doc, href, filename)
37
- doc[:href] = href
39
+ # Links doc-object to source code where it came from.
40
+ def add_source_data(doc, src)
41
+ doc[:href] = src[:html_filename] + "#line-" + src[:linenr].to_s
42
+ doc[:filename] = src[:filename]
43
+ doc[:linenr] = src[:linenr]
44
+ # class-level doc-comment can contain constructor and config
45
+ # options, link those to the same location in source.
38
46
  if doc[:tagname] == :class
39
- doc[:filename] = filename
40
- doc[:cfg].each {|cfg| cfg[:href] = href }
41
- doc[:method].each {|method| method[:href] = href }
47
+ doc[:cfg].each {|cfg| add_source_data(cfg, src) }
48
+ doc[:method].each {|method| add_source_data(method, src) }
42
49
  end
43
50
  doc
44
51
  end
data/lib/jsduck/app.rb CHANGED
@@ -50,8 +50,8 @@ module JsDuck
50
50
  puts "Parsing #{fname} ..." if @verbose
51
51
  code = IO.read(fname)
52
52
  {
53
- :name => fname,
54
- :src_name => src.write(code, fname),
53
+ :filename => fname,
54
+ :html_filename => File.basename(src.write(code, fname)),
55
55
  :data => Parser.new(code).parse,
56
56
  }
57
57
  end
@@ -61,8 +61,8 @@ module JsDuck
61
61
  def aggregate(parsed_files)
62
62
  agr = Aggregator.new
63
63
  parsed_files.each do |file|
64
- puts "Aggregating #{file[:name]} ..." if @verbose
65
- agr.aggregate(file[:data], File.basename(file[:name]), File.basename(file[:src_name]))
64
+ puts "Aggregating #{file[:filename]} ..." if @verbose
65
+ agr.aggregate(file[:data], file[:filename], file[:html_filename])
66
66
  end
67
67
  agr.result
68
68
  end
@@ -75,7 +75,11 @@ module JsDuck
75
75
  if d[:tagname] == :class
76
76
  classes[d[:name]] = Class.new(d, classes)
77
77
  else
78
- puts "Warning: Ignoring " + d[:tagname].to_s + ": " + (d[:name] || "")
78
+ type = d[:tagname].to_s
79
+ name = d[:name]
80
+ file = d[:filename]
81
+ line = d[:linenr]
82
+ puts "Warning: Ignoring #{type}: #{name} in #{file} line #{line}"
79
83
  end
80
84
  end
81
85
  classes.values
data/lib/jsduck/class.rb CHANGED
@@ -18,6 +18,12 @@ module JsDuck
18
18
  @doc[:extends] ? @classes[@doc[:extends]] : nil
19
19
  end
20
20
 
21
+ # Returns array of mixin class instances.
22
+ # Returns empty array if no mixins
23
+ def mixins
24
+ @doc[:mixins] ? @doc[:mixins].collect {|classname| @classes[classname] } : []
25
+ end
26
+
21
27
  # Returns true when this class inherits from the specified class.
22
28
  # Also returns true when the class itself is the one we are asking about.
23
29
  def inherits_from?(class_name)
@@ -51,9 +57,9 @@ module JsDuck
51
57
  ms
52
58
  end
53
59
 
54
- # Returns hash of public members of class (and parent classes).
55
- # Members are methods, properties, cfgs, events (member type
56
- # is speified through 'type' parameter).
60
+ # Returns hash of public members of class (and of parent classes
61
+ # and mixin classes). Members are methods, properties, cfgs,
62
+ # events (member type is specified through 'type' parameter).
57
63
  #
58
64
  # When parent and child have members with same name,
59
65
  # member from child overrides tha parent member.
@@ -61,11 +67,17 @@ module JsDuck
61
67
  # We also set :member property to each member to the full class
62
68
  # name where it belongs, so one can tell them apart afterwards.
63
69
  def members_hash(type)
64
- parent_members = parent ? parent.members_hash(type) : {}
70
+ all_members = parent ? parent.members_hash(type) : {}
71
+
72
+ mixins.each do |mix|
73
+ all_members.merge!(mix.members_hash(type))
74
+ end
75
+
65
76
  @doc[type].each do |m|
66
- parent_members[m[:name]] = m if !m[:private]
77
+ all_members[m[:name]] = m if !m[:private]
67
78
  end
68
- parent_members
79
+
80
+ all_members
69
81
  end
70
82
 
71
83
  # A way to access full class name with similar syntax to
@@ -90,10 +90,15 @@ module JsDuck
90
90
  at_xtype
91
91
  elsif look(/@member\b/)
92
92
  at_member
93
+ elsif look(/@author\b/)
94
+ at_author
93
95
  elsif look(/@static\b/)
94
96
  boolean_at_tag(/@static/, :static)
95
97
  elsif look(/@(private|ignore|hide|protected)\b/)
96
98
  boolean_at_tag(/@(private|ignore|hide|protected)/, :private)
99
+ elsif look(/@markdown\b/)
100
+ # this is detected just to be ignored
101
+ boolean_at_tag(/@markdown/, :markdown)
97
102
  elsif look(/@/)
98
103
  @current_tag[:doc] += @input.scan(/@/)
99
104
  elsif look(/[^@]/)
@@ -207,6 +212,15 @@ module JsDuck
207
212
  skip_white
208
213
  end
209
214
 
215
+ # matches @author some name ... newline
216
+ def at_author
217
+ match(/@author/)
218
+ add_tag(:author)
219
+ skip_horiz_white
220
+ @current_tag[:name] = @input.scan(/.*$/)
221
+ skip_white
222
+ end
223
+
210
224
  # Used to match @private, @ignore, @hide, ...
211
225
  def boolean_at_tag(regex, propname)
212
226
  match(regex)
@@ -11,7 +11,7 @@ module JsDuck
11
11
  @id = @cls.full_name + "-events"
12
12
  @title = "Public Events"
13
13
  @column_title = "Event"
14
- @row_class = "method-row"
14
+ @row_class = "event-row"
15
15
  @short_params = ShortParams.new
16
16
  @long_params = LongParams.new(@cls)
17
17
  end
data/lib/jsduck/merger.rb CHANGED
@@ -33,7 +33,7 @@ module JsDuck
33
33
  :method
34
34
  elsif doc_map[:property] || doc_map[:type]
35
35
  :property
36
- elsif code[:type] == :ext_extend
36
+ elsif code[:type] == :ext_define
37
37
  :class
38
38
  elsif code[:type] == :assignment && class_name?(*code[:left])
39
39
  :class
@@ -109,7 +109,9 @@ module JsDuck
109
109
  :name => detect_name(:class, doc_map, code, :full_name),
110
110
  :doc => detect_doc(docs),
111
111
  :extends => detect_extends(doc_map, code),
112
+ :mixins => detect_mixins(doc_map, code),
112
113
  :xtype => detect_xtype(doc_map),
114
+ :author => detect_author(doc_map),
113
115
  :singleton => !!doc_map[:singleton],
114
116
  :private => !!doc_map[:private],
115
117
  }
@@ -176,6 +178,8 @@ module JsDuck
176
178
  code[:name]
177
179
  elsif code[:type] == :assignment
178
180
  name_type == :full_name ? code[:left].join(".") : code[:left].last
181
+ elsif code[:type] == :ext_define
182
+ name_type == :full_name ? code[:name] : code[:name].split(/\./).last
179
183
  else
180
184
  ""
181
185
  end
@@ -215,6 +219,16 @@ module JsDuck
215
219
  doc_map[:extends].first[:extends]
216
220
  elsif code[:type] == :assignment && code[:right] && code[:right][:type] == :ext_extend
217
221
  code[:right][:extend].join(".")
222
+ elsif code[:type] == :ext_define
223
+ code[:extend]
224
+ end
225
+ end
226
+
227
+ def detect_mixins(doc_map, code)
228
+ if code[:type] == :ext_define && code[:mixins]
229
+ code[:mixins]
230
+ else
231
+ []
218
232
  end
219
233
  end
220
234
 
@@ -222,6 +236,10 @@ module JsDuck
222
236
  doc_map[:xtype] ? doc_map[:xtype].first[:name] : nil
223
237
  end
224
238
 
239
+ def detect_author(doc_map)
240
+ doc_map[:author] ? doc_map[:author].first[:name] : nil
241
+ end
242
+
225
243
  def detect_params(docs, code)
226
244
  implicit = detect_implicit_params(code)
227
245
  explicit = detect_explicit_params(docs)
data/lib/jsduck/page.rb CHANGED
@@ -51,8 +51,11 @@ module JsDuck
51
51
  [
52
52
  "<table cellspacing='0'>",
53
53
  abstract_row("Extends:", @cls.parent ? class_link(@cls.parent.full_name) : "Object"),
54
+ @cls.mixins.length > 0 ? abstract_row("Mixins:", mixins) : "",
54
55
  abstract_row("Defind In:", file_link),
55
56
  @subclasses[@cls] ? abstract_row("Subclasses:", subclasses) : "",
57
+ @cls[:xtype] ? abstract_row("xtype:", @cls[:xtype]) : "",
58
+ @cls[:author] ? abstract_row("Author:", @cls[:author]) : "",
56
59
  "</table>",
57
60
  ].join("\n")
58
61
  end
@@ -63,7 +66,7 @@ module JsDuck
63
66
  end
64
67
 
65
68
  def file_link
66
- "<a href='source/#{@cls[:href]}'>#{@cls[:filename]}</a>"
69
+ "<a href='source/#{@cls[:href]}'>#{File.basename(@cls[:filename])}</a>"
67
70
  end
68
71
 
69
72
  def subclasses
@@ -71,6 +74,11 @@ module JsDuck
71
74
  subs.collect {|cls| class_link(cls.full_name, cls.short_name) }.join(", ")
72
75
  end
73
76
 
77
+ def mixins
78
+ mixs = @cls.mixins.sort {|a, b| a.full_name <=> b.full_name }
79
+ mixs.collect {|cls| class_link(cls.full_name, cls.short_name) }.join(", ")
80
+ end
81
+
74
82
  def abstract_row(label, info)
75
83
  "<tr><td class='label'>#{label}</td><td class='hd-info'>#{info}</td></tr>"
76
84
  end
data/lib/jsduck/parser.rb CHANGED
@@ -67,12 +67,15 @@ module JsDuck
67
67
  # The following is a recursive-descent parser for JavaScript that
68
68
  # can possibly follow a doc-comment
69
69
 
70
- # <code-block> := <function> | <var-declaration> | <assignment> | <property-literal>
70
+ # <code-block> := <function> | <var-declaration> | <ext-define> |
71
+ # <assignment> | <property-literal>
71
72
  def code_block
72
73
  if look("function")
73
74
  function
74
75
  elsif look("var")
75
76
  var_declaration
77
+ elsif look("Ext", ".", "define", "(", :string)
78
+ ext_define
76
79
  elsif look(:ident, ":") || look(:string, ":")
77
80
  property_literal
78
81
  elsif look(",", :ident, ":") || look(",", :string, ":")
@@ -175,6 +178,87 @@ module JsDuck
175
178
  }
176
179
  end
177
180
 
181
+ # <ext-define> := "Ext" "." "define" "(" <string> "," <ext-define-cfg>
182
+ def ext_define
183
+ name = match("Ext", ".", "define", "(", :string)
184
+
185
+ if look(",", "{")
186
+ match(",")
187
+ cfg = ext_define_cfg
188
+ else
189
+ cfg = {}
190
+ end
191
+
192
+ cfg[:type] = :ext_define
193
+ cfg[:name] = name
194
+
195
+ cfg
196
+ end
197
+
198
+ # <ext-define-cfg> := "{" ( <extend> | <mixins> | <?> )*
199
+ def ext_define_cfg
200
+ match("{")
201
+ cfg = {}
202
+ found = true
203
+ while found
204
+ found = false
205
+ if look("extend", ":", :string)
206
+ cfg[:extend] = ext_define_extend
207
+ found = true
208
+ elsif look("mixins", ":", "{")
209
+ cfg[:mixins] = ext_define_mixins
210
+ found = true
211
+ elsif look(:ident, ":")
212
+ match(:ident, ":")
213
+ if look(:string) || look(:number) || look(:regex) ||
214
+ look("true") || look("false") ||
215
+ look("null") || look("undefined")
216
+ # Some key with literal value -- ignore
217
+ @lex.next
218
+ found = true
219
+ elsif look("[")
220
+ # Some key with array of strings -- ignore
221
+ found = array_of_strings
222
+ end
223
+ end
224
+ match(",") if look(",")
225
+ end
226
+ cfg
227
+ end
228
+
229
+ # <ext-define-extend> := "extend" ":" <string>
230
+ def ext_define_extend
231
+ match("extend", ":", :string)
232
+ end
233
+
234
+ # <ext-define-mixins> := "mixins" ":" "{" [ <ident> ":" <string> ","? ]* "}"
235
+ def ext_define_mixins
236
+ match("mixins", ":", "{")
237
+ mixins = []
238
+ while look(:ident, ":", :string)
239
+ mixins << match(:ident, ":", :string)
240
+ match(",") if look(",")
241
+ end
242
+ match("}") if look("}")
243
+ mixins
244
+ end
245
+
246
+ # <array-of-strings> := "[" [ <string> ","? ]* "]"
247
+ def array_of_strings
248
+ match("[")
249
+ while look(:string)
250
+ match(:string)
251
+ match(",") if look(",")
252
+ end
253
+
254
+ if look("]")
255
+ match("]")
256
+ true
257
+ else
258
+ false
259
+ end
260
+ end
261
+
178
262
  # <property-literal> := ( <ident> | <string> ) ":" <expression>
179
263
  def property_literal
180
264
  left = look(:ident) ? match(:ident) : match(:string)
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsduck
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
- version: "0.3"
8
+ - 4
9
+ version: "0.4"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Rene Saarsoo
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-08 00:00:00 +02:00
17
+ date: 2011-02-28 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency