Skip to content

Commit cdb6174

Browse files
committed
Notify StaticReads when constant values are defined or removed
When a constant value (not a module/class) is defined or removed across files, the StaticRead objects that track constant resolution were not being notified. This caused cross-file constant references to remain untyped when the defining file was loaded after the referencing file.
1 parent 0a3cc27 commit cdb6174

4 files changed

Lines changed: 72 additions & 8 deletions

File tree

lib/typeprof/core/ast/const.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ def define0(genv)
8383
@cpath.define(genv) if @cpath
8484
@rhs.define(genv) if @rhs
8585
if @static_cpath
86-
mod = genv.resolve_const(@static_cpath)
87-
mod.add_def(self)
88-
mod
86+
cdef = genv.resolve_const(@static_cpath)
87+
cdef.on_const_added(genv, @static_cpath)
88+
cdef.add_def(self)
89+
cdef
8990
else
9091
nil
9192
end
@@ -102,7 +103,9 @@ def define_copy(genv)
102103

103104
def undefine0(genv)
104105
if @static_cpath
105-
genv.resolve_const(@static_cpath).remove_def(self)
106+
cdef = genv.resolve_const(@static_cpath)
107+
cdef.remove_def(self)
108+
cdef.on_const_removed(genv, @static_cpath)
106109
end
107110
@rhs.undefine(genv) if @rhs
108111
@cpath.undefine(genv) if @cpath

lib/typeprof/core/ast/sig_decl.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,10 @@ def attrs = { cpath: }
425425

426426
def define0(genv)
427427
@type.define(genv)
428-
mod = genv.resolve_const(@cpath)
429-
mod.add_decl(self)
430-
mod
428+
cdef = genv.resolve_const(@cpath)
429+
cdef.on_const_added(genv, @cpath)
430+
cdef.add_decl(self)
431+
cdef
431432
end
432433

433434
def define_copy(genv)
@@ -438,7 +439,9 @@ def define_copy(genv)
438439
end
439440

440441
def undefine0(genv)
441-
genv.resolve_const(@cpath).remove_decl(self)
442+
cdef = genv.resolve_const(@cpath)
443+
cdef.remove_decl(self)
444+
cdef.on_const_removed(genv, @cpath)
442445
@type.undefine(genv)
443446
end
444447

lib/typeprof/core/env/value_entity.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,19 @@ def remove_def(def_)
2828
def exist?
2929
!@decls.empty? || !@defs.empty?
3030
end
31+
32+
def on_const_added(genv, cpath)
33+
unless exist?
34+
parent_mod = genv.resolve_cpath(cpath[0..-2])
35+
genv.add_static_eval_queue(:inner_modules_changed, [parent_mod, cpath[-1]])
36+
end
37+
end
38+
39+
def on_const_removed(genv, cpath)
40+
unless exist?
41+
parent_mod = genv.resolve_cpath(cpath[0..-2])
42+
genv.add_static_eval_queue(:inner_modules_changed, [parent_mod, cpath[-1]])
43+
end
44+
end
3145
end
3246
end

scenario/const/cross_file_value.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
## update: test0.rb
2+
module Foo
3+
X = 1
4+
end
5+
6+
## update: test1.rb
7+
module Foo
8+
class Bar
9+
def get_x
10+
X
11+
end
12+
end
13+
end
14+
15+
## assert: test1.rb
16+
module Foo
17+
class Bar
18+
def get_x: -> Integer
19+
end
20+
end
21+
22+
## update: test0.rb
23+
module Foo
24+
# X is removed
25+
end
26+
27+
## assert: test1.rb
28+
module Foo
29+
class Bar
30+
def get_x: -> untyped
31+
end
32+
end
33+
34+
## update: test0.rb
35+
module Foo
36+
X = "hello"
37+
end
38+
39+
## assert: test1.rb
40+
module Foo
41+
class Bar
42+
def get_x: -> String
43+
end
44+
end

0 commit comments

Comments
 (0)