Skip to content

Commit 4bb8920

Browse files
committed
Update environment
1 parent 859450e commit 4bb8920

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

lib/rbs/environment.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,23 @@ def insert_ruby_decl(decl, context:, namespace:)
409409
decl.each_decl do |member|
410410
insert_ruby_decl(member, context: inner_context, namespace: name.to_namespace)
411411
end
412+
413+
when AST::Ruby::Declarations::ConstantDecl
414+
name = decl.constant_name.with_prefix(namespace)
415+
416+
if entry = constant_entry(name)
417+
case entry
418+
when ClassAliasEntry, ModuleAliasEntry, ConstantEntry
419+
raise DuplicatedDeclarationError.new(name, decl, entry.decl)
420+
when ClassEntry, ModuleEntry
421+
raise DuplicatedDeclarationError.new(name, decl, *entry.each_decl.to_a)
422+
end
423+
end
424+
425+
constant_decls[name] = ConstantEntry.new(name: name, decl: decl, context: context)
426+
427+
else
428+
raise "Unknown Ruby declaration type: #{decl.class}"
412429
end
413430
end
414431

@@ -717,6 +734,17 @@ def resolve_ruby_decl(resolver, decl, context:, prefix:)
717734
end
718735
end
719736

737+
when AST::Ruby::Declarations::ConstantDecl
738+
full_name = decl.constant_name.with_prefix(prefix)
739+
740+
AST::Ruby::Declarations::ConstantDecl.new(
741+
decl.buffer,
742+
full_name,
743+
decl.node,
744+
decl.leading_comment,
745+
decl.type_annotation&.map_type_name {|name, _, _| absolute_type_name(resolver, nil, name, context: context) }
746+
)
747+
720748
else
721749
raise "Unknown declaration type: #{decl.class}"
722750
end

sig/environment.rbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module RBS
2424
class TypeAliasEntry < SingleEntry[TypeName, AST::Declarations::TypeAlias]
2525
end
2626

27-
class ConstantEntry < SingleEntry[TypeName, AST::Declarations::Constant]
27+
class ConstantEntry < SingleEntry[TypeName, AST::Declarations::Constant | AST::Ruby::Declarations::ConstantDecl]
2828
end
2929

3030
class GlobalEntry < SingleEntry[Symbol, AST::Declarations::Global]

test/rbs/environment_test.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,4 +746,51 @@ module World
746746
assert_equal 2, module_decl.context_decls.size
747747
end
748748
end
749+
750+
def test__ruby__constant_declarations
751+
result = parse_inline(<<~RUBY)
752+
A = "123"
753+
B = [1, 2] #: Object
754+
Object::FOO = :FOO
755+
756+
class Object
757+
BAR = "BAR"
758+
end
759+
RUBY
760+
761+
env = Environment.new
762+
env.add_source(RBS::Source::Ruby.new(result.buffer, result.prism_result, result.declarations, result.diagnostics))
763+
resolved_env = env.resolve_type_names
764+
765+
# Check top-level constant A with inferred type
766+
assert_operator resolved_env.constant_decls, :key?, type_name("::A")
767+
resolved_env.constant_decls[type_name("::A")].tap do |entry|
768+
assert_equal type_name("::A"), entry.name
769+
assert_equal "::String", entry.decl.type.to_s
770+
end
771+
772+
# Check top-level constant B with type annotation
773+
assert_operator resolved_env.constant_decls, :key?, type_name("::B")
774+
resolved_env.constant_decls[type_name("::B")].tap do |entry|
775+
assert_equal type_name("::B"), entry.name
776+
assert_equal "::Object", entry.decl.type.to_s
777+
end
778+
779+
# Check constant path Object::FOO
780+
assert_operator resolved_env.constant_decls, :key?, type_name("::Object::FOO")
781+
resolved_env.constant_decls[type_name("::Object::FOO")].tap do |entry|
782+
assert_equal type_name("::Object::FOO"), entry.name
783+
assert_equal "::Symbol", entry.decl.type.to_s
784+
end
785+
786+
# Check constant inside class Object
787+
assert_operator resolved_env.constant_decls, :key?, type_name("::Object::BAR")
788+
resolved_env.constant_decls[type_name("::Object::BAR")].tap do |entry|
789+
assert_equal type_name("::Object::BAR"), entry.name
790+
assert_equal "::String", entry.decl.type.to_s
791+
end
792+
793+
# Verify that Object class is created
794+
assert_operator resolved_env.class_decls, :key?, type_name("::Object")
795+
end
749796
end

0 commit comments

Comments
 (0)