jsduck 5.0.0.beta2 → 5.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Rakefile +14 -4
  2. data/bin/jsduck +3 -1
  3. data/jsduck.gemspec +2 -2
  4. data/lib/jsduck/app.rb +8 -0
  5. data/lib/jsduck/assets.rb +3 -0
  6. data/lib/jsduck/batch_processor.rb +2 -0
  7. data/lib/jsduck/categories/class_name.rb +2 -26
  8. data/lib/jsduck/categories/factory.rb +5 -43
  9. data/lib/jsduck/columns.rb +56 -0
  10. data/lib/jsduck/doc/delimited_parser.rb +105 -0
  11. data/lib/jsduck/doc/scanner.rb +2 -1
  12. data/lib/jsduck/doc/standard_tag_parser.rb +37 -71
  13. data/lib/jsduck/guide_anchors.rb +32 -0
  14. data/lib/jsduck/guide_toc.rb +49 -0
  15. data/lib/jsduck/guides.rb +14 -32
  16. data/lib/jsduck/inline/video.rb +2 -8
  17. data/lib/jsduck/js/ast.rb +13 -305
  18. data/lib/jsduck/js/class.rb +245 -0
  19. data/lib/jsduck/js/event.rb +34 -0
  20. data/lib/jsduck/js/fires.rb +42 -0
  21. data/lib/jsduck/js/method.rb +94 -0
  22. data/lib/jsduck/js/method_calls.rb +40 -0
  23. data/lib/jsduck/js/node.rb +29 -0
  24. data/lib/jsduck/js/property.rb +64 -0
  25. data/lib/jsduck/js/{function.rb → returns.rb} +8 -3
  26. data/lib/jsduck/js/scoped_traverser.rb +42 -0
  27. data/lib/jsduck/logger.rb +13 -1
  28. data/lib/jsduck/merger.rb +34 -27
  29. data/lib/jsduck/news.rb +128 -0
  30. data/lib/jsduck/options.rb +59 -2
  31. data/lib/jsduck/params_merger.rb +47 -0
  32. data/lib/jsduck/process/accessors.rb +8 -2
  33. data/lib/jsduck/process/fires.rb +71 -0
  34. data/lib/jsduck/process/importer.rb +19 -1
  35. data/lib/jsduck/render/class.rb +11 -4
  36. data/lib/jsduck/render/signature_util.rb +14 -0
  37. data/lib/jsduck/tag/alias.rb +0 -20
  38. data/lib/jsduck/tag/alternate_class_names.rb +0 -5
  39. data/lib/jsduck/tag/cfg.rb +30 -5
  40. data/lib/jsduck/tag/class.rb +45 -2
  41. data/lib/jsduck/tag/css_mixin.rb +8 -4
  42. data/lib/jsduck/tag/css_var.rb +26 -5
  43. data/lib/jsduck/tag/default.rb +2 -8
  44. data/lib/jsduck/tag/enum.rb +7 -10
  45. data/lib/jsduck/tag/event.rb +12 -4
  46. data/lib/jsduck/tag/extends.rb +0 -6
  47. data/lib/jsduck/tag/fires.rb +53 -0
  48. data/lib/jsduck/tag/icons/cfg.png +0 -0
  49. data/lib/jsduck/tag/icons/css_mixin.png +0 -0
  50. data/lib/jsduck/tag/icons/css_var.png +0 -0
  51. data/lib/jsduck/tag/icons/event.png +0 -0
  52. data/lib/jsduck/tag/icons/method.png +0 -0
  53. data/lib/jsduck/tag/icons/property.png +0 -0
  54. data/lib/jsduck/tag/member_tag.rb +130 -0
  55. data/lib/jsduck/tag/method.rb +44 -4
  56. data/lib/jsduck/tag/param.rb +8 -60
  57. data/lib/jsduck/tag/property.rb +28 -5
  58. data/lib/jsduck/tag/tag.rb +3 -75
  59. data/lib/jsduck/tag/type.rb +1 -11
  60. data/lib/jsduck/tag_registry.rb +6 -48
  61. data/lib/jsduck/web/css.rb +8 -1
  62. data/lib/jsduck/web/data.rb +2 -1
  63. data/lib/jsduck/web/index_html.rb +1 -0
  64. data/lib/jsduck/web/member_icons.rb +43 -0
  65. data/lib/jsduck/web/search.rb +3 -2
  66. data/lib/jsduck/web/writer.rb +8 -0
  67. metadata +31 -27
  68. data/lib/jsduck/docs_code_comparer.rb +0 -44
  69. data/lib/jsduck/render/signature.rb +0 -94
  70. data/lib/jsduck/tag/autodetected.rb +0 -21
  71. data/lib/jsduck/tag/name.rb +0 -36
