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
@@ -0,0 +1,72 @@
|
|
1
|
+
module YARD
|
2
|
+
module Handlers
|
3
|
+
class Processor
|
4
|
+
attr_accessor :file, :namespace, :visibility
|
5
|
+
attr_accessor :scope, :owner, :load_order_errors, :parser_type
|
6
|
+
|
7
|
+
def initialize(file = nil, load_order_errors = false, parser_type = Parser::SourceParser.parser_type)
|
8
|
+
@file = file || "(stdin)"
|
9
|
+
@namespace = YARD::Registry.root
|
10
|
+
@visibility = :public
|
11
|
+
@scope = :instance
|
12
|
+
@owner = @namespace
|
13
|
+
@load_order_errors = load_order_errors
|
14
|
+
@parser_type = parser_type
|
15
|
+
@handlers_loaded = {}
|
16
|
+
load_handlers
|
17
|
+
end
|
18
|
+
|
19
|
+
def process(statements)
|
20
|
+
statements.each_with_index do |stmt, index|
|
21
|
+
find_handlers(stmt).each do |handler|
|
22
|
+
begin
|
23
|
+
handler.new(self, stmt).process
|
24
|
+
rescue Parser::LoadOrderError => loaderr
|
25
|
+
raise # Pass this up
|
26
|
+
rescue NamespaceMissingError => missingerr
|
27
|
+
log.warn "The #{missingerr.object.type} #{missingerr.object.path} has not yet been recognized."
|
28
|
+
log.warn "If this class/method is part of your source tree, this will affect your documentation results."
|
29
|
+
log.warn "You can correct this issue by loading the source file for this object before `#{file}'"
|
30
|
+
log.warn
|
31
|
+
rescue Parser::UndocumentableError => undocerr
|
32
|
+
log.warn "in #{handler.to_s}: Undocumentable #{undocerr.message}"
|
33
|
+
log.warn "\tin file '#{file}':#{stmt.line}:\n\n" + stmt.show + "\n"
|
34
|
+
rescue => e
|
35
|
+
log.error "Unhandled exception in #{handler.to_s}:"
|
36
|
+
log.error "#{e.class.class_name}: #{e.message}"
|
37
|
+
log.error " in `#{file}`:#{stmt.line}:\n\n#{stmt.show}\n"
|
38
|
+
log.error "Stack trace:" + e.backtrace[0..5].map {|x| "\n\t#{x}" }.join + "\n"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_handlers(statement)
|
45
|
+
Base.subclasses.find_all do |handler|
|
46
|
+
handler_base_class > handler &&
|
47
|
+
(handler.namespace_only? ? owner.is_a?(CodeObjects::NamespaceObject) : true) &&
|
48
|
+
handler.handles?(statement)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def handler_base_class
|
55
|
+
handler_base_namespace.const_get(:Base)
|
56
|
+
end
|
57
|
+
|
58
|
+
def handler_base_namespace
|
59
|
+
case parser_type
|
60
|
+
when :ruby; Ruby
|
61
|
+
when :ruby18; Ruby::Legacy
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def load_handlers
|
66
|
+
return if @handlers_loaded[parser_type]
|
67
|
+
handler_base_namespace.constants.each {|c| handler_base_namespace.const_get(c) }
|
68
|
+
@handlers_loaded[parser_type] = true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class YARD::Handlers::Ruby::AliasHandler < YARD::Handlers::Ruby::Base
|
2
|
+
handles :alias, method_call(:alias_method)
|
3
|
+
|
4
|
+
def process
|
5
|
+
names = []
|
6
|
+
if statement.type == :alias
|
7
|
+
names = statement.map {|o| o.jump(:ident, :op, :kw, :const).first }
|
8
|
+
elsif statement.call?
|
9
|
+
statement.parameters(false).each do |obj|
|
10
|
+
case obj.type
|
11
|
+
when :symbol_literal
|
12
|
+
names << obj.jump(:ident, :op, :kw, :const).source
|
13
|
+
when :string_literal
|
14
|
+
names << obj.jump(:string_content).source
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
raise YARD::Parser::UndocumentableError, "alias/alias_method" if names.size != 2
|
19
|
+
|
20
|
+
new_meth, old_meth = names[0].to_sym, names[1].to_sym
|
21
|
+
old_obj = namespace.child(:name => old_meth, :scope => scope)
|
22
|
+
new_obj = register MethodObject.new(namespace, new_meth, scope) do |o|
|
23
|
+
o.visibility = visibility
|
24
|
+
o.scope = scope
|
25
|
+
o.add_file(parser.file, statement.line)
|
26
|
+
o.docstring = statement.comments
|
27
|
+
|
28
|
+
if old_obj
|
29
|
+
o.signature = old_obj.signature
|
30
|
+
o.source = old_obj.source
|
31
|
+
else
|
32
|
+
o.signature = "def #{new_meth}" # this is all we know.
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
namespace.aliases[new_obj] = old_meth
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class YARD::Handlers::Ruby::AttributeHandler < YARD::Handlers::Ruby::Base
|
2
|
+
handles method_call(:attr)
|
3
|
+
handles method_call(:attr_reader)
|
4
|
+
handles method_call(:attr_writer)
|
5
|
+
handles method_call(:attr_accessor)
|
6
|
+
|
7
|
+
def process
|
8
|
+
read, write = true, false
|
9
|
+
params = statement.parameters(false).dup
|
10
|
+
|
11
|
+
# Change read/write based on attr_reader/writer/accessor
|
12
|
+
case statement.method_name(true)
|
13
|
+
when :attr
|
14
|
+
# In the case of 'attr', the second parameter (if given) isn't a symbol.
|
15
|
+
if params.size == 2
|
16
|
+
write = true if params.pop == s(:var_ref, s(:kw, "true"))
|
17
|
+
end
|
18
|
+
when :attr_accessor
|
19
|
+
write = true
|
20
|
+
when :attr_reader
|
21
|
+
# change nothing
|
22
|
+
when :attr_writer
|
23
|
+
read, write = false, true
|
24
|
+
end
|
25
|
+
|
26
|
+
# Add all attributes
|
27
|
+
validated_attribute_names(params).each do |name|
|
28
|
+
namespace.attributes[scope][name] = SymbolHash[:read => nil, :write => nil]
|
29
|
+
|
30
|
+
# Show their methods as well
|
31
|
+
{:read => name, :write => "#{name}="}.each do |type, meth|
|
32
|
+
next unless (type == :read ? read : write)
|
33
|
+
|
34
|
+
namespace.attributes[scope][name][type] = MethodObject.new(namespace, meth, scope) do |o|
|
35
|
+
if type == :write
|
36
|
+
src = "def #{meth}(value)"
|
37
|
+
full_src = "#{src}\n @#{name} = value\nend"
|
38
|
+
doc = "Sets the attribute +#{name}+\n@param value the value to set the attribute +#{name}+ to."
|
39
|
+
else
|
40
|
+
src = "def #{meth}"
|
41
|
+
full_src = "#{src}\n @#{name}\nend"
|
42
|
+
doc = "Returns the value of attribute +#{name}+"
|
43
|
+
end
|
44
|
+
o.source ||= full_src
|
45
|
+
o.signature ||= src
|
46
|
+
o.docstring = statement.comments.to_s.empty? ? doc : statement.comments
|
47
|
+
end
|
48
|
+
|
49
|
+
# Register the objects explicitly
|
50
|
+
register namespace.attributes[scope][name][type]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def validated_attribute_names(params)
|
58
|
+
params.map do |obj|
|
59
|
+
case obj.type
|
60
|
+
when :symbol_literal
|
61
|
+
obj.jump(:ident, :op, :kw, :const).source
|
62
|
+
when :string_literal
|
63
|
+
obj.jump(:string_content).source
|
64
|
+
else
|
65
|
+
raise YARD::Parser::UndocumentableError, obj.source
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module YARD
|
2
|
+
module Handlers
|
3
|
+
module Ruby
|
4
|
+
class HandlesExtension
|
5
|
+
def initialize(name) @name = name end
|
6
|
+
def matches?(node) raise NotImplementedError end
|
7
|
+
protected
|
8
|
+
attr_reader :name
|
9
|
+
end
|
10
|
+
|
11
|
+
class MethodCallWrapper < HandlesExtension
|
12
|
+
def matches?(node)
|
13
|
+
case node.type
|
14
|
+
when :var_ref
|
15
|
+
if !node.parent || node.parent.type == :list
|
16
|
+
return true if node[0].type == :ident && node[0][0] == name
|
17
|
+
end
|
18
|
+
when :fcall, :command
|
19
|
+
return true if node[0][0] == name
|
20
|
+
when :call, :command_call
|
21
|
+
return true if node[2][0] == name
|
22
|
+
end
|
23
|
+
false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class TestNodeWrapper < HandlesExtension
|
28
|
+
def matches?(node) !node.send(name).is_a?(FalseClass) end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Base < Handlers::Base
|
32
|
+
class << self
|
33
|
+
include Parser::Ruby
|
34
|
+
|
35
|
+
def method_call(name)
|
36
|
+
MethodCallWrapper.new(name.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
def meta_type(meth)
|
40
|
+
TestNodeWrapper.new(meth.to_s + "?")
|
41
|
+
end
|
42
|
+
|
43
|
+
def handles?(node)
|
44
|
+
handlers.any? do |a_handler|
|
45
|
+
case a_handler
|
46
|
+
when Symbol
|
47
|
+
a_handler == node.type
|
48
|
+
when String
|
49
|
+
node.source == a_handler
|
50
|
+
when Regexp
|
51
|
+
node.source =~ a_handler
|
52
|
+
when Parser::Ruby::AstNode
|
53
|
+
a_handler == node
|
54
|
+
when HandlesExtension
|
55
|
+
a_handler.matches?(node)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
include Parser::Ruby
|
62
|
+
|
63
|
+
def parse_block(inner_node, opts = {})
|
64
|
+
push_state(opts) do
|
65
|
+
nodes = inner_node.type == :list ? inner_node.children : [inner_node]
|
66
|
+
parser.process(nodes)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class YARD::Handlers::Ruby::ClassConditionHandler < YARD::Handlers::Ruby::Base
|
2
|
+
namespace_only
|
3
|
+
handles meta_type(:condition)
|
4
|
+
|
5
|
+
def process
|
6
|
+
condition = parse_condition
|
7
|
+
if condition == nil
|
8
|
+
# Parse both blocks if we're unsure of the condition
|
9
|
+
parse_then_block
|
10
|
+
parse_else_block
|
11
|
+
elsif condition
|
12
|
+
parse_then_block
|
13
|
+
else
|
14
|
+
parse_else_block
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
# Parses the condition part of the if/unless statement
|
21
|
+
#
|
22
|
+
# @return [true, false, nil] true if the condition can be definitely
|
23
|
+
# parsed to true, false if not, and nil if the condition cannot be
|
24
|
+
# parsed with certainty (it's dynamic)
|
25
|
+
def parse_condition
|
26
|
+
condition = nil
|
27
|
+
|
28
|
+
# Right now we can handle very simple unary conditions like:
|
29
|
+
# if true
|
30
|
+
# if false
|
31
|
+
# if 0
|
32
|
+
# if 100 (not 0)
|
33
|
+
# if defined? SOME_CONSTANT
|
34
|
+
#
|
35
|
+
# The last case will do a lookup in the registry and then one
|
36
|
+
# in the Ruby world (using eval).
|
37
|
+
case statement.condition.type
|
38
|
+
when :int
|
39
|
+
condition = statement.condition[0] != "0"
|
40
|
+
when :defined
|
41
|
+
# defined? keyword used, let's see if we can look up the name
|
42
|
+
# in the registry, then we'll try using Ruby's powers. eval() is not
|
43
|
+
# *too* dangerous here since code is not actually executed.
|
44
|
+
name = statement.condition[0].source
|
45
|
+
obj = YARD::Registry.resolve(namespace, name, true)
|
46
|
+
condition = true if obj || Object.instance_eval("defined? #{name}")
|
47
|
+
when :var_ref
|
48
|
+
var = statement.condition[0]
|
49
|
+
if var == s(:kw, "true")
|
50
|
+
condition = true
|
51
|
+
elsif var == s(:kw, "false")
|
52
|
+
condition = false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Invert an unless condition
|
57
|
+
if statement.type == :unless || statement.type == :unless_mod
|
58
|
+
condition = !condition if condition != nil
|
59
|
+
end
|
60
|
+
condition
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_then_block
|
64
|
+
parse_block(statement.then_block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def parse_else_block
|
68
|
+
parse_block(statement.else_block) if statement.else_block
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class YARD::Handlers::Ruby::ClassHandler < YARD::Handlers::Ruby::Base
|
2
|
+
handles :class, :sclass
|
3
|
+
|
4
|
+
def process
|
5
|
+
if statement.type == :class
|
6
|
+
classname = statement[0].source
|
7
|
+
superclass = parse_superclass(statement[1])
|
8
|
+
undocsuper = statement[1] && superclass.nil?
|
9
|
+
|
10
|
+
klass = register ClassObject.new(namespace, classname) do |o|
|
11
|
+
o.docstring = statement.comments
|
12
|
+
o.superclass = superclass if superclass
|
13
|
+
o.superclass.type = :class if o.superclass.is_a?(Proxy)
|
14
|
+
end
|
15
|
+
parse_block(statement[2], namespace: klass)
|
16
|
+
|
17
|
+
if undocsuper
|
18
|
+
raise YARD::Parser::UndocumentableError, 'superclass (class was added without superclass)'
|
19
|
+
end
|
20
|
+
elsif statement.type == :sclass
|
21
|
+
if statement[0] == s(:var_ref, s(:kw, "self"))
|
22
|
+
parse_block(statement[1], namespace: namespace, scope: :class)
|
23
|
+
else
|
24
|
+
classname = statement[0].source
|
25
|
+
proxy = Proxy.new(namespace, classname)
|
26
|
+
|
27
|
+
# Allow constants to reference class names
|
28
|
+
if ConstantObject === proxy
|
29
|
+
if proxy.value =~ /\A#{NAMESPACEMATCH}\Z/
|
30
|
+
proxy = Proxy.new(namespace, proxy.value)
|
31
|
+
else
|
32
|
+
raise YARD::Parser::UndocumentableError, "constant class reference '#{classname}'"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if classname[0,1] =~ /[A-Z]/
|
37
|
+
register ClassObject.new(namespace, classname) if Proxy === proxy
|
38
|
+
parse_block(statement[1], namespace: proxy, scope: :class)
|
39
|
+
else
|
40
|
+
raise YARD::Parser::UndocumentableError, "class '#{classname}'"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
sig_end = (statement[1] ? statement[1].source_end : statement[0].source_end) - statement.source_start
|
45
|
+
raise YARD::Parser::UndocumentableError, "class: #{statement.source[0..sig_end]}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def parse_superclass(superclass)
|
52
|
+
return nil unless superclass
|
53
|
+
|
54
|
+
case superclass.type
|
55
|
+
when :var_ref
|
56
|
+
return superclass.source if superclass.first.type == :const
|
57
|
+
when :const, :const_ref, :const_path_ref, :top_const_ref
|
58
|
+
return superclass.source
|
59
|
+
when :fcall, :command
|
60
|
+
methname = superclass.method_name.source
|
61
|
+
if methname == "DelegateClass"
|
62
|
+
return superclass.parameters.first.source
|
63
|
+
elsif superclass.method_name.type == :const
|
64
|
+
return methname
|
65
|
+
end
|
66
|
+
when :call, :command_call
|
67
|
+
cname = superclass.namespace.source
|
68
|
+
if cname =~ /^O?Struct$/ && superclass.method_name(true) == :new
|
69
|
+
return cname
|
70
|
+
end
|
71
|
+
end
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class YARD::Handlers::Ruby::ClassVariableHandler < YARD::Handlers::Ruby::Base
|
2
|
+
namespace_only
|
3
|
+
handles :assign
|
4
|
+
|
5
|
+
def process
|
6
|
+
if statement[0].type == :var_field && statement[0][0].type == :cvar
|
7
|
+
name = statement[0][0][0]
|
8
|
+
register ClassVariableObject.new(namespace, name) {|o| o.source = statement }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
|
2
|
+
namespace_only
|
3
|
+
handles :assign
|
4
|
+
|
5
|
+
def process
|
6
|
+
if statement[0].type == :var_field && statement[0][0].type == :const
|
7
|
+
name = statement[0][0][0]
|
8
|
+
value = statement[1].source
|
9
|
+
register ConstantObject.new(namespace, name) {|o| o.source = statement; o.value = value.strip }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class YARD::Handlers::Ruby::ExceptionHandler < YARD::Handlers::Ruby::Base
|
2
|
+
handles method_call(:raise)
|
3
|
+
|
4
|
+
def process
|
5
|
+
return unless owner.is_a?(MethodObject) # Only methods yield
|
6
|
+
return if owner.has_tag?(:raise)
|
7
|
+
|
8
|
+
klass = nil
|
9
|
+
params = statement.parameters(false)
|
10
|
+
if params.size == 1
|
11
|
+
if params.first.ref? && params.first.first.type != :ident
|
12
|
+
klass = params.first.source
|
13
|
+
elsif params.first.call? && params.first.method_name(true) == :new
|
14
|
+
klass = params.first.namespace.source
|
15
|
+
end
|
16
|
+
else
|
17
|
+
klass = params.first.source
|
18
|
+
end
|
19
|
+
|
20
|
+
owner.docstring.add_tag YARD::Tags::Tag.new(:raise, '', klass) if klass
|
21
|
+
end
|
22
|
+
end
|