typeprof 0.1.2 → 0.4.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/.gitignore +3 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +10 -21
- data/LICENSE +21 -0
- data/README.md +1 -1
- data/doc/demo.md +398 -0
- data/doc/doc.ja.md +11 -1
- data/doc/doc.md +16 -7
- data/exe/typeprof +2 -1
- data/lib/typeprof.rb +9 -0
- data/lib/typeprof/analyzer.rb +455 -364
- data/lib/typeprof/arguments.rb +397 -0
- data/lib/typeprof/block.rb +133 -0
- data/lib/typeprof/builtin.rb +125 -116
- data/lib/typeprof/cli.rb +62 -71
- data/lib/typeprof/config.rb +114 -0
- data/lib/typeprof/container-type.rb +208 -27
- data/lib/typeprof/export.rb +201 -96
- data/lib/typeprof/import.rb +451 -365
- data/lib/typeprof/iseq.rb +43 -2
- data/lib/typeprof/method.rb +139 -100
- data/lib/typeprof/type.rb +138 -297
- data/lib/typeprof/utils.rb +4 -18
- data/lib/typeprof/version.rb +3 -0
- data/smoke/arguments2.rb +55 -0
- data/smoke/array-each3.rb +1 -4
- data/smoke/array12.rb +1 -1
- data/smoke/array6.rb +1 -0
- data/smoke/block-ambiguous.rb +36 -0
- data/smoke/block-args1-rest.rb +62 -0
- data/smoke/block-args1.rb +59 -0
- data/smoke/block-args2-rest.rb +62 -0
- data/smoke/block-args2.rb +59 -0
- data/smoke/block-args3-rest.rb +73 -0
- data/smoke/block-args3.rb +70 -0
- data/smoke/block-blockarg.rb +27 -0
- data/smoke/block-kwarg.rb +52 -0
- data/smoke/block11.rb +1 -1
- data/smoke/block13.rb +9 -0
- data/smoke/block13.rbs +3 -0
- data/smoke/block14.rb +17 -0
- data/smoke/block4.rb +2 -2
- data/smoke/block5.rb +1 -0
- data/smoke/block6.rb +1 -1
- data/smoke/block7.rb +0 -2
- data/smoke/block8.rb +2 -2
- data/smoke/block9.rb +1 -1
- data/smoke/blown.rb +1 -1
- data/smoke/class-hierarchy.rb +54 -0
- data/smoke/class-hierarchy2.rb +27 -0
- data/smoke/class.rb +2 -0
- data/smoke/constant1.rb +13 -5
- data/smoke/constant2.rb +2 -0
- data/smoke/cvar.rb +1 -0
- data/smoke/demo10.rb +1 -1
- data/smoke/demo5.rb +3 -0
- data/smoke/demo8.rb +2 -2
- data/smoke/demo9.rb +1 -3
- data/smoke/flow7.rb +1 -7
- data/smoke/flow8.rb +13 -0
- data/smoke/gvar.rb +1 -1
- data/smoke/gvar2.rb +17 -0
- data/smoke/gvar2.rbs +1 -0
- data/smoke/hash4.rb +1 -1
- data/smoke/inheritance2.rb +6 -0
- data/smoke/instance_eval.rb +1 -1
- data/smoke/int_times.rb +1 -1
- data/smoke/ivar3.rb +16 -0
- data/smoke/ivar3.rbs +3 -0
- data/smoke/keyword3.rb +1 -2
- data/smoke/keyword4.rb +1 -1
- 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 +5 -0
- data/smoke/multiple-superclass.rb +12 -0
- data/smoke/next2.rb +1 -1
- data/smoke/optional1.rb +1 -1
- data/smoke/optional2.rb +1 -1
- data/smoke/optional3.rb +10 -0
- data/smoke/proc4.rb +1 -1
- 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-extend.rb +9 -0
- data/smoke/rbs-extend.rbs +7 -0
- data/smoke/rbs-interface.rb +24 -0
- data/smoke/rbs-interface.rbs +12 -0
- data/smoke/rbs-proc1.rb +9 -0
- data/smoke/rbs-proc1.rbs +3 -0
- data/smoke/rbs-proc2.rb +20 -0
- data/smoke/rbs-proc2.rbs +3 -0
- data/smoke/rbs-proc3.rb +13 -0
- data/smoke/rbs-proc3.rbs +4 -0
- data/smoke/rbs-record.rb +17 -0
- data/smoke/rbs-record.rbs +4 -0
- data/smoke/rbs-tyvar.rb +18 -0
- data/smoke/rbs-tyvar.rbs +5 -0
- data/smoke/rbs-tyvar2.rb +20 -0
- data/smoke/rbs-tyvar2.rbs +9 -0
- data/smoke/rbs-tyvar3.rb +25 -0
- data/smoke/rbs-tyvar3.rbs +4 -0
- data/smoke/rbs-vars.rb +39 -0
- data/smoke/rbs-vars.rbs +7 -0
- data/smoke/rest1.rb +1 -1
- data/smoke/rest2.rb +1 -1
- data/smoke/rest3.rb +1 -1
- data/smoke/rest5.rb +1 -1
- data/smoke/rest6.rb +1 -1
- data/smoke/retry1.rb +1 -1
- data/smoke/return.rb +1 -1
- data/smoke/singleton_method.rb +3 -0
- data/smoke/step.rb +1 -1
- data/smoke/struct.rb +6 -2
- data/smoke/struct3.rb +14 -0
- data/smoke/super1.rb +18 -0
- data/smoke/symbol-proc.rb +24 -0
- data/smoke/union-recv.rb +6 -0
- data/smoke/user-demo.rb +15 -0
- data/smoke/wrong-extend.rb +1 -0
- data/tools/setup-insns-def.rb +1 -1
- data/tools/stackprof-wrapper.rb +1 -1
- data/typeprof.gemspec +12 -4
- metadata +68 -10
- data/.gitmodules +0 -6
- data/run.sh +0 -3
- data/smoke/variadic1.rb.notyet +0 -5
data/lib/typeprof/import.rb
CHANGED
|
@@ -3,208 +3,124 @@ 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
|
-
|
|
97
|
-
|
|
98
|
-
# topological sort
|
|
99
|
-
queue = class2super.keys.map {|name| [:visit, name] }
|
|
100
|
-
visited = {}
|
|
101
|
-
until queue.empty?
|
|
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
|
|
88
|
+
def conv_classes
|
|
89
|
+
json = {}
|
|
137
90
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
91
|
+
each_class_decl do |name, decls|
|
|
92
|
+
super_class_name = get_super_class_name(name, decls)
|
|
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 = []
|
|
98
|
+
extended_modules = []
|
|
143
99
|
methods = {}
|
|
100
|
+
ivars = {}
|
|
101
|
+
cvars = {}
|
|
144
102
|
rbs_sources = {}
|
|
145
|
-
type_params = nil
|
|
146
103
|
|
|
147
|
-
|
|
104
|
+
decls.each do |decl|
|
|
148
105
|
decl = decl.decl
|
|
149
|
-
|
|
106
|
+
|
|
150
107
|
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
|
|
108
|
+
raise "inconsistent type parameter declaration" if type_params && type_params != type_params2
|
|
109
|
+
type_params = type_params2
|
|
156
110
|
|
|
157
111
|
decl.members.each do |member|
|
|
158
112
|
case member
|
|
159
113
|
when RBS::AST::Members::MethodDefinition
|
|
160
114
|
name = member.name
|
|
161
115
|
|
|
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
116
|
method_types = member.types.map do |method_type|
|
|
199
117
|
case method_type
|
|
200
|
-
when RBS::MethodType
|
|
201
|
-
|
|
202
|
-
when :super
|
|
203
|
-
raise NotImplementedError
|
|
118
|
+
when RBS::MethodType then method_type
|
|
119
|
+
when :super then raise NotImplementedError
|
|
204
120
|
end
|
|
205
121
|
end
|
|
206
122
|
|
|
207
|
-
method_def =
|
|
123
|
+
method_def = conv_method_def(method_types)
|
|
208
124
|
rbs_source = [(member.kind == :singleton ? "self." : "") + member.name.to_s, member.types.map {|type| type.location.source }]
|
|
209
125
|
if member.instance?
|
|
210
126
|
methods[[false, name]] = method_def
|
|
@@ -214,8 +130,16 @@ module TypeProf
|
|
|
214
130
|
methods[[true, name]] = method_def
|
|
215
131
|
rbs_sources[[true, name]] = rbs_source
|
|
216
132
|
end
|
|
217
|
-
|
|
218
|
-
|
|
133
|
+
when RBS::AST::Members::AttrReader
|
|
134
|
+
ty = conv_type(member.type)
|
|
135
|
+
methods[[false, member.name]] = attr_reader_def(ty)
|
|
136
|
+
when RBS::AST::Members::AttrWriter
|
|
137
|
+
ty = conv_type(member.type)
|
|
138
|
+
methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
|
|
139
|
+
when RBS::AST::Members::AttrAccessor
|
|
140
|
+
ty = conv_type(member.type)
|
|
141
|
+
methods[[false, member.name]] = attr_reader_def(ty)
|
|
142
|
+
methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
|
|
219
143
|
when RBS::AST::Members::Alias
|
|
220
144
|
if member.instance?
|
|
221
145
|
method_def = methods[[false, member.old_name]]
|
|
@@ -225,322 +149,484 @@ module TypeProf
|
|
|
225
149
|
method_def = methods[[true, member.old_name]]
|
|
226
150
|
methods[[true, member.new_name]] = method_def if method_def
|
|
227
151
|
end
|
|
152
|
+
|
|
228
153
|
when RBS::AST::Members::Include
|
|
229
154
|
name = member.name
|
|
230
|
-
|
|
231
|
-
|
|
155
|
+
if name.kind == :class
|
|
156
|
+
mod = conv_type_name(name)
|
|
157
|
+
included_modules << mod
|
|
158
|
+
else
|
|
159
|
+
# including an interface is not supported yet
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
when RBS::AST::Members::Extend
|
|
163
|
+
name = member.name
|
|
164
|
+
if name.kind == :class
|
|
165
|
+
mod = conv_type_name(name)
|
|
166
|
+
extended_modules << mod
|
|
167
|
+
else
|
|
168
|
+
# extending a module with an interface is not supported yet
|
|
169
|
+
end
|
|
170
|
+
|
|
232
171
|
when RBS::AST::Members::InstanceVariable
|
|
172
|
+
ivars[member.name] = conv_type(member.type)
|
|
233
173
|
when RBS::AST::Members::ClassVariable
|
|
234
|
-
|
|
174
|
+
cvars[member.name] = conv_type(member.type)
|
|
175
|
+
|
|
176
|
+
when RBS::AST::Members::Public, RBS::AST::Members::Private # XXX
|
|
177
|
+
|
|
178
|
+
# The following declarations are ignoreable because they are handled in other level
|
|
235
179
|
when RBS::AST::Declarations::Constant
|
|
236
|
-
when RBS::AST::Declarations::Alias
|
|
180
|
+
when RBS::AST::Declarations::Alias # type alias
|
|
181
|
+
when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module
|
|
182
|
+
when RBS::AST::Declarations::Interface
|
|
183
|
+
|
|
237
184
|
else
|
|
238
185
|
warn "Importing #{ member.class.name } is not supported yet"
|
|
239
|
-
#p member
|
|
240
186
|
end
|
|
241
187
|
end
|
|
242
188
|
end
|
|
243
189
|
|
|
244
|
-
|
|
245
|
-
|
|
190
|
+
json[klass] = {
|
|
191
|
+
type_params: type_params,
|
|
192
|
+
superclass: superclass,
|
|
193
|
+
members: {
|
|
194
|
+
included_modules: included_modules,
|
|
195
|
+
extended_modules: extended_modules,
|
|
196
|
+
methods: methods,
|
|
197
|
+
ivars: ivars,
|
|
198
|
+
cvars: cvars,
|
|
199
|
+
rbs_sources: rbs_sources,
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
end
|
|
246
203
|
|
|
247
|
-
|
|
204
|
+
json
|
|
248
205
|
end
|
|
249
206
|
|
|
250
|
-
def
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
207
|
+
def each_class_decl
|
|
208
|
+
# topological sort
|
|
209
|
+
# * superclasses and modules appear earlier than their subclasses (Object is earlier than String)
|
|
210
|
+
# * namespace module appers earlier than its children (Process is earlier than Process::Status)
|
|
211
|
+
visited = {}
|
|
212
|
+
queue = @cur_env.class_decls.keys.map {|name| [:visit, name] }
|
|
213
|
+
until queue.empty?
|
|
214
|
+
event, name = queue.pop
|
|
215
|
+
case event
|
|
216
|
+
when :visit
|
|
217
|
+
if !visited[name]
|
|
218
|
+
visited[name] = true
|
|
219
|
+
queue << [:new, name]
|
|
220
|
+
@all_env.class_decls[name].decls.each do |decl|
|
|
221
|
+
decl = decl.decl
|
|
222
|
+
next if decl.is_a?(RBS::AST::Declarations::Module)
|
|
223
|
+
each_ancestor(decl) {|name| queue << [:visit, name] }
|
|
224
|
+
end
|
|
225
|
+
queue << [:visit, name.namespace.to_type_name] if !name.namespace.empty?
|
|
226
|
+
end
|
|
227
|
+
when :new
|
|
228
|
+
decls = @cur_env.class_decls[name]
|
|
229
|
+
yield name, decls.decls if decls
|
|
256
230
|
end
|
|
257
|
-
|
|
231
|
+
end
|
|
258
232
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
233
|
+
@cur_env.interface_decls.each do |name, decl|
|
|
234
|
+
yield name, [decl]
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def each_ancestor(decl, &blk)
|
|
239
|
+
yield decl.name
|
|
240
|
+
super_class = decl.super_class || RBS::BuiltinNames::Object
|
|
241
|
+
return if decl.name == RBS::BuiltinNames::BasicObject.name
|
|
242
|
+
return if decl.name == super_class.name
|
|
243
|
+
@all_env.class_decls[super_class.name].decls.each do |decl|
|
|
244
|
+
each_ancestor(decl.decl, &blk)
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def get_super_class_name(name, decls)
|
|
249
|
+
return nil if name == RBS::BuiltinNames::BasicObject.name
|
|
276
250
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
251
|
+
decls.each do |decl|
|
|
252
|
+
decl = decl.decl
|
|
253
|
+
case decl
|
|
254
|
+
when RBS::AST::Declarations::Class
|
|
255
|
+
return decl.super_class.name if decl.super_class
|
|
256
|
+
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
|
|
257
|
+
return nil
|
|
258
|
+
else
|
|
259
|
+
raise "unknown declaration: %p" % decl.class
|
|
281
260
|
end
|
|
282
|
-
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
return RBS::BuiltinNames::Object.name
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def conv_method_def(rbs_method_types)
|
|
267
|
+
rbs_method_types.map do |method_type|
|
|
268
|
+
conv_func(method_type.type_params, method_type.type, method_type.block)
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def conv_func(type_params, func, block)
|
|
273
|
+
blk = block ? conv_block(block) : nil
|
|
274
|
+
|
|
275
|
+
lead_tys = func.required_positionals.map {|type| conv_type(type.type) }
|
|
276
|
+
opt_tys = func.optional_positionals.map {|type| conv_type(type.type) }
|
|
277
|
+
rest_ty = func.rest_positionals
|
|
278
|
+
rest_ty = conv_type(rest_ty.type) if rest_ty
|
|
279
|
+
opt_kw_tys = func.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
|
280
|
+
req_kw_tys = func.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
|
281
|
+
rest_kw_ty = func.rest_keywords
|
|
282
|
+
raise NotImplementedError if rest_kw_ty # XXX
|
|
283
|
+
|
|
284
|
+
ret_ty = conv_type(func.return_type)
|
|
285
|
+
|
|
286
|
+
{
|
|
287
|
+
type_params: type_params,
|
|
288
|
+
lead_tys: lead_tys,
|
|
289
|
+
opt_tys: opt_tys,
|
|
290
|
+
rest_ty: rest_ty,
|
|
291
|
+
req_kw_tys: req_kw_tys,
|
|
292
|
+
opt_kw_tys: opt_kw_tys,
|
|
293
|
+
rest_kw_ty: rest_kw_ty,
|
|
294
|
+
blk: blk,
|
|
295
|
+
ret_ty: ret_ty,
|
|
296
|
+
}
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def attr_reader_def(ty)
|
|
300
|
+
[{
|
|
301
|
+
type_params: [],
|
|
302
|
+
lead_tys: [],
|
|
303
|
+
opt_tys: [],
|
|
304
|
+
rest_ty: nil,
|
|
305
|
+
req_kw_tys: {},
|
|
306
|
+
opt_kw_tys: {},
|
|
307
|
+
rest_kw_ty: nil,
|
|
308
|
+
blk: nil,
|
|
309
|
+
ret_ty: ty,
|
|
310
|
+
}]
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def attr_writer_def(ty)
|
|
314
|
+
[{
|
|
315
|
+
type_params: [],
|
|
316
|
+
lead_tys: [ty],
|
|
317
|
+
opt_tys: [],
|
|
318
|
+
rest_ty: nil,
|
|
319
|
+
req_kw_tys: {},
|
|
320
|
+
opt_kw_tys: {},
|
|
321
|
+
rest_kw_ty: nil,
|
|
322
|
+
blk: nil,
|
|
323
|
+
ret_ty: ty,
|
|
324
|
+
}]
|
|
283
325
|
end
|
|
284
326
|
|
|
285
|
-
def
|
|
286
|
-
type =
|
|
327
|
+
def conv_block(rbs_block)
|
|
328
|
+
type = rbs_block.type
|
|
329
|
+
|
|
330
|
+
# XXX
|
|
287
331
|
raise NotImplementedError unless type.optional_keywords.empty?
|
|
288
332
|
raise NotImplementedError unless type.required_keywords.empty?
|
|
289
|
-
raise NotImplementedError unless type.optional_positionals.empty?
|
|
290
333
|
raise NotImplementedError if type.rest_keywords
|
|
334
|
+
|
|
335
|
+
req = rbs_block.required
|
|
336
|
+
|
|
291
337
|
lead_tys = type.required_positionals.map do |type|
|
|
292
|
-
|
|
338
|
+
conv_type(type.type)
|
|
293
339
|
end
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
340
|
+
opt_tys = type.optional_positionals.map do |type|
|
|
341
|
+
conv_type(type.type)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
ret_ty = conv_type(type.return_type)
|
|
297
345
|
|
|
298
|
-
|
|
346
|
+
[req, lead_tys, opt_tys, ret_ty]
|
|
299
347
|
end
|
|
300
348
|
|
|
301
|
-
def
|
|
349
|
+
def conv_type(ty)
|
|
302
350
|
case ty
|
|
303
351
|
when RBS::Types::ClassSingleton
|
|
304
|
-
|
|
305
|
-
[:class, klass]
|
|
352
|
+
[:class, conv_type_name(ty.name)]
|
|
306
353
|
when RBS::Types::ClassInstance
|
|
307
|
-
klass = ty.name
|
|
354
|
+
klass = conv_type_name(ty.name)
|
|
308
355
|
case klass
|
|
309
356
|
when [:Array]
|
|
310
357
|
raise if ty.args.size != 1
|
|
311
|
-
[:array, :Array, [],
|
|
358
|
+
[:array, [:Array], [], conv_type(ty.args.first)]
|
|
312
359
|
when [:Hash]
|
|
313
360
|
raise if ty.args.size != 2
|
|
314
361
|
key, val = ty.args
|
|
315
|
-
[:hash, :Hash, [
|
|
362
|
+
[:hash, [:Hash], [conv_type(key), conv_type(val)]]
|
|
316
363
|
when [:Enumerator]
|
|
317
364
|
raise if ty.args.size != 2
|
|
318
|
-
[:array, :Enumerator, [],
|
|
365
|
+
[:array, [:Enumerator], [], conv_type(ty.args.first)]
|
|
319
366
|
else
|
|
320
367
|
[:instance, klass]
|
|
321
368
|
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]
|
|
369
|
+
when RBS::Types::Bases::Bool then [:bool]
|
|
370
|
+
when RBS::Types::Bases::Any then [:any]
|
|
371
|
+
when RBS::Types::Bases::Void then [:void]
|
|
372
|
+
when RBS::Types::Bases::Self then [:self]
|
|
373
|
+
when RBS::Types::Bases::Nil then [:nil]
|
|
374
|
+
when RBS::Types::Bases::Bottom then [:union, []]
|
|
375
|
+
when RBS::Types::Variable then [:var, ty.name]
|
|
336
376
|
when RBS::Types::Tuple
|
|
337
|
-
tys = ty.types.map {|ty2|
|
|
338
|
-
[:array, :Array, tys, [:union, []]]
|
|
377
|
+
tys = ty.types.map {|ty2| conv_type(ty2) }
|
|
378
|
+
[:array, [:Array], tys, [:union, []]]
|
|
339
379
|
when RBS::Types::Literal
|
|
340
380
|
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]
|
|
381
|
+
when Integer then [:int]
|
|
382
|
+
when String then [:str]
|
|
383
|
+
when true then [:true]
|
|
384
|
+
when false then [:false]
|
|
385
|
+
when Symbol then [:sym, ty.literal]
|
|
351
386
|
else
|
|
352
387
|
p ty.literal
|
|
353
388
|
raise NotImplementedError
|
|
354
389
|
end
|
|
355
390
|
when RBS::Types::Alias
|
|
356
391
|
alias_decl = @all_env.alias_decls[ty.name]
|
|
357
|
-
alias_decl ?
|
|
392
|
+
alias_decl ? conv_type(alias_decl.decl.type) : [:any]
|
|
358
393
|
when RBS::Types::Union
|
|
359
|
-
[:union, ty.types.map {|ty2|
|
|
394
|
+
[:union, ty.types.map {|ty2| conv_type(ty2) }.compact]
|
|
360
395
|
when RBS::Types::Optional
|
|
361
|
-
[:optional,
|
|
362
|
-
when RBS::Types::Record
|
|
363
|
-
[:any]
|
|
396
|
+
[:optional, conv_type(ty.type)]
|
|
364
397
|
when RBS::Types::Interface
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
398
|
+
# XXX: Currently, only a few builtin interfaces are supported
|
|
399
|
+
case ty.to_s
|
|
400
|
+
when "::_ToStr" then [:str]
|
|
401
|
+
when "::_ToInt" then [:int]
|
|
402
|
+
when "::_ToAry[U]" then [:array, [:Array], [], [:var, :U]]
|
|
403
|
+
else
|
|
404
|
+
[:instance, conv_type_name(ty.name)]
|
|
369
405
|
end
|
|
370
|
-
|
|
406
|
+
when RBS::Types::Bases::Instance then [:any] # XXX: not implemented yet
|
|
407
|
+
when RBS::Types::Record
|
|
408
|
+
[:hash_record, [:Hash], ty.fields.map {|key, ty| [key, conv_type(ty)] }]
|
|
409
|
+
when RBS::Types::Proc
|
|
410
|
+
[:proc, conv_func(nil, ty.type, nil)]
|
|
371
411
|
else
|
|
372
|
-
|
|
373
|
-
|
|
412
|
+
warn "unknown RBS type: %p" % ty.class
|
|
413
|
+
[:any]
|
|
374
414
|
end
|
|
375
415
|
end
|
|
376
|
-
end
|
|
377
|
-
|
|
378
|
-
module RubySignatureImporter
|
|
379
|
-
module_function
|
|
380
416
|
|
|
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
|
|
417
|
+
def conv_type_name(name)
|
|
418
|
+
name.namespace.path + [name.name]
|
|
388
419
|
end
|
|
420
|
+
end
|
|
389
421
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
import_ruby_signature(scratch, scratch.rbs_reader.load_builtin)
|
|
422
|
+
class Import
|
|
423
|
+
def self.import_builtin(scratch)
|
|
424
|
+
Import.new(scratch, scratch.rbs_reader.load_builtin).import
|
|
394
425
|
end
|
|
395
426
|
|
|
396
|
-
def import_library(scratch, feature)
|
|
427
|
+
def self.import_library(scratch, feature)
|
|
428
|
+
begin
|
|
429
|
+
json = scratch.rbs_reader.load_library(feature)
|
|
430
|
+
rescue RBS::EnvironmentLoader::UnknownLibraryNameError
|
|
431
|
+
return nil
|
|
432
|
+
end
|
|
397
433
|
# need cache?
|
|
398
|
-
|
|
399
|
-
rescue RBS::EnvironmentLoader::UnknownLibraryNameError
|
|
400
|
-
false
|
|
434
|
+
Import.new(scratch, json).import
|
|
401
435
|
end
|
|
402
436
|
|
|
403
|
-
def import_rbs_file(scratch, rbs_path)
|
|
404
|
-
|
|
437
|
+
def self.import_rbs_file(scratch, rbs_path)
|
|
438
|
+
rbs_path = Pathname(rbs_path) unless rbs_path.is_a?(Pathname)
|
|
439
|
+
Import.new(scratch, scratch.rbs_reader.load_path(rbs_path)).import(true)
|
|
405
440
|
end
|
|
406
441
|
|
|
407
|
-
def
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
442
|
+
def initialize(scratch, json)
|
|
443
|
+
@scratch = scratch
|
|
444
|
+
@json = json
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
def import(explicit = false)
|
|
448
|
+
classes = @json[:classes].map do |classpath, cdef|
|
|
449
|
+
type_params = cdef[:type_params]
|
|
450
|
+
superclass = cdef[:superclass]
|
|
451
|
+
members = cdef[:members]
|
|
452
|
+
|
|
453
|
+
name = classpath.last
|
|
454
|
+
superclass = path_to_klass(superclass) if superclass
|
|
455
|
+
base_klass = path_to_klass(classpath[0..-2])
|
|
456
|
+
|
|
457
|
+
klass = @scratch.get_constant(base_klass, name)
|
|
458
|
+
if klass.is_a?(Type::Any)
|
|
459
|
+
klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
|
|
460
|
+
|
|
461
|
+
# There builtin classes are needed to interpret RBS declarations
|
|
462
|
+
case classpath
|
|
463
|
+
when [:NilClass] then Type::Builtin[:nil] = klass
|
|
464
|
+
when [:TrueClass] then Type::Builtin[:true] = klass
|
|
465
|
+
when [:FalseClass] then Type::Builtin[:false] = klass
|
|
466
|
+
when [:Integer] then Type::Builtin[:int] = klass
|
|
467
|
+
when [:String] then Type::Builtin[:str] = klass
|
|
468
|
+
when [:Symbol] then Type::Builtin[:sym] = klass
|
|
469
|
+
when [:Array] then Type::Builtin[:ary] = klass
|
|
470
|
+
when [:Hash] then Type::Builtin[:hash] = klass
|
|
471
|
+
when [:Proc] then Type::Builtin[:proc] = klass
|
|
428
472
|
end
|
|
429
473
|
end
|
|
430
|
-
|
|
474
|
+
|
|
475
|
+
[klass, members]
|
|
431
476
|
end
|
|
432
477
|
|
|
433
|
-
classes.each do |klass,
|
|
478
|
+
classes.each do |klass, members|
|
|
479
|
+
included_modules = members[:included_modules]
|
|
480
|
+
extended_modules = members[:extended_modules]
|
|
481
|
+
methods = members[:methods]
|
|
482
|
+
ivars = members[:ivars]
|
|
483
|
+
cvars = members[:cvars]
|
|
484
|
+
rbs_sources = members[:rbs_sources]
|
|
485
|
+
|
|
434
486
|
included_modules.each do |mod|
|
|
435
|
-
|
|
436
|
-
|
|
487
|
+
@scratch.include_module(klass, path_to_klass(mod), nil)
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
extended_modules.each do |mod|
|
|
491
|
+
@scratch.extend_module(klass, path_to_klass(mod), nil)
|
|
437
492
|
end
|
|
493
|
+
|
|
438
494
|
methods.each do |(singleton, method_name), mdef|
|
|
439
|
-
rbs_source = nil
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
495
|
+
rbs_source = explicit ? rbs_sources[[singleton, method_name]] : nil
|
|
496
|
+
mdef = conv_method_def(method_name, mdef, rbs_source)
|
|
497
|
+
@scratch.add_method(klass, method_name, singleton, mdef)
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
ivars.each do |ivar_name, ty|
|
|
501
|
+
ty = conv_type(ty)
|
|
502
|
+
@scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
|
|
443
503
|
end
|
|
504
|
+
|
|
505
|
+
cvars.each do |ivar_name, ty|
|
|
506
|
+
ty = conv_type(ty)
|
|
507
|
+
@scratch.add_cvar_write!(klass, ivar_name, ty, nil)
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
@json[:constants].each do |classpath, value|
|
|
512
|
+
base_klass = path_to_klass(classpath[0..-2])
|
|
513
|
+
value = conv_type(value)
|
|
514
|
+
@scratch.add_constant(base_klass, classpath[-1], value, nil)
|
|
444
515
|
end
|
|
445
516
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
value = convert_type(scratch, value)
|
|
449
|
-
scratch.add_constant(base_klass, classpath[-1], value)
|
|
517
|
+
@json[:globals].each do |name, value|
|
|
518
|
+
@scratch.add_gvar_write!(name, conv_type(value), nil)
|
|
450
519
|
end
|
|
451
520
|
|
|
452
521
|
true
|
|
453
522
|
end
|
|
454
523
|
|
|
455
|
-
def
|
|
456
|
-
sig_rets = mdef.
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
else
|
|
460
|
-
blk = Type::Instance.new(scratch.get_constant(Type::Builtin[:obj], :NilClass))
|
|
461
|
-
end
|
|
462
|
-
|
|
463
|
-
begin
|
|
464
|
-
lead_tys = lead_tys.map {|ty| convert_type(scratch, ty) }
|
|
465
|
-
opt_tys = opt_tys.map {|ty| convert_type(scratch, ty) }
|
|
466
|
-
rest_ty = convert_type(scratch, rest_ty) if rest_ty
|
|
467
|
-
kw_tys = []
|
|
468
|
-
req_kw_tys.each {|key, ty| kw_tys << [true, key, convert_type(scratch, ty)] }
|
|
469
|
-
opt_kw_tys.each {|key, ty| kw_tys << [false, key, convert_type(scratch, ty)] }
|
|
470
|
-
kw_rest_ty = convert_type(scratch, rest_kw_ty) if rest_kw_ty
|
|
471
|
-
fargs = FormalArguments.new(lead_tys, opt_tys, rest_ty, [], kw_tys, kw_rest_ty, blk)
|
|
472
|
-
ret_ty = convert_type(scratch, ret_ty)
|
|
473
|
-
[fargs, ret_ty]
|
|
474
|
-
rescue UnsupportedType
|
|
475
|
-
nil
|
|
476
|
-
end
|
|
477
|
-
end.compact
|
|
524
|
+
def conv_method_def(method_name, mdef, rbs_source)
|
|
525
|
+
sig_rets = mdef.flat_map do |sig_ret|
|
|
526
|
+
conv_func(sig_ret)
|
|
527
|
+
end
|
|
478
528
|
|
|
479
529
|
TypedMethodDef.new(sig_rets, rbs_source)
|
|
480
530
|
end
|
|
481
531
|
|
|
482
|
-
def
|
|
483
|
-
|
|
484
|
-
lead_tys = lead_tys
|
|
485
|
-
|
|
486
|
-
|
|
532
|
+
def conv_func(sig_ret)
|
|
533
|
+
#type_params = sig_ret[:type_params] # XXX
|
|
534
|
+
lead_tys = sig_ret[:lead_tys]
|
|
535
|
+
opt_tys = sig_ret[:opt_tys]
|
|
536
|
+
rest_ty = sig_ret[:rest_ty]
|
|
537
|
+
req_kw_tys = sig_ret[:req_kw_tys]
|
|
538
|
+
opt_kw_tys = sig_ret[:opt_kw_tys]
|
|
539
|
+
rest_kw_ty = sig_ret[:rest_kw_ty]
|
|
540
|
+
blk = sig_ret[:blk]
|
|
541
|
+
ret_ty = sig_ret[:ret_ty]
|
|
542
|
+
|
|
543
|
+
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
|
544
|
+
opt_tys = opt_tys.map {|ty| conv_type(ty) }
|
|
545
|
+
rest_ty = conv_type(rest_ty) if rest_ty
|
|
546
|
+
kw_tys = []
|
|
547
|
+
req_kw_tys.each {|key, ty| kw_tys << [true, key, conv_type(ty)] }
|
|
548
|
+
opt_kw_tys.each {|key, ty| kw_tys << [false, key, conv_type(ty)] }
|
|
549
|
+
kw_rest_ty = conv_type(rest_kw_ty) if rest_kw_ty
|
|
550
|
+
|
|
551
|
+
blks = conv_block(blk)
|
|
552
|
+
|
|
553
|
+
ret_ty = conv_type(ret_ty)
|
|
554
|
+
|
|
555
|
+
blks.map do |blk|
|
|
556
|
+
[MethodSignature.new(lead_tys, opt_tys, rest_ty, [], kw_tys, kw_rest_ty, blk), ret_ty]
|
|
557
|
+
end
|
|
487
558
|
end
|
|
488
559
|
|
|
489
|
-
|
|
560
|
+
def conv_block(blk)
|
|
561
|
+
return [Type.nil] unless blk
|
|
562
|
+
req, lead_tys, opt_tys, ret_ty = blk
|
|
563
|
+
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
|
564
|
+
opt_tys = opt_tys.map {|ty| conv_type(ty) }
|
|
565
|
+
msig = MethodSignature.new(lead_tys, opt_tys, nil, nil, nil, nil, nil)
|
|
566
|
+
ret_ty = conv_type(ret_ty)
|
|
567
|
+
ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])]
|
|
568
|
+
ret << Type.nil unless req
|
|
569
|
+
ret
|
|
490
570
|
end
|
|
491
571
|
|
|
492
|
-
def
|
|
572
|
+
def conv_type(ty)
|
|
493
573
|
case ty.first
|
|
494
|
-
when :class
|
|
495
|
-
|
|
496
|
-
when :
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
when :
|
|
503
|
-
|
|
504
|
-
when :
|
|
505
|
-
|
|
506
|
-
when :
|
|
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])
|
|
574
|
+
when :class then path_to_klass(ty[1])
|
|
575
|
+
when :instance then Type::Instance.new(path_to_klass(ty[1]))
|
|
576
|
+
when :any then Type.any
|
|
577
|
+
when :void then Type::Void.new
|
|
578
|
+
when :nil then Type.nil
|
|
579
|
+
when :optional then Type.optional(conv_type(ty[1]))
|
|
580
|
+
when :bool then Type.bool
|
|
581
|
+
when :self then Type::Var.new(:self)
|
|
582
|
+
when :int then Type::Instance.new(Type::Builtin[:int])
|
|
583
|
+
when :str then Type::Instance.new(Type::Builtin[:str])
|
|
584
|
+
when :sym then Type::Symbol.new(ty.last, Type::Instance.new(Type::Builtin[:sym]))
|
|
585
|
+
when :true then Type::Instance.new(Type::Builtin[:true])
|
|
586
|
+
when :false then Type::Instance.new(Type::Builtin[:false])
|
|
520
587
|
when :array
|
|
521
|
-
_,
|
|
522
|
-
lead_tys = lead_tys.map {|ty|
|
|
523
|
-
rest_ty =
|
|
524
|
-
base_type = Type::Instance.new(
|
|
588
|
+
_, path, lead_tys, rest_ty = ty
|
|
589
|
+
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
|
590
|
+
rest_ty = conv_type(rest_ty)
|
|
591
|
+
base_type = Type::Instance.new(path_to_klass(path))
|
|
525
592
|
Type::Array.new(Type::Array::Elements.new(lead_tys, rest_ty), base_type)
|
|
526
593
|
when :hash
|
|
527
|
-
_,
|
|
528
|
-
Type.gen_hash do |h|
|
|
529
|
-
k_ty =
|
|
530
|
-
v_ty =
|
|
594
|
+
_, path, (k, v) = ty
|
|
595
|
+
Type.gen_hash(Type::Instance.new(path_to_klass(path))) do |h|
|
|
596
|
+
k_ty = conv_type(k)
|
|
597
|
+
v_ty = conv_type(v)
|
|
531
598
|
h[k_ty] = v_ty
|
|
532
599
|
end
|
|
600
|
+
when :hash_record
|
|
601
|
+
_, path, key_tys = ty
|
|
602
|
+
Type.gen_hash(Type::Instance.new(path_to_klass(path))) do |h|
|
|
603
|
+
key_tys.each do |key, ty|
|
|
604
|
+
k_ty = Type::Symbol.new(key, Type::Instance.new(Type::Builtin[:sym]))
|
|
605
|
+
v_ty = conv_type(ty)
|
|
606
|
+
h[k_ty] = v_ty
|
|
607
|
+
end
|
|
608
|
+
end
|
|
533
609
|
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]))
|
|
610
|
+
tys = ty[1]
|
|
611
|
+
Type::Union.new(Utils::Set[*tys.map {|ty2| conv_type(ty2) }], nil) # XXX: Array and Hash support
|
|
538
612
|
when :var
|
|
539
|
-
Type::Var.new(ty[1])
|
|
613
|
+
Type::Var.new(ty[1])
|
|
614
|
+
when :proc
|
|
615
|
+
msig, ret_ty = conv_func(ty[1]).first # Currently, RBS Proc does not accept a block, so the size should be always one
|
|
616
|
+
Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Instance.new(Type::Builtin[:proc]))
|
|
540
617
|
else
|
|
541
618
|
pp ty
|
|
542
619
|
raise NotImplementedError
|
|
543
620
|
end
|
|
544
621
|
end
|
|
622
|
+
|
|
623
|
+
def path_to_klass(path)
|
|
624
|
+
klass = Type::Builtin[:obj]
|
|
625
|
+
path.each do |name|
|
|
626
|
+
klass = @scratch.get_constant(klass, name)
|
|
627
|
+
raise path.inspect if klass == Type.any
|
|
628
|
+
end
|
|
629
|
+
klass
|
|
630
|
+
end
|
|
545
631
|
end
|
|
546
632
|
end
|