yard 0.6.1 → 0.6.2

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.

Files changed (93) hide show
  1. data/ChangeLog +356 -0
  2. data/README.md +27 -5
  3. data/docs/GettingStarted.md +45 -6
  4. data/docs/Tags.md +16 -5
  5. data/docs/WhatsNew.md +60 -2
  6. data/lib/yard.rb +16 -37
  7. data/lib/yard/autoload.rb +5 -0
  8. data/lib/yard/cli/command.rb +18 -6
  9. data/lib/yard/cli/command_parser.rb +1 -0
  10. data/lib/yard/cli/config.rb +113 -0
  11. data/lib/yard/cli/gems.rb +16 -7
  12. data/lib/yard/cli/server.rb +30 -8
  13. data/lib/yard/cli/stats.rb +1 -1
  14. data/lib/yard/cli/yardoc.rb +16 -1
  15. data/lib/yard/code_objects/base.rb +7 -2
  16. data/lib/yard/code_objects/class_object.rb +1 -0
  17. data/lib/yard/code_objects/method_object.rb +1 -0
  18. data/lib/yard/code_objects/proxy.rb +8 -2
  19. data/lib/yard/config.rb +225 -0
  20. data/lib/yard/handlers/base.rb +29 -2
  21. data/lib/yard/handlers/processor.rb +1 -1
  22. data/lib/yard/handlers/ruby/class_handler.rb +6 -1
  23. data/lib/yard/handlers/ruby/constant_handler.rb +13 -15
  24. data/lib/yard/handlers/ruby/exception_handler.rb +1 -1
  25. data/lib/yard/handlers/ruby/extend_handler.rb +3 -0
  26. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +1 -0
  27. data/lib/yard/handlers/ruby/legacy/class_handler.rb +7 -1
  28. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +8 -10
  29. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +1 -1
  30. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +3 -0
  31. data/lib/yard/handlers/ruby/legacy/method_handler.rb +1 -0
  32. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +13 -2
  33. data/lib/yard/handlers/ruby/method_handler.rb +1 -0
  34. data/lib/yard/handlers/ruby/mixin_handler.rb +14 -4
  35. data/lib/yard/handlers/ruby/struct_handler_methods.rb +10 -1
  36. data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
  37. data/lib/yard/parser/c_parser.rb +26 -11
  38. data/lib/yard/parser/ruby/legacy/statement_list.rb +26 -9
  39. data/lib/yard/parser/source_parser.rb +5 -2
  40. data/lib/yard/serializers/yardoc_serializer.rb +2 -2
  41. data/lib/yard/server.rb +11 -0
  42. data/lib/yard/server/commands/frames_command.rb +1 -1
  43. data/lib/yard/server/commands/library_command.rb +22 -13
  44. data/lib/yard/server/commands/library_index_command.rb +1 -0
  45. data/lib/yard/server/commands/search_command.rb +2 -0
  46. data/lib/yard/server/commands/static_file_command.rb +6 -1
  47. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +3 -3
  48. data/lib/yard/templates/helpers/html_helper.rb +1 -1
  49. data/lib/yard/templates/helpers/markup_helper.rb +13 -12
  50. data/lib/yard/verifier.rb +3 -1
  51. data/spec/cli/config_spec.rb +72 -0
  52. data/spec/cli/gems_spec.rb +81 -0
  53. data/spec/cli/server_spec.rb +35 -5
  54. data/spec/cli/stats_spec.rb +15 -0
  55. data/spec/cli/yardoc_spec.rb +39 -1
  56. data/spec/code_objects/base_spec.rb +2 -0
  57. data/spec/code_objects/method_object_spec.rb +5 -0
  58. data/spec/code_objects/proxy_spec.rb +20 -5
  59. data/spec/config_spec.rb +165 -0
  60. data/spec/handlers/alias_handler_spec.rb +7 -0
  61. data/spec/handlers/base_spec.rb +64 -0
  62. data/spec/handlers/class_condition_handler_spec.rb +13 -8
  63. data/spec/handlers/class_handler_spec.rb +54 -46
  64. data/spec/handlers/constant_handler_spec.rb +13 -0
  65. data/spec/handlers/examples/alias_handler_001.rb.txt +2 -0
  66. data/spec/handlers/examples/class_handler_001.rb.txt +12 -1
  67. data/spec/handlers/examples/constant_handler_001.rb.txt +6 -0
  68. data/spec/handlers/examples/exception_handler_001.rb.txt +8 -0
  69. data/spec/handlers/examples/method_handler_001.rb.txt +6 -0
  70. data/spec/handlers/examples/visibility_handler_001.rb.txt +3 -0
  71. data/spec/handlers/exception_handler_spec.rb +5 -0
  72. data/spec/handlers/extend_handler_spec.rb +4 -0
  73. data/spec/handlers/method_handler_spec.rb +5 -0
  74. data/spec/handlers/mixin_handler_spec.rb +10 -0
  75. data/spec/handlers/visibility_handler_spec.rb +4 -0
  76. data/spec/parser/base_spec.rb +1 -1
  77. data/spec/parser/c_parser_spec.rb +39 -1
  78. data/spec/parser/examples/override.c.txt +424 -0
  79. data/spec/parser/ruby/legacy/statement_list_spec.rb +11 -0
  80. data/spec/parser/source_parser_spec.rb +33 -1
  81. data/spec/server/commands/static_file_command_spec.rb +20 -3
  82. data/spec/server_spec.rb +10 -0
  83. data/spec/templates/examples/method001.html +33 -3
  84. data/spec/templates/examples/method001.txt +8 -1
  85. data/spec/templates/helpers/markup_helper_spec.rb +21 -26
  86. data/spec/templates/method_spec.rb +3 -1
  87. data/spec/verifier_spec.rb +5 -0
  88. data/templates/default/fulldoc/html/css/style.css +4 -1
  89. data/templates/default/fulldoc/html/js/app.js +1 -1
  90. data/templates/default/tags/html/option.erb +1 -3
  91. data/templates/default/tags/setup.rb +18 -15
  92. metadata +11 -4
  93. data/spec/yard_spec.rb +0 -55
