typeprof 0.21.11 → 0.30.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -31
  3. data/bin/typeprof +5 -0
  4. data/doc/doc.ja.md +134 -0
  5. data/doc/doc.md +136 -0
  6. data/lib/typeprof/cli/cli.rb +178 -0
  7. data/lib/typeprof/cli.rb +3 -133
  8. data/lib/typeprof/code_range.rb +112 -0
  9. data/lib/typeprof/core/ast/base.rb +263 -0
  10. data/lib/typeprof/core/ast/call.rb +259 -0
  11. data/lib/typeprof/core/ast/const.rb +126 -0
  12. data/lib/typeprof/core/ast/control.rb +433 -0
  13. data/lib/typeprof/core/ast/meta.rb +150 -0
  14. data/lib/typeprof/core/ast/method.rb +339 -0
  15. data/lib/typeprof/core/ast/misc.rb +263 -0
  16. data/lib/typeprof/core/ast/module.rb +123 -0
  17. data/lib/typeprof/core/ast/pattern.rb +140 -0
  18. data/lib/typeprof/core/ast/sig_decl.rb +471 -0
  19. data/lib/typeprof/core/ast/sig_type.rb +663 -0
  20. data/lib/typeprof/core/ast/value.rb +319 -0
  21. data/lib/typeprof/core/ast/variable.rb +315 -0
  22. data/lib/typeprof/core/ast.rb +472 -0
  23. data/lib/typeprof/core/builtin.rb +146 -0
  24. data/lib/typeprof/core/env/method.rb +137 -0
  25. data/lib/typeprof/core/env/method_entity.rb +55 -0
  26. data/lib/typeprof/core/env/module_entity.rb +408 -0
  27. data/lib/typeprof/core/env/static_read.rb +155 -0
  28. data/lib/typeprof/core/env/type_alias_entity.rb +27 -0
  29. data/lib/typeprof/core/env/value_entity.rb +32 -0
  30. data/lib/typeprof/core/env.rb +366 -0
  31. data/lib/typeprof/core/graph/box.rb +998 -0
  32. data/lib/typeprof/core/graph/change_set.rb +224 -0
  33. data/lib/typeprof/core/graph/filter.rb +155 -0
  34. data/lib/typeprof/core/graph/vertex.rb +225 -0
  35. data/lib/typeprof/core/service.rb +514 -0
  36. data/lib/typeprof/core/type.rb +352 -0
  37. data/lib/typeprof/core/util.rb +81 -0
  38. data/lib/typeprof/core.rb +31 -0
  39. data/lib/typeprof/diagnostic.rb +35 -0
  40. data/lib/typeprof/lsp/messages.rb +415 -0
  41. data/lib/typeprof/lsp/server.rb +203 -0
  42. data/lib/typeprof/lsp/text.rb +69 -0
  43. data/lib/typeprof/lsp/util.rb +51 -0
  44. data/lib/typeprof/lsp.rb +4 -907
  45. data/lib/typeprof/version.rb +1 -1
  46. data/lib/typeprof.rb +4 -18
  47. data/typeprof.gemspec +5 -7
  48. metadata +47 -33
  49. data/.github/dependabot.yml +0 -6
  50. data/.github/workflows/main.yml +0 -39
  51. data/.gitignore +0 -9
  52. data/Gemfile +0 -17
  53. data/Gemfile.lock +0 -41
  54. data/Rakefile +0 -10
  55. data/exe/typeprof +0 -10
  56. data/lib/typeprof/analyzer.rb +0 -2598
  57. data/lib/typeprof/arguments.rb +0 -414
  58. data/lib/typeprof/block.rb +0 -176
  59. data/lib/typeprof/builtin.rb +0 -893
  60. data/lib/typeprof/code-range.rb +0 -177
  61. data/lib/typeprof/config.rb +0 -158
  62. data/lib/typeprof/container-type.rb +0 -912
  63. data/lib/typeprof/export.rb +0 -589
  64. data/lib/typeprof/import.rb +0 -852
  65. data/lib/typeprof/insns-def.rb +0 -65
  66. data/lib/typeprof/iseq.rb +0 -864
  67. data/lib/typeprof/method.rb +0 -355
  68. data/lib/typeprof/type.rb +0 -1140
  69. data/lib/typeprof/utils.rb +0 -212
  70. data/tools/coverage.rb +0 -14
  71. data/tools/setup-insns-def.rb +0 -30
  72. data/typeprof-lsp +0 -3
