solargraph 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/solargraph/api_map.rb +57 -50
- data/lib/solargraph/code_map.rb +17 -27
- data/lib/solargraph/server.rb +1 -1
- data/lib/solargraph/shell.rb +14 -1
- data/lib/solargraph/suggestion.rb +12 -6
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +24 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e99bdc143ca29ca298dc48668e2eab23a73fb338
|
4
|
+
data.tar.gz: a2c8fc45842f2d30f30c964f427962992223315e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7eee90d32b54be8ed26faa90c55794c68981e90e6fae4dfafba8a226847bb06fe90485876a82be679d83bca3fac5eb33c63072d98a517418c6437ba91956873
|
7
|
+
data.tar.gz: c8b992d21569e07e36db02c08c332c7309ee206daf81ff5489ce440a308b50d1e6cdabc337b728ecd37403e745f1f6fc4ffbb1562e3d486908f8372b2cafcd5d
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -15,14 +15,20 @@ module Solargraph
|
|
15
15
|
MAPPABLE_METHODS = [
|
16
16
|
:include, :require, :autoload, :attr_reader, :attr_writer, :attr_accessor, :private, :public, :protected
|
17
17
|
]
|
18
|
+
|
18
19
|
include NodeMethods
|
19
20
|
|
20
21
|
attr_reader :workspace
|
21
22
|
|
22
23
|
def initialize workspace = nil
|
23
24
|
@workspace = workspace
|
24
|
-
#process_workspace
|
25
25
|
clear
|
26
|
+
unless @workspace.nil? #or has_yardoc?
|
27
|
+
files = Dir[File.join workspace, 'lib', '**', '*.rb'] + Dir[File.join workspace, 'app', '**', '*.rb']
|
28
|
+
files.each { |f|
|
29
|
+
append_file f
|
30
|
+
}
|
31
|
+
end
|
26
32
|
end
|
27
33
|
|
28
34
|
def clear
|
@@ -31,17 +37,12 @@ module Solargraph
|
|
31
37
|
@parent_stack = {}
|
32
38
|
@namespace_map = {}
|
33
39
|
@namespace_tree = {}
|
34
|
-
#@pending_requires = []
|
35
40
|
@required = []
|
36
41
|
end
|
37
42
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# process_files
|
42
|
-
# process_requires
|
43
|
-
# process_maps
|
44
|
-
#end
|
43
|
+
def has_yardoc?
|
44
|
+
workspace and File.exist?(File.join(workspace, '.yardoc'))
|
45
|
+
end
|
45
46
|
|
46
47
|
def append_file filename
|
47
48
|
append_source File.read(filename), filename
|
@@ -53,22 +54,21 @@ module Solargraph
|
|
53
54
|
end
|
54
55
|
|
55
56
|
def append_node node, comments, filename = nil
|
56
|
-
|
57
|
+
@file_comments[filename] = associate_comments(node, comments)
|
58
|
+
mapified = reduce(node, @file_comments[filename])
|
57
59
|
root = AST::Node.new(:begin, [filename])
|
58
60
|
mapified.children.each { |c|
|
59
61
|
root = root.append c
|
60
62
|
}
|
61
63
|
@file_nodes[filename] = root
|
62
|
-
@file_comments[filename] = associate_comments(mapified, comments)
|
63
64
|
@required.uniq!
|
64
65
|
process_maps
|
65
66
|
end
|
66
67
|
|
67
68
|
def associate_comments node, comments
|
68
|
-
comment_hash = Parser::Source::Comment.
|
69
|
+
comment_hash = Parser::Source::Comment.associate_locations(node, comments)
|
69
70
|
yard_hash = {}
|
70
71
|
comment_hash.each_pair { |k, v|
|
71
|
-
#ctxt = v.map(&:text).join("\r\n")
|
72
72
|
ctxt = ''
|
73
73
|
v.each { |l|
|
74
74
|
ctxt += l.text.gsub(/^#/, '') + "\n"
|
@@ -81,7 +81,8 @@ module Solargraph
|
|
81
81
|
|
82
82
|
def get_comment_for node
|
83
83
|
filename = get_filename_for(node)
|
84
|
-
|
84
|
+
return nil if @file_comments[filename].nil?
|
85
|
+
@file_comments[filename][node.loc]
|
85
86
|
end
|
86
87
|
|
87
88
|
def self.get_keywords without_snippets: false
|
@@ -142,7 +143,17 @@ module Solargraph
|
|
142
143
|
}
|
143
144
|
unless cursor.nil?
|
144
145
|
cursor.keys.each { |k|
|
145
|
-
|
146
|
+
type = get_namespace_type(k, fqns)
|
147
|
+
kind = nil
|
148
|
+
detail = nil
|
149
|
+
if type == :class
|
150
|
+
kind = Suggestion::CLASS
|
151
|
+
detail = 'Class'
|
152
|
+
elsif type == :module
|
153
|
+
kind = Suggestion::MODULE
|
154
|
+
detail = 'Module'
|
155
|
+
end
|
156
|
+
result.push Suggestion.new(k, kind: kind, detail: detail)
|
146
157
|
}
|
147
158
|
nodes = get_namespace_nodes(fqns)
|
148
159
|
nodes.each { |n|
|
@@ -225,7 +236,6 @@ module Solargraph
|
|
225
236
|
if node.kind_of?(AST::Node)
|
226
237
|
node.children.each { |c|
|
227
238
|
if c.kind_of?(AST::Node)
|
228
|
-
#next if [:class, :module].include?(c.type)
|
229
239
|
is_inst = !find_parent(c, :def).nil?
|
230
240
|
if c.type == :ivasgn and ( (scope == :instance and is_inst) or (scope != :instance and !is_inst) )
|
231
241
|
arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE)
|
@@ -266,7 +276,7 @@ module Solargraph
|
|
266
276
|
end
|
267
277
|
|
268
278
|
def get_global_variables
|
269
|
-
# TODO
|
279
|
+
# TODO: Get them
|
270
280
|
[]
|
271
281
|
end
|
272
282
|
|
@@ -323,19 +333,25 @@ module Solargraph
|
|
323
333
|
end
|
324
334
|
|
325
335
|
def get_instance_methods(namespace, root = '')
|
326
|
-
meths =
|
336
|
+
meths = []
|
337
|
+
meths += inner_get_instance_methods(namespace, root, []) unless has_yardoc?
|
327
338
|
yard = YardMap.new(required: @required, workspace: @workspace)
|
328
|
-
|
329
|
-
if
|
330
|
-
meths
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
+
yard_meths = yard.get_instance_methods(namespace, root)
|
340
|
+
if yard_meths.any?
|
341
|
+
meths.concat yard_meths
|
342
|
+
else
|
343
|
+
type = get_namespace_type(namespace, root)
|
344
|
+
if type == :class
|
345
|
+
meths += yard.get_instance_methods('Object')
|
346
|
+
elsif type == :module
|
347
|
+
meths += yard.get_instance_methods('Module')
|
348
|
+
end
|
349
|
+
# TODO: Look out for repeats. Consider not doing this at all.
|
350
|
+
sc = get_superclass(namespace, root)
|
351
|
+
until sc.nil?
|
352
|
+
meths += yard.get_instance_methods(sc, root)
|
353
|
+
sc = get_superclass(sc)
|
354
|
+
end
|
339
355
|
end
|
340
356
|
meths
|
341
357
|
end
|
@@ -374,7 +390,7 @@ module Solargraph
|
|
374
390
|
elsif current_scope == :public
|
375
391
|
if c.kind_of?(AST::Node) and c.type == :def
|
376
392
|
cmnt = get_comment_for(c)
|
377
|
-
meths.push Suggestion.new(c.children[0], kind: Suggestion::METHOD, documentation: cmnt) if c.children[0].to_s[0].match(/[a-z]/i)
|
393
|
+
meths.push Suggestion.new(c.children[0], kind: Suggestion::METHOD, documentation: cmnt, detail: fqns) if c.children[0].to_s[0].match(/[a-z]/i)
|
378
394
|
elsif c.kind_of?(AST::Node) and c.type == :send and c.children[1] == :attr_reader
|
379
395
|
c.children[2..-1].each { |x|
|
380
396
|
meths.push Suggestion.new(x.children[0], kind: Suggestion::METHOD) if x.type == :sym
|
@@ -421,15 +437,6 @@ module Solargraph
|
|
421
437
|
|
422
438
|
private
|
423
439
|
|
424
|
-
def mapify node
|
425
|
-
root = node
|
426
|
-
if !root.kind_of?(AST::Node) or root.type != :begin
|
427
|
-
root = AST::Node.new(:begin, [node], {})
|
428
|
-
end
|
429
|
-
root = reduce root
|
430
|
-
root
|
431
|
-
end
|
432
|
-
|
433
440
|
def mappable?(node)
|
434
441
|
# TODO Add node.type :casgn (constant assignment)
|
435
442
|
if node.kind_of?(AST::Node) and (node.type == :class or node.type == :module or node.type == :def or node.type == :defs or node.type == :ivasgn or node.type == :gvasgn or node.type == :or_asgn)
|
@@ -441,42 +448,42 @@ module Solargraph
|
|
441
448
|
end
|
442
449
|
end
|
443
450
|
|
444
|
-
def reduce node
|
445
|
-
mappable = get_mappable_nodes(node.children)
|
451
|
+
def reduce node, comment_hash
|
452
|
+
mappable = get_mappable_nodes(node.children, comment_hash)
|
446
453
|
result = node.updated nil, mappable
|
447
454
|
result
|
448
455
|
end
|
449
456
|
|
450
|
-
def get_mappable_nodes arr
|
457
|
+
def get_mappable_nodes arr, comment_hash
|
451
458
|
result = []
|
452
459
|
arr.each { |n|
|
453
460
|
if mappable?(n)
|
454
|
-
min = minify(n)
|
461
|
+
min = minify(n, comment_hash)
|
455
462
|
result.push min
|
456
463
|
else
|
457
464
|
next unless n.kind_of?(AST::Node)
|
458
|
-
result += get_mappable_nodes(n.children)
|
465
|
+
result += get_mappable_nodes(n.children, comment_hash)
|
459
466
|
end
|
460
467
|
}
|
461
468
|
result
|
462
469
|
end
|
463
470
|
|
464
|
-
def minify node
|
471
|
+
def minify node, comment_hash
|
465
472
|
return node if node.type == :args
|
466
473
|
type = node.type
|
467
474
|
children = []
|
468
475
|
if node.type == :class
|
469
476
|
children += node.children[0, 2]
|
470
|
-
children += get_mappable_nodes(node.children[2..-1])
|
477
|
+
children += get_mappable_nodes(node.children[2..-1], comment_hash)
|
471
478
|
elsif node.type == :def
|
472
479
|
children += node.children[0, 2]
|
473
|
-
children += get_mappable_nodes(node.children[2..-1])
|
480
|
+
children += get_mappable_nodes(node.children[2..-1], comment_hash)
|
474
481
|
elsif node.type == :defs
|
475
482
|
children += node.children[0, 3]
|
476
|
-
children += get_mappable_nodes(node.children[3..-1])
|
483
|
+
children += get_mappable_nodes(node.children[3..-1], comment_hash)
|
477
484
|
elsif node.type == :module
|
478
485
|
children += node.children[0, 1]
|
479
|
-
children += get_mappable_nodes(node.children[1..-1])
|
486
|
+
children += get_mappable_nodes(node.children[1..-1], comment_hash)
|
480
487
|
elsif node.type == :ivasgn or node.type == :gvasgn
|
481
488
|
children += node.children
|
482
489
|
elsif node.type == :send and node.children[1] == :include
|
@@ -500,7 +507,7 @@ module Solargraph
|
|
500
507
|
end
|
501
508
|
|
502
509
|
def map_parents node, tree = []
|
503
|
-
if node.kind_of?(AST::Node)
|
510
|
+
if node.kind_of?(AST::Node)
|
504
511
|
@parent_stack[node] = tree
|
505
512
|
node.children.each { |c|
|
506
513
|
map_parents c, [node] + tree
|
data/lib/solargraph/code_map.rb
CHANGED
@@ -7,26 +7,30 @@ module Solargraph
|
|
7
7
|
|
8
8
|
include NodeMethods
|
9
9
|
|
10
|
-
def initialize code: '', filename: nil
|
11
|
-
workspace
|
12
|
-
|
13
|
-
filename.gsub!(File::ALT_SEPARATOR, File::SEPARATOR) unless File::ALT_SEPARATOR.nil?
|
10
|
+
def initialize code: '', filename: nil, workspace: nil
|
11
|
+
if workspace.nil? and !filename.nil?
|
12
|
+
filename = filename.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless File::ALT_SEPARATOR.nil?
|
14
13
|
workspace = CodeMap.find_workspace(filename)
|
15
14
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
if workspace.nil?
|
16
|
+
@api_map = ApiMap.new(workspace)
|
17
|
+
else
|
18
|
+
ser_file = File.join(workspace, '.solargraph.ser')
|
19
|
+
if File.exist?(ser_file)
|
20
|
+
begin
|
21
|
+
@api_map = Marshal.load(File.read(ser_file))
|
22
|
+
rescue Exception => e
|
23
|
+
@api_map = ApiMap.new(workspace)
|
22
24
|
end
|
23
|
-
|
25
|
+
else
|
26
|
+
@api_map = ApiMap.new(workspace)
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
@code = code.gsub(/\r/, '')
|
27
31
|
tries = 0
|
28
32
|
# Hide incomplete code to avoid syntax errors
|
29
|
-
tmp = "#{code}\nX".gsub(/[\.@]([\s])/, '#\1').gsub(/([\A\s]?)def([\s]*?[\n\Z])/, '\1#ef\2')
|
33
|
+
tmp = "#{@code}\nX".gsub(/[\.@]([\s])/, '#\1').gsub(/([\A\s]?)def([\s]*?[\n\Z])/, '\1#ef\2')
|
30
34
|
#tmp = code
|
31
35
|
begin
|
32
36
|
@node, comments = Parser::CurrentRuby.parse_with_comments(tmp)
|
@@ -36,7 +40,6 @@ module Solargraph
|
|
36
40
|
tries += 1
|
37
41
|
spot = e.diagnostic.location.begin_pos
|
38
42
|
if spot == tmp.length
|
39
|
-
puts e.message
|
40
43
|
tmp = tmp[0..-2] + '#'
|
41
44
|
else
|
42
45
|
tmp = tmp[0..spot] + '#' + tmp[spot+2..-1].to_s
|
@@ -181,20 +184,7 @@ module Solargraph
|
|
181
184
|
result = @api_map.namespaces_in(ns)
|
182
185
|
end
|
183
186
|
elsif phrase.include?('.')
|
184
|
-
|
185
|
-
# TODO: For now we're assuming only one period. That's obviously a bad assumption.
|
186
|
-
#base = phrase[0..phrase.index('.')-1]
|
187
|
-
#ns_here = namespace_at(index)
|
188
|
-
#result = @api_map.get_methods(base, ns_here)
|
189
|
-
#scope = parent_node_from(index, :class, :module, :def, :defs) || @node
|
190
|
-
#var = find_local_variable_node(base, scope)
|
191
|
-
#unless var.nil?
|
192
|
-
# obj = infer(var.children[1])
|
193
|
-
# result = @api_map.get_instance_methods(obj) unless obj.nil?
|
194
|
-
#end
|
195
|
-
|
196
|
-
# TODO: Alternate version that resolves signature
|
197
|
-
result = resolve_signature_at index
|
187
|
+
result = resolve_signature_at @code[0, index].rindex('.')
|
198
188
|
else
|
199
189
|
current_namespace = namespace_at(index)
|
200
190
|
parts = current_namespace.to_s.split('::')
|
data/lib/solargraph/server.rb
CHANGED
@@ -14,7 +14,7 @@ module Solargraph
|
|
14
14
|
rescue Exception => e
|
15
15
|
STDERR.puts e
|
16
16
|
STDERR.puts e.backtrace.join("\n")
|
17
|
-
{ "status" => "err", "message" => e.message }.to_json
|
17
|
+
{ "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/lib/solargraph/shell.rb
CHANGED
@@ -54,6 +54,18 @@ module Solargraph
|
|
54
54
|
Solargraph::Server.run!
|
55
55
|
end
|
56
56
|
|
57
|
+
desc 'serialize DIRECTORY', 'Cache an API map of DIRECTORY'
|
58
|
+
def serialize directory
|
59
|
+
api_map = ApiMap.new directory
|
60
|
+
files = Dir[File.join directory, 'lib', '**', '*.rb'] + Dir[File.join directory, 'app', '**', '*.rb']
|
61
|
+
files.each { |f|
|
62
|
+
api_map.append_file f
|
63
|
+
}
|
64
|
+
File.open(File.join(directory, '.solargraph.ser'), 'wb') { |file|
|
65
|
+
file << Marshal.dump(api_map)
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
57
69
|
desc 'suggest', 'Get code suggestions for the provided input'
|
58
70
|
long_desc <<-LONGDESC
|
59
71
|
Analyze a Ruby file and output a list of code suggestions in JSON format.
|
@@ -76,7 +88,8 @@ module Solargraph
|
|
76
88
|
rescue Exception => e
|
77
89
|
STDERR.puts e
|
78
90
|
STDERR.puts e.backtrace.join("\n")
|
79
|
-
result = { "status" => "err", "message" => e.message }.to_json
|
91
|
+
#result = { "status" => "err", "message" => e.message }.to_json
|
92
|
+
result = { "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
|
80
93
|
STDOUT.puts result
|
81
94
|
end
|
82
95
|
end
|
@@ -10,15 +10,16 @@ module Solargraph
|
|
10
10
|
VARIABLE = 'Variable'
|
11
11
|
SNIPPET = 'Snippet'
|
12
12
|
|
13
|
-
attr_reader :label, :kind, :insert, :detail, :documentation
|
13
|
+
attr_reader :label, :kind, :insert, :detail, :documentation, :code_object, :location
|
14
14
|
|
15
|
-
def initialize label, kind: KEYWORD, insert: nil, detail: nil, documentation: nil, code_object: nil
|
15
|
+
def initialize label, kind: KEYWORD, insert: nil, detail: nil, documentation: nil, code_object: nil, location: nil
|
16
16
|
@label = label.to_s
|
17
17
|
@kind = kind
|
18
18
|
@insert = insert || @label
|
19
19
|
@detail = detail
|
20
20
|
@code_object = code_object
|
21
21
|
@documentation = documentation
|
22
|
+
@location = location
|
22
23
|
end
|
23
24
|
|
24
25
|
def to_s
|
@@ -26,14 +27,19 @@ module Solargraph
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def to_json args={}
|
29
|
-
{
|
30
|
+
obj = {
|
30
31
|
label: @label,
|
31
32
|
kind: @kind,
|
32
33
|
insert: @insert,
|
33
34
|
detail: @detail,
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
location: (@location.nil? ? nil : @location.to_s)
|
36
|
+
}
|
37
|
+
if @code_object.nil?
|
38
|
+
obj[:documentation] = @documentation.all unless @documentation.nil?
|
39
|
+
else
|
40
|
+
obj[:documentation] = @code_object.docstring.all unless @code_object.docstring.nil?
|
41
|
+
end
|
42
|
+
obj.to_json(args)
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -10,12 +10,20 @@ module Solargraph
|
|
10
10
|
wsy = File.join(workspace, '.yardoc')
|
11
11
|
yardocs.push wsy if File.exist?(wsy)
|
12
12
|
end
|
13
|
+
used = []
|
13
14
|
required.each { |r|
|
14
|
-
|
15
|
-
|
15
|
+
if workspace.nil? or !File.exist?(File.join workspace, 'lib', "#{r}.rb")
|
16
|
+
g = r.split('/').first
|
17
|
+
unless used.include?(g)
|
18
|
+
used.push g
|
19
|
+
gy = YARD::Registry.yardoc_file_for_gem(g)
|
20
|
+
yardocs.push gy unless gy.nil?
|
21
|
+
end
|
22
|
+
end
|
16
23
|
}
|
17
24
|
yardocs.push File.join(Dir.home, '.solargraph', 'cache', '2.0.0', 'yardoc')
|
18
25
|
#yardocs.push File.join(Dir.home, '.solargraph', 'cache', '2.0.0', 'yardoc-stdlib')
|
26
|
+
yardocs.uniq!
|
19
27
|
end
|
20
28
|
|
21
29
|
def yardocs
|
@@ -38,7 +46,16 @@ module Solargraph
|
|
38
46
|
end
|
39
47
|
}
|
40
48
|
consts.each { |c|
|
41
|
-
|
49
|
+
detail = nil
|
50
|
+
kind = nil
|
51
|
+
if c.kind_of?(YARD::CodeObjects::ClassObject)
|
52
|
+
detail = 'Class'
|
53
|
+
kind = Suggestion::CLASS
|
54
|
+
elsif c.kind_of?(YARD::CodeObjects::ModuleObject)
|
55
|
+
detail = 'Module'
|
56
|
+
kind = Suggestion::MODULE
|
57
|
+
end
|
58
|
+
result.push Suggestion.new(c.to_s.split('::').last, detail: detail, kind: kind)
|
42
59
|
}
|
43
60
|
result
|
44
61
|
end
|
@@ -79,7 +96,7 @@ module Solargraph
|
|
79
96
|
unless ns.nil?
|
80
97
|
ns.meths(scope: :class, visibility: [:public]).each { |m|
|
81
98
|
n = m.to_s.split('.').last
|
82
|
-
meths.push Suggestion.new("#{n}", kind: Suggestion::METHOD) if n.to_s.match(/^[a-z]/i)
|
99
|
+
meths.push Suggestion.new("#{n}", kind: Suggestion::METHOD, detail: "#{ns}") if n.to_s.match(/^[a-z]/i)
|
83
100
|
}
|
84
101
|
if ns.kind_of?(YARD::CodeObjects::ClassObject) and namespace != 'Class'
|
85
102
|
meths += get_instance_methods('Class')
|
@@ -104,7 +121,9 @@ module Solargraph
|
|
104
121
|
unless ns.nil?
|
105
122
|
ns.meths(scope: :instance, visibility: [:public]).each { |m|
|
106
123
|
n = m.to_s.split('#').last
|
107
|
-
|
124
|
+
if n.to_s.match(/^[a-z]/i) and !m.to_s.start_with?('Kernel#') and !m.docstring.to_s.include?(':nodoc:')
|
125
|
+
meths.push Suggestion.new("#{n}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: "#{ns}", location: "#{m.file}:#{m.line}")
|
126
|
+
end
|
108
127
|
}
|
109
128
|
if ns.kind_of?(YARD::CodeObjects::ClassObject) and namespace != 'Object'
|
110
129
|
meths += get_instance_methods('Object')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solargraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|