@@ -115,7 +115,7 @@ module YARD
115
115
  Base.subclasses.find_all do |handler|
116
116
  handler_base_class > handler &&
117
117
  (handler.namespace_only? ? owner.is_a?(CodeObjects::NamespaceObject) : true) &&
118
- handler.handles?(statement)
118
+ handler.matches_file?(file) && handler.handles?(statement)
119
119
  end
120
120
  end
121
121
 
@@ -18,7 +18,11 @@ class YARD::Handlers::Ruby::ClassHandler < YARD::Handlers::Ruby::Base
18
18
  o.superclass = superclass if superclass
19
19
  o.superclass.type = :class if o.superclass.is_a?(Proxy)
20
20
  end
21
- parse_struct_superclass(klass, statement[1]) if is_a_struct
21
+ if is_a_struct
22
+ parse_struct_superclass(klass, statement[1])
23
+ elsif klass
24
+ create_attributes(klass, members_from_tags(klass))
25
+ end
22
26
  parse_block(statement[2], namespace: klass)
23
27
 
24
28
  if undocsuper
@@ -96,6 +100,7 @@ class YARD::Handlers::Ruby::ClassHandler < YARD::Handlers::Ruby::Base
96
100
 
97
101
  case superclass.type
98
102
  when :var_ref
103
+ return namespace.path if superclass.first == s(:kw, "self")
99
104
  return superclass.source if superclass.first.type == :const
100
105
  when :const, :const_ref, :const_path_ref, :top_const_ref
101
106
  return superclass.source
@@ -1,5 +1,6 @@
1
1
  # Handles any constant assignment
2
2
  class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
3
+ include YARD::Handlers::Ruby::StructHandlerMethods
3
4
  namespace_only
4
5
  handles :assign
5
6
 
@@ -23,25 +24,22 @@ class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
23
24
  def process_structclass(statement)
24
25
  lhs = statement[0][0]
25
26
  if lhs.type == :const
26
- klass = register ClassObject.new(namespace, lhs[0])
27
- klass.superclass = P(:Struct)
28
- parse_attributes(klass, statement[1].parameters)
27
+ klass = create_class(lhs[0], P(:Struct))
28
+ create_attributes(klass, extract_parameters(statement[1]))
29
29
  else
