Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make constant resolution strict for Module#include #291

Merged
merged 1 commit into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions lib/typeprof/core/ast/const.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,19 @@ def initialize(raw_node, lenv)
else
raise raw_node.type.to_s
end
@strict_const_scope = lenv.strict_const_scope
end

attr_reader :cname, :cbase, :toplevel, :cname_code_range
attr_reader :cname, :cbase, :toplevel, :cname_code_range, :strict_const_scope

def attrs = { cname:, toplevel: }
def attrs = { cname:, toplevel:, strict_const_scope: }
def subnodes = { cbase: }

def define0(genv)
if @cbase
ScopedConstRead.new(@cname, @cbase.define(genv))
ScopedConstRead.new(@cname, @cbase.define(genv), @strict_const_scope)
else
BaseConstRead.new(genv, @cname, @toplevel ? CRef::Toplevel : @lenv.cref)
BaseConstRead.new(genv, @cname, @toplevel ? CRef::Toplevel : @lenv.cref, @strict_const_scope)
end
end

Expand Down
4 changes: 3 additions & 1 deletion lib/typeprof/core/ast/meta.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ def initialize(raw_node, lenv)
# TODO: error for splat
@args = raw_node.arguments.arguments.map do |raw_arg|
next if raw_arg.is_a?(Prism::SplatNode)
AST.create_node(raw_arg, lenv)
lenv.use_strict_const_scope do
AST.create_node(raw_arg, lenv)
end
end.compact
# TODO: error for non-LIT
# TODO: fine-grained hover
Expand Down
12 changes: 6 additions & 6 deletions lib/typeprof/core/ast/sig_decl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ def define0(genv)
static_ret[:self_types] = self_types = []
@self_types.zip(@self_type_args) do |(cpath, toplevel), args|
args.each {|arg| arg.define(genv) }
const_read = BaseConstRead.new(genv, cpath.first, toplevel ? CRef::Toplevel : @lenv.cref)
const_read = BaseConstRead.new(genv, cpath.first, toplevel ? CRef::Toplevel : @lenv.cref, false)
const_reads = [const_read]
cpath[1..].each do |cname|
const_read = ScopedConstRead.new(cname, const_read)
const_read = ScopedConstRead.new(cname, const_read, false)
const_reads << const_read
end
mod = genv.resolve_cpath(@cpath)
Expand Down Expand Up @@ -150,10 +150,10 @@ def define0(genv)
const_reads = []
if @superclass_cpath
@superclass_args.each {|arg| arg.define(genv) }
const_read = BaseConstRead.new(genv, @superclass_cpath.first, @superclass_toplevel ? CRef::Toplevel : @lenv.cref)
const_read = BaseConstRead.new(genv, @superclass_cpath.first, @superclass_toplevel ? CRef::Toplevel : @lenv.cref, false)
const_reads << const_read
@superclass_cpath[1..].each do |cname|
const_read = ScopedConstRead.new(cname, const_read)
const_read = ScopedConstRead.new(cname, const_read, false)
const_reads << const_read
end
mod = genv.resolve_cpath(@cpath)
Expand Down Expand Up @@ -219,10 +219,10 @@ def attrs = { cpath:, toplevel: }
def define0(genv)
@args.each {|arg| arg.define(genv) }
const_reads = []
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
const_reads << const_read
@cpath[1..].each do |cname|
const_read = ScopedConstRead.new(cname, const_read)
const_read = ScopedConstRead.new(cname, const_read, false)
const_reads << const_read
end
mod = genv.resolve_cpath(@lenv.cref.cpath)
Expand Down
20 changes: 10 additions & 10 deletions lib/typeprof/core/ast/sig_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,13 @@ def define0(genv)

