yard 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yard might be problematic. Click here for more details.

@@ -51,11 +51,18 @@ module YARD
51
51
 
52
52
  private
53
53
  def top_level_parse(statements)
54
- statements.each do |stmt|
55
- find_handlers(stmt).each do |handler|
56
- handler.new(self, stmt).process
54
+ statements.each do |stmt|
55
+ find_handlers(stmt).each do |handler|
56
+ begin
57
+ handler.new(self, stmt).process
58
+ rescue => e
59
+ STDERR.puts "#{handler.to_s} error in `#{file}`:#{stmt.tokens.first.line_no}: #{stmt.tokens.to_s}"
60
+ STDERR.puts "Exception message: #{e.message}"
61
+ STDERR.puts e.backtrace[0, 5]
62
+ STDERR.puts
63
+ end
64
+ end
57
65
  end
58
- end
59
66
  end
60
67
 
61
68
  def find_handlers(stmt)
@@ -174,7 +181,7 @@ module YARD
174
181
  #
175
182
  # if a ||
176
183
  # b
177
- if [EXPR_END, EXPR_ARG].include? last_tk.lex_state
184
+ if last_tk && [EXPR_END, EXPR_ARG].include?(last_tk.lex_state)
178
185
  stmt_number += 1
179
186
  new_statement = true
180
187
  #p "NEW STATEMENT #{statement.to_s}"
@@ -31,28 +31,41 @@ module YARD
31
31
  # @see TagLibrary::define_tag!
32
32
  module TagLibrary
33
33
  class << self
34
+ attr_reader :labels
35
+
36
+ ##
37
+ # Sorts the labels lexically by their label name, often used when displaying
38
+ # the tags.
39
+ #
40
+ # @return [Array<Symbol,String>] the sorted labels as an array of the tag name and label
41
+ def sorted_labels
42
+ labels.sort_by {|a| a.last }
43
+ end
44
+
34
45
  ##
35
46
  # Convenience method to define a new tag using one of {Tag}'s factory methods, or the
36
47
  # regular {Tag::parse_tag} factory method if none is supplied.
37
48
  #
38
49
  # @param tag the tag name to create
39
50
  # @param meth the {Tag} factory method to call when creating the tag
40
- def self.define_tag!(tag, meth = "")
51
+ def self.define_tag!(label, tag, meth = "")
41
52
  meth = meth.to_s
42
53
  send_name = meth.empty? ? "" : "_" + meth
43
54
  class_eval "def #{tag}_tag(text) Tag.parse_tag#{send_name}(#{tag.inspect}, text) end"
55
+ @labels ||= {}
56
+ @labels.update(tag => label)
44
57
  end
45
58
 
46
- define_tag! :param, :with_types_and_name
47
- define_tag! :yieldparam, :with_types_and_name
48
- define_tag! :yield
49
- define_tag! :return, :with_types
50
- define_tag! :deprecated
51
- define_tag! :author
52
- define_tag! :raise, :with_name
53
- define_tag! :see
54
- define_tag! :since
55
- define_tag! :version
59
+ define_tag! "Parameters", :param, :with_types_and_name
60
+ define_tag! "Block Parameters", :yieldparam, :with_types_and_name
61
+ define_tag! "Yields", :yield
62
+ define_tag! "Returns", :return, :with_types
63
+ define_tag! "Deprecated", :deprecated
64
+ define_tag! "Author", :author
65
+ define_tag! "Raises", :raise, :with_name
66
+ define_tag! "See Also", :see
67
+ define_tag! "Since", :since
68
+ define_tag! "Version", :version
56
69
  end
57
70
  end
58
71
 
@@ -1,3 +1,8 @@
1
- YARD_VERSION = "0.2.0"
1
+ module YARD
2
+ VERSION = "0.2.1"
3
+ end
4
+
5
+ require File.dirname(__FILE__) + '/extra'
6
+ require File.dirname(__FILE__) + '/logger'
2
7
  require File.dirname(__FILE__) + '/namespace'
3
8
  require File.dirname(__FILE__) + '/source_parser'