30
30
  raise YARD::Parser::UndocumentableError, "Struct assignment to #{statement[0].source}"
31
31
  end
32
32
  end
33
33
 
34
- def parse_attributes(klass, attributes)
35
- return unless attributes
36
-
37
- scope = :instance
38
- attributes.each do |node|
39
- next if !node.respond_to?(:type) || node.type != :symbol_literal
40
- name = node.jump(:ident).source
41
- klass.attributes[scope][name] = SymbolHash[:read => nil, :write => nil]
42
- {read: name, write: "#{name}="}.each do |type, meth|
43
- klass.attributes[scope][name][type] = register MethodObject.new(klass, meth, scope)
44
- end
45
- end
34
+ # Extract the parameters from the Struct.new AST node, returning them as a list
35
+ # of strings
36
+ #
37
+ # @param [MethodCallNode] superclass the AST node for the Struct.new call
38
+ # @return [Array<String>] the member names to generate methods for
39
+ def extract_parameters(superclass)
40
+ return [] unless superclass.parameters
41
+ members = superclass.parameters.select {|x| x && x.type == :symbol_literal}
42
+ members.map! {|x| x.source.strip[1..-1]}
43
+ members
46
44
  end
47
45
  end
@@ -15,7 +15,7 @@ class YARD::Handlers::Ruby::ExceptionHandler < YARD::Handlers::Ruby::Base
15
15
  elsif params.first.call? && params.first.method_name(true) == :new
16
16
  klass = params.first.namespace.source
17
17
  end
18
- else
18
+ elsif params.size > 1
19
19
  klass = params.first.source
20
20
  end
21
21
 
@@ -10,6 +10,9 @@ class YARD::Handlers::Ruby::ExtendHandler < YARD::Handlers::Ruby::MixinHandler
10
10
 
11
11
  def process_mixin(mixin)
12
12
  if mixin == s(:var_ref, s(:kw, "self"))
13
+ if namespace.is_a?(ClassObject)
14
+ raise UndocumentableError, "extend(self) statement on class"
15
+ end
13
16
  namespace.mixins(scope) << namespace
14
17
  else
15
18
  super
@@ -70,6 +70,7 @@ class YARD::Handlers::Ruby::Legacy::ClassConditionHandler < YARD::Handlers::Ruby
70
70
 
71
71
  # @since 0.5.5
72
72
  def parse_else_block
73
+ return unless statement.block
73
74
  stmtlist = YARD::Parser::Ruby::Legacy::StatementList
74
75
  stmtlist.new(statement.block).each do |stmt|
75
76
  if TkELSE === stmt.tokens.first
@@ -19,7 +19,11 @@ class YARD::Handlers::Ruby::Legacy::ClassHandler < YARD::Handlers::Ruby::Legacy:
19
19
  o.superclass = superclass if superclass
20
20
  o.superclass.type = :class if o.superclass.is_a?(Proxy)
21
21
  end
22
- parse_struct_subclass(klass, superclass_def) if is_a_struct
22
+ if is_a_struct
23
+ parse_struct_subclass(klass, superclass_def)
24
+ elsif klass
25
+ create_attributes(klass, members_from_tags(klass))
26
+ end
23
27
  parse_block(:namespace => klass)
24
28
 
25
29
  if undocsuper
@@ -98,6 +102,8 @@ class YARD::Handlers::Ruby::Legacy::ClassHandler < YARD::Handlers::Ruby::Legacy:
98
102
  /\ADelegateClass\((.+?)\)\s*\Z/,
