yard 0.2.2 → 0.2.3

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 (204) hide show
  1. data/LICENSE +1 -1
  2. data/README.markdown +200 -0
  3. data/Rakefile +6 -1
  4. data/benchmarks/format_args.rb +46 -0
  5. data/benchmarks/parsing.rb +13 -1
  6. data/benchmarks/rdoc_vs_yardoc.rb +10 -0
  7. data/benchmarks/ripper_parser.rb +12 -0
  8. data/docs/CODE_OBJECTS.markdown +121 -0
  9. data/docs/FAQ.markdown +34 -0
  10. data/docs/GENERATORS.markdown +211 -0
  11. data/docs/GETTING_STARTED.markdown +263 -0
  12. data/docs/GLOSSARY.markdown +13 -0
  13. data/docs/HANDLERS.markdown +158 -0
  14. data/docs/OVERVIEW.markdown +64 -0
  15. data/docs/PARSER.markdown +180 -0
  16. data/docs/TAGS.markdown +181 -0
  17. data/docs/WHATSNEW.markdown +96 -0
  18. data/docs/images/code-objects-class-diagram.png +0 -0
  19. data/docs/images/handlers-class-diagram.png +0 -0
  20. data/docs/images/overview-class-diagram.png +0 -0
  21. data/docs/images/parser-class-diagram.png +0 -0
  22. data/docs/images/tags-class-diagram.png +0 -0
  23. data/lib/yard.rb +4 -1
  24. data/lib/yard/autoload.rb +79 -31
  25. data/lib/yard/cli/yard_graph.rb +8 -2
  26. data/lib/yard/cli/yardoc.rb +61 -8
  27. data/lib/yard/code_objects/base.rb +78 -135
  28. data/lib/yard/code_objects/class_object.rb +9 -8
  29. data/lib/yard/code_objects/constant_object.rb +1 -0
  30. data/lib/yard/code_objects/extended_method_object.rb +9 -0
  31. data/lib/yard/code_objects/method_object.rb +18 -5
  32. data/lib/yard/code_objects/module_object.rb +8 -1
  33. data/lib/yard/code_objects/namespace_object.rb +25 -16
  34. data/lib/yard/code_objects/proxy.rb +22 -22
  35. data/lib/yard/core_ext/file.rb +1 -1
  36. data/lib/yard/core_ext/string.rb +0 -4
  37. data/lib/yard/core_ext/symbol_hash.rb +3 -2
  38. data/lib/yard/docstring.rb +180 -0
  39. data/lib/yard/generators/base.rb +33 -13
  40. data/lib/yard/generators/class_generator.rb +4 -2
  41. data/lib/yard/generators/constants_generator.rb +3 -2
  42. data/lib/yard/generators/full_doc_generator.rb +76 -9
  43. data/lib/yard/generators/helpers/base_helper.rb +18 -1
  44. data/lib/yard/generators/helpers/filter_helper.rb +2 -2
  45. data/lib/yard/generators/helpers/html_helper.rb +94 -39
  46. data/lib/yard/generators/helpers/html_syntax_highlight_helper.rb +49 -0
  47. data/lib/yard/generators/helpers/markup_helper.rb +86 -0
  48. data/lib/yard/generators/helpers/method_helper.rb +23 -7
  49. data/lib/yard/generators/method_generator.rb +15 -3
  50. data/lib/yard/generators/method_listing_generator.rb +3 -3
  51. data/lib/yard/generators/mixins_generator.rb +8 -2
  52. data/lib/yard/generators/module_generator.rb +3 -2
  53. data/lib/yard/generators/overloads_generator.rb +20 -0
  54. data/lib/yard/generators/quick_doc_generator.rb +3 -9
  55. data/lib/yard/generators/root_generator.rb +32 -0
  56. data/lib/yard/generators/source_generator.rb +2 -17
  57. data/lib/yard/generators/tags_generator.rb +34 -6
  58. data/lib/yard/generators/uml_generator.rb +16 -6
  59. data/lib/yard/handlers/base.rb +88 -253
  60. data/lib/yard/handlers/processor.rb +72 -0
  61. data/lib/yard/handlers/ruby/alias_handler.rb +38 -0
  62. data/lib/yard/handlers/ruby/attribute_handler.rb +69 -0
  63. data/lib/yard/handlers/ruby/base.rb +72 -0
  64. data/lib/yard/handlers/ruby/class_condition_handler.rb +70 -0
  65. data/lib/yard/handlers/ruby/class_handler.rb +74 -0
  66. data/lib/yard/handlers/ruby/class_variable_handler.rb +11 -0
  67. data/lib/yard/handlers/ruby/constant_handler.rb +12 -0
  68. data/lib/yard/handlers/ruby/exception_handler.rb +22 -0
  69. data/lib/yard/handlers/ruby/extend_handler.rb +19 -0
  70. data/lib/yard/handlers/{alias_handler.rb → ruby/legacy/alias_handler.rb} +3 -4
  71. data/lib/yard/handlers/{attribute_handler.rb → ruby/legacy/attribute_handler.rb} +2 -2
  72. data/lib/yard/handlers/ruby/legacy/base.rb +198 -0
  73. data/lib/yard/handlers/{class_handler.rb → ruby/legacy/class_handler.rb} +18 -6
  74. data/lib/yard/handlers/{class_variable_handler.rb → ruby/legacy/class_variable_handler.rb} +1 -1
  75. data/lib/yard/handlers/{constant_handler.rb → ruby/legacy/constant_handler.rb} +2 -2
  76. data/lib/yard/handlers/{exception_handler.rb → ruby/legacy/exception_handler.rb} +3 -3
  77. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +18 -0
  78. data/lib/yard/handlers/ruby/legacy/method_handler.rb +31 -0
  79. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +28 -0
  80. data/lib/yard/handlers/{module_handler.rb → ruby/legacy/module_handler.rb} +1 -1
  81. data/lib/yard/handlers/{visibility_handler.rb → ruby/legacy/visibility_handler.rb} +1 -1
  82. data/lib/yard/handlers/{yield_handler.rb → ruby/legacy/yield_handler.rb} +4 -4
  83. data/lib/yard/handlers/ruby/method_condition_handler.rb +7 -0
  84. data/lib/yard/handlers/ruby/method_handler.rb +48 -0
  85. data/lib/yard/handlers/ruby/mixin_handler.rb +25 -0
  86. data/lib/yard/handlers/ruby/module_handler.rb +9 -0
  87. data/lib/yard/handlers/ruby/visibility_handler.rb +18 -0
  88. data/lib/yard/handlers/ruby/yield_handler.rb +28 -0
  89. data/lib/yard/parser/ruby/ast_node.rb +263 -0
  90. data/lib/yard/parser/{ruby_lex.rb → ruby/legacy/ruby_lex.rb} +258 -259
  91. data/lib/yard/parser/{statement.rb → ruby/legacy/statement.rb} +8 -4
  92. data/lib/yard/parser/ruby/legacy/statement_list.rb +262 -0
  93. data/lib/yard/parser/{token_list.rb → ruby/legacy/token_list.rb} +1 -1
  94. data/lib/yard/parser/ruby/ruby_parser.rb +307 -0
  95. data/lib/yard/parser/source_parser.rb +76 -45
  96. data/lib/yard/rake/yardoc_task.rb +6 -1
  97. data/lib/yard/registry.rb +45 -19
  98. data/lib/yard/serializers/file_system_serializer.rb +8 -3
  99. data/lib/yard/tags/default_factory.rb +70 -10
  100. data/lib/yard/tags/default_tag.rb +12 -0
  101. data/lib/yard/tags/library.rb +65 -26
  102. data/lib/yard/tags/option_tag.rb +12 -0
  103. data/lib/yard/tags/overload_tag.rb +62 -0
  104. data/lib/yard/tags/ref_tag.rb +7 -0
  105. data/lib/yard/tags/ref_tag_list.rb +27 -0
  106. data/lib/yard/tags/tag.rb +1 -0
  107. data/lib/yard/tags/tag_format_error.rb +6 -0
  108. data/spec/cli/yardoc_spec.rb +43 -0
  109. data/spec/code_objects/base_spec.rb +56 -68
  110. data/spec/code_objects/class_object_spec.rb +18 -6
  111. data/spec/code_objects/constants_spec.rb +2 -0
  112. data/spec/code_objects/method_object_spec.rb +33 -5
  113. data/spec/code_objects/module_object_spec.rb +66 -8
  114. data/spec/code_objects/namespace_object_spec.rb +37 -17
  115. data/spec/code_objects/proxy_spec.rb +13 -2
  116. data/spec/core_ext/string_spec.rb +14 -2
  117. data/spec/core_ext/symbol_hash_spec.rb +9 -3
  118. data/spec/docstring_spec.rb +139 -0
  119. data/spec/generators/full_doc_generator_spec.rb +29 -0
  120. data/spec/generators/helpers/html_helper_spec.rb +74 -0
  121. data/spec/generators/helpers/markup_helper_spec.rb +95 -0
  122. data/spec/handlers/alias_handler_spec.rb +16 -3
  123. data/spec/handlers/attribute_handler_spec.rb +1 -1
  124. data/spec/handlers/base_spec.rb +15 -141
  125. data/spec/handlers/class_condition_handler_spec.rb +49 -0
  126. data/spec/handlers/class_handler_spec.rb +44 -3
  127. data/spec/handlers/class_variable_handler_spec.rb +1 -1
  128. data/spec/handlers/constant_handler_spec.rb +1 -1
  129. data/spec/handlers/examples/alias_handler_001.rb.txt +7 -3
  130. data/spec/handlers/examples/class_condition_handler_001.rb.txt +61 -0
  131. data/spec/handlers/examples/class_handler_001.rb.txt +33 -0
  132. data/spec/handlers/examples/exception_handler_001.rb.txt +1 -1
  133. data/spec/handlers/examples/extend_handler_001.rb.txt +8 -0
  134. data/spec/handlers/examples/method_condition_handler_001.rb.txt +10 -0
  135. data/spec/handlers/examples/method_handler_001.rb.txt +16 -4
  136. data/spec/handlers/examples/mixin_handler_001.rb.txt +10 -2
  137. data/spec/handlers/examples/module_handler_001.rb.txt +4 -0
  138. data/spec/handlers/examples/visibility_handler_001.rb.txt +1 -1
  139. data/spec/handlers/exception_handler_spec.rb +2 -2
  140. data/spec/handlers/extend_handler_spec.rb +15 -0
  141. data/spec/handlers/legacy_base_spec.rb +128 -0
  142. data/spec/handlers/method_condition_handler_spec.rb +14 -0
  143. data/spec/handlers/method_handler_spec.rb +38 -5
  144. data/spec/handlers/mixin_handler_spec.rb +15 -7
  145. data/spec/handlers/module_handler_spec.rb +5 -1
  146. data/spec/handlers/processor_spec.rb +19 -0
  147. data/spec/handlers/ruby/base_spec.rb +90 -0
  148. data/spec/handlers/ruby/legacy/base_spec.rb +53 -0
  149. data/spec/handlers/spec_helper.rb +22 -16
  150. data/spec/handlers/visibility_handler_spec.rb +4 -4
  151. data/spec/handlers/yield_handler_spec.rb +1 -1
  152. data/spec/parser/ruby/ast_node_spec.rb +15 -0
  153. data/spec/parser/ruby/legacy/statement_list_spec.rb +145 -0
  154. data/spec/parser/{token_list_spec.rb → ruby/legacy/token_list_spec.rb} +4 -4
  155. data/spec/parser/source_parser_spec.rb +0 -15
  156. data/spec/rake/yardoc_task_spec.rb +48 -0
  157. data/spec/registry_spec.rb +28 -2
  158. data/spec/serializers/file_system_serializer_spec.rb +7 -1
  159. data/spec/spec_helper.rb +1 -1
  160. data/spec/tags/default_factory_spec.rb +135 -0
  161. data/spec/tags/default_tag_spec.rb +11 -0
  162. data/spec/tags/overload_tag_spec.rb +35 -0
  163. data/spec/tags/ref_tag_list_spec.rb +53 -0
  164. data/templates/default/attributes/html/header.erb +17 -5
  165. data/templates/default/attributes/text/header.erb +1 -1
  166. data/templates/default/fulldoc/html/all_files.erb +19 -0
  167. data/templates/default/fulldoc/html/all_methods.erb +8 -7
  168. data/templates/default/fulldoc/html/all_namespaces.erb +4 -1
  169. data/templates/default/fulldoc/html/app.js +1 -1
  170. data/templates/default/fulldoc/html/{readme.erb → file.erb} +2 -2
  171. data/templates/default/fulldoc/html/header.erb +1 -1
  172. data/templates/default/fulldoc/html/index.erb +4 -3
  173. data/templates/default/fulldoc/html/style.css +13 -3
  174. data/templates/default/fulldoc/html/syntax_highlight.css +8 -5
  175. data/templates/default/method/text/header.erb +1 -0
  176. data/templates/default/method/text/title.erb +1 -0
  177. data/templates/default/methodsignature/html/main.erb +10 -8
  178. data/templates/default/methodsignature/text/main.erb +4 -1
  179. data/templates/default/methodsummary/html/summary.erb +8 -4
  180. data/templates/default/methodsummary/text/summary.erb +4 -1
  181. data/templates/default/mixins/html/header.erb +3 -3
  182. data/templates/default/overloads/html/header.erb +8 -0
  183. data/templates/default/overloads/text/header.erb +8 -0
  184. data/templates/default/root/html/header.erb +4 -0
  185. data/templates/default/tags/html/example.erb +20 -0
  186. data/templates/default/tags/html/option.erb +27 -0
  187. data/templates/default/tags/html/param.erb +21 -0
  188. data/templates/default/tags/html/tags.erb +4 -1
  189. data/templates/default/tags/html/todo.erb +8 -0
  190. data/templates/default/tags/text/example.erb +14 -0
  191. data/templates/default/tags/text/header.erb +3 -3
  192. data/templates/default/tags/text/option.erb +5 -0
  193. data/templates/default/tags/text/param.erb +9 -0
  194. data/templates/default/uml/dot/dependencies.erb +1 -1
  195. data/templates/default/uml/dot/info.erb +1 -1
  196. data/templates/default/uml/dot/superclasses.erb +2 -2
  197. data/templates/javadoc/methodsummary/html/summary.erb +2 -2
  198. data/templates/javadoc/mixins/html/header.erb +3 -3
  199. metadata +108 -139
  200. data/README +0 -211
  201. data/lib/yard/handlers/method_handler.rb +0 -27
  202. data/lib/yard/handlers/mixin_handler.rb +0 -16
  203. data/lib/yard/parser/statement_list.rb +0 -167
  204. data/lib/yard/tags/merbdoc_factory.rb +0 -47
