Class: T::Types::Base
- Inherits:
-
Object
- Object
- T::Types::Base
- Defined in:
- lib/types/types/base.rb
Direct Known Subclasses
Private::Types::NotTyped, Private::Types::StringHolder, Private::Types::TypeAlias, Private::Types::Void, Anything, AttachedClassType, ClassOf, Enum, FixedArray, FixedHash, Intersection, NoReturn, Proc, SelfType, Simple, TEnum, TypeParameter, TypeVariable, TypedClass, TypedEnumerable, Union, Untyped
Class Method Summary collapse
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
Type equivalence, defined by serializing the type to a string (with ‘#name`) and comparing the resulting strings for equality.
- #describe_obj(obj) ⇒ Object
- #error_message_for_obj(obj) ⇒ Object
- #error_message_for_obj_recursive(obj) ⇒ Object
-
#hash ⇒ Object
Equality methods (necessary for deduping types with ‘uniq`).
-
#name ⇒ Object
Equality is based on name, so be sure the name reflects all relevant state when implementing.
-
#recursively_valid?(obj) ⇒ Boolean
this will be redefined in certain subclasses.
-
#subtype_of?(t2) ⇒ Boolean
Mirrors ruby_typer::core::Types::isSubType See git.corp.stripe.com/stripe-internal/ruby-typer/blob/9fc8ed998c04ac0b96592ae6bb3493b8a925c5c1/core/types/subtyping.cc#L912-L950.
- #to_s ⇒ Object
- #valid?(obj) ⇒ Boolean
- #validate!(obj) ⇒ Object
Class Method Details
.method_added(method_name) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/types/types/base.rb', line 6 def self.method_added(method_name) super(method_name) # What is now `subtype_of_single?` used to be named `subtype_of?`. Make sure people don't # override the wrong thing. # # NB: Outside of T::Types, we would enforce this by using `sig` and not declaring the method # as overridable, but doing so here would result in a dependency cycle. if method_name == :subtype_of? && self != T::Types::Base raise "`subtype_of?` should not be overridden. You probably want to override " \ "`subtype_of_single?` instead." end end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
Type equivalence, defined by serializing the type to a string (with ‘#name`) and comparing the resulting strings for equality.
175 176 177 178 179 180 181 182 |
# File 'lib/types/types/base.rb', line 175 def ==(other) case other when T::Types::Base other.name == self.name else false end end |
#describe_obj(obj) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/types/types/base.rb', line 120 def describe_obj(obj) # Would be redundant to print class and value in these common cases. case obj when nil, true, false return "type #{obj.class}" end # In rare cases, obj.inspect may fail, or be undefined, so rescue. begin # Default inspect behavior of, eg; `#<Object:0x0...>` is ugly; just print the hash instead, which is more concise/readable. if obj.method(:inspect).owner == Kernel "type #{obj.class} with hash #{obj.hash}" elsif T::Configuration.include_value_in_type_errors? "type #{obj.class} with value #{T::Utils.string_truncate_middle(obj.inspect, 30, 30)}" else "type #{obj.class}" end rescue StandardError, SystemStackError "type #{obj.class} with unprintable value" end end |
#error_message_for_obj(obj) ⇒ Object
142 143 144 145 146 147 148 |
# File 'lib/types/types/base.rb', line 142 def (obj) if valid?(obj) nil else (obj) end end |
#error_message_for_obj_recursive(obj) ⇒ Object
150 151 152 153 154 155 156 |
# File 'lib/types/types/base.rb', line 150 def (obj) if recursively_valid?(obj) nil else (obj) end end |
#hash ⇒ Object
Equality methods (necessary for deduping types with ‘uniq`)
169 170 171 |
# File 'lib/types/types/base.rb', line 169 def hash name.hash end |
#name ⇒ Object
Equality is based on name, so be sure the name reflects all relevant state when implementing.
37 38 39 |
# File 'lib/types/types/base.rb', line 37 def name raise NotImplementedError end |
#recursively_valid?(obj) ⇒ Boolean
this will be redefined in certain subclasses
20 21 22 |
# File 'lib/types/types/base.rb', line 20 def recursively_valid?(obj) valid?(obj) end |
#subtype_of?(t2) ⇒ Boolean
Mirrors ruby_typer::core::Types::isSubType See git.corp.stripe.com/stripe-internal/ruby-typer/blob/9fc8ed998c04ac0b96592ae6bb3493b8a925c5c1/core/types/subtyping.cc#L912-L950
This method cannot be overridden (see ‘method_added` above). Subclasses only need to implement `subtype_of_single?`).
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/types/types/base.rb', line 46 def subtype_of?(t2) t1 = self if t2.is_a?(T::Private::Types::TypeAlias) t2 = t2.aliased_type end if t2.is_a?(T::Types::Anything) return true end if t1.is_a?(T::Private::Types::TypeAlias) return t1.aliased_type.subtype_of?(t2) end if t1.is_a?(T::Types::TypeVariable) || t2.is_a?(T::Types::TypeVariable) # Generics are erased at runtime. Let's treat them like `T.untyped` for # the purpose of things like override checking. return true end # pairs to cover: 1 (_, _) # 2 (_, And) # 3 (_, Or) # 4 (And, _) # 5 (And, And) # 6 (And, Or) # 7 (Or, _) # 8 (Or, And) # 9 (Or, Or) # Note: order of cases here matters! if t1.is_a?(T::Types::Union) # 7, 8, 9 # this will be incorrect if/when we have Type members return t1.types.all? {|t1_member| t1_member.subtype_of?(t2)} end if t2.is_a?(T::Types::Intersection) # 2, 5 # this will be incorrect if/when we have Type members return t2.types.all? {|t2_member| t1.subtype_of?(t2_member)} end if t2.is_a?(T::Types::Union) if t1.is_a?(T::Types::Intersection) # 6 # dropping either of parts eagerly make subtype test be too strict. # we have to try both cases, when we normally try only one return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} || t1.types.any? {|t1_member| t1_member.subtype_of?(t2)} end return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} # 3 end if t1.is_a?(T::Types::Intersection) # 4 # this will be incorrect if/when we have Type members return t1.types.any? {|t1_member| t1_member.subtype_of?(t2)} end # 1; Start with some special cases if t1.is_a?(T::Private::Types::Void) return t2.is_a?(T::Private::Types::Void) end if t1.is_a?(T::Types::Untyped) || t2.is_a?(T::Types::Untyped) return true end # Rest of (1) subtype_of_single?(t2) end |
#to_s ⇒ Object
116 117 118 |
# File 'lib/types/types/base.rb', line 116 def to_s name end |
#valid?(obj) ⇒ Boolean
24 25 26 |
# File 'lib/types/types/base.rb', line 24 def valid?(obj) raise NotImplementedError end |
#validate!(obj) ⇒ Object
162 163 164 165 |
# File 'lib/types/types/base.rb', line 162 def validate!(obj) err = (obj) raise TypeError.new(err) if err end |