Class: Tapioca::Gem::Pipeline
- Inherits:
-
Object
- Object
- Tapioca::Gem::Pipeline
- Includes:
- RBIHelper, Runtime::Reflection
- Defined in:
- lib/tapioca/gem/pipeline.rb
Defined Under Namespace
Classes: MethodDefinitionLookupResult, MethodInGemWithLocation, MethodInGemWithoutLocation, MethodNotInGem, MethodUnknown
Constant Summary collapse
- IGNORED_SYMBOLS =
: Array
["YAML", "MiniTest", "Mutex"]
Constants included from SorbetHelper
SorbetHelper::FEATURE_REQUIREMENTS, SorbetHelper::SORBET_BIN, SorbetHelper::SORBET_EXE_PATH_ENV_VAR, SorbetHelper::SORBET_GEM_SPEC, SorbetHelper::SORBET_PAYLOAD_URL, SorbetHelper::SPOOM_CONTEXT
Constants included from Runtime::Reflection
Runtime::Reflection::ANCESTORS_METHOD, Runtime::Reflection::CLASS_METHOD, Runtime::Reflection::CONSTANTS_METHOD, Runtime::Reflection::EQUAL_METHOD, Runtime::Reflection::METHOD_METHOD, Runtime::Reflection::NAME_METHOD, Runtime::Reflection::OBJECT_ID_METHOD, Runtime::Reflection::PRIVATE_INSTANCE_METHODS_METHOD, Runtime::Reflection::PROTECTED_INSTANCE_METHODS_METHOD, Runtime::Reflection::PUBLIC_INSTANCE_METHODS_METHOD, Runtime::Reflection::REQUIRED_FROM_LABELS, Runtime::Reflection::SINGLETON_CLASS_METHOD, Runtime::Reflection::SUPERCLASS_METHOD, Runtime::Reflection::SignatureBlockError, Runtime::Reflection::UNDEFINED_CONSTANT
Instance Attribute Summary collapse
-
#error_handler ⇒ Object
readonly
: ^(String error) -> void.
-
#gem ⇒ Object
readonly
: Gemfile::GemSpec.
Instance Method Summary collapse
-
#compile ⇒ Object
: -> RBI::Tree.
-
#constant_in_gem?(name) ⇒ Boolean
: ((String | Symbol) name) -> bool.
-
#initialize(gem, error_handler:, include_doc: false, include_loc: false) ⇒ Pipeline
constructor
: (Gemfile::GemSpec gem, error_handler: ^(String error) -> void, ?include_doc: bool, ?include_loc: bool) -> void.
-
#method_definition_in_gem(method_name, owner) ⇒ Object
: (Symbol method_name, T::Module owner) -> MethodDefinitionLookupResult.
-
#name_of(constant) ⇒ Object
: (T::Module constant) -> String?.
-
#push_const(symbol, constant, node) ⇒ Object
: (String symbol, T::Module constant, RBI::Const node) -> void.
-
#push_constant(symbol, constant) ⇒ Object
: (String symbol, BasicObject constant) -> void.
-
#push_foreign_constant(symbol, constant) ⇒ Object
: (String symbol, T::Module constant) -> void.
-
#push_foreign_scope(symbol, constant, node) ⇒ Object
: (String symbol, T::Module constant, RBI::Scope node) -> void.
-
#push_method(symbol, constant, method, node, signature, parameters) ⇒ Object
: ( | String symbol, | T::Module constant, | UnboundMethod method, | RBI::Method node, | untyped signature, | Array[[Symbol, String]] parameters | ) -> void.
-
#push_scope(symbol, constant, node) ⇒ Object
: (String symbol, T::Module constant, RBI::Scope node) -> void.
-
#push_symbol(symbol) ⇒ Object
: (String symbol) -> void.
-
#symbol_in_payload?(symbol_name) ⇒ Boolean
: (String symbol_name) -> bool.
Methods included from RBIHelper
#as_nilable_type, #as_non_nilable_type, #create_block_param, #create_kw_opt_param, #create_kw_param, #create_kw_rest_param, #create_opt_param, #create_param, #create_rest_param, #create_typed_param, #sanitize_signature_types, serialize_type_variable, #valid_method_name?, #valid_parameter_name?
Methods included from SorbetHelper
#sorbet, #sorbet_path, #sorbet_supports?
Methods included from Runtime::Reflection
#abstract_type_of, #ancestors_of, #are_equal?, #attached_class_of, #class_of, #const_source_location, #constant_defined?, #constantize, #constants_of, #descendants_of, #file_candidates_for, #final_module?, #inherited_ancestors_of, #method_of, #name_of_type, #object_id_of, #private_instance_methods_of, #protected_instance_methods_of, #public_instance_methods_of, #qualified_name_of, #resolve_loc, #sealed_module?, #signature_of, #signature_of!, #singleton_class_of, #superclass_of
Constructor Details
#initialize(gem, error_handler:, include_doc: false, include_loc: false) ⇒ Pipeline
: (Gemfile::GemSpec gem, error_handler: ^(String error) -> void, ?include_doc: bool, ?include_loc: bool) -> void
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/tapioca/gem/pipeline.rb', line 19 def initialize( gem, error_handler:, include_doc: false, include_loc: false ) @root = RBI::Tree.new #: RBI::Tree @gem = gem @seen = Set.new #: Set[String] @alias_namespace = Set.new #: Set[String] @error_handler = error_handler @events = [] #: Array[Gem::Event] @payload_symbols = Static::SymbolLoader.payload_symbols #: Set[String] @bootstrap_symbols = load_bootstrap_symbols(@gem) #: Set[String] @bootstrap_symbols.each { |symbol| push_symbol(symbol) } @node_listeners = [] #: Array[Gem::Listeners::Base] @node_listeners << Gem::Listeners::SorbetTypeVariables.new(self) @node_listeners << Gem::Listeners::Mixins.new(self) @node_listeners << Gem::Listeners::DynamicMixins.new(self) @node_listeners << Gem::Listeners::Methods.new(self) @node_listeners << Gem::Listeners::SorbetHelpers.new(self) @node_listeners << Gem::Listeners::SorbetEnums.new(self) @node_listeners << Gem::Listeners::SorbetProps.new(self) @node_listeners << Gem::Listeners::SorbetRequiredAncestors.new(self) @node_listeners << Gem::Listeners::SorbetSignatures.new(self) @node_listeners << Gem::Listeners::Subconstants.new(self) @node_listeners << Gem::Listeners::YardDoc.new(self) if include_doc @node_listeners << Gem::Listeners::ForeignConstants.new(self) @node_listeners << Gem::Listeners::SourceLocation.new(self) if include_loc @node_listeners << Gem::Listeners::RemoveEmptyPayloadScopes.new(self) end |
Instance Attribute Details
#error_handler ⇒ Object (readonly)
: ^(String error) -> void
16 17 18 |
# File 'lib/tapioca/gem/pipeline.rb', line 16 def error_handler @error_handler end |
#gem ⇒ Object (readonly)
: Gemfile::GemSpec
13 14 15 |
# File 'lib/tapioca/gem/pipeline.rb', line 13 def gem @gem end |
Instance Method Details
#compile ⇒ Object
: -> RBI::Tree
56 57 58 59 |
# File 'lib/tapioca/gem/pipeline.rb', line 56 def compile dispatch(next_event) until @events.empty? @root end |
#constant_in_gem?(name) ⇒ Boolean
: ((String | Symbol) name) -> bool
117 118 119 120 121 122 123 124 |
# File 'lib/tapioca/gem/pipeline.rb', line 117 def constant_in_gem?(name) loc = const_source_location(name) # If the source location of the constant isn't available or is "(eval)", all bets are off. return true if loc.nil? || loc.file.nil? || loc.file == "(eval)" gem.contains_path?(loc.file) end |
#method_definition_in_gem(method_name, owner) ⇒ Object
: (Symbol method_name, T::Module owner) -> MethodDefinitionLookupResult
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/tapioca/gem/pipeline.rb', line 153 def method_definition_in_gem(method_name, owner) definitions = Tapioca::Runtime::Trackers::MethodDefinition.method_definitions_for(method_name, owner) # If the source location of the method isn't available, signal that by returning nil. return MethodUnknown.new if definitions.empty? # Look up the first entry that matches a file in the gem. found = definitions.find { |loc| @gem.contains_path?(loc.file) } unless found # If the source location of the method is "(eval)", err on the side of caution and include the method. found = definitions.find { |loc| loc.file == "(eval)" } # However, we can just return true to signal that the method should be included. # We can't provide a source location for it, but we want it to be included in the gem RBI. return MethodInGemWithoutLocation.new if found end # If we searched but couldn't find a source location in the gem, return false to signal that. return MethodNotInGem.new unless found MethodInGemWithLocation.new(found) end |
#name_of(constant) ⇒ Object
: (T::Module constant) -> String?
179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/tapioca/gem/pipeline.rb', line 179 def name_of(constant) name = name_of_proxy_target(constant, super(class_of(constant))) return name if name name = super(constant) return if name.nil? return unless are_equal?(constant, constantize(name, inherit: true)) name = "Struct" if name =~ /^(::)?Struct::[^:]+$/ name end |
#push_const(symbol, constant, node) ⇒ Object
: (String symbol, T::Module constant, RBI::Const node) -> void
80 81 82 |
# File 'lib/tapioca/gem/pipeline.rb', line 80 def push_const(symbol, constant, node) @events << Gem::ConstNodeAdded.new(symbol, constant, node) end |
#push_constant(symbol, constant) ⇒ Object
: (String symbol, BasicObject constant) -> void
70 71 72 |
# File 'lib/tapioca/gem/pipeline.rb', line 70 def push_constant(symbol, constant) @events << Gem::ConstantFound.new(symbol, constant) end |
#push_foreign_constant(symbol, constant) ⇒ Object
: (String symbol, T::Module constant) -> void
75 76 77 |
# File 'lib/tapioca/gem/pipeline.rb', line 75 def push_foreign_constant(symbol, constant) @events << Gem::ForeignConstantFound.new(symbol, constant) end |
#push_foreign_scope(symbol, constant, node) ⇒ Object
: (String symbol, T::Module constant, RBI::Scope node) -> void
90 91 92 |
# File 'lib/tapioca/gem/pipeline.rb', line 90 def push_foreign_scope(symbol, constant, node) @events << Gem::ForeignScopeNodeAdded.new(symbol, constant, node) end |
#push_method(symbol, constant, method, node, signature, parameters) ⇒ Object
: ( | String symbol, | T::Module constant, | UnboundMethod method, | RBI::Method node, | untyped signature, | Array[[Symbol, String]] parameters | ) -> void
102 103 104 |
# File 'lib/tapioca/gem/pipeline.rb', line 102 def push_method(symbol, constant, method, node, signature, parameters) # rubocop:disable Metrics/ParameterLists @events << Gem::MethodNodeAdded.new(symbol, constant, method, node, signature, parameters) end |
#push_scope(symbol, constant, node) ⇒ Object
: (String symbol, T::Module constant, RBI::Scope node) -> void
85 86 87 |
# File 'lib/tapioca/gem/pipeline.rb', line 85 def push_scope(symbol, constant, node) @events << Gem::ScopeNodeAdded.new(symbol, constant, node) end |
#push_symbol(symbol) ⇒ Object
: (String symbol) -> void
64 65 66 |
# File 'lib/tapioca/gem/pipeline.rb', line 64 def push_symbol(symbol) @events << Gem::SymbolFound.new(symbol) end |
#symbol_in_payload?(symbol_name) ⇒ Boolean
: (String symbol_name) -> bool
109 110 111 112 113 114 |
# File 'lib/tapioca/gem/pipeline.rb', line 109 def symbol_in_payload?(symbol_name) symbol_name = symbol_name[2..-1] if symbol_name.start_with?("::") return false unless symbol_name @payload_symbols.include?(symbol_name) end |