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.
- data/LICENSE +1 -1
- data/README.markdown +200 -0
- data/Rakefile +6 -1
- data/benchmarks/format_args.rb +46 -0
- data/benchmarks/parsing.rb +13 -1
- data/benchmarks/rdoc_vs_yardoc.rb +10 -0
- data/benchmarks/ripper_parser.rb +12 -0
- data/docs/CODE_OBJECTS.markdown +121 -0
- data/docs/FAQ.markdown +34 -0
- data/docs/GENERATORS.markdown +211 -0
- data/docs/GETTING_STARTED.markdown +263 -0
- data/docs/GLOSSARY.markdown +13 -0
- data/docs/HANDLERS.markdown +158 -0
- data/docs/OVERVIEW.markdown +64 -0
- data/docs/PARSER.markdown +180 -0
- data/docs/TAGS.markdown +181 -0
- data/docs/WHATSNEW.markdown +96 -0
- data/docs/images/code-objects-class-diagram.png +0 -0
- data/docs/images/handlers-class-diagram.png +0 -0
- data/docs/images/overview-class-diagram.png +0 -0
- data/docs/images/parser-class-diagram.png +0 -0
- data/docs/images/tags-class-diagram.png +0 -0
- data/lib/yard.rb +4 -1
- data/lib/yard/autoload.rb +79 -31
- data/lib/yard/cli/yard_graph.rb +8 -2
- data/lib/yard/cli/yardoc.rb +61 -8
- data/lib/yard/code_objects/base.rb +78 -135
- data/lib/yard/code_objects/class_object.rb +9 -8
- data/lib/yard/code_objects/constant_object.rb +1 -0
- data/lib/yard/code_objects/extended_method_object.rb +9 -0
- data/lib/yard/code_objects/method_object.rb +18 -5
- data/lib/yard/code_objects/module_object.rb +8 -1
- data/lib/yard/code_objects/namespace_object.rb +25 -16
- data/lib/yard/code_objects/proxy.rb +22 -22
- data/lib/yard/core_ext/file.rb +1 -1
- data/lib/yard/core_ext/string.rb +0 -4
- data/lib/yard/core_ext/symbol_hash.rb +3 -2
- data/lib/yard/docstring.rb +180 -0
- data/lib/yard/generators/base.rb +33 -13
- data/lib/yard/generators/class_generator.rb +4 -2
- data/lib/yard/generators/constants_generator.rb +3 -2
- data/lib/yard/generators/full_doc_generator.rb +76 -9
- data/lib/yard/generators/helpers/base_helper.rb +18 -1
- data/lib/yard/generators/helpers/filter_helper.rb +2 -2
- data/lib/yard/generators/helpers/html_helper.rb +94 -39
- data/lib/yard/generators/helpers/html_syntax_highlight_helper.rb +49 -0
- data/lib/yard/generators/helpers/markup_helper.rb +86 -0
- data/lib/yard/generators/helpers/method_helper.rb +23 -7
- data/lib/yard/generators/method_generator.rb +15 -3
- data/lib/yard/generators/method_listing_generator.rb +3 -3
- data/lib/yard/generators/mixins_generator.rb +8 -2
- data/lib/yard/generators/module_generator.rb +3 -2
- data/lib/yard/generators/overloads_generator.rb +20 -0
- data/lib/yard/generators/quick_doc_generator.rb +3 -9
- data/lib/yard/generators/root_generator.rb +32 -0
- data/lib/yard/generators/source_generator.rb +2 -17
- data/lib/yard/generators/tags_generator.rb +34 -6
- data/lib/yard/generators/uml_generator.rb +16 -6
- data/lib/yard/handlers/base.rb +88 -253
- data/lib/yard/handlers/processor.rb +72 -0
- data/lib/yard/handlers/ruby/alias_handler.rb +38 -0
- data/lib/yard/handlers/ruby/attribute_handler.rb +69 -0
- data/lib/yard/handlers/ruby/base.rb +72 -0
- data/lib/yard/handlers/ruby/class_condition_handler.rb +70 -0
- data/lib/yard/handlers/ruby/class_handler.rb +74 -0
- data/lib/yard/handlers/ruby/class_variable_handler.rb +11 -0
- data/lib/yard/handlers/ruby/constant_handler.rb +12 -0
- data/lib/yard/handlers/ruby/exception_handler.rb +22 -0
- data/lib/yard/handlers/ruby/extend_handler.rb +19 -0
- data/lib/yard/handlers/{alias_handler.rb → ruby/legacy/alias_handler.rb} +3 -4
- data/lib/yard/handlers/{attribute_handler.rb → ruby/legacy/attribute_handler.rb} +2 -2
- data/lib/yard/handlers/ruby/legacy/base.rb +198 -0
- data/lib/yard/handlers/{class_handler.rb → ruby/legacy/class_handler.rb} +18 -6
- data/lib/yard/handlers/{class_variable_handler.rb → ruby/legacy/class_variable_handler.rb} +1 -1
- data/lib/yard/handlers/{constant_handler.rb → ruby/legacy/constant_handler.rb} +2 -2
- data/lib/yard/handlers/{exception_handler.rb → ruby/legacy/exception_handler.rb} +3 -3
- data/lib/yard/handlers/ruby/legacy/extend_handler.rb +18 -0
- data/lib/yard/handlers/ruby/legacy/method_handler.rb +31 -0
- data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +28 -0
- data/lib/yard/handlers/{module_handler.rb → ruby/legacy/module_handler.rb} +1 -1
- data/lib/yard/handlers/{visibility_handler.rb → ruby/legacy/visibility_handler.rb} +1 -1
- data/lib/yard/handlers/{yield_handler.rb → ruby/legacy/yield_handler.rb} +4 -4
- data/lib/yard/handlers/ruby/method_condition_handler.rb +7 -0
- data/lib/yard/handlers/ruby/method_handler.rb +48 -0
- data/lib/yard/handlers/ruby/mixin_handler.rb +25 -0
- data/lib/yard/handlers/ruby/module_handler.rb +9 -0
- data/lib/yard/handlers/ruby/visibility_handler.rb +18 -0
- data/lib/yard/handlers/ruby/yield_handler.rb +28 -0
- data/lib/yard/parser/ruby/ast_node.rb +263 -0
- data/lib/yard/parser/{ruby_lex.rb → ruby/legacy/ruby_lex.rb} +258 -259
- data/lib/yard/parser/{statement.rb → ruby/legacy/statement.rb} +8 -4
- data/lib/yard/parser/ruby/legacy/statement_list.rb +262 -0
- data/lib/yard/parser/{token_list.rb → ruby/legacy/token_list.rb} +1 -1
- data/lib/yard/parser/ruby/ruby_parser.rb +307 -0
- data/lib/yard/parser/source_parser.rb +76 -45
- data/lib/yard/rake/yardoc_task.rb +6 -1
- data/lib/yard/registry.rb +45 -19
- data/lib/yard/serializers/file_system_serializer.rb +8 -3
- data/lib/yard/tags/default_factory.rb +70 -10
- data/lib/yard/tags/default_tag.rb +12 -0
- data/lib/yard/tags/library.rb +65 -26
- data/lib/yard/tags/option_tag.rb +12 -0
- data/lib/yard/tags/overload_tag.rb +62 -0
- data/lib/yard/tags/ref_tag.rb +7 -0
- data/lib/yard/tags/ref_tag_list.rb +27 -0
- data/lib/yard/tags/tag.rb +1 -0
- data/lib/yard/tags/tag_format_error.rb +6 -0
- data/spec/cli/yardoc_spec.rb +43 -0
- data/spec/code_objects/base_spec.rb +56 -68
- data/spec/code_objects/class_object_spec.rb +18 -6
- data/spec/code_objects/constants_spec.rb +2 -0
- data/spec/code_objects/method_object_spec.rb +33 -5
- data/spec/code_objects/module_object_spec.rb +66 -8
- data/spec/code_objects/namespace_object_spec.rb +37 -17
- data/spec/code_objects/proxy_spec.rb +13 -2
- data/spec/core_ext/string_spec.rb +14 -2
- data/spec/core_ext/symbol_hash_spec.rb +9 -3
- data/spec/docstring_spec.rb +139 -0
- data/spec/generators/full_doc_generator_spec.rb +29 -0
- data/spec/generators/helpers/html_helper_spec.rb +74 -0
- data/spec/generators/helpers/markup_helper_spec.rb +95 -0
- data/spec/handlers/alias_handler_spec.rb +16 -3
- data/spec/handlers/attribute_handler_spec.rb +1 -1
- data/spec/handlers/base_spec.rb +15 -141
- data/spec/handlers/class_condition_handler_spec.rb +49 -0
- data/spec/handlers/class_handler_spec.rb +44 -3
- data/spec/handlers/class_variable_handler_spec.rb +1 -1
- data/spec/handlers/constant_handler_spec.rb +1 -1
- data/spec/handlers/examples/alias_handler_001.rb.txt +7 -3
- data/spec/handlers/examples/class_condition_handler_001.rb.txt +61 -0
- data/spec/handlers/examples/class_handler_001.rb.txt +33 -0
- data/spec/handlers/examples/exception_handler_001.rb.txt +1 -1
- data/spec/handlers/examples/extend_handler_001.rb.txt +8 -0
- data/spec/handlers/examples/method_condition_handler_001.rb.txt +10 -0
- data/spec/handlers/examples/method_handler_001.rb.txt +16 -4
- data/spec/handlers/examples/mixin_handler_001.rb.txt +10 -2
- data/spec/handlers/examples/module_handler_001.rb.txt +4 -0
- data/spec/handlers/examples/visibility_handler_001.rb.txt +1 -1
- data/spec/handlers/exception_handler_spec.rb +2 -2
- data/spec/handlers/extend_handler_spec.rb +15 -0
- data/spec/handlers/legacy_base_spec.rb +128 -0
- data/spec/handlers/method_condition_handler_spec.rb +14 -0
- data/spec/handlers/method_handler_spec.rb +38 -5
- data/spec/handlers/mixin_handler_spec.rb +15 -7
- data/spec/handlers/module_handler_spec.rb +5 -1
- data/spec/handlers/processor_spec.rb +19 -0
- data/spec/handlers/ruby/base_spec.rb +90 -0
- data/spec/handlers/ruby/legacy/base_spec.rb +53 -0
- data/spec/handlers/spec_helper.rb +22 -16
- data/spec/handlers/visibility_handler_spec.rb +4 -4
- data/spec/handlers/yield_handler_spec.rb +1 -1
- data/spec/parser/ruby/ast_node_spec.rb +15 -0
- data/spec/parser/ruby/legacy/statement_list_spec.rb +145 -0
- data/spec/parser/{token_list_spec.rb → ruby/legacy/token_list_spec.rb} +4 -4
- data/spec/parser/source_parser_spec.rb +0 -15
- data/spec/rake/yardoc_task_spec.rb +48 -0
- data/spec/registry_spec.rb +28 -2
- data/spec/serializers/file_system_serializer_spec.rb +7 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/tags/default_factory_spec.rb +135 -0
- data/spec/tags/default_tag_spec.rb +11 -0
- data/spec/tags/overload_tag_spec.rb +35 -0
- data/spec/tags/ref_tag_list_spec.rb +53 -0
- data/templates/default/attributes/html/header.erb +17 -5
- data/templates/default/attributes/text/header.erb +1 -1
- data/templates/default/fulldoc/html/all_files.erb +19 -0
- data/templates/default/fulldoc/html/all_methods.erb +8 -7
- data/templates/default/fulldoc/html/all_namespaces.erb +4 -1
- data/templates/default/fulldoc/html/app.js +1 -1
- data/templates/default/fulldoc/html/{readme.erb → file.erb} +2 -2
- data/templates/default/fulldoc/html/header.erb +1 -1
- data/templates/default/fulldoc/html/index.erb +4 -3
- data/templates/default/fulldoc/html/style.css +13 -3
- data/templates/default/fulldoc/html/syntax_highlight.css +8 -5
- data/templates/default/method/text/header.erb +1 -0
- data/templates/default/method/text/title.erb +1 -0
- data/templates/default/methodsignature/html/main.erb +10 -8
- data/templates/default/methodsignature/text/main.erb +4 -1
- data/templates/default/methodsummary/html/summary.erb +8 -4
- data/templates/default/methodsummary/text/summary.erb +4 -1
- data/templates/default/mixins/html/header.erb +3 -3
- data/templates/default/overloads/html/header.erb +8 -0
- data/templates/default/overloads/text/header.erb +8 -0
- data/templates/default/root/html/header.erb +4 -0
- data/templates/default/tags/html/example.erb +20 -0
- data/templates/default/tags/html/option.erb +27 -0
- data/templates/default/tags/html/param.erb +21 -0
- data/templates/default/tags/html/tags.erb +4 -1
- data/templates/default/tags/html/todo.erb +8 -0
- data/templates/default/tags/text/example.erb +14 -0
- data/templates/default/tags/text/header.erb +3 -3
- data/templates/default/tags/text/option.erb +5 -0
- data/templates/default/tags/text/param.erb +9 -0
- data/templates/default/uml/dot/dependencies.erb +1 -1
- data/templates/default/uml/dot/info.erb +1 -1
- data/templates/default/uml/dot/superclasses.erb +2 -2
- data/templates/javadoc/methodsummary/html/summary.erb +2 -2
- data/templates/javadoc/mixins/html/header.erb +3 -3
- metadata +108 -139
- data/README +0 -211
- data/lib/yard/handlers/method_handler.rb +0 -27
- data/lib/yard/handlers/mixin_handler.rb +0 -16
- data/lib/yard/parser/statement_list.rb +0 -167
- 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 = /(?:(?:#{
|
24
|
-
METHODNAMEMATCH = /[a-zA-Z_]\w*[
|
25
|
-
METHODMATCH = /(?:(?:#{NAMESPACEMATCH}|self)\s*(
|
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", "
|
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"
|
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
|
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
|
-
|
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]] =
|
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
|
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
|
-
@
|
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(/#{
|
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
|
-
|
208
|
-
|
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 =
|
21
|
-
if superclass.is_a?
|
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
|
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
|
@@ -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)
|
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
|
51
|
+
((prefix ? (sep == ISEP ? sep : "") : "") + super().to_s).to_sym
|
45
52
|
end
|
46
53
|
|
47
54
|
protected
|
48
55
|
|
49
|
-
def sep
|
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, :
|
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
|
-
@
|
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]
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
child(:name => o.name, :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
|
-
|
74
|
-
if mixin.
|
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
|