@@ -0,0 +1,64 @@
1
+ <% if tag("deprecated") %>
2
+ <p><strong>Deprecated.</strong> <em><%= to_html tag("deprecated").text %></em></p>
3
+ <% end %>
4
+ <% if tag("yield") %>
5
+ <p><strong>Yields Block.</strong> <em><%= to_html tag("yield").text %></em></p>
6
+ <% end %>
7
+ <p>
8
+ <%= to_html docstring %>
9
+ </p>
10
+ <% unless tags.empty? %>
11
+ <dl>
12
+ <% unless tags("param").empty? %>
13
+ <dt>Parameters:</dt>
14
+ <dd>
15
+ <% tags("param").each do |tag| %>
16
+ <% unless tag.types.empty? %>
17
+ [<%= tag.types.collect {|t| "<tt>" + link_to_path(t, parent) + "</tt>" }.join(", ") %>]
18
+ <% end %>
19
+ <tt><%= tag.name %></tt> <%= "- " + to_html(tag.text) if tag.text %><br />
20
+ <% end %>
21
+ </dd>
22
+ <% end %>
23
+ <% unless tags("yieldparam").empty? %>
24
+ <dt>Yield Parameters:</dt>
25
+ <dd>
26
+ <% tags("yieldparam").each do |tag| %>
27
+ <% unless tag.types.empty? %>
28
+ [<%= tag.types.collect {|t| "<tt>" + link_to_path(t, parent) + "</tt>" }.join(", ") %>]
29
+ <% end %>
30
+ <tt><%= tag.name %></tt> <%= "- " + to_html(tag.text) if tag.text %><br />
31
+ <% end %>
32
+ </dd>
33
+ <% end %>
34
+ <% if has_tag?("return") %>
35
+ <dt>Returns:</dt>
36
+ <dd><%= to_html tag("return").text %></dd>
37
+ <% end %>
38
+ <% unless tags("raise").empty? %>
39
+ <dt>Raises:</dt>
40
+ <dd>
41
+ <% tags("raise").each do |tag| %>
42
+ <tt><%= link_to_path(tag.name, parent) %></tt> <%= "- " + to_html(tag.text) if tag.text %><br />
43
+ <% end %>
44
+ </dd>
45
+ <% end %>
46
+
47
+ <% if has_tag?("author") %>
48
+ <dt>Author:</dt>
49
+ <dd><%= to_html tag("author").text %></dd>
50
+ <% end %>
51
+ <% if has_tag?("version") %>
52
+ <dt>Version:</dt>
53
+ <dd><%= to_html tag("version").text %></dd>
54
+ <% end %>
55
+ <% if has_tag?("since") %>
56
+ <dt>Since:</dt>
57
+ <dd><%= to_html tag("since").text %></dd>
58
+ <% end %>
59
+ <% unless tags("see").empty? %>
60
+ <dt>See Also:</dt>
61
+ <dd><%= tags("see").collect {|t| "<tt>" + link_to_path(t.text, parent) + "</tt>" }.join(", ") %></dd>
62
+ <% end %>
63
+ </dl>
64
+ <% end %>
@@ -0,0 +1,226 @@
1
+ <% _class_methods = class_methods.select {|k,m| m.visibility == :public }.sort %>
2
+ <% _instance_methods = instance_methods.select {|k,m| m.visibility == :public && k != 'initialize' && k != 'method_missing' }.sort %>
3
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html>
7
+ <head>
8
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
9
+ <title>Ruby documentation: <%= path %></title>
10
+ <style>
11
+ .topdoc * dt {
12
+ font-weight: bold;
13
+ }
14
+ .fulldoc {
15
+ margin-left: 37px;
16
+ }
17
+ .fulldoc * dt {
18
+ font-weight: bold;
19
+ }
20
+ h1 { color: #000; }
21
+ td { padding: 3px; }
22
+ </style>
23
+ <base target="_self" />
24
+ </head
25
+ <body>
26
+ <h1>Class <%= path %></h1>
27
+ <% unless superclasses.empty? %>
28
+ <pre>
29
+ <% spaces = 0 -%>
30
+ <% superclasses.reverse.each do |superclass| -%><%= (" " * spaces) + (spaces > 0 ? "+--" : "") + link_to_path(superclass) %>
31
+ <% spaces += (spaces == 0 ? 2 : 4) -%><%= (" " * spaces) + "|" %>
32
+ <% end -%><%= (" " * spaces ) + "+--" + path %>
33
+ </pre>
34
+ <% end %>
35
+
36
+ <% unless mixins.empty? %>
37
+ <p>
38
+ <strong>All Included Modules:</strong><br />
39
+ <%= "&nbsp;" * 7 %><%= mixins.collect {|m| link_to_path(m) }.join(", ") %>
40
+ </p>
41
+ <% end %>
42
+
43
+ <hr />
44
+
45
+ <% if docstring %>
46
+ <div class="topdoc">
47
+ <%= formatter.render('_fulldoc') %>
48
+ </div>
49
+ <hr />
50
+ <% end %>
51
+
52
+ <% unless self[:attributes].empty? %>
53
+ <h1>Attributes</h1>
54
+ <p style="line-height:20px">
55
+ <% self[:attributes].sort.each do |name, rw| %>
56
+ <tt><%= name %> [<%= [(rw[:read] ? "R" : nil), (rw[:write] ? "W" : nil)].compact.join(", ") %>]</tt><br />
57
+ <% end %>
58
+ </p>
59
+ <% end %>
60
+
61
+ <% displayed_constants = false %>
62
+ <% unless constants.empty? %>
63
+ <h1>Constants</h1><% displayed_constants = true %>
64
+ <dl>
65
+ <% constants.each do |name, constant| %>
66
+ <dt id="const-<%= name %>"><pre><%= constant.full_source.gsub(/\s+/,' ') %></pre></dt>
67
+ <dd><%= to_html constant.docstring %></dd>
68
+ <% end %>
69
+ </dl>
70
+ <% end %>
71
+
72
+ <% inheritance_tree.each do |name| %>
73
+ <% superclass = Namespace.at(name) or next %>
74
+ <% unless (consts = superclass.constants).empty? %>
75
+ <% unless displayed_constants %><h1>Constants</h1><% end %>
76
+ <p><table border="1" width="100%">
77
+ <tr background="#ddddff">
78
+ <th>Constants <%= superclass.type == :module ? "included" : "inherited" %> from <%= link_to_path(superclass.path) %></th>
79
+ </tr>
80
+ <tr>
81
+ <td><%= consts.collect {|m| "<tt>" + link_to_path(m.first, superclass.path) + "</tt>" }.join(", ") %></td>
82
+ </tr>
83
+ </table></p>
84
+ <% end %>
85
+ <% end %>
86
+
87
+ <% displayed_cvars = false %>
88
+ <% unless class_variables.empty? %>
89
+ <h1>Class Variables</h1><% displayed_cvars = true %>
90
+ <dl>
91
+ <% class_variables.each do |name, cvar| %>
92
+ <dt><pre><%= cvar.source.gsub(/\s+/,' ') %></pre></dt>
93
+ <dd><%= to_html cvar.docstring %></dd>
94
+ <% end %>
95
+ </dl>
96
+ <% end %>
97
+
98
+ <% superclasses.each do |name| %>
99
+ <% superclass = Namespace.at(name) or next %>
100
+ <% unless (consts = superclass.class_variables.sort).empty? %>
101
+ <% unless displayed_cvars %><h1>Constants</h1><% end %>
102
+ <p><table border="1" width="100%">
103
+ <tr background="#ddddff">
104
+ <th>Class Variables inherited from <%= link_to_path(superclass.path) %></th>
105
+ </tr>
106
+ <tr>
107
+ <td><%= consts.reject {|name, cvar| class_variables.has_key? name }.
108
+ collect {|name, cvar| "<tt>" + link_to_path(cvar, nil, name) + "</tt>" }.join(", ") %></td>
109
+ </tr>
110
+ </table></p>
111
+ <% end %>
112
+ <% end %>
113
+
114
+ <% if method = instance_methods['initialize'] %>
115
+ <h1>Constructor Summary</h1>
116
+ <tt>
117
+ <%= method.source.gsub(/\Adef\s+/, '') %>
118
+ <% unless method.tags("yieldparam").empty? %>
119
+ {|<%= method.tags("yieldparam").collect {|t| t.name }.join(", ") %>| ... }
120
+ <% end %>
121
+ </tt>
122
+ <%= method.to_s(format, template) %>
123
+ <% else %>
124
+ <% inheritance_tree.each do |name| %>
125
+ <% superclass = Namespace.at(name) or next %>
126
+ <% if method = superclass.instance_methods['initialize'] %>
127
+ <h1>Constructor Summary</h1>
128
+ <p>
129
+ <em>This class inherits a constructor from <tt><%= link_to_path(method.path, nil, method.parent.path) %></tt></em>
130
+ </p>
131
+ <% break %>
132
+ <% end %>
133
+ <% end %>
134
+ <% end %>
135
+
136
+ <% if method = instance_methods['method_missing'] %>
137
+ <h1>Dynamic Method Handling</h1>
138
+ <p><em>This class handles dynamic methods through the <tt>method_missing</tt> method</em></p>
139
+ <%= method.to_s(format, template) %>
140
+ <% else %>
141
+ <% inheritance_tree.each do |name| %>
142
+ <% superclass = Namespace.at(name) or next %>
143
+ <% if method = superclass.instance_methods['method_missing'] %>
144
+ <h1>Dynamic Method Handling</h1>
145
+ <p>
146
+ <em>
147
+ This class handles dynamic methods through the
148
+ <tt>
149
+ <%= link_to_path(method.path, nil, 'method_missing') %></tt> method in
150
+ the <%= superclass.type %> <tt><%= link_to_path(superclass.path) %></tt>
151
+ </tt>
152
+ </em>
153
+ </p>
154
+ <% break %>
155
+ <% end %>
156
+ <% end %>
157
+ <% end %>
158
+
159
+ <% displayed_public_meth_summary = false %>
160
+ <% CodeObject::SCOPES.each do |scope| %>
161
+ <% unless eval("_#{scope}_methods").empty? %>
162
+ <% displayed_public_meth_summary = true %>
163
+ <h1>Public <%= scope.to_s.capitalize %> Method Summary</h1>
164
+ <table border="1" width="100%">
165
+ <% eval("_#{scope}_methods").each do |name, method| %>
166
+ <tr>
167
+ <td width="70" align="right" valign="top">
168
+ <small>
169
+ <% if method.tag("return") && method.tag("return").types %>
170
+ <%= method.tag("return").types.collect {|t| link_to_path(t) }.join(", ") %>
171
+ <% else %>
172
+ <%= ClassObject::BASE_OBJECT %>
173
+ <% end %>
174
+ </small>
175
+ </td>
176
+ <td>
177
+ <tt>
178
+ <%= method.source.sub(/\Adef\s+\S+?(\(|\s|;|$)/, link_to_path(method.path, nil, method.name) + '\1') if method.source %>
179
+ <% unless method.tags("yieldparam").empty? %>
180
+ {|<%= method.tags("yieldparam").collect {|t| t.name }.join(", ") %>| ... }
181
+ <% end %>
182
+ </tt><br />
183
+ <%= ("&nbsp;" * 5) + to_html(method.docstring.sub(/(\.|\n).+/m,'')) + "." if method.docstring && !method.docstring.empty? %>
184
+ <% if method.tag("deprecated") %>
185
+ <br /><strong>Deprecated.</strong> <em><%= method.tag("deprecated").text %></em>
186
+ <% end %>
187
+ </td>
188
+ </tr>
189
+ <% end %>
190
+ </table>
191
+ <% end %>
192
+
193
+ <% inheritance_tree.each do |name| %>
194
+ <% superclass = Namespace.at(name) or next %>
195
+ <% unless (meths = superclass.send("#{scope}_methods").select {|k,m| m.visibility == :public }).empty? %>
196
+ <% unless displayed_public_meth_summary %>
197
+ <h1>Public <%= scope.to_s.capitalize %> Method Summary</h1>
198
+ <% end %>
199
+ <p><table border="1" width="100%">
200
+ <tr background="#ddddff">
201
+ <th>
202
+ Public <%= scope %> methods <%= superclass.type == :module ? "included" : "inherited" %>
203
+ from <%= link_to_path(superclass.path) %>
204
+ </th>
205
+ </tr>
206
+ <tr>
207
+ <td><%= superclass.send("#{scope}_methods").reject {|name, m| meths.include? name }.
208
+ collect {|name, m| "<tt>" + link_to_path(superclass.path + (scope == :instance ? "#" : "::") +
209
+ name, nil, name) + "</tt>" }.join(", ") %></td>
210
+ </tr>
211
+ </table></p>
212
+ <% end %>
213
+ <% end %>
214
+ <% end %>
215
+
216
+ <% CodeObject::SCOPES.each do |scope| %>
217
+ <% unless eval("_#{scope}_methods").empty? %>
218
+ <h1>Public <%= scope.to_s.capitalize %> Method Details</h1>
219
+ <% eval("_#{scope}_methods").each do |name, method| %>
220
+ <%= method.to_s(format, template) %>
221
+ <hr />
222
+ <% end %>
223
+ <% end %>
224
+ <% end %>
225
+ </body>
226
+ </html>
@@ -0,0 +1,20 @@
1
+ <div id="<%= scope %>_method-<%= name %>">
2
+ <h3><%= name %></h3>
3
+ <%
4
+ if tag("return") && !tag("return").types.empty?
5
+ type = tag("return").types.collect {|t| link_to_path(t, parent) }.join(", ")
6
+ type = "[#{type}]" if tag("return").types.size > 1
7
+ else
8
+ type = ClassObject::BASE_OBJECT
9
+ end
10
+ %>
11
+ <tt>
12
+ <%= source.gsub(/\Adef/, "#{visibility} " + type) if source %>
13
+ <% unless tags("yieldparam").empty? %>
14
+ {|<%= tags("yieldparam").map {|t| t.name }.join(", ") %>| ... }
15
+ <% end %>
16
+ </tt>
17
+ <div class="fulldoc">
18
+ <%= formatter.render('_fulldoc') %>
19
+ </div>
20
+ </div>
@@ -0,0 +1,126 @@
1
+ <% _class_methods = class_methods.select {|k,m| m.visibility == :public }.sort %>
2
+ <% _instance_methods = instance_methods.select {|k,m| m.visibility == :public && k != 'initialize' && k != 'method_missing' }.sort %>
3
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html>
7
+ <head>
8
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
9
+ <title>Ruby documentation: <%= path %></title>
10
+ <style>
11
+ .topdoc * dt {
12
+ font-weight: bold;
13
+ }
14
+ .fulldoc {
15
+ margin-left: 37px;
16
+ }
17
+ .fulldoc * dt {
18
+ font-weight: bold;
19
+ }
20
+ h1 { color: #000; }
21
+ td { padding: 3px; }
22
+ </style>
23
+ <base target="_self" />
24
+ </head>
25
+ <body>
26
+ <h1>Module <%= path %></h1>
27
+
28
+ <% if mixins && !mixins.empty? %>
29
+ <p>
30
+ <strong>All Included Modules:</strong><br />
31
+ <%= "&nbsp;" * 7 %><%= mixins.collect {|m| link_to_path(m) }.join(", ") %>
32
+ </p>
33
+ <% end %>
34
+
35
+ <hr />
36
+
37
+ <% if docstring %>
38
+ <div class="topdoc">
39
+ <%= formatter.render('_fulldoc') %>
40
+ </div>
41
+ <hr />
42
+ <% end %>
43
+
44
+ <% if self[:attributes] && !self[:attributes].empty? %>
45
+ <h1>Attributes</h1>
46
+ <p style="line-height:20px">
47
+ <% self[:attributes].sort.each do |name, rw| %>
48
+ <tt><%= name %> [<%= [(rw[:read] ? "R" : nil), (rw[:write] ? "W" : nil)].compact.join(", ") %>]</tt><br />
49
+ <% end %>
50
+ </p>
51
+ <% end %>
52
+
53
+ <% displayed_constants = false %>
54
+ <% if constants && !constants.empty? %>
55
+ <h1>Constants</h1><% displayed_constants = true %>
56
+ <dl>
57
+ <% constants.each do |name, constant| %>
58
+ <dt id="const-<%= name %>"><pre><%= constant.full_source.gsub(/\s+/,' ') %></pre></dt>
59
+ <dd><%= to_html constant.docstring %></dd>
60
+ <% end %>
61
+ </dl>
62
+ <% end %>
63
+
64
+ <% if method = instance_methods['initialize'] %>
65
+ <h1>Constructor Summary</h1>
66
+ <tt>
67
+ <%= method.source.gsub(/\Adef\s+/, '') %>
68
+ <% unless method.tags("yieldparam").empty? %>
69
+ {|<%= method.tags("yieldparam").collect {|t| t.name }.join(", ") %>| ... }
70
+ <% end %>
71
+ </tt>
72
+ <%= method.to_s(format, template) %>
73
+ <% end %>
74
+
75
+ <% if method = instance_methods['method_missing'] %>
76
+ <h1>Dynamic Method Handling</h1>
77
+ <p><em>This class handles dynamic methods through the <tt>method_missing</tt> method</em></p>
78
+ <%= method.to_s(format, template) %>
79
+ <% end %>
80
+
81
+ <% displayed_public_meth_summary = false %>
82
+ <% CodeObject::SCOPES.each do |scope| %>
83
+ <% unless eval("_#{scope}_methods").empty? %>
84
+ <% displayed_public_meth_summary = true %>
85
+ <h1>Public <%= scope.to_s.capitalize %> Method Summary</h1>
86
+ <table border="1" width="100%">
87
+ <% eval("_#{scope}_methods").each do |name, method| %>
88
+ <tr>
89
+ <td width="70" align="right" valign="top">
90
+ <small>
91
+ <% if method.tag("return") && method.tag("return").types %>
92
+ <%= method.tag("return").types.collect {|t| link_to_path(t) }.join(", ") %>
93
+ <% else %>
94
+ <%= ClassObject::BASE_OBJECT %>
95
+ <% end %>
96
+ </small>
97
+ </td>
98
+ <td>
99
+ <tt>
100
+ <%= method.source.sub(/\Adef\s+\S+?(\(|\s|;|$)/, link_to_path(method.path, nil, method.name) + '\1') if method.source %>
101
+ <% unless method.tags("yieldparam").empty? %>
102
+ {|<%= method.tags("yieldparam").collect {|t| t.name }.join(", ") %>| ... }
103
+ <% end %>
104
+ </tt><br />
105
+ <%= ("&nbsp;" * 5) + to_html(method.docstring.sub(/(\.|\n).+/m,'')) + "." if method.docstring && !method.docstring.empty? %>
106
+ <% if method.tag("deprecated") %>
107
+ <br /><strong>Deprecated.</strong> <em><%= method.tag("deprecated").text %></em>
108
+ <% end %>
109
+ </td>
110
+ </tr>
111
+ <% end %>
112
+ </table>
113
+ <% end %>
114
+ <% end %>
115
+
116
+ <% CodeObject::SCOPES.each do |scope| %>
117
+ <% unless eval("_#{scope}_methods").empty? %>
118
+ <h1>Public <%= scope.to_s.capitalize %> Method Details</h1>
119
+ <% eval("_#{scope}_methods").each do |name, method| %>
120
+ <%= method.to_s(format, template) %>
121
+ <hr />
122
+ <% end %>
123
+ <% end %>
124
+ <% end %>
125
+ </body>
126
+ </html>