Class: RBS::ConstantTable
- Inherits:
-
Object
- Object
- RBS::ConstantTable
- Defined in:
- lib/rbs/constant_table.rb
Instance Attribute Summary collapse
-
#constant_scopes_cache ⇒ Object
readonly
Returns the value of attribute constant_scopes_cache.
-
#definition_builder ⇒ Object
readonly
Returns the value of attribute definition_builder.
Instance Method Summary collapse
- #absolute_type(type, context:) ⇒ Object
- #absolute_type_name(type_name, context:, location:) ⇒ Object
- #constant_scopes(name) ⇒ Object
- #constant_scopes0(name, scopes: []) ⇒ Object
- #constant_scopes_module(name, scopes:) ⇒ Object
- #env ⇒ Object
-
#initialize(builder:) ⇒ ConstantTable
constructor
A new instance of ConstantTable.
- #name_to_constant(name) ⇒ Object
- #resolve_constant_reference(name, context:) ⇒ Object
- #resolve_constant_reference_context(name, context:) ⇒ Object
- #resolve_constant_reference_inherit(name, scopes:, no_object: false) ⇒ Object
- #resolver ⇒ Object
- #split_name(name) ⇒ Object
Constructor Details
#initialize(builder:) ⇒ ConstantTable
Returns a new instance of ConstantTable.
14 15 16 17 |
# File 'lib/rbs/constant_table.rb', line 14 def initialize(builder:) @definition_builder = builder @constant_scopes_cache = {} end |
Instance Attribute Details
#constant_scopes_cache ⇒ Object (readonly)
Returns the value of attribute constant_scopes_cache.
4 5 6 |
# File 'lib/rbs/constant_table.rb', line 4 def constant_scopes_cache @constant_scopes_cache end |
#definition_builder ⇒ Object (readonly)
Returns the value of attribute definition_builder.
3 4 5 |
# File 'lib/rbs/constant_table.rb', line 3 def definition_builder @definition_builder end |
Instance Method Details
#absolute_type(type, context:) ⇒ Object
19 20 21 22 23 |
# File 'lib/rbs/constant_table.rb', line 19 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:) ⇒ Object
25 26 27 28 |
# File 'lib/rbs/constant_table.rb', line 25 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) ⇒ Object
99 100 101 |
# File 'lib/rbs/constant_table.rb', line 99 def constant_scopes(name) constant_scopes_cache[name] ||= constant_scopes0(name, scopes: []) end |
#constant_scopes0(name, scopes: []) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/rbs/constant_table.rb', line 122 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 else raise "Unexpected declaration: #{name} (#{entry.class})" end scopes end |
#constant_scopes_module(name, scopes:) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rbs/constant_table.rb', line 103 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 ⇒ Object
6 7 8 |
# File 'lib/rbs/constant_table.rb', line 6 def env definition_builder.env end |
#name_to_constant(name) ⇒ Object
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/rbs/constant_table.rb', line 30 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:) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/rbs/constant_table.rb', line 45 def resolve_constant_reference(name, context:) raise "Context cannot be empty: Specify `[Namespace.root]`" if context.empty? head, *tail = split_name(name) 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) || resolve_constant_reference_inherit(head, scopes: constant_scopes(context.first.to_type_name)) end if head_constant tail.inject(head_constant) do |constant, name| 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:) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/rbs/constant_table.rb', line 69 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) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/rbs/constant_table.rb', line 82 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 ⇒ Object
10 11 12 |
# File 'lib/rbs/constant_table.rb', line 10 def resolver @resolver ||= TypeNameResolver.from_env(env) end |
#split_name(name) ⇒ Object
41 42 43 |
# File 'lib/rbs/constant_table.rb', line 41 def split_name(name) name.namespace.path + [name.name] end |