jsduck 5.0.0.beta01 → 5.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/.travis.yml +1 -0
  2. data/README.md +6 -32
  3. data/Rakefile +5 -5
  4. data/bin/jsduck +0 -1
  5. data/js-classes/String.js +3 -5
  6. data/jsduck.gemspec +3 -2
  7. data/lib/jsduck/aggregator.rb +1 -3
  8. data/lib/jsduck/app.rb +2 -2
  9. data/lib/jsduck/categories/file.rb +0 -6
  10. data/lib/jsduck/class.rb +1 -2
  11. data/lib/jsduck/doc/parser.rb +12 -5
  12. data/lib/jsduck/doc/scanner.rb +6 -0
  13. data/lib/jsduck/doc/standard_tag_parser.rb +10 -5
  14. data/lib/jsduck/doc/subproperties.rb +9 -2
  15. data/lib/jsduck/docs_code_comparer.rb +20 -7
  16. data/lib/jsduck/exporter/app.rb +18 -13
  17. data/lib/jsduck/exporter/full.rb +18 -21
  18. data/lib/jsduck/format/doc.rb +0 -1
  19. data/lib/jsduck/format/html_stack.rb +1 -2
  20. data/lib/jsduck/format/subproperties.rb +2 -2
  21. data/lib/jsduck/inline/auto_link.rb +1 -1
  22. data/lib/jsduck/inline/img.rb +1 -1
  23. data/lib/jsduck/inline/link.rb +4 -6
  24. data/lib/jsduck/inline/video.rb +1 -2
  25. data/lib/jsduck/js/ast.rb +1 -1
  26. data/lib/jsduck/js/esprima.rb +24 -9
  27. data/lib/jsduck/logger.rb +50 -12
  28. data/lib/jsduck/members_index.rb +1 -2
  29. data/lib/jsduck/merger.rb +20 -2
  30. data/lib/jsduck/options.rb +125 -24
  31. data/lib/jsduck/process/accessors.rb +21 -8
  32. data/lib/jsduck/process/enums.rb +2 -3
  33. data/lib/jsduck/process/ext4_events.rb +2 -1
  34. data/lib/jsduck/process/global_members.rb +1 -2
  35. data/lib/jsduck/process/importer.rb +2 -6
  36. data/lib/jsduck/process/inherit_class.rb +58 -0
  37. data/lib/jsduck/process/inherit_doc.rb +6 -175
  38. data/lib/jsduck/process/inherit_members.rb +257 -0
  39. data/lib/jsduck/process/lint.rb +18 -7
  40. data/lib/jsduck/process/overrides.rb +1 -2
  41. data/lib/jsduck/render/class.rb +1 -1
  42. data/lib/jsduck/tag/alias.rb +2 -1
  43. data/lib/jsduck/tag/alternate_class_names.rb +1 -0
  44. data/lib/jsduck/tag/aside.rb +3 -3
  45. data/lib/jsduck/tag/author.rb +18 -3
  46. data/lib/jsduck/tag/autodetected.rb +21 -0
  47. data/lib/jsduck/tag/boolean_tag.rb +1 -1
  48. data/lib/jsduck/tag/cfg.rb +7 -3
  49. data/lib/jsduck/tag/class.rb +1 -1
  50. data/lib/jsduck/tag/class_list_tag.rb +1 -1
  51. data/lib/jsduck/tag/constructor.rb +1 -1
  52. data/lib/jsduck/tag/css_var.rb +1 -1
  53. data/lib/jsduck/tag/default.rb +1 -1
  54. data/lib/jsduck/tag/deprecated_tag.rb +1 -1
  55. data/lib/jsduck/tag/docauthor.rb +2 -0
  56. data/lib/jsduck/tag/enum.rb +2 -2
  57. data/lib/jsduck/tag/event.rb +1 -1
  58. data/lib/jsduck/tag/extends.rb +1 -1
  59. data/lib/jsduck/tag/ftype.rb +2 -1
  60. data/lib/jsduck/tag/inheritdoc.rb +1 -1
  61. data/lib/jsduck/tag/localdoc.rb +33 -0
  62. data/lib/jsduck/tag/markdown.rb +1 -1
  63. data/lib/jsduck/tag/member.rb +1 -1
  64. data/lib/jsduck/tag/method.rb +1 -1
  65. data/lib/jsduck/tag/mixins.rb +1 -0
  66. data/lib/jsduck/tag/override.rb +1 -1
  67. data/lib/jsduck/tag/param.rb +16 -5
  68. data/lib/jsduck/tag/preventable.rb +1 -1
  69. data/lib/jsduck/tag/property.rb +7 -3
  70. data/lib/jsduck/tag/ptype.rb +2 -1
  71. data/lib/jsduck/tag/requires.rb +1 -0
  72. data/lib/jsduck/tag/return.rb +2 -1
  73. data/lib/jsduck/tag/since.rb +1 -5
  74. data/lib/jsduck/tag/tag.rb +21 -12
  75. data/lib/jsduck/tag/throws.rb +2 -1
  76. data/lib/jsduck/tag/type.rb +2 -2
  77. data/lib/jsduck/tag/uses.rb +1 -0
  78. data/lib/jsduck/tag/xtype.rb +2 -1
  79. data/lib/jsduck/tag_loader.rb +26 -15
  80. data/lib/jsduck/tag_registry.rb +20 -11
  81. data/lib/jsduck/web/css.rb +22 -0
  82. data/lib/jsduck/web/data.rb +50 -0
  83. data/lib/jsduck/web/icons.rb +31 -0
  84. data/lib/jsduck/web/index_html.rb +88 -0
  85. data/lib/jsduck/web/search.rb +148 -0
  86. data/lib/jsduck/{source/writer.rb → web/source.rb} +2 -2
  87. data/lib/jsduck/web/template.rb +52 -0
  88. data/lib/jsduck/web/writer.rb +84 -0
  89. metadata +513 -488
  90. data/lib/jsduck/app_data.rb +0 -41
  91. data/lib/jsduck/icons.rb +0 -29
  92. data/lib/jsduck/index_html.rb +0 -84
  93. data/lib/jsduck/search_data.rb +0 -146
  94. data/lib/jsduck/template_dir.rb +0 -50
  95. data/lib/jsduck/web_writer.rb +0 -87
