module Steep class TypeConstruction class Pair attr_reader type: AST::Types::t attr_reader constr: TypeConstruction def initialize: (type: AST::Types::t, constr: TypeConstruction) -> void def with: (?type: AST::Types::t, ?constr: TypeConstruction) -> Pair def +: (Pair other) -> Pair def context: () -> TypeInference::Context def to_ary: () -> [AST::Types::t, TypeConstruction, TypeInference::Context] end include NodeHelper attr_reader checker: Subtyping::Check attr_reader source: Source attr_reader annotations: AST::Annotation::Collection attr_reader typing: Typing attr_reader context: TypeInference::Context def module_context: () -> TypeInference::Context::ModuleContext? def method_context: () -> TypeInference::Context::MethodContext? def block_context: () -> TypeInference::Context::BlockContext? def break_context: () -> TypeInference::Context::BreakContext? def self_type: () -> untyped def variable_context: () -> TypeInference::Context::TypeVariableContext def initialize: (checker: untyped, source: untyped, annotations: untyped, typing: untyped, context: untyped) -> void def with_new_typing: (Typing typing) -> TypeConstruction def with_updated_context: (?type_env: TypeInference::TypeEnv) -> TypeConstruction def with: (?annotations: untyped, ?context: TypeInference::Context, ?typing: untyped) -> TypeConstruction def update_context: () { (TypeInference::Context) -> TypeInference::Context } -> TypeConstruction def update_type_env: () { (TypeInference::TypeEnv) -> TypeInference::TypeEnv } -> TypeConstruction def check_relation: (sub_type: AST::Types::t, super_type: AST::Types::t, ?constraints: Subtyping::Constraints) -> Subtyping::Result::Base # This is a variation of `#check_relation` method. # It checks if given subtyping relation `sub_type <: super_type` holds or not, and returns truthy when *doesn't* hold. # # * Returns `nil` if holds # * Returns subclass of `Result::Base` if the subtyping doesn't hold # # This allow you writing a subtyping check as: # # ```ruby # if relation = no_subtyping?(sub_type: type1, super_type: type2) # # Implement error reporting # end # ``` # def no_subtyping?: (sub_type: AST::Types::t, super_type: AST::Types::t, ?constraints: Subtyping::Constraints) -> Subtyping::Result::Base? def for_new_method: (Symbol method_name, Parser::AST::Node node, args: Array[Parser::AST::Node], self_type: untyped, definition: RBS::Definition?) -> TypeConstruction def with_method_constr: (untyped method_name, untyped node, args: untyped, self_type: untyped, definition: untyped) { (untyped) -> untyped } -> untyped def implement_module: (module_name: untyped, annotations: untyped, ?super_name: untyped?) -> untyped def default_module_context: (untyped implement_module_name, nesting: untyped) -> untyped def for_module: (untyped node, untyped new_module_name) -> untyped def with_module_constr: (untyped node, untyped module_name) { (untyped) -> untyped } -> untyped def for_class: (untyped node, untyped new_class_name, untyped super_class_name) -> untyped def with_class_constr: (untyped node, untyped new_class_name, untyped super_class_name) { (untyped) -> untyped } -> untyped def with_sclass_constr: [A] (Parser::AST::Node node, AST::Types::t `type`) { (TypeConstruction?) -> A } -> A def for_sclass: (Parser::AST::Node node, AST::Types::t `type`) -> TypeConstruction? def for_branch: (Parser::AST::Node node, ?break_context: TypeInference::Context::BreakContext?) -> untyped def add_typing: (Parser::AST::Node node, type: AST::Types::t, ?constr: TypeConstruction) -> Pair def add_call: (untyped call) -> untyped def synthesize: (Parser::AST::Node node, ?hint: AST::Types::t?, ?condition: bool) -> Pair def check: (Parser::AST::Node node, AST::Types::t `type`, ?constraints: Subtyping::Constraints) { (AST::Types::t, AST::Types::t, Subtyping::Result::Base) -> void } -> Pair def masgn_lhs?: (untyped lhs) -> untyped def lvasgn: (Parser::AST::Node node, AST::Types::t) -> Pair def ivasgn: (Parser::AST::Node node, AST::Types::t rhs_type) -> Pair def type_masgn: (Parser::AST::Node node) -> Pair def type_masgn_type: (Parser::AST::Node mlhs_node, AST::Types::t? rhs_type, masgn: TypeInference::MultipleAssignment, optional: bool) -> TypeConstruction? def constant_typename: (Parser::AST::Node parent, Symbol name) -> RBS::TypeName? def synthesize_constant: (Parser::AST::Node node, Parser::AST::Node? parent_node, Symbol constant_name) { () -> void } -> [AST::Types::t, TypeConstruction, RBS::TypeName?] def optional_proc?: (untyped `type`) -> (untyped | nil | nil | nil | nil) def type_lambda: (Parser::AST::Node node, params_node: Parser::AST::Node, body_node: Parser::AST::Node, type_hint: AST::Types::t?) -> Pair def synthesize_children: (Parser::AST::Node node, ?skips: Array[Parser::AST::Node]) -> TypeConstruction def type_send_interface: (Parser::AST::Node node, interface: Interface::Interface, receiver: Parser::AST::Node, receiver_type: AST::Types::t, method_name: Symbol, arguments: Array[Parser::AST::Node], block_params: Parser::AST::Node?, block_body: Parser::AST::Node?) -> Pair def type_send: (untyped node, send_node: untyped, block_params: untyped, block_body: untyped, ?unwrap: bool) -> untyped def calculate_interface: (untyped `type`, private: untyped, ?self_type: untyped) -> untyped def expand_self: (untyped `type`) -> untyped SPECIAL_METHOD_NAMES: { array_compact: untyped, hash_compact: untyped } KNOWN_PURE_METHODS: Set[method_name] def try_special_method: (untyped node, receiver_type: untyped, method_name: untyped, method_type: untyped, arguments: untyped, block_params: untyped, block_body: untyped) -> (::Array[untyped] | nil) def type_method_call: ( Parser::AST::Node node, method_name: Symbol, receiver_type: AST::Types::t, method: Interface::Interface::Entry, arguments: Array[Parser::AST::Node], block_params: Parser::AST::Node?, block_body: Parser::AST::Node?, topdown_hint: untyped ) -> [TypeInference::MethodCall::t, TypeConstruction]? def inspect: () -> ::String def with_child_typing: (range: untyped) { (untyped) -> untyped } -> untyped # Bypass :splat and :kwsplat def bypass_splat: (untyped node) { (untyped) -> untyped } -> untyped # Solve a constraint in the block and return a substitution if succeeds. # # * When the constraint has a solution, `#apply_solution` returns a tuple of substituted `MethodType`, `true`, and the substitution. # * When the constraint doesn't have a solution, `#apply_solution` returns a tuple of the original `MethodType`, `false`, and empty substitution. # def apply_solution: ( Array[Diagnostic::Ruby::Base] errors, node: Parser::AST::Node, method_type: Interface::MethodType ) { () -> Interface::Substitution } -> [Interface::MethodType, bool, Interface::Substitution] def eliminate_vars: (untyped `type`, untyped variables, ?to: untyped) -> untyped def try_method_type: (Parser::AST::Node node, receiver_type: AST::Types::t, method_name: Symbol, method_type: Interface::MethodType, arguments: Array[Parser::AST::Node], block_params: Parser::AST::Node?, block_body: Parser::AST::Node?, topdown_hint: untyped) -> [TypeInference::MethodCall::t, TypeConstruction] def type_check_argument: (Parser::AST::Node node, receiver_type: AST::Types::t, type: AST::Types::t, constraints: Subtyping::Constraints, errors: Array[Diagnostic::Ruby::Base], ?report_node: Parser::AST::Node) -> Pair def type_block_without_hint: (node: untyped, block_annotations: untyped, block_params: untyped, block_body: untyped) { () -> untyped } -> untyped # Returns a Pair of # # * TypeConstruction to type check the block, and # * Set of local variable names to unpin after type checking the block # def for_block: ( Parser::AST::Node? body_node, block_params: TypeInference::BlockParams, block_param_hint: TypeInference::MethodParams?, block_type_hint: AST::Types::t?, block_block_hint: Interface::Block?, block_annotations: AST::Annotation::Collection, node_type_hint: AST::Types::t? ) -> TypeConstruction # Synthesize the block body and returns the type of the body # # The constructor can be discarded because it cannot change anything outer than block. # def synthesize_block: (node: Parser::AST::Node, block_type_hint: AST::Types::t?, block_body: Parser::AST::Node?) -> AST::Types::t def nesting: () -> RBS::Resolver::context def absolute_name: (untyped name) -> untyped def union_type: (*AST::Types::t types) -> AST::Types::t def validate_method_definitions: (untyped node, untyped module_name) -> (nil | untyped) def fallback_to_any: (Parser::AST::Node node) ?{ () -> Diagnostic::Ruby::Base } -> Pair def self_class?: (untyped node) -> untyped def namespace_module?: (untyped node) -> (false | untyped) def type_any_rec: (Parser::AST::Node node) -> Pair def unwrap: (untyped `type`) -> untyped def deep_expand_alias: (AST::Types::t `type`) -> AST::Types::t | [A] (AST::Types::t) { (AST::Types::t) -> A } -> A def flatten_union: (untyped `type`) -> untyped def select_flatten_types: (untyped `type`) { () -> untyped } -> untyped def partition_flatten_types: (AST::Types::t `type`) { (AST::Types::t) -> boolish } -> [Array[AST::Types::t], Array[AST::Types::t]] def flatten_array_elements: (untyped `type`) -> untyped def expand_alias: (AST::Types::t `type`) -> AST::Types::t | [A] (AST::Types::t) { (AST::Types::t) -> A } -> A def test_literal_type: (untyped literal, untyped hint) -> (untyped | nil) def to_instance_type: (untyped `type`, ?args: untyped?) -> untyped def try_tuple_type!: (Parser::AST::Node node, ?hint: AST::Types::t?) -> Pair def try_tuple_type: (Parser::AST::Node node, AST::Types::Tuple? hint) -> (nil | untyped) # Try to convert a object of `type` with zero-arity method `method`. # # Returns `nil` when # # 1. The `type` cannot be converted to an interface, or # 2. There is no that `conversion` method defined # # ```ruby # try_convert(`::Object`, :to_s) # Returns `::String` # try_convert(`::String`, :to_ary) # Returns nil # ``` # def try_convert: (AST::Types::t `type`, Symbol method) -> AST::Types::t? def try_array_type: (untyped node, untyped hint) -> untyped # Returns a record type if `hash_node` can have a record type. # # You can give a hint through `record_type` by passing a `AST::Types::Record` object. # If you pass `nil`, then we know the type is expected to be a record, but the detail is not given. # # Returns `nil` when the `hash_node` cannot have a record type. # def type_hash_record: (Parser::AST::Node hash_node, AST::Types::Record? record_type) -> Pair? # Give hash_node a type based on hint. # # * When hint is Record type, it may have record type. # * When hint is union type, it tries recursively with the union cases. # * Otherwise, it tries to be a hash instance. # def type_hash: (untyped hash_node, hint: untyped) -> untyped # Returns the first one from elements of `types` that returns a type `t` where `t <: hint`. # def pick_one_of: (Array[AST::Types::t] types, range: untyped) { (AST::Types::t hint, TypeConstruction) -> Pair? } -> Pair? def save_typing: () -> untyped # Returns `true` if a method call can be identified as _pure_. # # * The `node` is not a call with call # * It always calls _pure_ method # * The `receiver` is _pure_ # * All of the arguments are _pure_ # def pure_send?: (TypeInference::MethodCall::Typed call, Parser::AST::Node receiver, Array[Parser::AST::Node] arguments) -> bool end end