yard 0.5.8 → 0.6.0

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 (211) hide show
  1. data/.yardopts +2 -0
  2. data/ChangeLog +1064 -0
  3. data/README.md +103 -42
  4. data/Rakefile +3 -2
  5. data/benchmarks/parsing.rb +2 -1
  6. data/bin/yard +4 -0
  7. data/bin/yard-graph +1 -1
  8. data/bin/yard-server +4 -0
  9. data/docs/GettingStarted.md +8 -8
  10. data/docs/Handlers.md +5 -5
  11. data/docs/Overview.md +5 -5
  12. data/docs/Parser.md +1 -1
  13. data/docs/Tags.md +1 -1
  14. data/docs/Templates.md +27 -6
  15. data/docs/WhatsNew.md +222 -2
  16. data/lib/rubygems_plugin.rb +1 -0
  17. data/lib/yard.rb +7 -1
  18. data/lib/yard/autoload.rb +46 -6
  19. data/lib/yard/cli/{base.rb → command.rb} +20 -6
  20. data/lib/yard/cli/command_parser.rb +87 -0
  21. data/lib/yard/cli/diff.rb +176 -0
  22. data/lib/yard/cli/gems.rb +74 -0
  23. data/lib/yard/cli/{yard_graph.rb → graph.rb} +9 -8
  24. data/lib/yard/cli/help.rb +18 -0
  25. data/lib/yard/cli/server.rb +137 -0
  26. data/lib/yard/cli/stats.rb +210 -0
  27. data/lib/yard/cli/yardoc.rb +315 -116
  28. data/lib/yard/cli/yri.rb +45 -4
  29. data/lib/yard/code_objects/base.rb +73 -30
  30. data/lib/yard/code_objects/class_object.rb +9 -1
  31. data/lib/yard/code_objects/method_object.rb +11 -0
  32. data/lib/yard/code_objects/namespace_object.rb +8 -2
  33. data/lib/yard/code_objects/proxy.rb +2 -2
  34. data/lib/yard/core_ext/array.rb +3 -49
  35. data/lib/yard/core_ext/file.rb +7 -0
  36. data/lib/yard/core_ext/insertion.rb +60 -0
  37. data/lib/yard/docstring.rb +34 -7
  38. data/lib/yard/globals.rb +2 -2
  39. data/lib/yard/handlers/base.rb +101 -20
  40. data/lib/yard/handlers/processor.rb +23 -7
  41. data/lib/yard/handlers/ruby/alias_handler.rb +1 -0
  42. data/lib/yard/handlers/ruby/attribute_handler.rb +8 -0
  43. data/lib/yard/handlers/ruby/base.rb +71 -2
  44. data/lib/yard/handlers/ruby/class_condition_handler.rb +10 -0
  45. data/lib/yard/handlers/ruby/class_handler.rb +7 -4
  46. data/lib/yard/handlers/ruby/class_variable_handler.rb +1 -0
  47. data/lib/yard/handlers/ruby/constant_handler.rb +1 -0
  48. data/lib/yard/handlers/ruby/exception_handler.rb +1 -0
  49. data/lib/yard/handlers/ruby/extend_handler.rb +2 -3
  50. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +1 -0
  51. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +2 -0
  52. data/lib/yard/handlers/ruby/legacy/base.rb +15 -2
  53. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +5 -0
  54. data/lib/yard/handlers/ruby/legacy/class_handler.rb +7 -4
  55. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +1 -0
  56. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +1 -0
  57. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +1 -0
  58. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +1 -3
  59. data/lib/yard/handlers/ruby/legacy/method_handler.rb +7 -3
  60. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +2 -1
  61. data/lib/yard/handlers/ruby/legacy/module_handler.rb +1 -0
  62. data/lib/yard/handlers/ruby/legacy/process_handler.rb +1 -0
  63. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +1 -0
  64. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +1 -0
  65. data/lib/yard/handlers/ruby/method_condition_handler.rb +1 -0
  66. data/lib/yard/handlers/ruby/method_handler.rb +5 -1
  67. data/lib/yard/handlers/ruby/mixin_handler.rb +2 -1
  68. data/lib/yard/handlers/ruby/module_handler.rb +1 -0
  69. data/lib/yard/handlers/ruby/process_handler.rb +7 -1
  70. data/lib/yard/handlers/ruby/struct_handler_methods.rb +3 -0
  71. data/lib/yard/handlers/ruby/visibility_handler.rb +8 -2
  72. data/lib/yard/handlers/ruby/yield_handler.rb +1 -0
  73. data/lib/yard/logging.rb +7 -1
  74. data/lib/yard/parser/base.rb +1 -0
  75. data/lib/yard/parser/c_parser.rb +2 -0
  76. data/lib/yard/parser/ruby/ast_node.rb +82 -63
  77. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +36 -10
  78. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +1 -0
  79. data/lib/yard/parser/ruby/legacy/statement.rb +9 -5
  80. data/lib/yard/parser/ruby/legacy/statement_list.rb +20 -11
  81. data/lib/yard/parser/ruby/ruby_parser.rb +18 -1
  82. data/lib/yard/parser/source_parser.rb +6 -1
  83. data/lib/yard/registry.rb +284 -278
  84. data/lib/yard/registry_store.rb +4 -2
  85. data/lib/yard/serializers/base.rb +30 -13
  86. data/lib/yard/serializers/file_system_serializer.rb +10 -1
  87. data/lib/yard/server/adapter.rb +51 -0
  88. data/lib/yard/server/commands/base.rb +98 -0
  89. data/lib/yard/server/commands/display_file_command.rb +20 -0
  90. data/lib/yard/server/commands/display_object_command.rb +50 -0
  91. data/lib/yard/server/commands/frames_command.rb +31 -0
  92. data/lib/yard/server/commands/library_command.rb +83 -0
  93. data/lib/yard/server/commands/library_index_command.rb +23 -0
  94. data/lib/yard/server/commands/list_command.rb +44 -0
  95. data/lib/yard/server/commands/search_command.rb +67 -0
  96. data/lib/yard/server/commands/static_file_command.rb +45 -0
  97. data/lib/yard/server/doc_server_helper.rb +22 -0
  98. data/lib/yard/server/doc_server_serializer.rb +29 -0
  99. data/lib/yard/server/library_version.rb +86 -0
  100. data/lib/yard/server/rack_adapter.rb +38 -0
  101. data/lib/yard/server/router.rb +110 -0
  102. data/lib/yard/server/static_caching.rb +16 -0
  103. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +78 -0
  104. data/lib/yard/server/templates/default/fulldoc/html/images/processing.gif +0 -0
  105. data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +12 -0
  106. data/lib/yard/server/templates/default/fulldoc/html/js/live.js +32 -0
  107. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +46 -0
  108. data/lib/yard/server/templates/default/layout/html/headers.erb +11 -0
  109. data/lib/yard/server/templates/doc_server/frames/html/frames.erb +13 -0
  110. data/lib/yard/server/templates/doc_server/frames/html/setup.rb +3 -0
  111. data/lib/yard/server/templates/doc_server/full_list/html/full_list.erb +34 -0
  112. data/lib/yard/server/templates/doc_server/full_list/html/setup.rb +10 -0
  113. data/lib/yard/server/templates/doc_server/library_list/html/contents.erb +13 -0
  114. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +26 -0
  115. data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +12 -0
  116. data/lib/yard/server/templates/doc_server/library_list/html/setup.rb +3 -0
  117. data/lib/yard/server/templates/doc_server/library_list/html/title.erb +2 -0
  118. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +51 -0
  119. data/lib/yard/server/templates/doc_server/processing/html/setup.rb +3 -0
  120. data/lib/yard/server/templates/doc_server/search/html/search.erb +19 -0
  121. data/lib/yard/server/templates/doc_server/search/html/setup.rb +8 -0
  122. data/lib/yard/server/webrick_adapter.rb +38 -0
  123. data/lib/yard/tags/default_factory.rb +0 -5
  124. data/lib/yard/tags/library.rb +61 -22
  125. data/lib/yard/tags/tag.rb +26 -4
  126. data/lib/yard/templates/engine.rb +12 -1
  127. data/lib/yard/templates/erb_cache.rb +2 -1
  128. data/lib/yard/templates/helpers/base_helper.rb +96 -3
  129. data/lib/yard/templates/helpers/filter_helper.rb +5 -0
  130. data/lib/yard/templates/helpers/html_helper.rb +204 -94
  131. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +4 -0
  132. data/lib/yard/templates/helpers/markup_helper.rb +58 -3
  133. data/lib/yard/templates/helpers/method_helper.rb +7 -0
  134. data/lib/yard/templates/helpers/module_helper.rb +5 -0
  135. data/lib/yard/templates/helpers/text_helper.rb +10 -1
  136. data/lib/yard/templates/helpers/uml_helper.rb +13 -0
  137. data/lib/yard/templates/section.rb +106 -0
  138. data/lib/yard/templates/template.rb +20 -19
  139. data/lib/yard/verifier.rb +21 -2
  140. data/spec/cli/command_parser_spec.rb +43 -0
  141. data/spec/cli/diff_spec.rb +170 -0
  142. data/spec/cli/help_spec.rb +22 -0
  143. data/spec/cli/server_spec.rb +140 -0
  144. data/spec/cli/stats_spec.rb +75 -0
  145. data/spec/cli/yardoc_spec.rb +438 -182
  146. data/spec/cli/yri_spec.rb +13 -1
  147. data/spec/code_objects/base_spec.rb +51 -6
  148. data/spec/code_objects/class_object_spec.rb +15 -1
  149. data/spec/code_objects/method_object_spec.rb +29 -0
  150. data/spec/code_objects/namespace_object_spec.rb +150 -129
  151. data/spec/core_ext/array_spec.rb +4 -23
  152. data/spec/core_ext/insertion_spec.rb +37 -0
  153. data/spec/docstring_spec.rb +63 -0
  154. data/spec/handlers/attribute_handler_spec.rb +4 -0
  155. data/spec/handlers/base_spec.rb +98 -26
  156. data/spec/handlers/class_handler_spec.rb +5 -1
  157. data/spec/handlers/examples/attribute_handler_001.rb.txt +5 -0
  158. data/spec/handlers/examples/class_handler_001.rb.txt +4 -0
  159. data/spec/handlers/examples/module_handler_001.rb.txt +6 -1
  160. data/spec/handlers/examples/visibility_handler_001.rb.txt +4 -0
  161. data/spec/handlers/method_handler_spec.rb +5 -0
  162. data/spec/handlers/module_handler_spec.rb +4 -0
  163. data/spec/handlers/visibility_handler_spec.rb +6 -0
  164. data/spec/parser/source_parser_spec.rb +24 -0
  165. data/spec/registry_spec.rb +44 -8
  166. data/spec/server/adapter_spec.rb +38 -0
  167. data/spec/server/commands/base_spec.rb +87 -0
  168. data/spec/server/commands/static_file_command_spec.rb +67 -0
  169. data/spec/server/doc_server_serializer_spec.rb +58 -0
  170. data/spec/server/router_spec.rb +115 -0
  171. data/spec/server/spec_helper.rb +17 -0
  172. data/spec/server/static_caching_spec.rb +39 -0
  173. data/spec/server/webrick_servlet_spec.rb +20 -0
  174. data/spec/templates/constant_spec.rb +40 -0
  175. data/spec/templates/engine_spec.rb +9 -5
  176. data/spec/templates/examples/class002.html +1 -3
  177. data/spec/templates/examples/constant001.txt +25 -0
  178. data/spec/templates/examples/constant002.txt +7 -0
  179. data/spec/templates/examples/constant003.txt +11 -0
  180. data/spec/templates/examples/module001.txt +1 -1
  181. data/spec/templates/examples/module002.html +319 -0
  182. data/spec/templates/helpers/base_helper_spec.rb +2 -2
  183. data/spec/templates/helpers/html_helper_spec.rb +93 -3
  184. data/spec/templates/helpers/html_syntax_highlight_helper_spec.rb +5 -0
  185. data/spec/templates/helpers/markup_helper_spec.rb +94 -67
  186. data/spec/templates/helpers/shared_signature_examples.rb +9 -0
  187. data/spec/templates/helpers/text_helper_spec.rb +12 -0
  188. data/spec/templates/module_spec.rb +21 -4
  189. data/spec/templates/section_spec.rb +146 -0
  190. data/spec/templates/template_spec.rb +9 -20
  191. data/templates/default/class/setup.rb +5 -5
  192. data/templates/default/constant/text/header.erb +11 -0
  193. data/templates/default/constant/text/setup.rb +3 -0
  194. data/templates/default/fulldoc/html/css/style.css +29 -3
  195. data/templates/default/fulldoc/html/js/app.js +67 -1
  196. data/templates/default/fulldoc/html/js/full_list.js +3 -8
  197. data/templates/default/fulldoc/html/js/jquery.js +150 -15
  198. data/templates/default/fulldoc/html/setup.rb +9 -0
  199. data/templates/default/layout/html/footer.erb +1 -1
  200. data/templates/default/layout/html/setup.rb +7 -25
  201. data/templates/default/method_details/html/source.erb +1 -1
  202. data/templates/default/module/html/attribute_summary.erb +2 -2
  203. data/templates/default/module/html/method_summary.erb +2 -2
  204. data/templates/default/module/setup.rb +27 -4
  205. data/templates/default/onefile/html/files.erb +5 -0
  206. data/templates/default/onefile/html/layout.erb +22 -0
  207. data/templates/default/onefile/html/readme.erb +3 -0
  208. data/templates/default/onefile/html/setup.rb +40 -0
  209. data/templates/default/root/html/setup.rb +1 -0
  210. data/templates/default/tags/setup.rb +26 -33
  211. metadata +80 -10
