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,16 @@
|
|
1
|
+
module YARD
|
2
|
+
module Serializers
|
3
|
+
class Base
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
def initialize(opts = {})
|
7
|
+
@options = SymbolHash.new(false).update(opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def before_serialize; end
|
11
|
+
def serialize(object, data) end
|
12
|
+
def after_serialize(data); end
|
13
|
+
def serialized_path(object) end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module YARD
|
4
|
+
module Serializers
|
5
|
+
class FileSystemSerializer < Base
|
6
|
+
attr_reader :basepath, :extension
|
7
|
+
|
8
|
+
def initialize(opts = {})
|
9
|
+
super
|
10
|
+
@basepath = (options[:basepath] || 'doc').to_s
|
11
|
+
@extension = (options.has_key?(:extension) ? options[:extension] : 'html').to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialize(object, data)
|
15
|
+
path = File.join(basepath, *serialized_path(object))
|
16
|
+
FileUtils.mkdir_p File.dirname(path)
|
17
|
+
log.debug "Serializing to #{path}"
|
18
|
+
File.open(path, "w") {|f| f.write data }
|
19
|
+
end
|
20
|
+
|
21
|
+
def serialized_path(object)
|
22
|
+
return object if object.is_a?(String)
|
23
|
+
|
24
|
+
objname = object.name.to_s
|
25
|
+
objname += '_' + object.scope.to_s[0,1] if object.is_a?(CodeObjects::MethodObject)
|
26
|
+
fspath = [objname + (extension.empty? ? '' : ".#{extension}")]
|
27
|
+
if object.namespace && object.namespace.path != ""
|
28
|
+
fspath.unshift *object.namespace.path.split(CodeObjects::NSEP)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Don't change the filenames, it just makes it more complicated
|
32
|
+
# to figure out the original name.
|
33
|
+
#fspath.map! do |p|
|
34
|
+
# p.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
|
35
|
+
#end
|
36
|
+
|
37
|
+
# Remove special chars from filenames.
|
38
|
+
# Windows disallows \ / : * ? " < > | but we will just remove any
|
39
|
+
# non alphanumeric (plus period, underscore and dash).
|
40
|
+
fspath.map! do |p|
|
41
|
+
p.gsub(/[^\w\.-]/) {|x| '_' + x[0].to_s(16).upcase }
|
42
|
+
end
|
43
|
+
|
44
|
+
File.join(fspath)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module YARD
|
2
|
+
module Serializers
|
3
|
+
class StdoutSerializer < Base
|
4
|
+
def initialize(wrap = nil)
|
5
|
+
@wrap = wrap
|
6
|
+
end
|
7
|
+
|
8
|
+
def serialize(object, data)
|
9
|
+
print(@wrap ? word_wrap(data, @wrap) : data)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def word_wrap(text, length = 80)
|
15
|
+
# See ruby-talk/10655 / Ernest Ellingson
|
16
|
+
text.gsub(/\t/," ").gsub(/.{1,50}(?:\s|\Z)/){($& +
|
17
|
+
5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module YARD
|
2
|
+
module Tags
|
3
|
+
class DefaultFactory
|
4
|
+
##
|
5
|
+
# Parses tag text and creates a new tag with descriptive text
|
6
|
+
#
|
7
|
+
# @param tag_name the name of the tag to parse
|
8
|
+
# @param [String] text the raw tag text
|
9
|
+
# @return [Tag] a tag object with the tag_name and text values filled
|
10
|
+
def parse_tag(tag_name, text)
|
11
|
+
Tag.new(tag_name, text)
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Parses tag text and creates a new tag with a key name and descriptive text
|
16
|
+
#
|
17
|
+
# @param tag_name the name of the tag to parse
|
18
|
+
# @param [String] text the raw tag text
|
19
|
+
# @return [Tag] a tag object with the tag_name, name and text values filled
|
20
|
+
def parse_tag_with_name(tag_name, text)
|
21
|
+
name, text = *extract_name_from_text(text)
|
22
|
+
Tag.new(tag_name, text, nil, name)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Parses tag text and creates a new tag with formally declared types and
|
27
|
+
# descriptive text
|
28
|
+
#
|
29
|
+
# @param tag_name the name of the tag to parse
|
30
|
+
# @param [String] text the raw tag text
|
31
|
+
# @return [Tag] a tag object with the tag_name, types and text values filled
|
32
|
+
def parse_tag_with_types(tag_name, text)
|
33
|
+
types, text = *extract_types_from_text(text)
|
34
|
+
Tag.new(tag_name, text, types)
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Parses tag text and creates a new tag with formally declared types, a key
|
39
|
+
# name and descriptive text
|
40
|
+
#
|
41
|
+
# @param tag_name the name of the tag to parse
|
42
|
+
# @param [String] text the raw tag text
|
43
|
+
# @return [Tag] a tag object with the tag_name, name, types and text values filled
|
44
|
+
def parse_tag_with_types_and_name(tag_name, text)
|
45
|
+
types, text = *extract_types_from_text(text)
|
46
|
+
name, text = *extract_name_from_text(text)
|
47
|
+
Tag.new(tag_name, text, types, name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_tag_with_raw_text(tag_name, text, raw_text)
|
51
|
+
Tag.new(tag_name, raw_text)
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_tag_with_raw_title_and_text(tag_name, text, raw_text)
|
55
|
+
title, desc = *extract_title_and_desc_from_raw_text(raw_text)
|
56
|
+
Tag.new(tag_name, desc, nil, title)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
##
|
62
|
+
# Extracts the name from raw tag text returning the name and remaining value
|
63
|
+
#
|
64
|
+
# @param [String] text the raw tag text
|
65
|
+
# @return [Array] an array holding the name as the first element and the
|
66
|
+
# value as the second element
|
67
|
+
def extract_name_from_text(text)
|
68
|
+
text.strip.split(" ", 2)
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Extracts the type signatures from the raw tag text
|
73
|
+
#
|
74
|
+
# @param [String] text the raw tag text
|
75
|
+
# @return [Array] an array holding the value as the first element and
|
76
|
+
# the array of types as the second element
|
77
|
+
def extract_types_from_text(text)
|
78
|
+
types, text = [], text.strip
|
79
|
+
if text =~ /^\s*\[(.+?)\]\s*(.*)/
|
80
|
+
text, types = $2, $1.split(",").collect {|e| e.strip }
|
81
|
+
end
|
82
|
+
[types, text]
|
83
|
+
end
|
84
|
+
|
85
|
+
def extract_title_and_desc_from_raw_text(raw_text)
|
86
|
+
title, desc = nil, nil
|
87
|
+
if raw_text =~ /\A[ \t]\n/
|
88
|
+
desc = raw_text
|
89
|
+
else
|
90
|
+
raw_text = raw_text.split(/\r?\n/)
|
91
|
+
title = raw_text.shift.squeeze(' ').strip
|
92
|
+
desc = raw_text.join("\n")
|
93
|
+
end
|
94
|
+
[title, desc]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module YARD
|
2
|
+
module Tags
|
3
|
+
##
|
4
|
+
# Holds all the registered meta tags. If you want to extend YARD and add
|
5
|
+
# a new meta tag, you can do it in one of two ways.
|
6
|
+
#
|
7
|
+
# == Method #1
|
8
|
+
# Write your own +tagname_tag+ method that takes the raw text as a parameter.
|
9
|
+
# Example:
|
10
|
+
# def mytag_tag(text)
|
11
|
+
# Tag.parse_tag("mytag", text)
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# This will allow you to use @mytag TEXT to add meta data to classes through
|
15
|
+
# the docstring. {Tag} has a few convenience factory methods to create
|
16
|
+
#
|
17
|
+
# == Method #2
|
18
|
+
# Use {Library::define_tag!} to define a new tag by passing the tag name
|
19
|
+
# and the factory method to use when creating the tag. These definitions will
|
20
|
+
# be auto expanded into ruby code similar to what is shown in method #1. If you
|
21
|
+
# do not provide a factory method to use, it will default to {Tag::parse_tag}
|
22
|
+
# Example:
|
23
|
+
# define_tag :param, :with_types_and_name
|
24
|
+
# define_tag :author
|
25
|
+
#
|
26
|
+
# The first line will expand to the code:
|
27
|
+
# def param_tag(text) Tag.parse_tag_with_types_and_name(text) end
|
28
|
+
#
|
29
|
+
# The second line will expand to:
|
30
|
+
# def author_tag(text) Tag.parse_tag(text) end
|
31
|
+
#
|
32
|
+
# @see Library::define_tag
|
33
|
+
class Library
|
34
|
+
class << self
|
35
|
+
attr_reader :labels
|
36
|
+
attr_accessor :default_factory
|
37
|
+
|
38
|
+
def default_factory
|
39
|
+
@default_factory ||= DefaultFactory.new
|
40
|
+
end
|
41
|
+
|
42
|
+
def default_factory=(factory)
|
43
|
+
@default_factory = factory.is_a?(Class) ? factory.new : factory
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Sorts the labels lexically by their label name, often used when displaying
|
48
|
+
# the tags.
|
49
|
+
#
|
50
|
+
# @return [Array<Symbol>, String] the sorted labels as an array of the tag name and label
|
51
|
+
def sorted_labels
|
52
|
+
labels.sort_by {|a| a.last.downcase }
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Convenience method to define a new tag using one of {Tag}'s factory methods, or the
|
57
|
+
# regular {Tag::parse_tag} factory method if none is supplied.
|
58
|
+
#
|
59
|
+
# @param [#to_s] tag the tag name to create
|
60
|
+
# @param meth the {Tag} factory method to call when creating the tag
|
61
|
+
def define_tag(label, tag, meth = "")
|
62
|
+
class_eval <<-eof, __FILE__, __LINE__
|
63
|
+
def #{tag}_tag(text, raw_text)
|
64
|
+
send_to_factory(#{tag.inspect}, #{meth.inspect}, text, raw_text)
|
65
|
+
end
|
66
|
+
eof
|
67
|
+
|
68
|
+
@labels ||= SymbolHash.new(false)
|
69
|
+
@labels.update(tag => label)
|
70
|
+
tag
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def send_to_factory(tag_name, meth, text, raw_text)
|
77
|
+
meth = meth.to_s
|
78
|
+
send_name = "parse_tag" + (meth.empty? ? "" : "_" + meth)
|
79
|
+
if @factory.respond_to?(send_name)
|
80
|
+
arity = @factory.method(send_name).arity
|
81
|
+
@factory.send send_name, tag_name, text, *(arity == 3 ? [raw_text] : [])
|
82
|
+
else
|
83
|
+
raise NoMethodError, "Factory #{@factory.class_name} does not implement factory method :#{meth}."
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
public
|
88
|
+
|
89
|
+
def initialize(factory = Library.default_factory)
|
90
|
+
@factory = factory
|
91
|
+
end
|
92
|
+
|
93
|
+
define_tag "Parameters", :param, :with_types_and_name
|
94
|
+
define_tag "Yield Parameters", :yieldparam, :with_types_and_name
|
95
|
+
define_tag "Yields", :yield, :with_types
|
96
|
+
define_tag "Default Value", :default, :with_name
|
97
|
+
define_tag "Returns", :return, :with_types
|
98
|
+
define_tag "Deprecated", :deprecated
|
99
|
+
define_tag "Author", :author
|
100
|
+
define_tag "Raises", :raise, :with_types
|
101
|
+
define_tag "See Also", :see
|
102
|
+
define_tag "Since", :since
|
103
|
+
define_tag "Version", :version
|
104
|
+
define_tag "API Visibility", :api
|
105
|
+
define_tag "Todo Item", :todo
|
106
|
+
define_tag "Example", :example, :with_raw_title_and_text
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module YARD
|
2
|
+
module Tags
|
3
|
+
class MerbdocFactory < DefaultFactory
|
4
|
+
##
|
5
|
+
# Parses tag text and creates a new tag with formally declared types and
|
6
|
+
# descriptive text
|
7
|
+
#
|
8
|
+
# @param tag_name the name of the tag to parse
|
9
|
+
# @param text<String> the raw tag text
|
10
|
+
# @return <Tag> a tag object with the tag_name, types and text values filled
|
11
|
+
def parse_tag_with_types(tag_name, text)
|
12
|
+
_, types, text = *extract_types_from_text(text)
|
13
|
+
# TODO warn if name value ('_') is not nil, because that's invalid syntax
|
14
|
+
Tag.new(tag_name, text, types)
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Parses tag text and creates a new tag with formally declared types, a key
|
19
|
+
# name and descriptive text
|
20
|
+
#
|
21
|
+
# @param tag_name the name of the tag to parse
|
22
|
+
# @param text<String> the raw tag text
|
23
|
+
# @return <Tag> a tag object with the tag_name, name, types and text values filled
|
24
|
+
def parse_tag_with_types_and_name(tag_name, text)
|
25
|
+
name, types, text = *extract_types_from_text(text)
|
26
|
+
name, text = *extract_name_from_text(text) if name.nil?
|
27
|
+
Tag.new(tag_name, text, types, name)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
##
|
33
|
+
# Extracts the type signatures with an optional name from the raw tag text
|
34
|
+
#
|
35
|
+
# @param text<String> the raw tag text
|
36
|
+
# @return <Array> an array holding the name as the first element (nil if empty),
|
37
|
+
# array of types as the second element and the raw text as the last.
|
38
|
+
def extract_types_from_text(text)
|
39
|
+
name, types, text = nil, [], text.strip
|
40
|
+
if text =~ /^\s*(\S*)\s*<(.+?)>\s*(.*)/
|
41
|
+
name, text, types = $1, $3, $2.split(",").collect {|e| e.strip }
|
42
|
+
end
|
43
|
+
[name, types, text]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module YARD
|
2
|
+
module Tags
|
3
|
+
class Tag
|
4
|
+
attr_reader :tag_name, :text, :types, :name
|
5
|
+
|
6
|
+
##
|
7
|
+
# Creates a new tag object with a tag name and text. Optionally, formally declared types
|
8
|
+
# and a key name can be specified.
|
9
|
+
#
|
10
|
+
# Types are mainly for meta tags that rely on type information, such as +param+, +return+, etc.
|
11
|
+
#
|
12
|
+
# Key names are for tags that declare meta data for a specific key or name, such as +param+,
|
13
|
+
# +raise+, etc.
|
14
|
+
#
|
15
|
+
# @param tag_name the tag name to create the tag for
|
16
|
+
# @param [String] text the descriptive text for this tag
|
17
|
+
# @param [Array<String>] types optional type list of formally declared types
|
18
|
+
# for the tag
|
19
|
+
# @param [String] name optional key name which the tag refers to
|
20
|
+
def initialize(tag_name, text, types = nil, name = nil)
|
21
|
+
@tag_name, @text, @name, @types = tag_name.to_s, text, name, (types ? [types].flatten.compact : nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Convenience method to access the first type specified. This should mainly
|
26
|
+
# be used for tags that only specify one type.
|
27
|
+
#
|
28
|
+
# @return [String] the first of the list of specified types
|
29
|
+
# @see #types
|
30
|
+
def type
|
31
|
+
types.first
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe YARD::CodeObjects::Base do
|
4
|
+
before { Registry.clear }
|
5
|
+
|
6
|
+
it "should return a unique instance of any registered object" do
|
7
|
+
obj = ClassObject.new(:root, :Me)
|
8
|
+
obj2 = ModuleObject.new(:root, :Me)
|
9
|
+
obj.object_id.should == obj2.object_id
|
10
|
+
|
11
|
+
obj3 = ModuleObject.new(obj, :Too)
|
12
|
+
obj4 = CodeObjects::Base.new(obj3, :Hello)
|
13
|
+
obj4.parent = obj
|
14
|
+
|
15
|
+
obj5 = CodeObjects::Base.new(obj3, :hello)
|
16
|
+
obj4.object_id.should_not == obj5.object_id
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should recall the block if #new is called on an existing object" do
|
20
|
+
o1 = ClassObject.new(:root, :Me) do |o|
|
21
|
+
o.docstring = "DOCSTRING"
|
22
|
+
end
|
23
|
+
|
24
|
+
o2 = ClassObject.new(:root, :Me) do |o|
|
25
|
+
o.docstring = "NOT_DOCSTRING"
|
26
|
+
end
|
27
|
+
|
28
|
+
o1.object_id.should == o2.object_id
|
29
|
+
o1.docstring.should == "NOT_DOCSTRING"
|
30
|
+
o2.docstring.should == "NOT_DOCSTRING"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should handle empty docstrings with #short_docstring" do
|
34
|
+
o1 = ClassObject.new(nil, :Me)
|
35
|
+
o1.short_docstring.should == ""
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return the first sentence with #short_docstring" do
|
39
|
+
o = ClassObject.new(nil, :Me)
|
40
|
+
o.docstring = "DOCSTRING. Another sentence"
|
41
|
+
o.short_docstring.should == "DOCSTRING."
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return the first paragraph with #short_docstring" do
|
45
|
+
o = ClassObject.new(nil, :Me)
|
46
|
+
o.docstring = "DOCSTRING, and other stuff\n\nAnother sentence."
|
47
|
+
o.short_docstring.should == "DOCSTRING, and other stuff."
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return proper short_docstring when docstring is changed" do
|
51
|
+
o = ClassObject.new(:root, :Me)
|
52
|
+
o.docstring = "DOCSTRING, and other stuff\n\nAnother sentence."
|
53
|
+
o.short_docstring.should == "DOCSTRING, and other stuff."
|
54
|
+
o.docstring = "DOCSTRING."
|
55
|
+
o.short_docstring.should == "DOCSTRING."
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should not double the ending period in short_docstring" do
|
59
|
+
o = ClassObject.new(nil, :Me)
|
60
|
+
o.docstring = "Returns a list of tags specified by +name+ or all tags if +name+ is not specified.\n\nTest"
|
61
|
+
o.short_docstring.should == "Returns a list of tags specified by +name+ or all tags if +name+ is not specified."
|
62
|
+
|
63
|
+
Parser::SourceParser.parse_string <<-eof
|
64
|
+
##
|
65
|
+
# Returns a list of tags specified by +name+ or all tags if +name+ is not specified.
|
66
|
+
#
|
67
|
+
# @param name the tag name to return data for, or nil for all tags
|
68
|
+
# @return [Array<Tags::Tag>] the list of tags by the specified tag name
|
69
|
+
def tags(name = nil)
|
70
|
+
return @tags if name.nil?
|
71
|
+
@tags.select {|tag| tag.tag_name.to_s == name.to_s }
|
72
|
+
end
|
73
|
+
eof
|
74
|
+
P('#tags').short_docstring.should == "Returns a list of tags specified by +name+ or all tags if +name+ is not specified."
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should allow complex name and convert that to namespace" do
|
78
|
+
obj = CodeObjects::Base.new(nil, "A::B")
|
79
|
+
obj.namespace.path.should == "A"
|
80
|
+
obj.name.should == :B
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should allow namespace to be nil and not register in the Registry" do
|
84
|
+
obj = CodeObjects::Base.new(nil, :Me)
|
85
|
+
obj.namespace.should == nil
|
86
|
+
Registry.at(:Me).should == nil
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should allow namespace to be a NamespaceObject" do
|
90
|
+
ns = ModuleObject.new(:root, :Name)
|
91
|
+
obj = CodeObjects::Base.new(ns, :Me)
|
92
|
+
obj.namespace.should == ns
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should allow :root to be the shorthand namespace of `Registry.root`" do
|
96
|
+
obj = CodeObjects::Base.new(:root, :Me)
|
97
|
+
obj.namespace.should == Registry.root
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
it "should not allow any other types as namespace" do
|
102
|
+
lambda { CodeObjects::Base.new("ROOT!", :Me) }.should raise_error(ArgumentError)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should register itself in the registry if namespace is supplied" do
|
106
|
+
obj = ModuleObject.new(:root, :Me)
|
107
|
+
Registry.at(:Me).should == obj
|
108
|
+
|
109
|
+
obj2 = ModuleObject.new(obj, :Too)
|
110
|
+
Registry.at(:"Me::Too").should == obj2
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should set any attribute using #[]=" do
|
114
|
+
obj = ModuleObject.new(:root, :YARD)
|
115
|
+
obj[:some_attr] = "hello"
|
116
|
+
obj[:some_attr].should == "hello"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "#[]= should use the accessor method if available" do
|
120
|
+
obj = CodeObjects::Base.new(:root, :YARD)
|
121
|
+
obj[:source] = "hello"
|
122
|
+
obj.source.should == "hello"
|
123
|
+
obj.source = "unhello"
|
124
|
+
obj[:source].should == "unhello"
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should set attributes via attr= through method_missing" do
|
128
|
+
obj = CodeObjects::Base.new(:root, :YARD)
|
129
|
+
obj.something = 2
|
130
|
+
obj.something.should == 2
|
131
|
+
obj[:something].should == 2
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should exist in the parent's #children after creation" do
|
135
|
+
obj = ModuleObject.new(:root, :YARD)
|
136
|
+
obj2 = MethodObject.new(obj, :testing)
|
137
|
+
obj.children.should include(obj2)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should parse comments into tags" do
|
141
|
+
obj = CodeObjects::Base.new(nil, :Object)
|
142
|
+
comments = <<-eof
|
143
|
+
@param name Hello world
|
144
|
+
how are you?
|
145
|
+
@param name2
|
146
|
+
this is a new line
|
147
|
+
@param name3 and this
|
148
|
+
is a new paragraph:
|
149
|
+
|
150
|
+
right here.
|
151
|
+
eof
|
152
|
+
obj.send(:parse_comments, comments)
|
153
|
+
obj.tags("param").each do |tag|
|
154
|
+
if tag.name == "name"
|
155
|
+
tag.text.should == "Hello world how are you?"
|
156
|
+
elsif tag.name == "name2"
|
157
|
+
tag.text.should == "this is a new line"
|
158
|
+
elsif tag.name == "name3"
|
159
|
+
tag.text.should == "and this is a new paragraph:\n\nright here."
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should properly re-indent source starting from 0 indentation" do
|
165
|
+
obj = CodeObjects::Base.new(nil, :test)
|
166
|
+
obj.source = <<-eof
|
167
|
+
def mymethod
|
168
|
+
if x == 2 &&
|
169
|
+
5 == 5
|
170
|
+
3
|
171
|
+
else
|
172
|
+
1
|
173
|
+
end
|
174
|
+
end
|
175
|
+
eof
|
176
|
+
obj.source.should == "def mymethod\n if x == 2 &&\n 5 == 5\n 3 \n else\n 1\n end\nend"
|
177
|
+
|
178
|
+
Registry.clear
|
179
|
+
Parser::SourceParser.parse_string <<-eof
|
180
|
+
def key?(key)
|
181
|
+
super(key)
|
182
|
+
end
|
183
|
+
eof
|
184
|
+
Registry.at('#key?').source.should == "def key?(key)\n super(key)\nend"
|
185
|
+
|
186
|
+
Registry.clear
|
187
|
+
Parser::SourceParser.parse_string <<-eof
|
188
|
+
def key?(key)
|
189
|
+
if x == 2
|
190
|
+
puts key
|
191
|
+
else
|
192
|
+
exit
|
193
|
+
end
|
194
|
+
end
|
195
|
+
eof
|
196
|
+
Registry.at('#key?').source.should == "def key?(key)\n if x == 2\n puts key\n else\n exit\n end\nend"
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should not add newlines to source when parsing sub blocks" do
|
200
|
+
Parser::SourceParser.parse_string <<-eof
|
201
|
+
module XYZ
|
202
|
+
module ZYX
|
203
|
+
class ABC
|
204
|
+
def msg
|
205
|
+
hello_world
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
eof
|
211
|
+
Registry.at('XYZ::ZYX::ABC#msg').source.should == "def msg\n hello_world\nend"
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should handle source for 'def x; end'" do
|
215
|
+
Registry.clear
|
216
|
+
Parser::SourceParser.parse_string "def x; 2 end"
|
217
|
+
Registry.at('#x').source.should == "def x; 2 end"
|
218
|
+
end
|
219
|
+
end
|