Class: Steep::Interface::Function::Params

Inherits:
Object
  • Object
show all
Defined in:
lib/steep/interface/function.rb

Defined Under Namespace

Modules: Utils Classes: KeywordParams, PositionalParams

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(positional_params:, keyword_params:) ⇒ Params

Returns a new instance of Params.



781
782
783
784
# File 'lib/steep/interface/function.rb', line 781

def initialize(positional_params:, keyword_params:)
  @positional_params = positional_params
  @keyword_params = keyword_params
end

Instance Attribute Details

#keyword_paramsObject (readonly)

Returns the value of attribute keyword_params.



773
774
775
# File 'lib/steep/interface/function.rb', line 773

def keyword_params
  @keyword_params
end

#positional_paramsObject (readonly)

Returns the value of attribute positional_params.



772
773
774
# File 'lib/steep/interface/function.rb', line 772

def positional_params
  @positional_params
end

Class Method Details

.build(required: [], optional: [], rest: nil, required_keywords: {}, optional_keywords: {}, rest_keywords: nil) ⇒ Object



775
776
777
778
779
# File 'lib/steep/interface/function.rb', line 775

def self.build(required: [], optional: [], rest: nil, required_keywords: {}, optional_keywords: {}, rest_keywords: nil)
  positional_params = PositionalParams.build(required: required, optional: optional, rest: rest)
  keyword_params = KeywordParams.new(requireds: required_keywords, optionals: optional_keywords, rest: rest_keywords)
  new(positional_params: positional_params, keyword_params: keyword_params)
end

.emptyObject



807
808
809
# File 'lib/steep/interface/function.rb', line 807

def self.empty
  self.new(positional_params: nil, keyword_params: KeywordParams.new)
end

Instance Method Details

#&(other) ⇒ Object

Returns the intersection between self and other. Returns nil if the intersection cannot be computed.

(self & other) <: self
(self & other) <: other

