yard-go 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +5 -0
  4. data/lib/yard-go.rb +14 -0
  5. data/lib/yard-go/code_objects.rb +86 -0
  6. data/lib/yard-go/extensions.rb +64 -0
  7. data/lib/yard-go/handlers.rb +186 -0
  8. data/lib/yard-go/helpers.rb +94 -0
  9. data/lib/yard-go/parser.rb +194 -0
  10. data/lib/yard-go/version.rb +3 -0
  11. data/templates/default/bare_struct/html/fields.erb +15 -0
  12. data/templates/default/bare_struct/html/inherited_fields.erb +15 -0
  13. data/templates/default/bare_struct/html/method_signature.erb +18 -0
  14. data/templates/default/bare_struct/html/setup.rb +11 -0
  15. data/templates/default/field/html/method_signature.erb +4 -0
  16. data/templates/default/field/html/setup.rb +1 -0
  17. data/templates/default/fulldoc/html/css/common.css +33 -0
  18. data/templates/default/fulldoc/html/css/highlight.github.css +123 -0
  19. data/templates/default/fulldoc/html/full_list_package.erb +2 -0
  20. data/templates/default/fulldoc/html/setup.rb +10 -0
  21. data/templates/default/interface/html/implemented_by.erb +5 -0
  22. data/templates/default/interface/html/setup.rb +6 -0
  23. data/templates/default/layout/html/layout.erb +29 -0
  24. data/templates/default/layout/html/setup.rb +33 -0
  25. data/templates/default/method_details/html/source.erb +10 -0
  26. data/templates/default/module/html/box_info.erb +3 -0
  27. data/templates/default/module/html/constant_summary.erb +22 -0
  28. data/templates/default/module/html/inherited_methods.erb +18 -0
  29. data/templates/default/module/html/item_summary.erb +23 -0
  30. data/templates/default/module/html/method_details_list.erb +9 -0
  31. data/templates/default/module/html/packages.erb +4 -0
  32. data/templates/default/module/html/setup.rb +33 -0
  33. data/templates/default/package/html/list_summary.erb +12 -0
  34. data/templates/default/package/html/setup.rb +22 -0
  35. data/templates/default/package/html/type_details.erb +9 -0
  36. data/templates/default/struct/html/fields_details.erb +9 -0
  37. data/templates/default/struct/html/fields_summary.erb +12 -0
  38. data/templates/default/struct/html/implemented_interfaces.erb +5 -0
  39. data/templates/default/struct/html/inherited_fields.erb +15 -0
  40. data/templates/default/struct/html/setup.rb +9 -0
  41. data/yard-go.gemspec +15 -0
  42. metadata +83 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ad1b6df43092cbf0ade8457bc09cd7eaa0c4a9ee
