yard-go 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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)