@@ -40,14 +40,26 @@ module JsDuck
40
40
  # print warning for each class or public member with no name
41
41
  def warn_no_doc
42
42
  @relations.each do |cls|
43
- if cls[:doc] == ""
43
+
44
+ if cls[:doc] == "" && !cls[:private]
44
45
  warn(:no_doc, "No documentation for #{cls[:name]}", cls)
45
46
  end
46
- end
47
- each_member do |member|
48
- if member[:doc] == "" && !member[:private] && !member[:hide] && !JsDuck::Class.constructor?(member)
49
- warn(:no_doc, "No documentation for #{member[:owner]}##{member[:name]}", member)
47
+
48
+ cls.all_local_members.each do |member|
49
+ if !member[:private] && !member[:hide] && !JsDuck::Class.constructor?(member)
50
+ if member[:doc] == ""
51
+ warn(:no_doc, "No documentation for #{member[:owner]}##{member[:name]}", member)
52
+ end
53
+
54
+ (member[:params] || []).each do |p|
55
+ if p[:doc] == ""
56
+ warn(:no_doc, "No documentation for parameter #{p[:name]} of #{member[:owner]}##{member[:name]}", member)
57
+ end
58
+ end
59
+
60
+ end
50
61
  end
62
+
51
63
  end
52
64
  end
53
65
 
@@ -125,8 +137,7 @@ module JsDuck
125
137
 
126
138
  # Prints warning + filename and linenumber from doc-context
127
139
  def warn(type, msg, member)
128
- context = member[:files][0]
129
- Logger.warn(type, msg, context[:filename], context[:linenr])
140
+ Logger.warn(type, msg, member[:files][0])
130
141
  end
131
142
 
132
143
  end
@@ -37,8 +37,7 @@ module JsDuck
37
37
  def process(override)
38
38
  target = @classes_hash[override[:override]]
39
39
  unless target
40
- ctx = override[:files][0]
41
- return Logger.warn(:extend, "Class #{override[:override]} not found", ctx[:filename], ctx[:linenr])
40
+ return Logger.warn(:extend, "Class #{override[:override]} not found", override[:files][0])
42
41
  end
