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,194 @@
1
+ require 'json'
2
+
3
+ module YARDGo
4
+ module Parser
5
+ class Statement < OpenStruct
6
+ def to_s; source end
7
+ end
8
+
9
+ class Go < YARD::Parser::Base
10
+ include YARD
11
+ include YARD::CodeObjects
12
+
13
+ @@matches = {
14
+ comment: %r{^\s*//(.*)},
15
+ package: /^package (\w+)/,
16
+ function: /^func (\w+)\((.*?)\)(.*?)\{/,
17
+ struct: /^type (\w+) struct\s+\{/,
18
+ interface: /^type (\w+) interface\s+\{/,
19
+ method: /^func \(\w+\s+\*?(.+?)\) (\w+)\((.*?)\)(.*)\{/,
20
+ close_brace: /^\}/,
21
+ close_paren: /^\)/,
22
+ single_var: /^(var|const)\s+(.+?)\s*=\s*(.+)/,
23
+ multi_var: /^(var|const)\s*\(/
24
+ }
25
+
26
+ def tokenize; [] end
27
+ def enumerator; @ast end
28
+
29
+ attr_reader :file
30
+
31
+ def initialize(source, file)
32
+ YARD::CodeObjects.send(:remove_const, :NSEP)
33
+ YARD::CodeObjects.const_set(:NSEP, '/')
34
+ YARD::CodeObjects.send(:remove_const, :NSEPQ)
35
+ YARD::CodeObjects.const_set(:NSEPQ, '/')
36
+ YARD::CodeObjects.send(:remove_const, :ISEP)
37
+ YARD::CodeObjects.const_set(:ISEP, '.')
38
+ YARD::CodeObjects.send(:remove_const, :ISEPQ)
39
+ YARD::CodeObjects.const_set(:ISEPQ, '.')
40
+ @lines = source.split(/\r?\n/)
41
+ @file = file
42
+ @svc_docs = {}
43
+ @ast = []
44
+ @structs = {}
45
+ @lineno = 0
46
+ end
47
+
48
+ def parse
49
+ clear_comments
50
+ consume_until do
51
+ case line
52
+ when @@matches[:comment]
53
+ add_comment($1)
54
+
55
+ when @@matches[:package]
56
+ @ast << s(:package, package_name: $1)
57
+
58
+ when @@matches[:function]
59
+ t = s(:function, name: $1, args: $2, ret: $3)
60
+ attach_source(t)
61
+ @ast << t
62
+
63
+ when @@matches[:struct]
64
+ t = init_struct($1)
65
+ consume_fields(t)
66
+
67
+ when @@matches[:interface]
68
+ t = s(:interface, name: $1, fields: [])
69
+ consume_fields(t)
70
+ @ast << t
71
+
72
+ when @@matches[:method]
73
+ t = init_struct($1)
74
+ m = s(:method, type: $1, name: $2, args: $3, ret: $4)
75
+ attach_source(m)
76
+ t.meths.push(m)
77
+
78
+ when @@matches[:single_var]
79
+ type, lhs, src = $1.to_sym, $2, [$3]
80
+ name, vartype = *lhs.split(/\s+/)
81
+
82
+ @lineno += 1
83
+ consume_until %r{^(\w|\/\/)} do
84
+ src << line
85
+ end
86
+ @lineno -= 1
87
+
88
+ @ast << s(type, name: name, vartype: vartype, value: src.join("\n"))
89
+
90
+ when @@matches[:multi_var]
91
+ type = $1.to_sym
92
+ clear_comments
93
+
94
+ @lineno += 1
95
+ consume_until @@matches[:close_paren] do
96
+ case line
97
+ when @@matches[:comment]
98
+ add_comment($1)
99
+ when /^(\s*)(.+?)\s*=\s*(.+)/m
100
+ mindent, lhs, src = $1.length, $2, [$3]
101
+ name, vartype = *lhs.split(/\s+/)
102
+
103
+ @lineno += 1
104
+ consume_until @@matches[:close_paren] do
105
+ indent = (line[/^(\s+)/, 1] || "").length
106
+ break if indent < mindent
107
+ break if indent == mindent && line =~ /^\s+(\w|\/\/)/
108
+ src << line
109
+ end
110
+ @lineno -= 1
111
+
112
+ @ast << s(type, name: name, vartype: vartype, value: src.join("\n"))
113
+ end
114
+ end
115
+
116
+ else
117
+ if @comments.size > 0
118
+ @ast << s(:comment)
119
+ else
120
+ clear_comments
121
+ end
122
+ end
123
+ end
124
+
125
+ @ast += @structs.values
126
+
127
+ self
128
+ end
129
+
130
+ private
131
+
132
+ def init_struct(name)
133
+ @structs[name] ||= s(:struct, name: name, fields: [], meths: [])
134
+ end
135
+
136
+ def consume_fields(t)
137
+ @lineno += 1
138
+ consume_until @@matches[:close_brace] do
139
+ case line
140
+ when @@matches[:comment]
141
+ add_comment($1)
142
+ when /^\s*\*?([\w\.]+)\s*(?:`(.+?)`)?\s*$/
143
+ path, tags = $1, $2
144
+ name = path.split('.').last
145
+ t.fields.push(s(:composition, name: name, path: path, tags: tags))
146
+ when /^\s*(\w+)(\(.*?\))\s*(.*)?\s*(?:`(.+?)`)?\s*$/
147
+ t.fields.push(s(:fieldfn, name: $1, args: $3, ret: $4, tags: $5))
148
+ when /^\s*(\w+)\s*(\S+)\s*(?:`(.+?)`)?\s*$/
149
+ t.fields.push(s(:field, name: $1, field_type: $2, tags: $3))
150
+ else
151
+ clear_comments
152
+ end
153
+ end
154
+ end
155
+
156
+ def s(type, opts = {})
157
+ options = {source: line}.merge(opts)
158
+ c = @comments.join("\n")
159
+ c = c.gsub(/(\n[ \t]*\n[ \t]*\n)(.+\n\n)/, '\1## \2')
160
+ clear_comments
161
+ Statement.new(options.merge(type: type.to_sym, comments: c, line: @lineno))
162
+ end
163
+
164
+ def line
165
+ @lines[@lineno]
166
+ end
167
+
168
+ def clear_comments
169
+ @comments = []
170
+ end
171
+
172
+ def add_comment(match)
173
+ @comments.push(match.sub(/^ /, ''))
174
+ end
175
+
176
+ def consume_until(re = nil, &block)
177
+ while @lineno < @lines.size
178
+ break if re && line =~ re
179
+ yield
180
+ @lineno += 1
181
+ end
182
+ end
183
+
184
+ def attach_source(t)
185
+ src = []
186
+ consume_until @@matches[:close_brace] do
187
+ src << line
188
+ end
189
+ src << line
190
+ t.source = src.join("\n")
191
+ end
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,3 @@
1
+ module YARDGo
2
+ VERSION = "0.5.0"
3
+ end
@@ -0,0 +1,15 @@
1
+ <div class="tags">
2
+ <p class="tag_title">Structure Fields:</p>
3
+ <dl class="fields">
4
+ <% @fields.sort_by {|m| m.tag(:gotags) && m.tag(:gotags).text =~ /required:"true"/ ? -1 : 1 }.each do |m| %>
5
+ <dt><code>
6
+ <strong><%= m.name %></strong> <%= signature_types m %>
7
+ <% if m.tag(:gotags) && m.tag(:gotags).text =~ /required:"true"/ %><span class="note title readonly">required</span><% end %>
8
+ </code></dt>
9
+ <dd><%= htmlify m.docstring %></dd>
10
+ <% end %>
11
+ <% if @fields.size == 0 %>
12
+ <dt><em>(empty struct)</em></dt>
13
+ <% end %>
14
+ </dl>
15
+ </div>
@@ -0,0 +1,15 @@
1
+ <% found_method = false %>
2
+ <% object.inheritance_tree(true)[1..-1].each do |superclass| %>
3
+ <% next if superclass.is_a?(YARD::CodeObjects::Proxy) %>
4
+ <% next if options.embed_mixins.size > 0 && options.embed_mixins_match?(superclass) != false %>
5
+ <% meths = superclass.children.select {|c| c.type == :field } %>
6
+ <% next if meths.size == 0 %>
7
+ <% if method_listing.size == 0 && !found_method %><h2>Method Summary</h2><% end %>
8
+ <% found_method = true %>
9
+ <h3 class="inherited">Fields <%= superclass.type == :class ? 'inherited' : 'included' %> from <%= linkify superclass %></h3>
10
+ <p class="inherited"><%=
11
+ meths.sort_by {|o| o.name.to_s }.map do |m|
12
+ linkify(m)
13
+ end.join(", ")
14
+ %></p>
15
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <h3 class="signature <%= 'first' if @index == 0 %>" id="<%= anchor_for(object) %>">
2
+ <% if object.tags(:overload).size == 1 %>
3
+ <%= signature(object.tag(:overload), false) %>
4
+ <% elsif object.tags(:overload).size > 1 %>
5
+ <% object.tags(:overload).each do |overload| %>
6
+ <span class="overload"><%= signature(overload, false) %></span>
7
+ <% end %>
8
+ <% else %>
9
+ <%= signature(object, false) %>
10
+ <% end %>
11
+
12
+ <% if owner != object.namespace %>
13
+ <span class="not_defined_here">
14
+ Originally defined in <%= object.namespace.type %>
15
+ <%= linkify object, owner.relative_path(object.namespace) %>
16
+ </span>
17
+ <% end %>
18
+ </h3>
@@ -0,0 +1,11 @@
1
+ include T('default/method_details/html')
2
+
3
+ def init
4
+ super
5
+ sections.last.push(:fields, [T('docstring')], :inherited_fields)
6
+ end
7
+
8
+ def fields
9
+ @fields = object.children.select {|t| t.type == :field }
10
+ erb(:fields)
11
+ end
@@ -0,0 +1,4 @@
1
+ <h3 class="signature <%= 'first' if @index == 0 %>" id="<%= anchor_for(object) %>">
2
+ <%= signature(object, false) %>
3
+ <% if object.tag(:gotags).text && !object.tag(:gotags).text.empty? %><code>`<%= object.tag(:gotags).text %>`</code><% end %>
4
+ </h3>
@@ -0,0 +1 @@
1
+ include T('default/method_details/html')
@@ -0,0 +1,33 @@
1
+ #content .tags dl.fields { margin-left: 30px; }
2
+ #content .inline-objects p.children { line-height: 2.4em; }
3
+ #content .inline-objects p.children .object_link a {
4
+ font-family: monospace;
5
+ padding: 5px 7px;
6
+ padding-right: 4px;
7
+ margin-right: 5px;
8
+ background: #f8f8f8;
9
+ border: 1px solid #f0f0f0;
10
+ border-radius: 5px;
11
+ font-weight: bold;
12
+ }
13
+ #content .package.signature {
14
+ font-weight: normal;
15
+ font-family: monospace;
16
+ font-size: 1.05em;
17
+ }
18
+ #content .inline-objects p.children .object_link a:hover {
19
+ background: #CFEBFF; border-color: #A4CCDA;
20
+ }
21
+ #content dl.constants { font-size: 1.05em; }
22
+ #content dl.constants .note { padding-right: 6px; }
23
+ #content dl.constants dt { font-weight: normal; }
24
+ #content dl.constants dt .defn { margin-bottom: 10px; }
25
+ #content dl.constants dd { font-family: sans-serif; white-space: normal; }
26
+ #content dl.constants dd h3 { font-size: 1.05em; margin: 0; }
27
+ .note.title.interface, .note.title.struct {
28
+ font-weight: bold;
29
+ color: #8C8B00;
30
+ background: #FEFFE1;
31
+ border-color: #D9DBBC;
32
+ }
33
+ pre, code { tab-size: 2; }
@@ -0,0 +1,123 @@
1
+ /*
2
+
3
+ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
4
+
5
+ */
6
+
7
+ .hljs {
8
+ display: block;
9
+ overflow-x: auto;
10
+ padding: 0.5em;
11
+ color: #333;
12
+ background: #f8f8f8;
13
+ -webkit-text-size-adjust: none;
14
+ }
15
+
16
+ .hljs-comment,
17
+ .diff .hljs-header {
18
+ color: #998;
19
+ font-style: italic;
20
+ }
21
+
22
+ .hljs-keyword,
23
+ .css .rule .hljs-keyword,
24
+ .hljs-winutils,
25
+ .nginx .hljs-title,
26
+ .hljs-subst,
27
+ .hljs-request,
28
+ .hljs-status {
29
+ color: #333;
30
+ font-weight: bold;
31
+ }
32
+
33
+ .hljs-number,
34
+ .hljs-hexcolor,
35
+ .hljs-constant {
36
+ color: #008080;
37
+ }
38
+
39
+ .hljs-string,
40
+ .hljs-tag .hljs-value,
41
+ .hljs-doctag,
42
+ .tex .hljs-formula {
43
+ color: #d14;
44
+ }
45
+
46
+ .hljs-title,
47
+ .hljs-id,
48
+ .scss .hljs-preprocessor {
49
+ color: #900;
50
+ font-weight: bold;
51
+ }
52
+
53
+ .hljs-list .hljs-keyword,
54
+ .hljs-subst {
55
+ font-weight: normal;
56
+ }
57
+
58
+ .hljs-class .hljs-title,
59
+ .hljs-type,
60
+ .vhdl .hljs-literal,
61
+ .tex .hljs-command {
62
+ color: #458;
63
+ font-weight: bold;
64
+ }
65
+
66
+ .hljs-tag,
67
+ .hljs-tag .hljs-title,
68
+ .hljs-rule .hljs-property,
69
+ .django .hljs-tag .hljs-keyword {
70
+ color: #000080;
71
+ font-weight: normal;
72
+ }
73
+
74
+ .hljs-attribute,
75
+ .hljs-variable,
76
+ .lisp .hljs-body,
77
+ .hljs-name {
78
+ color: #008080;
79
+ }
80
+
81
+ .hljs-regexp {
82
+ color: #009926;
83
+ }
84
+
85
+ .hljs-symbol,
86
+ .ruby .hljs-symbol .hljs-string,
87
+ .lisp .hljs-keyword,
88
+ .clojure .hljs-keyword,
89
+ .scheme .hljs-keyword,
90
+ .tex .hljs-special,
91
+ .hljs-prompt {
92
+ color: #990073;
93
+ }
94
+
95
+ .hljs-built_in {
96
+ color: #0086b3;
97
+ }
98
+
99
+ .hljs-preprocessor,
100
+ .hljs-pragma,
101
+ .hljs-pi,
102
+ .hljs-doctype,
103
+ .hljs-shebang,
104
+ .hljs-cdata {
105
+ color: #999;
106
+ font-weight: bold;
107
+ }
108
+
109
+ .hljs-deletion {
110
+ background: #fdd;
111
+ }
112
+
113
+ .hljs-addition {
114
+ background: #dfd;
115
+ }
116
+
117
+ .diff .hljs-change {
118
+ background: #0086b3;
119
+ }
120
+
121
+ .hljs-chunk {
122
+ color: #aaa;
123
+ }
@@ -0,0 +1,2 @@
1
+ <li id="object_" class="odd"><div class="item" style="padding-left:30px"><%= link_object(Registry.root, Registry.root.title, nil, false) %></div></li>
2
+ <%= class_list %>
@@ -0,0 +1,10 @@
1
+ def run_verifier(objs)
2
+ super(objs.reject {|t| t.type == :bare_struct })
3
+ end
4
+
5
+ def generate_package_list
6
+ @items = options.objects if options.objects
7
+ @list_title = "Package List"
8
+ @list_type = "package"
9
+ generate_list_contents
10
+ end
@@ -0,0 +1,5 @@
1
+ <% list = object.implementing_structs %>
2
+ <% if list.size > 0 %>
3
+ <h3 class="inherited">Implemented By</h3>
4
+ <p class="inherited"><%= list.sort_by {|o| o.name.to_s }.map {|m| linkify(m) }.join(", ") %></p>
5
+ <% end %>