@@ -1,5 +1,4 @@
1
1
  require "jsduck/tag/tag"
2
- require "jsduck/docs_code_comparer"
3
2
  require "jsduck/util/html"
4
3
 
5
4
  module JsDuck::Tag
@@ -9,19 +8,14 @@ module JsDuck::Tag
9
8
  #
10
9
  # @cfg [blah=somedefault]
11
10
  #
12
- # This tag class exists to take care of the merging of :default
13
- # fields and to generate the "Defaults to:" text in final HTML.
11
+ # This tag class exists to generate the "Defaults to:" text in final
12
+ # HTML.
14
13
  class Default < Tag
15
14
  def initialize
16
15
  @tagname = :default
17
- @merge_context = :property_like
18
16
  @html_position = POS_DEFAULT
19
17
  end
20
18
 
21
- def merge(h, docs, code)
22
- JsDuck::DocsCodeComparer.merge_if_matches(h, :default, docs, code)
23
- end
24
-
25
19
  def to_html(m)
26
20
  return if m[:default] == "undefined"
27
21
 
@@ -5,7 +5,6 @@ module JsDuck::Tag
5
5
  def initialize
6
6
  @pattern = "enum"
7
7
  @tagname = :enum
8
- @merge_context = :class
9
8
  @html_position = POS_ENUM
10
9
  # Green box
11
10
  @css = <<-EOCSS
@@ -19,7 +18,13 @@ module JsDuck::Tag
19
18
 
20
19
  # @enum {Type} [name=default] ...
21
20
  def parse_doc(p, pos)
22
- enum = p.standard_tag({:tagname => :enum, :type => true, :name => true})
21
+ enum = p.standard_tag({
22
+ :tagname => :enum,
23
+ :type => true,
24
+ :name => true,
25
+ :default => true,
26
+ :optional => true
27
+ })
23
28
 
24
29
  # @enum is a special case of class, so we also generate a class
25
30
  # tag with the same name as given for @enum.
@@ -36,14 +41,6 @@ module JsDuck::Tag
36
41
  }
37
42
  end
38
43
 
39
- # Takes the :enum always from docs, but the :doc_only can come
40
- # from either code or docs.
41
- def merge(h, docs, code)
42
- return unless docs[:enum]
43
- h[:enum] = docs[:enum]
44
- h[:enum][:doc_only] = docs[:enum][:doc_only] || (code[:enum] && code[:enum][:doc_only])
45
- end
46
-
47
44
  def to_html(cls)
48
45
  if cls[:enum][:doc_only]
49
46
  first = cls[:members][0] || {:name => 'foo', :default => '"foo"'}
@@ -1,15 +1,15 @@
1
- require "jsduck/tag/tag"
1
+ require "jsduck/tag/member_tag"
2
+ require "jsduck/params_merger"
2
3
 
3
4
  module JsDuck::Tag
4
- class Event < Tag
5
+ class Event < MemberTag
5
6
  def initialize
6
7
  @pattern = "event"
7
8
  @tagname = :event
8
9
  @member_type = {
9
- :name => :event,
10
- :category => :method_like,
11
10
  :title => "Events",
12
11
  :position => MEMBER_POS_EVENT,
12
+ :icon => File.dirname(__FILE__) + "/icons/event.png"
13
13
  }
14
14
  end
15
15
 
@@ -24,5 +24,13 @@ module JsDuck::Tag
24
24
  def process_doc(h, tags, pos)
25
25
  h[:name] = tags[0][:name]
26
26
  end
27
+
28
+ def merge(h, docs, code)
29
+ JsDuck::ParamsMerger.merge(h, docs, code)
30
+ end
31
+
32
+ def to_html(event, cls)
33
+ member_link(event) + member_params(event[:params])
34
+ end
27
35
  end
28
36
  end
@@ -8,7 +8,6 @@ module JsDuck::Tag
8
8
  @tagname = :extends
9
9
  @ext_define_pattern = "extend"
10
10
  @ext_define_default = {:extends => "Ext.Base"}
11
- @merge_context = :class
12
11
  end
13
12
 
