yard 0.6.8 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of yard might be problematic. Click here for more details.
- data/.yardopts +1 -0
- data/ChangeLog +723 -0
- data/README.md +16 -6
- data/docs/CodeObjects.md +10 -16
- data/docs/GettingStarted.md +232 -32
- data/docs/Glossary.md +1 -2
- data/docs/Handlers.md +10 -16
- data/docs/Overview.md +14 -13
- data/docs/Parser.md +13 -22
- data/docs/Tags.md +209 -16
- data/docs/Templates.md +237 -26
- data/docs/WhatsNew.md +178 -2
- data/lib/yard.rb +13 -10
- data/lib/yard/autoload.rb +22 -18
- data/lib/yard/cli/command.rb +13 -12
- data/lib/yard/cli/command_parser.rb +20 -19
- data/lib/yard/cli/config.rb +19 -19
- data/lib/yard/cli/diff.rb +46 -21
- data/lib/yard/cli/gems.rb +11 -11
- data/lib/yard/cli/graph.rb +13 -13
- data/lib/yard/cli/help.rb +1 -1
- data/lib/yard/cli/list.rb +22 -0
- data/lib/yard/cli/server.rb +17 -17
- data/lib/yard/cli/stats.rb +32 -32
- data/lib/yard/cli/yardoc.rb +181 -135
- data/lib/yard/cli/yri.rb +29 -29
- data/lib/yard/code_objects/base.rb +101 -101
- data/lib/yard/code_objects/class_object.rb +20 -20
- data/lib/yard/code_objects/constant_object.rb +1 -1
- data/lib/yard/code_objects/extended_method_object.rb +5 -5
- data/lib/yard/code_objects/extra_file_object.rb +89 -0
- data/lib/yard/code_objects/macro_object.rb +215 -0
- data/lib/yard/code_objects/method_object.rb +30 -30
- data/lib/yard/code_objects/module_object.rb +1 -1
- data/lib/yard/code_objects/namespace_object.rb +39 -39
- data/lib/yard/code_objects/proxy.rb +38 -38
- data/lib/yard/code_objects/root_object.rb +1 -1
- data/lib/yard/config.rb +40 -40
- data/lib/yard/core_ext/array.rb +2 -2
- data/lib/yard/core_ext/file.rb +11 -11
- data/lib/yard/core_ext/insertion.rb +10 -10
- data/lib/yard/core_ext/module.rb +2 -2
- data/lib/yard/core_ext/string.rb +2 -2
- data/lib/yard/core_ext/symbol_hash.rb +14 -14
- data/lib/yard/docstring.rb +122 -54
- data/lib/yard/globals.rb +2 -2
- data/lib/yard/handlers/base.rb +216 -127
- data/lib/yard/handlers/processor.rb +65 -27
- data/lib/yard/handlers/ruby/alias_handler.rb +6 -3
- data/lib/yard/handlers/ruby/attribute_handler.rb +7 -6
- data/lib/yard/handlers/ruby/base.rb +50 -31
- data/lib/yard/handlers/ruby/class_condition_handler.rb +11 -11
- data/lib/yard/handlers/ruby/class_handler.rb +10 -10
- data/lib/yard/handlers/ruby/class_variable_handler.rb +3 -3
- data/lib/yard/handlers/ruby/constant_handler.rb +7 -7
- data/lib/yard/handlers/ruby/exception_handler.rb +2 -2
- data/lib/yard/handlers/ruby/extend_handler.rb +1 -1
- data/lib/yard/handlers/ruby/legacy/alias_handler.rb +8 -5
- data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +6 -5
- data/lib/yard/handlers/ruby/legacy/base.rb +42 -27
- data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +9 -9
- data/lib/yard/handlers/ruby/legacy/class_handler.rb +13 -12
- data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +3 -6
- data/lib/yard/handlers/ruby/legacy/constant_handler.rb +5 -8
- data/lib/yard/handlers/ruby/legacy/exception_handler.rb +1 -1
- data/lib/yard/handlers/ruby/legacy/extend_handler.rb +1 -0
- data/lib/yard/handlers/ruby/legacy/macro_handler.rb +40 -0
- data/lib/yard/handlers/ruby/legacy/method_handler.rb +10 -10
- data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +4 -3
- data/lib/yard/handlers/ruby/legacy/module_handler.rb +2 -1
- data/lib/yard/handlers/ruby/legacy/private_constant_handler.rb +4 -4
- data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
- data/lib/yard/handlers/ruby/legacy/yield_handler.rb +3 -3
- data/lib/yard/handlers/ruby/macro_handler.rb +41 -0
- data/lib/yard/handlers/ruby/macro_handler_methods.rb +130 -0
- data/lib/yard/handlers/ruby/method_condition_handler.rb +1 -1
- data/lib/yard/handlers/ruby/method_handler.rb +13 -13
- data/lib/yard/handlers/ruby/mixin_handler.rb +4 -4
- data/lib/yard/handlers/ruby/module_handler.rb +2 -1
- data/lib/yard/handlers/ruby/private_constant_handler.rb +4 -4
- data/lib/yard/handlers/ruby/struct_handler_methods.rb +11 -11
- data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
- data/lib/yard/handlers/ruby/yield_handler.rb +5 -5
- data/lib/yard/logging.rb +11 -11
- data/lib/yard/parser/base.rb +8 -8
- data/lib/yard/parser/c_parser.rb +42 -33
- data/lib/yard/parser/ruby/ast_node.rb +62 -61
- data/lib/yard/parser/ruby/legacy/ruby_lex.rb +66 -66
- data/lib/yard/parser/ruby/legacy/ruby_parser.rb +4 -4
- data/lib/yard/parser/ruby/legacy/statement.rb +11 -11
- data/lib/yard/parser/ruby/legacy/statement_list.rb +15 -15
- data/lib/yard/parser/ruby/legacy/token_list.rb +9 -9
- data/lib/yard/parser/ruby/ruby_parser.rb +51 -37
- data/lib/yard/parser/source_parser.rb +271 -46
- data/lib/yard/rake/yardoc_task.rb +18 -17
- data/lib/yard/registry.rb +64 -64
- data/lib/yard/registry_store.rb +34 -34
- data/lib/yard/rubygems/backports.rb +8 -0
- data/lib/yard/rubygems/backports/LICENSE.txt +57 -0
- data/lib/yard/rubygems/backports/MIT.txt +20 -0
- data/lib/yard/rubygems/backports/gem.rb +8 -0
- data/lib/yard/rubygems/backports/source_index.rb +353 -0
- data/lib/yard/rubygems/specification.rb +2 -2
- data/lib/yard/serializers/base.rb +20 -20
- data/lib/yard/serializers/file_system_serializer.rb +28 -24
- data/lib/yard/serializers/process_serializer.rb +3 -3
- data/lib/yard/serializers/stdout_serializer.rb +6 -6
- data/lib/yard/serializers/yardoc_serializer.rb +17 -17
- data/lib/yard/server/adapter.rb +12 -12
- data/lib/yard/server/commands/base.rb +26 -26
- data/lib/yard/server/commands/display_file_command.rb +3 -2
- data/lib/yard/server/commands/display_object_command.rb +5 -5
- data/lib/yard/server/commands/frames_command.rb +1 -1
- data/lib/yard/server/commands/library_command.rb +7 -7
- data/lib/yard/server/commands/library_index_command.rb +2 -2
- data/lib/yard/server/commands/list_command.rb +8 -8
- data/lib/yard/server/commands/search_command.rb +8 -8
- data/lib/yard/server/commands/static_file_command.rb +3 -3
- data/lib/yard/server/doc_server_helper.rb +6 -3
- data/lib/yard/server/doc_server_serializer.rb +1 -1
- data/lib/yard/server/library_version.rb +45 -45
- data/lib/yard/server/rack_adapter.rb +10 -10
- data/lib/yard/server/router.rb +28 -28
- data/lib/yard/server/static_caching.rb +5 -5
- data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +3 -3
- data/lib/yard/server/templates/default/fulldoc/html/js/live.js +1 -1
- data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +2 -2
- data/lib/yard/server/templates/default/layout/html/headers.erb +13 -8
- data/lib/yard/server/templates/default/layout/html/setup.rb +7 -0
- data/lib/yard/server/templates/doc_server/full_list/html/full_list.erb +2 -2
- data/lib/yard/server/templates/doc_server/full_list/html/setup.rb +14 -4
- data/lib/yard/server/templates/doc_server/library_list/html/contents.erb +2 -2
- data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +2 -2
- data/lib/yard/server/templates/doc_server/processing/html/processing.erb +1 -1
- data/lib/yard/server/templates/doc_server/search/html/search.erb +1 -1
- data/lib/yard/server/webrick_adapter.rb +2 -2
- data/lib/yard/tags/default_factory.rb +19 -19
- data/lib/yard/tags/default_tag.rb +1 -1
- data/lib/yard/tags/library.rb +68 -63
- data/lib/yard/tags/option_tag.rb +1 -1
- data/lib/yard/tags/overload_tag.rb +9 -9
- data/lib/yard/tags/ref_tag_list.rb +2 -2
- data/lib/yard/tags/tag.rb +7 -7
- data/lib/yard/templates/engine.rb +31 -31
- data/lib/yard/templates/erb_cache.rb +1 -1
- data/lib/yard/templates/helpers/base_helper.rb +46 -32
- data/lib/yard/templates/helpers/filter_helper.rb +2 -2
- data/lib/yard/templates/helpers/html_helper.rb +120 -81
- data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +4 -4
- data/lib/yard/templates/helpers/markup/rdoc_markup.rb +9 -9
- data/lib/yard/templates/helpers/markup_helper.rb +37 -30
- data/lib/yard/templates/helpers/method_helper.rb +7 -7
- data/lib/yard/templates/helpers/text_helper.rb +7 -7
- data/lib/yard/templates/helpers/uml_helper.rb +3 -3
- data/lib/yard/templates/section.rb +14 -14
- data/lib/yard/templates/template.rb +54 -54
- data/lib/yard/verifier.rb +27 -27
- data/spec/cli/list_spec.rb +8 -0
- data/spec/cli/yardoc_spec.rb +58 -10
- data/spec/code_objects/extra_file_object_spec.rb +132 -0
- data/spec/code_objects/macro_object_spec.rb +154 -0
- data/spec/docstring_spec.rb +90 -0
- data/spec/handlers/base_spec.rb +22 -0
- data/spec/handlers/examples/macro_handler_001.rb.txt +73 -0
- data/spec/handlers/examples/method_handler_001.rb.txt +17 -0
- data/spec/handlers/macro_handler_spec.rb +140 -0
- data/spec/handlers/method_handler_spec.rb +28 -0
- data/spec/handlers/processor_spec.rb +4 -0
- data/spec/handlers/spec_helper.rb +1 -1
- data/spec/parser/c_parser_spec.rb +47 -16
- data/spec/parser/examples/extrafile.c.txt +8 -0
- data/spec/parser/examples/multifile.c.txt +6 -0
- data/spec/parser/ruby/ruby_parser_spec.rb +5 -0
- data/spec/parser/source_parser_spec.rb +235 -0
- data/spec/rake/yardoc_task_spec.rb +22 -17
- data/spec/serializers/file_system_serializer_spec.rb +6 -0
- data/spec/server/commands/library_command_spec.rb +39 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/templates/examples/method001.html +6 -6
- data/spec/templates/examples/method002.html +4 -4
- data/spec/templates/examples/method003.html +10 -10
- data/spec/templates/examples/method005.html +2 -2
- data/spec/templates/examples/module001.dot +2 -0
- data/spec/templates/examples/module001.html +76 -37
- data/spec/templates/examples/module001.txt +1 -1
- data/spec/templates/helpers/base_helper_spec.rb +7 -2
- data/spec/templates/helpers/html_helper_spec.rb +49 -5
- data/spec/templates/helpers/markup_helper_spec.rb +9 -8
- data/spec/templates/module_spec.rb +7 -0
- data/spec/templates/onefile_spec.rb +47 -0
- data/templates/default/fulldoc/html/css/style.css +7 -5
- data/templates/default/fulldoc/html/full_list.erb +13 -10
- data/templates/default/fulldoc/html/full_list_files.erb +1 -1
- data/templates/default/fulldoc/html/js/app.js +16 -14
- data/templates/default/fulldoc/html/js/full_list.js +7 -6
- data/templates/default/fulldoc/html/setup.rb +78 -17
- data/templates/default/layout/html/files.erb +1 -1
- data/templates/default/layout/html/headers.erb +11 -7
- data/templates/default/layout/html/search.erb +4 -4
- data/templates/default/layout/html/setup.rb +28 -8
- data/templates/default/module/html/inherited_attributes.erb +17 -0
- data/templates/default/module/setup.rb +1 -1
- data/templates/default/onefile/html/files.erb +2 -2
- data/templates/default/onefile/html/layout.erb +1 -1
- data/templates/default/onefile/html/setup.rb +7 -5
- data/templates/default/tags/html/option.erb +1 -1
- data/templates/default/tags/html/tag.erb +3 -3
- data/templates/guide/class/html/setup.rb +1 -0
- data/templates/guide/docstring/html/setup.rb +1 -0
- data/templates/guide/fulldoc/html/css/style.css +91 -0
- data/templates/guide/fulldoc/html/js/app.js +33 -0
- data/templates/guide/fulldoc/html/setup.rb +54 -0
- data/templates/guide/layout/html/layout.erb +81 -0
- data/templates/guide/layout/html/setup.rb +24 -0
- data/templates/guide/method/html/header.erb +18 -0
- data/templates/guide/method/html/setup.rb +21 -0
- data/templates/guide/module/html/header.erb +7 -0
- data/templates/guide/module/html/method_list.erb +5 -0
- data/templates/guide/module/html/setup.rb +26 -0
- data/templates/guide/tags/html/setup.rb +8 -0
- metadata +40 -7
- data/lib/yard/handlers/ruby/legacy/process_handler.rb +0 -13
- data/lib/yard/handlers/ruby/process_handler.rb +0 -18
- data/spec/handlers/process_handler_spec.rb +0 -17
@@ -5,9 +5,9 @@ module YARD::CodeObjects
|
|
5
5
|
# The {ClassObject} that this class object inherits from in Ruby source.
|
6
6
|
# @return [ClassObject] a class object that is the superclass of this one
|
7
7
|
attr_reader :superclass
|
8
|
-
|
8
|
+
|
9
9
|
# Creates a new class object in +namespace+ with +name+
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# @see Base.new
|
12
12
|
def initialize(namespace, name, *args, &block)
|
13
13
|
super
|
@@ -25,16 +25,16 @@ module YARD::CodeObjects
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# Whether or not the class is a Ruby Exception
|
30
|
-
#
|
30
|
+
#
|
31
31
|
# @return [Boolean] whether the object represents a Ruby exception
|
32
32
|
def is_exception?
|
33
33
|
inheritance_tree.reverse.any? {|o| BUILTIN_EXCEPTIONS_HASH.has_key? o.path }
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# Returns the inheritance tree of the object including self.
|
37
|
-
#
|
37
|
+
#
|
38
38
|
# @param [Boolean] include_mods whether or not to include mixins in the
|
39
39
|
# inheritance tree.
|
40
40
|
# @return [Array<NamespaceObject>] the list of code objects that make up
|
@@ -50,10 +50,10 @@ module YARD::CodeObjects
|
|
50
50
|
m.inheritance_tree(include_mods)
|
51
51
|
end.flatten.uniq
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
# Returns the list of methods matching the options hash. Returns
|
55
55
|
# all methods if hash is empty.
|
56
|
-
#
|
56
|
+
#
|
57
57
|
# @param [Hash] opts the options hash to match
|
58
58
|
# @option opts [Boolean] :inherited (true) whether inherited methods should be
|
59
59
|
# included in the list
|
@@ -62,16 +62,16 @@ module YARD::CodeObjects
|
|
62
62
|
# @return [Array<MethodObject>] the list of methods that matched
|
63
63
|
def meths(opts = {})
|
64
64
|
opts = SymbolHash[:inherited => true].update(opts)
|
65
|
-
list = super(opts)
|
65
|
+
list = super(opts)
|
66
66
|
list += inherited_meths(opts).reject do |o|
|
67
67
|
next(false) if opts[:all]
|
68
68
|
list.find {|o2| o2.name == o.name && o2.scope == o.scope }
|
69
69
|
end if opts[:inherited]
|
70
70
|
list
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
# Returns only the methods that were inherited.
|
74
|
-
#
|
74
|
+
#
|
75
75
|
# @return [Array<MethodObject>] the list of inherited method objects
|
76
76
|
def inherited_meths(opts = {})
|
77
77
|
inheritance_tree[1..-1].inject([]) do |list, superclass|
|
@@ -86,9 +86,9 @@ module YARD::CodeObjects
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
# Returns the list of constants matching the options hash.
|
91
|
-
#
|
91
|
+
#
|
92
92
|
# @param [Hash] opts the options hash to match
|
93
93
|
# @option opts [Boolean] :inherited (true) whether inherited constant should be
|
94
94
|
# included in the list
|
@@ -99,9 +99,9 @@ module YARD::CodeObjects
|
|
99
99
|
opts = SymbolHash[:inherited => true].update(opts)
|
100
100
|
super(opts) + (opts[:inherited] ? inherited_constants : [])
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
# Returns only the constants that were inherited.
|
104
|
-
#
|
104
|
+
#
|
105
105
|
# @return [Array<ConstantObject>] the list of inherited constant objects
|
106
106
|
def inherited_constants
|
107
107
|
inheritance_tree[1..-1].inject([]) do |list, superclass|
|
@@ -114,11 +114,11 @@ module YARD::CodeObjects
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
# Sets the superclass of the object
|
119
|
-
#
|
119
|
+
#
|
120
120
|
# @param [Base, Proxy, String, Symbol, nil] object the superclass value
|
121
|
-
# @return [void]
|
121
|
+
# @return [void]
|
122
122
|
def superclass=(object)
|
123
123
|
case object
|
124
124
|
when Base, Proxy, NilClass
|
@@ -126,13 +126,13 @@ module YARD::CodeObjects
|
|
126
126
|
when String, Symbol
|
127
127
|
@superclass = Proxy.new(namespace, object)
|
128
128
|
else
|
129
|
-
raise ArgumentError, "superclass must be CodeObject, Proxy, String or Symbol"
|
129
|
+
raise ArgumentError, "superclass must be CodeObject, Proxy, String or Symbol"
|
130
130
|
end
|
131
131
|
|
132
132
|
if name == @superclass.name && namespace != YARD::Registry.root && !object.is_a?(Base)
|
133
133
|
@superclass = Proxy.new(namespace.namespace, object)
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
if @superclass == self
|
137
137
|
msg = "superclass #{@superclass.inspect} cannot be the same as the declared class #{self.inspect}"
|
138
138
|
@superclass = P("::Object")
|
@@ -1,20 +1,20 @@
|
|
1
1
|
module YARD::CodeObjects
|
2
2
|
# Represents an instance method of a module that was mixed into the class
|
3
3
|
# scope of another namespace.
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# @see MethodObject
|
6
6
|
class ExtendedMethodObject
|
7
7
|
instance_methods.each {|m| undef_method(m) unless m =~ /^__/ || m.to_sym == :object_id }
|
8
|
-
|
8
|
+
|
9
9
|
# @return [Symbol] always +:class+
|
10
10
|
def scope; :class end
|
11
|
-
|
11
|
+
|
12
12
|
# Sets up a delegate for {MethodObject} obj.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# @param [MethodObject] obj the instance method to treat as a mixed in
|
15
15
|
# class method on another namespace.
|
16
16
|
def initialize(obj) @del = obj end
|
17
|
-
|
17
|
+
|
18
18
|
# Sends all methods to the {MethodObject} assigned in {#initialize}
|
19
19
|
# @see #initialize
|
20
20
|
# @see MethodObject
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module YARD::CodeObjects
|
2
|
+
# An ExtraFileObject represents an extra documentation file (README or other
|
3
|
+
# file). It is not strictly a CodeObject (does not inherit from `Base`) although
|
4
|
+
# it implements `path`, `name` and `type`, and therefore should be structurally
|
5
|
+
# compatible with most CodeObject interfaces.
|
6
|
+
class ExtraFileObject
|
7
|
+
attr_accessor :filename
|
8
|
+
attr_accessor :attributes
|
9
|
+
attr_accessor :name
|
10
|
+
attr_accessor :contents
|
11
|
+
|
12
|
+
# Creates a new extra file object.
|
13
|
+
# @param [String] filename the location on disk of the file
|
14
|
+
# @param [String] contents the file contents. If not set, the contents
|
15
|
+
# will be read from disk using the +filename+.
|
16
|
+
def initialize(filename, contents = nil)
|
17
|
+
self.filename = filename
|
18
|
+
self.name = File.basename(filename).gsub(/\.[^.]+$/, '')
|
19
|
+
self.attributes = SymbolHash.new(false)
|
20
|
+
parse_contents(contents || File.read(@filename))
|
21
|
+
end
|
22
|
+
|
23
|
+
alias path name
|
24
|
+
|
25
|
+
def title
|
26
|
+
attributes[:title] || name
|
27
|
+
end
|
28
|
+
|
29
|
+
def inspect
|
30
|
+
"#<yardoc #{type} #{filename} attrs=#{attributes.inspect}>"
|
31
|
+
end
|
32
|
+
alias to_s inspect
|
33
|
+
|
34
|
+
def type; 'extra_file' end
|
35
|
+
|
36
|
+
def ==(other)
|
37
|
+
return false unless self.class === other
|
38
|
+
other.filename == filename
|
39
|
+
end
|
40
|
+
alias eql? ==
|
41
|
+
alias equal? ==
|
42
|
+
def hash; filename.hash end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# @param [String] data the file contents
|
47
|
+
def parse_contents(data)
|
48
|
+
retried = false
|
49
|
+
cut_index = 0
|
50
|
+
data = data.split("\n")
|
51
|
+
data.each_with_index do |line, index|
|
52
|
+
case line
|
53
|
+
when /^#!(\S+)\s*$/
|
54
|
+
if index == 0
|
55
|
+
attributes[:markup] = $1
|
56
|
+
else
|
57
|
+
cut_index = index
|
58
|
+
break
|
59
|
+
end
|
60
|
+
when /^\s*#\s*@(\S+)\s*(.+?)\s*$/
|
61
|
+
attributes[$1] = $2
|
62
|
+
else
|
63
|
+
cut_index = index
|
64
|
+
break
|
65
|
+
end
|
66
|
+
end
|
67
|
+
data = data[cut_index..-1] if cut_index > 0
|
68
|
+
self.contents = data.join("\n")
|
69
|
+
|
70
|
+
if contents.respond_to?(:force_encoding) && attributes[:encoding]
|
71
|
+
begin
|
72
|
+
contents.force_encoding(attributes[:encoding])
|
73
|
+
rescue ArgumentError
|
74
|
+
log.warn "Invalid encoding `#{attributes[:encoding]}' in #{filename}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
rescue ArgumentError => e
|
78
|
+
if retried && e.message =~ /invalid byte sequence/
|
79
|
+
# This should never happen.
|
80
|
+
log.warn "Could not read #{filename}, #{e.message}. You probably want to set `--charset`."
|
81
|
+
self.contents = ''
|
82
|
+
return
|
83
|
+
end
|
84
|
+
data.force_encoding('binary') if data.respond_to?(:force_encoding)
|
85
|
+
retried = true
|
86
|
+
retry
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
module YARD
|
2
|
+
module CodeObjects
|
3
|
+
# A MacroObject represents a docstring defined through +@macro NAME+ and can be
|
4
|
+
# reused by specifying the tag +@macro NAME+. You can also provide the
|
5
|
+
# +attached+ type flag to the macro definition to have it attached to the
|
6
|
+
# specific DSL method so it will be implicitly reused.
|
7
|
+
#
|
8
|
+
# Macros are fully described in the {file:docs/Tags.md#macros Tags Overview}
|
9
|
+
# document.
|
10
|
+
#
|
11
|
+
# @example Creating a basic named macro
|
12
|
+
# # @macro prop
|
13
|
+
# # @method $1(${3-})
|
14
|
+
# # @return [$2] the value of the $0
|
15
|
+
# property :foo, String, :a, :b
|
16
|
+
#
|
17
|
+
# # @macro prop
|
18
|
+
# property :bar, Numeric, :value
|
19
|
+
#
|
20
|
+
# @example Creating a macro that is attached to the method call
|
21
|
+
# # @macro [attach] prop2
|
22
|
+
# # @method $1(value)
|
23
|
+
# property :foo
|
24
|
+
#
|
25
|
+
# # Extra data added to docstring
|
26
|
+
# property :bar
|
27
|
+
class MacroObject < Base
|
28
|
+
MACRO_MATCH = /(\\)?\$(?:\{(-?\d+|\*)(-)?(-?\d+)?\}|(-?\d+|\*))/
|
29
|
+
|
30
|
+
class << self
|
31
|
+
# Creates a new macro and fills in the relevant properties.
|
32
|
+
# @param [String] macro_name the name of the macro, must be unique.
|
33
|
+
# @param [String] data the data the macro should expand when re-used
|
34
|
+
# @param [CodeObjects::Base] method_object an object to attach this
|
35
|
+
# macro to. If supplied, {#attached?} will be true
|
36
|
+
# @return [MacroObject] the newly created object
|
37
|
+
def create(macro_name, data, method_object = nil)
|
38
|
+
obj = new(:root, macro_name)
|
39
|
+
obj.macro_data = data
|
40
|
+
obj.method_object = method_object
|
41
|
+
obj
|
42
|
+
end
|
43
|
+
|
44
|
+
# Finds a macro using +macro_name+
|
45
|
+
# @return [MacroObject] if a macro is found
|
46
|
+
# @return [nil] if there is no registered macro by that name
|
47
|
+
def find(macro_name)
|
48
|
+
Registry.at('.macro.' + macro_name.to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Parses a given docstring and determines if the macro is "new" or
|
52
|
+
# not. If the macro has $variable names or if it has a @macro tag
|
53
|
+
# with the [new] or [attached] flag, it is considered new.
|
54
|
+
#
|
55
|
+
# If a new macro is found, the macro is created and registered. Otherwise
|
56
|
+
# the macro name is searched and returned. If a macro is not found,
|
57
|
+
# nil is returned.
|
58
|
+
#
|
59
|
+
# @param [CodeObjects::Base] method_object an optional method to attach
|
60
|
+
# the macro to. Only used if the macro is being created, otherwise
|
61
|
+
# this argument is ignored.
|
62
|
+
# @return [MacroObject] the newly created or existing macro, depending
|
63
|
+
# on whether the @macro tag was a new tag or not.
|
64
|
+
# @return [nil] if the +data+ has no macro tag or if the macro is
|
65
|
+
# not new and no macro by the macro name is found.
|
66
|
+
def find_or_create(data, method_object = nil)
|
67
|
+
docstring = Docstring === data ? data : Docstring.new(data)
|
68
|
+
return unless docstring.tag(:macro)
|
69
|
+
return unless name = macro_name(docstring)
|
70
|
+
if new_macro?(docstring)
|
71
|
+
method_object = nil unless attached_macro?(docstring, method_object)
|
72
|
+
create(name, macro_data(docstring), method_object)
|
73
|
+
else
|
74
|
+
find(name)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
alias create_docstring find_or_create
|
78
|
+
|
79
|
+
# Expands +macro_data+ using the interpolation parameters.
|
80
|
+
#
|
81
|
+
# Interpolation rules:
|
82
|
+
# * $0, $1, $2, ... = the Nth parameter in +call_params+
|
83
|
+
# * $& = the full statement source (excluding block)
|
84
|
+
# * Also supports $\{N-M} ranges, as well as negative indexes on N or M
|
85
|
+
# * Use \$ to escape the variable name in a macro.
|
86
|
+
#
|
87
|
+
# @macro [new] macro.expand
|
88
|
+
# @param [Array<String>] call_params the method name and parameters
|
89
|
+
# to the method call. These arguments will fill \$0-N
|
90
|
+
# @param [String] full_source the full source line (excluding block)
|
91
|
+
# interpolated as \$&
|
92
|
+
# @param [String] block_source Currently unused. Will support
|
93
|
+
# interpolating the block data as a variable.
|
94
|
+
# @return [String] the expanded macro data
|
95
|
+
# @param [String] macro_data the macro data to expand (taken from {#macro_data})
|
96
|
+
def expand(macro_data, call_params = [], full_source = '', block_source = '')
|
97
|
+
macro_data = macro_data.all if macro_data.is_a?(Docstring)
|
98
|
+
macro_data.gsub(MACRO_MATCH) do
|
99
|
+
escape, first, last, rng = $1, $2 || $5, $4, $3 ? true : false
|
100
|
+
next $&[1..-1] if escape
|
101
|
+
if first == '*'
|
102
|
+
last ? $& : full_source
|
103
|
+
else
|
104
|
+
first_i = first.to_i
|
105
|
+
last_i = (last ? last.to_i : call_params.size)
|
106
|
+
last_i = first_i unless rng
|
107
|
+
params = call_params[first_i..last_i]
|
108
|
+
params ? params.join(", ") : ''
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Applies a macro on a docstring by creating any macro data inside of
|
114
|
+
# the docstring first. Equivalent to calling {find_or_create} and {apply_macro}
|
115
|
+
# on the new macro object.
|
116
|
+
#
|
117
|
+
# @param [Docstring] docstring the docstring to create a macro out of
|
118
|
+
# @macro macro.expand
|
119
|
+
# @see find_or_create
|
120
|
+
def apply(docstring, call_params = [], full_source = '', block_source = '', method_object = nil)
|
121
|
+
macro = find_or_create(docstring, method_object)
|
122
|
+
apply_macro(macro, docstring, call_params, full_source, block_source)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Applies a macro to a docstring, interpolating the macro's data on the
|
126
|
+
# docstring and appending any extra local docstring data that was in
|
127
|
+
# the original +docstring+ object.
|
128
|
+
#
|
129
|
+
# @param [MacroObject] macro the macro object
|
130
|
+
# @macro macro.expand
|
131
|
+
def apply_macro(macro, docstring, call_params = [], full_source = '', block_source = '')
|
132
|
+
docstring = Docstring.new(docstring) unless Docstring === docstring
|
133
|
+
data = []
|
134
|
+
data << macro.expand(call_params, full_source, block_source) if macro
|
135
|
+
if !macro && new_macro?(docstring)
|
136
|
+
data << expand(macro_data(docstring), call_params, full_source, block_source)
|
137
|
+
end
|
138
|
+
data << nonmacro_data(docstring)
|
139
|
+
data.join("\n").strip
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def new_macro?(docstring)
|
145
|
+
if docstring.tag(:macro)
|
146
|
+
if types = docstring.tag(:macro).types
|
147
|
+
return true if types.include?('new') || types.include?('attach')
|
148
|
+
end
|
149
|
+
if docstring.all =~ MACRO_MATCH
|
150
|
+
return true
|
151
|
+
end
|
152
|
+
end
|
153
|
+
false
|
154
|
+
end
|
155
|
+
|
156
|
+
def attached_macro?(docstring, method_object)
|
157
|
+
return false if method_object.nil?
|
158
|
+
return false if docstring.tag(:macro).types.nil?
|
159
|
+
docstring.tag(:macro).types.include?('attach')
|
160
|
+
end
|
161
|
+
|
162
|
+
def macro_name(docstring)
|
163
|
+
docstring.tag(:macro).name
|
164
|
+
end
|
165
|
+
|
166
|
+
def macro_data(docstring)
|
167
|
+
new_docstring = docstring.dup
|
168
|
+
new_docstring.delete_tags(:macro)
|
169
|
+
tag_text = docstring.tag(:macro).text
|
170
|
+
if !tag_text || tag_text.strip.empty?
|
171
|
+
new_docstring.to_raw.strip
|
172
|
+
else
|
173
|
+
tag_text
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def nonmacro_data(docstring)
|
178
|
+
if new_macro?(docstring)
|
179
|
+
text = docstring.tag(:macro).text
|
180
|
+
return '' if !text || text.strip.empty?
|
181
|
+
end
|
182
|
+
new_docstring = docstring.dup
|
183
|
+
new_docstring.delete_tags(:macro)
|
184
|
+
new_docstring.to_raw
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# @return [String] the macro data stored on the object
|
189
|
+
attr_accessor :macro_data
|
190
|
+
|
191
|
+
# @return [CodeObjects::Base] the method object that this macro is
|
192
|
+
# attached to.
|
193
|
+
attr_accessor :method_object
|
194
|
+
|
195
|
+
# @return [Boolean] whether this macro is attached to a method
|
196
|
+
def attached?; method_object ? true : false end
|
197
|
+
def path; '.macro.' + name.to_s end
|
198
|
+
def sep; '.' end
|
199
|
+
|
200
|
+
# Expands the macro using
|
201
|
+
# @param [Array<String>] call_params a list of tokens that are passed
|
202
|
+
# to the method call
|
203
|
+
# @param [String] full_source the full method call (not including the block)
|
204
|
+
# @param [String] block_source the source passed in the block of the method
|
205
|
+
# call, if there is a block.
|
206
|
+
# @example Expanding a Macro
|
207
|
+
# macro.expand(%w(property foo bar), 'property :foo, :bar', '') #=>
|
208
|
+
# "...macro data interpolating this line of code..."
|
209
|
+
# @see expand
|
210
|
+
def expand(call_params = [], full_source = '', block_source = '')
|
211
|
+
self.class.expand(macro_data, call_params, full_source, block_source)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|