typeprof 0.31.1 → 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 +27 -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 +77 -31
- data/lib/typeprof/core/ast/value.rb +14 -6
- data/lib/typeprof/core/ast/variable.rb +11 -4
- data/lib/typeprof/core/ast.rb +95 -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 +79 -17
- data/lib/typeprof/core/graph/box.rb +379 -52
- 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 +41 -7
- 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
|
@@ -2,60 +2,63 @@ module TypeProf::Core
|
|
|
2
2
|
class MethodEntity
|
|
3
3
|
def initialize
|
|
4
4
|
@builtin = nil
|
|
5
|
-
@decls = Set[]
|
|
6
|
-
@overloading_decls = Set[]
|
|
7
|
-
@defs = Set[]
|
|
8
|
-
@aliases = {}
|
|
9
|
-
@method_call_boxes = Set[]
|
|
10
5
|
end
|
|
11
6
|
|
|
12
|
-
attr_reader :decls, :defs, :aliases, :method_call_boxes
|
|
13
7
|
attr_accessor :builtin
|
|
14
8
|
|
|
9
|
+
def decls = @decls ||= Set.empty
|
|
10
|
+
def defs = @defs ||= Set.empty
|
|
11
|
+
def aliases = @aliases ||= {}
|
|
12
|
+
def method_call_boxes = @method_call_boxes ||= Set.empty
|
|
13
|
+
|
|
14
|
+
private def overloading_decls = @overloading_decls ||= Set.empty
|
|
15
|
+
|
|
15
16
|
def add_decl(decl)
|
|
16
17
|
if decl.overloading
|
|
17
|
-
|
|
18
|
+
overloading_decls << decl
|
|
18
19
|
else
|
|
19
|
-
|
|
20
|
+
decls << decl
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def remove_decl(decl)
|
|
24
25
|
if decl.overloading
|
|
25
|
-
|
|
26
|
+
overloading_decls.delete(decl) || raise
|
|
26
27
|
else
|
|
27
|
-
|
|
28
|
+
decls.delete(decl) || raise
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
def add_def(mdef)
|
|
32
|
-
|
|
33
|
+
defs << mdef
|
|
33
34
|
self
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
def remove_def(mdef)
|
|
37
|
-
|
|
38
|
+
defs.delete(mdef) || raise
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
def add_alias(node, old_mid)
|
|
41
|
-
|
|
42
|
+
aliases[node] = old_mid
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
def remove_alias(node)
|
|
45
|
-
|
|
46
|
+
aliases.delete(node) || raise
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def exist?
|
|
49
|
-
@builtin || !@decls.empty? || !@defs.empty?
|
|
50
|
+
@builtin || (@decls && !@decls.empty?) || (@defs && !@defs.empty?)
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
def add_run_all_mdefs(genv)
|
|
54
|
+
return unless @defs
|
|
53
55
|
@defs.each do |mdef|
|
|
54
56
|
genv.add_run(mdef)
|
|
55
57
|
end
|
|
56
58
|
end
|
|
57
59
|
|
|
58
60
|
def add_run_all_method_call_boxes(genv)
|
|
61
|
+
return unless @method_call_boxes
|
|
59
62
|
@method_call_boxes.each do |box|
|
|
60
63
|
genv.add_run(box)
|
|
61
64
|
end
|
|
@@ -3,13 +3,18 @@ module TypeProf::Core
|
|
|
3
3
|
def initialize(cpath, outer_module = self)
|
|
4
4
|
@cpath = cpath
|
|
5
5
|
|
|
6
|
-
@module_decls = Set
|
|
7
|
-
@module_defs = Set
|
|
8
|
-
@include_decls = Set
|
|
9
|
-
@include_defs = Set
|
|
6
|
+
@module_decls = Set.empty
|
|
7
|
+
@module_defs = Set.empty
|
|
8
|
+
@include_decls = Set.empty
|
|
9
|
+
@include_defs = Set.empty
|
|
10
10
|
@prepend_decls = []
|
|
11
11
|
@prepend_defs = []
|
|
12
12
|
|
|
13
|
+
# `class Foo = Bar` / `module Foo = Bar` declarations attached to this entity.
|
|
14
|
+
# Maps an alias decl to the target ModuleEntity at the time of registration.
|
|
15
|
+
@alias_decls = {}
|
|
16
|
+
@alias_target = nil
|
|
17
|
+
|
|
13
18
|
@inner_modules = {}
|
|
14
19
|
@outer_module = outer_module
|
|
15
20
|
|
|
@@ -25,7 +30,7 @@ module TypeProf::Core
|
|
|
25
30
|
|
|
26
31
|
# class Foo[X, Y, Z] < Bar[A, B, C]
|
|
27
32
|
@superclass_type_args = nil # A, B, C
|
|
28
|
-
@type_params =
|
|
33
|
+
@type_params = {} # X, Y, Z
|
|
29
34
|
|
|
30
35
|
@consts = {}
|
|
31
36
|
@methods = { true => {}, false => {} }
|
|
@@ -34,14 +39,16 @@ module TypeProf::Core
|
|
|
34
39
|
@type_aliases = {}
|
|
35
40
|
|
|
36
41
|
@static_reads = {}
|
|
37
|
-
@subclass_checks = Set
|
|
38
|
-
@ivar_reads = Set
|
|
39
|
-
@cvar_reads = Set
|
|
42
|
+
@subclass_checks = Set.empty
|
|
43
|
+
@ivar_reads = Set.empty # should be handled in @ivars ??
|
|
44
|
+
@cvar_reads = Set.empty
|
|
40
45
|
end
|
|
41
46
|
|
|
42
47
|
attr_reader :cpath
|
|
43
48
|
attr_reader :module_decls
|
|
44
49
|
attr_reader :module_defs
|
|
50
|
+
attr_reader :alias_decls
|
|
51
|
+
attr_reader :alias_target
|
|
45
52
|
|
|
46
53
|
attr_reader :inner_modules
|
|
47
54
|
attr_reader :outer_module
|
|
@@ -79,7 +86,7 @@ module TypeProf::Core
|
|
|
79
86
|
end
|
|
80
87
|
|
|
81
88
|
def exist?
|
|
82
|
-
!@module_decls.empty? || !@module_defs.empty?
|
|
89
|
+
!@module_decls.empty? || !@module_defs.empty? || !@alias_decls.empty?
|
|
83
90
|
end
|
|
84
91
|
|
|
85
92
|
def on_inner_modules_changed(genv, changed_cname)
|
|
@@ -115,9 +122,10 @@ module TypeProf::Core
|
|
|
115
122
|
@module_decls << decl
|
|
116
123
|
|
|
117
124
|
if @type_params
|
|
118
|
-
update_type_params
|
|
125
|
+
update_type_params
|
|
119
126
|
else
|
|
120
|
-
@type_params =
|
|
127
|
+
@type_params = {}
|
|
128
|
+
decl.params.zip(decl.params_default_types) {|name, default_type| @type_params[name] = default_type }
|
|
121
129
|
end
|
|
122
130
|
|
|
123
131
|
if decl.is_a?(AST::SigClassNode) && !@superclass_type_args
|
|
@@ -133,7 +141,7 @@ module TypeProf::Core
|
|
|
133
141
|
@outer_module.get_const(get_cname).remove_decl(decl)
|
|
134
142
|
@module_decls.delete(decl) || raise
|
|
135
143
|
|
|
136
|
-
update_type_params
|
|
144
|
+
update_type_params
|
|
137
145
|
if decl.is_a?(AST::SigClassNode) && @superclass_type_args == decl.superclass_args
|
|
138
146
|
@superclass_type_args = nil
|
|
139
147
|
@module_decls.each do |decl|
|
|
@@ -152,13 +160,12 @@ module TypeProf::Core
|
|
|
152
160
|
@module_decls.each do |decl|
|
|
153
161
|
params = decl.params
|
|
154
162
|
next unless params
|
|
155
|
-
if @type_params
|
|
156
|
-
@type_params =
|
|
157
|
-
|
|
158
|
-
@type_params = params
|
|
163
|
+
if !@type_params || @type_params.size < params.size
|
|
164
|
+
@type_params = {}
|
|
165
|
+
params.zip(decl.params_default_types) {|name, default_type| @type_params[name] = default_type }
|
|
159
166
|
end
|
|
160
167
|
end
|
|
161
|
-
@type_params ||=
|
|
168
|
+
@type_params ||= {}
|
|
162
169
|
# TODO: report an error if there are multiple inconsistent declarations
|
|
163
170
|
end
|
|
164
171
|
|
|
@@ -176,6 +183,22 @@ module TypeProf::Core
|
|
|
176
183
|
on_module_removed(genv)
|
|
177
184
|
end
|
|
178
185
|
|
|
186
|
+
def add_alias_decl(genv, decl, target_mod)
|
|
187
|
+
on_module_added(genv)
|
|
188
|
+
@alias_decls[decl] = target_mod
|
|
189
|
+
@alias_target = @alias_decls.values.first
|
|
190
|
+
ce = @outer_module.get_const(get_cname)
|
|
191
|
+
ce.add_decl(decl)
|
|
192
|
+
ce
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def remove_alias_decl(genv, decl)
|
|
196
|
+
@outer_module.get_const(get_cname).remove_decl(decl)
|
|
197
|
+
@alias_decls.delete(decl) || raise
|
|
198
|
+
@alias_target = @alias_decls.values.first
|
|
199
|
+
on_module_removed(genv)
|
|
200
|
+
end
|
|
201
|
+
|
|
179
202
|
def add_include_decl(genv, node)
|
|
180
203
|
@include_decls << node
|
|
181
204
|
genv.add_static_eval_queue(:parent_modules_changed, self)
|
|
@@ -237,7 +260,7 @@ module TypeProf::Core
|
|
|
237
260
|
old_parent.child_modules.delete(self) if set.empty?
|
|
238
261
|
end
|
|
239
262
|
if new_parent
|
|
240
|
-
set = new_parent.child_modules[self] ||= Set
|
|
263
|
+
set = new_parent.child_modules[self] ||= Set.empty
|
|
241
264
|
set << origin
|
|
242
265
|
end
|
|
243
266
|
return [new_parent, true]
|
|
@@ -261,6 +284,8 @@ module TypeProf::Core
|
|
|
261
284
|
next
|
|
262
285
|
when AST::ModuleNode
|
|
263
286
|
return nil
|
|
287
|
+
when AST::StructNewNode
|
|
288
|
+
return [] # inherits from Object (Struct < Object)
|
|
264
289
|
else
|
|
265
290
|
raise
|
|
266
291
|
end
|
|
@@ -436,6 +461,19 @@ module TypeProf::Core
|
|
|
436
461
|
@ivars[singleton][name] ||= ValueEntity.new
|
|
437
462
|
end
|
|
438
463
|
|
|
464
|
+
def add_ivar_decl(genv, singleton, name, decl)
|
|
465
|
+
ive = get_ivar(singleton, name)
|
|
466
|
+
ive.add_decl(decl)
|
|
467
|
+
ive.on_decl_changed(genv)
|
|
468
|
+
ive
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
def remove_ivar_decl(genv, singleton, name, decl)
|
|
472
|
+
ive = get_ivar(singleton, name)
|
|
473
|
+
ive.remove_decl(decl)
|
|
474
|
+
ive.on_decl_changed(genv)
|
|
475
|
+
end
|
|
476
|
+
|
|
439
477
|
def get_cvar(name)
|
|
440
478
|
@cvars[name] ||= ValueEntity.new
|
|
441
479
|
end
|
|
@@ -2,8 +2,8 @@ module TypeProf::Core
|
|
|
2
2
|
class StaticRead
|
|
3
3
|
def initialize(name)
|
|
4
4
|
@name = name
|
|
5
|
-
@followers = Set
|
|
6
|
-
@source_modules = Set
|
|
5
|
+
@followers = Set.empty
|
|
6
|
+
@source_modules = Set.empty
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
attr_reader :name, :followers
|
|
@@ -37,11 +37,11 @@ module TypeProf::Core
|
|
|
37
37
|
scope = cref.cpath
|
|
38
38
|
mod = genv.resolve_cpath(scope)
|
|
39
39
|
genv.each_superclass(mod, false) do |mod, _singleton|
|
|
40
|
-
break if mod == genv.mod_object && break_object
|
|
40
|
+
break if mod == genv.mod_object && (break_object || cref.outer)
|
|
41
41
|
|
|
42
42
|
unless @source_modules.include?(mod)
|
|
43
43
|
@source_modules << mod
|
|
44
|
-
(mod.static_reads[@name] ||= Set
|
|
44
|
+
(mod.static_reads[@name] ||= Set.empty) << self
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
return if check_module(genv, mod)
|
|
@@ -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,16 +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)
|
|
118
122
|
end
|
|
119
123
|
elsif base_ty.is_a?(Type::Singleton)
|
|
120
|
-
base_ty.mod.type_params&.each do |param|
|
|
121
|
-
ty_env[param] = Source.new
|
|
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
|
|
122
126
|
end
|
|
123
127
|
end
|
|
124
|
-
args = mod.type_params.zip(type_args).map do |param, arg|
|
|
125
|
-
|
|
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
|
|
126
134
|
end
|
|
127
135
|
Type::Instance.new(self, mod, args)
|
|
128
136
|
end
|
|
@@ -213,6 +221,18 @@ module TypeProf::Core
|
|
|
213
221
|
raise unless cpath # annotation
|
|
214
222
|
cpath.each do |cname|
|
|
215
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
|
|
216
236
|
end
|
|
217
237
|
mod
|
|
218
238
|
end
|
|
@@ -251,13 +271,14 @@ module TypeProf::Core
|
|
|
251
271
|
mod.get_type_alias(name)
|
|
252
272
|
end
|
|
253
273
|
|
|
254
|
-
def load_core_rbs(raw_decls)
|
|
255
|
-
|
|
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, {}, [])
|
|
256
277
|
decls = raw_decls.map do |raw_decl|
|
|
257
278
|
AST.create_rbs_decl(raw_decl, lenv)
|
|
258
279
|
end.compact
|
|
259
280
|
|
|
260
|
-
decls += AST.parse_rbs("typeprof-rbs-shim.rbs", <<-RBS)
|
|
281
|
+
decls += AST.parse_rbs("typeprof-rbs-shim.rbs", <<-RBS, position_encoding)
|
|
261
282
|
class Exception
|
|
262
283
|
include _Exception
|
|
263
284
|
end
|
|
@@ -272,6 +293,9 @@ module TypeProf::Core
|
|
|
272
293
|
class Hash[K, V]
|
|
273
294
|
include _Each[[K, V]]
|
|
274
295
|
end
|
|
296
|
+
class Object
|
|
297
|
+
include Hash::_Key
|
|
298
|
+
end
|
|
275
299
|
RBS
|
|
276
300
|
|
|
277
301
|
# Loading frequently used modules first will reduces constant resolution
|
|
@@ -295,9 +319,41 @@ module TypeProf::Core
|
|
|
295
319
|
end
|
|
296
320
|
end
|
|
297
321
|
|
|
298
|
-
class
|
|
299
|
-
|
|
322
|
+
class FileContext
|
|
323
|
+
attr_reader :path, :comments, :position_encoding
|
|
324
|
+
def initialize(path, position_encoding = nil, prism_source = nil, comments = nil)
|
|
300
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
|
|
301
357
|
@cref = cref
|
|
302
358
|
@locals = locals
|
|
303
359
|
@return_boxes = return_boxes
|
|
@@ -305,9 +361,16 @@ module TypeProf::Core
|
|
|
305
361
|
@next_boxes = []
|
|
306
362
|
@ivar_narrowings = {}
|
|
307
363
|
@strict_const_scope = false
|
|
364
|
+
@forward_args = forward_args
|
|
308
365
|
end
|
|
309
366
|
|
|
310
|
-
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
|
|
311
374
|
|
|
312
375
|
def new_var(name, node)
|
|
313
376
|
@locals[name] = Vertex.new(node)
|
|
@@ -337,7 +400,6 @@ module TypeProf::Core
|
|
|
337
400
|
@break_vtx ||= Vertex.new(:break_vtx)
|
|
338
401
|
end
|
|
339
402
|
|
|
340
|
-
|
|
341
403
|
def push_ivar_narrowing(name, narrowing)
|
|
342
404
|
raise unless narrowing.is_a?(Narrowing::Constraint)
|
|
343
405
|
(@ivar_narrowings[name] ||= []) << narrowing
|
|
@@ -380,7 +442,7 @@ module TypeProf::Core
|
|
|
380
442
|
case @scope_level
|
|
381
443
|
when :instance
|
|
382
444
|
mod = genv.resolve_cpath(@cpath || [])
|
|
383
|
-
type_params = mod.type_params.map {|
|
|
445
|
+
type_params = mod.type_params.map {|(_name, _default_ty)| Source.new() } # TODO: better support
|
|
384
446
|
ty = Type::Instance.new(genv, mod, type_params)
|
|
385
447
|
Source.new(ty)
|
|
386
448
|
when :class
|