@@ -0,0 +1,72 @@
1
+ module YARD
2
+ module Handlers
3
+ class Processor
4
+ attr_accessor :file, :namespace, :visibility
5
+ attr_accessor :scope, :owner, :load_order_errors, :parser_type
6
+
7
+ def initialize(file = nil, load_order_errors = false, parser_type = Parser::SourceParser.parser_type)
8
+ @file = file || "(stdin)"
9
+ @namespace = YARD::Registry.root
10
+ @visibility = :public
11
+ @scope = :instance
12
+ @owner = @namespace
13
+ @load_order_errors = load_order_errors
14
+ @parser_type = parser_type
15
+ @handlers_loaded = {}
16
+ load_handlers
17
+ end
18
+
19
+ def process(statements)
20
+ statements.each_with_index do |stmt, index|
21
+ find_handlers(stmt).each do |handler|
22
+ begin
23
+ handler.new(self, stmt).process
24
+ rescue Parser::LoadOrderError => loaderr
25
+ raise # Pass this up
26
+ rescue NamespaceMissingError => missingerr
27
+ log.warn "The #{missingerr.object.type} #{missingerr.object.path} has not yet been recognized."
28
+ log.warn "If this class/method is part of your source tree, this will affect your documentation results."
29
+ log.warn "You can correct this issue by loading the source file for this object before `#{file}'"
30
+ log.warn
31
+ rescue Parser::UndocumentableError => undocerr
32
+ log.warn "in #{handler.to_s}: Undocumentable #{undocerr.message}"
33
+ log.warn "\tin file '#{file}':#{stmt.line}:\n\n" + stmt.show + "\n"
34
+ rescue => e
35
+ log.error "Unhandled exception in #{handler.to_s}:"
36
+ log.error "#{e.class.class_name}: #{e.message}"
37
+ log.error " in `#{file}`:#{stmt.line}:\n\n#{stmt.show}\n"
38
+ log.error "Stack trace:" + e.backtrace[0..5].map {|x| "\n\t#{x}" }.join + "\n"
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def find_handlers(statement)
45
+ Base.subclasses.find_all do |handler|
46
+ handler_base_class > handler &&
47
+ (handler.namespace_only? ? owner.is_a?(CodeObjects::NamespaceObject) : true) &&
48
+ handler.handles?(statement)
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def handler_base_class
55
+ handler_base_namespace.const_get(:Base)
56
+ end
57
+
58
+ def handler_base_namespace
59
+ case parser_type
60
+ when :ruby; Ruby
61
+ when :ruby18; Ruby::Legacy
62
+ end
63
+ end
64
+
65
+ def load_handlers
66
+ return if @handlers_loaded[parser_type]
67
+ handler_base_namespace.constants.each {|c| handler_base_namespace.const_get(c) }
68
+ @handlers_loaded[parser_type] = true
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,38 @@
1
+ class YARD::Handlers::Ruby::AliasHandler < YARD::Handlers::Ruby::Base
2
+ handles :alias, method_call(:alias_method)
3
+
4
+ def process
5
+ names = []
6
+ if statement.type == :alias
7
+ names = statement.map {|o| o.jump(:ident, :op, :kw, :const).first }
8
+ elsif statement.call?
9
+ statement.parameters(false).each do |obj|
10
+ case obj.type
11
+ when :symbol_literal
12
+ names << obj.jump(:ident, :op, :kw, :const).source
13
+ when :string_literal
14
+ names << obj.jump(:string_content).source
15
+ end
16
+ end
17
+ end
18
+ raise YARD::Parser::UndocumentableError, "alias/alias_method" if names.size != 2
19
+
20
+ new_meth, old_meth = names[0].to_sym, names[1].to_sym
21
+ old_obj = namespace.child(:name => old_meth, :scope => scope)
22
+ new_obj = register MethodObject.new(namespace, new_meth, scope) do |o|
23
+ o.visibility = visibility
24
+ o.scope = scope
25
+ o.add_file(parser.file, statement.line)
26
+ o.docstring = statement.comments
27
+
28
+ if old_obj
29
+ o.signature = old_obj.signature
30
+ o.source = old_obj.source
31
+ else
32
+ o.signature = "def #{new_meth}" # this is all we know.
33
+ end
34
+ end
35
+
36
+ namespace.aliases[new_obj] = old_meth
37
+ end
38
+ end
@@ -0,0 +1,69 @@
1
+ class YARD::Handlers::Ruby::AttributeHandler < YARD::Handlers::Ruby::Base
2
+ handles method_call(:attr)
3
+ handles method_call(:attr_reader)
4
+ handles method_call(:attr_writer)
5
+ handles method_call(:attr_accessor)
6
+
7
+ def process
8
+ read, write = true, false
9
+ params = statement.parameters(false).dup
10
+
11
+ # Change read/write based on attr_reader/writer/accessor
12
+ case statement.method_name(true)
13
+ when :attr
14
+ # In the case of 'attr', the second parameter (if given) isn't a symbol.
15
+ if params.size == 2
16
+ write = true if params.pop == s(:var_ref, s(:kw, "true"))
17
+ end
18
+ when :attr_accessor
19
+ write = true
20
+ when :attr_reader
21
+ # change nothing
22
+ when :attr_writer
23
+ read, write = false, true
24
+ end
25
+
26
+ # Add all attributes
27
+ validated_attribute_names(params).each do |name|
28
+ namespace.attributes[scope][name] = SymbolHash[:read => nil, :write => nil]
29
+
30
+ # Show their methods as well
31
+ {:read => name, :write => "#{name}="}.each do |type, meth|
32
+ next unless (type == :read ? read : write)
33
+
34
+ namespace.attributes[scope][name][type] = MethodObject.new(namespace, meth, scope) do |o|
35
+ if type == :write
36
+ src = "def #{meth}(value)"
37
+ full_src = "#{src}\n @#{name} = value\nend"
38
+ doc = "Sets the attribute +#{name}+\n@param value the value to set the attribute +#{name}+ to."
39
+ else
40
+ src = "def #{meth}"
41
+ full_src = "#{src}\n @#{name}\nend"
42
+ doc = "Returns the value of attribute +#{name}+"
43
+ end
44
+ o.source ||= full_src
45
+ o.signature ||= src
46
+ o.docstring = statement.comments.to_s.empty? ? doc : statement.comments
47
+ end
48
+
49
+ # Register the objects explicitly
50
+ register namespace.attributes[scope][name][type]
51
+ end
52
+ end
53
+ end
54
+
55
+ protected
56
+
57
+ def validated_attribute_names(params)
58
+ params.map do |obj|
59
+ case obj.type
60
+ when :symbol_literal
61
+ obj.jump(:ident, :op, :kw, :const).source
62
+ when :string_literal
63
+ obj.jump(:string_content).source
64
+ else
65
+ raise YARD::Parser::UndocumentableError, obj.source
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,72 @@
1
+ module YARD
2
+ module Handlers
3
+ module Ruby
4
+ class HandlesExtension
5
+ def initialize(name) @name = name end
6
+ def matches?(node) raise NotImplementedError end
7
+ protected
8
+ attr_reader :name
9
+ end
10
+
11
+ class MethodCallWrapper < HandlesExtension
12
+ def matches?(node)
13
+ case node.type
14
+ when :var_ref
15
+ if !node.parent || node.parent.type == :list
16
+ return true if node[0].type == :ident && node[0][0] == name
17
+ end
18
+ when :fcall, :command
19
+ return true if node[0][0] == name
20
+ when :call, :command_call
21
+ return true if node[2][0] == name
22
+ end
23
+ false
24
+ end
25
+ end
26
+
27
+ class TestNodeWrapper < HandlesExtension
28
+ def matches?(node) !node.send(name).is_a?(FalseClass) end
29
+ end
30
+
31
+ class Base < Handlers::Base
32
+ class << self
33
+ include Parser::Ruby
34
+
35
+ def method_call(name)
36
+ MethodCallWrapper.new(name.to_s)
37
+ end
38
+
39
+ def meta_type(meth)
40
+ TestNodeWrapper.new(meth.to_s + "?")
41
+ end
42
+
43
+ def handles?(node)
44
+ handlers.any? do |a_handler|
45
+ case a_handler
46
+ when Symbol
47
+ a_handler == node.type
48
+ when String
49
+ node.source == a_handler
50
+ when Regexp
51
+ node.source =~ a_handler
52
+ when Parser::Ruby::AstNode
53
+ a_handler == node
54
+ when HandlesExtension
55
+ a_handler.matches?(node)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ include Parser::Ruby
62
+
63
+ def parse_block(inner_node, opts = {})
64
+ push_state(opts) do
65
+ nodes = inner_node.type == :list ? inner_node.children : [inner_node]
66
+ parser.process(nodes)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,70 @@
1
+ class YARD::Handlers::Ruby::ClassConditionHandler < YARD::Handlers::Ruby::Base
2
+ namespace_only
3
+ handles meta_type(:condition)
4
+
5
+ def process
6
+ condition = parse_condition
7
+ if condition == nil
8
+ # Parse both blocks if we're unsure of the condition
9
+ parse_then_block
10
+ parse_else_block
11
+ elsif condition
12
+ parse_then_block
13
+ else
14
+ parse_else_block
15
+ end
16
+ end
17
+
18
+ protected
19
+
20
+ # Parses the condition part of the if/unless statement
21
+ #
22
+ # @return [true, false, nil] true if the condition can be definitely
23
+ # parsed to true, false if not, and nil if the condition cannot be
24
+ # parsed with certainty (it's dynamic)
25
+ def parse_condition
26
+ condition = nil
27
+
28
+ # Right now we can handle very simple unary conditions like:
29
+ # if true
30
+ # if false
31
+ # if 0
32
+ # if 100 (not 0)
33
+ # if defined? SOME_CONSTANT
34
+ #
35
+ # The last case will do a lookup in the registry and then one
36
+ # in the Ruby world (using eval).
37
+ case statement.condition.type
38
+ when :int
39
+ condition = statement.condition[0] != "0"
40
+ when :defined
41
+ # defined? keyword used, let's see if we can look up the name
42
+ # in the registry, then we'll try using Ruby's powers. eval() is not
43
+ # *too* dangerous here since code is not actually executed.
44
+ name = statement.condition[0].source
45
+ obj = YARD::Registry.resolve(namespace, name, true)
46
+ condition = true if obj || Object.instance_eval("defined? #{name}")
47
+ when :var_ref
48
+ var = statement.condition[0]
49
+ if var == s(:kw, "true")
50
+ condition = true
51
+ elsif var == s(:kw, "false")
52
+ condition = false
53
+ end
54
+ end
55
+
56
+ # Invert an unless condition
57
+ if statement.type == :unless || statement.type == :unless_mod
58
+ condition = !condition if condition != nil
59
+ end
60
+ condition
61
+ end
62
+
63
+ def parse_then_block
64
+ parse_block(statement.then_block)
65
+ end
66
+
67
+ def parse_else_block
68
+ parse_block(statement.else_block) if statement.else_block
69
+ end
70
+ end
@@ -0,0 +1,74 @@
1
+ class YARD::Handlers::Ruby::ClassHandler < YARD::Handlers::Ruby::Base
2
+ handles :class, :sclass
3
+
4
+ def process
5
+ if statement.type == :class
6
+ classname = statement[0].source
7
+ superclass = parse_superclass(statement[1])
8
+ undocsuper = statement[1] && superclass.nil?
9
+
10
+ klass = register ClassObject.new(namespace, classname) do |o|
11
+ o.docstring = statement.comments
12
+ o.superclass = superclass if superclass
13
+ o.superclass.type = :class if o.superclass.is_a?(Proxy)
14
+ end
15
+ parse_block(statement[2], namespace: klass)
16
+
17
+ if undocsuper
18
+ raise YARD::Parser::UndocumentableError, 'superclass (class was added without superclass)'
19
+ end
20
+ elsif statement.type == :sclass
21
+ if statement[0] == s(:var_ref, s(:kw, "self"))
22
+ parse_block(statement[1], namespace: namespace, scope: :class)
23
+ else
24
+ classname = statement[0].source
25
+ proxy = Proxy.new(namespace, classname)
26
+
27
+ # Allow constants to reference class names
28
+ if ConstantObject === proxy
29
+ if proxy.value =~ /\A#{NAMESPACEMATCH}\Z/
30
+ proxy = Proxy.new(namespace, proxy.value)
31
+ else
32
+ raise YARD::Parser::UndocumentableError, "constant class reference '#{classname}'"
33
+ end
34
+ end
35
+
36
+ if classname[0,1] =~ /[A-Z]/
37
+ register ClassObject.new(namespace, classname) if Proxy === proxy
38
+ parse_block(statement[1], namespace: proxy, scope: :class)
39
+ else
40
+ raise YARD::Parser::UndocumentableError, "class '#{classname}'"
41
+ end
42
+ end
43
+ else
44
+ sig_end = (statement[1] ? statement[1].source_end : statement[0].source_end) - statement.source_start
45
+ raise YARD::Parser::UndocumentableError, "class: #{statement.source[0..sig_end]}"
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def parse_superclass(superclass)
52
+ return nil unless superclass
53
+
54
+ case superclass.type
55
+ when :var_ref
56
+ return superclass.source if superclass.first.type == :const
57
+ when :const, :const_ref, :const_path_ref, :top_const_ref
58
+ return superclass.source
59
+ when :fcall, :command
60
+ methname = superclass.method_name.source
61
+ if methname == "DelegateClass"
62
+ return superclass.parameters.first.source
63
+ elsif superclass.method_name.type == :const
64
+ return methname
65
+ end
66
+ when :call, :command_call
67
+ cname = superclass.namespace.source
68
+ if cname =~ /^O?Struct$/ && superclass.method_name(true) == :new
69
+ return cname
70
+ end
71
+ end
72
+ nil
73
+ end
74
+ end
@@ -0,0 +1,11 @@
1
+ class YARD::Handlers::Ruby::ClassVariableHandler < YARD::Handlers::Ruby::Base
2
+ namespace_only
3
+ handles :assign
4
+
5
+ def process
6
+ if statement[0].type == :var_field && statement[0][0].type == :cvar
7
+ name = statement[0][0][0]
8
+ register ClassVariableObject.new(namespace, name) {|o| o.source = statement }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
2
+ namespace_only
3
+ handles :assign
4
+
5
+ def process
6
+ if statement[0].type == :var_field && statement[0][0].type == :const
7
+ name = statement[0][0][0]
8
+ value = statement[1].source
9
+ register ConstantObject.new(namespace, name) {|o| o.source = statement; o.value = value.strip }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,22 @@
1
+ class YARD::Handlers::Ruby::ExceptionHandler < YARD::Handlers::Ruby::Base
2
+ handles method_call(:raise)
3
+
4
+ def process
5
+ return unless owner.is_a?(MethodObject) # Only methods yield
6
+ return if owner.has_tag?(:raise)
7
+
8
+ klass = nil
9
+ params = statement.parameters(false)
10
+ if params.size == 1
11
+ if params.first.ref? && params.first.first.type != :ident
12
+ klass = params.first.source
13
+ elsif params.first.call? && params.first.method_name(true) == :new
14
+ klass = params.first.namespace.source
15
+ end
16
+ else
17
+ klass = params.first.source
18
+ end
19
+
20
+ owner.docstring.add_tag YARD::Tags::Tag.new(:raise, '', klass) if klass
21
+ end
22
+ end