‘self & other` accept `arg` if `arg` is acceptable for both of `self` and `other`.



968
969
970
971
972
# File 'lib/steep/interface/function.rb', line 968

def &(other)
  pp = PositionalParams.merge_for_intersection(positional_params, other.positional_params) rescue return
  kp = keyword_params & other.keyword_params or return
  Params.new(positional_params: pp, keyword_params: kp)
end

#+(other) ⇒ Object

self + params returns a new params for overloading.



954
955
956
957
958
# File 'lib/steep/interface/function.rb', line 954

def +(other)
  pp = PositionalParams.merge_for_overload(positional_params, other.positional_params)
  kp = keyword_params + other.keyword_params
  Params.new(positional_params: pp, keyword_params: kp)
end

#==(other) ⇒ Object Also known as: eql?



811
812
813
814
815
# File 'lib/steep/interface/function.rb', line 811

def ==(other)
  other.is_a?(self.class) &&
    other.positional_params == positional_params &&
    other.keyword_params == keyword_params
end

#closed?Boolean

Returns:

  • (Boolean)


900
901
902
# File 'lib/steep/interface/function.rb', line 900

def closed?
  each_type.all? { _1.free_variables.empty? }
end

#drop_firstObject



872
873
874
875
876
877
878
879
880
881
# File 'lib/steep/interface/function.rb', line 872

def drop_first
  case
  when positional_params
    update(positional_params: positional_params.tail)
  when has_keywords?
    without_keywords()
  else
    raise "Cannot drop from empty params"
  end
end

#each_positional_param(&block) ⇒ Object



858
859
860
861
862
863
864
865
866
# File 'lib/steep/interface/function.rb', line 858

def each_positional_param(&block)
  if block_given?
    if positional_params
      positional_params.each(&block)
    end
  else
    enum_for :each_positional_param
  end
end

#each_type(&block) ⇒ Object



883
884
885
886
887
888
889
890
# File 'lib/steep/interface/function.rb', line 883

def each_type(&block)
  if block
    positional_params&.each_type(&block)
    keyword_params.each_type(&block)
  else
    enum_for :each_type
  end
end

#empty?Boolean

Returns:

  • (Boolean)


943
944
945
# File 'lib/steep/interface/function.rb', line 943

def empty?
  !has_positional? && !has_keywords?
end

#first_paramObject



790
791
792
# File 'lib/steep/interface/function.rb', line 790

def first_param
  positional_params&.head
end

#flat_keywordsObject



838
839
840
# File 'lib/steep/interface/function.rb', line 838

def flat_keywords
  required_keywords.merge(optional_keywords)
end

#flat_unnamed_paramsObject



823
824
825
826
827
828
829
830
831
832
833
834
835
836
# File 'lib/steep/interface/function.rb', line 823

def flat_unnamed_params
  if positional_params
    positional_params.each.with_object([]) do |param, types|
      case param
      when PositionalParams::Required
        types << [:required, param.type]
      when PositionalParams::Optional
        types << [:optional, param.type]
      end
    end
  else
    []
  end
end

#free_variablesObject



892
893
894
895
896
897
898
# File 'lib/steep/interface/function.rb', line 892

def free_variables()
  @fvs ||= Set.new.tap do |set|
    each_type do |type|
      set.merge(type.free_variables)
    end
  end
end

#has_keywords?Boolean

Returns:

  • (Boolean)


854
855
856
# File 'lib/steep/interface/function.rb', line 854

def has_keywords?
  !keyword_params.empty?
end

#has_positional?Boolean

Returns:

  • (Boolean)


803
804
805
# File 'lib/steep/interface/function.rb', line 803

def has_positional?
  positional_params ? true : false
end

#hashObject



819
820
821
# File 'lib/steep/interface/function.rb', line 819

def hash
  self.class.hash ^ positional_params.hash ^ keyword_params.hash
end

#map_type(&block) ⇒ Object



936
937
938
939
940
941
# File 'lib/steep/interface/function.rb', line 936

def map_type(&block)
  self.class.new(
    positional_params: positional_params&.map_type(&block),
    keyword_params: keyword_params.map_type(&block)
  )
end

#optionalObject



742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
# File 'lib/steep/interface/function.rb', line 742

def optional
  array = [] #: Array[AST::Types::t]

  positional_params&.each do |param|
    case param
    when PositionalParams::Required
      # skip
    when PositionalParams::Optional
      array << param.type
    else
      break
    end
  end

  array
end

#optional?Boolean

Returns true if all arguments are non-required.

Returns:

  • (Boolean)


948
949
950
# File 'lib/steep/interface/function.rb', line 948

def optional?
  required.empty? && required_keywords.empty?
end

#optional_keywordsObject



846
847
848
# File 'lib/steep/interface/function.rb', line 846

def optional_keywords
  keyword_params.optionals
end

#requiredObject



727
728
729
730
731
732
733
734
735
736
737
738
739
740
# File 'lib/steep/interface/function.rb', line 727

def required
  array = [] #: Array[AST::Types::t]

  positional_params&.each do |param|
    case param
    when PositionalParams::Required
      array << param.type
    else
      break
    end
  end

  array
end

#required_keywordsObject



842
843
844
# File 'lib/steep/interface/function.rb', line 842

def required_keywords
  keyword_params.requireds
end

#restObject



759
760
761
762
763
764
765
766
767
768
769
770
# File 'lib/steep/interface/function.rb', line 759

def rest
  positional_params&.each do |param|
    case param
    when PositionalParams::Required, PositionalParams::Optional
      # skip
    when PositionalParams::Rest
      return param.type
    end
  end

  nil
end

#rest_keywordsObject



850
851
852
# File 'lib/steep/interface/function.rb', line 850

def rest_keywords
  keyword_params.rest
end

#sizeObject



922
923
924
# File 'lib/steep/interface/function.rb', line 922

def size
  (positional_params&.size || 0) + keyword_params.size
end

#subst(s) ⇒ Object



904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
# File 'lib/steep/interface/function.rb', line 904

def subst(s)
  return self if s.empty?
  return self if empty?
  return self if each_type.none? {|t| s.apply?(t) }

  pp = positional_params
  kp = keyword_params

  if positional_params && positional_params.each_type.any? {|t| s.apply?(t) }
    pp = positional_params.subst(s)
  end
  if keyword_params && keyword_params.each_type.any? {|t| s.apply?(t) }
    kp = keyword_params.subst(s)
  end

  self.class.new(positional_params: pp, keyword_params: kp)
end

#to_sObject



926
927
928
929
930
931
932
933
934
# File 'lib/steep/interface/function.rb', line 926

def to_s
  required = self.required.map {|ty| ty.to_s }
  optional = self.optional.map {|ty| "?#{ty}" }
  rest = self.rest ? ["*#{self.rest}"] : [] #: Array[String]
  required_keywords = keyword_params.requireds.map {|name, type| "#{name}: #{type}" }
  optional_keywords = keyword_params.optionals.map {|name, type| "?#{name}: #{type}"}
  rest_keywords = keyword_params.rest ? ["**#{keyword_params.rest}"] : [] #: Array[String]
  "(#{(required + optional + rest + required_keywords + optional_keywords + rest_keywords).join(", ")})"
end

#update(positional_params: self.positional_params, keyword_params: self.keyword_params) ⇒ Object



786
787
788
# File 'lib/steep/interface/function.rb', line 786

def update(positional_params: self.positional_params, keyword_params: self.keyword_params)
  self.class.new(positional_params: positional_params, keyword_params: keyword_params)
end

#with_first_param(param) ⇒ Object



794
795
796
797
798
799
800
801
# File 'lib/steep/interface/function.rb', line 794

def with_first_param(param)
  update(
    positional_params: PositionalParams.new(
      head: param,
      tail: positional_params
    )
  )
end

#without_keywordsObject



868
869
870
# File 'lib/steep/interface/function.rb', line 868

def without_keywords
  update(keyword_params: KeywordParams.new)
end

#|(other) ⇒ Object

Returns the union between self and other.

 self <: (self | other)
other <: (self | other)

‘self | other` accept `arg` if `self` accepts `arg` or `other` accepts `arg`.



981
982
983
984
985
# File 'lib/steep/interface/function.rb', line 981

def |(other)
  pp = PositionalParams.merge_for_union(positional_params, other.positional_params) rescue return
  kp = keyword_params | other.keyword_params or return
  Params.new(positional_params: pp, keyword_params: kp)
end