data/lib/yard/cli/yri.rb CHANGED
@@ -3,10 +3,26 @@ require 'rbconfig'
3
3
  module YARD
4
4
  module CLI
5
5
  # A tool to view documentation in the console like `ri`
6
- class YRI < Base
6
+ class YRI < Command
7
+ # The location in {YARD::CONFIG_DIR} where the YRI cache file is loaded
8
+ # from.
7
9
  CACHE_FILE = File.expand_path('~/.yard/yri_cache')
10
+
11
+ # A file containing all paths, delimited by newlines, to search for
12
+ # yardoc databases.
13
+ # @since 0.5.1
8
14
  SEARCH_PATHS_FILE = File.expand_path('~/.yard/yri_search_paths')
9
15
 
16
+ # Default search paths that should be loaded dynamically into YRI. These paths
17
+ # take precedence over all other paths ({SEARCH_PATHS_FILE} and RubyGems
18
+ # paths). To add a path, call:
19
+ #
20
+ # DEFAULT_SEARCH_PATHS.push("/path/to/.yardoc")
21
+ #
22
+ # @return [Array<String>] a list of extra search paths
23
+ # @since 0.6.0
24
+ DEFAULT_SEARCH_PATHS = []
25
+
10
26
  # Helper method to run the utility on an instance.
