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
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'stringio'
|
2
|
+
require 'ostruct'
|
2
3
|
|
3
4
|
begin require 'continuation'; rescue LoadError; end
|
4
5
|
|
@@ -6,52 +7,63 @@ module YARD
|
|
6
7
|
module Parser
|
7
8
|
# Raised when an object is recognized but cannot be documented. This
|
8
9
|
# generally occurs when the Ruby syntax used to declare an object is
|
9
|
-
# too dynamic in nature.
|
10
|
+
# too dynamic in nature.
|
10
11
|
class UndocumentableError < Exception; end
|
11
|
-
|
12
|
+
|
12
13
|
# Raised when the parser sees a Ruby syntax error
|
13
14
|
class ParserSyntaxError < UndocumentableError; end
|
14
|
-
|
15
|
-
# A LoadOrderError occurs when a handler needs to modify a
|
15
|
+
|
16
|
+
# A LoadOrderError occurs when a handler needs to modify a
|
16
17
|
# {CodeObjects::NamespaceObject} (usually by adding a child to it)
|
17
|
-
# that has not yet been resolved.
|
18
|
-
#
|
18
|
+
# that has not yet been resolved.
|
19
|
+
#
|
19
20
|
# @see Handers::Base#ensure_loaded!
|
20
21
|
class LoadOrderError < Exception; end
|
21
|
-
|
22
|
+
|
22
23
|
# Responsible for parsing a source file into the namespace. Parsing
|
23
24
|
# also invokes handlers to process the parsed statements and generate
|
24
25
|
# any code objects that may be recognized.
|
25
|
-
#
|
26
|
+
#
|
26
27
|
# == Custom Parsers
|
27
28
|
# SourceParser allows custom parsers to be registered and called when
|
28
29
|
# a certain filetype is recognized. To register a parser and hook it
|
29
30
|
# up to a set of file extensions, call {register_parser_type}
|
30
|
-
#
|
31
|
+
#
|
31
32
|
# @see register_parser_type
|
32
33
|
# @see Handlers::Base
|
33
34
|
# @see CodeObjects::Base
|
34
|
-
class SourceParser
|
35
|
+
class SourceParser
|
35
36
|
SHEBANG_LINE = /\A\s*#!\S+/
|
36
37
|
ENCODING_LINE = /\A(?:\s*#*!.*\r?\n)?\s*#+.*coding\s*[:=]{1,2}\s*(\S+)/i
|
37
38
|
|
39
|
+
# Byte order marks for various encodings
|
40
|
+
# @since 0.7.0
|
41
|
+
ENCODING_BYTE_ORDER_MARKS = {
|
42
|
+
'utf-8' => "\xEF\xBB\xBF",
|
43
|
+
# Not yet supported
|
44
|
+
#'utf-16be' => "\xFE\xFF",
|
45
|
+
#'utf-16le' => "\xFF\xFE",
|
46
|
+
#'utf-32be' => "\x00\x00\xFF\xFE",
|
47
|
+
#'utf-32le' => "\xFF\xFE",
|
48
|
+
}
|
49
|
+
|
38
50
|
class << self
|
39
51
|
# @return [Symbol] the default parser type (defaults to :ruby)
|
40
52
|
attr_reader :parser_type
|
41
|
-
|
53
|
+
|
42
54
|
def parser_type=(value)
|
43
55
|
@parser_type = validated_parser_type(value)
|
44
56
|
end
|
45
|
-
|
57
|
+
|
46
58
|
# Parses a path or set of paths
|
47
|
-
#
|
59
|
+
#
|
48
60
|
# @param [String, Array<String>] paths a path, glob, or list of paths to
|
49
61
|
# parse
|
50
62
|
# @param [Array<String, Regexp>] excluded a list of excluded path matchers
|
51
63
|
# @param [Fixnum] level the logger level to use during parsing. See
|
52
64
|
# {YARD::Logger}
|
53
|
-
# @return the parser object that was used to parse the source.
|
54
|
-
def parse(paths = ["lib/**/*.rb", "ext/**/*.c"], excluded = [], level = log.level)
|
65
|
+
# @return the parser object that was used to parse the source.
|
66
|
+
def parse(paths = ["{lib,app}/**/*.rb", "ext/**/*.c"], excluded = [], level = log.level)
|
55
67
|
log.debug("Parsing #{paths.inspect} with `#{parser_type}` parser")
|
56
68
|
excluded = excluded.map do |path|
|
57
69
|
case path
|
@@ -68,27 +80,27 @@ module YARD
|
|
68
80
|
parse_in_order(*files.uniq)
|
69
81
|
end
|
70
82
|
end
|
71
|
-
|
83
|
+
|
72
84
|
# Parses a string +content+
|
73
|
-
#
|
85
|
+
#
|
74
86
|
# @param [String] content the block of code to parse
|
75
87
|
# @param [Symbol] ptype the parser type to use. See {parser_type}.
|
76
88
|
# @return the parser object that was used to parse +content+
|
77
89
|
def parse_string(content, ptype = parser_type)
|
78
90
|
new(ptype).parse(StringIO.new(content))
|
79
91
|
end
|
80
|
-
|
92
|
+
|
81
93
|
# Tokenizes but does not parse the block of code
|
82
|
-
#
|
94
|
+
#
|
83
95
|
# @param [String] content the block of code to tokenize
|
84
96
|
# @param [Symbol] ptype the parser type to use. See {parser_type}.
|
85
97
|
# @return [Array] a list of tokens
|
86
98
|
def tokenize(content, ptype = parser_type)
|
87
99
|
new(ptype).tokenize(content)
|
88
100
|
end
|
89
|
-
|
101
|
+
|
90
102
|
# Registers a new parser type.
|
91
|
-
#
|
103
|
+
#
|
92
104
|
# @example Registering a parser for "java" files
|
93
105
|
# SourceParser.register_parser_type :java, JavaParser, 'java'
|
94
106
|
# @param [Symbol] type a symbolic name for the parser type
|
@@ -104,7 +116,7 @@ module YARD
|
|
104
116
|
parser_type_extensions[type.to_sym] = extensions if extensions
|
105
117
|
parser_types[type.to_sym] = parser_klass
|
106
118
|
end
|
107
|
-
|
119
|
+
|
108
120
|
# @return [Hash{Symbol=>Object}] a list of registered parser types
|
109
121
|
# @private
|
110
122
|
# @since 0.5.6
|
@@ -112,7 +124,7 @@ module YARD
|
|
112
124
|
undef parser_types
|
113
125
|
def parser_types; @@parser_types ||= {} end
|
114
126
|
def parser_types=(value) @@parser_types = value end
|
115
|
-
|
127
|
+
|
116
128
|
# @return [Hash] a list of registered parser type extensions
|
117
129
|
# @private
|
118
130
|
# @since 0.5.6
|
@@ -123,7 +135,7 @@ module YARD
|
|
123
135
|
|
124
136
|
# Finds a parser type that is registered for the extension. If no
|
125
137
|
# type is found, the default Ruby type is returned.
|
126
|
-
#
|
138
|
+
#
|
127
139
|
# @return [Symbol] the parser type to be used for the extension
|
128
140
|
# @since 0.5.6
|
129
141
|
def parser_type_for_extension(extension)
|
@@ -132,10 +144,10 @@ module YARD
|
|
132
144
|
end
|
133
145
|
validated_parser_type(type ? type.first : :ruby)
|
134
146
|
end
|
135
|
-
|
147
|
+
|
136
148
|
# Returns the validated parser type. Basically, enforces that :ruby
|
137
149
|
# type is never set if the Ripper library is not available
|
138
|
-
#
|
150
|
+
#
|
139
151
|
# @param [Symbol] type the parser type to set
|
140
152
|
# @return [Symbol] the validated parser type
|
141
153
|
# @private
|
@@ -143,16 +155,193 @@ module YARD
|
|
143
155
|
!defined?(::Ripper) && type == :ruby ? :ruby18 : type
|
144
156
|
end
|
145
157
|
|
146
|
-
|
158
|
+
# @group Parser Callbacks
|
159
|
+
|
160
|
+
# Registers a callback to be called before a list of files is parsed
|
161
|
+
# via {parse}. The block passed to this method will be called on
|
162
|
+
# subsequent parse calls.
|
163
|
+
#
|
164
|
+
# @example Installing a simple callback
|
165
|
+
# SourceParser.before_parse_list do |files, globals|
|
166
|
+
# puts "Starting to parse..."
|
167
|
+
# end
|
168
|
+
# YARD.parse('lib/**/*.rb')
|
169
|
+
# # prints "Starting to parse..."
|
170
|
+
#
|
171
|
+
# @example Setting global state
|
172
|
+
# SourceParser.before_parse_list do |files, globals|
|
173
|
+
# globals.method_count = 0
|
174
|
+
# end
|
175
|
+
# SourceParser.after_parse_list do |files, globals|
|
176
|
+
# puts "Found #{globals.method_count} methods"
|
177
|
+
# end
|
178
|
+
# class MyCountHandler < Handlers::Ruby::Base
|
179
|
+
# handles :def, :defs
|
180
|
+
# process { globals.method_count += 1 }
|
181
|
+
# end
|
182
|
+
# YARD.parse
|
183
|
+
# # Prints: "Found 37 methods"
|
184
|
+
#
|
185
|
+
# @example Using a global callback to cancel parsing
|
186
|
+
# SourceParser.before_parse_list do |files, globals|
|
187
|
+
# return false if files.include?('foo.rb')
|
188
|
+
# end
|
189
|
+
#
|
190
|
+
# YARD.parse(['foo.rb', 'bar.rb']) # callback cancels this method
|
191
|
+
# YARD.parse('bar.rb') # parses normally
|
192
|
+
#
|
193
|
+
# @yield [files, globals] the yielded block is called once before
|
194
|
+
# parsing all files
|
195
|
+
# @yieldparam [Array<String>] files the list of files that will be parsed.
|
196
|
+
# @yieldparam [OpenStruct] globals a global structure to store arbitrary
|
197
|
+
# state for post processing (see {Handlers::Processor#globals})
|
198
|
+
# @yieldreturn [Boolean] if the block returns +false+, parsing is
|
199
|
+
# cancelled.
|
200
|
+
# @return [Proc] the yielded block
|
201
|
+
# @see after_parse_list
|
202
|
+
# @see before_parse_file
|
203
|
+
# @since 0.7.0
|
204
|
+
def before_parse_list(&block)
|
205
|
+
before_parse_list_callbacks << block
|
206
|
+
end
|
207
|
+
|
208
|
+
# Registers a callback to be called after a list of files is parsed
|
209
|
+
# via {parse}. The block passed to this method will be called on
|
210
|
+
# subsequent parse calls.
|
211
|
+
#
|
212
|
+
# @example Printing results after parsing occurs
|
213
|
+
# SourceParser.after_parse_list do
|
214
|
+
# puts "Finished parsing!"
|
215
|
+
# end
|
216
|
+
# YARD.parse
|
217
|
+
# # Prints "Finished parsing!" after parsing files
|
218
|
+
# @yield [files, globals] the yielded block is called once before
|
219
|
+
# parsing all files
|
220
|
+
# @yieldparam [Array<String>] files the list of files that will be parsed.
|
221
|
+
# @yieldparam [OpenStruct] globals a global structure to store arbitrary
|
222
|
+
# state for post processing (see {Handlers::Processor#globals})
|
223
|
+
# @yieldreturn [void] the return value for the block is ignored.
|
224
|
+
# @return [Proc] the yielded block
|
225
|
+
# @see before_parse_list
|
226
|
+
# @see before_parse_file
|
227
|
+
# @since 0.7.0
|
228
|
+
def after_parse_list(&block)
|
229
|
+
after_parse_list_callbacks << block
|
230
|
+
end
|
231
|
+
|
232
|
+
# Registers a callback to be called before an individual file is parsed.
|
233
|
+
# The block passed to this method will be called on subsequent parse
|
234
|
+
# calls.
|
235
|
+
#
|
236
|
+
# To register a callback that is called before the entire list of files
|
237
|
+
# is processed, see {before_parse_list}.
|
238
|
+
#
|
239
|
+
# @example Installing a simple callback
|
240
|
+
# SourceParser.before_parse_file do |parser|
|
241
|
+
# puts "I'm parsing #{parser.file}"
|
242
|
+
# end
|
243
|
+
# YARD.parse('lib/**/*.rb')
|
244
|
+
# # prints:
|
245
|
+
# "I'm parsing lib/foo.rb"
|
246
|
+
# "I'm parsing lib/foo_bar.rb"
|
247
|
+
# "I'm parsing lib/last_file.rb"
|
248
|
+
#
|
249
|
+
# @example Cancel parsing of any test_*.rb files
|
250
|
+
# SourceParser.before_parse_file do |parser|
|
251
|
+
# return false if parser.file =~ /^test_.+\.rb$/
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
# @yield [parser] the yielded block is called once before each
|
255
|
+
# file that is parsed. This might happen many times for a single
|
256
|
+
# codebase.
|
257
|
+
# @yieldparam [SourceParser] parser the parser object that will {#parse}
|
258
|
+
# the file.
|
259
|
+
# @yieldreturn [Boolean] if the block returns +false+, parsing for
|
260
|
+
# the file is cancelled.
|
261
|
+
# @return [Proc] the yielded block
|
262
|
+
# @see after_parse_file
|
263
|
+
# @see before_parse_list
|
264
|
+
# @since 0.7.0
|
265
|
+
def before_parse_file(&block)
|
266
|
+
before_parse_file_callbacks << block
|
267
|
+
end
|
268
|
+
|
269
|
+
# Registers a callback to be called after an individual file is parsed.
|
270
|
+
# The block passed to this method will be called on subsequent parse
|
271
|
+
# calls.
|
272
|
+
#
|
273
|
+
# To register a callback that is called after the entire list of files
|
274
|
+
# is processed, see {after_parse_list}.
|
275
|
+
#
|
276
|
+
# @example Printing the length of each file after it is parsed
|
277
|
+
# SourceParser.after_parse_file do |parser|
|
278
|
+
# puts "#{parser.file} is #{parser.contents.size} characters"
|
279
|
+
# end
|
280
|
+
# YARD.parse('lib/**/*.rb')
|
281
|
+
# # prints:
|
282
|
+
# "lib/foo.rb is 1240 characters"
|
283
|
+
# "lib/foo_bar.rb is 248 characters"
|
284
|
+
#
|
285
|
+
# @yield [parser] the yielded block is called once after each file
|
286
|
+
# that is parsed. This might happen many times for a single codebase.
|
287
|
+
# @yieldparam [SourceParser] parser the parser object that parsed
|
288
|
+
# the file.
|
289
|
+
# @yieldreturn [void] the return value for the block is ignored.
|
290
|
+
# @return [Proc] the yielded block
|
291
|
+
# @see before_parse_file
|
292
|
+
# @see after_parse_list
|
293
|
+
# @since 0.7.0
|
294
|
+
def after_parse_file(&block)
|
295
|
+
after_parse_file_callbacks << block
|
296
|
+
end
|
297
|
+
|
298
|
+
# @return [Array<Proc>] the list of callbacks to be called before
|
299
|
+
# parsing a list of files. Should only be used for testing.
|
300
|
+
# @since 0.7.0
|
301
|
+
def before_parse_list_callbacks
|
302
|
+
@before_parse_list_callbacks ||= []
|
303
|
+
end
|
304
|
+
|
305
|
+
# @return [Array<Proc>] the list of callbacks to be called after
|
306
|
+
# parsing a list of files. Should only be used for testing.
|
307
|
+
# @since 0.7.0
|
308
|
+
def after_parse_list_callbacks
|
309
|
+
@after_parse_list_callbacks ||= []
|
310
|
+
end
|
311
|
+
|
312
|
+
# @return [Array<Proc>] the list of callbacks to be called before
|
313
|
+
# parsing a file. Should only be used for testing.
|
314
|
+
# @since 0.7.0
|
315
|
+
def before_parse_file_callbacks
|
316
|
+
@before_parse_file_callbacks ||= []
|
317
|
+
end
|
147
318
|
|
319
|
+
# @return [Array<Proc>] the list of callbacks to be called after
|
320
|
+
# parsing a file. Should only be used for testing.
|
321
|
+
# @since 0.7.0
|
322
|
+
def after_parse_file_callbacks
|
323
|
+
@after_parse_file_callbacks ||= []
|
324
|
+
end
|
325
|
+
|
326
|
+
# @endgroup
|
327
|
+
|
328
|
+
private
|
329
|
+
|
148
330
|
# Parses a list of files in a queue. If a {LoadOrderError} is caught,
|
149
331
|
# the file is moved to the back of the queue with a Continuation object
|
150
332
|
# that can continue processing the file.
|
151
|
-
#
|
333
|
+
#
|
152
334
|
# @param [Array<String>] files a list of files to queue for parsing
|
153
335
|
# @return [void]
|
154
336
|
def parse_in_order(*files)
|
337
|
+
global_state = OpenStruct.new
|
155
338
|
files = files.sort_by {|x| x.length if x }
|
339
|
+
files_copy = files.dup
|
340
|
+
|
341
|
+
before_parse_list_callbacks.each do |cb|
|
342
|
+
return if cb.call(files_copy, global_state) == false
|
343
|
+
end
|
344
|
+
|
156
345
|
while file = files.shift
|
157
346
|
begin
|
158
347
|
if file.is_a?(Array) && file.last.is_a?(Continuation)
|
@@ -160,13 +349,17 @@ module YARD
|
|
160
349
|
file.last.call
|
161
350
|
elsif file.is_a?(String)
|
162
351
|
log.debug("Processing #{file}...")
|
163
|
-
new(parser_type, true).parse(file)
|
352
|
+
new(parser_type, true, global_state).parse(file)
|
164
353
|
end
|
165
354
|
rescue LoadOrderError => e
|
166
355
|
# Out of order file. Push the context to the end and we'll call it
|
167
356
|
files.push([file, e.message])
|
168
357
|
end
|
169
358
|
end
|
359
|
+
|
360
|
+
after_parse_list_callbacks.each do |cb|
|
361
|
+
cb.call(files_copy, global_state)
|
362
|
+
end
|
170
363
|
end
|
171
364
|
end
|
172
365
|
|
@@ -175,21 +368,32 @@ module YARD
|
|
175
368
|
register_parser_type :c, CParser, ['c', 'cc', 'cxx', 'cpp']
|
176
369
|
|
177
370
|
self.parser_type = :ruby
|
178
|
-
|
179
|
-
#
|
371
|
+
|
372
|
+
# @return [String] the filename being parsed by the parser.
|
180
373
|
attr_reader :file
|
181
|
-
|
182
|
-
#
|
183
|
-
# be set by the {#initialize constructor}.
|
374
|
+
|
375
|
+
# @return [Symbol] the parser type associated with the parser instance.
|
376
|
+
# This should be set by the {#initialize constructor}.
|
184
377
|
attr_reader :parser_type
|
378
|
+
|
379
|
+
# @return [OpenStruct] an open struct containing arbitrary global state
|
380
|
+
# shared between files and handlers.
|
381
|
+
# @since 0.7.0
|
382
|
+
attr_reader :globals
|
383
|
+
|
384
|
+
# @return [String] the contents of the file to be parsed
|
385
|
+
# @since 0.7.0
|
386
|
+
attr_reader :contents
|
185
387
|
|
186
388
|
# Creates a new parser object for code parsing with a specific parser type.
|
187
|
-
#
|
389
|
+
#
|
188
390
|
# @param [Symbol] parser_type the parser type to use
|
189
391
|
# @param [Boolean] load_order_errors whether or not to raise the {LoadOrderError}
|
190
|
-
|
392
|
+
# @param [OpenStruct] globals global state to be re-used across separate source files
|
393
|
+
def initialize(parser_type = SourceParser.parser_type, load_order_errors = false, globals = nil)
|
191
394
|
@load_order_errors = load_order_errors
|
192
395
|
@file = '(stdin)'
|
396
|
+
@globals = globals || OpenStruct.new
|
193
397
|
self.parser_type = parser_type
|
194
398
|
end
|
195
399
|
|
@@ -214,28 +418,39 @@ module YARD
|
|
214
418
|
else
|
215
419
|
content = content.read if content.respond_to? :read
|
216
420
|
end
|
217
|
-
|
421
|
+
|
422
|
+
@contents = content
|
218
423
|
@parser = parser_class.new(content, file)
|
424
|
+
|
425
|
+
self.class.before_parse_file_callbacks.each do |cb|
|
426
|
+
return @parser if cb.call(self) == false
|
427
|
+
end
|
428
|
+
|
219
429
|
@parser.parse
|
220
430
|
post_process
|
431
|
+
|
432
|
+
self.class.after_parse_file_callbacks.each do |cb|
|
433
|
+
cb.call(self)
|
434
|
+
end
|
435
|
+
|
221
436
|
@parser
|
222
437
|
rescue ArgumentError, NotImplementedError => e
|
223
438
|
log.warn("Cannot parse `#{file}': #{e.message}")
|
224
439
|
rescue ParserSyntaxError => e
|
225
440
|
log.warn(e.message.capitalize)
|
226
441
|
end
|
227
|
-
|
442
|
+
|
228
443
|
# Tokenizes but does not parse the block of code using the current {#parser_type}
|
229
|
-
#
|
444
|
+
#
|
230
445
|
# @param [String] content the block of code to tokenize
|
231
446
|
# @return [Array] a list of tokens
|
232
447
|
def tokenize(content)
|
233
448
|
@parser = parser_class.new(content, file)
|
234
449
|
@parser.tokenize
|
235
450
|
end
|
236
|
-
|
451
|
+
|
237
452
|
private
|
238
|
-
|
453
|
+
|
239
454
|
# Searches for encoding line and forces encoding
|
240
455
|
# @since 0.5.3
|
241
456
|
def convert_encoding(content)
|
@@ -243,25 +458,35 @@ module YARD
|
|
243
458
|
if content =~ ENCODING_LINE
|
244
459
|
content.force_encoding($1)
|
245
460
|
else
|
461
|
+
old_encoding = content.encoding
|
462
|
+
content.force_encoding('binary')
|
463
|
+
ENCODING_BYTE_ORDER_MARKS.each do |encoding, bom|
|
464
|
+
bom.force_encoding('binary')
|
465
|
+
if content[0,bom.size] == bom
|
466
|
+
content.force_encoding(encoding)
|
467
|
+
return content
|
468
|
+
end
|
469
|
+
end
|
470
|
+
content.force_encoding(old_encoding)
|
246
471
|
content
|
247
472
|
end
|
248
473
|
end
|
249
474
|
|
250
475
|
# Runs a {Handlers::Processor} object to post process the parsed statements.
|
251
|
-
# @return [void]
|
476
|
+
# @return [void]
|
252
477
|
def post_process
|
253
478
|
return unless @parser.respond_to? :enumerator
|
254
479
|
return unless enumerator = @parser.enumerator
|
255
|
-
post = Handlers::Processor.new(@file, @load_order_errors, @parser_type)
|
480
|
+
post = Handlers::Processor.new(@file, @load_order_errors, @parser_type, @globals)
|
256
481
|
post.process(enumerator)
|
257
482
|
end
|
258
483
|
|
259
484
|
def parser_type=(value)
|
260
485
|
@parser_type = self.class.validated_parser_type(value)
|
261
486
|
end
|
262
|
-
|
487
|
+
|
263
488
|
# Guesses the parser type to use depending on the file extension.
|
264
|
-
#
|
489
|
+
#
|
265
490
|
# @param [String] filename the filename to use to guess the parser type
|
266
491
|
# @return [Symbol] a parser type that matches the filename
|
267
492
|
def parser_type_for_filename(filename)
|
@@ -269,7 +494,7 @@ module YARD
|
|
269
494
|
type = self.class.parser_type_for_extension(ext)
|
270
495
|
parser_type == :ruby18 && type == :ruby ? :ruby18 : type
|
271
496
|
end
|
272
|
-
|
497
|
+
|
273
498
|
# @since 0.5.6
|
274
499
|
def parser_class
|
275
500
|
klass = self.class.parser_types[parser_type]
|