typeprof 0.31.0 → 0.32.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/README.md +2 -1
- data/doc/report_guide.md +88 -0
- data/lib/typeprof/cli/cli.rb +9 -3
- data/lib/typeprof/code_range.rb +7 -5
- data/lib/typeprof/core/ast/base.rb +18 -6
- data/lib/typeprof/core/ast/call.rb +96 -32
- data/lib/typeprof/core/ast/const.rb +12 -9
- data/lib/typeprof/core/ast/control.rb +60 -30
- data/lib/typeprof/core/ast/meta.rb +194 -2
- data/lib/typeprof/core/ast/method.rb +74 -20
- data/lib/typeprof/core/ast/misc.rb +84 -7
- data/lib/typeprof/core/ast/module.rb +33 -3
- data/lib/typeprof/core/ast/sig_decl.rb +85 -24
- data/lib/typeprof/core/ast/sig_type.rb +78 -32
- data/lib/typeprof/core/ast/value.rb +14 -6
- data/lib/typeprof/core/ast/variable.rb +11 -4
- data/lib/typeprof/core/ast.rb +97 -14
- data/lib/typeprof/core/builtin.rb +184 -12
- data/lib/typeprof/core/env/method.rb +171 -6
- data/lib/typeprof/core/env/method_entity.rb +18 -15
- data/lib/typeprof/core/env/module_entity.rb +56 -18
- data/lib/typeprof/core/env/static_read.rb +4 -4
- data/lib/typeprof/core/env/type_alias_entity.rb +1 -1
- data/lib/typeprof/core/env/value_entity.rb +25 -3
- data/lib/typeprof/core/env.rb +81 -15
- data/lib/typeprof/core/graph/box.rb +380 -53
- data/lib/typeprof/core/graph/change_set.rb +59 -46
- data/lib/typeprof/core/graph/filter.rb +8 -5
- data/lib/typeprof/core/graph/vertex.rb +20 -19
- data/lib/typeprof/core/service.rb +317 -23
- data/lib/typeprof/core/type.rb +43 -8
- data/lib/typeprof/core/util.rb +6 -0
- data/lib/typeprof/lsp/messages.rb +5 -0
- data/lib/typeprof/lsp/server.rb +35 -4
- data/lib/typeprof/version.rb +1 -1
- metadata +3 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module TypeProf::Core
|
|
2
2
|
class ValueEntity
|
|
3
3
|
def initialize
|
|
4
|
-
@decls = Set
|
|
5
|
-
@defs = Set
|
|
6
|
-
@read_boxes = Set
|
|
4
|
+
@decls = Set.empty
|
|
5
|
+
@defs = Set.empty
|
|
6
|
+
@read_boxes = Set.empty
|
|
7
7
|
@vtx = Vertex.new(self)
|
|
8
8
|
end
|
|
9
9
|
|
|
@@ -17,6 +17,14 @@ module TypeProf::Core
|
|
|
17
17
|
@decls.delete(decl) || raise
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Re-run all read boxes that depend on this entity. Used when a
|
|
21
|
+
# declaration is added or removed so that dependents (e.g. an
|
|
22
|
+
# IVarReadBox that previously fell back to the inferred type) can
|
|
23
|
+
# observe the new state.
|
|
24
|
+
def on_decl_changed(genv)
|
|
25
|
+
@read_boxes.each {|box| genv.add_run(box) }
|
|
26
|
+
end
|
|
27
|
+
|
|
20
28
|
def add_def(def_)
|
|
21
29
|
@defs << def_
|
|
22
30
|
end
|
|
@@ -28,5 +36,19 @@ module TypeProf::Core
|
|
|
28
36
|
def exist?
|
|
29
37
|
!@decls.empty? || !@defs.empty?
|
|
30
38
|
end
|
|
39
|
+
|
|
40
|
+
def on_const_added(genv, cpath)
|
|
41
|
+
unless exist?
|
|
42
|
+
parent_mod = genv.resolve_cpath(cpath[0..-2])
|
|
43
|
+
genv.add_static_eval_queue(:inner_modules_changed, [parent_mod, cpath[-1]])
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def on_const_removed(genv, cpath)
|
|
48
|
+
unless exist?
|
|
49
|
+
parent_mod = genv.resolve_cpath(cpath[0..-2])
|
|
50
|
+
genv.add_static_eval_queue(:inner_modules_changed, [parent_mod, cpath[-1]])
|
|
51
|
+
end
|
|
52
|
+
end
|
|
31
53
|
end
|
|
32
54
|
end
|
data/lib/typeprof/core/env.rb
CHANGED
|
@@ -6,9 +6,9 @@ module TypeProf::Core
|
|
|
6
6
|
@static_eval_queue = []
|
|
7
7
|
|
|
8
8
|
@run_queue = []
|
|
9
|
-
@run_queue_set = Set
|
|
9
|
+
@run_queue_set = Set.empty
|
|
10
10
|
|
|
11
|
-
@pending_diagnostic_paths = Set
|
|
11
|
+
@pending_diagnostic_paths = Set.empty
|
|
12
12
|
|
|
13
13
|
@mod_object = ModuleEntity.new([])
|
|
14
14
|
@mod_object.inner_modules[:Object] = @mod_object
|
|
@@ -36,9 +36,12 @@ module TypeProf::Core
|
|
|
36
36
|
@complex_type = Type::Instance.new(self, resolve_cpath([:Complex]), [])
|
|
37
37
|
@proc_type = Type::Instance.new(self, resolve_cpath([:Proc]), [])
|
|
38
38
|
@symbol_type = Type::Instance.new(self, resolve_cpath([:Symbol]), [])
|
|
39
|
+
@method_type = Type::Instance.new(self, resolve_cpath([:Method]), [])
|
|
39
40
|
@set_type = Type::Instance.new(self, resolve_cpath([:Set]), [])
|
|
40
41
|
@regexp_type = Type::Instance.new(self, resolve_cpath([:Regexp]), [])
|
|
41
42
|
|
|
43
|
+
@bot_type = Type::Bot.new(self)
|
|
44
|
+
|
|
42
45
|
@run_count = 0
|
|
43
46
|
end
|
|
44
47
|
|
|
@@ -48,7 +51,8 @@ module TypeProf::Core
|
|
|
48
51
|
attr_reader :cls_type, :mod_type
|
|
49
52
|
attr_reader :obj_type, :nil_type, :true_type, :false_type, :str_type
|
|
50
53
|
attr_reader :int_type, :float_type, :rational_type, :complex_type
|
|
51
|
-
attr_reader :proc_type, :symbol_type, :set_type, :regexp_type
|
|
54
|
+
attr_reader :proc_type, :symbol_type, :method_type, :set_type, :regexp_type
|
|
55
|
+
attr_reader :bot_type
|
|
52
56
|
|
|
53
57
|
def gen_ary_type(elem_vtx)
|
|
54
58
|
Type::Instance.new(self, @mod_ary, [elem_vtx])
|
|
@@ -113,12 +117,20 @@ module TypeProf::Core
|
|
|
113
117
|
def get_instance_type(mod, type_args, changes, base_ty_env, base_ty)
|
|
114
118
|
ty_env = base_ty_env.dup
|
|
115
119
|
if base_ty.is_a?(Type::Instance)
|
|
116
|
-
base_ty.mod.type_params.zip(base_ty.args) do |param, arg|
|
|
117
|
-
ty_env[param] = arg || Source.new
|
|
120
|
+
base_ty.mod.type_params.zip(base_ty.args) do |(param, default_ty), arg|
|
|
121
|
+
ty_env[param] = arg || (default_ty ? default_ty.covariant_vertex(self, changes, ty_env) : Source.new)
|
|
122
|
+
end
|
|
123
|
+
elsif base_ty.is_a?(Type::Singleton)
|
|
124
|
+
base_ty.mod.type_params&.each do |(param, default_ty)|
|
|
125
|
+
ty_env[param] = default_ty ? default_ty.covariant_vertex(self, changes, ty_env) : Source.new
|
|
118
126
|
end
|
|
119
127
|
end
|
|
120
|
-
args = mod.type_params.zip(type_args).map do |param, arg|
|
|
121
|
-
|
|
128
|
+
args = mod.type_params.zip(type_args).map do |(param, default_ty), arg|
|
|
129
|
+
if changes
|
|
130
|
+
(arg || default_ty)&.covariant_vertex(self, changes, ty_env) || Source.new
|
|
131
|
+
else
|
|
132
|
+
Source.new
|
|
133
|
+
end
|
|
122
134
|
end
|
|
123
135
|
Type::Instance.new(self, mod, args)
|
|
124
136
|
end
|
|
@@ -209,6 +221,18 @@ module TypeProf::Core
|
|
|
209
221
|
raise unless cpath # annotation
|
|
210
222
|
cpath.each do |cname|
|
|
211
223
|
mod = mod.inner_modules[cname] ||= ModuleEntity.new(mod.cpath + [cname], mod)
|
|
224
|
+
mod = follow_alias(mod)
|
|
225
|
+
end
|
|
226
|
+
mod
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def follow_alias(mod)
|
|
230
|
+
visited = nil
|
|
231
|
+
while mod.alias_target
|
|
232
|
+
visited ||= Set.empty
|
|
233
|
+
break if visited.include?(mod) # cycle
|
|
234
|
+
visited << mod
|
|
235
|
+
mod = mod.alias_target
|
|
212
236
|
end
|
|
213
237
|
mod
|
|
214
238
|
end
|
|
@@ -247,13 +271,14 @@ module TypeProf::Core
|
|
|
247
271
|
mod.get_type_alias(name)
|
|
248
272
|
end
|
|
249
273
|
|
|
250
|
-
def load_core_rbs(raw_decls)
|
|
251
|
-
|
|
274
|
+
def load_core_rbs(raw_decls, position_encoding)
|
|
275
|
+
file_context = FileContext.new(nil, position_encoding)
|
|
276
|
+
lenv = LocalEnv.new(file_context, CRef::Toplevel, {}, [])
|
|
252
277
|
decls = raw_decls.map do |raw_decl|
|
|
253
278
|
AST.create_rbs_decl(raw_decl, lenv)
|
|
254
279
|
end.compact
|
|
255
280
|
|
|
256
|
-
decls += AST.parse_rbs("typeprof-rbs-shim.rbs", <<-RBS)
|
|
281
|
+
decls += AST.parse_rbs("typeprof-rbs-shim.rbs", <<-RBS, position_encoding)
|
|
257
282
|
class Exception
|
|
258
283
|
include _Exception
|
|
259
284
|
end
|
|
@@ -268,6 +293,9 @@ module TypeProf::Core
|
|
|
268
293
|
class Hash[K, V]
|
|
269
294
|
include _Each[[K, V]]
|
|
270
295
|
end
|
|
296
|
+
class Object
|
|
297
|
+
include Hash::_Key
|
|
298
|
+
end
|
|
271
299
|
RBS
|
|
272
300
|
|
|
273
301
|
# Loading frequently used modules first will reduces constant resolution
|
|
@@ -291,9 +319,41 @@ module TypeProf::Core
|
|
|
291
319
|
end
|
|
292
320
|
end
|
|
293
321
|
|
|
294
|
-
class
|
|
295
|
-
|
|
322
|
+
class FileContext
|
|
323
|
+
attr_reader :path, :comments, :position_encoding
|
|
324
|
+
def initialize(path, position_encoding = nil, prism_source = nil, comments = nil)
|
|
296
325
|
@path = path
|
|
326
|
+
@position_encoding = position_encoding || Encoding::UTF_16LE
|
|
327
|
+
@prism_source = prism_source
|
|
328
|
+
@code_units_cache = nil
|
|
329
|
+
@comments = comments
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# Returns [start_column, end_column] for a Prism::Location, in the session-configured
|
|
333
|
+
# position encoding. UTF-8 uses Prism's native byte columns directly (Prism's UTF-8
|
|
334
|
+
# code_units_cache reports code points, not bytes — see LSP 3.17 spec).
|
|
335
|
+
def column_offsets_for(prism_location)
|
|
336
|
+
if @position_encoding == Encoding::UTF_8
|
|
337
|
+
[prism_location.start_column, prism_location.end_column]
|
|
338
|
+
else
|
|
339
|
+
cache = code_units_cache
|
|
340
|
+
[
|
|
341
|
+
prism_location.cached_start_code_units_column(cache),
|
|
342
|
+
prism_location.cached_end_code_units_column(cache),
|
|
343
|
+
]
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
private
|
|
348
|
+
|
|
349
|
+
def code_units_cache
|
|
350
|
+
@code_units_cache ||= @prism_source&.code_units_cache(@position_encoding)
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
class LocalEnv
|
|
355
|
+
def initialize(file_context, cref, locals, return_boxes, forward_args = nil)
|
|
356
|
+
@file_context = file_context
|
|
297
357
|
@cref = cref
|
|
298
358
|
@locals = locals
|
|
299
359
|
@return_boxes = return_boxes
|
|
@@ -301,9 +361,16 @@ module TypeProf::Core
|
|
|
301
361
|
@next_boxes = []
|
|
302
362
|
@ivar_narrowings = {}
|
|
303
363
|
@strict_const_scope = false
|
|
364
|
+
@forward_args = forward_args
|
|
304
365
|
end
|
|
305
366
|
|
|
306
|
-
attr_reader :
|
|
367
|
+
attr_reader :file_context, :cref, :locals, :return_boxes, :break_vtx, :next_boxes, :strict_const_scope
|
|
368
|
+
attr_accessor :module_function, :forward_args
|
|
369
|
+
|
|
370
|
+
def path = @file_context&.path
|
|
371
|
+
def code_range_from_node(node)
|
|
372
|
+
TypeProf::CodeRange.from_node(node, @file_context)
|
|
373
|
+
end
|
|
307
374
|
|
|
308
375
|
def new_var(name, node)
|
|
309
376
|
@locals[name] = Vertex.new(node)
|
|
@@ -333,7 +400,6 @@ module TypeProf::Core
|
|
|
333
400
|
@break_vtx ||= Vertex.new(:break_vtx)
|
|
334
401
|
end
|
|
335
402
|
|
|
336
|
-
|
|
337
403
|
def push_ivar_narrowing(name, narrowing)
|
|
338
404
|
raise unless narrowing.is_a?(Narrowing::Constraint)
|
|
339
405
|
(@ivar_narrowings[name] ||= []) << narrowing
|
|
@@ -376,7 +442,7 @@ module TypeProf::Core
|
|
|
376
442
|
case @scope_level
|
|
377
443
|
when :instance
|
|
378
444
|
mod = genv.resolve_cpath(@cpath || [])
|
|
379
|
-
type_params = mod.type_params.map {|
|
|
445
|
+
type_params = mod.type_params.map {|(_name, _default_ty)| Source.new() } # TODO: better support
|
|
380
446
|
ty = Type::Instance.new(genv, mod, type_params)
|
|
381
447
|
Source.new(ty)
|
|
382
448
|
when :class
|