From 97c99843de977f0414c7d2f0863508fcff280a5b Mon Sep 17 00:00:00 2001 From: pvcresin Date: Wed, 18 Feb 2026 12:43:04 +0000 Subject: [PATCH] Fix superclass constant resolution to avoid self-reference --- lib/typeprof/core/ast/module.rb | 6 +++++- lib/typeprof/core/env/static_read.rb | 11 +++++++++++ .../regressions/superclass-self-reference.rb | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 scenario/regressions/superclass-self-reference.rb diff --git a/lib/typeprof/core/ast/module.rb b/lib/typeprof/core/ast/module.rb index d1490a8b..f3649dd6 100644 --- a/lib/typeprof/core/ast/module.rb +++ b/lib/typeprof/core/ast/module.rb @@ -101,7 +101,11 @@ def subnodes def define0(genv) if @static_cpath && @superclass_cpath const = @superclass_cpath.define(genv) - const.followers << genv.resolve_cpath(@static_cpath) if const + if const + const.exclude_cpath = @static_cpath + const.refresh(genv) + const.followers << genv.resolve_cpath(@static_cpath) + end end super(genv) end diff --git a/lib/typeprof/core/env/static_read.rb b/lib/typeprof/core/env/static_read.rb index e33dbdb8..518e4b98 100644 --- a/lib/typeprof/core/env/static_read.rb +++ b/lib/typeprof/core/env/static_read.rb @@ -4,9 +4,11 @@ def initialize(name) @name = name @followers = Set[] @source_modules = Set[] + @exclude_cpath = nil end attr_reader :name, :followers + attr_accessor :exclude_cpath def propagate(genv) @followers.each do |follower| @@ -68,6 +70,10 @@ def initialize(genv, name, cref, strict_const_scope) def on_scope_updated(genv) resolve(genv, @cref, @search_ancestors, false) end + + def refresh(genv) + on_scope_updated(genv) + end end class ScopedStaticRead < StaticRead @@ -85,6 +91,10 @@ def on_cbase_updated(genv) resolution_failed(genv) end end + + def refresh(genv) + on_cbase_updated(genv) + end end module ConstRead @@ -93,6 +103,7 @@ def check_module(genv, mod) if cdef && cdef.exist? inner_mod = genv.resolve_cpath(mod.cpath + [@name]) # TODO cpath = inner_mod.exist? ? inner_mod.cpath : nil + return false if @exclude_cpath && cpath == @exclude_cpath update_module(genv, cpath, cdef) return true end diff --git a/scenario/regressions/superclass-self-reference.rb b/scenario/regressions/superclass-self-reference.rb new file mode 100644 index 00000000..9fa1ecd3 --- /dev/null +++ b/scenario/regressions/superclass-self-reference.rb @@ -0,0 +1,19 @@ +## update: model.rb +class Foo + def value = 1 +end + +module Bar + class Foo < Foo + end +end + +## update: test.rb +def call + Bar::Foo.new.value +end + +## assert: test.rb +class Object + def call: -> Integer +end