jsduck 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
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