Class: RBI::Type Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/rbi/type.rb,
lib/rbi/rbs_printer.rb,
lib/rbi/type_parser.rb,
lib/rbi/type_visitor.rb

Overview

This class is abstract.

The base class for all RBI types.

Defined Under Namespace

Classes: All, Any, Anything, AttachedClass, Boolean, Class, ClassOf, Composite, Error, Generic, Nilable, NoReturn, Proc, SelfType, Shape, Simple, Tuple, TypeParameter, Untyped, Visitor, Void

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeType

: -> void



905
906
907
# File 'lib/rbi/type.rb', line 905

def initialize
  @nilable = false #: bool
end

Class Method Details

.all(type1, type2, *types) ⇒ Object

Builds a type that represents an intersection of multiple types like ‘T.all(String, Integer)`.

Note that this method transforms types such as ‘T.all(String, String)` into `String`, so it may return something other than a `All`. : (Type type1, Type type2, *Type types) -> Type



847
848
849
# File 'lib/rbi/type.rb', line 847

def all(type1, type2, *types)
  All.new([type1, type2, *types]).simplify
end

.any(type1, type2, *types) ⇒ Object

Builds a type that represents a union of multiple types like ‘T.any(String, Integer)`.

Note that this method transforms types such as ‘T.any(String, NilClass)` into `T.nilable(String)`, so it may return something other than a `Any`. : (Type type1, Type type2, *Type types) -> Type



856
857
858
# File 'lib/rbi/type.rb', line 856

def any(type1, type2, *types)
  Any.new([type1, type2, *types]).simplify
end

.anythingObject

Builds a type that represents ‘T.anything`. : -> Anything



778
779
780
# File 'lib/rbi/type.rb', line 778

def anything
  Anything.new
end

.attached_classObject

Builds a type that represents ‘T.attached_class`. : -> AttachedClass



784
785
786
# File 'lib/rbi/type.rb', line 784

def attached_class
  AttachedClass.new
end

.booleanObject

Builds a type that represents ‘T::Boolean`. : -> Boolean



790
791
792
# File 'lib/rbi/type.rb', line 790

def boolean
  Boolean.new
end

.class_of(type, type_parameter = nil) ⇒ Object

Builds a type that represents the singleton class of another type like ‘T.class_of(Foo)`. : (Simple type, ?Type? type_parameter) -> ClassOf



828
829
830
# File 'lib/rbi/type.rb', line 828

def class_of(type, type_parameter = nil)
  ClassOf.new(type, type_parameter)
end

.generic(name, *params) ⇒ Object

Builds a type that represents a generic type like ‘T::Array` or `T::Hash[Symbol, Integer]`. : (String name, *(Type | Array) params) -> Generic



864
865
866
# File 'lib/rbi/type.rb', line 864

def generic(name, *params)
  Generic.new(name, *params.flatten)
end

.nilable(type) ⇒ Object

Builds a type that represents a nilable of another type like ‘T.nilable(String)`.

Note that this method transforms types such as ‘T.nilable(T.untyped)` into `T.untyped`, so it may return something other than a `RBI::Type::Nilable`. : (Type type) -> Type



837
838
839
840
# File 'lib/rbi/type.rb', line 837

def nilable(type)
  nilable = Nilable.new(type)
  nilable.simplify
end

.noreturnObject

Builds a type that represents ‘T.noreturn`. : -> NoReturn



796
797
798
# File 'lib/rbi/type.rb', line 796

def noreturn
  NoReturn.new
end

.parse_node(node) ⇒ Object

: (Prism::Node node) -> Type



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rbi/type_parser.rb', line 26

def parse_node(node)
  case node
  when Prism::ConstantReadNode, Prism::ConstantPathNode
    parse_constant(node)
  when Prism::CallNode
    parse_call(node)
  when Prism::ArrayNode
    parse_tuple(node)
  when Prism::HashNode, Prism::KeywordHashNode
    parse_shape(node)
  when Prism::ParenthesesNode
    body = node.body
    raise Error, "Expected exactly 1 child, got 0" unless body.is_a?(Prism::StatementsNode)

    children = body.body
    raise Error, "Expected exactly 1 child, got #{children.size}" unless children.size == 1

    parse_node(
      children.first, #: as !nil
    )
  else
    raise Error, "Unexpected node `#{node}`"
  end
end

.parse_string(string) ⇒ Object

: (String string) -> Type

Raises:



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/rbi/type_parser.rb', line 10

def parse_string(string)
  result = Prism.parse(string)
  unless result.success?
    raise Error, result.errors.map { |e| "#{e.message}." }.join(" ")
  end

  node = result.value
  raise Error, "Expected a type expression, got `#{node.class}`" unless node.is_a?(Prism::ProgramNode)
  raise Error, "Expected a type expression, got nothing" if node.statements.body.empty?
  raise Error, "Expected a single type expression, got `#{node.slice}`" if node.statements.body.size > 1

  node = node.statements.body.first #: as !nil
  parse_node(node)
end

.procObject

Builds a type that represents a proc type like ‘T.proc.void`. : -> Proc



892
893
894
# File 'lib/rbi/type.rb', line 892

def proc
  Proc.new
end

.self_typeObject

Builds a type that represents ‘T.self_type`. : -> SelfType