11
27
  # @see #run
12
28
  def self.run(*args) new.run(*args) end
@@ -20,7 +36,11 @@ module YARD
20
36
  load_cache
21
37
  @search_paths.uniq!
22
38
  end
23
-
39
+
40
+ def description
41
+ "A tool to view documentation in the console like `ri`"
42
+ end
43
+
24
44
  # Runs the command-line utility.
25
45
  #
26
46
  # @example
@@ -48,11 +68,16 @@ module YARD
48
68
 
49
69
  protected
50
70
 
71
+ # Prints the command usage
72
+ # @return [void]
73
+ # @since 0.5.6
51
74
  def print_usage
52
75
  puts "Usage: yri [options] <Path to object>"
53
76
  puts "See yri --help for more options."
54
77
  end
55
78
 
79
+ # Caches the .yardoc file where an object can be found in the {CACHE_FILE}
80
+ # @return [void]
56
81
  def cache_object(name, path)
57
82
  return if path == Registry.yardoc_file
58
83
  @cache[name] = path
@@ -64,6 +89,8 @@ module YARD
64
89
  end
65
90
  end
66
91
 
92
+ # @param [CodeObjects::Base] object the object to print.
93
+ # @return [String] the formatted output for an object.
67
94
  def print_object(object)
68
95
  if object.type == :method && object.is_alias?
