@@ -75,6 +75,11 @@ def self.rbs_absolute_type_name(name)
7575 def self . rbs_search_method ( klass , method_name , singleton )
7676 return unless rbs_builder
7777
78+ if klass . is_a? InterfaceType
79+ definition = klass . definition
80+ return definition && definition . methods [ method_name ]
81+ end
82+
7883 klass . ancestors . each do |ancestor |
7984 next unless ( name = Methods ::MODULE_NAME_METHOD . bind_call ( ancestor ) )
8085
@@ -93,6 +98,8 @@ def self.method_return_type(type, method_name)
9398 [ t , t . module_or_class , true ]
9499 in InstanceType
95100 [ t , t . klass , false ]
101+ in InterfaceType
102+ [ t , t , false ]
96103 end
97104 end
98105 types = receivers . flat_map do |receiver_type , klass , singleton |
@@ -115,6 +122,8 @@ def self.accessor_method_return_type(type, method_name)
115122 t . module_or_class
116123 in InstanceType
117124 t . instances
125+ in InterfaceType
126+ nil
118127 end
119128 end . flatten
120129 instances = instances . sample ( OBJECT_TO_TYPE_SAMPLE_SIZE ) if instances . size > OBJECT_TO_TYPE_SAMPLE_SIZE
@@ -136,6 +145,8 @@ def self.rbs_methods(type, method_name, args_types, kwargs_type, has_block)
136145 [ t , t . module_or_class , true ]
137146 in InstanceType
138147 [ t , t . klass , false ]
148+ in InterfaceType
149+ [ t , t , false ]
139150 end
140151 end
141152 has_splat = args_types . include? ( nil )
@@ -193,7 +204,14 @@ def self.intersect?(a, b)
193204 end
194205
195206 aa , bb = [ atypes , btypes ] . map { |types | ( types [ InstanceType ] || [ ] ) . map ( &:klass ) }
196- ( aa . flat_map ( &:ancestors ) & bb ) . any?
207+ return true if ( aa . flat_map ( &:ancestors ) & bb ) . any?
208+
209+ [ [ atypes [ InterfaceType ] , b ] , [ btypes [ InterfaceType ] , a ] ] . any? do |interfaces , other |
210+ interfaces &.any? do |interface |
211+ methods = interface . methods
212+ !methods . empty? && other . types . any? { |t | ( methods - t . methods ) . empty? }
213+ end
214+ end
197215 end
198216
199217 def self . type_from_object ( object )
@@ -340,6 +358,38 @@ def inspect_without_params
340358 end
341359 end
342360
361+ class InterfaceType
362+ attr_reader :name , :args
363+
364+ def initialize ( name , args = [ ] )
365+ @name = name
366+ @args = args
367+ end
368+
369+ def definition
370+ return @definition if defined? ( @definition )
371+
372+ @definition = ( Types . rbs_builder &.build_interface ( @name ) rescue nil )
373+ end
374+
375+ def transform ( ) = yield ( self )
376+ def methods ( ) = definition ? definition . methods . keys : [ ]
377+ def all_methods ( ) = methods
378+
379+ def named_params
380+ definition ? definition . type_params . zip ( @args ) . to_h . compact : { }
381+ end
382+
383+ def constants ( ) = [ ]
384+ def types ( ) = [ self ]
385+ def nillable? ( ) = false
386+ def nonnillable ( ) = self
387+
388+ def inspect
389+ args . empty? ? name . name . to_s : "#{ name . name } [#{ args . map ( &:inspect ) . join ( ', ' ) } ]"
390+ end
391+ end
392+
343393 NIL = InstanceType . new NilClass
344394 OBJECT = InstanceType . new Object
345395 TRUE = InstanceType . new TrueClass
@@ -364,6 +414,7 @@ class UnionType
364414 def initialize ( *types )
365415 @types = [ ]
366416 singleton_types = [ ]
417+ interface_types = { }
367418 instance_types = { }
368419 collect = -> type do
369420 case type
@@ -377,10 +428,12 @@ def initialize(*types)
377428 end
378429 in SingletonType
379430 singleton_types << type
431+ in InterfaceType
432+ interface_types [ [ type . name , type . args ] ] ||= type
380433 end
381434 end
382435 types . each ( &collect )
383- @types = singleton_types . uniq + instance_types . map do |klass , ( params , instances ) |
436+ @types = singleton_types . uniq + interface_types . values + instance_types . map do |klass , ( params , instances ) |
384437 params = params . map { |v | UnionType [ *v ] }
385438 InstanceType . new ( klass , params , instances )
386439 end
@@ -434,12 +487,13 @@ def self.from_rbs_type(return_type, self_type, extra_vars = {})
434487 self_type . transform do |type |
435488 case type
436489 in SingletonType
437- InstanceType . new ( self_type . module_or_class . is_a? ( Class ) ? Class : Module )
490+ InstanceType . new ( type . module_or_class . is_a? ( Class ) ? Class : Module )
438491 in InstanceType
439492 SingletonType . new type . klass
493+ in InterfaceType
494+ CLASS
440495 end
441496 end
442- UnionType [ *types ]
443497 when RBS ::Types ::Bases ::Bool
444498 BOOLEAN
445499 when RBS ::Types ::Bases ::Instance
@@ -467,11 +521,11 @@ def self.from_rbs_type(return_type, self_type, extra_vars = {})
467521 when RBS ::Types ::Variable
468522 if extra_vars . key? return_type . name
469523 extra_vars [ return_type . name ]
470- elsif self_type . is_a? InstanceType
524+ elsif self_type . is_a? ( InstanceType ) || self_type . is_a? ( InterfaceType )
471525 self_type . named_params [ return_type . name ] || OBJECT
472526 elsif self_type . is_a? UnionType
473527 types = self_type . types . filter_map do |t |
474- t . named_params [ return_type . name ] if t . is_a? InstanceType
528+ t . named_params [ return_type . name ] if t . is_a? ( InstanceType ) || t . is_a? ( InterfaceType )
475529 end
476530 UnionType [ *types ]
477531 else
@@ -480,20 +534,11 @@ def self.from_rbs_type(return_type, self_type, extra_vars = {})
480534 when RBS ::Types ::Optional
481535 UnionType [ from_rbs_type ( return_type . type , self_type , extra_vars ) , NIL ]
482536 when RBS ::Types ::Alias
483- case return_type . name . name
484- when :int
485- INTEGER
486- when :boolish
487- BOOLEAN
488- when :string
489- STRING
490- else
491- # TODO: ???
492- OBJECT
493- end
537+ expanded = ( rbs_builder . expand_alias2 return_type . name , return_type . args rescue nil )
538+ expanded ? from_rbs_type ( expanded , self_type , extra_vars ) : OBJECT
494539 when RBS ::Types ::Interface
495- # unimplemented
496- OBJECT
540+ args = return_type . args . map { from_rbs_type _1 , self_type , extra_vars }
541+ InterfaceType . new return_type . name , args
497542 when RBS ::Types ::ClassInstance
498543 klass = return_type . name . to_namespace . path . reduce ( Object ) { _1 . const_get _2 }
499544 if return_type . args
@@ -553,6 +598,13 @@ def self._match_free_variable(vars, rbs_type, value, accumulator)
553598 values = ac [ from ]
554599 ( accumulator [ to ] ||= [ ] ) . concat values if values
555600 end
601+ in [ RBS ::Types ::Union ,]
602+ rbs_type . types . each do |t |
603+ _match_free_variable vars , t , value , accumulator
604+ end
605+ in [ RBS ::Types ::Alias ,]
606+ expanded = rbs_builder . expand_alias2 rbs_type . name , rbs_type . args rescue nil
607+ _match_free_variable vars , expanded , value , accumulator if expanded
556608 else
557609 end
558610 end
0 commit comments