Class: RBS::TypeNameResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/rbs/type_name_resolver.rb

Constant Summary collapse

Query =
_ = Struct.new(:type_name, :context, keyword_init: true)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTypeNameResolver

Returns a new instance of TypeNameResolver.



8
9
10
11
# File 'lib/rbs/type_name_resolver.rb', line 8

def initialize()
  @all_names = Set[]
  @cache = {}
end

Instance Attribute Details

#all_namesObject (readonly)

Returns the value of attribute all_names.



5
6
7
# File 'lib/rbs/type_name_resolver.rb', line 5

def all_names
  @all_names
end

#cacheObject (readonly)

Returns the value of attribute cache.



6
7
8
# File 'lib/rbs/type_name_resolver.rb', line 6

def cache
  @cache
end

Class Method Details

.from_env(env) ⇒ Object



13
14
15
16
17
# File 'lib/rbs/type_name_resolver.rb', line 13

def self.from_env(env)
  new.add_names(env.class_decls.keys)
    .add_names(env.interface_decls.keys)
    .add_names(env.alias_decls.keys)
end

Instance Method Details

#add_names(names) ⇒ Object



19
20
21
22
# File 'lib/rbs/type_name_resolver.rb', line 19

def add_names(names)
  all_names.merge(names)
  self
end

#has_name?(full_name) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
# File 'lib/rbs/type_name_resolver.rb', line 59

def has_name?(full_name)
  if all_names.include?(full_name)
    full_name
  end
end

#resolve(type_name, context:) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rbs/type_name_resolver.rb', line 31

def resolve(type_name, context:)
  if type_name.absolute?
    return type_name
  end

  query = Query.new(type_name: type_name, context: context)
  try_cache(query) do
    path_head, *path_tail = type_name.to_namespace.path
    raise unless path_head

    name_head = TypeName.new(name: path_head, namespace: Namespace.empty)

    absolute_head = context.find do |namespace|
      # @type break: TypeName
      full_name = name_head.with_prefix(namespace)
      has_name?(full_name) and break full_name
    end

    case absolute_head
    when TypeName
      has_name?(Namespace.new(path: absolute_head.to_namespace.path.push(*path_tail), absolute: true).to_type_name)
    when Namespace
      # This cannot happen because the `context.find` doesn't return a Namespace.
      raise
    end
  end
end

#try_cache(query) ⇒ Object



24
25
26
27
28
29
# File 'lib/rbs/type_name_resolver.rb', line 24

def try_cache(query)
  cache.fetch(query) do
    result = yield
    cache[query] = result
  end
end