Class: Steep::TypeInference::TypeEnv
- Inherits:
-
Object
- Object
- Steep::TypeInference::TypeEnv
- Defined in:
- lib/steep/type_inference/type_env.rb
Instance Attribute Summary collapse
-
#const_env ⇒ Object
readonly
Returns the value of attribute const_env.
-
#const_types ⇒ Object
readonly
Returns the value of attribute const_types.
-
#gvar_types ⇒ Object
readonly
Returns the value of attribute gvar_types.
-
#ivar_types ⇒ Object
readonly
Returns the value of attribute ivar_types.
-
#lvar_types ⇒ Object
readonly
Returns the value of attribute lvar_types.
-
#subtyping ⇒ Object
readonly
Returns the value of attribute subtyping.
Class Method Summary collapse
Instance Method Summary collapse
- #assert_annotation(name, annotated_type:, original_type:, self_type:) ⇒ Object
- #assert_assign(var_type:, lhs_type:, self_type:) ⇒ Object
- #assign(lvar: nil, const: nil, gvar: nil, ivar: nil, type:, self_type:, &block) ⇒ Object
- #get(lvar: nil, const: nil, gvar: nil, ivar: nil) ⇒ Object
-
#initialize(subtyping:, const_env:) ⇒ TypeEnv
constructor
A new instance of TypeEnv.
- #initialize_copy(other) ⇒ Object
- #join!(envs) ⇒ Object
- #lookup_dictionary(ivar:, gvar:) ⇒ Object
- #lvar_name(lvar) ⇒ Object
- #merge!(original_env:, override_env:, self_type:, &block) ⇒ Object
- #set(lvar: nil, const: nil, gvar: nil, ivar: nil, type:) ⇒ Object
- #with_annotations(lvar_types: {}, ivar_types: {}, const_types: {}, gvar_types: {}, self_type:, &block) ⇒ Object
Constructor Details
#initialize(subtyping:, const_env:) ⇒ TypeEnv
Returns a new instance of TypeEnv.
11 12 13 14 15 16 17 18 |
# File 'lib/steep/type_inference/type_env.rb', line 11 def initialize(subtyping:, const_env:) @subtyping = subtyping @lvar_types = {} @const_types = {} @gvar_types = {} @ivar_types = {} @const_env = const_env end |
Instance Attribute Details
#const_env ⇒ Object (readonly)
Returns the value of attribute const_env.
9 10 11 |
# File 'lib/steep/type_inference/type_env.rb', line 9 def const_env @const_env end |
#const_types ⇒ Object (readonly)
Returns the value of attribute const_types.
6 7 8 |
# File 'lib/steep/type_inference/type_env.rb', line 6 def const_types @const_types end |
#gvar_types ⇒ Object (readonly)
Returns the value of attribute gvar_types.
7 8 9 |
# File 'lib/steep/type_inference/type_env.rb', line 7 def gvar_types @gvar_types end |
#ivar_types ⇒ Object (readonly)
Returns the value of attribute ivar_types.
8 9 10 |
# File 'lib/steep/type_inference/type_env.rb', line 8 def ivar_types @ivar_types end |
#lvar_types ⇒ Object (readonly)
Returns the value of attribute lvar_types.
5 6 7 |
# File 'lib/steep/type_inference/type_env.rb', line 5 def lvar_types @lvar_types end |
#subtyping ⇒ Object (readonly)
Returns the value of attribute subtyping.
4 5 6 |
# File 'lib/steep/type_inference/type_env.rb', line 4 def subtyping @subtyping end |
Class Method Details
.build(annotations:, signatures:, subtyping:, const_env:) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/steep/type_inference/type_env.rb', line 29 def self.build(annotations:, signatures:, subtyping:, const_env:) new(subtyping: subtyping, const_env: const_env).tap do |env| annotations.lvar_types.each do |name, type| env.set(lvar: name, type: type) end annotations.ivar_types.each do |name, type| env.set(ivar: name, type: type) end annotations.const_types.each do |name, type| env.set(const: name, type: type) end signatures.name_to_global.each do |name, global| type = signatures.absolute_type(global.type, namespace: Ruby::Signature::Namespace.root) {|ty| ty.name.absolute! } env.set(gvar: name, type: subtyping.factory.type(type)) end end end |
Instance Method Details
#assert_annotation(name, annotated_type:, original_type:, self_type:) ⇒ Object
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/steep/type_inference/type_env.rb', line 223 def assert_annotation(name, annotated_type:, original_type:, self_type:) return annotated_type if annotated_type == original_type annotated_type = subtyping.(annotated_type) original_type = subtyping.(original_type) relation = Subtyping::Relation.new(sub_type: annotated_type, super_type: original_type) constraints = Subtyping::Constraints.new(unknowns: Set.new) subtyping.check(relation, constraints: constraints, self_type: self_type).else do |result| yield name, relation, result end annotated_type end |
#assert_assign(var_type:, lhs_type:, self_type:) ⇒ Object
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/steep/type_inference/type_env.rb', line 201 def assert_assign(var_type:, lhs_type:, self_type:) return var_type if var_type == lhs_type var_type = subtyping.(var_type) lhs_type = subtyping.(lhs_type) relation = Subtyping::Relation.new(sub_type: lhs_type, super_type: var_type) constraints = Subtyping::Constraints.new(unknowns: Set.new) subtyping.check(relation, self_type: self_type, constraints: constraints).else do |result| yield result end var_type end |
#assign(lvar: nil, const: nil, gvar: nil, ivar: nil, type:, self_type:, &block) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/steep/type_inference/type_env.rb', line 149 def assign(lvar: nil, const: nil, gvar: nil, ivar: nil, type:, self_type:, &block) case when lvar yield_self do name = lvar_name(lvar) var_type = lvar_types[name] if var_type assert_assign(var_type: var_type, lhs_type: type, self_type: self_type, &block) else lvar_types[name] = type end end when const yield_self do const_type = const_types[const] || const_env.lookup(const) if const_type assert_assign(var_type: const_type, lhs_type: type, self_type: self_type, &block) else yield nil AST::Types::Any.new end end else lookup_dictionary(ivar: ivar, gvar: gvar) do |var_name, dictionary| if dictionary.key?(var_name) assert_assign(var_type: dictionary[var_name], lhs_type: type, self_type: self_type, &block) else yield nil AST::Types::Any.new end end end end |
#get(lvar: nil, const: nil, gvar: nil, ivar: nil) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/steep/type_inference/type_env.rb', line 94 def get(lvar: nil, const: nil, gvar: nil, ivar: nil) case when lvar lvar_name(lvar).yield_self do |name| if lvar_types.key?(name) lvar_types[name] else ty = yield lvar_types[name] = ty || AST::Types::Any.new end end when const if const_types.key?(const) const_types[const] else const_env.lookup(const).yield_self do |type| if type type else yield AST::Types::Any.new end end end else lookup_dictionary(ivar: ivar, gvar: gvar) do |var_name, dictionary| if dictionary.key?(var_name) dictionary[var_name] else yield AST::Types::Any.new end end end end |
#initialize_copy(other) ⇒ Object
20 21 22 23 24 25 26 27 |
# File 'lib/steep/type_inference/type_env.rb', line 20 def initialize_copy(other) @subtyping = other.subtyping @lvar_types = other.lvar_types.dup @const_types = other.const_types.dup @gvar_types = other.gvar_types.dup @ivar_types = other.ivar_types.dup @const_env = other.const_env end |
#join!(envs) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/steep/type_inference/type_env.rb', line 67 def join!(envs) lvars = {} common_vars = envs.map {|env| Set.new(env.lvar_types.keys) }.inject {|a, b| a & b } envs.each do |env| env.lvar_types.each do |name, type| unless lvar_types.key?(name) lvars[name] = [] unless lvars[name] lvars[name] << type end end end lvars.each do |name, types| if lvar_types.key?(name) || common_vars.member?(name) set(lvar: name, type: AST::Types::Union.build(types: types)) else set(lvar: name, type: AST::Types::Union.build(types: types + [AST::Types::Nil.new])) end end end |
#lookup_dictionary(ivar:, gvar:) ⇒ Object
183 184 185 186 187 188 189 190 |
# File 'lib/steep/type_inference/type_env.rb', line 183 def lookup_dictionary(ivar:, gvar:) case when ivar yield ivar, ivar_types when gvar yield gvar, gvar_types end end |
#lvar_name(lvar) ⇒ Object
192 193 194 195 196 197 198 199 |
# File 'lib/steep/type_inference/type_env.rb', line 192 def lvar_name(lvar) case lvar when Symbol lvar when ASTUtils::Labeling::LabeledName lvar.name end end |
#merge!(original_env:, override_env:, self_type:, &block) ⇒ Object
217 218 219 220 221 |
# File 'lib/steep/type_inference/type_env.rb', line 217 def merge!(original_env:, override_env:, self_type:, &block) original_env.merge!(override_env) do |name, original_type, override_type| assert_annotation name, annotated_type: override_type, original_type: original_type, self_type: self_type, &block end end |
#set(lvar: nil, const: nil, gvar: nil, ivar: nil, type:) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/steep/type_inference/type_env.rb', line 130 def set(lvar: nil, const: nil, gvar: nil, ivar: nil, type:) case when lvar lvar_name(lvar).yield_self do |name| lvar_types[name] = type end when const const_types[const] = type else lookup_dictionary(ivar: ivar, gvar: gvar) do |var_name, dictionary| dictionary[var_name] = type end end end |
#with_annotations(lvar_types: {}, ivar_types: {}, const_types: {}, gvar_types: {}, self_type:, &block) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/steep/type_inference/type_env.rb', line 47 def with_annotations(lvar_types: {}, ivar_types: {}, const_types: {}, gvar_types: {}, self_type:, &block) dup.tap do |env| merge!(original_env: env.lvar_types, override_env: lvar_types, self_type: self_type, &block) merge!(original_env: env.ivar_types, override_env: ivar_types, self_type: self_type, &block) merge!(original_env: env.gvar_types, override_env: gvar_types, self_type: self_type, &block) const_types.each do |name, annotated_type| original_type = self.const_types[name] || const_env.lookup(name) if original_type assert_annotation name, original_type: original_type, annotated_type: annotated_type, self_type: self_type, &block end env.const_types[name] = annotated_type end end end |