Class: MilkTea::SubstituteTypeVisitor
- Inherits:
-
Object
- Object
- MilkTea::SubstituteTypeVisitor
- Defined in:
- lib/milk_tea/core/types/visitor.rb
Instance Method Summary collapse
- #apply(type) ⇒ Object
-
#initialize(substitutions) ⇒ SubstituteTypeVisitor
constructor
A new instance of SubstituteTypeVisitor.
Constructor Details
#initialize(substitutions) ⇒ SubstituteTypeVisitor
Returns a new instance of SubstituteTypeVisitor.
268 269 270 |
# File 'lib/milk_tea/core/types/visitor.rb', line 268 def initialize(substitutions) @substitutions = substitutions end |
Instance Method Details
#apply(type) ⇒ Object
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/milk_tea/core/types/visitor.rb', line 272 def apply(type) case type when Types::TypeVar @substitutions.fetch(type.name, type) when Types::LifetimeRef @substitutions.fetch(type.name, type) when Types::Nullable substituted = apply(type.base) substituted.equal?(type.base) ? type : Types::Registry.nullable(substituted) when Types::GenericInstance new_args = type.arguments.map do |arg| arg.is_a?(Types::LiteralTypeArg) ? arg : apply(arg) end type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : Types::Registry.generic_instance(type.name, new_args) when Types::Span substituted = apply(type.element_type) substituted.equal?(type.element_type) ? type : Types::Registry.span(substituted) when Types::Task substituted = apply(type.result_type) substituted.equal?(type.result_type) ? type : Types::Registry.task(substituted) when Types::Event new_payload = type.payload_type ? apply(type.payload_type) : nil if new_payload.equal?(type.payload_type) type else Types::Event.new(type.name, capacity: type.capacity, payload_type: new_payload, module_name: type.module_name, visibility: type.visibility, owner_type_name: type.owner_type_name) end when Types::Proc changed = false new_params = type.params.map do |param| new_param_type = apply(param.type) new_boundary = param.boundary_type ? apply(param.boundary_type) : nil changed = true unless new_param_type.equal?(param.type) && new_boundary.equal?(param.boundary_type) Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary) end new_return = apply(type.return_type) changed = true unless new_return.equal?(type.return_type) changed ? Types::Registry.proc(params: new_params, return_type: new_return) : type when Types::Function changed = false new_params = type.params.map do |param| new_param_type = apply(param.type) new_boundary = param.boundary_type ? apply(param.boundary_type) : nil changed = true unless new_param_type.equal?(param.type) && new_boundary.equal?(param.boundary_type) Types::Registry.parameter(param.name, new_param_type, mutable: param.mutable, passing_mode: param.passing_mode, boundary_type: new_boundary) end new_return = apply(type.return_type) changed = true unless new_return.equal?(type.return_type) new_receiver = type.receiver_type ? apply(type.receiver_type) : nil changed = true unless new_receiver.equal?(type.receiver_type) changed ? Types::Registry.function(type.name, params: new_params, return_type: new_return, receiver_type: new_receiver, receiver_editable: type.receiver_editable, variadic: type.variadic, external: type.external) : type when Types::StructInstance new_args = type.arguments.map { |arg| apply(arg) } type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args) when Types::VariantInstance new_args = type.arguments.map { |arg| apply(arg) } type.arguments.zip(new_args).all? { |old, new| old.equal?(new) } ? type : type.definition.instantiate(new_args) else type end end |