yard 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of yard might be problematic. Click here for more details.
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README +211 -0
- data/Rakefile +31 -0
- data/benchmarks/builtins_vs_eval.rb +23 -0
- data/benchmarks/erb_vs_erubis.rb +53 -0
- data/benchmarks/generation.rb +37 -0
- data/benchmarks/parsing.rb +33 -0
- data/bin/view_generator +17 -0
- data/bin/yard-graph +4 -0
- data/bin/yardoc +1 -93
- data/bin/yri +12 -3
- data/lib/yard.rb +10 -5
- data/lib/yard/autoload.rb +116 -0
- data/lib/yard/cli/yard_graph.rb +86 -0
- data/lib/yard/cli/yardoc.rb +131 -0
- data/lib/yard/code_objects/base.rb +321 -0
- data/lib/yard/code_objects/class_object.rb +89 -0
- data/lib/yard/code_objects/class_variable_object.rb +4 -0
- data/lib/yard/code_objects/constant_object.rb +4 -0
- data/lib/yard/code_objects/method_object.rb +51 -0
- data/lib/yard/code_objects/module_object.rb +4 -0
- data/lib/yard/code_objects/namespace_object.rb +88 -0
- data/lib/yard/code_objects/proxy.rb +183 -0
- data/lib/yard/code_objects/root_object.rb +8 -0
- data/lib/yard/core_ext/file.rb +26 -0
- data/lib/yard/core_ext/logger.rb +5 -0
- data/lib/yard/core_ext/module.rb +9 -0
- data/lib/yard/core_ext/string.rb +13 -0
- data/lib/yard/core_ext/symbol_hash.rb +24 -0
- data/lib/yard/generators/attributes_generator.rb +22 -0
- data/lib/yard/generators/base.rb +285 -0
- data/lib/yard/generators/class_generator.rb +25 -0
- data/lib/yard/generators/constants_generator.rb +73 -0
- data/lib/yard/generators/constructor_generator.rb +25 -0
- data/lib/yard/generators/deprecated_generator.rb +15 -0
- data/lib/yard/generators/docstring_generator.rb +15 -0
- data/lib/yard/generators/full_doc_generator.rb +59 -0
- data/lib/yard/generators/helpers/base_helper.rb +52 -0
- data/lib/yard/generators/helpers/filter_helper.rb +21 -0
- data/lib/yard/generators/helpers/html_helper.rb +137 -0
- data/lib/yard/generators/helpers/method_helper.rb +27 -0
- data/lib/yard/generators/helpers/uml_helper.rb +16 -0
- data/lib/yard/generators/inheritance_generator.rb +16 -0
- data/lib/yard/generators/method_details_generator.rb +18 -0
- data/lib/yard/generators/method_generator.rb +31 -0
- data/lib/yard/generators/method_listing_generator.rb +105 -0
- data/lib/yard/generators/method_missing_generator.rb +25 -0
- data/lib/yard/generators/method_signature_generator.rb +19 -0
- data/lib/yard/generators/method_summary_generator.rb +21 -0
- data/lib/yard/generators/mixins_generator.rb +15 -0
- data/lib/yard/generators/module_generator.rb +22 -0
- data/lib/yard/generators/quick_doc_generator.rb +31 -0
- data/lib/yard/generators/source_generator.rb +26 -0
- data/lib/yard/generators/tags_generator.rb +50 -0
- data/lib/yard/generators/uml_generator.rb +92 -0
- data/lib/yard/generators/visibility_group_generator.rb +26 -0
- data/lib/yard/handlers/alias_handler.rb +32 -0
- data/lib/yard/handlers/attribute_handler.rb +54 -0
- data/lib/yard/handlers/base.rb +509 -0
- data/lib/yard/handlers/class_handler.rb +44 -0
- data/lib/yard/handlers/class_variable_handler.rb +13 -0
- data/lib/yard/handlers/constant_handler.rb +13 -0
- data/lib/yard/handlers/exception_handler.rb +12 -0
- data/lib/yard/handlers/method_handler.rb +27 -0
- data/lib/yard/handlers/mixin_handler.rb +16 -0
- data/lib/yard/handlers/module_handler.rb +9 -0
- data/lib/yard/handlers/visibility_handler.rb +14 -0
- data/lib/yard/handlers/yield_handler.rb +26 -0
- data/lib/yard/logging.rb +27 -0
- data/lib/yard/parser/ruby_lex.rb +1344 -0
- data/lib/yard/parser/source_parser.rb +109 -0
- data/lib/yard/parser/statement.rb +36 -0
- data/lib/yard/parser/statement_list.rb +167 -0
- data/lib/yard/parser/token_list.rb +58 -0
- data/lib/yard/rake/yardoc_task.rb +30 -0
- data/lib/yard/registry.rb +136 -0
- data/lib/yard/serializers/base.rb +16 -0
- data/lib/yard/serializers/file_system_serializer.rb +48 -0
- data/lib/yard/serializers/process_serializer.rb +14 -0
- data/lib/yard/serializers/stdout_serializer.rb +21 -0
- data/lib/yard/tags/default_factory.rb +98 -0
- data/lib/yard/tags/library.rb +109 -0
- data/lib/yard/tags/merbdoc_factory.rb +47 -0
- data/lib/yard/tags/tag.rb +35 -0
- data/spec/code_objects/base_spec.rb +219 -0
- data/spec/code_objects/class_object_spec.rb +176 -0
- data/spec/code_objects/code_object_list_spec.rb +33 -0
- data/spec/code_objects/constants_spec.rb +79 -0
- data/spec/code_objects/method_object_spec.rb +30 -0
- data/spec/code_objects/module_object_spec.rb +73 -0
- data/spec/code_objects/namespace_object_spec.rb +129 -0
- data/spec/code_objects/proxy_spec.rb +80 -0
- data/spec/code_objects/spec_helper.rb +3 -0
- data/spec/core_ext/file_spec.rb +20 -0
- data/spec/core_ext/string_spec.rb +4 -0
- data/spec/core_ext/symbol_hash_spec.rb +80 -0
- data/spec/generators/base_spec.rb +64 -0
- data/spec/generators/helpers/base_helper_spec.rb +15 -0
- data/spec/generators/helpers/html_helper_spec.rb +56 -0
- data/spec/generators/quick_doc_generator_spec.rb +13 -0
- data/spec/handlers/alias_handler_spec.rb +50 -0
- data/spec/handlers/attribute_handler_spec.rb +78 -0
- data/spec/handlers/base_spec.rb +165 -0
- data/spec/handlers/class_handler_spec.rb +68 -0
- data/spec/handlers/class_variable_handler_spec.rb +9 -0
- data/spec/handlers/constant_handler_spec.rb +13 -0
- data/spec/handlers/examples/alias_handler_001.rb.txt +24 -0
- data/spec/handlers/examples/attribute_handler_001.rb.txt +19 -0
- data/spec/handlers/examples/class_handler_001.rb.txt +39 -0
- data/spec/handlers/examples/class_variable_handler_001.rb.txt +9 -0
- data/spec/handlers/examples/constant_handler_001.rb.txt +10 -0
- data/spec/handlers/examples/exception_handler_001.rb.txt +42 -0
- data/spec/handlers/examples/method_handler_001.rb.txt +35 -0
- data/spec/handlers/examples/mixin_handler_001.rb.txt +12 -0
- data/spec/handlers/examples/module_handler_001.rb.txt +16 -0
- data/spec/handlers/examples/visibility_handler_001.rb.txt +20 -0
- data/spec/handlers/examples/yield_handler_001.rb.txt +55 -0
- data/spec/handlers/exception_handler_spec.rb +35 -0
- data/spec/handlers/method_handler_spec.rb +35 -0
- data/spec/handlers/mixin_handler_spec.rb +30 -0
- data/spec/handlers/module_handler_spec.rb +25 -0
- data/spec/handlers/spec_helper.rb +21 -0
- data/spec/handlers/visibility_handler_spec.rb +24 -0
- data/spec/handlers/yield_handler_spec.rb +51 -0
- data/spec/parser/examples/example1.rb.txt +8 -0
- data/spec/parser/examples/tag_handler_001.rb.txt +8 -0
- data/spec/parser/source_parser_spec.rb +43 -0
- data/spec/parser/tag_parsing_spec.rb +18 -0
- data/spec/parser/token_list_spec.rb +35 -0
- data/spec/registry_spec.rb +70 -0
- data/spec/serializers/file_system_serializer_spec.rb +91 -0
- data/spec/serializers/spec_helper.rb +2 -0
- data/spec/spec_helper.rb +77 -0
- data/templates/default/attributes/html/header.erb +35 -0
- data/templates/default/attributes/text/header.erb +10 -0
- data/templates/default/class/html/header.erb +4 -0
- data/templates/default/constants/html/constants.erb +9 -0
- data/templates/default/constants/html/header.erb +3 -0
- data/templates/default/constants/html/included.erb +9 -0
- data/templates/default/constants/html/inherited.erb +9 -0
- data/templates/default/constructor/html/header.erb +10 -0
- data/templates/default/deprecated/html/main.erb +4 -0
- data/templates/default/deprecated/text/main.erb +3 -0
- data/templates/default/docstring/html/main.erb +3 -0
- data/templates/default/docstring/text/main.erb +3 -0
- data/templates/default/fulldoc/html/all_methods.erb +25 -0
- data/templates/default/fulldoc/html/all_namespaces.erb +19 -0
- data/templates/default/fulldoc/html/app.js +18 -0
- data/templates/default/fulldoc/html/header.erb +15 -0
- data/templates/default/fulldoc/html/html_head.erb +3 -0
- data/templates/default/fulldoc/html/index.erb +18 -0
- data/templates/default/fulldoc/html/jquery.js +11 -0
- data/templates/default/fulldoc/html/readme.erb +15 -0
- data/templates/default/fulldoc/html/style.css +65 -0
- data/templates/default/fulldoc/html/syntax_highlight.css +21 -0
- data/templates/default/inheritance/html/header.erb +8 -0
- data/templates/default/inheritance/text/header.erb +3 -0
- data/templates/default/method/html/aliases.erb +6 -0
- data/templates/default/method/html/header.erb +3 -0
- data/templates/default/method/html/title.erb +3 -0
- data/templates/default/methoddetails/html/header.erb +8 -0
- data/templates/default/methoddetails/html/method_header.erb +3 -0
- data/templates/default/methodmissing/html/header.erb +12 -0
- data/templates/default/methodsignature/html/main.erb +8 -0
- data/templates/default/methodsignature/text/main.erb +5 -0
- data/templates/default/methodsummary/html/header.erb +5 -0
- data/templates/default/methodsummary/html/included.erb +9 -0
- data/templates/default/methodsummary/html/inherited.erb +9 -0
- data/templates/default/methodsummary/html/summary.erb +25 -0
- data/templates/default/methodsummary/text/header.erb +5 -0
- data/templates/default/methodsummary/text/included.erb +0 -0
- data/templates/default/methodsummary/text/inherited.erb +0 -0
- data/templates/default/methodsummary/text/summary.erb +3 -0
- data/templates/default/mixins/html/header.erb +4 -0
- data/templates/default/module/html/header.erb +4 -0
- data/templates/default/quickdoc/html/header.erb +15 -0
- data/templates/default/quickdoc/text/header.erb +12 -0
- data/templates/default/source/html/main.erb +15 -0
- data/templates/default/source/text/main.erb +4 -0
- data/templates/default/tags/html/header.erb +4 -0
- data/templates/default/tags/html/see.erb +13 -0
- data/templates/default/tags/html/tags.erb +20 -0
- data/templates/default/tags/text/header.erb +3 -0
- data/templates/default/tags/text/see.erb +5 -0
- data/templates/default/tags/text/tags.erb +7 -0
- data/templates/default/uml/dot/child.erb +1 -0
- data/templates/default/uml/dot/dependencies.erb +10 -0
- data/templates/default/uml/dot/header.erb +6 -0
- data/templates/default/uml/dot/info.erb +14 -0
- data/templates/default/uml/dot/subgraph.erb +6 -0
- data/templates/default/uml/dot/superclasses.erb +9 -0
- data/templates/default/uml/dot/unknown.erb +3 -0
- data/templates/default/uml/dot/unknown_child.erb +1 -0
- data/templates/default/visibilitygroup/html/header.erb +6 -0
- data/templates/javadoc/attributes/html/header.erb +16 -0
- data/templates/javadoc/class/html/header.erb +4 -0
- data/templates/javadoc/constants/html/constants.erb +9 -0
- data/templates/javadoc/constants/html/header.erb +3 -0
- data/templates/javadoc/constants/html/included.erb +12 -0
- data/templates/javadoc/constants/html/inherited.erb +12 -0
- data/templates/javadoc/constructor/html/header.erb +10 -0
- data/templates/javadoc/deprecated/html/main.erb +0 -0
- data/templates/javadoc/docstring/html/main.erb +6 -0
- data/templates/javadoc/fulldoc/html/all_methods.erb +25 -0
- data/templates/javadoc/fulldoc/html/all_namespaces.erb +19 -0
- data/templates/javadoc/fulldoc/html/app.js +18 -0
- data/templates/javadoc/fulldoc/html/header.erb +15 -0
- data/templates/javadoc/fulldoc/html/html_head.erb +3 -0
- data/templates/javadoc/fulldoc/html/index.erb +18 -0
- data/templates/javadoc/fulldoc/html/jquery.js +11 -0
- data/templates/javadoc/fulldoc/html/readme.erb +15 -0
- data/templates/javadoc/fulldoc/html/style.css +22 -0
- data/templates/javadoc/fulldoc/html/syntax_highlight.css +21 -0
- data/templates/javadoc/inheritance/html/header.erb +6 -0
- data/templates/javadoc/method/html/aliases.erb +6 -0
- data/templates/javadoc/method/html/header.erb +4 -0
- data/templates/javadoc/method/html/title.erb +4 -0
- data/templates/javadoc/methoddetails/html/header.erb +8 -0
- data/templates/javadoc/methoddetails/html/method_header.erb +0 -0
- data/templates/javadoc/methodmissing/html/header.erb +12 -0
- data/templates/javadoc/methodsignature/html/main.erb +8 -0
- data/templates/javadoc/methodsummary/html/header.erb +5 -0
- data/templates/javadoc/methodsummary/html/included.erb +12 -0
- data/templates/javadoc/methodsummary/html/inherited.erb +12 -0
- data/templates/javadoc/methodsummary/html/summary.erb +25 -0
- data/templates/javadoc/mixins/html/header.erb +5 -0
- data/templates/javadoc/module/html/header.erb +4 -0
- data/templates/javadoc/source/html/main.erb +15 -0
- data/templates/javadoc/tags/html/header.erb +5 -0
- data/templates/javadoc/tags/html/see.erb +8 -0
- data/templates/javadoc/tags/html/tags.erb +19 -0
- data/templates/javadoc/visibilitygroup/html/header.erb +5 -0
- metadata +352 -50
- data/README.pdf +0 -0
- data/lib/code_object.rb +0 -337
- data/lib/extra.rb +0 -8
- data/lib/formatter.rb +0 -90
- data/lib/handlers/all_handlers.rb +0 -2
- data/lib/handlers/attribute_handler.rb +0 -51
- data/lib/handlers/class_handler.rb +0 -30
- data/lib/handlers/class_variable_handler.rb +0 -9
- data/lib/handlers/code_object_handler.rb +0 -104
- data/lib/handlers/constant_handler.rb +0 -11
- data/lib/handlers/exception_handler.rb +0 -20
- data/lib/handlers/method_handler.rb +0 -28
- data/lib/handlers/mixin_handler.rb +0 -15
- data/lib/handlers/module_handler.rb +0 -9
- data/lib/handlers/visibility_handler.rb +0 -7
- data/lib/handlers/yield_handler.rb +0 -33
- data/lib/logger.rb +0 -19
- data/lib/namespace.rb +0 -98
- data/lib/quick_doc.rb +0 -104
- data/lib/ruby_lex.rb +0 -1321
- data/lib/source_parser.rb +0 -253
- data/lib/tag_library.rb +0 -175
- data/lib/tag_type.rb +0 -155
- data/templates/default/html/_fulldoc.erb +0 -64
- data/templates/default/html/class.erb +0 -226
- data/templates/default/html/method.erb +0 -20
- data/templates/default/html/module.erb +0 -126
- data/test/fixtures/docstring.txt +0 -23
- data/test/fixtures/docstring2.txt +0 -4
- data/test/test_code_object.rb +0 -66
- data/test/test_namespace.rb +0 -10
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module YARD
|
4
|
+
module Parser
|
5
|
+
class LoadOrderError < Exception; end
|
6
|
+
|
7
|
+
# Responsible for parsing a source file into the namespace
|
8
|
+
class SourceParser
|
9
|
+
class << self
|
10
|
+
def parse(paths = "lib/**/*.rb", level = log.level)
|
11
|
+
if paths.is_a?(Array)
|
12
|
+
files = paths.map {|p| Dir[p] }.flatten
|
13
|
+
else
|
14
|
+
files = Dir[File.join(Dir.pwd, paths)]
|
15
|
+
end
|
16
|
+
|
17
|
+
log.enter_level(level) do
|
18
|
+
parse_in_order(*files.uniq)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_string(content)
|
23
|
+
new.parse(StringIO.new(content))
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def parse_in_order(*files)
|
29
|
+
while file = files.shift
|
30
|
+
begin
|
31
|
+
if file.is_a?(Array) && file.last.is_a?(Continuation)
|
32
|
+
log.debug("Re-processing #{file.first}")
|
33
|
+
file.last.call
|
34
|
+
elsif file.is_a?(String)
|
35
|
+
log.debug("Processing #{file}...")
|
36
|
+
new(true).parse(file)
|
37
|
+
end
|
38
|
+
rescue LoadOrderError => e
|
39
|
+
# Out of order file. Push the context to the end and we'll call it
|
40
|
+
files.push([file, e.message])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :file
|
47
|
+
attr_accessor :namespace, :visibility, :scope, :owner, :load_order_errors
|
48
|
+
|
49
|
+
def initialize(load_order_errors = false)
|
50
|
+
@file = "<STDIN>"
|
51
|
+
@namespace = YARD::Registry.root
|
52
|
+
@visibility = :public
|
53
|
+
@scope = :instance
|
54
|
+
@owner = @namespace
|
55
|
+
@load_order_errors = load_order_errors
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Creates a new SourceParser that parses a file and returns
|
60
|
+
# analysis information about it.
|
61
|
+
#
|
62
|
+
# @param [String, TokenList, StatementList, #read] content the source file to parse
|
63
|
+
def parse(content = __FILE__)
|
64
|
+
case content
|
65
|
+
when String
|
66
|
+
@file = content
|
67
|
+
statements = StatementList.new(IO.read(content))
|
68
|
+
when TokenList
|
69
|
+
statements = StatementList.new(content)
|
70
|
+
when StatementList
|
71
|
+
statements = content
|
72
|
+
else
|
73
|
+
if content.respond_to? :read
|
74
|
+
statements = StatementList.new(content.read)
|
75
|
+
else
|
76
|
+
raise ArgumentError, "Invalid argument for SourceParser::parse: #{content.inspect}:#{content.class}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
top_level_parse(statements)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
def top_level_parse(statements)
|
85
|
+
statements.each do |stmt|
|
86
|
+
find_handlers(stmt).each do |handler|
|
87
|
+
begin
|
88
|
+
handler.new(self, stmt).process
|
89
|
+
rescue LoadOrderError => loaderr
|
90
|
+
raise # Pass this up
|
91
|
+
rescue Handlers::UndocumentableError => undocerr
|
92
|
+
log.warn "in #{handler.to_s}: Undocumentable #{undocerr.message}"
|
93
|
+
log.warn "\tin file '#{file}':#{stmt.tokens.first.line_no}:\n\n" + stmt.inspect + "\n"
|
94
|
+
rescue => e
|
95
|
+
log.error "Unhandled exception in #{handler.to_s}:"
|
96
|
+
log.error "#{e.class.class_name}: #{e.message}"
|
97
|
+
log.error " in `#{file}`:#{stmt.tokens.first.line_no}:\n\n#{stmt.inspect}\n"
|
98
|
+
log.error "Stack trace:" + e.backtrace[0..5].map {|x| "\n\t#{x}" }.join + "\n"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def find_handlers(stmt)
|
105
|
+
Handlers::Base.subclasses.find_all {|sub| sub.handles? stmt.tokens }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module YARD
|
2
|
+
module Parser
|
3
|
+
class Statement
|
4
|
+
attr_reader :tokens, :comments, :block
|
5
|
+
|
6
|
+
def initialize(tokens, block = nil, comments = nil)
|
7
|
+
@tokens = tokens
|
8
|
+
@block = block
|
9
|
+
@comments = comments
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect(lines = nil)
|
13
|
+
flineno = tokens.first.line_no
|
14
|
+
buf = [""]
|
15
|
+
tokens.each do |tk|
|
16
|
+
if tk.is_a?(RubyToken::TkNL)
|
17
|
+
buf.push ""
|
18
|
+
else
|
19
|
+
buf.last << tk.text
|
20
|
+
end
|
21
|
+
end
|
22
|
+
buf.map {|line| "\t#{flineno}: #{line}" }.join("\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def clean_tokens(tokens)
|
27
|
+
last_tk = nil
|
28
|
+
tokens.reject do |tk|
|
29
|
+
tk.is_a?(RubyToken::TkNL) ||
|
30
|
+
(last_tk.is_a?(RubyToken::TkSPACE) &&
|
31
|
+
last_tk.class == tk.class) && last_tk = tk
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module YARD
|
2
|
+
module Parser
|
3
|
+
class StatementList < Array
|
4
|
+
include RubyToken
|
5
|
+
|
6
|
+
# The following list of tokens will require a block to be opened
|
7
|
+
# if used at the beginning of a statement.
|
8
|
+
OPEN_BLOCK_TOKENS = [TkCLASS, TkDEF, TkMODULE, TkUNTIL,
|
9
|
+
TkIF, TkUNLESS, TkWHILE, TkFOR, TkCASE]
|
10
|
+
COLON_TOKENS = [TkUNTIL, TkIF, TkUNLESS, TkWHILE, TkCASE, TkWHEN]
|
11
|
+
|
12
|
+
##
|
13
|
+
# Creates a new statement list
|
14
|
+
#
|
15
|
+
# @param [TokenList, String] content the tokens to create the list from
|
16
|
+
def initialize(content)
|
17
|
+
if content.is_a? TokenList
|
18
|
+
@tokens = content.dup
|
19
|
+
elsif content.is_a? String
|
20
|
+
@tokens = TokenList.new(content)
|
21
|
+
else
|
22
|
+
raise ArgumentError, "Invalid content for StatementList: #{content.inspect}:#{content.class}"
|
23
|
+
end
|
24
|
+
|
25
|
+
parse_statements
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def parse_statements
|
31
|
+
while stmt = next_statement do self << stmt end
|
32
|
+
end
|
33
|
+
|
34
|
+
# MUST REFACTOR THIS CODE
|
35
|
+
# WARNING WARNING WARNING WARNING
|
36
|
+
# MUST REFACTOR THIS CODE |
|
37
|
+
# OR CHILDREN WILL DIE V
|
38
|
+
# WARNING WARNING WARNING WARNING
|
39
|
+
# THIS IS MEANT TO BE UGLY.
|
40
|
+
def next_statement
|
41
|
+
statement, block, comments = TokenList.new, nil, nil
|
42
|
+
stmt_number, level = 0, 0
|
43
|
+
new_statement, open_block = true, false
|
44
|
+
last_tk, last_ns_tk, before_last_tk = nil, nil, nil
|
45
|
+
open_parens = 0
|
46
|
+
|
47
|
+
while tk = @tokens.shift
|
48
|
+
#p tk.class
|
49
|
+
# !!!!!!!!!!!!!!!!!!!! REMOVED TkfLPAREN, TkfLBRACK
|
50
|
+
open_parens += 1 if [TkLPAREN, TkLBRACK].include? tk.class
|
51
|
+
open_parens -= 1 if [TkRPAREN, TkRBRACK].include?(tk.class)
|
52
|
+
|
53
|
+
#if open_parens < 0 || level < 0
|
54
|
+
# STDERR.puts block.to_s + " TOKEN #{tk.inspect}"
|
55
|
+
# exit
|
56
|
+
#end
|
57
|
+
|
58
|
+
# Get the initial comments
|
59
|
+
if statement.empty?
|
60
|
+
# Two new-lines in a row will destroy any comment blocks
|
61
|
+
if [TkCOMMENT].include?(tk.class) && last_tk.class == TkNL &&
|
62
|
+
(before_last_tk && (before_last_tk.class == TkNL || before_last_tk.class == TkSPACE))
|
63
|
+
comments = nil
|
64
|
+
elsif tk.class == TkCOMMENT
|
65
|
+
# Remove the "#" and up to 1 space before the text
|
66
|
+
# Since, of course, the convention is to have "# text"
|
67
|
+
# and not "#text", which I deem ugly (you heard it here first)
|
68
|
+
comments ||= []
|
69
|
+
comments << tk.text.gsub(/^#+\s{0,1}/, '')
|
70
|
+
comments.pop if comments.size == 1 && comments.first =~ /^\s*$/
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Ignore any initial comments or whitespace
|
75
|
+
unless statement.empty? && [TkSPACE, TkNL, TkCOMMENT].include?(tk.class)
|
76
|
+
# Decrease if end or '}' is seen
|
77
|
+
level -= 1 if [TkEND, TkRBRACE].include?(tk.class)
|
78
|
+
|
79
|
+
# If the level is greater than 0, add the code to the block text
|
80
|
+
# otherwise it's part of the statement text
|
81
|
+
if stmt_number > 0
|
82
|
+
#puts "Block of #{statement}"
|
83
|
+
#puts "#{stmt_number} #{tk.line_no} #{level} #{open_parens} #{tk.class.class_name} \t#{tk.text.inspect} #{tk.lex_state} #{open_block.inspect}"
|
84
|
+
block ||= TokenList.new
|
85
|
+
block << tk
|
86
|
+
elsif stmt_number == 0 && tk.class != TkNL && tk.class != TkSEMICOLON && tk.class != TkCOMMENT
|
87
|
+
statement << tk
|
88
|
+
end
|
89
|
+
|
90
|
+
#puts "#{tk.line_no} #{level} #{open_parens} #{tk.class.class_name} \t#{tk.text.inspect} #{tk.lex_state} #{open_block.inspect}"
|
91
|
+
|
92
|
+
# Increase level if we have a 'do' or block opening
|
93
|
+
if tk.class == TkLBRACE #|| tk.class == TkfLBRACE
|
94
|
+
level += 1
|
95
|
+
elsif [TkDO, TkBEGIN].include?(tk.class)
|
96
|
+
#p "#{tk.line_no} #{level} #{tk} \t#{tk.text} #{tk.lex_state}"
|
97
|
+
level += 1
|
98
|
+
open_block = false # Cancel our wish to open a block for the if, we're doing it now
|
99
|
+
end
|
100
|
+
|
101
|
+
# Vouch to open a block when this statement would otherwise end
|
102
|
+
open_block = [level, tk.class] if (new_statement ||
|
103
|
+
(last_tk && last_tk.lex_state == EXPR_BEG)) &&
|
104
|
+
OPEN_BLOCK_TOKENS.include?(tk.class)
|
105
|
+
|
106
|
+
# Check if this token creates a new statement or not
|
107
|
+
#puts "#{open_parens} open brackets for: #{statement.to_s}"
|
108
|
+
if open_parens == 0 && ((last_tk && [TkSEMICOLON, TkNL, TkEND_OF_SCRIPT].include?(tk.class)) ||
|
109
|
+
(open_block && open_block.last == TkDEF && tk.class == TkRPAREN))
|
110
|
+
|
111
|
+
# Make sure we don't have any running expressions
|
112
|
+
# This includes things like
|
113
|
+
#
|
114
|
+
# class <
|
115
|
+
# Foo
|
116
|
+
#
|
117
|
+
# if a ||
|
118
|
+
# b
|
119
|
+
if (last_tk && [EXPR_END, EXPR_ARG].include?(last_tk.lex_state)) ||
|
120
|
+
(open_block && [TkNL, TkSEMICOLON].include?(tk.class) && last_ns_tk.class != open_block.last)
|
121
|
+
stmt_number += 1
|
122
|
+
new_statement = true
|
123
|
+
#p "NEW STATEMENT #{block.to_s}"
|
124
|
+
|
125
|
+
# The statement started with a if/while/begin, so we must go to the next level now
|
126
|
+
if open_block && open_block.first == level
|
127
|
+
if tk.class == TkNL && block.nil?
|
128
|
+
block = TokenList.new
|
129
|
+
block << tk
|
130
|
+
end
|
131
|
+
|
132
|
+
open_block = false
|
133
|
+
level += 1
|
134
|
+
end
|
135
|
+
end
|
136
|
+
elsif tk.class != TkSPACE
|
137
|
+
new_statement = false
|
138
|
+
end
|
139
|
+
|
140
|
+
# Else keyword is kind of weird
|
141
|
+
if tk.is_a? TkELSE
|
142
|
+
new_statement = true
|
143
|
+
stmt_number += 1
|
144
|
+
open_block = false
|
145
|
+
end
|
146
|
+
|
147
|
+
# We're done if we've ended a statement and we're at level 0
|
148
|
+
break if new_statement && level == 0
|
149
|
+
|
150
|
+
#raise "Unexpected end" if level < 0
|
151
|
+
end
|
152
|
+
|
153
|
+
#break if new_statement && level == 0
|
154
|
+
|
155
|
+
before_last_tk = last_tk
|
156
|
+
last_tk = tk # Save last token
|
157
|
+
last_ns_tk = tk unless [TkSPACE, TkNL, TkEND_OF_SCRIPT].include? tk.class
|
158
|
+
end
|
159
|
+
|
160
|
+
# Return the code block with starting token and initial comments
|
161
|
+
# If there is no code in the block, return nil
|
162
|
+
comments = comments.compact if comments
|
163
|
+
statement.empty? ? nil : Statement.new(statement, block, comments)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module YARD
|
2
|
+
module Parser
|
3
|
+
class TokenList < Array
|
4
|
+
include RubyToken
|
5
|
+
|
6
|
+
def initialize(content = nil)
|
7
|
+
self << content if content
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
collect {|t| t.text }.join
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param [TokenList, Token, String] tokens
|
15
|
+
# A list of tokens. If the token is a string, it
|
16
|
+
# is parsed with {RubyLex}.
|
17
|
+
def push(*tokens)
|
18
|
+
tokens.each do |tok|
|
19
|
+
if tok.is_a?(TokenList) || tok.is_a?(Array)
|
20
|
+
concat tok
|
21
|
+
elsif tok.is_a?(Token)
|
22
|
+
super tok
|
23
|
+
elsif tok.is_a?(String)
|
24
|
+
parse_content(tok)
|
25
|
+
else
|
26
|
+
raise ArgumentError, "Expecting token, list of tokens or string of code to be tokenized. Got #{tok.class}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
self
|
30
|
+
end
|
31
|
+
alias_method :<<, :push
|
32
|
+
|
33
|
+
def squeeze(type = TkSPACE)
|
34
|
+
last = nil
|
35
|
+
TokenList.new(map {|t| x = t.is_a?(type) && last.is_a?(type) ? nil : t; last = t; x })
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def parse_content(content)
|
41
|
+
lex = RubyLex.new(content)
|
42
|
+
while tk = lex.token do
|
43
|
+
self << convert_token(lex, tk)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def convert_token(lex, tk)
|
48
|
+
if TkSYMBEG === tk && next_tk = lex.token
|
49
|
+
sym = TkSYMBOL.new(tk.line_no, tk.char_no, nil)
|
50
|
+
sym.lex_state = lex.lex_state
|
51
|
+
sym.set_text(tk.text + next_tk.text)
|
52
|
+
else
|
53
|
+
tk
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
module YARD
|
5
|
+
module Rake
|
6
|
+
|
7
|
+
class YardocTask < ::Rake::TaskLib
|
8
|
+
attr_accessor :name
|
9
|
+
attr_accessor :options
|
10
|
+
attr_accessor :files
|
11
|
+
|
12
|
+
def initialize(name = :yardoc)
|
13
|
+
@name = name
|
14
|
+
@options = []
|
15
|
+
@files = []
|
16
|
+
|
17
|
+
yield self if block_given?
|
18
|
+
self.options += ENV['OPTS'].split(/[ ,]/) if ENV['OPTS']
|
19
|
+
self.files += ENV['FILES'].split(/[ ,]/) if ENV['FILES']
|
20
|
+
|
21
|
+
define
|
22
|
+
end
|
23
|
+
|
24
|
+
def define
|
25
|
+
desc "Generate YARD Documentation"
|
26
|
+
task(name) { YARD::CLI::Yardoc.run *(options + files) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'find'
|
3
|
+
|
4
|
+
module YARD
|
5
|
+
class Registry
|
6
|
+
DEFAULT_YARDOC_FILE = ".yardoc"
|
7
|
+
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
@objects = {}
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :objects
|
14
|
+
|
15
|
+
def method_missing(meth, *args, &block)
|
16
|
+
if instance.respond_to? meth
|
17
|
+
instance.send(meth, *args, &block)
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def clear
|
24
|
+
instance.clear
|
25
|
+
objects.clear
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :yardoc_file
|
30
|
+
attr_reader :proxy_types
|
31
|
+
|
32
|
+
def load(files = [], reload = false)
|
33
|
+
if files.is_a?(Array)
|
34
|
+
if File.exists?(yardoc_file) && !reload
|
35
|
+
load_yardoc
|
36
|
+
else
|
37
|
+
size = namespace.size
|
38
|
+
YARD.parse(files)
|
39
|
+
save if namespace.size > size
|
40
|
+
end
|
41
|
+
true
|
42
|
+
elsif files.is_a?(String)
|
43
|
+
load_yardoc(files)
|
44
|
+
true
|
45
|
+
else
|
46
|
+
raise ArgumentError, "Must take a list of files to parse or the .yardoc file to load."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_yardoc(file = yardoc_file)
|
51
|
+
return false unless File.exists?(file)
|
52
|
+
ns, pt = *Marshal.load(IO.read(file))
|
53
|
+
namespace.update(ns)
|
54
|
+
proxy_types.update(pt)
|
55
|
+
end
|
56
|
+
|
57
|
+
def save(file = yardoc_file)
|
58
|
+
File.open(file, "w") {|f| Marshal.dump([@namespace, @proxy_types], f) }
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def all(*types)
|
63
|
+
namespace.values.select do |obj|
|
64
|
+
if types.empty?
|
65
|
+
obj != Registry.root
|
66
|
+
else
|
67
|
+
obj != Registry.root &&
|
68
|
+
types.any? do |type|
|
69
|
+
type.is_a?(Symbol) ? obj.type == type : obj.is_a?(type)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def paths
|
76
|
+
namespace.keys.map {|k| k.to_s }
|
77
|
+
end
|
78
|
+
|
79
|
+
def at(path) path.to_s.empty? ? root : namespace[path] end
|
80
|
+
alias_method :[], :at
|
81
|
+
|
82
|
+
def root; namespace[:root] end
|
83
|
+
def delete(object) namespace.delete(object.path) end
|
84
|
+
|
85
|
+
def clear
|
86
|
+
@namespace = SymbolHash.new
|
87
|
+
@namespace[:root] = CodeObjects::RootObject.new(nil, :root)
|
88
|
+
@proxy_types = {}
|
89
|
+
end
|
90
|
+
|
91
|
+
def initialize
|
92
|
+
@yardoc_file = DEFAULT_YARDOC_FILE
|
93
|
+
clear
|
94
|
+
end
|
95
|
+
|
96
|
+
def register(object)
|
97
|
+
return if object.is_a?(CodeObjects::Proxy)
|
98
|
+
namespace[object.path] = object
|
99
|
+
end
|
100
|
+
|
101
|
+
def resolve(namespace, name, proxy_fallback = false)
|
102
|
+
namespace = root if namespace == :root || !namespace
|
103
|
+
|
104
|
+
newname = name.to_s.gsub(/^#{CodeObjects::ISEP}/, '')
|
105
|
+
if name =~ /^#{CodeObjects::NSEP}/
|
106
|
+
[name, newname[2..-1]].each do |n|
|
107
|
+
return at(n) if at(n)
|
108
|
+
end
|
109
|
+
else
|
110
|
+
while namespace
|
111
|
+
[CodeObjects::NSEP, CodeObjects::ISEP].each do |s|
|
112
|
+
path = newname
|
113
|
+
if namespace != root
|
114
|
+
path = [namespace.path, newname].join(s)
|
115
|
+
end
|
116
|
+
found = at(path)
|
117
|
+
return found if found
|
118
|
+
end
|
119
|
+
namespace = namespace.parent
|
120
|
+
end
|
121
|
+
|
122
|
+
# Look for ::name or #name in the root space
|
123
|
+
[CodeObjects::NSEP, CodeObjects::ISEP].each do |s|
|
124
|
+
found = at(s + newname)
|
125
|
+
return found if found
|
126
|
+
end
|
127
|
+
end
|
128
|
+
proxy_fallback ? CodeObjects::Proxy.new(namespace, name) : nil
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
attr_accessor :namespace
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|