class RBS::Resolver::TypeNameResolver
TypeNameResolver resolves given relative type name to absolute type name under a module nesting context.
The type name resolution doesnβt take account of ancestors of modules. It just ignores included modules and super classes.
Attributes
Hash[TypeName, [ TypeName, context ]]
Public Class Methods
(Environment) → instance
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 16 def self.build(env) all_names = Set.new #: Set[TypeName] all_names.merge(env.class_decls.keys) all_names.merge(env.interface_decls.keys) all_names.merge(env.type_alias_decls.keys) aliases = {} #: Hash[TypeName, [TypeName, context]] env.class_alias_decls.each do |name, entry| aliases[name] = [entry.decl.old_name, entry.context] end new(all_names, aliases) end
Public Instance Methods
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 82 def aliased_name?(type_name) if aliases.key?(type_name) type_name end end
Returns the type name if it is an alias (not normalized)
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 76 def has_type_name?(full_name) if all_names.include?(full_name) full_name end end
Returns the type name if it exists in all_names (normalized)
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 121 def normalize_namespace(type_name, rhs, context, visited) if visited.include?(type_name) # Cycle detected return false end visited << type_name begin resolve_namespace0(rhs, context, visited) ensure visited.delete(type_name) end end
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 39 def resolve(type_name, context:) if type_name.absolute? && has_type_name?(type_name) return type_name end try_cache([type_name, context]) do if type_name.class? resolve_namespace0(type_name, context, Set.new) || nil else namespace = type_name.namespace if namespace.empty? resolve_type_name(type_name.name, context) else if namespace = resolve_namespace0(namespace.to_type_name, context, Set.new) type_name = TypeName.new(name: type_name.name, namespace: namespace.to_namespace) has_type_name?(type_name) end end end end end
Translates given type name to absolute type name
Returns nil if cannot find associated type name. Module names in the type name are normalized.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 104 def resolve_head_namespace(head, context) if context outer, inner = context case inner when false resolve_head_namespace(head, outer) when TypeName has_type_name?(inner) or raise "Context must be normalized: #{inner.inspect}" type_name = TypeName.new(name: head, namespace: inner.to_namespace) has_type_name?(type_name) || aliased_name?(type_name) || resolve_head_namespace(head, outer) end else type_name = TypeName.new(name: head, namespace: Namespace.root) has_type_name?(type_name) || aliased_name?(type_name) end end
Translates the head module name in the context and returns an absolute type name
Returns nil if cannot find associated type name. The returned namespace may be an alias
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 62 def resolve_namespace(type_name, context:) if type_name.absolute? && has_type_name?(type_name) return type_name end unless type_name.class? raise "Type name must be a class name: #{type_name}" end try_cache([type_name, context]) do ns = resolve_namespace0(type_name, context, Set.new) or return ns end end
Translates given type name to absolute type name
Returns false if a cycle is detected while resolving aliases. Returns nil if the type name cannot be resolved.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 136 def resolve_namespace0(type_name, context, visited) head, *tail = [*type_name.namespace.path, type_name.name] head = head #: Symbol head = if type_name.absolute? root_name = TypeName.new(name: head, namespace: Namespace.root) has_type_name?(root_name) || aliased_name?(root_name) else resolve_head_namespace(head, context) end if head if (rhs, context = aliases.fetch(head, nil)) head = normalize_namespace(head, rhs, context, visited) or return head end tail.inject(head) do |namespace, name| type_name = TypeName.new(name: name, namespace: namespace.to_namespace) case when has_type_name?(type_name) type_name when (rhs, context = aliases.fetch(type_name, nil)) m = normalize_namespace(type_name, rhs, context, visited) or return m else return nil end end end end
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/resolver/type_name_resolver.rb, line 88 def resolve_type_name(type_name, context) if context outer, inner = context case inner when false resolve_type_name(type_name, outer) else has_type_name?(inner) or raise "Context must be normalized: #{inner.inspect}" has_type_name?(TypeName.new(name: type_name, namespace: inner.to_namespace)) || resolve_type_name(type_name, outer) end else type_name = TypeName.new(name: type_name, namespace: Namespace.root) has_type_name?(type_name) end end
Resolves the type name in the given context