Class: RBS::Environment
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Classes:
| |
Inherits: | Object |
Defined in: | lib/rbs/environment.rb |
Class Method Summary
- .from_loader(loader)
- .new ⇒ Environment constructor
Instance Attribute Summary
- #alias_decls readonly
- #class_decls readonly
- #constant_decls readonly
- #declarations readonly
- #global_decls readonly
- #interface_decls readonly
Instance Method Summary
- #<<(decl)
- #absolute_type(resolver, type, context:)
- #absolute_type_name(resolver, type_name, context:)
- #buffers
- #buffers_decls
- #cache_name(cache, name:, decl:, outer:)
- #foo
- #initialize_copy(other)
- #insert_decl(decl, outer:, namespace:)
- #inspect
- #reject
- #resolve_declaration(resolver, decl, outer:, prefix:)
- #resolve_member(resolver, member, context:)
- #resolve_method_type(resolver, type, context:)
- #resolve_type_names(only: nil)
- #resolve_type_params(resolver, params, context:)
- #validate_type_params
Constructor Details
.new ⇒ Environment
# File 'lib/rbs/environment.rb', line 126
def initialize @buffers = [] @declarations = [] @class_decls = {} @interface_decls = {} @alias_decls = {} @constant_decls = {} @global_decls = {} end
Class Method Details
.from_loader(loader)
[ GitHub ]# File 'lib/rbs/environment.rb', line 148
def self.from_loader(loader) self.new.tap do |env| loader.load(env: env) end end
Instance Attribute Details
#alias_decls (readonly)
[ GitHub ]# File 'lib/rbs/environment.rb', line 9
attr_reader :alias_decls
#class_decls (readonly)
[ GitHub ]# File 'lib/rbs/environment.rb', line 7
attr_reader :class_decls
#constant_decls (readonly)
[ GitHub ]# File 'lib/rbs/environment.rb', line 10
attr_reader :constant_decls
#declarations (readonly)
[ GitHub ]# File 'lib/rbs/environment.rb', line 5
attr_reader :declarations
#global_decls (readonly)
[ GitHub ]# File 'lib/rbs/environment.rb', line 11
attr_reader :global_decls
#interface_decls (readonly)
[ GitHub ]# File 'lib/rbs/environment.rb', line 8
attr_reader :interface_decls
Instance Method Details
#<<(decl)
[ GitHub ]# File 'lib/rbs/environment.rb', line 221
def <<(decl) declarations << decl insert_decl(decl, outer: [], namespace: Namespace.root) self end
#absolute_type(resolver, type, context:)
[ GitHub ]# File 'lib/rbs/environment.rb', line 478
def absolute_type(resolver, type, context:) type.map_type_name do |name, _, _| absolute_type_name(resolver, name, context: context) end end
#absolute_type_name(resolver, type_name, context:)
[ GitHub ]# File 'lib/rbs/environment.rb', line 474
def absolute_type_name(resolver, type_name, context:) resolver.resolve(type_name, context: context) || type_name end
#buffers
[ GitHub ]# File 'lib/rbs/environment.rb', line 489
def buffers buffers_decls.keys.compact end
#buffers_decls
[ GitHub ]# File 'lib/rbs/environment.rb', line 493
def buffers_decls # @type var hash: Hash[Buffer, Array[AST::Declarations::t]] hash = {} declarations.each do |decl| location = decl.location or next (hash[location.buffer] ||= []) << decl end hash end
#cache_name(cache, name:, decl:, outer:)
[ GitHub ]# File 'lib/rbs/environment.rb', line 154
def cache_name(cache, name:, decl:, outer:) if cache.key?(name) raise DuplicatedDeclarationError.new(_ = name, _ = decl, _ = cache[name].decl) end cache[name] = SingleEntry.new(name: name, decl: decl, outer: outer) end
#foo
[ GitHub ]# File 'lib/rbs/environment.rb', line 93
def foo a = [1].sample() return unless a a + 1 end
#initialize_copy(other)
[ GitHub ]# File 'lib/rbs/environment.rb', line 137
def initialize_copy(other) @buffers = other.buffers.dup @declarations = other.declarations.dup @class_decls = other.class_decls.dup @interface_decls = other.interface_decls.dup @alias_decls = other.alias_decls.dup @constant_decls = other.constant_decls.dup @global_decls = other.global_decls.dup end
#insert_decl(decl, outer:, namespace:)
[ GitHub ]# File 'lib/rbs/environment.rb', line 162
def insert_decl(decl, outer:, namespace:) case decl when AST::Declarations::Class, AST::Declarations::Module name = decl.name.with_prefix(namespace) if constant_decls.key?(name) raise DuplicatedDeclarationError.new(name, decl, constant_decls[name].decl) end unless class_decls.key?(name) case decl when AST::Declarations::Class class_decls[name] ||= ClassEntry.new(name: name) when AST::Declarations::Module class_decls[name] ||= ModuleEntry.new(name: name) end end existing_entry = class_decls[name] case when decl.is_a?(AST::Declarations::Module) && existing_entry.is_a?(ModuleEntry) # @type var existing_entry: ModuleEntry # @type var decl: AST::Declarations::Module existing_entry.insert(decl: decl, outer: outer) when decl.is_a?(AST::Declarations::Class) && existing_entry.is_a?(ClassEntry) # @type var existing_entry: ClassEntry # @type var decl: AST::Declarations::Class existing_entry.insert(decl: decl, outer: outer) else raise DuplicatedDeclarationError.new(name, decl, existing_entry.decls[0].decl) end prefix = outer + [decl] ns = name.to_namespace decl.each_decl do |d| insert_decl(d, outer: prefix, namespace: ns) end when AST::Declarations::Interface cache_name interface_decls, name: decl.name.with_prefix(namespace), decl: decl, outer: outer when AST::Declarations::Alias cache_name alias_decls, name: decl.name.with_prefix(namespace), decl: decl, outer: outer when AST::Declarations::Constant name = decl.name.with_prefix(namespace) if class_decls.key?(name) raise DuplicatedDeclarationError.new(name, decl, class_decls[name].decls[0].decl) end cache_name constant_decls, name: name, decl: decl, outer: outer when AST::Declarations::Global cache_name global_decls, name: decl.name, decl: decl, outer: outer end end
#inspect
[ GitHub ]# File 'lib/rbs/environment.rb', line 484
def inspect ivars = %i[@declarations @class_decls @interface_decls @alias_decls @constant_decls @global_decls] "\#<RBS::Environment #{ivars.map { |iv| "#{iv}=(#{instance_variable_get(iv).size} items)"}.join(' ')}>" end
#reject
[ GitHub ]# File 'lib/rbs/environment.rb', line 505
def reject env = Environment.new declarations.each do |decl| unless yield(decl) env << decl end end env end
#resolve_declaration(resolver, decl, outer:, prefix:)
[ GitHub ]# File 'lib/rbs/environment.rb', line 248
def resolve_declaration(resolver, decl, outer:, prefix:) if decl.is_a?(AST::Declarations::Global) # @type var decl: AST::Declarations::Global return AST::Declarations::Global.new( name: decl.name, type: absolute_type(resolver, decl.type, context: [Namespace.root]), location: decl.location, comment: decl.comment ) end context = (outer + [decl]).each.with_object([Namespace.root]) do |decl, array| head = array.first or raise array.unshift(head + decl.name.to_namespace) end outer_context = context.drop(1) case decl when AST::Declarations::Class outer_ = outer + [decl] prefix_ = prefix + decl.name.to_namespace AST::Declarations::Class.new( name: decl.name.with_prefix(prefix), type_params: resolve_type_params(resolver, decl.type_params, context: context), super_class: decl.super_class&.yield_self do |super_class| AST::Declarations::Class::Super.new( name: absolute_type_name(resolver, super_class.name, context: outer_context), args: super_class.args.map {|type| absolute_type(resolver, type, context: outer_context) }, location: super_class.location ) end, members: decl.members.map do |member| case member when AST::Members::Base resolve_member(resolver, member, context: context) when AST::Declarations::Base resolve_declaration( resolver, member, outer: outer_, prefix: prefix_ ) else raise end end, location: decl.location, annotations: decl.annotations, comment: decl.comment ) when AST::Declarations::Module outer_ = outer + [decl] prefix_ = prefix + decl.name.to_namespace AST::Declarations::Module.new( name: decl.name.with_prefix(prefix), type_params: resolve_type_params(resolver, decl.type_params, context: context), self_types: decl.self_types.map do |module_self| AST::Declarations::Module::Self.new( name: absolute_type_name(resolver, module_self.name, context: context), args: module_self.args.map {|type| absolute_type(resolver, type, context: context) }, location: module_self.location ) end, members: decl.members.map do |member| case member when AST::Members::Base resolve_member(resolver, member, context: context) when AST::Declarations::Base resolve_declaration( resolver, member, outer: outer_, prefix: prefix_ ) else raise end end, location: decl.location, annotations: decl.annotations, comment: decl.comment ) when AST::Declarations::Interface AST::Declarations::Interface.new( name: decl.name.with_prefix(prefix), type_params: resolve_type_params(resolver, decl.type_params, context: context), members: decl.members.map do |member| resolve_member(resolver, member, context: context) end, comment: decl.comment, location: decl.location, annotations: decl.annotations ) when AST::Declarations::Alias AST::Declarations::Alias.new( name: decl.name.with_prefix(prefix), type_params: resolve_type_params(resolver, decl.type_params, context: context), type: absolute_type(resolver, decl.type, context: context), location: decl.location, annotations: decl.annotations, comment: decl.comment ) when AST::Declarations::Constant AST::Declarations::Constant.new( name: decl.name.with_prefix(prefix), type: absolute_type(resolver, decl.type, context: context), location: decl.location, comment: decl.comment ) end end
#resolve_member(resolver, member, context:)
[ GitHub ]# File 'lib/rbs/environment.rb', line 362
def resolve_member(resolver, member, context:) case member when AST::Members::MethodDefinition AST::Members::MethodDefinition.new( name: member.name, kind: member.kind, types: member.types.map do |type| resolve_method_type(resolver, type, context: context) end, comment: member.comment, overload: member.overload?, annotations: member.annotations, location: member.location, visibility: member.visibility ) when AST::Members::AttrAccessor AST::Members::AttrAccessor.new( name: member.name, type: absolute_type(resolver, member.type, context: context), kind: member.kind, annotations: member.annotations, comment: member.comment, location: member.location, ivar_name: member.ivar_name, visibility: member.visibility ) when AST::Members::AttrReader AST::Members::AttrReader.new( name: member.name, type: absolute_type(resolver, member.type, context: context), kind: member.kind, annotations: member.annotations, comment: member.comment, location: member.location, ivar_name: member.ivar_name, visibility: member.visibility ) when AST::Members::AttrWriter AST::Members::AttrWriter.new( name: member.name, type: absolute_type(resolver, member.type, context: context), kind: member.kind, annotations: member.annotations, comment: member.comment, location: member.location, ivar_name: member.ivar_name, visibility: member.visibility ) when AST::Members::InstanceVariable AST::Members::InstanceVariable.new( name: member.name, type: absolute_type(resolver, member.type, context: context), comment: member.comment, location: member.location ) when AST::Members::ClassInstanceVariable AST::Members::ClassInstanceVariable.new( name: member.name, type: absolute_type(resolver, member.type, context: context), comment: member.comment, location: member.location ) when AST::Members::ClassVariable AST::Members::ClassVariable.new( name: member.name, type: absolute_type(resolver, member.type, context: context), comment: member.comment, location: member.location ) when AST::Members::Include AST::Members::Include.new( name: absolute_type_name(resolver, member.name, context: context), args: member.args.map {|type| absolute_type(resolver, type, context: context) }, comment: member.comment, location: member.location, annotations: member.annotations ) when AST::Members::Extend AST::Members::Extend.new( name: absolute_type_name(resolver, member.name, context: context), args: member.args.map {|type| absolute_type(resolver, type, context: context) }, comment: member.comment, location: member.location, annotations: member.annotations ) when AST::Members::Prepend AST::Members::Prepend.new( name: absolute_type_name(resolver, member.name, context: context), args: member.args.map {|type| absolute_type(resolver, type, context: context) }, comment: member.comment, location: member.location, annotations: member.annotations ) else member end end
#resolve_method_type(resolver, type, context:)
[ GitHub ]# File 'lib/rbs/environment.rb', line 460
def resolve_method_type(resolver, type, context:) type.map_type do |ty| absolute_type(resolver, ty, context: context) end.map_type_bound do |bound| _ = absolute_type(resolver, bound, context: context) end end
#resolve_type_names(only: nil)
[ GitHub ]# File 'lib/rbs/environment.rb', line 233
def resolve_type_names(only: nil) resolver = TypeNameResolver.from_env(self) env = Environment.new() declarations.each do |decl| if only && !only.member?(decl) env << decl else env << resolve_declaration(resolver, decl, outer: [], prefix: Namespace.root) end end env end
#resolve_type_params(resolver, params, context:)
[ GitHub ]# File 'lib/rbs/environment.rb', line 468
def resolve_type_params(resolver, params, context:) params.map do |param| param.map_type {|type| _ = absolute_type(resolver, type, context: context) } end end
#validate_type_params
[ GitHub ]# File 'lib/rbs/environment.rb', line 227
def validate_type_params class_decls.each_value do |decl| decl.primary end end