static_reads = []
if @cpath.empty?
static_reads << BaseTypeAliasRead.new(genv, @name, @toplevel ? CRef::Toplevel : @lenv.cref)
static_reads << BaseTypeAliasRead.new(genv, @name, @toplevel ? CRef::Toplevel : @lenv.cref, false)
else
static_reads << BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
static_reads << BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
@cpath[1..].each do |cname|
static_reads << ScopedConstRead.new(cname, static_reads.last)
static_reads << ScopedConstRead.new(cname, static_reads.last, false)
end
static_reads << ScopedTypeAliasRead.new(@name, static_reads.last)
static_reads << ScopedTypeAliasRead.new(@name, static_reads.last, false)
end
static_reads
end
Expand Down Expand Up @@ -343,11 +343,11 @@ def attrs = { cpath:, toplevel: }

def define0(genv)
const_reads = []
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
const_reads << const_read
unless @cpath.empty?
@cpath[1..].each do |cname|
const_read = ScopedConstRead.new(cname, const_read)
const_read = ScopedConstRead.new(cname, const_read, false)
const_reads << const_read
end
end
Expand Down Expand Up @@ -403,11 +403,11 @@ def attrs = { cpath:, toplevel: }
def define0(genv)
@args.each {|arg| arg.define(genv) }
const_reads = []
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
const_reads << const_read
unless @cpath.empty?
@cpath[1..].each do |cname|
const_read = ScopedConstRead.new(cname, const_read)
const_read = ScopedConstRead.new(cname, const_read, false)
const_reads << const_read
end
end
Expand Down Expand Up @@ -615,11 +615,11 @@ def attrs = { cpath:, toplevel: }
def define0(genv)
@args.each {|arg| arg.define(genv) }
const_reads = []
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
const_reads << const_read
unless @cpath.empty?
@cpath[1..].each do |cname|
const_read = ScopedConstRead.new(cname, const_read)
const_read = ScopedConstRead.new(cname, const_read, false)
const_reads << const_read
end
end
Expand Down
10 changes: 9 additions & 1 deletion lib/typeprof/core/env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,10 @@ def initialize(path, cref, locals, return_boxes)
@break_vtx = nil
@next_boxes = []
@filters = {}
@strict_const_scope = false
end

attr_reader :path, :cref, :locals, :return_boxes, :break_vtx, :next_boxes
attr_reader :path, :cref, :locals, :return_boxes, :break_vtx, :next_boxes, :strict_const_scope

def new_var(name, node)
@locals[name] = Vertex.new(node)
Expand Down Expand Up @@ -335,6 +336,13 @@ def apply_read_filter(genv, node, name, vtx)
end
vtx
end

def use_strict_const_scope
@strict_const_scope = true
yield
ensure
@strict_const_scope = false
end
end

class CRef
Expand Down
17 changes: 9 additions & 8 deletions lib/typeprof/core/env/static_read.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ def destroy(genv)
@source_modules.clear
end

def resolve(genv, cref, break_object)
def resolve(genv, cref, search_ancestors, break_object)
destroy(genv)

first = true
while cref
scope = cref.cpath
mod = genv.resolve_cpath(scope)
Expand All @@ -47,39 +46,41 @@ def resolve(genv, cref, break_object)

return if check_module(genv, mod)

break unless first
break unless search_ancestors
end
first = false
search_ancestors = false
cref = cref.outer
end
resolution_failed(genv)
end
end

class BaseStaticRead < StaticRead
def initialize(genv, name, cref)
def initialize(genv, name, cref, strict_const_scope)
super(name)
@cref = cref
@search_ancestors = !strict_const_scope
genv.add_static_eval_queue(:static_read_changed, self)
end

attr_reader :cref

def on_scope_updated(genv)
resolve(genv, @cref, false)
resolve(genv, @cref, @search_ancestors, false)
end
end

class ScopedStaticRead < StaticRead
def initialize(name, cbase)
def initialize(name, cbase, strict_const_scope)
super(name)
@cbase = cbase
@cbase.followers << self if @cbase
@search_ancestors = !strict_const_scope
end

def on_cbase_updated(genv)
if @cbase && @cbase.cpath
resolve(genv, CRef.new(@cbase.cpath, :class, nil, nil), true)
resolve(genv, CRef.new(@cbase.cpath, :class, nil, nil), @search_ancestors, true)
else
resolution_failed(genv)
end
Expand Down