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
@@ -17,59 +17,71 @@ module YARD
17
17
  alias_method :<<, :push
18
18
  end
19
19
 
20
- NSEP = '::'
21
- ISEP = '#'
20
+ NSEPQ = NSEP = '::'
21
+ ISEPQ = ISEP = '#'
22
+ CSEP = '.'
23
+ CSEPQ = Regexp.quote CSEP
22
24
  CONSTANTMATCH = /[A-Z]\w*/
23
- NAMESPACEMATCH = /(?:(?:#{Regexp.quote NSEP})?#{CONSTANTMATCH})+/
24
- METHODNAMEMATCH = /[a-zA-Z_]\w*[!?]?|[-+~]\@|<<|>>|=~|===?|[<>]=?|\*\*|[-\/+%^&*~`|]|\[\]=?/
25
- METHODMATCH = /(?:(?:#{NAMESPACEMATCH}|self)\s*(?:\.|#{Regexp.quote NSEP})\s*)?#{METHODNAMEMATCH}/
25
+ NAMESPACEMATCH = /(?:(?:#{NSEPQ})?#{CONSTANTMATCH})+/
26
+ METHODNAMEMATCH = /[a-zA-Z_]\w*[!?=]?|[-+~]\@|<<|>>|=~|===?|[<>]=?|\*\*|[-\/+%^&*~`|]|\[\]=?/
27
+ METHODMATCH = /(?:(?:#{NAMESPACEMATCH}|self)\s*(?:#{CSEPQ}|#{NSEPQ})\s*)?#{METHODNAMEMATCH}/
26
28
 
27
29
  BUILTIN_EXCEPTIONS = ["SecurityError", "Exception", "NoMethodError", "FloatDomainError",
28
30
  "IOError", "TypeError", "NotImplementedError", "SystemExit", "Interrupt", "SyntaxError",
29
31
  "RangeError", "NoMemoryError", "ArgumentError", "ThreadError", "EOFError", "RuntimeError",
30
32
  "ZeroDivisionError", "StandardError", "LoadError", "NameError", "LocalJumpError", "SystemCallError",
31
33
  "SignalException", "ScriptError", "SystemStackError", "RegexpError", "IndexError"]
34
+ # Note: MatchingData is a 1.8.x legacy class
32
35
  BUILTIN_CLASSES = ["TrueClass", "Array", "Dir", "Struct", "UnboundMethod", "Object", "Fixnum", "Float",
33
- "ThreadGroup", "MatchData", "Proc", "Binding", "Class", "Time", "Bignum", "NilClass", "Symbol",
34
- "Numeric", "String", "Data", "MatchingData", "Regexp", "Integer", "File", "IO", "Range", "FalseClass",
36
+ "ThreadGroup", "MatchingData", "MatchData", "Proc", "Binding", "Class", "Time", "Bignum", "NilClass", "Symbol",
37
+ "Numeric", "String", "Data", "MatchData", "Regexp", "Integer", "File", "IO", "Range", "FalseClass",
35
38
  "Method", "Continuation", "Thread", "Hash", "Module"] + BUILTIN_EXCEPTIONS
36
39
  BUILTIN_MODULES = ["ObjectSpace", "Signal", "Marshal", "Kernel", "Process", "GC", "FileTest", "Enumerable",
37
- "Comparable", "Errno", "Precision", "Math", "DTracer"]
40
+ "Comparable", "Errno", "Precision", "Math"]
38
41
  BUILTIN_ALL = BUILTIN_CLASSES + BUILTIN_MODULES
39
42
 
40
43
  BUILTIN_EXCEPTIONS_HASH = BUILTIN_EXCEPTIONS.inject({}) {|h,n| h.update(n => true) }
41
44
 
42
45
  class Base
43
- attr_reader :name
44
- attr_accessor :namespace
45
- attr_accessor :source, :signature, :file, :line, :docstring, :dynamic
46
+ attr_reader :name, :files
47
+ attr_accessor :namespace, :source, :signature, :docstring, :dynamic
46
48
 
47
49
  def dynamic?; @dynamic end
48
50
 
49
51
  class << self
50
52
  def new(namespace, name, *args, &block)
51
- if name =~ /(?:#{NSEP}|#{ISEP})([^#{NSEP}#{ISEP}]+)$/
53
+ if name.to_s[0,2] == NSEP
54
+ name = name.to_s[2..-1]
55
+ namespace = Registry.root
56
+ elsif name =~ /(?:#{NSEPQ}|#{ISEPQ}|#{CSEPQ})([^#{NSEPQ}#{ISEPQ}#{CSEPQ}]+)$/
52
57
  return new(Proxy.new(namespace, $`), $1, *args, &block)
53
58
  end
54
59
 
55
60
  keyname = namespace && namespace.respond_to?(:path) ? namespace.path : ''
56
61
  if self == RootObject
57
62
  keyname = :root
63
+ elsif self == MethodObject
64
+ keyname += (args.first && args.first.to_sym == :class ? CSEP : ISEP) + name.to_s
58
65
  elsif keyname.empty?
59
66
  keyname = name.to_s
60
- elsif self == MethodObject
61
- keyname += (!args.first || args.first.to_sym == :instance ? ISEP : NSEP) + name.to_s
62
67
  else
63
68
  keyname += NSEP + name.to_s
64
69
  end
65
70
 
66
- if self != RootObject && obj = Registry[keyname]
71
+ obj = Registry.objects[keyname]
72
+ obj = nil if obj && obj.class != self
73
+
74
+ if self != RootObject && obj
67
75
  yield(obj) if block_given?
68
76
  obj
69
77
  else
70
78
  Registry.objects[keyname] = super(namespace, name, *args, &block)
71
79
  end
72
80
  end
81
+
82
+ def ===(other)
83
+ self >= other.class ? true : false
84
+ end
73
85
  end
74
86
 
75
87
  def initialize(namespace, name, *args)
@@ -78,13 +90,50 @@ module YARD
78
90
  raise ArgumentError, "Invalid namespace object: #{namespace}"
79
91
  end
80
92
 
93
+ @files = []
94
+ @current_file_has_comments = false
81
95
  @name = name.to_sym
82
96
  @tags = []
83
- @docstring = ""
97
+ @docstring = Docstring.new('', self)
84
98
  self.namespace = namespace
85
99
  yield(self) if block_given?
86
100
  end
87
101
 
102
+ # Associates a file with a code object, optionally adding the line where it was defined.
103
+ # By convention, '<STDIN>' should be used to associate code that comes form standard input.
104
+ #
105
+ # @param [String] file the filename ('<STDIN>' for standard input)
106
+ # @param [Fixnum, nil] the line number where the object lies in the file
107
+ # @param [Boolean] whether or not the definition has comments associated. This
108
+ # will allow {#file} to return the definition where the comments were made instead
109
+ # of any empty definitions that might have been parsed before (module namespaces for instance).
110
+ def add_file(file, line = nil, has_comments = false)
111
+ raise(ArgumentError, "file cannot be nil or empty") if file.nil? || file == ''
112
+ obj = [file.to_s, line]
113
+ if has_comments && !@current_file_has_comments
114
+ @current_file_has_comments = true
115
+ @files.unshift(obj)
116
+ else
117
+ @files << obj # back of the line
118
+ end
119
+ end
120
+
121
+ # Returns the filename the object was first parsed at, taking
122
+ # definitions with docstrings first.
123
+ #
124
+ # @return [String] a filename
125
+ def file
126
+ @files.first ? @files.first[0] : nil
127
+ end
128
+
129
+ # Returns the line the object was first parsed at (or nil)
130
+ #
131
+ # @return [Fixnum] the line where the object was first defined.
132
+ # @return [nil] if there is no line associated with the object
133
+ def line
134
+ @files.first ? @files.first[1] : nil
135
+ end
136
+
88
137
  def ==(other)
89
138
  if other.is_a?(Proxy)
90
139
  path == other.path
@@ -111,7 +160,7 @@ module YARD
111
160
 
112
161
  def method_missing(meth, *args, &block)
113
162
  if meth.to_s =~ /=$/
114
- self[meth.to_s[0..-2]] = *args
163
+ self[meth.to_s[0..-2]] = args.first
115
164
  elsif instance_variable_get("@#{meth}")
116
165
  self[meth]
117
166
  else
@@ -126,7 +175,7 @@ module YARD
126
175
  # the +Parser::Statement+ holding the source code or the raw source
127
176
  # as a +String+ for the definition of the code object only (not the block)
128
177
  def source=(statement)
129
- if statement.is_a? Parser::Statement
178
+ if statement.is_a? Parser::Ruby::Legacy::Statement
130
179
  src = statement.tokens.to_s
131
180
  blk = statement.block ? statement.block.to_s : ""
132
181
  if src =~ /^def\s.*[^\)]$/ && blk[0,1] !~ /\r|\n/
@@ -136,6 +185,10 @@ module YARD
136
185
  @source = format_source(src + blk)
137
186
  self.line = statement.tokens.first.line_no
138
187
  self.signature = src
188
+ elsif statement.respond_to?(:source)
189
+ self.line = statement.line
190
+ self.signature = statement.first_line
191
+ @source = format_source(statement.source.strip)
139
192
  else
140
193
  @source = format_source(statement.to_s)
141
194
  end
@@ -145,24 +198,13 @@ module YARD
145
198
  # Attaches a docstring to a code oject by parsing the comments attached to the statement
146
199
  # and filling the {#tags} and {#docstring} methods with the parsed information.
147
200
  #
148
- # @param [String, Array<String>] comments
201
+ # @param [String, Array<String>, Docstring] comments
149
202
  # the comments attached to the code object to be parsed
150
203
  # into a docstring and meta tags.
151
204
  def docstring=(comments)
152
- @short_docstring = nil
153
- parse_comments(comments) if comments
205
+ @docstring = Docstring === comments ? comments : Docstring.new(comments, self)
154
206
  end
155
207
 
156
- ##
157
- # Gets the first line of a docstring to the period or the first paragraph.
158
- #
159
- # @return [String] The first line or paragraph of the docstring; always ends with a period.
160
- def short_docstring
161
- @short_docstring ||= (docstring.split(/\.|\r?\n\r?\n/).first || '')
162
- @short_docstring += '.' unless @short_docstring.empty?
163
- @short_docstring
164
- end
165
-
166
208
  ##
167
209
  # Default type is the lowercase class name without the "Object" suffix
168
210
  #
@@ -170,7 +212,7 @@ module YARD
170
212
  #
171
213
  # @return [Symbol] the type of code object this represents
172
214
  def type
173
- self.class.name.split(/#{NSEP}/).last.gsub(/Object$/, '').downcase.to_sym
215
+ self.class.name.split(/#{NSEPQ}/).last.gsub(/Object$/, '').downcase.to_sym
174
216
  end
175
217
 
176
218
  def path
@@ -203,113 +245,14 @@ module YARD
203
245
  alias_method :parent, :namespace
204
246
  alias_method :parent=, :namespace=
205
247
 
206
- ##
207
- # Convenience method to return the first tag
208
- # object in the list of tag objects of that name
209
- #
210
- # Example:
211
- # doc = YARD::Documentation.new("@return zero when nil")
212
- # doc.tag("return").text # => "zero when nil"
213
- #
214
- # @param [#to_s] name the tag name to return data for
215
- # @return [Tags::Tag] the first tag in the list of {#tags}
216
- def tag(name)
217
- @tags.find {|tag| tag.tag_name.to_s == name.to_s }
218
- end
219
-
220
- ##
221
- # Returns a list of tags specified by +name+ or all tags if +name+ is not specified.
222
- #
223
- # @param name the tag name to return data for, or nil for all tags
224
- # @return [Array<Tags::Tag>] the list of tags by the specified tag name
225
- def tags(name = nil)
226
- return @tags if name.nil?
227
- @tags.select {|tag| tag.tag_name.to_s == name.to_s }
228
- end
229
-
230
- ##
231
- # Returns true if at least one tag by the name +name+ was declared
232
- #
233
- # @param [String] name the tag name to search for
234
- # @return [Boolean] whether or not the tag +name+ was declared
235
- def has_tag?(name)
236
- @tags.any? {|tag| tag.tag_name.to_s == name.to_s }
237
- end
248
+ def tag(name); @docstring.tag(name) end
249
+ def tags(name = nil); @docstring.tags(name) end
250
+ def has_tag?(name); @docstring.has_tag?(name) end
238
251
 
239
252
  protected
240
253
 
241
254
  def sep; NSEP end
242
255
 
243
- private
244
-
245
- ##
246
- # Parses out comments split by newlines into a new code object
247
- #
248
- # @param [Array<String>, String] comments
249
- # the newline delimited array of comments. If the comments
250
- # are passed as a String, they will be split by newlines.
251
- def parse_comments(comments)
252
- return if comments.empty?
253
- meta_match = /^@(\S+)\s*(.*)/
254
- comments = comments.split(/\r?\n/) if comments.is_a? String
255
- @tags, @docstring = [], ""
256
-
257
- indent, last_indent = comments.first[/^\s*/].length, 0
258
- orig_indent = 0
259
- last_line = ""
260
- tag_name, tag_klass, tag_buf, raw_buf = nil, nil, "", []
261
-
262
- (comments+['']).each_with_index do |line, index|
263
- indent = line[/^\s*/].length
264
- empty = (line =~ /^\s*$/ ? true : false)
265
- done = comments.size == index
266
-
267
- if tag_name && (((indent < orig_indent && !empty) || done) ||
268
- (indent <= last_indent && line =~ meta_match))
269
- tagfactory = Tags::Library.new
270
- tag_method = "#{tag_name}_tag"
271
- if tag_name && tagfactory.respond_to?(tag_method)
272
- if tagfactory.method(tag_method).arity == 2
273
- @tags << tagfactory.send(tag_method, tag_buf, raw_buf.join("\n"))
274
- else
275
- @tags << tagfactory.send(tag_method, tag_buf)
276
- end
277
- else
278
- log.warn "Unknown tag @#{tag_name} in documentation for `#{path}`"
279
- end
280
- tag_name, tag_buf, raw_buf = nil, '', []
281
- orig_indent = 0
282
- end
283
-
284
- # Found a meta tag
285
- if line =~ meta_match
286
- orig_indent = indent
287
- tag_name, tag_buf = $1, $2
288
- raw_buf = [tag_buf.dup]
289
- elsif tag_name && indent >= orig_indent && !empty
290
- # Extra data added to the tag on the next line
291
- last_empty = last_line =~ /^[ \t]*$/ ? true : false
292
-
293
- if last_empty
294
- tag_buf << "\n\n"
295
- raw_buf << ''
296
- end
297
-
298
- tag_buf << line.gsub(/^[ \t]{#{indent}}/, last_empty ? '' : ' ')
299
- raw_buf << line.gsub(/^[ \t]{#{orig_indent}}/, '')
300
- elsif !tag_name
301
- # Regular docstring text
302
- @docstring << line << "\n"
303
- end
304
-
305
- last_indent = indent
306
- last_line = line
307
- end
308
-
309
- # Remove trailing/leading whitespace / newlines
310
- @docstring.gsub!(/\A[\r\n\s]+|[\r\n\s]+\Z/, '')
311
- end
312
-
313
256
  # Formats source code by removing leading indentation
314
257
  def format_source(source)
315
258
  source.chomp!
@@ -318,4 +261,4 @@ module YARD
318
261
  end
319
262
  end
320
263
  end
321
- end
264
+ end
@@ -6,7 +6,7 @@ module YARD::CodeObjects
6
6
  super
7
7
 
8
8
  if is_exception?
9
- self.superclass ||= :Exception
9
+ self.superclass ||= :Exception unless P(namespace, name) == P(:Exception)
10
10
  else
11
11
  self.superclass ||= :Object unless P(namespace, name) == P(:Object)
12
12
  end
@@ -17,13 +17,14 @@ module YARD::CodeObjects
17
17
  end
18
18
 
19
19
  def inheritance_tree(include_mods = false)
20
- list = [self] + (include_mods ? mixins : [])
21
- if superclass.is_a? Proxy
20
+ list = (include_mods ? mixins(:instance) : [])
21
+ if superclass.is_a?(Proxy) || superclass.respond_to?(:inheritance_tree)
22
22
  list << superclass unless superclass == P(:Object)
23
- elsif superclass.respond_to? :inheritance_tree
24
- list += superclass.inheritance_tree
25
23
  end
26
- list
24
+ [self] + list.map do |m|
25
+ next m unless m.respond_to?(:inheritance_tree)
26
+ m.inheritance_tree(include_mods)
27
+ end.flatten
27
28
  end
28
29
 
29
30
  def meths(opts = {})
@@ -80,10 +81,10 @@ module YARD::CodeObjects
80
81
  end
81
82
 
82
83
  if @superclass == self
83
- msg = "superclass #{@superclass.inspect} cannot be the same as the subclass #{self}"
84
+ msg = "superclass #{@superclass.inspect} cannot be the same as the declared class #{self.inspect}"
84
85
  @superclass = P(:Object)
85
86
  raise ArgumentError, msg
86
87
  end
87
88
  end
88
89
  end
89
- end
90
+ end
@@ -1,4 +1,5 @@
1
1
  module YARD::CodeObjects
2
2
  class ConstantObject < Base
3
+ attr_accessor :value
3
4
  end
4
5
  end
@@ -0,0 +1,9 @@
1
+ module YARD::CodeObjects
2
+ class ExtendedMethodObject
3
+ instance_methods.each {|m| undef_method(m) unless m =~ /^__/ || m.to_sym == :object_id }
4
+
5
+ def scope; :class end
6
+ def initialize(obj) @del = obj end
7
+ def method_missing(sym, *args, &block) @del.__send__(sym, *args, &block) end
8
+ end
9
+ end
@@ -1,15 +1,22 @@
1
1
  module YARD::CodeObjects
2
2
  class MethodObject < Base
3
- attr_accessor :visibility, :scope, :explicit
3
+ attr_accessor :visibility, :scope, :explicit, :parameters
4
4
 
5
5
  def initialize(namespace, name, scope = :instance)
6
6
  self.visibility = :public
7
7
  self.scope = scope
8
+ self.parameters = []
8
9
 
9
10
  super
10
11
  end
11
12
 
12
- def scope=(v) @scope = v.to_sym end
13
+ def scope=(v)
14
+ reregister = @scope ? true : false
15
+ YARD::Registry.delete(self) if reregister
16
+ @scope = v.to_sym
17
+ YARD::Registry.register(self) if reregister
18
+ end
19
+
13
20
  def visibility=(v) @visibility = v.to_sym end
14
21
 
15
22
  def is_attribute?
@@ -41,11 +48,17 @@ module YARD::CodeObjects
41
48
  end
42
49
 
43
50
  def name(prefix = false)
44
- prefix && sep == ISEP ? sep + super().to_s : super()
51
+ ((prefix ? (sep == ISEP ? sep : "") : "") + super().to_s).to_sym
45
52
  end
46
53
 
47
54
  protected
48
55
 
49
- def sep; scope == :class ? super : ISEP end
56
+ def sep
57
+ if scope == :class
58
+ namespace && namespace != YARD::Registry.root ? CSEP : NSEP
59
+ else
60
+ ISEP
61
+ end
62
+ end
50
63
  end
51
- end
64
+ end
@@ -1,4 +1,11 @@
1
1
  module YARD::CodeObjects
2
2
  class ModuleObject < NamespaceObject
3
+ def inheritance_tree(include_mods = false)
4
+ return [self] unless include_mods
5
+ [self] + mixins(:instance).map do |m|
6
+ next m unless m.respond_to?(:inheritance_tree)
7
+ m.inheritance_tree(true)
8
+ end.flatten
9
+ end
3
10
  end
4
- end
11
+ end
@@ -1,10 +1,12 @@
1
1
  module YARD::CodeObjects
2
2
  class NamespaceObject < Base
3
- attr_reader :children, :cvars, :meths, :constants, :mixins, :attributes, :aliases
3
+ attr_reader :children, :cvars, :meths, :constants, :attributes, :aliases
4
+ attr_reader :class_mixins, :instance_mixins
4
5
 
5
6
  def initialize(namespace, name, *args, &block)
6
7
  @children = CodeObjectList.new(self)
7
- @mixins = CodeObjectList.new(self)
8
+ @class_mixins = CodeObjectList.new(self)
9
+ @instance_mixins = CodeObjectList.new(self)
8
10
  @attributes = SymbolHash[:class => SymbolHash.new, :instance => SymbolHash.new]
9
11
  @aliases = {}
10
12
  super
@@ -25,7 +27,7 @@ module YARD::CodeObjects
25
27
  opts = SymbolHash[opts]
26
28
  children.find do |obj|
27
29
  opts.each do |meth, value|
28
- break false if obj[meth] != value
30
+ break false if !(value.is_a?(Array) ? value.include?(obj[meth]) : obj[meth] == value)
29
31
  end
30
32
  end
31
33
  end
@@ -51,16 +53,17 @@ module YARD::CodeObjects
51
53
  end
52
54
 
53
55
  def included_meths(opts = {})
54
- mixins.reverse.inject([]) do |list, mixin|
55
- if mixin.is_a?(Proxy)
56
- list
57
- else
58
- list += mixin.meths(opts).reject do |o|
59
- child(:name => o.name, :scope => o.scope) ||
60
- list.find {|o2| o2.name == o.name && o2.scope == o.scope }
56
+ opts = SymbolHash[:scope => [:instance, :class]].update(opts)
57
+ [opts[:scope]].flatten.map do |scope|
58
+ mixins(scope).reverse.inject([]) do |list, mixin|
59
+ next list if mixin.is_a?(Proxy)
60
+ arr = mixin.meths(opts.merge(:scope => :instance)).reject do |o|
61
+ child(:name => o.name, :scope => scope) || list.find {|o2| o2.name == o.name }
61
62
  end
63
+ arr.map! {|o| ExtendedMethodObject.new(o) } if scope == :class
64
+ list + arr
62
65
  end
63
- end
66
+ end.flatten
64
67
  end
65
68
 
66
69
  def constants(opts = {})
@@ -70,13 +73,13 @@ module YARD::CodeObjects
70
73
  end
71
74
 
72
75
  def included_constants
73
- mixins.reverse.inject([]) do |list, mixin|
74
- if mixin.is_a?(Proxy)
75
- list
76
- else
76
+ instance_mixins.reverse.inject([]) do |list, mixin|
77
+ if mixin.respond_to? :constants
77
78
  list += mixin.constants.reject do |o|
78
79
  child(:name => o.name) || list.find {|o2| o2.name == o.name }
79
80
  end
81
+ else
82
+ list
80
83
  end
81
84
  end
82
85
  end
@@ -84,5 +87,11 @@ module YARD::CodeObjects
84
87
  def cvars
85
88
  children.select {|o| o.is_a? ClassVariableObject }
86
89
  end
90
+
91
+ def mixins(*scopes)
92
+ return class_mixins if scopes == [:class]
93
+ return instance_mixins if scopes == [:instance]
94
+ class_mixins | instance_mixins
95
+ end
87
96
  end
88
- end
97
+ end