Sha256: 68709c5caf4e017913990e25c7451734370c1c3e570123ba447a2277aa060db8

Contents?: true

Size: 1.35 KB

Versions: 8

Compression:

Stored size: 1.35 KB

Contents

module RBS
  class TypeNameResolver
    Query = Struct.new(:type_name, :context, keyword_init: true)

    attr_reader :all_names
    attr_reader :cache

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

    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

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

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

    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
        name_head = TypeName.new(name: path_head, namespace: Namespace.empty)

        absolute_head = context.each.find do |namespace|
          full_name = name_head.with_prefix(namespace)
          has_name?(full_name) and break full_name
        end

        if absolute_head
          has_name?(Namespace.new(path: absolute_head.to_namespace.path.push(*path_tail), absolute: true).to_type_name)
        end
      end
    end

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

Version data entries

8 entries across 8 versions & 1 rubygems

Version Path
rbs-0.11.0 lib/rbs/type_name_resolver.rb
rbs-0.10.0 lib/rbs/type_name_resolver.rb
rbs-0.9.1 lib/rbs/type_name_resolver.rb
rbs-0.9.0 lib/rbs/type_name_resolver.rb
rbs-0.8.0 lib/rbs/type_name_resolver.rb
rbs-0.7.0 lib/rbs/type_name_resolver.rb
rbs-0.6.0 lib/rbs/type_name_resolver.rb
rbs-0.5.0 lib/rbs/type_name_resolver.rb