4
+ data.tar.gz: e15019dbc2d1bee24731016ec03f3606f48e7c97
5
+ SHA512:
6
+ metadata.gz: 27ce96455c464b3bf3867bcf79bc9db023669799920e0824915050a7dd2b0421190e1e9fed322948de7689d088d79d7e6a1186535a869dd72abe43e5b3b13837
7
+ data.tar.gz: f382bdeb474bc40b1f65c8eafa50f1763704c97466e18a32db84187627ea42c4430b417edd364a76e77b17df8c8f0a2a70b2f9469bbed97715e812a1128d542e
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Loren Segal
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,5 @@
1
+ # YARD for Go
2
+
3
+ A [YARD][yard] plugin that adds support for documenting Go source programs.
4
+
5
+ [yard]: http://yardoc.org
@@ -0,0 +1,14 @@
1
+ require 'yard'
2
+
3
+ require_relative './yard-go/code_objects'
4
+ require_relative './yard-go/extensions'
5
+ require_relative './yard-go/handlers'
6
+ require_relative './yard-go/helpers'
7
+ require_relative './yard-go/parser'
8
+ require_relative './yard-go/version'
9
+
10
+ YARD::Templates::Engine.register_template_path(File.dirname(__FILE__) + '/../templates')
11
+ YARD::Parser::SourceParser.register_parser_type(:go, YARDGo::Parser::Go, 'go')
12
+ YARD::Handlers::Processor.register_handler_namespace(:go, YARDGo::Handlers)
13
+ YARD::Tags::Library.visible_tags -= [:return]
14
+ YARD::Tags::Library.define_tag "Read-only", :readonly
@@ -0,0 +1,86 @@
1
+ module YARDGo
2
+ module CodeObjects
3
+ class PackageObject < YARD::CodeObjects::NamespaceObject
4
+ def sep; '/' end
5
+ def type; :package end
6
+ def source_type; :go end
7
+ def title; name.to_s end
8
+
9
+ def full_path
10
+ File.join(parent.full_path, name.to_s)
11
+ end
12
+
13
+ def inheritance_tree(*args) [self] end
14
+ end
15
+
16
+ class StructObject < YARD::CodeObjects::NamespaceObject
17
+ def sep; '.' end
18
+ def type; :struct end
19
+ def scope; :instance end
20
+ def title; namespace.title + "." + name.to_s end
21
+ def source_type; :go end
22
+
23
+ def inheritance_tree(include_mods = false)
24
+ list = (include_mods ? mixins(:instance) : [])
25
+ [self] + list.map do |m|
26
+ next m if m == self
27
+ next m unless m.respond_to?(:inheritance_tree)
28
+ m.inheritance_tree(include_mods)
29
+ end.flatten.uniq
30
+ end
31
+
32
+ def implemented_interfaces
33
+ YARD::Registry.all(:interface).select {|i| implements?(i) }
34
+ end
35
+
36
+ def implements?(interface)
37
+ interface.implemented_by?(self)
38
+ end
39
+ end
40
+
41
+ class BareStructObject < StructObject
42
+ def sep; '.' end
43
+ def type; :bare_struct end
44
+ def source_type; :go end
45
+ end
46
+
47
+ class FuncObject < YARD::CodeObjects::MethodObject
48
+ def sep; '.' end
49
+ def name(str = false) str ? super(false).to_s : super(false) end
50
+ def type; :method end
51
+ def title; parent.title + "." + name.to_s + "()" end
52
+ def scope_name; has_tag?(:abstract) ? "Interface Method" : (scope == :class ? "Function" : "Method") end
53
+ def source_type; :go end
54
+ end
55
+
56
+ class FieldObject < YARD::CodeObjects::Base
57
+ def sep; '::' end
58
+ def type; :field end
59
+ def title; namespace.title + "." + name.to_s end
60
+ def source_type; :go end
61
+
62
+ attr_accessor :field_type, :go_tags
63
+ end
64
+
65
+ class InterfaceObject < StructObject
66
+ def sep; '.' end
67
+ def type; :interface end
68
+ def source_type; :go end
69
+
70
+ def implemented_by?(struct)
71
+ m = struct.children.select {|t| t.type == :method && t.scope == :instance }.map(&:name)
72
+ children.select {|t| t.type == :method && t.scope == :instance }.all? {|t| m.include?(t.name) }
73
+ end
74
+
75
+ def implementing_structs
76
+ YARD::Registry.all(:struct).select {|s| implemented_by?(s) }
77
+ end
78
+ end
79
+
80
+ class ConstantObject < YARD::CodeObjects::ConstantObject
81
+ def sep; '.' end
82
+ def type; :constant end
83
+ def source_type; :go end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,64 @@
1
+ require 'strscan'
2
+
3
+ class YARD::CodeObjects::RootObject
4
+ def full_path
5
+ File.relative_path(ENV["GOPATH"] + "/src", Dir.pwd)
6
+ end
7
+ end
8
+
9
+ class YARD::CLI::Yardoc
10
+ def all_objects
11
+ YARD::Registry.all(:root, :package, :struct, :interface)
12
+ end
13
+ end
14
+
15
+ class YARD::CLI::Stats
16
+ undef stats_for_modules
17
+ undef stats_for_classes
18
+
19
+ def stats_for_packages
20
+ output "Packages", *type_statistics(:package)
21
+ end
22
+
23
+ def stats_for_structs
24
+ struct_stats = type_statistics(:struct)
25
+ bstruct_stats = type_statistics(:bare_struct)
26
+ stats = struct_stats.zip(bstruct_stats).map {|o| o.reduce(:+) }
27
+ output "Structs", *stats
28
+ end
29
+
30
+ def stats_for_interfaces
31
+ output "Interfaces", *type_statistics(:interface)
32
+ end
33
+
34
+ def stats_for_fields
35
+ output "Fields", *type_statistics(:field)
36
+ end
37
+ end
38
+
39
+ module YARD::Templates::Helpers::HtmlSyntaxHighlightHelper
40
+ MATCHES = {
41
+ "hljs-keyword" => %r{\b(?:break|default|func|interface|select|case|defer|go|map|struct|chan|else|goto|package|switch|const|fallthrough|if|range|type|continue|for|import|return|var)\b},
42
+ "hljs-constant" => %r{\b(nil|false|true|error|string|int64|int|int32|float|float32|float64|bool)\b},
43
+ "hljs-string" => %r{"(?:[^\\"]|\\.)*"|`.+?`},
44
+ "hljs-comment" => %r{\/\/.+},
45
+ }
46
+
47
+ def html_syntax_highlight_go(source)
48
+ s = StringScanner.new(source, true)
49
+
50
+ highlighted = ""
51
+ until s.eos?
52
+ found = false
53
+ MATCHES.each do |klass, re|
54
+ if s.scan(re)
55
+ found = true
56
+ highlighted << "<span class=\"#{klass}\">#{s[0]}</span>"
57
+ end
58
+ end
59
+ highlighted << s.getch unless found
60
+ end
61
+
62
+ '<div class="hljs">' + highlighted + '</div>'
63
+ end
64
+ end
@@ -0,0 +1,186 @@
1
+ module YARDGo
2
+ module Handlers
3
+ class Base < YARD::Handlers::Base
4
+ include YARDGo::CodeObjects
5
+
6
+ def self.handles?(node)
7
+ handlers.any? do |h|
8
+ (node.name.nil? || node.name[0] == node.name[0].upcase) &&
9
+ node.type == h
10
+ end
11
+ end
12
+
13
+ def parse_block(inner_node, opts = {})
14
+ push_state(opts) { parser.process([inner_node].flatten) }
15
+ end
16
+
17
+ def call_params; [] end
18
+ def caller_method; nil end
19
+
20
+ def pkg
21
+ return @pkg if @pkg
22
+ pkg = :root
23
+ path = File.dirname(File.relative_path(Dir.pwd, parser.file))
24
+ parts = path.split('/')
25
+ while parts.size > 0
26
+ pkg = PackageObject.new(pkg, parts.shift)
27
+ pkg.add_file(path) unless pkg.file
28
+ end
29
+
30
+ @pkg = pkg
31
+ end
32
+
33
+ def test_file?
34
+ parser.file =~ /_test\.go$/
35
+ end
36
+ end
37
+
38
+ class StructHandler < Base
39
+ handles :struct
40
+
41
+ process do
42
+ return if test_file?
43
+
44
+ ns = if regular_meths.size > 0 # it's a "class"
45
+ register StructObject.new(pkg, statement.name)
46
+ else # bare struct
47
+ register BareStructObject.new(pkg, statement.name)
48
+ end
49
+
50
+ parse_block(statement.meths, namespace: ns)
51
+ parse_block(statement.fields, namespace: ns)
52
+ end
53
+
54
+ def regular_meths
55
+ statement.meths.reject {|s| s.name =~ /^(Go)?String$/ }
56
+ end
57
+ end
58
+
59
+ class InterfaceHandler < Base
60
+ handles :interface
61
+
62
+ process do
63
+ return if test_file?
64
+
65
+ obj = register InterfaceObject.new(pkg, statement.name)
66
+ parse_block(statement.fields, namespace: obj)
67
+ end
68
+ end
69
+
70
+ class FunctionHandler < Base
71
+ handles :function
72
+ handles :method
73
+
74
+ process do
75
+ return parse_example if test_file?
76
+
77
+ scope = statement.type == :function ? :class : :instance
78
+ ns = statement.type == :function ? pkg : namespace
79
+ ctor_fn = false
80
+
81
+ if scope == :class && statement.ret =~ /^\s*\*([A-Z]\w*)\s*$/
82
+ ctor_fn = true
83
+ ns = StructObject.new(pkg, $1)
84
+ end
85
+
86
+ obj = register FuncObject.new(ns, statement.name, scope)
87
+ obj.signature = "func #{statement.name}#{statement.args}"
88
+ obj.parameters = statement.args.split(/,/).map{|a| [a, nil] }
89
+
90
+ if statement.ret && statement.ret.strip != ""
91
+ obj.add_tag YARD::Tags::Tag.new(:return, '', [statement.ret])
92
+ end
93
+
94
+ if ctor_fn
95
+ obj.group = "Constructor Functions"
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ def parse_example
102
+ return unless statement.name =~ /^Example(.+)/
103
+ parts = $1.split("_")
104
+
105
+ ns = pkg
106
+ if parts.size > 1
107
+ ns = P(pkg, parts.first)
108
+ ensure_loaded! ns
109
+ end
110
+
111
+ meth = P(ns, "." + parts.last)
112
+ ensure_loaded! meth
113
+
114
+ src = statement.source.split("\n")[1...-1].map {|l| l.sub(/^\t/, "") }.join("\n").sub(/\n^\/\/ Output:.+\Z/m, "")
115
+ meth.add_tag YARD::Tags::Tag.new(:example, src, nil, "")
116
+ end
117
+ end
118
+
119
+ class FieldFnHandler < Base
120
+ handles :fieldfn
121
+
122
+ process do
123
+ return if test_file?
124
+
125
+ obj = register FuncObject.new(namespace, statement.name, :instance)
126
+ obj.signature = "func #{statement.name}(#{statement.args})"
127
+ obj.parameters = statement.args.split(/,/).map{|a| [a, nil] }
128
+ if statement.ret && statement.ret.strip != ""
129
+ obj.add_tag YARD::Tags::Tag.new(:return, '', [statement.ret])
130
+ end
131
+ obj.add_tag YARD::Tags::Tag.new(:abstract, '')
132
+ end
133
+
134
+ end
135
+
136
+ class FieldHandler < Base
137
+ handles :field
138
+
139
+ process do
140
+ return if test_file?
141
+
142
+ obj = register FieldObject.new(namespace, statement.name, :instance)
143
+ obj.add_tag YARD::Tags::Tag.new(:return, '', [statement.field_type])
144
+ obj.add_tag YARD::Tags::Tag.new(:gotags, statement.tags)
145
+ end
146
+ end
147
+
148
+ class PackageHandler < Base
149
+ handles :package
150
+
151
+ process do
152
+ return if test_file?
153
+ register_docstring pkg if statement.comments.size > 0
154
+ end
155
+ end
156
+
157
+ class ConstantHandler < Base
158
+ handles :const
159
+ handles :var
160
+
161
+ process do
162
+ return if test_file?
163
+
164
+ obj = register ConstantObject.new(pkg, statement.name)
165
+
166
+ lhs = statement.name
167
+ lhs += " " + statement.vartype if statement.vartype
168
+ obj.source = "#{statement.type} #{lhs} = #{statement.value}"
169
+ obj.value = statement.value
170
+ obj.add_tag YARD::Tags::Tag.new(:constant_type, statement.type.to_s)
171
+ obj.add_tag YARD::Tags::Tag.new(:return, '', [statement.vartype])
172
+ obj.add_tag YARD::Tags::Tag.new(:readonly, '') if statement.type == :const
173
+ end
174
+ end
175
+
176
+ class CompositionHandler < Base
177
+ handles :composition
178
+
179
+ process do
180
+ return if test_file?
181
+
182
+ namespace.mixins(:instance) << P(namespace, statement.path)
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,94 @@
1
+ module LinkHelpers
2
+ include YARDGo::CodeObjects
3
+
4
+ def link_object(obj, title = nil, anchor = nil, relative = true)
5
+ case obj
6
+ when BareStructObject
7
+ origobj = object
8
+ @object = object.namespace if BareStructObject === object
9
+ link = super(obj.namespace, title || obj.name, anchor_for(obj), true)
10
+ @object = origobj
11
+ link
12
+ else
13
+ super(obj, title, anchor, relative)
14
+ end
15
+ end
16
+
17
+ def anchor_for(obj)
18
+ case obj
19
+ when BareStructObject
20
+ "type-#{obj.name}"
21
+ else
22
+ super(obj)
23
+ end
24
+ end
25
+
26
+ def signature(obj, link = true, show_extras = true, full_attr_name = true)
27
+ case obj
28
+ when FieldObject
29
+ ret = obj.has_tag?(:return) ? obj.tag(:return).types.join(", ") : ""
30
+ if link
31
+ return linkify obj, "<strong>#{obj.name}</strong> #{ret}"
32
+ else
33
+ return "<strong>#{obj.name}</strong> #{link_types(ret)}"
34
+ end
35
+ when BareStructObject, StructObject, InterfaceObject
36
+ if link
37
+ return linkify obj, "<strong>#{obj.name}</strong>"
38
+ else
39
+ return "<strong>#{obj.name}</strong> struct"
40
+ end
41
+ when FuncObject
42
+ src = obj.source.split(/\n/).first.sub(/\{\s*$/, '').sub(/(<a\s[^>]+>|\b)#{obj.name.to_s}(<\/a>)?\(/, "<strong>#{obj.name}</strong>(")
43
+ src = link_types(src) unless link
44
+ src
45
+
46
+ if link
47
+ return linkify obj, src
48
+ else
49
+ return src
50
+ end
51
+ end
52
+
53
+ super(obj, link, show_extras, full_attr_name)
54
+ end
55
+
56
+ def signature_types(meth, link = true)
57
+ meth = convert_method_to_overload(meth)
58
+ if meth.respond_to?(:object) && !meth.has_tag?(:return)
59
+ meth = meth.object
60
+ end
61
+
62
+ val = ""
63
+ if meth.tag(:return) && meth.tag(:return).types
64
+ val = meth.tag(:return).types.join(", ")
65
+ end
66
+
67
+ link ? link_types(val) : val
68
+ end
69
+
70
+ def link_types(text)
71
+ text.gsub(/\b(?:[a-z]\w*\.)?[A-Z]\w*:?/) do |m|
72
+ if m[-1] == ":"
73
+ m
74
+ else
75
+ link_object YARD::Registry.resolve(object, m), m
76
+ end
77
+ end
78
+ end
79
+
80
+ def html_syntax_highlight(source, type = nil)
81
+ super(source, type || :go)
82
+ end
83
+
84
+ def format_object_title(obj)
85
+ case obj
86
+ when YARD::CodeObjects::RootObject
87
+ "Package: #{obj.full_path.split('/').last}"
88
+ else
89
+ super(obj)
90
+ end
91
+ end
92
+ end
93
+
94
+ YARD::Templates::Helpers::HtmlHelper.send(:prepend, LinkHelpers)