yard 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -69,9 +69,9 @@ module YARD
|
|
69
69
|
#
|
70
70
|
def included_meths_by_module
|
71
71
|
all_meths = current_object.included_meths(:scope => scope, :visibility => visibility)
|
72
|
-
current_object.mixins.each do |mixin|
|
72
|
+
current_object.mixins(scope).each do |mixin|
|
73
73
|
next if mixin.is_a?(CodeObjects::Proxy)
|
74
|
-
meths = mixin.meths(meths_opts).select {|c| all_meths.include?(c) }
|
74
|
+
meths = mixin.meths(meths_opts.merge(:scope => :instance)).select {|c| all_meths.include?(c) }
|
75
75
|
remove_ignored_meths!(meths)
|
76
76
|
next if meths.empty?
|
77
77
|
yield(mixin, meths)
|
@@ -102,4 +102,4 @@ module YARD
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
105
|
-
end
|
105
|
+
end
|
@@ -1,15 +1,21 @@
|
|
1
1
|
module YARD
|
2
2
|
module Generators
|
3
3
|
class MixinsGenerator < Base
|
4
|
+
attr_reader :scope
|
4
5
|
before_generate :has_mixins?
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
super
|
9
|
+
@scope = options[:scope]
|
10
|
+
end
|
5
11
|
|
6
12
|
def sections_for(object) [:header] end
|
7
13
|
|
8
14
|
protected
|
9
15
|
|
10
16
|
def has_mixins?(object)
|
11
|
-
!object.mixins.empty?
|
17
|
+
!object.mixins(@scope).empty?
|
12
18
|
end
|
13
19
|
end
|
14
20
|
end
|
15
|
-
end
|
21
|
+
end
|
@@ -7,7 +7,8 @@ module YARD
|
|
7
7
|
[
|
8
8
|
:header,
|
9
9
|
[
|
10
|
-
G(MixinsGenerator),
|
10
|
+
G(MixinsGenerator, :scope => :class),
|
11
|
+
G(MixinsGenerator, :scope => :instance),
|
11
12
|
G(DocstringGenerator),
|
12
13
|
G(AttributesGenerator),
|
13
14
|
G(ConstantsGenerator),
|
@@ -19,4 +20,4 @@ module YARD
|
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
22
|
-
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module YARD
|
2
|
+
module Generators
|
3
|
+
class OverloadsGenerator < Base
|
4
|
+
before_generate :has_overloads?
|
5
|
+
|
6
|
+
def sections_for(object)
|
7
|
+
[
|
8
|
+
:header,
|
9
|
+
[G(MethodGenerator)]
|
10
|
+
]
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def has_overloads?(object)
|
16
|
+
object.tags(:overload).size > 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -5,14 +5,8 @@ module YARD
|
|
5
5
|
case object
|
6
6
|
when CodeObjects::MethodObject
|
7
7
|
[
|
8
|
-
:header,
|
9
|
-
[
|
10
|
-
G(DeprecatedGenerator),
|
11
|
-
G(DocstringGenerator),
|
12
|
-
G(MethodSignatureGenerator),
|
13
|
-
G(TagsGenerator),
|
14
|
-
G(SourceGenerator)
|
15
|
-
]
|
8
|
+
:header,
|
9
|
+
[G(MethodGenerator)]
|
16
10
|
]
|
17
11
|
when CodeObjects::NamespaceObject
|
18
12
|
[
|
@@ -28,4 +22,4 @@ module YARD
|
|
28
22
|
end
|
29
23
|
end
|
30
24
|
end
|
31
|
-
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module YARD
|
2
|
+
module Generators
|
3
|
+
class RootGenerator < Base
|
4
|
+
before_generate :is_root?
|
5
|
+
before_generate :has_data?
|
6
|
+
|
7
|
+
def sections_for(object)
|
8
|
+
[
|
9
|
+
:header,
|
10
|
+
[
|
11
|
+
G(MixinsGenerator, :scope => :class),
|
12
|
+
G(MixinsGenerator, :scope => :instance),
|
13
|
+
G(ConstantsGenerator),
|
14
|
+
G(VisibilityGroupGenerator, :visibility => :public),
|
15
|
+
G(VisibilityGroupGenerator, :visibility => :protected),
|
16
|
+
G(VisibilityGroupGenerator, :visibility => :private)
|
17
|
+
]
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def has_data?(object)
|
24
|
+
object.meths.size > 0 || object.constants.size > 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_root?(object)
|
28
|
+
object == Registry.root
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,26 +1,11 @@
|
|
1
1
|
module YARD
|
2
2
|
module Generators
|
3
3
|
class SourceGenerator < Base
|
4
|
+
include Helpers::MethodHelper
|
5
|
+
|
4
6
|
def sections_for(object)
|
5
7
|
[:main] if object.source
|
6
8
|
end
|
7
|
-
|
8
|
-
protected
|
9
|
-
|
10
|
-
def format_lines(object)
|
11
|
-
i = -1
|
12
|
-
object.source.split(/\n/).map { object.line + (i += 1) }.join("\n")
|
13
|
-
end
|
14
|
-
|
15
|
-
def format_code(object, show_lines = false)
|
16
|
-
i = -1
|
17
|
-
lines = object.source.split(/\n/)
|
18
|
-
longestline = (object.line + lines.size).to_s.length
|
19
|
-
lines.map do |line|
|
20
|
-
lineno = object.line + (i += 1)
|
21
|
-
(" " * (longestline - lineno.to_s.length)) + lineno.to_s + " " + line
|
22
|
-
end.join("\n")
|
23
|
-
end
|
24
9
|
end
|
25
10
|
end
|
26
11
|
end
|
@@ -1,20 +1,26 @@
|
|
1
1
|
module YARD
|
2
2
|
module Generators
|
3
3
|
class TagsGenerator < Base
|
4
|
-
before_section :header,
|
4
|
+
before_section :header, :has_tags?
|
5
|
+
before_section :option, :has_options?
|
6
|
+
before_section :param, :has_params?
|
5
7
|
|
6
8
|
def sections_for(object)
|
7
|
-
[:header, [:param, :yieldparam, :return, :raise, :author, :version, :since, :see]]
|
9
|
+
[:header, [:example, :param, :yield, :yieldparam, :yieldreturn, :return, :raise, :todo, :author, :version, :since, :see]]
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
11
|
-
render_tags :
|
12
|
+
def yield(object)
|
13
|
+
render_tags :yield
|
12
14
|
end
|
13
15
|
|
14
16
|
def yieldparam(object)
|
15
17
|
render_tags :yieldparam
|
16
18
|
end
|
17
|
-
|
19
|
+
|
20
|
+
def yieldreturn(object)
|
21
|
+
render_tags :yieldreturn
|
22
|
+
end
|
23
|
+
|
18
24
|
def return(object)
|
19
25
|
render_tags :return
|
20
26
|
end
|
@@ -37,14 +43,36 @@ module YARD
|
|
37
43
|
|
38
44
|
protected
|
39
45
|
|
46
|
+
def has_params?(object)
|
47
|
+
object.is_a?(CodeObjects::MethodObject) && tags_by_param(object).size > 0
|
48
|
+
end
|
49
|
+
|
40
50
|
def has_tags?(object)
|
41
51
|
object.tags.size > 0
|
42
52
|
end
|
43
53
|
|
54
|
+
def has_options?(object)
|
55
|
+
object.has_tag?(:option)
|
56
|
+
end
|
57
|
+
|
44
58
|
def render_tags(name, opts = {})
|
45
59
|
opts = { :name => name }.update(opts)
|
46
60
|
render(current_object, 'tags', opts)
|
47
61
|
end
|
62
|
+
|
63
|
+
def tags_by_param(object)
|
64
|
+
cache = {}
|
65
|
+
[:param, :option].each do |sym|
|
66
|
+
object.tags(sym).each do |t|
|
67
|
+
cache[t.name.to_s] = t
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
object.parameters.map do |p|
|
72
|
+
name = p.first.to_s
|
73
|
+
cache[name] || cache[name[/^[*&](\w+)$/, 1]]
|
74
|
+
end.compact
|
75
|
+
end
|
48
76
|
end
|
49
77
|
end
|
50
|
-
end
|
78
|
+
end
|
@@ -60,22 +60,32 @@ module YARD
|
|
60
60
|
|
61
61
|
def process_objects(object)
|
62
62
|
@objects[object.path] = object
|
63
|
-
@objects[object.superclass.path] = object.superclass if object.is_a?(CodeObjects::ClassObject)
|
63
|
+
@objects[object.superclass.path] = object.superclass if object.is_a?(CodeObjects::ClassObject) && object.superclass
|
64
64
|
object.mixins.each {|o| @objects[o.path] = o }
|
65
65
|
|
66
66
|
namespaces(object).each {|o| process_objects(o) }
|
67
67
|
end
|
68
68
|
|
69
|
-
def method_list(object)
|
69
|
+
def method_list(object, attributes = false)
|
70
70
|
vissort = lambda {|vis| vis == :public ? 'a' : (vis == :protected ? 'b' : 'c') }
|
71
71
|
|
72
|
-
object.meths(:inherited => false, :included => false, :visibility => options[:visibility])
|
73
|
-
|
74
|
-
|
72
|
+
meths = object.meths(:inherited => false, :included => false, :visibility => options[:visibility])
|
73
|
+
meths = remove_overriden_meths(object, meths)
|
74
|
+
meths = meths.select {|o| attributes ? o.is_attribute? : !o.is_attribute? }
|
75
|
+
meths = meths.reject {|o| o.is_alias? }
|
76
|
+
meths = meths.sort_by {|o| "#{o.scope}#{vissort.call(o.visibility)}#{o.name}" }
|
75
77
|
end
|
76
78
|
|
77
79
|
private
|
78
80
|
|
81
|
+
def remove_overriden_meths(object, meth_list)
|
82
|
+
object.inheritance_tree(true)[1..-1].each do |sclass|
|
83
|
+
next if CodeObjects::Proxy === sclass
|
84
|
+
meth_list.reject! {|o| sclass.child(:scope => o.scope, :name => o.name) }
|
85
|
+
end
|
86
|
+
meth_list
|
87
|
+
end
|
88
|
+
|
79
89
|
def tidy(data)
|
80
90
|
indent = 0
|
81
91
|
data.split(/\n/).map do |line|
|
@@ -89,4 +99,4 @@ module YARD
|
|
89
99
|
end
|
90
100
|
end
|
91
101
|
end
|
92
|
-
end
|
102
|
+
end
|
data/lib/yard/handlers/base.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module YARD
|
2
2
|
module Handlers
|
3
|
-
class
|
3
|
+
class NamespaceMissingError < Parser::UndocumentableError
|
4
|
+
attr_accessor :object
|
5
|
+
def initialize(object) @object = object end
|
6
|
+
end
|
4
7
|
|
5
8
|
# = Handlers
|
6
9
|
#
|
@@ -33,7 +36,7 @@ module YARD
|
|
33
36
|
# A Handler is automatically registered when it is subclassed from the
|
34
37
|
# base class. The only other thing that needs to be done is to specify
|
35
38
|
# which statement the handler will process. This is done with the +handles+
|
36
|
-
# declaration, taking either a {Parser::RubyToken}, {String} or
|
39
|
+
# declaration, taking either a {Parser::Ruby::Legacy::RubyToken}, {String} or `Regexp`.
|
37
40
|
# Here is a simple example which processes module statements.
|
38
41
|
#
|
39
42
|
# class MyModuleHandler < YARD::Handlers::Base
|
@@ -53,10 +56,10 @@ module YARD
|
|
53
56
|
#
|
54
57
|
# === +statement+ Attribute
|
55
58
|
#
|
56
|
-
# The +statement+ attribute pertains to the {Parser::Statement} object
|
59
|
+
# The +statement+ attribute pertains to the {Parser::Ruby::Legacy::Statement} object
|
57
60
|
# containing a set of tokens parsed in by the parser. This is the main set
|
58
61
|
# of data to be analyzed and processed. The comments attached to the statement
|
59
|
-
# can be accessed by the {Parser::Statement#comments} method, but generally
|
62
|
+
# can be accessed by the {Parser::Ruby::Legacy::Statement#comments} method, but generally
|
60
63
|
# the data to be processed will live in the +tokens+ attribute. This list
|
61
64
|
# can be converted to a +String+ using +#to_s+ to parse the data with
|
62
65
|
# regular expressions (or other text processing mechanisms), if needed.
|
@@ -131,14 +134,11 @@ module YARD
|
|
131
134
|
# @see #parse_block
|
132
135
|
#
|
133
136
|
class Base
|
134
|
-
attr_accessor :__context__
|
135
|
-
|
136
137
|
# For accessing convenience, eg. "MethodObject"
|
137
138
|
# instead of the full qualified namespace
|
138
139
|
include YARD::CodeObjects
|
139
140
|
|
140
|
-
|
141
|
-
include YARD::Parser::RubyToken
|
141
|
+
include Parser
|
142
142
|
|
143
143
|
class << self
|
144
144
|
def clear_subclasses
|
@@ -146,7 +146,7 @@ module YARD
|
|
146
146
|
end
|
147
147
|
|
148
148
|
def subclasses
|
149
|
-
@@subclasses
|
149
|
+
@@subclasses ||= []
|
150
150
|
end
|
151
151
|
|
152
152
|
def inherited(subclass)
|
@@ -164,7 +164,7 @@ module YARD
|
|
164
164
|
# the handlers, otherwise the same code will be parsed
|
165
165
|
# multiple times and slow YARD down.
|
166
166
|
#
|
167
|
-
# @param [Parser::RubyToken, String, Regexp]
|
167
|
+
# @param [Parser::RubyToken, Symbol, String, Regexp] matches
|
168
168
|
# statements that match the declaration will be
|
169
169
|
# processed by this handler. A {String} match is
|
170
170
|
# equivalent to a +/\Astring/+ regular expression
|
@@ -172,19 +172,24 @@ module YARD
|
|
172
172
|
# token matches match only the first token of the
|
173
173
|
# statement.
|
174
174
|
#
|
175
|
-
def handles(
|
176
|
-
@
|
175
|
+
def handles(*matches)
|
176
|
+
(@handlers ||= []).push(*matches)
|
177
177
|
end
|
178
178
|
|
179
|
-
def handles?(
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
179
|
+
def handles?(statement)
|
180
|
+
raise NotImplementedError, "override #handles? in a subclass"
|
181
|
+
end
|
182
|
+
|
183
|
+
def handlers
|
184
|
+
@handlers ||= []
|
185
|
+
end
|
186
|
+
|
187
|
+
def namespace_only
|
188
|
+
@namespace_only = true
|
189
|
+
end
|
190
|
+
|
191
|
+
def namespace_only?
|
192
|
+
@namespace_only ? true : false
|
188
193
|
end
|
189
194
|
end
|
190
195
|
|
@@ -213,11 +218,50 @@ module YARD
|
|
213
218
|
raise NotImplementedError, "#{self} did not implement a #process method for handling."
|
214
219
|
end
|
215
220
|
|
221
|
+
def parse_block(*args)
|
222
|
+
raise NotImplementedError, "#{self} did not implement a #parse_block method for handling"
|
223
|
+
end
|
224
|
+
|
216
225
|
protected
|
217
226
|
|
218
227
|
attr_reader :parser, :statement
|
219
228
|
attr_accessor :owner, :namespace, :visibility, :scope
|
220
229
|
|
230
|
+
def owner; parser.owner end
|
231
|
+
def owner=(v) parser.owner=(v) end
|
232
|
+
def namespace; parser.namespace end
|
233
|
+
def namespace=(v); parser.namespace=(v) end
|
234
|
+
def visibility; parser.visibility end
|
235
|
+
def visibility=(v); parser.visibility=(v) end
|
236
|
+
def scope; parser.scope end
|
237
|
+
def scope=(v); parser.scope=(v) end
|
238
|
+
|
239
|
+
def push_state(opts = {}, &block)
|
240
|
+
opts = {
|
241
|
+
:namespace => nil,
|
242
|
+
:scope => :instance,
|
243
|
+
:owner => nil
|
244
|
+
}.update(opts)
|
245
|
+
|
246
|
+
if opts[:namespace]
|
247
|
+
ns, vis, sc = namespace, visibility, scope
|
248
|
+
self.namespace = opts[:namespace]
|
249
|
+
self.visibility = :public
|
250
|
+
self.scope = opts[:scope]
|
251
|
+
end
|
252
|
+
|
253
|
+
oldowner, self.owner = self.owner, opts[:owner] ? opts[:owner] : namespace
|
254
|
+
yield
|
255
|
+
self.owner = oldowner
|
256
|
+
|
257
|
+
if opts[:namespace]
|
258
|
+
self.namespace = ns
|
259
|
+
self.owner = namespace
|
260
|
+
self.visibility = vis
|
261
|
+
self.scope = sc
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
221
265
|
# Do some post processing on a list of code objects.
|
222
266
|
# Adds basic attributes to the list of objects like
|
223
267
|
# the filename, line number, {CodeObjects::Base#dynamic},
|
@@ -234,7 +278,11 @@ module YARD
|
|
234
278
|
objects.flatten.each do |object|
|
235
279
|
next unless object.is_a?(CodeObjects::Base)
|
236
280
|
|
237
|
-
|
281
|
+
begin
|
282
|
+
ensure_loaded!(object.namespace)
|
283
|
+
object.namespace.children << object
|
284
|
+
rescue NamespaceMissingError
|
285
|
+
end
|
238
286
|
|
239
287
|
# Yield the object to the calling block because ruby will parse the syntax
|
240
288
|
#
|
@@ -243,266 +291,53 @@ module YARD
|
|
243
291
|
# as the block for #register. We need to make sure this gets to the object.
|
244
292
|
yield(object) if block_given?
|
245
293
|
|
246
|
-
|
247
|
-
|
248
|
-
if (object.is_a?(NamespaceObject) && statement.comments) || !object.is_a?(NamespaceObject)
|
249
|
-
object.file = parser.file
|
250
|
-
object.line = statement.tokens.first.line_no
|
251
|
-
elsif object.is_a?(NamespaceObject) && !statement.comments
|
252
|
-
object.file ||= parser.file
|
253
|
-
object.line ||= statement.tokens.first.line_no
|
254
|
-
end
|
255
|
-
|
294
|
+
object.add_file(parser.file, statement.line, statement.comments)
|
295
|
+
|
256
296
|
# Add docstring if there is one.
|
257
297
|
object.docstring = statement.comments if statement.comments
|
258
298
|
|
259
299
|
# Add source only to non-class non-module objects
|
260
300
|
unless object.is_a?(NamespaceObject)
|
261
|
-
object.source ||= statement
|
301
|
+
object.source ||= statement
|
262
302
|
end
|
263
303
|
|
264
|
-
# Make it dynamic if
|
304
|
+
# Make it dynamic if its owner is not its namespace.
|
265
305
|
# This generally means it was defined in a method (or block of some sort)
|
266
306
|
object.dynamic = true if owner != namespace
|
267
307
|
end
|
268
308
|
objects.size == 1 ? objects.first : objects
|
269
309
|
end
|
270
|
-
|
271
|
-
def parse_block(opts = nil)
|
272
|
-
opts = {
|
273
|
-
:namespace => nil,
|
274
|
-
:scope => :instance,
|
275
|
-
:owner => nil
|
276
|
-
}.update(opts || {})
|
277
|
-
|
278
|
-
if opts[:namespace]
|
279
|
-
ns, vis, sc = namespace, visibility, scope
|
280
|
-
self.namespace = opts[:namespace]
|
281
|
-
self.visibility = :public
|
282
|
-
self.scope = opts[:scope]
|
283
|
-
end
|
284
|
-
|
285
|
-
self.owner = opts[:owner] ? opts[:owner] : namespace
|
286
|
-
parser.parse(statement.block) if statement.block
|
287
|
-
|
288
|
-
if opts[:namespace]
|
289
|
-
self.namespace = ns
|
290
|
-
self.owner = namespace
|
291
|
-
self.visibility = vis
|
292
|
-
self.scope = sc
|
293
|
-
end
|
294
|
-
end
|
295
310
|
|
296
|
-
def
|
297
|
-
def owner=(v) @parser.owner=(v) end
|
298
|
-
def namespace; @parser.namespace end
|
299
|
-
def namespace=(v); @parser.namespace=(v) end
|
300
|
-
def visibility; @parser.visibility end
|
301
|
-
def visibility=(v); @parser.visibility=(v) end
|
302
|
-
def scope; @parser.scope end
|
303
|
-
def scope=(v); @parser.scope=(v) end
|
304
|
-
|
305
|
-
def ensure_namespace_loaded!(object, max_retries = 1)
|
311
|
+
def ensure_loaded!(object, max_retries = 1)
|
306
312
|
unless parser.load_order_errors
|
307
|
-
|
313
|
+
if object.is_a?(Proxy)
|
314
|
+
raise NamespaceMissingError, object
|
315
|
+
else
|
316
|
+
nil
|
317
|
+
end
|
308
318
|
end
|
309
319
|
|
310
|
-
|
311
|
-
|
320
|
+
if RUBY_PLATFORM =~ /java/
|
321
|
+
log.warn "JRuby does not implement Kernel#callcc and cannot load files in order. You must specify the correct order manually."
|
322
|
+
raise NamespaceMissingError, object
|
323
|
+
end
|
312
324
|
|
313
325
|
retries, context = 0, nil
|
314
326
|
callcc {|c| context = c }
|
315
327
|
|
316
328
|
retries += 1
|
317
329
|
|
318
|
-
if object.
|
330
|
+
if object.is_a?(Proxy)
|
319
331
|
if retries <= max_retries
|
320
332
|
log.debug "Missing object #{object.parent} in file `#{parser.file}', moving it to the back of the line."
|
321
333
|
raise Parser::LoadOrderError, context
|
322
|
-
|
323
|
-
|
324
|
-
if retries > max_retries && !object.parent.is_a?(Proxy) && !BUILTIN_ALL.include?(object.path)
|
325
|
-
load_order_warn(object.parent)
|
334
|
+
else
|
335
|
+
raise NamespaceMissingError, object
|
326
336
|
end
|
327
337
|
else
|
328
338
|
log.debug "Object #{object} successfully resolved. Adding item to #{object.parent}'s children"
|
329
|
-
object.namespace.children << object
|
330
|
-
end
|
331
|
-
|
332
|
-
rescue NotImplementedError
|
333
|
-
log.warn "JRuby does not implement Kernel#callcc and cannot load files in order. You must specify the correct order manually."
|
334
|
-
load_order_warn(object.parent)
|
335
|
-
end
|
336
|
-
|
337
|
-
def load_order_warn(object)
|
338
|
-
log.warn "The #{object.type} #{object.path} has not yet been recognized."
|
339
|
-
log.warn "If this class/method is part of your source tree, this will affect your documentation results."
|
340
|
-
log.warn "You can correct this issue by loading the source file for this object before `#{parser.file}'"
|
341
|
-
log.warn
|
342
|
-
end
|
343
|
-
|
344
|
-
# The string value of a token. For example, the return value for the symbol :sym
|
345
|
-
# would be :sym. The return value for a string "foo #{bar}" would be the literal
|
346
|
-
# "foo #{bar}" without any interpolation. The return value of the identifier
|
347
|
-
# 'test' would be the same value: 'test'. Here is a list of common types and
|
348
|
-
# their return values:
|
349
|
-
#
|
350
|
-
# @example
|
351
|
-
# tokval(TokenList.new('"foo"').first) => "foo"
|
352
|
-
# tokval(TokenList.new(':foo').first) => :foo
|
353
|
-
# tokval(TokenList.new('CONSTANT').first, RubyToken::TkId) => "CONSTANT"
|
354
|
-
# tokval(TokenList.new('identifier').first, RubyToken::TkId) => "identifier"
|
355
|
-
# tokval(TokenList.new('3.25').first) => 3.25
|
356
|
-
# tokval(TokenList.new('/xyz/i').first) => /xyz/i
|
357
|
-
#
|
358
|
-
# @param [Token] token The token of the class
|
359
|
-
#
|
360
|
-
# @param [Array<Class<Token>>, Symbol] accepted_types
|
361
|
-
# The allowed token types that this token can be. Defaults to [{TkVal}].
|
362
|
-
# A list of types would be, for example, [{TkSTRING}, {TkSYMBOL}], to return
|
363
|
-
# the token's value if it is either of those types. If +TkVal+ is accepted,
|
364
|
-
# +TkNode+ is also accepted.
|
365
|
-
#
|
366
|
-
# Certain symbol keys are allowed to specify multiple types in one fell swoop.
|
367
|
-
# These symbols are:
|
368
|
-
# :string => +TkSTRING+, +TkDSTRING+, +TkDXSTRING+ and +TkXSTRING+
|
369
|
-
# :attr => +TkSYMBOL+ and +TkSTRING+
|
370
|
-
# :identifier => +TkIDENTIFIER, +TkFID+ and +TkGVAR+.
|
371
|
-
# :number => +TkFLOAT+, +TkINTEGER+
|
372
|
-
#
|
373
|
-
# @return [Object] if the token is one of the accepted types, in its real value form.
|
374
|
-
# It should be noted that identifiers and constants are kept in String form.
|
375
|
-
# @return [nil] if the token is not any of the specified accepted types
|
376
|
-
def tokval(token, *accepted_types)
|
377
|
-
accepted_types = [TkVal] if accepted_types.empty?
|
378
|
-
accepted_types.push(TkNode) if accepted_types.include? TkVal
|
379
|
-
|
380
|
-
if accepted_types.include?(:attr)
|
381
|
-
accepted_types.push(TkSTRING, TkSYMBOL)
|
382
|
-
end
|
383
|
-
|
384
|
-
if accepted_types.include?(:string)
|
385
|
-
accepted_types.push(TkSTRING, TkDSTRING, TkXSTRING, TkDXSTRING)
|
386
|
-
end
|
387
|
-
|
388
|
-
if accepted_types.include?(:identifier)
|
389
|
-
accepted_types.push(TkIDENTIFIER, TkFID, TkGVAR)
|
390
|
-
end
|
391
|
-
|
392
|
-
if accepted_types.include?(:number)
|
393
|
-
accepted_types.push(TkFLOAT, TkINTEGER)
|
394
|
-
end
|
395
|
-
|
396
|
-
return unless accepted_types.any? {|t| t === token }
|
397
|
-
|
398
|
-
case token
|
399
|
-
when TkSTRING, TkDSTRING, TkXSTRING, TkDXSTRING
|
400
|
-
token.text[1..-2]
|
401
|
-
when TkSYMBOL
|
402
|
-
token.text[1..-1].to_sym
|
403
|
-
when TkFLOAT
|
404
|
-
token.text.to_f
|
405
|
-
when TkINTEGER
|
406
|
-
token.text.to_i
|
407
|
-
when TkREGEXP
|
408
|
-
token.text =~ /\A\/(.+)\/([^\/])\Z/
|
409
|
-
Regexp.new($1, $2)
|
410
|
-
when TkTRUE
|
411
|
-
true
|
412
|
-
when TkFALSE
|
413
|
-
false
|
414
|
-
when TkNIL
|
415
|
-
nil
|
416
|
-
else
|
417
|
-
token.text
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
# Returns a list of symbols or string values from a statement.
|
422
|
-
# The list must be a valid comma delimited list, and values
|
423
|
-
# will only be returned to the end of the list only.
|
424
|
-
#
|
425
|
-
# Example:
|
426
|
-
# attr_accessor :a, 'b', :c, :d => ['a', 'b', 'c', 'd']
|
427
|
-
# attr_accessor 'a', UNACCEPTED_TYPE, 'c' => ['a', 'c']
|
428
|
-
#
|
429
|
-
# The tokval list of a {TokenList} of the above
|
430
|
-
# code would be the {#tokval} value of :a, 'b',
|
431
|
-
# :c and :d.
|
432
|
-
#
|
433
|
-
# It should also be noted that this function stops immediately at
|
434
|
-
# any ruby keyword encountered:
|
435
|
-
# "attr_accessor :a, :b, :c if x == 5" => ['a', 'b', 'c']
|
436
|
-
#
|
437
|
-
# @param [TokenList] tokenlist The list of tokens to process.
|
438
|
-
# @param [Array<Class<Token>>] accepted_types passed to {#tokval}
|
439
|
-
# @return [Array<String>] the list of tokvalues in the list.
|
440
|
-
# @return [Array<EMPTY>] if there are no symbols or Strings in the list
|
441
|
-
# @see #tokval
|
442
|
-
def tokval_list(tokenlist, *accepted_types)
|
443
|
-
return [] unless tokenlist
|
444
|
-
out = [[]]
|
445
|
-
parencount, beforeparen = 0, 0
|
446
|
-
needcomma = false
|
447
|
-
seen_comma = true
|
448
|
-
tokenlist.each do |token|
|
449
|
-
tokval = tokval(token, *accepted_types)
|
450
|
-
parencond = !out.last.empty? && tokval != nil
|
451
|
-
#puts "#{seen_comma.inspect} #{parencount} #{token.class.class_name} #{out.inspect}"
|
452
|
-
case token
|
453
|
-
when TkCOMMA
|
454
|
-
if parencount == 0
|
455
|
-
out << [] unless out.last.empty?
|
456
|
-
needcomma = false
|
457
|
-
seen_comma = true
|
458
|
-
else
|
459
|
-
out.last << token.text if parencond
|
460
|
-
end
|
461
|
-
when TkLPAREN
|
462
|
-
if seen_comma
|
463
|
-
beforeparen += 1
|
464
|
-
else
|
465
|
-
parencount += 1
|
466
|
-
out.last << token.text if parencond
|
467
|
-
end
|
468
|
-
when TkRPAREN
|
469
|
-
if beforeparen > 0
|
470
|
-
beforeparen -= 1
|
471
|
-
else
|
472
|
-
out.last << token.text if parencount > 0 && tokval != nil
|
473
|
-
parencount -= 1
|
474
|
-
end
|
475
|
-
when TkLBRACE, TkLBRACK, TkDO
|
476
|
-
parencount += 1
|
477
|
-
out.last << token.text if tokval != nil
|
478
|
-
when TkRBRACE, TkRBRACK, TkEND
|
479
|
-
out.last << token.text if tokval != nil
|
480
|
-
parencount -= 1
|
481
|
-
else
|
482
|
-
break if TkKW === token && ![TkTRUE, TkFALSE, TkSUPER, TkSELF, TkNIL].include?(token.class)
|
483
|
-
|
484
|
-
seen_comma = false unless TkWhitespace === token
|
485
|
-
if parencount == 0
|
486
|
-
next if needcomma
|
487
|
-
next if TkWhitespace === token
|
488
|
-
if tokval != nil
|
489
|
-
out.last << tokval
|
490
|
-
else
|
491
|
-
out.last.clear
|
492
|
-
needcomma = true
|
493
|
-
end
|
494
|
-
elsif parencond
|
495
|
-
needcomma = true
|
496
|
-
out.last << token.text
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
if beforeparen == 0 && parencount < 0
|
501
|
-
break
|
502
|
-
end
|
503
339
|
end
|
504
|
-
|
505
|
-
out.map {|e| e.empty? ? nil : (e.size == 1 ? e.pop : e.flatten.join) }.compact
|
340
|
+
object
|
506
341
|
end
|
507
342
|
end
|
508
343
|
end
|