msgpack-idl 0.1.0 → 0.1.1
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.
- data/ChangeLog +4 -0
- data/lib/msgpack/idl/ast.rb +164 -3
- data/lib/msgpack/idl/command/example.rb +64 -4
- data/lib/msgpack/idl/command/idl.rb +75 -42
- data/lib/msgpack/idl/command/vimcolor.rb +254 -0
- data/lib/msgpack/idl/command/vimcolor/mark.vim +67 -0
- data/lib/msgpack/idl/command/vimcolor/msgspec.vim +68 -0
- data/lib/msgpack/idl/error.rb +1 -1
- data/lib/msgpack/idl/evaluator.rb +283 -138
- data/lib/msgpack/idl/ir.rb +31 -6
- data/lib/msgpack/idl/parser/rule.rb +20 -3
- data/lib/msgpack/idl/parser/transform.rb +15 -18
- data/lib/msgpack/idl/version.rb +1 -1
- metadata +7 -4
data/ChangeLog
CHANGED
data/lib/msgpack/idl/ast.rb
CHANGED
@@ -20,7 +20,21 @@ module IDL
|
|
20
20
|
|
21
21
|
|
22
22
|
module AST
|
23
|
+
SUMMARY_LINES = 6
|
24
|
+
|
23
25
|
class Element
|
26
|
+
alias text to_s
|
27
|
+
|
28
|
+
def summary
|
29
|
+
t = text
|
30
|
+
lines = t.split("\n")
|
31
|
+
return t if lines.size <= SUMMARY_LINES
|
32
|
+
if lines.last == "}"
|
33
|
+
(lines[0,SUMMARY_LINES-2] + [" ...", "}"]).join("\n")
|
34
|
+
else
|
35
|
+
(lines[0,SUMMARY_LINES-1] + [" ..."]).join("\n")
|
36
|
+
end
|
37
|
+
end
|
24
38
|
end
|
25
39
|
|
26
40
|
class Document < Array
|
@@ -31,6 +45,10 @@ module AST
|
|
31
45
|
@path = path
|
32
46
|
end
|
33
47
|
attr_reader :path
|
48
|
+
|
49
|
+
def text
|
50
|
+
"include #{@path}"
|
51
|
+
end
|
34
52
|
end
|
35
53
|
|
36
54
|
|
@@ -40,6 +58,14 @@ module AST
|
|
40
58
|
@lang = lang
|
41
59
|
end
|
42
60
|
attr_reader :scopes, :lang
|
61
|
+
|
62
|
+
def text
|
63
|
+
if @lang
|
64
|
+
"namespace #{@lang} #{@scopes.join('.')}"
|
65
|
+
else
|
66
|
+
"namespace #{@scopes.join('.')}"
|
67
|
+
end
|
68
|
+
end
|
43
69
|
end
|
44
70
|
|
45
71
|
|
@@ -50,6 +76,15 @@ module AST
|
|
50
76
|
@fields = fields
|
51
77
|
end
|
52
78
|
attr_reader :name, :super_class, :fields
|
79
|
+
|
80
|
+
def text
|
81
|
+
t = "message #{@name}"
|
82
|
+
t << " < #{@super_class.text}" if @super_class
|
83
|
+
t << " {\n"
|
84
|
+
t << @fields.map {|f| " #{f.text}\n" }.join
|
85
|
+
t << "}"
|
86
|
+
t
|
87
|
+
end
|
53
88
|
end
|
54
89
|
|
55
90
|
|
@@ -65,6 +100,14 @@ module AST
|
|
65
100
|
@modifier = modifier
|
66
101
|
end
|
67
102
|
attr_reader :id, :type, :name, :modifier
|
103
|
+
|
104
|
+
def text
|
105
|
+
if @modifier == FIELD_OPTIONAL
|
106
|
+
"#{@id}: optional #{@type.text} #{@name}"
|
107
|
+
else
|
108
|
+
"#{@id}: #{@type.text} #{@name}"
|
109
|
+
end
|
110
|
+
end
|
68
111
|
end
|
69
112
|
|
70
113
|
class ValueAssignedField < Field
|
@@ -73,6 +116,10 @@ module AST
|
|
73
116
|
@value = value
|
74
117
|
end
|
75
118
|
attr_reader :value
|
119
|
+
|
120
|
+
def text
|
121
|
+
"#{super} = #{@value.text}"
|
122
|
+
end
|
76
123
|
end
|
77
124
|
|
78
125
|
|
@@ -82,6 +129,13 @@ module AST
|
|
82
129
|
@fields = fields
|
83
130
|
end
|
84
131
|
attr_reader :name, :fields
|
132
|
+
|
133
|
+
def text
|
134
|
+
t = "enum #{@name} {\n"
|
135
|
+
t << @fields.map {|f| " #{f.text}\n" }.join
|
136
|
+
t << "}"
|
137
|
+
t
|
138
|
+
end
|
85
139
|
end
|
86
140
|
|
87
141
|
class EnumField < Element
|
@@ -90,16 +144,65 @@ module AST
|
|
90
144
|
@name = name
|
91
145
|
end
|
92
146
|
attr_reader :id, :name
|
147
|
+
|
148
|
+
def text
|
149
|
+
"#{@id}: #{@name}"
|
150
|
+
end
|
93
151
|
end
|
94
152
|
|
95
153
|
|
96
154
|
class Service < Element
|
97
|
-
def initialize(name, version,
|
155
|
+
def initialize(name, version, functions)
|
98
156
|
@name = name
|
99
157
|
@version = version
|
100
|
-
@
|
158
|
+
@functions = functions
|
159
|
+
end
|
160
|
+
attr_reader :name, :version, :functions
|
161
|
+
|
162
|
+
def text
|
163
|
+
t = "service #{@name}"
|
164
|
+
t << ":#{@version}" if @version
|
165
|
+
t << " {\n"
|
166
|
+
t << @functions.map {|f| " #{f.text}\n" }.join
|
167
|
+
t << "}"
|
168
|
+
t
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class Inherit < Element
|
173
|
+
end
|
174
|
+
|
175
|
+
class InheritAll < Inherit
|
176
|
+
def text
|
177
|
+
"inherit *"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
class InheritName < Inherit
|
182
|
+
def initialize(name)
|
183
|
+
@name = name
|
184
|
+
end
|
185
|
+
attr_reader :name
|
186
|
+
|
187
|
+
def text
|
188
|
+
"inherit #{@name}"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
class InheritFunc < Inherit
|
193
|
+
def initialize(name, return_type, args, exceptions)
|
194
|
+
@name = name
|
195
|
+
@return_type = return_type
|
196
|
+
@args = args
|
197
|
+
@exceptions = exceptions
|
198
|
+
end
|
199
|
+
attr_reader :name, :return_type, :args, :exceptions
|
200
|
+
|
201
|
+
def text
|
202
|
+
t = "inherit #{@return_type.text} #{@name}(#{@args.map {|a| a.text }.join(', ') })"
|
203
|
+
t << " throws #{@exceptions.map {|ex| ex.text }.join(', ')}" if @exceptions && !@exceptions.empty?
|
204
|
+
t
|
101
205
|
end
|
102
|
-
attr_reader :name, :version, :funcs
|
103
206
|
end
|
104
207
|
|
105
208
|
class Func < Element
|
@@ -110,6 +213,12 @@ module AST
|
|
110
213
|
@exceptions = exceptions
|
111
214
|
end
|
112
215
|
attr_reader :name, :return_type, :args, :exceptions
|
216
|
+
|
217
|
+
def text
|
218
|
+
t = "#{@return_type.text} #{@name}(#{@args.map {|a| a.text }.join(', ')})"
|
219
|
+
t << " throws #{@exceptions.map {|ex| ex.text }.join(', ')}" if @exceptions && !@exceptions.empty?
|
220
|
+
t
|
221
|
+
end
|
113
222
|
end
|
114
223
|
|
115
224
|
|
@@ -121,6 +230,13 @@ module AST
|
|
121
230
|
|
122
231
|
attr_reader :name
|
123
232
|
attr_reader :scopes
|
233
|
+
|
234
|
+
def text
|
235
|
+
t = "application #{@name} {\n"
|
236
|
+
t << @scopes.map {|sc| " #{sc.text}\n" }.join
|
237
|
+
t << "}"
|
238
|
+
t
|
239
|
+
end
|
124
240
|
end
|
125
241
|
|
126
242
|
class Scope < Element
|
@@ -135,6 +251,12 @@ module AST
|
|
135
251
|
def default?
|
136
252
|
@default
|
137
253
|
end
|
254
|
+
|
255
|
+
def text
|
256
|
+
t = "#{@service}:#{@version} #{@name}"
|
257
|
+
t << " default" if @default
|
258
|
+
t
|
259
|
+
end
|
138
260
|
end
|
139
261
|
|
140
262
|
|
@@ -148,6 +270,14 @@ module AST
|
|
148
270
|
def nullable?
|
149
271
|
@nullable
|
150
272
|
end
|
273
|
+
|
274
|
+
def text
|
275
|
+
if @nullable
|
276
|
+
"#{@name}?"
|
277
|
+
else
|
278
|
+
"#{@name}"
|
279
|
+
end
|
280
|
+
end
|
151
281
|
end
|
152
282
|
|
153
283
|
class GenericType < Type
|
@@ -156,6 +286,10 @@ module AST
|
|
156
286
|
@type_params = type_params
|
157
287
|
end
|
158
288
|
attr_reader :type_params
|
289
|
+
|
290
|
+
def text
|
291
|
+
"#{super}<#{@type_params.map {|tp| tp.text }.join(',')}>"
|
292
|
+
end
|
159
293
|
end
|
160
294
|
|
161
295
|
FIELD_OPTIONAL = :optional
|
@@ -170,6 +304,10 @@ module AST
|
|
170
304
|
@name = name
|
171
305
|
end
|
172
306
|
attr_reader :name
|
307
|
+
|
308
|
+
def text
|
309
|
+
"#{@name}"
|
310
|
+
end
|
173
311
|
end
|
174
312
|
|
175
313
|
class EnumLiteral < Literal
|
@@ -178,6 +316,10 @@ module AST
|
|
178
316
|
@field = field
|
179
317
|
end
|
180
318
|
attr_reader :name, :field
|
319
|
+
|
320
|
+
def text
|
321
|
+
"#{@name}.#{@field}"
|
322
|
+
end
|
181
323
|
end
|
182
324
|
|
183
325
|
class IntLiteral < Literal
|
@@ -185,6 +327,10 @@ module AST
|
|
185
327
|
@value = value
|
186
328
|
end
|
187
329
|
attr_reader :value
|
330
|
+
|
331
|
+
def text
|
332
|
+
"#{@value}"
|
333
|
+
end
|
188
334
|
end
|
189
335
|
|
190
336
|
class FlaotLiteral < Literal
|
@@ -192,9 +338,16 @@ module AST
|
|
192
338
|
@value = value
|
193
339
|
end
|
194
340
|
attr_reader :value
|
341
|
+
|
342
|
+
def text
|
343
|
+
"#{@value}"
|
344
|
+
end
|
195
345
|
end
|
196
346
|
|
197
347
|
class NilLiteral < Literal
|
348
|
+
def text
|
349
|
+
%[nil]
|
350
|
+
end
|
198
351
|
end
|
199
352
|
|
200
353
|
class BoolLiteral < Literal
|
@@ -202,6 +355,10 @@ module AST
|
|
202
355
|
@value = value
|
203
356
|
end
|
204
357
|
attr_reader :value
|
358
|
+
|
359
|
+
def text
|
360
|
+
"#{@value}"
|
361
|
+
end
|
205
362
|
end
|
206
363
|
|
207
364
|
class TrueLiteral < BoolLiteral
|
@@ -220,6 +377,10 @@ module AST
|
|
220
377
|
def initialize(value)
|
221
378
|
@value = value
|
222
379
|
end
|
380
|
+
|
381
|
+
def text
|
382
|
+
@value.dump
|
383
|
+
end
|
223
384
|
end
|
224
385
|
|
225
386
|
#class ListLiteral < Literal
|
@@ -22,16 +22,16 @@ module Example
|
|
22
22
|
LIST
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.
|
25
|
+
def self.get(name)
|
26
26
|
n, summary, code = LIST.find {|n, summary, code|
|
27
27
|
name == n
|
28
28
|
}
|
29
29
|
unless code
|
30
30
|
raise "unknown example name: #{name}"
|
31
31
|
end
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
result = "# #{name} - #{summary} example\n"
|
33
|
+
result << code
|
34
|
+
result
|
35
35
|
end
|
36
36
|
|
37
37
|
def self.add(name, summary, code)
|
@@ -129,6 +129,66 @@ message LogInLog {
|
|
129
129
|
1: UserInfo user
|
130
130
|
2: Sites site
|
131
131
|
}
|
132
|
+
EOF
|
133
|
+
|
134
|
+
add 'service', 'simple rpc', <<EOF
|
135
|
+
exception DiskError {
|
136
|
+
1: string message
|
137
|
+
}
|
138
|
+
|
139
|
+
service PropertyStoreService {
|
140
|
+
raw? get(1: raw key)
|
141
|
+
void set(1: raw key, 2: raw value) throws DiskError
|
142
|
+
}
|
143
|
+
EOF
|
144
|
+
|
145
|
+
add 'version', 'versioned rpc', <<EOF
|
146
|
+
exception DiskError {
|
147
|
+
1: string message
|
148
|
+
}
|
149
|
+
|
150
|
+
service PropertyStoreService:0 {
|
151
|
+
void set(1: raw key, 2: raw value)
|
152
|
+
raw? get(1: raw key)
|
153
|
+
}
|
154
|
+
|
155
|
+
service PropertyStoreService:1 {
|
156
|
+
void set(1: raw key, 2: raw value) throws DiskError
|
157
|
+
|
158
|
+
# inherit former version's function
|
159
|
+
inherit get
|
160
|
+
}
|
161
|
+
|
162
|
+
service PropertyStoreService:2 {
|
163
|
+
void set(1: raw key, 2: raw value, 3: int flags) throws DiskError
|
164
|
+
|
165
|
+
# type-checked inheritance
|
166
|
+
inherit raw? get(1: raw key)
|
167
|
+
|
168
|
+
int? getFlags(1: raw key)
|
169
|
+
}
|
170
|
+
|
171
|
+
service PropertyStoreService:3 {
|
172
|
+
# inherit all functions
|
173
|
+
inherit *
|
174
|
+
}
|
175
|
+
EOF
|
176
|
+
|
177
|
+
add 'application', 'multi-namespace rpc', <<EOF
|
178
|
+
service KeyValueService:0 {
|
179
|
+
void set(1: raw key, 2: raw value)
|
180
|
+
raw? get(1: raw key)
|
181
|
+
}
|
182
|
+
|
183
|
+
service CacheService:0 {
|
184
|
+
void set(1: raw key, 2: raw value, 3: long expire)
|
185
|
+
raw? get(1: raw key)
|
186
|
+
}
|
187
|
+
|
188
|
+
application MyApp {
|
189
|
+
KeyValueService:0 kv default
|
190
|
+
CacheService:0 cache
|
191
|
+
}
|
132
192
|
EOF
|
133
193
|
|
134
194
|
end
|
@@ -29,6 +29,8 @@ Usage: #{prog} [options] -g LANG files...
|
|
29
29
|
options:
|
30
30
|
EOF
|
31
31
|
|
32
|
+
op.summary_indent = " "
|
33
|
+
|
32
34
|
comment = <<EOF
|
33
35
|
examples:
|
34
36
|
- generate java code from test.msgspec file:
|
@@ -36,19 +38,19 @@ examples:
|
|
36
38
|
$ ls gen-java # generated codes are here
|
37
39
|
|
38
40
|
- generate java code from test.msgspec file to ./out directory:
|
39
|
-
$ #{prog} -g java -o out test.msgspec
|
41
|
+
$ #{prog} -g java -o ./out test.msgspec
|
40
42
|
|
41
43
|
- install or update language module
|
42
|
-
$
|
44
|
+
$ #{prog} --update java
|
43
45
|
|
44
46
|
- show examples
|
45
|
-
$
|
46
|
-
$
|
47
|
+
$ #{prog} --example # show list of examples
|
48
|
+
$ #{prog} --example "types"
|
47
49
|
|
48
50
|
- generate sample code
|
49
|
-
$
|
50
|
-
$
|
51
|
-
$
|
51
|
+
$ #{prog} --install java
|
52
|
+
$ #{prog} --example sample > sample.msgspec
|
53
|
+
$ #{prog} -g java sample.msgspec
|
52
54
|
EOF
|
53
55
|
|
54
56
|
(class<<self;self;end).module_eval do
|
@@ -82,15 +84,15 @@ op.on('--update', 'install or update a language module') {
|
|
82
84
|
cmd = :update
|
83
85
|
}
|
84
86
|
|
85
|
-
op.on('--list', 'show list of
|
87
|
+
op.on('--list', 'show list of installed language modules') {
|
86
88
|
cmd = :list
|
87
89
|
}
|
88
90
|
|
89
|
-
op.
|
91
|
+
op.on('--help', 'show this message') {
|
90
92
|
usage nil
|
91
93
|
}
|
92
94
|
|
93
|
-
op.
|
95
|
+
op.on('--version', 'show version') {
|
94
96
|
require 'msgpack/idl/version'
|
95
97
|
puts MessagePack::IDL::VERSION
|
96
98
|
exit 0
|
@@ -124,11 +126,22 @@ when :example
|
|
124
126
|
|
125
127
|
def show_available_examples
|
126
128
|
puts "available examples:"
|
129
|
+
name_max = Example.list.max {|name,_,_| name.length }[0].length
|
127
130
|
Example.list.each {|name,summary,code|
|
128
|
-
puts " #{name}#{" "*(
|
131
|
+
puts " #{name}#{" "*(name_max+2-name.length)}: #{summary}"
|
129
132
|
}
|
130
133
|
end
|
131
134
|
|
135
|
+
def try_color_print(code)
|
136
|
+
require 'msgpack/idl/command/vimcolor'
|
137
|
+
syntax = File.join(
|
138
|
+
File.expand_path(File.dirname(__FILE__)), 'vimcolor', 'msgspec.vim')
|
139
|
+
vc = VimColor.new('vim', nil, nil, [":filetype off", ":source #{syntax}"])
|
140
|
+
puts vc.run(code, 'msgspec', :ansi)
|
141
|
+
rescue
|
142
|
+
puts code
|
143
|
+
end
|
144
|
+
|
132
145
|
if ARGV.length == 0
|
133
146
|
show_available_examples
|
134
147
|
exit 1
|
@@ -139,7 +152,7 @@ when :example
|
|
139
152
|
|
140
153
|
name = ARGV[0]
|
141
154
|
begin
|
142
|
-
Example.
|
155
|
+
code = Example.get(name)
|
143
156
|
rescue
|
144
157
|
show_available_examples
|
145
158
|
puts ""
|
@@ -147,6 +160,12 @@ when :example
|
|
147
160
|
exit 1
|
148
161
|
end
|
149
162
|
|
163
|
+
if STDOUT.tty?
|
164
|
+
try_color_print(code)
|
165
|
+
else
|
166
|
+
puts code
|
167
|
+
end
|
168
|
+
|
150
169
|
when :update
|
151
170
|
require 'rubygems'
|
152
171
|
require 'rubygems/gem_runner'
|
@@ -178,13 +197,14 @@ when :update
|
|
178
197
|
|
179
198
|
when :list
|
180
199
|
list = []
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
list
|
186
|
-
|
200
|
+
langdir = File.join('lib', 'msgpack', 'idl', 'lang')
|
201
|
+
Gem.path.each {|gemdir|
|
202
|
+
pattern = File.join(gemdir, 'gems', 'msgpack-idl-*', 'lib', 'msgpack', 'idl', 'lang', '*.rb')
|
203
|
+
Dir.glob(pattern).each {|path|
|
204
|
+
list << File.basename(path, '.rb')
|
205
|
+
}
|
187
206
|
}
|
207
|
+
list = list.sort.uniq
|
188
208
|
|
189
209
|
puts "available language modules:"
|
190
210
|
list.each {|lang|
|
@@ -221,6 +241,7 @@ when :generate
|
|
221
241
|
rescue LoadError
|
222
242
|
available = false
|
223
243
|
end
|
244
|
+
|
224
245
|
if !available || !MessagePack::IDL::Generator.available?(lang)
|
225
246
|
puts "Language module #{lang.dump} is not available."
|
226
247
|
puts "Try to install it as follows:"
|
@@ -228,35 +249,47 @@ when :generate
|
|
228
249
|
exit 1
|
229
250
|
end
|
230
251
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
252
|
+
begin
|
253
|
+
parser = MessagePack::IDL::Parser.new
|
254
|
+
files.each {|path|
|
255
|
+
if path == "-"
|
256
|
+
text = STDIN.read
|
257
|
+
parser.parse(text, '(stdin)', '.')
|
258
|
+
else
|
259
|
+
parser.parse_file(path)
|
260
|
+
end
|
261
|
+
}
|
262
|
+
ast = parser.ast
|
263
|
+
|
264
|
+
if conf[:show_ast]
|
265
|
+
require 'pp'
|
266
|
+
$stderr.puts "AST:"
|
267
|
+
$stderr.puts ast.pretty_inspect
|
238
268
|
end
|
239
|
-
}
|
240
|
-
ast = parser.ast
|
241
269
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
270
|
+
ev = MessagePack::IDL::Evaluator.new
|
271
|
+
ev.evaluate(ast)
|
272
|
+
ev.evaluate_inheritance
|
273
|
+
ir = ev.evaluate_spec(lang)
|
274
|
+
|
275
|
+
if conf[:show_ir]
|
276
|
+
require 'pp'
|
277
|
+
$stderr.puts "IR:"
|
278
|
+
$stderr.puts ir.pretty_inspect
|
279
|
+
end
|
247
280
|
|
248
|
-
|
249
|
-
|
250
|
-
ev.evaluate_inheritance
|
251
|
-
ir = ev.evaluate_spec(lang)
|
281
|
+
gen = MessagePack::IDL::Generator.new
|
282
|
+
gen.generate(lang, ir, out)
|
252
283
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
284
|
+
rescue MessagePack::IDL::SyntaxError => error
|
285
|
+
puts error.to_s
|
286
|
+
puts ""
|
287
|
+
exit 1
|
288
|
+
rescue MessagePack::IDL::SemanticsError => error
|
289
|
+
puts error.to_s
|
290
|
+
puts ""
|
291
|
+
exit 1
|
257
292
|
end
|
258
293
|
|
259
|
-
gen = MessagePack::IDL::Generator.new
|
260
|
-
gen.generate(lang, ir, out)
|
261
294
|
end
|
262
295
|
|