99
103
  /\A(#{NAMESPACEMATCH})\(/
100
104
  $1
105
+ when "self"
106
+ namespace.path
101
107
  end
102
108
  end
103
109
  end
@@ -1,5 +1,6 @@
1
1
  # (see Ruby::ConstantHandler)
2
2
  class YARD::Handlers::Ruby::Legacy::ConstantHandler < YARD::Handlers::Ruby::Legacy::Base
3
+ include YARD::Handlers::Ruby::StructHandlerMethods
3
4
  HANDLER_MATCH = /\A[A-Z]\w*\s*=[^=]\s*/m
4
5
  handles HANDLER_MATCH
5
6
 
@@ -19,15 +20,12 @@ class YARD::Handlers::Ruby::Legacy::ConstantHandler < YARD::Handlers::Ruby::Lega
19
20
  private
20
21
 
21
22
  def process_structclass(classname, parameters)
22
- scope = :instance
23
- klass = register ClassObject.new(namespace, classname)
24
- klass.superclass = P(:Struct)
25
-
26
- tokval_list(YARD::Parser::Ruby::Legacy::TokenList.new(parameters), TkSYMBOL).each do |name|
27
- klass.attributes[scope][name] = SymbolHash[:read => nil, :write => nil]
28
- {:read => name, :write => "#{name}="}.each do |type, meth|
29
- klass.attributes[scope][name][type] = register MethodObject.new(klass, meth, scope)
30
- end
31
- end
23
+ klass = create_class(classname, P(:Struct))
24
+ create_attributes(klass, extract_parameters(parameters))
25
+ end
26
+
27
+ def extract_parameters(parameters)
28
+ members = tokval_list(YARD::Parser::Ruby::Legacy::TokenList.new(parameters), TkSYMBOL)
29
+ members.map {|m| m.to_s }
32
30
  end
33
31
  end
@@ -6,7 +6,7 @@ class YARD::Handlers::Ruby::Legacy::ExceptionHandler < YARD::Handlers::Ruby::Leg
6
6
  return unless owner.is_a?(MethodObject) # Only methods yield
7
7
  return if owner.has_tag?(:raise)
8
8
 
9
- if klass = statement.tokens.to_s[/^raise[\(\s]*(#{NAMESPACEMATCH})(?:\)|,|\s|(?:\s*(?:\.|\:\:)\s*)?new|$)/, 1]
9
+ if klass = statement.tokens.to_s[/^raise[\(\s]*(#{NAMESPACEMATCH})\s*(?:\)|,|\s(?:if|unless|until)|;|(?:(?:\.|\:\:)\s*)?new|$)/, 1]
10
10
  owner.docstring.add_tag YARD::Tags::Tag.new(:raise, '', klass)
11
11
  end
12
12
  end
@@ -8,6 +8,9 @@ class YARD::Handlers::Ruby::Legacy::ExtendHandler < YARD::Handlers::Ruby::Legacy
8
8
 
9
9
  def process_mixin(mixin)
10
10
  if mixin == "self"
11
+ if namespace.is_a?(ClassObject)
12
+ raise UndocumentableError, "extend(self) statement on class"
13
+ end
11
14
  namespace.mixins(scope) << namespace
12
15
  else
13
16
  super
@@ -24,6 +24,7 @@ class YARD::Handlers::Ruby::Legacy::MethodHandler < YARD::Handlers::Ruby::Legacy
24
24
  nobj = P(namespace, prefix) unless prefix == "self"
25
25
  end
26
26
 
27
+ nobj = P(namespace, nobj.value) while nobj.type == :constant
27
28
  obj = register MethodObject.new(nobj, meth, mscope) do |o|
28
29
  o.visibility = visibility
29
30
  o.source = statement
@@ -3,8 +3,19 @@ class YARD::Handlers::Ruby::Legacy::MixinHandler < YARD::Handlers::Ruby::Legacy:
3
3
  handles /\Ainclude(\s|\()/
4
4
 
5
5
  process do
6
+ errors = []
6
7
  statement.tokens[1..-1].to_s.split(/\s*,\s*/).each do |mixin|
7
- process_mixin(mixin.strip)
8
+ mixin = mixin.strip
9
+ begin
10
+ process_mixin(mixin)
11
+ rescue YARD::Parser::UndocumentableError => err
12
+ errors << err.message
13
+ end
14
+ end
15
+
16
+ if errors.size > 0
17
+ msg = errors.size == 1 ? ": #{errors[0]}" : "s: #{errors.join(", ")}"
18
+ raise YARD::Parser::UndocumentableError, "mixin#{msg} for class #{namespace.path}"
8
19
  end
9
20
  end
10
21
 
@@ -12,7 +23,7 @@ class YARD::Handlers::Ruby::Legacy::MixinHandler < YARD::Handlers::Ruby::Legacy:
12
23
 
13
24
  def process_mixin(mixin)
14
25
  unless mixmatch = mixin[/\A(#{NAMESPACEMATCH})/, 1]
15
- raise YARD::Parser::UndocumentableError, "mixin #{mixin} for class #{namespace.path}"
26
+ raise YARD::Parser::UndocumentableError
16
27
  end
17
28
 
18
29
  obj = Proxy.new(namespace, mixmatch)
@@ -20,6 +20,7 @@ class YARD::Handlers::Ruby::MethodHandler < YARD::Handlers::Ruby::Base
20
20
  blk = statement[2]
21
21
  end
22
22
 
23
+ nobj = P(namespace, nobj.value) while nobj.type == :constant
23
24
  obj = register MethodObject.new(nobj, meth, mscope) do |o|
24
25
  o.visibility = visibility
25
26
  o.source = statement.source
@@ -4,15 +4,25 @@ class YARD::Handlers::Ruby::MixinHandler < YARD::Handlers::Ruby::Base
4
4
  handles method_call(:include)
5
5
 
6
6
  process do
7
- statement.parameters(false).each {|mixin| process_mixin(mixin) }
7
+ errors = []
8
+ statement.parameters(false).each do |mixin|
9
+ begin
10
+ process_mixin(mixin)
11
+ rescue YARD::Parser::UndocumentableError => err
12
+ errors << err.message
13
+ end
14
+ end
15
+ if errors.size > 0
16
+ msg = errors.size == 1 ? ": #{errors[0]}" : "s: #{errors.join(", ")}"
17
+ raise YARD::Parser::UndocumentableError, "mixin#{msg} for class #{namespace.path}"
18
+ end
8
19
  end
9
20
 
10
21
  protected
11
22
 
12
23
  def process_mixin(mixin)
13
- unless mixin.ref?
14
- raise YARD::Parser::UndocumentableError, "mixin #{mixin.source} for class #{namespace.path}"
15
- end
24
+ raise YARD::Parser::UndocumentableError unless mixin.ref?
25
+ raise YARD::Parser::UndocumentableError if mixin.first.type == :ident
16
26
 
17
27
  case obj = Proxy.new(namespace, mixin.source)
18
28
  when Proxy
@@ -1,4 +1,4 @@
1
- # Helper methods to parse @attr_* tags on a Struct class.
1
+ # Helper methods to parse @attr_* tags on a class.
2
2
  #
3
3
  # @since 0.5.6
4
4
  module YARD::Handlers::Ruby::StructHandlerMethods
@@ -15,6 +15,15 @@ module YARD::Handlers::Ruby::StructHandlerMethods
15
15
  specific_tag = type == :read ? :attr_reader : :attr_writer
16
16
  (klass.tags(specific_tag) + klass.tags(:attr)).find {|tag| tag.name == member}
17
17
  end
18
+
19
+ # Retrieves all members defined in @attr* tags
20
+ #
21
+ # @param [ClassObject] klass the class with the attributes
22
+ # @return [Array<String>] the list of members defined as attributes on the class
23
+ def members_from_tags(klass)
24
+ tags = klass.tags(:attr) + klass.tags(:attr_reader) + klass.tags(:attr_writer)
25
+ tags.map {|t| t.name }.uniq
26
+ end
18
27
 
19
28
  # Determines whether to create an attribute method based on the class's
20
29
  # tags.
@@ -13,7 +13,7 @@ class YARD::Handlers::Ruby::VisibilityHandler < YARD::Handlers::Ruby::Base
13
13
  when :fcall, :command
14
14
  statement[1].traverse do |node|
15
15
  case node.type
16
- when :symbol; source = node.jump(:ident).last
16
+ when :symbol; source = node.first.source
17
17
  when :string_content; source = node.source
18
18
  else next
19
19
  end
@@ -15,6 +15,7 @@ module YARD
15
15
  parse_modules
16
16
  parse_classes
17
17
  parse_methods
18
+ parse_constants
18
19
  parse_includes
19
20
  end
20
21
 
@@ -32,10 +33,10 @@ module YARD
32
33
 
33
34
  def ensure_loaded!(object, max_retries = 1)
34
35
  return if object.is_a?(CodeObjects::RootObject)
35
- if RUBY_PLATFORM =~ /java/ || defined?(::Rubinius)
36
+ unless CONTINUATIONS_SUPPORTED
36
37
  unless $NO_CONTINUATION_WARNING
37
38
  $NO_CONTINUATION_WARNING = true
38
- log.warn "JRuby/Rubinius do not implement Kernel#callcc and cannot " +
39
+ log.warn "JRuby/MacRuby/Rubinius do not implement Kernel#callcc and cannot " +
39
40
  "load files in order. You must specify the correct order manually."
40
41
  end
41
42
  raise NamespaceMissingError, object
@@ -94,7 +95,10 @@ module YARD
94
95
  def handle_constants(type, var_name, const_name, definition)
95
96
  namespace = @namespaces[var_name]
96
97
  obj = CodeObjects::ConstantObject.new(namespace, const_name)
97
- comment = find_constant_docstring(type, const_name)
98
+ obj.value = definition
99
+ obj.add_file(@file)
100
+ obj.source_type = :c
101
+ comment = find_constant_docstring(obj, type, const_name)
98
102
 
99
103
  # In the case of rb_define_const, the definition and comment are in
100
104
  # "/* definition: comment */" form. The literal ':' and '\' characters
@@ -126,8 +130,8 @@ module YARD
126
130
  object.docstring = parse_comments(object, comment) if comment
127
131
  end
128
132
 
129
- def find_constant_docstring(type, const_name)
130
- comments = if @content =~ %r{((?>^\s*/\*.*?\*/\s+))
133
+ def find_constant_docstring(object, type, const_name)
134
+ comment = if @content =~ %r{((?>^\s*/\*.*?\*/\s+))
131
135
  rb_define_#{type}\((?:\s*(\w+),)?\s*"#{const_name}"\s*,.*?\)\s*;}xmi
132
136
  $1
133
137
  elsif @content =~ %r{Document-(?:const|global|variable):\s#{const_name}\s*?\n((?>.*?\*/))}m
@@ -135,7 +139,7 @@ module YARD
135
139
  else
136
140
  ''
137
141
  end
138
- parse_comments(object, comments)
142
+ object.docstring = parse_comments(object, comment) if comment
139
143
  end
140
144
 
141
145
  def find_method_body(object, func_name, content = @content)
@@ -158,8 +162,8 @@ module YARD
158
162
  # distinct (for example Kernel.hash and Kernel.object_id share the same
159
163
  # implementation
160
164
 
161
- # override_comment = find_override_comment(object)
162
- # comment = override_comment if override_comment
165
+ override_comment = find_override_comment(object)
166
+ comment = override_comment if override_comment
163
167
 
164
168
  object.docstring = parse_comments(object, comment) if comment
165
169
  object.source = body_text
@@ -168,11 +172,22 @@ module YARD
168
172
  find_method_body(object, $2, content)
169
173
  else
170
174
  # No body, but might still have an override comment
171
- # comment = find_override_comment(object)
172
- comment = nil
175
+ comment = find_override_comment(object)
173
176
  object.docstring = parse_comments(object, comment) if comment
174
177
  end
175
178
  end
179
+
180
+ def find_override_comment(object, content = @content)
181
+ name = Regexp.escape(object.name.to_s)
182
+ class_name = object.parent.path
183
+ if content =~ %r{Document-method:\s+#{class_name}(?:\.|::|#)#{name}\s*?\n((?>.*?\*/))}m then
184
+ $1
185
+ elsif content =~ %r{Document-method:\s#{name}\s*?\n((?>.*?\*/))}m then
186
+ $1
187
+ else
188
+ nil
189
+ end
190
+ end
176
191
 
177
192
  def parse_comments(object, comments)
178
193
  spaces = nil
@@ -406,4 +421,4 @@ module YARD
406
421
  end
407
422
  end
408
423
  end
409
- end
424
+ end
@@ -42,7 +42,7 @@ module YARD
42
42
  @current_block = nil
43
43
  @comments_line = nil
44
44
  @statement, @block, @comments = TokenList.new, nil, nil
45
- @last_tk, @last_ns_tk, @before_last_tk = nil, nil, nil
45
+ @last_tk, @last_ns_tk, @before_last_tk, @before_last_ns_tk = nil, nil, nil, nil
46
46
  @first_line = nil
47
47
 
48
48
  while !@done && tk = @tokens.shift
@@ -50,6 +50,7 @@ module YARD
50
50
 
51
51
  @before_last_tk = @last_tk
52
52
  @last_tk = tk # Save last token
53
+ @before_last_ns_tk = @last_ns_tk
53
54
  @last_ns_tk = tk unless [TkSPACE, TkNL, TkEND_OF_SCRIPT].include? tk.class
54
55
  end
55
56
 
@@ -130,6 +131,12 @@ module YARD
130
131
  return if process_initial_comment(tk)
131
132
  return if @statement.empty? && [TkSPACE, TkNL, TkCOMMENT].include?(tk.class)
132
133
  @comments_last_line = nil
134
+ if @statement.empty? && tk.class == TkALIAS
135
+ @state = :alias_statement
136
+ @alias_values = []
137
+ push_token(tk)
138
+ return
139
+ end
133
140
  return if process_simple_block_opener(tk)
134
141
  push_token(tk)
135
142
  return if process_complex_block_opener(tk)
@@ -139,6 +146,15 @@ module YARD
139
146
  else
140
147
  @state = :balance
141
148
  end
149
+ when :alias_statement
150
+ push_token(tk)
151
+ @alias_values << tk unless [TkSPACE, TkNL, TkCOMMENT].include?(tk.class)
152
+ if @alias_values.size == 2
153
+ @state = :first_statement
154
+ if [NilClass, TkNL, TkEND_OF_SCRIPT, TkSEMICOLON].include?(peek_no_space.class)
155
+ @done = true
156
+ end
157
+ end
142
158
  when :balance
143
159
  @statement << tk
144
160
  return unless balances?(tk)
@@ -251,7 +267,6 @@ module YARD
251
267
  # @param [RubyToken::Token] tk the token to process
252
268
  def process_complex_block_opener(tk)
253
269
  return unless OPEN_BLOCK_TOKENS.include?(tk.class)
254
- return if @last_ns_tk.class == TkALIAS
255
270
 
256
271
  @current_block = tk.class
257
272
  @state = :block_statement
@@ -265,7 +280,7 @@ module YARD
265
280
  def process_statement_end(tk)
266
281
  # Whitespace means that we keep the same value of @new_statement as last token
267
282
  return if tk.class == TkSPACE
268
-
283
+
269
284
  return unless
270
285
  # We might be coming after a statement-ending token...
271
286
  ((@last_tk && [TkSEMICOLON, TkNL, TkEND_OF_SCRIPT].include?(tk.class)) ||
@@ -318,12 +333,14 @@ module YARD
318
333
  # @return [Boolean] whether or not the current statement's parentheses and blocks
319
334
  # are balanced after +tk+
320
335
  def balances?(tk)
321
- if [TkLPAREN, TkLBRACK, TkLBRACE, TkDO, TkBEGIN].include?(tk.class)
322
- @level += 1
323
- elsif OPEN_BLOCK_TOKENS.include?(tk.class)
324
- @level += 1 unless @last_ns_tk.class == TkALIAS || tk.class == TkELSIF
325
- elsif [TkRPAREN, TkRBRACK, TkRBRACE, TkEND].include?(tk.class) && @level > 0
326
- @level -= 1
336
+ unless @last_ns_tk.class == TkALIAS || @before_last_ns_tk.class == TkALIAS
337
+ if [TkLPAREN, TkLBRACK, TkLBRACE, TkDO, TkBEGIN].include?(tk.class)
338
+ @level += 1
339
+ elsif OPEN_BLOCK_TOKENS.include?(tk.class)
340
+ @level += 1 unless tk.class == TkELSIF
341
+ elsif [TkRPAREN, TkRBRACK, TkRBRACE, TkEND].include?(tk.class) && @level > 0
342
+ @level -= 1
343
+ end
327
344
  end
328
345
 
329
346
  @level == 0