69
96
  tmp = P(object.namespace, (object.scope == :instance ? "#" : "") +
@@ -73,6 +100,12 @@ module YARD
73
100
  object.format(:serializer => @serializer)
74
101
  end
75
102
 
103
+ # Locates an object by name starting in the cached paths and then
104
+ # searching through any search paths.
105
+ #
106
+ # @param [String] name the full name of the object
107
+ # @return [CodeObjects::Base] an object if found
108
+ # @return [nil] if no object is found
76
109
  def find_object(name)
77
110
  @search_paths.unshift(@cache[name]) if @cache[name]
78
111
  @search_paths.unshift(Registry.yardoc_file)
@@ -93,6 +126,8 @@ module YARD
93
126
 
94
127
  private
95
128
 
129
+ # Loads {CACHE_FILE}
130
+ # @return [void]
96
131
  def load_cache
97
132
  return unless File.file?(CACHE_FILE)
98
133
  File.readlines(CACHE_FILE).each do |line|
@@ -101,22 +136,28 @@ module YARD
101
136
  end
102
137
  end
103
138
 
139
+ # Adds all RubyGems yardoc files to search paths
140
+ # @return [void]
104
141
  def add_gem_paths
105
142
  require 'rubygems'
143
+ gem_paths = []
106
144
  Gem.source_index.find_name('').each do |spec|
107
145
  if yfile = Registry.yardoc_file_for_gem(spec.name)
108
146
  if spec.name =~ /^yard-doc-/
109
- @search_paths.unshift(yfile)
147
+ gem_paths.unshift(yfile)
110
148
  else
111
- @search_paths.push(yfile)
149
+ gem_paths.push(yfile)
112
150
  end
113
151
  end
114
152
  end
153
+ @search_paths += gem_paths
115
154
  rescue LoadError
116
155
  end
117
156
 
118
157
  # Adds paths in {SEARCH_PATHS_FILE}
158
+ # @since 0.5.1
119
159
  def add_default_paths
160
+ @search_paths.push(*DEFAULT_SEARCH_PATHS)
120
161
  return unless File.file?(SEARCH_PATHS_FILE)
121
162
  paths = File.readlines(SEARCH_PATHS_FILE).map {|l| l.strip }
122
163
  @search_paths.push(*paths)
@@ -28,31 +28,55 @@ module YARD
28
28
  end
29
29
 
30
30
 
31
+ # Namespace separator
31
32
  NSEP = '::'
33
+
34
+ # Regex-quoted namespace separator
32
35
  NSEPQ = NSEP
36
+
37
+ # Instance method separator
33
38
  ISEP = '#'
39
+
40
+ # Regex-quoted instance method separator
34
41
  ISEPQ = ISEP
42
+
43
+ # Class method separator
35
44
  CSEP = '.'
45
+
46
+ # Regex-quoted class method separator
36
47
  CSEPQ = Regexp.quote CSEP
48
+
49
+ # Regular expression to match constant name
37
50
  CONSTANTMATCH = /[A-Z]\w*/
51
+
52
+ # Regular expression to match namespaces (const A or complex path A::B)
38
53
  NAMESPACEMATCH = /(?:(?:#{NSEPQ})?#{CONSTANTMATCH})+/
54
+
55
+ # Regular expression to match a method name
39
56
  METHODNAMEMATCH = /[a-zA-Z_]\w*[!?=]?|[-+~]\@|<<|>>|=~|===?|<=>|[<>]=?|\*\*|[-\/+%^&*~`|]|\[\]=?/
40
- METHODMATCH = /(?:(?:#{NAMESPACEMATCH}|self)\s*(?:#{CSEPQ}|#{NSEPQ})\s*)?#{METHODNAMEMATCH}/
41
57
 
58
+ # Regular expression to match a fully qualified method def (self.foo, Class.foo).
59
+ METHODMATCH = /(?:(?:#{NAMESPACEMATCH}|[a-z]\w*)\s*(?:#{CSEPQ}|#{NSEPQ})\s*)?#{METHODNAMEMATCH}/
60
+
61
+ # All builtin Ruby exception classes for inheritance tree.
42
62
  BUILTIN_EXCEPTIONS = ["SecurityError", "Exception", "NoMethodError", "FloatDomainError",
43
63
  "IOError", "TypeError", "NotImplementedError", "SystemExit", "Interrupt", "SyntaxError",
44
64
  "RangeError", "NoMemoryError", "ArgumentError", "ThreadError", "EOFError", "RuntimeError",
45
65
  "ZeroDivisionError", "StandardError", "LoadError", "NameError", "LocalJumpError", "SystemCallError",
46
66
  "SignalException", "ScriptError", "SystemStackError", "RegexpError", "IndexError"]
47
- # Note: MatchingData is a 1.8.x legacy class
67
+ # All builtin Ruby classes for inheritance tree.
68
+ # @note MatchingData is a 1.8.x legacy class
48
69
  BUILTIN_CLASSES = ["TrueClass", "Array", "Dir", "Struct", "UnboundMethod", "Object", "Fixnum", "Float",
49
70
  "ThreadGroup", "MatchingData", "MatchData", "Proc", "Binding", "Class", "Time", "Bignum", "NilClass", "Symbol",
50
71
  "Numeric", "String", "Data", "MatchData", "Regexp", "Integer", "File", "IO", "Range", "FalseClass",
51
72
  "Method", "Continuation", "Thread", "Hash", "Module"] + BUILTIN_EXCEPTIONS
73
+ # All builtin Ruby modules for mixin handling.
52
74
  BUILTIN_MODULES = ["ObjectSpace", "Signal", "Marshal", "Kernel", "Process", "GC", "FileTest", "Enumerable",
53
75
  "Comparable", "Errno", "Precision", "Math"]
76
+ # All builtin Ruby classes and modules.
54
77
  BUILTIN_ALL = BUILTIN_CLASSES + BUILTIN_MODULES
55
78
 
79
+ # Hash of {BUILTIN_EXCEPTIONS} as keys and true as value (for O(1) lookups)
56
80
  BUILTIN_EXCEPTIONS_HASH = BUILTIN_EXCEPTIONS.inject({}) {|h,n| h.update(n => true) }
57
81
 
58
82
  # +Base+ is the superclass of all code objects recognized by YARD. A code
@@ -91,7 +115,7 @@ module YARD
91
115
  attr_reader :files
92
116
 
93
117
  # The namespace the object is defined in. If the object is in the
94
- # top level namespace, this is {Registry#root}
118
+ # top level namespace, this is {Registry.root}
95
119
  # @return [NamespaceObject] the namespace object
96
120
  attr_reader :namespace
97
121
 
@@ -120,10 +144,21 @@ module YARD
120
144
  # @return [Boolean] true if the method is conditionally defined at runtime
121
145
  attr_accessor :dynamic
122
146
 
147
+ # @return [String] the group this object is associated with
148
+ # @since 0.6.0
149
+ attr_accessor :group
150
+
123
151
  # Is the object defined conditionally at runtime?
124
152
  # @see #dynamic
125
153
  def dynamic?; @dynamic end
126
154
 
155
+ # This attribute exists in order to maintain a consistent interface
156
+ # with the {MethodObject} class, so that a {Verifier} expression need
157
+ # not check the object type before accessing visibility.
158
+ #
159
+ # @return [Symbol] always returns public for a base object.
160
+ def visibility; :public end
161
+
127
162
  class << self
128
163
  # Allocates a new code object
129
164
  # @return [Base]
@@ -137,26 +172,11 @@ module YARD
137
172
  return new(Proxy.new(namespace, $`), $1, *args, &block)
138
173
  end
139
174
 
140
- keyname = namespace && namespace.respond_to?(:path) ? namespace.path : ''
141
- if self == RootObject
142
- keyname = :root
143
- elsif self == MethodObject
144
- keyname += (args.first && args.first.to_sym == :class ? CSEP : ISEP) + name.to_s
145
- elsif keyname.empty?
146
- keyname = name.to_s
147
- else
148
- keyname += NSEP + name.to_s
149
- end
150
-
151
- obj = Registry.objects[keyname]
152
- obj = nil if obj && obj.class != self
153
-
154
- if self != RootObject && obj
155
- yield(obj) if block_given?
156
- obj
157
- else
158
- Registry.objects[keyname] = super(namespace, name, *args, &block)
159
- end
175
+ obj = super(namespace, name, *args)
176
+ existing_obj = Registry.at(obj.path)
177
+ obj = existing_obj if existing_obj && existing_obj.class == self
178
+ yield(obj) if block_given?
179
+ obj
160
180
  end
161
181
 
162
182
  # Compares the class with subclasses
@@ -176,13 +196,13 @@ module YARD
176
196
  # CodeObjects::Base.new(P("X::Y"), :Z) # or
177
197
  # CodeObjects::Base.new(Registry.root, "X::Y")
178
198
  # @param [NamespaceObject] namespace the namespace the object belongs in,
179
- # {Registry#root} or :root should be provided if it is associated with
199
+ # {Registry.root} or :root should be provided if it is associated with
180
200
  # the top level namespace.
181
201
  # @param [Symbol, String] name the name (or complex path) of the object.
182
202
  # @yield [self] a block to perform any extra initialization on the object
183
203
  # @yieldparam [Base] self the newly initialized code object
184
204
  # @return [Base] the newly created object
185
- def initialize(namespace, name, *args)
205
+ def initialize(namespace, name, *args, &block)
186
206
  if namespace && namespace != :root &&
187
207
  !namespace.is_a?(NamespaceObject) && !namespace.is_a?(Proxy)
188
208
  raise ArgumentError, "Invalid namespace object: #{namespace}"
@@ -220,6 +240,7 @@ module YARD
220
240
  def add_file(file, line = nil, has_comments = false)
221
241
  raise(ArgumentError, "file cannot be nil or empty") if file.nil? || file == ''
222
242
  obj = [file.to_s, line]
243
+ return if files.include?(obj)
223
244
  if has_comments && !@current_file_has_comments
224
245
  @current_file_has_comments = true
225
246
  @files.unshift(obj)
@@ -319,6 +340,18 @@ module YARD
319
340
  @source = format_source(statement.to_s)
320
341
  end
321
342
  end
343
+
344
+ def docstring
345
+ value = case @docstring
346
+ when Proxy
347
+ Docstring.new("", self)
348
+ when Base
349
+ @docstring.docstring
350
+ else
351
+ @docstring
352
+ end
353
+ @docstring_extra ? value + @docstring_extra : value
354
+ end
322
355
 
323
356
  # Attaches a docstring to a code oject by parsing the comments attached to the statement
324
357
  # and filling the {#tags} and {#docstring} methods with the parsed information.
@@ -327,7 +360,14 @@ module YARD
327
360
  # the comments attached to the code object to be parsed
328
361
  # into a docstring and meta tags.
329
362
  def docstring=(comments)
330
- @docstring = Docstring === comments ? comments : Docstring.new(comments, self)
363
+ if comments =~ /^\s*\(see (\S+)\s*\)(?:\s|$)/
364
+ path, extra = $1, $'
365
+ @docstring_extra = extra.empty? ? nil : Docstring.new(extra, self)
366
+ @docstring = Proxy.new(namespace, path)
367
+ else
368
+ @docstring_extra = nil
369
+ @docstring = Docstring === comments ? comments : Docstring.new(comments, self)
370
+ end
331
371
  end
332
372
 
333
373
  # Default type is the lowercase class name without the "Object" suffix.
@@ -358,6 +398,7 @@ module YARD
358
398
 
359
399
  # @param [Base, String] other another code object (or object path)
360
400
  # @return [String] the shortest relative path from this object to +other+
401
+ # @since 0.5.3
361
402
  def relative_path(other)
362
403
  other = other.path if other.respond_to?(:path)
363
404
  return other unless namespace
@@ -391,7 +432,7 @@ module YARD
391
432
  # Sets the namespace the object is defined in.
392
433
  #
393
434
  # @param [NamespaceObject, :root, nil] obj the new namespace (:root
394
- # for {Registry#root}). If obj is nil, the object is unregistered
435
+ # for {Registry.root}). If obj is nil, the object is unregistered
395
436
  # from the Registry.
396
437
  def namespace=(obj)
397
438
  if @namespace
@@ -402,6 +443,8 @@ module YARD
402
443
  @namespace = (obj == :root ? Registry.root : obj)
403
444
 
404
445
  if @namespace
446
+ reg_obj = Registry.at(path)
447
+ return if reg_obj && reg_obj.class == self.class
405
448
  @namespace.children << self unless @namespace.is_a?(Proxy)
406
449
  Registry.register(self)
407
450
  end
@@ -412,15 +455,15 @@ module YARD
412
455
 
413
456
  # Gets a tag from the {#docstring}
414
457
  # @see Docstring#tag
415
- def tag(name); @docstring.tag(name) end
458
+ def tag(name); docstring.tag(name) end
416
459
 
417
460
  # Gets a list of tags from the {#docstring}
418
461
  # @see Docstring#tags
419
- def tags(name = nil); @docstring.tags(name) end
462
+ def tags(name = nil); docstring.tags(name) end
420
463
 
421
464
  # Tests if the {#docstring} has a tag
422
465
  # @see Docstring#has_tag?
423
- def has_tag?(name); @docstring.has_tag?(name) end
466
+ def has_tag?(name); docstring.has_tag?(name) end
424
467
 
425
468
  # @return whether or not this object is a RootObject
426
469
  def root?; false end
@@ -1,4 +1,6 @@
1
1
  module YARD::CodeObjects
2
+ # A ClassObject represents a Ruby class in source code. It is a {ModuleObject}
3
+ # with extra inheritance semantics through the superclass.
2
4
  class ClassObject < NamespaceObject
3
5
  # The {ClassObject} that this class object inherits from in Ruby source.
4
6
  # @return [ClassObject] a class object that is the superclass of this one
@@ -59,7 +61,12 @@ module YARD::CodeObjects
59
61
  # @return [Array<MethodObject>] the list of methods that matched
60
62
  def meths(opts = {})
61
63
  opts = SymbolHash[:inherited => true].update(opts)
62
- super(opts) + (opts[:inherited] ? inherited_meths(opts) : [])
64
+ list = super(opts)
65
+ list += inherited_meths(opts).reject do |o|
66
+ next(false) if opts[:all]
67
+ list.find {|o2| o2.name == o.name && o2.scope == o.scope }
68
+ end if opts[:inherited]
69
+ list
63
70
  end
64
71
 
65
72
  # Returns only the methods that were inherited.
@@ -71,6 +78,7 @@ module YARD::CodeObjects
71
78
  list
72
79
  else
73
80
  list += superclass.meths(opts).reject do |o|
81
+ next(false) if opts[:all]
74
82
  child(:name => o.name, :scope => o.scope) ||
75
83
  list.find {|o2| o2.name == o.name && o2.scope == o.scope }
76
84
  end
@@ -61,17 +61,20 @@ module YARD::CodeObjects
61
61
  # Returns the read/writer info for the attribute if it is one
62
62
  # @return [SymbolHash] if there is information about the attribute
63
63
  # @return [nil] if the method is not an attribute
64
+ # @since 0.5.3
64
65
  def attr_info
65
66
  return nil unless namespace.is_a?(NamespaceObject)
66
67
  namespace.attributes[scope][name.to_s.gsub(/=$/, '')]
67
68
  end
68
69
 
69
70
  # @return [Boolean] whether the method is a writer attribute
71
+ # @since 0.5.3
70
72
  def writer?
71
73
  !!((info = attr_info) && info[:write] == self)
72
74
  end
73
75
 
74
76
  # @return [Boolean] whether the method is a reader attribute
77
+ # @since 0.5.3
75
78
  def reader?
76
79
  !!((info = attr_info) && info[:read] == self)
77
80
  end
@@ -97,6 +100,14 @@ module YARD::CodeObjects
97
100
  explicit ? true : false
98
101
  end
99
102
 
103
+ # @return [MethodObject] the object that this method overrides
104
+ # @return [nil] if it does not override a method
105
+ # @since 0.6.0
106
+ def overridden_method
107
+ meths = namespace.meths(:all => true)
108
+ meths.find {|m| m.path != path && m.name == name && m.scope == scope }
109
+ end
110
+
100
111
  # Returns all alias names of the object
101
112
  # @return [Array<Symbol>] the alias names
102
113
  def aliases
@@ -6,6 +6,10 @@ module YARD::CodeObjects
6
6
  attr_writer :constants, :cvars, :mixins, :child, :meths
7
7
  attr_writer :class_attributes, :instance_attributes
8
8
  attr_writer :included_constants, :included_meths
9
+
10
+ # @return [Array<String>] a list of ordered group names inside the namespace
11
+ # @since 0.6.0
12
+ attr_accessor :groups
9
13
 
10
14
  # The list of objects defined in this namespace
11
15
  # @return [Array<Base>] a list of objects
@@ -55,6 +59,7 @@ module YARD::CodeObjects
55
59
  @instance_mixins = CodeObjectList.new(self)
56
60
  @attributes = SymbolHash[:class => SymbolHash.new, :instance => SymbolHash.new]
57
61
  @aliases = {}
62
+ @groups = []
58
63
  super
59
64
  end
60
65
 
@@ -139,9 +144,10 @@ module YARD::CodeObjects
139
144
  def included_meths(opts = {})
140
145
  opts = SymbolHash[:scope => [:instance, :class]].update(opts)
141
146
  [opts[:scope]].flatten.map do |scope|
142
- mixins(scope).reverse.inject([]) do |list, mixin|
147
+ mixins(scope).inject([]) do |list, mixin|
143
148
  next list if mixin.is_a?(Proxy)
144
149
  arr = mixin.meths(opts.merge(:scope => :instance)).reject do |o|
150
+ next false if opts[:all]
145
151
  child(:name => o.name, :scope => scope) || list.find {|o2| o2.name == o.name }
146
152
  end
147
153
  arr.map! {|o| ExtendedMethodObject.new(o) } if scope == :class
@@ -164,7 +170,7 @@ module YARD::CodeObjects
164
170
  # Returns constants included from any mixins
165
171
  # @return [Array<ConstantObject>] a list of constant objects
166
172
  def included_constants
167
- instance_mixins.reverse.inject([]) do |list, mixin|
173
+ instance_mixins.inject([]) do |list, mixin|
168
174
  if mixin.respond_to? :constants
169
175
  list += mixin.constants.reject do |o|
170
176
  child(:name => o.name) || list.find {|o2| o2.name == o.name }
@@ -6,14 +6,14 @@ module YARD
6
6
  # The Proxy class is a way to lazily resolve code objects in
7
7
  # cases where the object may not yet exist. A proxy simply stores
8
8
  # an unresolved path until a method is called on the object, at which
9
- # point it does a lookup using {Registry#resolve}. If the object is
9
+ # point it does a lookup using {Registry.resolve}. If the object is
10
10
  # not found, a warning is raised and {ProxyMethodError} might be raised.
11
11
  #
12
12
  # @example Creates a Proxy to the String class from a module
13
13
  # # When the String class is parsed this method will
14
14
  # # begin to act like the String ClassObject.
15
15
  # Proxy.new(mymoduleobj, "String")
16
- # @see Registry#resolve
16
+ # @see Registry.resolve
17
17
  # @see ProxyMethodError
18
18
  class Proxy
19
19
  def self.===(other) other.is_a?(self) end