14
13
  # @extends classname
@@ -36,10 +35,5 @@ module JsDuck::Tag
36
35
  cls[:extends] = JsDuck::Js::Utils.make_string(ast)
37
36
  end
38
37
 
39
- # Ignore extending of the Object class
40
- def merge(h, docs, code)
41
- h[:extends] = docs[:extends] || code[:extends]
42
- h[:extends] = nil if h[:extends] == "Object"
43
- end
44
38
  end
45
39
  end
@@ -0,0 +1,53 @@
1
+ require "jsduck/tag/tag"
2
+ require "jsduck/logger"
3
+
4
+ module JsDuck::Tag
5
+ class Fires < Tag
6
+ def initialize
7
+ @pattern = "fires"
8
+ @tagname = :fires
9
+ @repeatable = true
10
+ @html_position = POS_FIRES
11
+ end
12
+
13
+ # @fires eventname
14
+ def parse_doc(p, pos)
15
+ {:tagname => :fires, :events => ident_list(p)}
16
+ end
17
+
18
+ # matches <ident> <ident> ... until line end
19
+ def ident_list(p)
20
+ list = []
21
+ while ident = p.hw.ident
22
+ list << ident
23
+ end
24
+ list
25
+ end
26
+
27
+ def process_doc(h, tags, pos)
28
+ h[:fires] = tags.map {|t| t[:events] }.flatten
29
+ end
30
+
31
+ def format(m, formatter)
32
+ cls = formatter.relations[m[:owner]]
33
+
34
+ m[:fires] = m[:fires].map do |name|
35
+ if cls.find_members({:tagname => :event, :name => name}).length > 0
36
+ formatter.link(m[:owner], name, name, :event)
37
+ else
38
+ JsDuck::Logger.warn(:fires, "@fires references unknown event: #{name}", m[:files][0])
39
+ name
40
+ end
41
+ end
42
+ end
43
+
44
+ def to_html(m)
45
+ return [
46
+ "<h3 class='pa'>Fires</h3>",
47
+ "<ul>",
48
+ m[:fires].map {|e| "<li>#{e}</li>" },
49
+ "</ul>",
50
+ ]
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,130 @@
1
+ require 'jsduck/tag/tag'
2
+ require 'jsduck/render/signature_util'
3
+
4
+ module JsDuck::Tag
5
+ # Base class for all builtin members.
6
+ class MemberTag < Tag
7
+ # Defines a class member type and specifies various settings. For
8
+ # example:
9
+ #
10
+ # {
11
+ # :title => "Events",
12
+ # :position => MEMBER_POS_EVENT,
13
+ # # The following are optional
14
+ # :toolbar_title => "Events",
15
+ # :icon => File.dirname(__FILE__) + "/icons/event.png",
16
+ # :subsections => [
17
+ # {:title => "Static events",
18
+ # :filter => {:static => false},
19
+ # :default => true},
20
+ # {:title => "Instance events",
21
+ # :filter => {:static => true}},
22
+ # ]
23
+ # }
24
+ #
25
+ # Position defines the ordering of member section in final HTML
26
+ # output.
27
+ #
28
+ # Title is shown at the top of each such section and also as a
29
+ # label on Docs app toolbar button unless :toolbar_title is
30
+ # specified.
31
+ #
32
+ # Icon defines a file to be used as member icon in various places
33
+ # of the docs app.
34
+ #
35
+ # Subsections allows splitting the list of members to several
36
+ # subgroups. For example methods get split into static and
37
+ # instance methods.
38
+ #
39
+ # - The :filter field defines how to filter out the members for
40
+ # this subcategory. :static=>true filters out all members that
41
+ # have a :static field with a truthy value. Conversely,
42
+ # :static=>false filters out members not having a :static field
43
+ # or having it with a falsy value.
44
+ #
45
+ # - Setting :default=>true will hide the subsection title when all
46
+ # the members end up in that subsection. For example when there
47
+ # are only instance methods, the docs will only contain the
48
+ # section title "Methods", as by default one should assume all
49
+ # methods are instance methods if not stated otherwise.
50
+ #
51
+ attr_reader :member_type
52
+
53
+ # Avoid already-defined-constant warnings in Ruby 1.8
54
+ unless defined?(MEMBER_POS_CFG)
55
+ MEMBER_POS_CFG = 1
56
+ MEMBER_POS_PROPERTY = 2
57
+ MEMBER_POS_METHOD = 3
58
+ MEMBER_POS_EVENT = 4
59
+ MEMBER_POS_CSS_VAR = 5
60
+ MEMBER_POS_CSS_MIXIN = 6
61
+ end
62
+
63
+ # Extracts the fields auto-detected from code that are relevant to
64
+ # the member type and returns a hash with them.
65
+ #
66
+ # The implementation here extracts fields applicable to all member
67
+ # types. When additional member-specific fields are to be
68
+ # extracted, override this method, but be sure to call the
69
+ # superclass method too.
70
+ #
71
+ # For example inside Method tag we might additionally want to
72
+ # extract :type and :default:
73
+ #
74
+ # def process_code(code)
75
+ # h = super(code)
76
+ # h[:type] = code[:type]
77
+ # h[:default] = code[:default]
78
+ # h
79
+ # end
80
+ #
81
+ def process_code(code)
82
+ return {
83
+ :tagname => code[:tagname],
84
+ # An auto-detected name might be "MyClass.prototype.myMethod" -
85
+ # for member name we only want the last "myMethod" part.
86
+ :name => code[:name] ? code[:name].split(/\./).last : nil,
87
+
88
+ :autodetected => code[:autodetected],
89
+ :inheritdoc => code[:inheritdoc],
90
+ :static => code[:static],
91
+ :private => code[:private],
92
+ :inheritable => code[:inheritable],
93
+ :linenr => code[:linenr],
94
+ }
95
+ end
96
+
97
+ # Merges documentation and code hashes into the result hash.
98
+ def merge(hash, docs, code)
99
+ end
100
+
101
+ # This method defines the signature-line of the member.
102
+ # For example it might return something like this:
103
+ #
104
+ # "apply(source, target) : Object"
105
+ #
106
+ # Use #member_link method to render the member name as link in a
107
+ # standard way. Similarly there's helper method #member_params
108
+ # for rendering the parameter list.
109
+ def to_html(context, cls)
110
+ end
111
+
112
+ # Creates HTML link to the given member.
113
+ # A helper method for use in #to_html.
114
+ def member_link(member)
115
+ JsDuck::Render::SignatureUtil::link(member[:owner], member[:id], member[:name])
116
+ end
117
+
118
+ # Creates HTML listing of parameters.
119
+ # When called with nil, creates empty params list.
120
+ # A helper method for use in #to_html.
121
+ def member_params(params)
122
+ ps = Array(params).map do |p|
123
+ p[:optional] ? "["+p[:name]+"]" : p[:name]
124
+ end.join(", ")
125
+
126
+ "( <span class='pre'>#{ps}</span> )"
127
+ end
128
+
129
+ end
130
+ end
@@ -1,16 +1,16 @@
1
- require "jsduck/tag/tag"
1
+ require "jsduck/tag/member_tag"
2
+ require "jsduck/params_merger"
2
3
 