802
803
804
# File 'lib/rbi/type.rb', line 802

def self_type
  SelfType.new
end

.shape(types = {}) ⇒ Object

Builds a type that represents a shape type like ‘String, age: Integer`. : (?Hash[(String | Symbol), Type] types) -> Shape



884
885
886
# File 'lib/rbi/type.rb', line 884

def shape(types = {})
  Shape.new(types)
end

.simple(name) ⇒ Object

Builds a simple type like ‘String` or `::Foo::Bar`.

It raises a ‘NameError` if the name is not a valid Ruby class identifier. : (String name) -> Simple

Raises:

  • (NameError)


767
768
769
770
771
772
# File 'lib/rbi/type.rb', line 767

def simple(name)
  # TODO: should we allow creating the instance anyway and move this to a `validate!` method?
  raise NameError, "Invalid type name: `#{name}`" unless valid_identifier?(name)

  Simple.new(name)
end

.t_class(type) ⇒ Object

Builds a type that represents the class of another type like ‘T::Class`. : (Type type) -> Class



822
823
824
# File 'lib/rbi/type.rb', line 822

def t_class(type)
  Class.new(type)
end

.tuple(*types) ⇒ Object

Builds a type that represents a tuple type like ‘[String, Integer]`. : (*(Type | Array) types) -> Tuple



878
879
880
# File 'lib/rbi/type.rb', line 878

def tuple(*types)
  Tuple.new(types.flatten)
end

.type_parameter(name) ⇒ Object

Builds a type that represents a type parameter like ‘T.type_parameter(:U)`. : (Symbol name) -> TypeParameter



870
871
872
# File 'lib/rbi/type.rb', line 870

def type_parameter(name)
  TypeParameter.new(name)
end

.untypedObject

Builds a type that represents ‘T.untyped`. : -> Untyped



808
809
810
# File 'lib/rbi/type.rb', line 808

def untyped
  Untyped.new
end

.voidObject

Builds a type that represents ‘void`. : -> Void



814
815
816
# File 'lib/rbi/type.rb', line 814

def void
  Void.new
end

Instance Method Details

#==(other) ⇒ Object

This method is abstract.

: (BasicObject) -> bool



976
# File 'lib/rbi/type.rb', line 976

def ==(other); end

#eql?(other) ⇒ Boolean

: (BasicObject other) -> bool

Returns:



979
980
981
# File 'lib/rbi/type.rb', line 979

def eql?(other)
  self == other
end

#hashObject

: -> Integer



985
986
987
# File 'lib/rbi/type.rb', line 985

def hash
  to_rbi.hash
end

#nilableObject

Returns a new type that is ‘nilable` if it is not already.

If the type is already nilable, it returns itself. “‘ruby type = RBI::Type.simple(“String”) type.to_rbi # => “String” type.nilable.to_rbi # => “T.nilable(String)” type.nilable.nilable.to_rbi # => “T.nilable(String)” “` : -> Type



919
920
921
# File 'lib/rbi/type.rb', line 919

def nilable
  Type.nilable(self)
end

#nilable?Boolean

Returns whether the type is nilable. : -> bool

Returns:



946
947
948
# File 'lib/rbi/type.rb', line 946

def nilable?
  is_a?(Nilable)
end

#non_nilableObject

Returns the non-nilable version of the type. If the type is already non-nilable, it returns itself. If the type is nilable, it returns the inner type.

“‘ruby type = RBI::Type.nilable(RBI::Type.simple(“String”)) type.to_rbi # => “T.nilable(String)” type.non_nilable.to_rbi # => “String” type.non_nilable.non_nilable.to_rbi # => “String” “` : -> Type



934
935
936
937
938
939
940
941
942
# File 'lib/rbi/type.rb', line 934

def non_nilable
  # TODO: Should this logic be moved into a builder method?
  case self
  when Nilable
    type
  else
    self
  end
end

#normalizeObject

This method is abstract.

Returns a normalized version of the type.

Normalized types are meant to be easier to process, not to read. For example, ‘T.any(TrueClass, FalseClass)` instead of `T::Boolean` or `T.any(String, NilClass)` instead of `T.nilable(String)`.

This is the inverse of ‘#simplify`.

: -> Type



960
# File 'lib/rbi/type.rb', line 960

def normalize; end

#rbs_stringObject

: -> String



1240
1241
1242
1243
1244
# File 'lib/rbi/rbs_printer.rb', line 1240

def rbs_string
  p = TypePrinter.new
  p.visit(self)
  p.string
end

#simplifyObject

This method is abstract.

Returns a simplified version of the type.

Simplified types are meant to be easier to read, not to process. For example, ‘T::Boolean` instead of `T.any(TrueClass, FalseClass)` or `T.nilable(String)` instead of `T.any(String, NilClass)`.

This is the inverse of ‘#normalize`.

: -> Type



972
# File 'lib/rbi/type.rb', line 972

def simplify; end

#to_rbiObject

This method is abstract.

: -> String



991
# File 'lib/rbi/type.rb', line 991

def to_rbi; end

#to_sObject

: -> String



995
996
997
# File 'lib/rbi/type.rb', line 995

def to_s
  to_rbi
end