typeprof 0.1.4 → 0.2.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +1 -1
- data/doc/doc.ja.md +5 -0
- data/doc/doc.md +9 -5
- data/lib/typeprof/analyzer.rb +97 -69
- data/lib/typeprof/builtin.rb +96 -92
- data/lib/typeprof/cli.rb +42 -4
- data/lib/typeprof/export.rb +36 -20
- data/lib/typeprof/import.rb +406 -365
- data/lib/typeprof/iseq.rb +1 -1
- data/lib/typeprof/method.rb +34 -33
- data/lib/typeprof/type.rb +1 -4
- data/run.sh +1 -1
- data/smoke/block13.rb +9 -0
- data/smoke/block13.rbs +3 -0
- data/smoke/class.rb +2 -0
- data/smoke/constant1.rb +3 -0
- data/smoke/demo5.rb +3 -0
- data/smoke/gvar.rb +1 -1
- data/smoke/gvar2.rb +17 -0
- data/smoke/gvar2.rbs +1 -0
- data/smoke/inheritance2.rb +6 -0
- data/smoke/ivar3.rb +16 -0
- data/smoke/ivar3.rbs +3 -0
- data/smoke/manual-rbs2.rb +1 -1
- data/smoke/manual-rbs3.rb +12 -0
- data/smoke/manual-rbs3.rbs +3 -0
- data/smoke/module4.rb +3 -0
- data/smoke/multiple-superclass.rb +8 -0
- data/smoke/rbs-alias.rb +9 -0
- data/smoke/rbs-alias.rbs +4 -0
- data/smoke/rbs-attr.rb +26 -0
- data/smoke/rbs-attr.rbs +5 -0
- data/smoke/rbs-vars.rb +39 -0
- data/smoke/rbs-vars.rbs +7 -0
- data/smoke/struct.rb +3 -0
- data/smoke/super1.rb +18 -0
- data/smoke/union-recv.rb +6 -0
- data/tools/setup-insns-def.rb +1 -1
- data/tools/stackprof-wrapper.rb +1 -1
- data/typeprof.gemspec +10 -4
- metadata +26 -7
data/lib/typeprof/import.rb
CHANGED
@@ -3,208 +3,125 @@ require "rbs"
|
|
3
3
|
module TypeProf
|
4
4
|
class RBSReader
|
5
5
|
def initialize
|
6
|
-
@env, @
|
6
|
+
@env, @builtin_env_json = RBSReader.get_builtin_env
|
7
7
|
end
|
8
8
|
|
9
|
-
@builtin_env = nil
|
10
|
-
def self.
|
11
|
-
|
9
|
+
@builtin_env = @builtin_env_json = nil
|
10
|
+
def self.get_builtin_env
|
11
|
+
unless @builtin_env
|
12
|
+
@builtin_env = RBS::Environment.new
|
13
|
+
@builtin_env_json = load_rbs(@builtin_env, builtin: true)
|
14
|
+
end
|
12
15
|
|
13
|
-
|
14
|
-
env = RBS::Environment.new
|
15
|
-
decls = loader.load(env: env)
|
16
|
-
@builtin_env = env
|
17
|
-
@builtin_env_dump = RBS2JSON.new(env, decls).dump
|
18
|
-
return env.dup, @builtin_env_dump
|
16
|
+
return @builtin_env.dup, @builtin_env_json
|
19
17
|
end
|
20
18
|
|
21
19
|
def load_builtin
|
22
|
-
@
|
20
|
+
@builtin_env_json
|
23
21
|
end
|
24
22
|
|
25
23
|
def load_library(lib)
|
26
|
-
|
27
|
-
loader.no_builtin!
|
28
|
-
loader.add(library: lib)
|
29
|
-
new_decls = loader.load(env: @env)
|
30
|
-
RBS2JSON.new(@env, new_decls).dump
|
24
|
+
RBSReader.load_rbs(@env, library: lib)
|
31
25
|
end
|
32
26
|
|
33
27
|
def load_path(path)
|
34
|
-
|
35
|
-
loader.no_builtin!
|
36
|
-
loader.add(path: path)
|
37
|
-
new_decls = loader.load(env: @env)
|
38
|
-
RBS2JSON.new(@env, new_decls).dump
|
28
|
+
RBSReader.load_rbs(@env, path: path)
|
39
29
|
end
|
40
|
-
end
|
41
30
|
|
42
|
-
|
43
|
-
|
44
|
-
|
31
|
+
def self.load_rbs(env, builtin: false, **opt)
|
32
|
+
loader = RBS::EnvironmentLoader.new
|
33
|
+
unless builtin
|
34
|
+
loader.no_builtin!
|
35
|
+
loader.add(**opt)
|
36
|
+
end
|
37
|
+
new_decls = loader.load(env: env)
|
45
38
|
|
46
|
-
|
47
|
-
@current_env = RBS::Environment.new()
|
39
|
+
all_env = env.resolve_type_names
|
48
40
|
|
41
|
+
resolver = RBS::TypeNameResolver.from_env(all_env)
|
42
|
+
cur_env = RBS::Environment.new
|
49
43
|
new_decls.each do |decl,|
|
50
|
-
|
44
|
+
cur_env << env.resolve_declaration(resolver, decl, outer: [], prefix: RBS::Namespace.root)
|
51
45
|
end
|
46
|
+
|
47
|
+
RBS2JSON.new(all_env, cur_env).dump_json
|
52
48
|
end
|
49
|
+
end
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
class RBS2JSON
|
52
|
+
def initialize(all_env, cur_env)
|
53
|
+
@all_env, @cur_env = all_env, cur_env
|
54
|
+
end
|
55
|
+
|
56
|
+
def dump_json
|
57
|
+
{
|
58
|
+
classes: conv_classes,
|
59
|
+
constants: conv_constants,
|
60
|
+
globals: conv_globals,
|
61
|
+
}
|
56
62
|
end
|
57
63
|
|
58
64
|
# constant_name = [Symbol]
|
59
65
|
#
|
60
66
|
# { constant_name => type }
|
61
|
-
def
|
67
|
+
def conv_constants
|
62
68
|
constants = {}
|
63
|
-
@
|
64
|
-
|
65
|
-
klass =
|
66
|
-
constants[klass] = convert_type(decl.decl.type)
|
69
|
+
@cur_env.constant_decls.each do |name, decl|
|
70
|
+
klass = conv_type_name(name)
|
71
|
+
constants[klass] = conv_type(decl.decl.type)
|
67
72
|
end
|
68
73
|
constants
|
69
74
|
end
|
70
75
|
|
71
|
-
#
|
72
|
-
# method_name = [singleton: true|false, Symbol}
|
73
|
-
# method_def = [...]
|
76
|
+
# gvar_name = Symbol (:$gvar)
|
74
77
|
#
|
75
|
-
# {
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
def import_rbs_classes
|
82
|
-
class2super = {}
|
83
|
-
# XXX: @env.each_global {|a| p a }
|
84
|
-
@current_env.class_decls.each do |name, decl|
|
85
|
-
decl.decls.each do |decl|
|
86
|
-
decl = decl.decl
|
87
|
-
if decl.is_a?(RBS::AST::Declarations::Class) && name != RBS::Factory.new.type_name("::Object")
|
88
|
-
#next unless decl.super_class
|
89
|
-
class2super[name] ||= decl.super_class&.name || RBS::BuiltinNames::Object.name
|
90
|
-
else
|
91
|
-
class2super[name] ||= nil
|
92
|
-
end
|
93
|
-
end
|
78
|
+
# { gvar_name => type }
|
79
|
+
def conv_globals
|
80
|
+
gvars = {}
|
81
|
+
@cur_env.global_decls.each do |name, decl|
|
82
|
+
decl = decl.decl
|
83
|
+
gvars[name] = conv_type(decl.type)
|
94
84
|
end
|
85
|
+
gvars
|
86
|
+
end
|
95
87
|
|
96
|
-
|
88
|
+
def conv_classes
|
89
|
+
json = {}
|
97
90
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
#p queue.map {|ev, name| [ev, name.to_s] }
|
103
|
-
event, name = queue.pop
|
104
|
-
case event
|
105
|
-
when :visit
|
106
|
-
if !visited[name]
|
107
|
-
visited[name] = true
|
108
|
-
queue << [:new, name]
|
109
|
-
decl = @all_env.class_decls[name]
|
110
|
-
decl.decls.each do |decl|
|
111
|
-
decl = decl.decl
|
112
|
-
next if decl.is_a?(RBS::AST::Declarations::Module)
|
113
|
-
until RBS::BuiltinNames::Object.name == decl.name
|
114
|
-
super_class = decl.super_class
|
115
|
-
break unless super_class
|
116
|
-
decls = @all_env.class_decls[super_class.name].decls
|
117
|
-
raise if decls.size >= 2 # no need to check
|
118
|
-
decl = decls.first.decl
|
119
|
-
queue << [:visit, decl.name]
|
120
|
-
end
|
121
|
-
end
|
122
|
-
if !name.namespace.empty?
|
123
|
-
queue << [:visit, name.namespace.to_type_name]
|
124
|
-
end
|
125
|
-
end
|
126
|
-
when :new
|
127
|
-
super_class_name = class2super[name]
|
128
|
-
klass = name.namespace.path + [name.name]
|
129
|
-
if super_class_name
|
130
|
-
superclass = super_class_name.namespace.path + [super_class_name.name]
|
131
|
-
else
|
132
|
-
superclass = nil
|
133
|
-
end
|
134
|
-
classes << [name, klass, superclass]
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
result = {}
|
139
|
-
classes.each do |type_name, klass, superclass|
|
140
|
-
next unless @current_env.class_decls[type_name]
|
91
|
+
each_class_decl do |name, decls|
|
92
|
+
super_class_name = get_super_class_name(name)
|
93
|
+
klass = conv_type_name(name)
|
94
|
+
superclass = super_class_name ? conv_type_name(super_class_name) : nil
|
141
95
|
|
96
|
+
type_params = nil
|
142
97
|
included_modules = []
|
143
98
|
methods = {}
|
99
|
+
ivars = {}
|
100
|
+
cvars = {}
|
144
101
|
rbs_sources = {}
|
145
|
-
type_params = nil
|
146
102
|
|
147
|
-
|
103
|
+
decls.each do |decl|
|
148
104
|
decl = decl.decl
|
149
|
-
|
105
|
+
|
106
|
+
raise NotImplementedError if decl.is_a?(RBS::AST::Declarations::Interface) # XXX
|
107
|
+
|
150
108
|
type_params2 = decl.type_params.params.map {|param| [param.name, param.variance] }
|
151
|
-
if type_params
|
152
|
-
|
153
|
-
else
|
154
|
-
type_params = type_params2
|
155
|
-
end
|
109
|
+
raise "inconsistent type parameter declaration" if type_params && type_params != type_params2
|
110
|
+
type_params = type_params2
|
156
111
|
|
157
112
|
decl.members.each do |member|
|
158
113
|
case member
|
159
114
|
when RBS::AST::Members::MethodDefinition
|
160
115
|
name = member.name
|
161
116
|
|
162
|
-
# ad-hoc filter
|
163
|
-
if member.instance?
|
164
|
-
case type_name.name
|
165
|
-
when :Object
|
166
|
-
next if name == :class
|
167
|
-
next if name == :send
|
168
|
-
next if name == :is_a?
|
169
|
-
next if name == :respond_to?
|
170
|
-
when :Array
|
171
|
-
next if name == :[]
|
172
|
-
next if name == :[]=
|
173
|
-
next if name == :pop
|
174
|
-
when :Enumerable
|
175
|
-
when :Enumerator
|
176
|
-
when :Hash
|
177
|
-
next if name == :[]
|
178
|
-
next if name == :[]=
|
179
|
-
next if name == :to_proc
|
180
|
-
#next unless [:empty?, :size].include?(name)
|
181
|
-
when :Struct
|
182
|
-
next if name == :initialize
|
183
|
-
when :Module
|
184
|
-
next if name == :include
|
185
|
-
next if name == :module_function
|
186
|
-
when :Proc
|
187
|
-
next if name == :call || name == :[]
|
188
|
-
when :Kernel
|
189
|
-
next if name == :Array
|
190
|
-
end
|
191
|
-
end
|
192
|
-
if member.singleton?
|
193
|
-
case type_name.name
|
194
|
-
when :Array
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
117
|
method_types = member.types.map do |method_type|
|
199
118
|
case method_type
|
200
|
-
when RBS::MethodType
|
201
|
-
|
202
|
-
when :super
|
203
|
-
raise NotImplementedError
|
119
|
+
when RBS::MethodType then method_type
|
120
|
+
when :super then raise NotImplementedError
|
204
121
|
end
|
205
122
|
end
|
206
123
|
|
207
|
-
method_def =
|
124
|
+
method_def = conv_method_def(method_types)
|
208
125
|
rbs_source = [(member.kind == :singleton ? "self." : "") + member.name.to_s, member.types.map {|type| type.location.source }]
|
209
126
|
if member.instance?
|
210
127
|
methods[[false, name]] = method_def
|
@@ -214,8 +131,16 @@ module TypeProf
|
|
214
131
|
methods[[true, name]] = method_def
|
215
132
|
rbs_sources[[true, name]] = rbs_source
|
216
133
|
end
|
217
|
-
|
218
|
-
|
134
|
+
when RBS::AST::Members::AttrReader
|
135
|
+
ty = conv_type(member.type)
|
136
|
+
methods[[false, member.name]] = attr_reader_def(ty)
|
137
|
+
when RBS::AST::Members::AttrWriter
|
138
|
+
ty = conv_type(member.type)
|
139
|
+
methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
|
140
|
+
when RBS::AST::Members::AttrAccessor
|
141
|
+
ty = conv_type(member.type)
|
142
|
+
methods[[false, member.name]] = attr_reader_def(ty)
|
143
|
+
methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
|
219
144
|
when RBS::AST::Members::Alias
|
220
145
|
if member.instance?
|
221
146
|
method_def = methods[[false, member.old_name]]
|
@@ -225,322 +150,438 @@ module TypeProf
|
|
225
150
|
method_def = methods[[true, member.old_name]]
|
226
151
|
methods[[true, member.new_name]] = method_def if method_def
|
227
152
|
end
|
153
|
+
|
228
154
|
when RBS::AST::Members::Include
|
229
155
|
name = member.name
|
230
|
-
|
231
|
-
|
156
|
+
if name.kind == :class
|
157
|
+
mod = conv_type_name(name)
|
158
|
+
included_modules << mod
|
159
|
+
else
|
160
|
+
# including an interface is not supported yet
|
161
|
+
end
|
162
|
+
|
232
163
|
when RBS::AST::Members::InstanceVariable
|
164
|
+
ivars[member.name] = conv_type(member.type)
|
233
165
|
when RBS::AST::Members::ClassVariable
|
234
|
-
|
166
|
+
cvars[member.name] = conv_type(member.type)
|
167
|
+
|
168
|
+
when RBS::AST::Members::Public, RBS::AST::Members::Private # XXX
|
169
|
+
|
170
|
+
# The following declarations are ignoreable because they are handled in other level
|
235
171
|
when RBS::AST::Declarations::Constant
|
236
|
-
when RBS::AST::Declarations::Alias
|
172
|
+
when RBS::AST::Declarations::Alias # type alias
|
173
|
+
when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module
|
174
|
+
when RBS::AST::Declarations::Interface
|
175
|
+
|
237
176
|
else
|
238
177
|
warn "Importing #{ member.class.name } is not supported yet"
|
239
|
-
#p member
|
240
178
|
end
|
241
179
|
end
|
242
180
|
end
|
243
181
|
|
244
|
-
|
245
|
-
|
182
|
+
json[klass] = {
|
183
|
+
type_params: type_params,
|
184
|
+
superclass: superclass,
|
185
|
+
members: {
|
186
|
+
included_modules: included_modules,
|
187
|
+
methods: methods,
|
188
|
+
ivars: ivars,
|
189
|
+
cvars: cvars,
|
190
|
+
rbs_sources: rbs_sources,
|
191
|
+
},
|
192
|
+
}
|
193
|
+
end
|
194
|
+
|
195
|
+
json
|
196
|
+
end
|
197
|
+
|
198
|
+
def each_class_decl
|
199
|
+
classes = []
|
200
|
+
|
201
|
+
# topological sort
|
202
|
+
# * superclasses and modules appear earlier than their subclasses (Object is earlier than String)
|
203
|
+
# * namespace module appers earlier than its children (Process is earlier than Process::Status)
|
204
|
+
visited = {}
|
205
|
+
queue = @cur_env.class_decls.keys.map {|name| [:visit, name] }
|
206
|
+
until queue.empty?
|
207
|
+
event, name = queue.pop
|
208
|
+
case event
|
209
|
+
when :visit
|
210
|
+
if !visited[name]
|
211
|
+
visited[name] = true
|
212
|
+
queue << [:new, name]
|
213
|
+
@all_env.class_decls[name].decls.each do |decl|
|
214
|
+
decl = decl.decl
|
215
|
+
next if decl.is_a?(RBS::AST::Declarations::Module)
|
216
|
+
each_ancestor(decl) {|name| queue << [:visit, name] }
|
217
|
+
end
|
218
|
+
queue << [:visit, name.namespace.to_type_name] if !name.namespace.empty?
|
219
|
+
end
|
220
|
+
when :new
|
221
|
+
decls = @cur_env.class_decls[name]
|
222
|
+
yield name, decls.decls if decls
|
223
|
+
end
|
224
|
+
end
|
246
225
|
|
247
|
-
|
226
|
+
classes
|
248
227
|
end
|
249
228
|
|
250
|
-
def
|
251
|
-
|
252
|
-
|
253
|
-
|
229
|
+
def each_ancestor(decl, &blk)
|
230
|
+
yield decl.name
|
231
|
+
super_class = decl.super_class || RBS::BuiltinNames::Object
|
232
|
+
return if decl.name == RBS::BuiltinNames::BasicObject.name
|
233
|
+
return if decl.name == super_class.name
|
234
|
+
@all_env.class_decls[super_class.name].decls.each do |decl|
|
235
|
+
each_ancestor(decl.decl, &blk)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def get_super_class_name(name)
|
240
|
+
return nil if name == RBS::BuiltinNames::BasicObject.name
|
241
|
+
|
242
|
+
@all_env.class_decls[name].decls.each do |decl|
|
243
|
+
decl = decl.decl
|
244
|
+
case decl
|
245
|
+
when RBS::AST::Declarations::Class
|
246
|
+
return decl.super_class.name if decl.super_class
|
247
|
+
when RBS::AST::Declarations::Module
|
248
|
+
return nil
|
254
249
|
else
|
255
|
-
|
250
|
+
raise "unknown declaration: %p" % decl.class
|
256
251
|
end
|
252
|
+
end
|
253
|
+
|
254
|
+
return RBS::BuiltinNames::Object.name
|
255
|
+
end
|
256
|
+
|
257
|
+
def conv_method_def(rbs_method_types)
|
258
|
+
rbs_method_types.map do |type|
|
259
|
+
blk = type.block ? conv_block(type.block) : nil
|
257
260
|
type_params = type.type_params
|
258
261
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
262
|
+
lead_tys = type.type.required_positionals.map {|type| conv_type(type.type) }
|
263
|
+
opt_tys = type.type.optional_positionals.map {|type| conv_type(type.type) }
|
264
|
+
rest_ty = type.type.rest_positionals
|
265
|
+
rest_ty = conv_type(rest_ty.type) if rest_ty
|
266
|
+
opt_kw_tys = type.type.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
267
|
+
req_kw_tys = type.type.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
268
|
+
rest_kw_ty = type.type.rest_keywords
|
269
|
+
raise NotImplementedError if rest_kw_ty # XXX
|
270
|
+
|
271
|
+
ret_ty = conv_type(type.type.return_type)
|
272
|
+
|
273
|
+
{
|
274
|
+
type_params: type_params,
|
275
|
+
lead_tys: lead_tys,
|
276
|
+
opt_tys: opt_tys,
|
277
|
+
rest_ty: rest_ty,
|
278
|
+
req_kw_tys: req_kw_tys,
|
279
|
+
opt_kw_tys: opt_kw_tys,
|
280
|
+
rest_kw_ty: rest_kw_ty,
|
281
|
+
blk: blk,
|
282
|
+
ret_ty: ret_ty,
|
283
|
+
}
|
284
|
+
end
|
285
|
+
end
|
276
286
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
287
|
+
def attr_reader_def(ty)
|
288
|
+
[{
|
289
|
+
type_params: [],
|
290
|
+
lead_tys: [],
|
291
|
+
opt_tys: [],
|
292
|
+
rest_ty: nil,
|
293
|
+
req_kw_tys: {},
|
294
|
+
opt_kw_tys: {},
|
295
|
+
rest_kw_ty: nil,
|
296
|
+
blk: nil,
|
297
|
+
ret_ty: ty,
|
298
|
+
}]
|
299
|
+
end
|
300
|
+
|
301
|
+
def attr_writer_def(ty)
|
302
|
+
[{
|
303
|
+
type_params: [],
|
304
|
+
lead_tys: [ty],
|
305
|
+
opt_tys: [],
|
306
|
+
rest_ty: nil,
|
307
|
+
req_kw_tys: {},
|
308
|
+
opt_kw_tys: {},
|
309
|
+
rest_kw_ty: nil,
|
310
|
+
blk: nil,
|
311
|
+
ret_ty: ty,
|
312
|
+
}]
|
283
313
|
end
|
284
314
|
|
285
|
-
def
|
286
|
-
type =
|
315
|
+
def conv_block(rbs_block)
|
316
|
+
type = rbs_block.type
|
317
|
+
|
318
|
+
# XXX
|
287
319
|
raise NotImplementedError unless type.optional_keywords.empty?
|
288
320
|
raise NotImplementedError unless type.required_keywords.empty?
|
289
|
-
raise NotImplementedError unless type.optional_positionals.empty?
|
290
321
|
raise NotImplementedError if type.rest_keywords
|
322
|
+
|
291
323
|
lead_tys = type.required_positionals.map do |type|
|
292
|
-
|
324
|
+
conv_type(type.type)
|
325
|
+
end
|
326
|
+
opt_tys = type.optional_positionals.map do |type|
|
327
|
+
conv_type(type.type)
|
293
328
|
end
|
294
|
-
ret_ty = convert_type(type.return_type)
|
295
|
-
[lead_tys, ret_ty]
|
296
|
-
end
|
297
329
|
|
298
|
-
|
330
|
+
ret_ty = conv_type(type.return_type)
|
331
|
+
|
332
|
+
[lead_tys, opt_tys, ret_ty]
|
299
333
|
end
|
300
334
|
|
301
|
-
def
|
335
|
+
def conv_type(ty)
|
302
336
|
case ty
|
303
337
|
when RBS::Types::ClassSingleton
|
304
|
-
|
305
|
-
[:class, klass]
|
338
|
+
[:class, conv_type_name(ty.name)]
|
306
339
|
when RBS::Types::ClassInstance
|
307
|
-
klass = ty.name
|
340
|
+
klass = conv_type_name(ty.name)
|
308
341
|
case klass
|
309
342
|
when [:Array]
|
310
343
|
raise if ty.args.size != 1
|
311
|
-
[:array, :Array, [],
|
344
|
+
[:array, [:Array], [], conv_type(ty.args.first)]
|
312
345
|
when [:Hash]
|
313
346
|
raise if ty.args.size != 2
|
314
347
|
key, val = ty.args
|
315
|
-
[:hash, :Hash, [
|
348
|
+
[:hash, [:Hash], [conv_type(key), conv_type(val)]]
|
316
349
|
when [:Enumerator]
|
317
350
|
raise if ty.args.size != 2
|
318
|
-
[:array, :Enumerator, [],
|
351
|
+
[:array, [:Enumerator], [], conv_type(ty.args.first)]
|
319
352
|
else
|
320
353
|
[:instance, klass]
|
321
354
|
end
|
322
|
-
when RBS::Types::Bases::Bool
|
323
|
-
|
324
|
-
when RBS::Types::Bases::
|
325
|
-
|
326
|
-
when RBS::Types::Bases::
|
327
|
-
|
328
|
-
when RBS::Types::
|
329
|
-
[:self]
|
330
|
-
when RBS::Types::Bases::Nil
|
331
|
-
[:nil]
|
332
|
-
when RBS::Types::Bases::Bottom
|
333
|
-
[:union, []]
|
334
|
-
when RBS::Types::Variable
|
335
|
-
[:var, ty.name]
|
355
|
+
when RBS::Types::Bases::Bool then [:bool]
|
356
|
+
when RBS::Types::Bases::Any then [:any]
|
357
|
+
when RBS::Types::Bases::Void then [:any]
|
358
|
+
when RBS::Types::Bases::Self then [:self]
|
359
|
+
when RBS::Types::Bases::Nil then [:nil]
|
360
|
+
when RBS::Types::Bases::Bottom then [:union, []]
|
361
|
+
when RBS::Types::Variable then [:var, ty.name]
|
336
362
|
when RBS::Types::Tuple
|
337
|
-
tys = ty.types.map {|ty2|
|
338
|
-
[:array, :Array, tys, [:union, []]]
|
363
|
+
tys = ty.types.map {|ty2| conv_type(ty2) }
|
364
|
+
[:array, [:Array], tys, [:union, []]]
|
339
365
|
when RBS::Types::Literal
|
340
366
|
case ty.literal
|
341
|
-
when Integer
|
342
|
-
|
343
|
-
when
|
344
|
-
|
345
|
-
when
|
346
|
-
[:true]
|
347
|
-
when false
|
348
|
-
[:false]
|
349
|
-
when Symbol
|
350
|
-
[:sym, ty.literal]
|
367
|
+
when Integer then [:int]
|
368
|
+
when String then [:str]
|
369
|
+
when true then [:true]
|
370
|
+
when false then [:false]
|
371
|
+
when Symbol then [:sym, ty.literal]
|
351
372
|
else
|
352
373
|
p ty.literal
|
353
374
|
raise NotImplementedError
|
354
375
|
end
|
355
376
|
when RBS::Types::Alias
|
356
377
|
alias_decl = @all_env.alias_decls[ty.name]
|
357
|
-
alias_decl ?
|
378
|
+
alias_decl ? conv_type(alias_decl.decl.type) : [:any]
|
358
379
|
when RBS::Types::Union
|
359
|
-
[:union, ty.types.map {|ty2|
|
380
|
+
[:union, ty.types.map {|ty2| conv_type(ty2) }.compact]
|
360
381
|
when RBS::Types::Optional
|
361
|
-
[:optional,
|
362
|
-
when RBS::Types::Record
|
363
|
-
[:any]
|
382
|
+
[:optional, conv_type(ty.type)]
|
364
383
|
when RBS::Types::Interface
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
384
|
+
# XXX: Currently, only a few builtin interfaces are supported
|
385
|
+
case ty.to_s
|
386
|
+
when "::_ToStr" then [:str]
|
387
|
+
when "::_ToInt" then [:int]
|
388
|
+
when "::_ToAry[U]" then [:array, [:Array], [], [:var, :U]]
|
389
|
+
else
|
390
|
+
[:any]
|
369
391
|
end
|
370
|
-
|
392
|
+
when RBS::Types::Bases::Instance then [:any] # XXX: not implemented yet
|
393
|
+
when RBS::Types::Record then [:any] # XXX: not implemented yet
|
394
|
+
when RBS::Types::Proc then [:any] # XXX: not implemented yet
|
371
395
|
else
|
372
|
-
|
373
|
-
|
396
|
+
warn "unknown RBS type: %p" % ty.class
|
397
|
+
[:any]
|
374
398
|
end
|
375
399
|
end
|
376
|
-
end
|
377
|
-
|
378
|
-
module RubySignatureImporter
|
379
|
-
module_function
|
380
400
|
|
381
|
-
def
|
382
|
-
|
383
|
-
path.each do |name|
|
384
|
-
klass = scratch.get_constant(klass, name)
|
385
|
-
raise if klass == Type.any
|
386
|
-
end
|
387
|
-
klass
|
401
|
+
def conv_type_name(name)
|
402
|
+
name.namespace.path + [name.name]
|
388
403
|
end
|
404
|
+
end
|
389
405
|
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
import_ruby_signature(scratch, scratch.rbs_reader.load_builtin)
|
406
|
+
class Import
|
407
|
+
def self.import_builtin(scratch)
|
408
|
+
Import.new(scratch, scratch.rbs_reader.load_builtin).import
|
394
409
|
end
|
395
410
|
|
396
|
-
def import_library(scratch, feature)
|
411
|
+
def self.import_library(scratch, feature)
|
412
|
+
begin
|
413
|
+
json = scratch.rbs_reader.load_library(feature)
|
414
|
+
rescue RBS::EnvironmentLoader::UnknownLibraryNameError
|
415
|
+
return nil
|
416
|
+
end
|
397
417
|
# need cache?
|
398
|
-
|
399
|
-
rescue RBS::EnvironmentLoader::UnknownLibraryNameError
|
400
|
-
false
|
418
|
+
Import.new(scratch, json).import
|
401
419
|
end
|
402
420
|
|
403
|
-
def import_rbs_file(scratch, rbs_path)
|
404
|
-
|
421
|
+
def self.import_rbs_file(scratch, rbs_path)
|
422
|
+
Import.new(scratch, scratch.rbs_reader.load_path(Pathname(rbs_path))).import(true)
|
405
423
|
end
|
406
424
|
|
407
|
-
def
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
425
|
+
def initialize(scratch, json)
|
426
|
+
@scratch = scratch
|
427
|
+
@json = json
|
428
|
+
end
|
429
|
+
|
430
|
+
def import(explicit = false)
|
431
|
+
classes = @json[:classes].map do |classpath, cdef|
|
432
|
+
type_params = cdef[:type_params]
|
433
|
+
superclass = cdef[:superclass]
|
434
|
+
members = cdef[:members]
|
435
|
+
|
436
|
+
name = classpath.last
|
437
|
+
superclass = path_to_klass(superclass) if superclass
|
438
|
+
base_klass = path_to_klass(classpath[0..-2])
|
439
|
+
|
440
|
+
klass = @scratch.get_constant(base_klass, name)
|
441
|
+
if klass.is_a?(Type::Any)
|
442
|
+
klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
|
443
|
+
|
444
|
+
# There builtin classes are needed to interpret RBS declarations
|
445
|
+
case classpath
|
446
|
+
when [:NilClass] then Type::Builtin[:nil] = klass
|
447
|
+
when [:TrueClass] then Type::Builtin[:true] = klass
|
448
|
+
when [:FalseClass] then Type::Builtin[:false] = klass
|
449
|
+
when [:Integer] then Type::Builtin[:int] = klass
|
450
|
+
when [:String] then Type::Builtin[:str] = klass
|
451
|
+
when [:Symbol] then Type::Builtin[:sym] = klass
|
452
|
+
when [:Array] then Type::Builtin[:ary] = klass
|
453
|
+
when [:Hash] then Type::Builtin[:hash] = klass
|
428
454
|
end
|
429
455
|
end
|
430
|
-
|
456
|
+
|
457
|
+
[klass, members]
|
431
458
|
end
|
432
459
|
|
433
|
-
classes.each do |klass,
|
460
|
+
classes.each do |klass, members|
|
461
|
+
included_modules = members[:included_modules]
|
462
|
+
methods = members[:methods]
|
463
|
+
ivars = members[:ivars]
|
464
|
+
cvars = members[:cvars]
|
465
|
+
rbs_sources = members[:rbs_sources]
|
466
|
+
|
434
467
|
included_modules.each do |mod|
|
435
|
-
|
436
|
-
scratch.include_module(klass, mod, false)
|
468
|
+
@scratch.include_module(klass, path_to_klass(mod), nil)
|
437
469
|
end
|
470
|
+
|
438
471
|
methods.each do |(singleton, method_name), mdef|
|
439
|
-
rbs_source = nil
|
440
|
-
|
441
|
-
|
442
|
-
|
472
|
+
rbs_source = explicit ? rbs_sources[[singleton, method_name]] : nil
|
473
|
+
mdef = conv_method_def(method_name, mdef, rbs_source)
|
474
|
+
@scratch.add_method(klass, method_name, singleton, mdef)
|
475
|
+
end
|
476
|
+
|
477
|
+
ivars.each do |ivar_name, ty|
|
478
|
+
ty = conv_type(ty)
|
479
|
+
@scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
|
480
|
+
end
|
481
|
+
|
482
|
+
cvars.each do |ivar_name, ty|
|
483
|
+
ty = conv_type(ty)
|
484
|
+
@scratch.add_cvar_write!(klass, ivar_name, ty, nil)
|
443
485
|
end
|
444
486
|
end
|
445
487
|
|
446
|
-
|
447
|
-
base_klass = path_to_klass(
|
448
|
-
value =
|
449
|
-
scratch.add_constant(base_klass, classpath[-1], value)
|
488
|
+
@json[:constants].each do |classpath, value|
|
489
|
+
base_klass = path_to_klass(classpath[0..-2])
|
490
|
+
value = conv_type(value)
|
491
|
+
@scratch.add_constant(base_klass, classpath[-1], value)
|
492
|
+
end
|
493
|
+
|
494
|
+
@json[:globals].each do |name, value|
|
495
|
+
@scratch.add_gvar_write!(name, conv_type(value), nil)
|
450
496
|
end
|
451
497
|
|
452
498
|
true
|
453
499
|
end
|
454
500
|
|
455
|
-
def
|
456
|
-
sig_rets = mdef.map do |
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
501
|
+
def conv_method_def(method_name, mdef, rbs_source)
|
502
|
+
sig_rets = mdef.map do |sig_ret|
|
503
|
+
#type_params = sig_ret[:type_params] # XXX
|
504
|
+
lead_tys = sig_ret[:lead_tys]
|
505
|
+
opt_tys = sig_ret[:opt_tys]
|
506
|
+
rest_ty = sig_ret[:rest_ty]
|
507
|
+
req_kw_tys = sig_ret[:req_kw_tys]
|
508
|
+
opt_kw_tys = sig_ret[:opt_kw_tys]
|
509
|
+
rest_kw_ty = sig_ret[:rest_kw_ty]
|
510
|
+
blk = sig_ret[:blk]
|
511
|
+
ret_ty = sig_ret[:ret_ty]
|
512
|
+
|
513
|
+
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
514
|
+
opt_tys = opt_tys.map {|ty| conv_type(ty) }
|
515
|
+
rest_ty = conv_type(rest_ty) if rest_ty
|
516
|
+
kw_tys = []
|
517
|
+
req_kw_tys.each {|key, ty| kw_tys << [true, key, conv_type(ty)] }
|
518
|
+
opt_kw_tys.each {|key, ty| kw_tys << [false, key, conv_type(ty)] }
|
519
|
+
kw_rest_ty = conv_type(rest_kw_ty) if rest_kw_ty
|
520
|
+
blk = blk ? conv_block(blk) : Type.nil
|
521
|
+
fargs = FormalArguments.new(lead_tys, opt_tys, rest_ty, [], kw_tys, kw_rest_ty, blk)
|
522
|
+
|
523
|
+
ret_ty = conv_type(ret_ty)
|
524
|
+
|
525
|
+
[fargs, ret_ty]
|
477
526
|
end.compact
|
478
527
|
|
479
528
|
TypedMethodDef.new(sig_rets, rbs_source)
|
480
529
|
end
|
481
530
|
|
482
|
-
def
|
483
|
-
lead_tys, ret_ty = blk
|
484
|
-
lead_tys = lead_tys.map {|ty|
|
485
|
-
|
486
|
-
|
531
|
+
def conv_block(blk)
|
532
|
+
lead_tys, opt_tys, ret_ty = blk
|
533
|
+
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
534
|
+
opt_tys = opt_tys.map {|ty| conv_type(ty) }
|
535
|
+
fargs = FormalArguments.new(lead_tys, opt_tys, nil, nil, nil, nil, nil)
|
536
|
+
ret_ty = conv_type(ret_ty)
|
537
|
+
Type::TypedProc.new(fargs, ret_ty, Type::Builtin[:proc])
|
487
538
|
end
|
488
539
|
|
489
|
-
|
490
|
-
end
|
491
|
-
|
492
|
-
def convert_type(scratch, ty)
|
540
|
+
def conv_type(ty)
|
493
541
|
case ty.first
|
494
|
-
when :class
|
495
|
-
|
496
|
-
when :
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
when :
|
503
|
-
|
504
|
-
when :
|
505
|
-
|
506
|
-
when :self
|
507
|
-
Type::Var.new(:self)
|
508
|
-
when :int
|
509
|
-
Type::Instance.new(Type::Builtin[:int])
|
510
|
-
when :str
|
511
|
-
Type::Instance.new(Type::Builtin[:str])
|
512
|
-
when :sym
|
513
|
-
Type::Symbol.new(ty.last, Type::Instance.new(Type::Builtin[:sym]))
|
514
|
-
when :nil
|
515
|
-
Type.nil
|
516
|
-
when :true
|
517
|
-
Type::Instance.new(Type::Builtin[:true])
|
518
|
-
when :false
|
519
|
-
Type::Instance.new(Type::Builtin[:false])
|
542
|
+
when :class then path_to_klass(ty[1])
|
543
|
+
when :instance then Type::Instance.new(path_to_klass(ty[1]))
|
544
|
+
when :any then Type.any
|
545
|
+
when :nil then Type.nil
|
546
|
+
when :optional then Type.optional(conv_type(ty[1]))
|
547
|
+
when :bool then Type.bool
|
548
|
+
when :self then Type::Var.new(:self)
|
549
|
+
when :int then Type::Instance.new(Type::Builtin[:int])
|
550
|
+
when :str then Type::Instance.new(Type::Builtin[:str])
|
551
|
+
when :sym then Type::Symbol.new(ty.last, Type::Instance.new(Type::Builtin[:sym]))
|
552
|
+
when :true then Type::Instance.new(Type::Builtin[:true])
|
553
|
+
when :false then Type::Instance.new(Type::Builtin[:false])
|
520
554
|
when :array
|
521
|
-
_,
|
522
|
-
lead_tys = lead_tys.map {|ty|
|
523
|
-
rest_ty =
|
524
|
-
base_type = Type::Instance.new(
|
555
|
+
_, path, lead_tys, rest_ty = ty
|
556
|
+
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
557
|
+
rest_ty = conv_type(rest_ty)
|
558
|
+
base_type = Type::Instance.new(path_to_klass(path))
|
525
559
|
Type::Array.new(Type::Array::Elements.new(lead_tys, rest_ty), base_type)
|
526
560
|
when :hash
|
527
|
-
_,
|
528
|
-
Type.gen_hash do |h|
|
529
|
-
k_ty =
|
530
|
-
v_ty =
|
561
|
+
_, path, (k, v) = ty
|
562
|
+
Type.gen_hash(Type::Instance.new(path_to_klass(path))) do |h|
|
563
|
+
k_ty = conv_type(k)
|
564
|
+
v_ty = conv_type(v)
|
531
565
|
h[k_ty] = v_ty
|
532
566
|
end
|
533
567
|
when :union
|
534
|
-
tys = ty[1]
|
535
|
-
Type::Union.new(Utils::Set[*tys.map {|ty2|
|
536
|
-
when :optional
|
537
|
-
Type.optional(convert_type(scratch, ty[1]))
|
568
|
+
tys = ty[1]
|
569
|
+
Type::Union.new(Utils::Set[*tys.map {|ty2| conv_type(ty2) }], nil) # XXX: Array and Hash support
|
538
570
|
when :var
|
539
|
-
Type::Var.new(ty[1])
|
571
|
+
Type::Var.new(ty[1])
|
540
572
|
else
|
541
573
|
pp ty
|
542
574
|
raise NotImplementedError
|
543
575
|
end
|
544
576
|
end
|
577
|
+
|
578
|
+
def path_to_klass(path)
|
579
|
+
klass = Type::Builtin[:obj]
|
580
|
+
path.each do |name|
|
581
|
+
klass = @scratch.get_constant(klass, name)
|
582
|
+
raise path.inspect if klass == Type.any
|
583
|
+
end
|
584
|
+
klass
|
585
|
+
end
|
545
586
|
end
|
546
587
|
end
|