3
4
  module JsDuck::Tag
4
5
  # Implementation of @method tag.
5
- class Method < Tag
6
+ class Method < MemberTag
6
7
  def initialize
7
8
  @pattern = "method"
8
9
  @tagname = :method
9
10
  @member_type = {
10
- :name => :method,
11
- :category => :method_like,
12
11
  :title => "Methods",
13
12
  :position => MEMBER_POS_METHOD,
13
+ :icon => File.dirname(__FILE__) + "/icons/method.png",
14
14
  :subsections => [
15
15
  {:title => "Instance methods", :filter => {:static => false}, :default => true},
16
16
  {:title => "Static methods", :filter => {:static => true}},
@@ -31,5 +31,45 @@ module JsDuck::Tag
31
31
  def process_doc(h, tags, pos)
32
32
  h[:name] = tags[0][:name] if tags[0][:name]
33
33
  end
34
+
35
+ def process_code(code)
36
+ h = super(code)
37
+ h[:params] = code[:params]
38
+ h[:chainable] = code[:chainable]
39
+ h[:fires] = code[:fires]
40
+ h[:method_calls] = code[:method_calls]
41
+ h
42
+ end
43
+
44
+ def merge(h, docs, code)
45
+ JsDuck::ParamsMerger.merge(h, docs, code)
46
+ end
47
+
48
+ def to_html(m, cls)
49
+ new_kw(m) + method_link(m, cls) + member_params(m[:params]) + return_value(m)
50
+ end
51
+
52
+ private
53
+
54
+ def new_kw(m)
55
+ constructor?(m) ? "<strong class='new-keyword'>new</strong>" : ""
56
+ end
57
+
58
+ def method_link(m, cls)
59
+ if constructor?(m)
60
+ member_link(:owner => m[:owner], :id => m[:id], :name => cls[:name])
61
+ else
62
+ member_link(m)
63
+ end
64
+ end
65
+
66
+ def constructor?(m)
67
+ m[:name] == "constructor"
68
+ end
69
+
70
+ def return_value(m)
71
+ m[:return] ? (" : " + m[:return][:html_type]) : ""
72
+ end
73
+
34
74
  end
35
75
  end
@@ -1,8 +1,6 @@
1
1
  require "jsduck/tag/tag"
2
2
  require "jsduck/doc/subproperties"
3
3
  require "jsduck/render/subproperties"
4
- require "jsduck/docs_code_comparer"
5
- require "jsduck/logger"
6
4
 
7
5
  module JsDuck::Tag
8
6
  class Param < Tag
@@ -10,13 +8,18 @@ module JsDuck::Tag
10
8
  @pattern = "param"
11
9
  @tagname = :params
12
10
  @repeatable = true
13
- @merge_context = :method_like
14
11
  @html_position = POS_PARAM
15
12
  end
16
13
 
17
14
  # @param {Type} [name=default] (optional) ...
18
15
  def parse_doc(p, pos)
19
- tag = p.standard_tag({:tagname => :params, :type => true, :name => true})
16
+ tag = p.standard_tag({
17
+ :tagname => :params,
18
+ :type => true,
19
+ :name => true,
20
+ :default => true,
21
+ :optional => true
22
+ })
20
23
  tag[:optional] = true if parse_optional(p)
21
24
  tag[:doc] = :multiline
22
25
  tag
@@ -28,14 +31,7 @@ module JsDuck::Tag
28
31
 
29
32
  def process_doc(h, tags, pos)
30
33
  h[:params] = JsDuck::Doc::Subproperties.nest(tags, pos)
31
- end
32
-
33
- def merge(h, docs, code)
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
+ h[:params] = nil if h[:params].length == 0
39
35
  end
40
36
 
41
37
  def format(m, formatter)
@@ -46,53 +42,5 @@ module JsDuck::Tag
46
42
  JsDuck::Render::Subproperties.render_params(m[:params]) if m[:params].length > 0
47
43
  end
48
44
 
49
- private
50
-
51
- def only_autodetected_params?(docs, code)
52
- (docs[:params] || []).length == 0 && (code[:params] || []).length > 0
53
- end
54
-
55
- def merge_params(docs, code, file)
56
- explicit = docs[:params] || []
57
- implicit = JsDuck::DocsCodeComparer.matches?(docs, code) ? (code[:params] || []) : []
58
- ex_len = explicit.length
59
- im_len = implicit.length
60
-
61
- if ex_len == 0 || im_len == 0
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.
65
- elsif ex_len < im_len
66
- # Warn when less parameters documented than found from code.
67
- JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but only #{ex_len} documented.", file)
68
- elsif ex_len > im_len
69
- # Warn when more parameters documented than found from code.
70
- JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but #{ex_len} documented.", file)
71
- elsif implicit.map {|p| p[:name] } != explicit.map {|p| p[:name] }
72
- # Warn when parameter names don't match up.
73
- ex_names = explicit.map {|p| p[:name] }
74
- im_names = implicit.map {|p| p[:name] }
75
- str = ex_names.zip(im_names).map {|p| ex, im = p; ex == im ? ex : (ex||"")+"/"+(im||"") }.join(", ")
76
- JsDuck::Logger.warn(:param_count, "Documented and auto-detected params don't match: #{str}", file)
77
- end
78
-
79
- # Override implicit parameters with explicit ones
80
- # But if explicit ones exist, don't append the implicit ones.
81
- params = []
82
- (ex_len > 0 ? ex_len : im_len).times do |i|
83
- im = implicit[i] || {}
84
- ex = explicit[i] || {}
85
- params << {
86
- :type => ex[:type] || im[:type] || "Object",
87
- :name => ex[:name] || im[:name] || "",
88
- :doc => ex[:doc] || im[:doc] || "",
89
- :optional => ex[:optional] || false,
90
- :default => ex[:default],
91
- :properties => ex[:properties] || [],
92
- }
93
- end
94
- params
95
- end
96
-
97
45
  end
98
46
  end