43
42
 
44
43
  # Combine comments of classes
@@ -45,7 +45,7 @@ module JsDuck
45
45
  end
46
46
 
47
47
  def render_section(sec)
48
- members = @cls[:members][sec[:name]] + @cls[:statics][sec[:name]]
48
+ members = @cls[:members].find_all {|m| m[:tagname] == sec[:name] }
49
49
 
50
50
  # Skip rendering empty sections
51
51
  return [] if members.length == 0
@@ -6,6 +6,7 @@ module JsDuck::Tag
6
6
  def initialize
7
7
  @pattern = "alias"
8
8
  @tagname = :aliases
9
+ @repeatable = true
9
10
  @ext_define_pattern = "alias"
10
11
  @ext_define_default = {:aliases => []}
11
12
  @merge_context = :class
@@ -14,7 +15,7 @@ module JsDuck::Tag
14
15
  # For backwards compatibility decide whether the @alias was used
15
16
  # as @inheritdoc (@alias used to have the meaning of @inheritdoc
16
17
  # before) or as a real Ext4 style alias definition.
17
- def parse_doc(p)
18
+ def parse_doc(p, pos)
18
19
  if p.look(/([\w.]+)?#\w+/)
19
20
  parse_as_inheritdoc(p)
20
21
  else
@@ -5,6 +5,7 @@ module JsDuck::Tag
5
5
  def initialize
6
6
  @pattern = ["alternateClassName", "alternateClassNames"]
7
7
  @tagname = :alternateClassNames
8
+ @repeatable = true
8
9
  @ext_define_pattern = "alternateClassName"
9
10
  @ext_define_default = {:alternateClassNames => []}
10
11
  @merge_context = :class
@@ -6,11 +6,12 @@ module JsDuck::Tag
6
6
  def initialize
7
7
  @pattern = "aside"
8
8
  @tagname = :aside
9
+ @repeatable = true
9
10
  @html_position = POS_ASIDE
10
11
  end
11
12
 
12
13
  # Parses: @aside [ guide | video| example ] name
13
- def parse_doc(p)
14
+ def parse_doc(p, pos)
14
15
  {
15
16
  :tagname => :aside,
16
17
  :type => aside_type(p),
@@ -62,8 +63,7 @@ module JsDuck::Tag
62
63
  end
63
64
 
64
65
  def warn(msg, context)
65
- file = context[:files][0]
66
- JsDuck::Logger.warn(:aside, msg, file[:filename], file[:linenr])
66
+ JsDuck::Logger.warn(:aside, msg, context[:files][0])
67
67
  nil
68
68
  end
69
69
 
@@ -1,15 +1,30 @@
1
1
  require "jsduck/tag/tag"
2
2
 
3
3
  module JsDuck::Tag
4
+ # Author tag gets processed, but no output gets created. Users of
5
+ # JSDuck may override this tag to make it print the names of
6
+ # authors.
4
7
  class Author < Tag
5
8
  def initialize
6
9
  @pattern = "author"
10
+ @tagname = :author
11
+ @repeatable = true
7
12
  end
8
13
 
9
14
  # @author Name of Author <email@example.com> ...
10
- # Everything until the end of line gets just ignored.
11
- def parse_doc(p)
12
- p.match(/.*$/)
15
+ def parse_doc(p, pos)
16
+ name = p.match(/[^<\n]*/).strip
17
+ if p.look(/</)
18
+ p.match(/</)
19
+ email = p.match(/[^>\n]*/)
20
+ p.match(/>/)
21
+ end
22
+
23
+ return {:tagname => @tagname, :name => name, :email => email}
24
+ end
25
+
26
+ def process_doc(context, tags, pos)
27
+ context[@tagname] = tags
13
28
  end
14
29
  end
15
30
  end
@@ -0,0 +1,21 @@
1
+ require "jsduck/tag/tag"
2
+ require "jsduck/docs_code_comparer"
3
+
4
+ module JsDuck::Tag
5
+ # There is no @autodetected tag.
6
+ #
7
+ # This tag class exists to take care of the merging of :autodetected
8
+ # field.
9
+ class Autodetected < Tag
10
+ def initialize
11
+ @tagname = :autodetected
12
+ @merge_context = [:class, :member]
13
+ end
14
+
15
+ def merge(h, docs, code)
16
+ if docs[:autodetected] || code[:autodetected]
17
+ h[:autodetected] = (code[:autodetected] || {}).merge(docs[:autodetected] || {})
18
+ end
19
+ end
20
+ end
21
+ end
@@ -12,7 +12,7 @@ module JsDuck::Tag
12
12
  end
13
13
 
14
14
  # Parses just the name of the tag.
15
- def parse_doc(p)
15
+ def parse_doc(p, pos)
16
16
  {:tagname => @tagname}
17
17
  end
18
18
 
@@ -6,6 +6,7 @@ module JsDuck::Tag
6
6
  def initialize
7
7
  @pattern = "cfg"
8
8
  @tagname = :cfg
9
+ @repeatable = true
9
10
  @member_type = {
10
11
  :name => :cfg,
11
12
  :category => :property_like,
@@ -20,7 +21,7 @@ module JsDuck::Tag
20
21
  end
21
22
 
22
23
  # @cfg {Type} [name=default] (required) ...
23
- def parse_doc(p)
24
+ def parse_doc(p, pos)
24
25
  tag = p.standard_tag({:tagname => :cfg, :type => true, :name => true})
25
26
  tag[:optional] = false if parse_required(p)
26
27
  tag[:doc] = :multiline
@@ -33,13 +34,16 @@ module JsDuck::Tag
33
34
 
34
35
  def process_doc(h, tags, pos)
35
36
  p = tags[0]
36
- h[:name] = p[:name]
37
37
  h[:type] = p[:type]
38
38
  h[:default] = p[:default]
39
- h[:properties] = JsDuck::Doc::Subproperties.nest(tags, pos)[0][:properties]
40
39
  h[:required] = true if p[:optional] == false
40
+
41
41
  # Documentation after the first @cfg is part of the top-level docs.
42
42
  h[:doc] += p[:doc]
43
+
44
+ nested = JsDuck::Doc::Subproperties.nest(tags, pos)[0]
45
+ h[:properties] = nested[:properties]
46
+ h[:name] = nested[:name]
43
47
  end
44
48
  end
45
49
  end
@@ -9,7 +9,7 @@ module JsDuck::Tag
9
9
  end
10
10
 
11
11
  # @class name
12
- def parse_doc(p)
12
+ def parse_doc(p, pos)
13
13
  {
14
14
  :tagname => :class,
15
15
  :name => p.ident_chain,
@@ -13,7 +13,7 @@ module JsDuck::Tag
13
13
  # #parse_ext_define to work.
14
14
  #
15
15
  class ClassListTag < Tag
16
- def parse_doc(p)
16
+ def parse_doc(p, pos)
17
17
  {
18
18
  :tagname => @tagname,
19
19
  :classes => classname_list(p),
@@ -8,7 +8,7 @@ module JsDuck::Tag
8
8
  end
9
9
 
10
10
  # @constructor
11
- def parse_doc(p)
11
+ def parse_doc(p, pos)
12
12
  {:tagname => :constructor, :doc => :multiline}
13
13
  end
14
14
 
@@ -15,7 +15,7 @@ module JsDuck::Tag
15
15
  end
16
16
 
17
17
  # @var {Type} [name=default] ...
18
- def parse_doc(p)
18
+ def parse_doc(p, pos)
19
19
  p.standard_tag({:tagname => :css_var, :type => true, :name => true})
20
20
  end
21
21
 
@@ -19,7 +19,7 @@ module JsDuck::Tag
19
19
  end
20
20
 
21
21
  def merge(h, docs, code)
22
- h[:default] = JsDuck::DocsCodeComparer.merge_if_matches(:default, docs, code)
22
+ JsDuck::DocsCodeComparer.merge_if_matches(h, :default, docs, code)
23
23
  end
24
24
 
25
25
  def to_html(m)
@@ -25,7 +25,7 @@ module JsDuck::Tag
25
25
  end
26
26
  end
27
27
 
28
- def parse_doc(p)
28
+ def parse_doc(p, pos)
29
29
  {
30
30
  :tagname => @tagname,
31
31
  :version => p.match(/[0-9.]+/),
@@ -4,7 +4,9 @@ module JsDuck::Tag
4
4
  # Exactly the same as @author tag - it's simply ignored.
5
5
  class Docauthor < Author
6
6
  def initialize
7
+ super
7
8
  @pattern = "docauthor"
9
+ @tagname = :docauthor
8
10
  end
9
11
  end
10
12
  end
@@ -18,7 +18,7 @@ module JsDuck::Tag
18
18
  end
19
19
 
20
20
  # @enum {Type} [name=default] ...
21
- def parse_doc(p)
21
+ def parse_doc(p, pos)
22
22
  enum = p.standard_tag({:tagname => :enum, :type => true, :name => true})
23
23
 
24
24
  # @enum is a special case of class, so we also generate a class
@@ -46,7 +46,7 @@ module JsDuck::Tag
46
46
 
47
47
  def to_html(cls)
48
48
  if cls[:enum][:doc_only]
49
- first = cls[:members][:property][0] || {:name => 'foo', :default => '"foo"'}
49
+ first = cls[:members][0] || {:name => 'foo', :default => '"foo"'}
50
50
  [
51
51
  "<div class='rounded-box enum-box'>",
52
52
  "<p><strong>ENUM:</strong> ",
@@ -14,7 +14,7 @@ module JsDuck::Tag
14
14
  end
15
15
 
16
16
  # @event name ...
17
- def parse_doc(p)
17
+ def parse_doc(p, pos)
18
18
  {
19
19
  :tagname => :event,
20
20
  :name => p.ident,
@@ -14,7 +14,7 @@ module JsDuck::Tag
14
14
  # @extends classname
15
15
  # or
16
16
  # @extends {classname}
17
- def parse_doc(p)
17
+ def parse_doc(p, pos)
18
18
  if p.match(/\{/)
19
19
  cls = p.ident_chain
20
20
  p.match(/\}/)
@@ -4,10 +4,11 @@ module JsDuck::Tag
4
4
  class Ftype < Xtype
5
5
  def initialize
6
6
  @pattern = "ftype"
7
+ @repeatable = true
7
8
  end
8
9
 
9
10
  # @ftype name
10
- def parse_doc(p)
11
+ def parse_doc(p, pos)
11
12
  {
12
13
  :tagname => :aliases,
13
14
  :name => parse_alias_shorthand(p, "feature")
@@ -9,7 +9,7 @@ module JsDuck::Tag
9
9
  end
10
10
 
11
11
  # @inheritdoc class.name#static-type-member
12
- def parse_doc(p)
12
+ def parse_doc(p, pos)
13
13
  parse_as_inheritdoc(p)
14
14
  end
15
15
 
@@ -0,0 +1,33 @@
1
+ require "jsduck/tag/tag"
2
+ require 'jsduck/format/shortener'
3
+
4
+ module JsDuck::Tag
5
+ # Non-inheritable documentation
6
+ class Localdoc < Tag
7
+ def initialize
8
+ @pattern = "localdoc"
9
+ @tagname = :localdoc
10
+ @html_position = POS_LOCALDOC
11
+ end
12
+
13
+ def parse_doc(p, pos)
14
+ {
15
+ :tagname => :localdoc,
16
+ :doc => :multiline,
17
+ }
18
+ end
19
+
20
+ def process_doc(m, tags, pos)
21
+ m[:localdoc] = tags.map {|t| t[:doc] }.join("\n\n")
22
+ end
23
+
24
+ def format(m, formatter)
25
+ m[:localdoc] = formatter.format(m[:localdoc])
26
+ end
27
+
28
+ def to_html(m)
29
+ m[:localdoc]
30
+ end
31
+
32
+ end
33
+ end
@@ -7,7 +7,7 @@ module JsDuck::Tag
7
7
  end
8
8
 
9
9
  # @markdown
10
- def parse_doc(p)
10
+ def parse_doc(p, pos)
11
11
  # Just completely ignore this tag.
12
12
  end
13
13
  end
@@ -10,7 +10,7 @@ module JsDuck::Tag
10
10
  end
11
11
 
12
12
  # @member classname
13
- def parse_doc(p)
13
+ def parse_doc(p, pos)
14
14
  {
15
15
  :tagname => :owner,
16
16
  :owner => p.ident_chain,
@@ -19,7 +19,7 @@ module JsDuck::Tag
19
19
  end
20
20
 
21
21
  # @method name ...
22
- def parse_doc(p)
22
+ def parse_doc(p, pos)
23
23
  {
24
24
  :tagname => :method,
25
25
  :name => p.ident,
@@ -5,6 +5,7 @@ module JsDuck::Tag
5
5
  def initialize
6
6
  @pattern = ["mixin", "mixins"]
7
7
  @tagname = :mixins
8
+ @repeatable = true
8
9
  @ext_define_pattern = "mixins"
9
10
  @ext_define_default = {:mixins => []}
10
11
  end
@@ -10,7 +10,7 @@ module JsDuck::Tag
10
10
  end
11
11
 
12
12
  # @override nameOfOverride
13
- def parse_doc(p)
13
+ def parse_doc(p, pos)
14
14
  if classname = p.ident_chain
15
15
  {
16
16
  :tagname => :override,
@@ -9,12 +9,13 @@ module JsDuck::Tag
9
9
  def initialize
10
10
  @pattern = "param"
11
11
  @tagname = :params
12
+ @repeatable = true
12
13
  @merge_context = :method_like
13
14
  @html_position = POS_PARAM
14
15
  end
15
16
 
16
17
  # @param {Type} [name=default] (optional) ...
17
- def parse_doc(p)
18
+ def parse_doc(p, pos)
18
19
  tag = p.standard_tag({:tagname => :params, :type => true, :name => true})
19
20
  tag[:optional] = true if parse_optional(p)
20
21
  tag[:doc] = :multiline
@@ -31,6 +32,10 @@ module JsDuck::Tag
31
32
 
32
33
  def merge(h, docs, code)
33
34
  h[:params] = merge_params(docs, code, h[:files].first)
35
+
36
+ if only_autodetected_params?(docs, code)
37
+ JsDuck::DocsCodeComparer.mark_autodetected(h, :params)
38
+ end
34
39
  end
35
40
 
36
41
  def format(m, formatter)
@@ -43,6 +48,10 @@ module JsDuck::Tag
43
48
 
44
49
  private
45
50
 
51
+ def only_autodetected_params?(docs, code)
52
+ (docs[:params] || []).length == 0 && (code[:params] || []).length > 0
53
+ end
54
+
46
55
  def merge_params(docs, code, file)
47
56
  explicit = docs[:params] || []
48
57
  implicit = JsDuck::DocsCodeComparer.matches?(docs, code) ? (code[:params] || []) : []
@@ -50,19 +59,21 @@ module JsDuck::Tag
50
59
  im_len = implicit.length
51
60
 
52
61
  if ex_len == 0 || im_len == 0
53
- # Skip
62
+ # Skip when either no implicit or explicit params
63
+ elsif ex_len != im_len && explicit.last[:type] =~ /\.\.\.$/
64
+ # Skip when vararg params are in play.
54
65
  elsif ex_len < im_len
55
66
  # Warn when less parameters documented than found from code.
56
- JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but only #{ex_len} documented.", file[:filename], file[:linenr])
67
+ JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but only #{ex_len} documented.", file)
57
68
  elsif ex_len > im_len
58
69
  # Warn when more parameters documented than found from code.
59
- JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but #{ex_len} documented.", file[:filename], file[:linenr])
70
+ JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but #{ex_len} documented.", file)
60
71
  elsif implicit.map {|p| p[:name] } != explicit.map {|p| p[:name] }
61
72
  # Warn when parameter names don't match up.
62
73
  ex_names = explicit.map {|p| p[:name] }
63
74
  im_names = implicit.map {|p| p[:name] }
64
75
  str = ex_names.zip(im_names).map {|p| ex, im = p; ex == im ? ex : (ex||"")+"/"+(im||"") }.join(", ")
65
- JsDuck::Logger.warn(:param_count, "Documented and auto-detected params don't match: #{str}", file[:filename], file[:linenr])
76
+ JsDuck::Logger.warn(:param_count, "Documented and auto-detected params don't match: #{str}", file)
66
77
  end
67
78
 
68
79
  # Override implicit parameters with explicit ones