Class: RBS::ConstantTable
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/rbs/constant_table.rb |
Class Method Summary
- .new(builder:) ⇒ ConstantTable constructor
Instance Attribute Summary
- #constant_scopes_cache readonly
- #definition_builder readonly
Instance Method Summary
- #absolute_type(type, context:)
- #absolute_type_name(type_name, context:, location:)
- #constant_scopes(name)
- #constant_scopes0(name, scopes: [])
- #constant_scopes_module(name, scopes:)
- #env
- #name_to_constant(name)
- #resolve_constant_reference(name, context:)
- #resolve_constant_reference_context(name, context:)
- #resolve_constant_reference_inherit(name, scopes:, no_object: false)
- #resolver
- #split_name(name)
Constructor Details
.new(builder:) ⇒ ConstantTable
# File 'lib/rbs/constant_table.rb', line 16
def initialize(builder:) @definition_builder = builder @constant_scopes_cache = {} end
Instance Attribute Details
#constant_scopes_cache (readonly)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 6
attr_reader :constant_scopes_cache
#definition_builder (readonly)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 5
attr_reader :definition_builder
Instance Method Details
#absolute_type(type, context:)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 21
def absolute_type(type, context:) type.map_type_name do |type_name, location| absolute_type_name(type_name, context: context, location: location) end end
#absolute_type_name(type_name, context:, location:)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 27
def absolute_type_name(type_name, context:, location:) resolver.resolve(type_name, context: context) or raise NoTypeFoundError.new(type_name: type_name, location: location) end
#constant_scopes(name)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 108
def constant_scopes(name) constant_scopes_cache[name] ||= constant_scopes0(name, scopes: []) end
#constant_scopes0(name, scopes: [])
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 131
def constant_scopes0(name, scopes: []) entry = env.class_decls[name] namespace = name.to_namespace case entry when Environment::ClassEntry unless name == BuiltinNames::BasicObject.name super_name = entry.primary.decl.super_class&.yield_self do |super_class| absolute_type_name(super_class.name, context: entry.primary.context, location: entry.primary.decl.location) end || BuiltinNames::Object.name constant_scopes0 super_name, scopes: scopes end entry.decls.each do |d| d.decl.members.each do |member| case member when AST::Members::Include if member.name.class? constant_scopes_module absolute_type_name(member.name, context: d.context, location: member.location), scopes: scopes end end end end scopes.unshift namespace when Environment::ModuleEntry constant_scopes0 BuiltinNames::Module.name, scopes: scopes constant_scopes_module name, scopes: scopes end scopes end
#constant_scopes_module(name, scopes:)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 112
def constant_scopes_module(name, scopes:) entry = env.class_decls[name] namespace = name.to_namespace entry.decls.each do |d| d.decl.members.each do |member| case member when AST::Members::Include if member.name.class? constant_scopes_module absolute_type_name(member.name, context: d.context, location: member.location), scopes: scopes end end end end scopes.unshift namespace end
#env
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 8
def env definition_builder.env end
#name_to_constant(name)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 32
def name_to_constant(name) case when entry = env.constant_decls[name] type = absolute_type(entry.decl.type, context: entry.context) Constant.new(name: name, type: type, entry: entry) when entry = env.class_decls[name] type = Types::ClassSingleton.new(name: name, location: nil) Constant.new(name: name, type: type, entry: entry) end end
#resolve_constant_reference(name, context:)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 47
def resolve_constant_reference(name, context:) raise "Context cannot be empty: Specify `[Namespace.root]`" if context.empty? head, *tail = split_name(name) raise unless head head_constant = case when name.absolute? name_to_constant(TypeName.new(name: head, namespace: Namespace.root)) when context == [Namespace.root] name_to_constant(TypeName.new(name: head, namespace: Namespace.root)) else resolve_constant_reference_context(head, context: context) || context.first.yield_self do |first_context| raise unless first_context resolve_constant_reference_inherit(head, scopes: constant_scopes(first_context.to_type_name)) end end tail.inject(head_constant) do |constant, name| if constant resolve_constant_reference_inherit( name, scopes: constant_scopes(constant.name), no_object: constant.name != BuiltinNames::Object.name ) end end end
#resolve_constant_reference_context(name, context:)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 78
def resolve_constant_reference_context(name, context:) head, *tail = context if head if head.path.last == name name_to_constant(head.to_type_name) else name_to_constant(TypeName.new(name: name, namespace: head)) || resolve_constant_reference_context(name, context: tail) end end end
#resolve_constant_reference_inherit(name, scopes:, no_object: false)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 91
def resolve_constant_reference_inherit(name, scopes:, no_object: false) scopes.each do |context| if context.path == [:Object] unless no_object constant = name_to_constant(TypeName.new(name: name, namespace: context)) || name_to_constant(TypeName.new(name: name, namespace: Namespace.root)) end else constant = name_to_constant(TypeName.new(name: name, namespace: context)) end return constant if constant end nil end
#resolver
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 12
def resolver @resolver ||= TypeNameResolver.from_env(env) end
#split_name(name)
[ GitHub ]# File 'lib/rbs/constant_table.rb', line 43
def split_name(name) name.namespace.path + [name.name] end