@@ -0,0 +1,155 @@
1
+ module TypeProf::Core
2
+ class StaticRead
3
+ def initialize(name)
4
+ @name = name
5
+ @followers = Set[]
6
+ @source_modules = Set[]
7
+ end
8
+
9
+ attr_reader :name, :followers
10
+
11
+ def propagate(genv)
12
+ @followers.each do |follower|
13
+ case follower
14
+ when ModuleEntity
15
+ genv.add_static_eval_queue(:parent_modules_changed, follower)
16
+ when ScopedStaticRead
17
+ follower.on_cbase_updated(genv)
18
+ when Box, IsAFilter
19
+ genv.add_run(follower)
20
+ else
21
+ raise follower.inspect
22
+ end
23
+ end
24
+ end
25
+
26
+ def destroy(genv)
27
+ @source_modules.each do |mod|
28
+ mod.static_reads[@name].delete(self) || raise
29
+ end
30
+ @source_modules.clear
31
+ end
32
+
33
+ def resolve(genv, cref, break_object)
34
+ destroy(genv)
35
+
36
+ first = true
37
+ while cref
38
+ scope = cref.cpath
39
+ mod = genv.resolve_cpath(scope)
40
+ genv.each_superclass(mod, false) do |mod, _singleton|
41
+ break if mod == genv.mod_object && break_object
42
+
43
+ unless @source_modules.include?(mod)
44
+ @source_modules << mod
45
+ (mod.static_reads[@name] ||= Set[]) << self
46
+ end
47
+
48
+ return if check_module(genv, mod)
49
+
50
+ break unless first
51
+ end
52
+ first = false
53
+ cref = cref.outer
54
+ end
55
+ resolution_failed(genv)
56
+ end
57
+ end
58
+
59
+ class BaseStaticRead < StaticRead
60
+ def initialize(genv, name, cref)
61
+ super(name)
62
+ @cref = cref
63
+ genv.add_static_eval_queue(:static_read_changed, self)
64
+ end
65
+
66
+ attr_reader :cref
67
+
68
+ def on_scope_updated(genv)
69
+ resolve(genv, @cref, false)
70
+ end
71
+ end
72
+
73
+ class ScopedStaticRead < StaticRead
74
+ def initialize(name, cbase)
75
+ super(name)
76
+ @cbase = cbase
77
+ @cbase.followers << self if @cbase
78
+ end
79
+
80
+ def on_cbase_updated(genv)
81
+ if @cbase && @cbase.cpath
82
+ resolve(genv, CRef.new(@cbase.cpath, :class, nil, nil), true)
83
+ else
84
+ resolution_failed(genv)
85
+ end
86
+ end
87
+ end
88
+
89
+ module ConstRead
90
+ def check_module(genv, mod)
91
+ cdef = mod.consts[@name]
92
+ if cdef && cdef.exist?
93
+ inner_mod = genv.resolve_cpath(mod.cpath + [@name]) # TODO
94
+ cpath = inner_mod.exist? ? inner_mod.cpath : nil
95
+ update_module(genv, cpath, cdef)
96
+ return true
97
+ end
98
+ return false
99
+ end
100
+
101
+ def resolution_failed(genv)
102
+ update_module(genv, nil, nil)
103
+ end
104
+
105
+ def update_module(genv, cpath, cdef)
106
+ if cpath != @cpath || cdef != @cdef
107
+ @cpath = cpath
108
+ @cdef = cdef
109
+ propagate(genv)
110
+ end
111
+ end
112
+
113
+ attr_reader :cpath, :cdef
114
+ end
115
+
116
+ class BaseConstRead < BaseStaticRead
117
+ include ConstRead
118
+ end
119
+
120
+ class ScopedConstRead < ScopedStaticRead
121
+ include ConstRead
122
+ end
123
+
124
+ module TypeAliasRead
125
+ def check_module(genv, mod)
126
+ tae = mod.type_aliases[@name]
127
+ if tae && tae.exist?
128
+ update_type_alias(genv, tae)
129
+ return true
130
+ end
131
+ return false
132
+ end
133
+
134
+ def resolution_failed(genv)
135
+ update_type_alias(genv, nil)
136
+ end
137
+
138
+ def update_type_alias(genv, tae)
139
+ if tae != @type_alias_entity
140
+ @type_alias_entity = tae
141
+ propagate(genv)
142
+ end
143
+ end
144
+
145
+ attr_reader :type_alias_entity
146
+ end
147
+
148
+ class BaseTypeAliasRead < BaseStaticRead
149
+ include TypeAliasRead
150
+ end
151
+
152
+ class ScopedTypeAliasRead < ScopedStaticRead
153
+ include TypeAliasRead
154
+ end
155
+ end
@@ -0,0 +1,27 @@
1
+ module TypeProf::Core
2
+ class TypeAliasEntity
3
+ def initialize
4
+ @decls = Set[]
5
+ @type = nil
6
+ end
7
+
8
+ attr_reader :decls, :type
9
+
10
+ def exist?
11
+ !@decls.empty?
12
+ end
13
+
14
+ def add_decl(decl)
15
+ @decls << decl
16
+ @type = decl.type unless @type
17
+ # TODO: report an error if there are duplicated declarations
18
+ end
19
+
20
+ def remove_decl(decl)
21
+ @decls.delete(decl) || raise
22
+ if @type == decl.type
23
+ @type = @decls.empty? ? nil : @decls.to_a.first.type
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ module TypeProf::Core
2
+ class ValueEntity
3
+ def initialize
4
+ @decls = Set[]
5
+ @defs = Set[]
6
+ @read_boxes = Set[]
7
+ @vtx = Vertex.new(self)
8
+ end
9
+
10
+ attr_reader :decls, :defs, :read_boxes, :vtx
11
+
12
+ def add_decl(decl)
13
+ @decls << decl
14
+ end
15
+
16
+ def remove_decl(decl)
17
+ @decls.delete(decl) || raise
18
+ end
19
+
20
+ def add_def(def_)
21
+ @defs << def_
22
+ end
23
+
24
+ def remove_def(def_)
25
+ @defs.delete(def_) || raise
26
+ end
27
+
28
+ def exist?
29
+ !@decls.empty? || !@defs.empty?
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,366 @@
1
+ module TypeProf::Core
2
+ class GlobalEnv
3
+ def initialize
4
+ @type_table = {}
5
+
6
+ @static_eval_queue = []
7
+
8
+ @run_queue = []
9
+ @run_queue_set = Set[]
10
+
11
+ @mod_object = ModuleEntity.new([])
12
+ @mod_object.inner_modules[:Object] = @mod_object
13
+
14
+ @mod_basic_object = resolve_cpath([:BasicObject])
15
+ @mod_class = resolve_cpath([:Class])
16
+ @mod_module = resolve_cpath([:Module])
17
+
18
+ @gvars = {}
19
+ @mod_ary = resolve_cpath([:Array])
20
+ @mod_hash = resolve_cpath([:Hash])
21
+ @mod_range = resolve_cpath([:Range])
22
+ @mod_str = resolve_cpath([:String])
23
+
24
+ @cls_type = Type::Instance.new(self, @mod_class, [])
25
+ @mod_type = Type::Instance.new(self, @mod_module, [])
26
+ @obj_type = Type::Instance.new(self, resolve_cpath([:Object]), [])
27
+ @nil_type = Type::Instance.new(self, resolve_cpath([:NilClass]), [])
28
+ @true_type = Type::Instance.new(self, resolve_cpath([:TrueClass]), [])
29
+ @false_type = Type::Instance.new(self, resolve_cpath([:FalseClass]), [])
30
+ @str_type = Type::Instance.new(self, resolve_cpath([:String]), [])
31
+ @int_type = Type::Instance.new(self, resolve_cpath([:Integer]), [])
32
+ @float_type = Type::Instance.new(self, resolve_cpath([:Float]), [])
33
+ @rational_type = Type::Instance.new(self, resolve_cpath([:Rational]), [])
34
+ @complex_type = Type::Instance.new(self, resolve_cpath([:Complex]), [])
35
+ @proc_type = Type::Instance.new(self, resolve_cpath([:Proc]), [])
36
+ @symbol_type = Type::Instance.new(self, resolve_cpath([:Symbol]), [])
37
+ @set_type = Type::Instance.new(self, resolve_cpath([:Set]), [])
38
+ @regexp_type = Type::Instance.new(self, resolve_cpath([:Regexp]), [])
39
+
40
+ @run_count = 0
41
+ end
42
+
43
+ attr_reader :type_table
44
+
45
+ attr_reader :mod_class, :mod_object, :mod_ary, :mod_hash, :mod_range, :mod_str
46
+ attr_reader :cls_type, :mod_type
47
+ attr_reader :obj_type, :nil_type, :true_type, :false_type, :str_type
48
+ attr_reader :int_type, :float_type, :rational_type, :complex_type
49
+ attr_reader :proc_type, :symbol_type, :set_type, :regexp_type
50
+
51
+ def gen_ary_type(elem_vtx)
52
+ Type::Instance.new(self, @mod_ary, [elem_vtx])
53
+ end
54
+
55
+ def gen_hash_type(key_vtx, val_vtx)
56
+ Type::Instance.new(self, @mod_hash, [key_vtx, val_vtx])
57
+ end
58
+
59
+ def gen_range_type(elem_vtx)
60
+ Type::Instance.new(self, @mod_range, [elem_vtx])
61
+ end
62
+
63
+ attr_accessor :run_count
64
+
65
+ def each_direct_superclass(mod, singleton)
66
+ while mod
67
+ yield mod, singleton
68
+ singleton, mod = get_superclass(singleton, mod)
69
+ end
70
+ end
71
+
72
+ def each_superclass(mod, singleton, &blk)
73
+ while mod
74
+ # TODO: prepended modules
75
+ yield mod, singleton
76
+ if singleton
77
+ # TODO: extended modules
78
+ else
79
+ each_included_module(mod, &blk)
80
+ end
81
+ singleton, mod = get_superclass(singleton, mod)
82
+ end
83
+ end
84
+
85
+ def each_included_module(mod, &blk)
86
+ mod.included_modules.each do |_inc_decl, inc_mod|
87
+ yield inc_mod, false
88
+ each_included_module(inc_mod, &blk)
89
+ end
90
+ end
91
+
92
+ def get_superclass(singleton, mod)
93
+ super_mod = mod.superclass
94
+ if super_mod
95
+ return [singleton, super_mod]
96
+ else
97
+ if mod == @mod_basic_object
98
+ if singleton
99
+ return [false, @mod_class]
100
+ else
101
+ return nil
102
+ end
103
+ elsif mod == @mod_module && !singleton
104
+ return nil
105
+ else
106
+ return [false, @mod_module]
107
+ end
108
+ end
109
+ end
110
+
111
+ def get_instance_type(mod, type_args, changes, base_ty_env, base_ty)
112
+ ty_env = base_ty_env.dup
113
+ if base_ty.is_a?(Type::Instance)
114
+ base_ty.mod.type_params.zip(base_ty.args) do |param, arg|
115
+ ty_env[param] = arg
116
+ end
117
+ end
118
+ args = mod.type_params.zip(type_args).map do |param, arg|
119
+ arg && changes ? arg.covariant_vertex(self, changes, ty_env) : Source.new
120
+ end
121
+ Type::Instance.new(self, mod, args)
122
+ end
123
+
124
+ def get_superclass_type(ty, changes, base_ty_env)
125
+ singleton, super_mod = get_superclass(ty.is_a?(Type::Singleton), ty.mod)
126
+ return unless super_mod
127
+
128
+ if singleton
129
+ Type::Singleton.new(self, super_mod)
130
+ else
131
+ get_instance_type(super_mod, ty.mod.superclass_type_args || [], changes, base_ty_env, ty)
132
+ end
133
+ end
134
+
135
+ def add_static_eval_queue(change_type, arg)
136
+ @static_eval_queue << [change_type, arg]
137
+ end
138
+
139
+ def define_all
140
+ until @static_eval_queue.empty?
141
+ change_type, arg = @static_eval_queue.shift
142
+ case change_type
143
+ when :inner_modules_changed
144
+ arg[0].on_inner_modules_changed(self, arg[1])
145
+ when :static_read_changed
146
+ case arg
147
+ when BaseStaticRead
148
+ arg.on_scope_updated(self)
149
+ when ScopedStaticRead
150
+ arg.on_cbase_updated(self)
151
+ else
152
+ raise
153
+ end
154
+ when :parent_modules_changed
155
+ arg.on_parent_modules_changed(self)
156
+ else
157
+ raise change_type.to_s
158
+ end
159
+ end
160
+ end
161
+
162
+ def add_run(obj)
163
+ unless @run_queue_set.include?(obj)
164
+ @run_queue << obj
165
+ @run_queue_set << obj
166
+ end
167
+ end
168
+
169
+ def run_all
170
+ run_count = 0
171
+ until @run_queue.empty?
172
+ obj = @run_queue.shift
173
+ @run_queue_set.delete(obj)
174
+ unless obj.destroyed
175
+ run_count += 1
176
+ obj.run(self)
177
+ end
178
+ end
179
+ @run_count += run_count
180
+ end
181
+
182
+ # just for validation
183
+ def get_vertexes(vtxs)
184
+ @mod_object.get_vertexes(vtxs)
185
+ @gvars.each_value do |gvar_entity|
186
+ vtxs << gvar_entity.vtx
187
+ end
188
+ end
189
+
190
+ # classes and modules
191
+
192
+ def resolve_cpath(cpath)
193
+ mod = @mod_object
194
+ raise unless cpath # annotation
195
+ cpath.each do |cname|
196
+ mod = mod.inner_modules[cname] ||= ModuleEntity.new(mod.cpath + [cname], mod)
197
+ end
198
+ mod
199
+ end
200
+
201
+ # constants
202
+
203
+ def resolve_const(cpath)
204
+ mod = resolve_cpath(cpath[0..-2])
205
+ mod.get_const(cpath[-1])
206
+ end
207
+
208
+ def resolve_method(cpath, singleton, mid)
209
+ mod = resolve_cpath(cpath)
210
+ mod.get_method(singleton, mid)
211
+ end
212
+
213
+ def resolve_gvar(name)
214
+ @gvars[name] ||= ValueEntity.new
215
+ end
216
+
217
+ def resolve_ivar(cpath, singleton, name)
218
+ # TODO: include はあとで考える
219
+ mod = resolve_cpath(cpath)
220
+ mod.get_ivar(singleton, name)
221
+ end
222
+
223
+ def resolve_cvar(cpath, name)
224
+ # TODO: include はあとで考える
225
+ mod = resolve_cpath(cpath)
226
+ mod.get_cvar(name)
227
+ end
228
+
229
+ def resolve_type_alias(cpath, name)
230
+ # TODO: include はあとで考える
231
+ mod = resolve_cpath(cpath)
232
+ mod.get_type_alias(name)
233
+ end
234
+
235
+ def load_core_rbs(raw_decls)
236
+ lenv = LocalEnv.new(nil, CRef::Toplevel, {}, [])
237
+ decls = raw_decls.map do |raw_decl|
238
+ AST.create_rbs_decl(raw_decl, lenv)
239
+ end.compact
240
+
241
+ decls += AST.parse_rbs("typeprof-rbs-shim.rbs", <<-RBS)
242
+ class Exception
243
+ include _Exception
244
+ end
245
+ class String
246
+ include _ToS
247
+ include _ToStr
248
+ end
249
+ class Array[Elem]
250
+ include _ToAry[Elem]
251
+ include _Each[Elem]
252
+ end
253
+ class Hash[K, V]
254
+ include _Each[[K, V]]
255
+ end
256
+ RBS
257
+
258
+ # Loading frequently used modules first will reduces constant resolution
259
+ # which makes loading faster :-)
260
+ critical_modules = [
261
+ decls.find {|decl| decl.cpath == [:Object] },
262
+ decls.find {|decl| decl.cpath == [:Module] },
263
+ decls.find {|decl| decl.cpath == [:Numeric] },
264
+ decls.find {|decl| decl.cpath == [:Integer] },
265
+ decls.find {|decl| decl.cpath == [:String] },
266
+ decls.find {|decl| decl.cpath == [:Array] },
267
+ decls.find {|decl| decl.cpath == [:Hash] },
268
+ decls.find {|decl| decl.cpath == [:Enumerator] },
269
+ ]
270
+ decls = critical_modules + (decls - critical_modules)
271
+
272
+ decls.each {|decl| decl.define(self) }
273
+ define_all
274
+ decls.each {|decl| decl.install(self) }
275
+ run_all
276
+ end
277
+ end
278
+
279
+ class LocalEnv
280
+ def initialize(path, cref, locals, return_boxes)
281
+ @path = path
282
+ @cref = cref
283
+ @locals = locals
284
+ @return_boxes = return_boxes
285
+ @break_vtx = nil
286
+ @next_boxes = []
287
+ @filters = {}
288
+ end
289
+
290
+ attr_reader :path, :cref, :locals, :return_boxes, :break_vtx, :next_boxes
291
+
292
+ def new_var(name, node)
293
+ @locals[name] = Vertex.new(node)
294
+ end
295
+
296
+ def set_var(name, vtx)
297
+ @locals[name] = vtx
298
+ end
299
+
300
+ def get_var(name)
301
+ @locals[name] || raise("#{ name }")
302
+ end
303
+
304
+ def exist_var?(name)
305
+ !!@locals[name]
306
+ end
307
+
308
+ def add_return_box(box)
309
+ @return_boxes << box
310
+ end
311
+
312
+ def add_next_box(box)
313
+ @next_boxes << box
314
+ end
315
+
316
+ def get_break_vtx
317
+ @break_vtx ||= Vertex.new(:break_vtx)
318
+ end
319
+
320
+
321
+ def push_read_filter(name, type)
322
+ (@filters[name] ||= []) << type
323
+ end
324
+
325
+ def pop_read_filter(name)
326
+ (@filters[name] ||= []).pop
327
+ end
328
+
329
+ def apply_read_filter(genv, node, name, vtx)
330
+ if @filters[name] && !@filters[name].empty?
331
+ case @filters[name].last
332
+ when :non_nil
333
+ return NilFilter.new(genv, node, vtx, false).next_vtx
334
+ end
335
+ end
336
+ vtx
337
+ end
338
+ end
339
+
340
+ class CRef
341
+ def initialize(cpath, scope_level, mid, outer)
342
+ @cpath = cpath
343
+ @scope_level = scope_level
344
+ @mid = mid
345
+ @outer = outer
346
+ end
347
+
348
+ attr_reader :cpath, :scope_level, :mid, :outer
349
+
350
+ def get_self(genv)
351
+ case @scope_level
352
+ when :instance
353
+ mod = genv.resolve_cpath(@cpath || [])
354
+ type_params = mod.type_params.map {|ty_param| Source.new() } # TODO: better support
355
+ ty = Type::Instance.new(genv, mod, type_params)
356
+ Source.new(ty)
357
+ when :class
358
+ Source.new(Type::Singleton.new(genv, genv.resolve_cpath(@cpath || [])))
359
+ else
360
+ Source.new()
361
+ end
362
+ end
363
+
364
+ Toplevel = self.new([], :instance, nil, nil)
365
+ end
366
+ end