diff --git a/lib/steep/expectations.rb b/lib/steep/expectations.rb index bcaec8bc3..6d6ba2ed4 100644 --- a/lib/steep/expectations.rb +++ b/lib/steep/expectations.rb @@ -203,7 +203,7 @@ def to_yaml array = [] #: Array[{ "file" => String, "diagnostics" => Array[untyped] }] diagnostics.each_key.sort.each do |key| - ds = diagnostics[key] + ds = diagnostics.fetch(key) array << { "file" => key.to_s, 'diagnostics' => ds.sort_by(&:sort_key).map(&:to_hash) diff --git a/lib/steep/interface/shape.rb b/lib/steep/interface/shape.rb index d307a7529..98684f198 100644 --- a/lib/steep/interface/shape.rb +++ b/lib/steep/interface/shape.rb @@ -125,7 +125,7 @@ def [](name) return nil unless key?(name) resolved_methods[name] ||= begin - entry = methods[name] + entry = methods.fetch(name) Entry.new( method_name: name, overloads: entry.overloads.map do |overload| diff --git a/lib/steep/server/change_buffer.rb b/lib/steep/server/change_buffer.rb index 6a9d002a6..7e86c7862 100644 --- a/lib/steep/server/change_buffer.rb +++ b/lib/steep/server/change_buffer.rb @@ -46,7 +46,7 @@ def collect_changes(request) changes[path] ||= [] request[:params][:contentChanges].each do |change| - changes[path] << Services::ContentChange.new( + changes.fetch(path) << Services::ContentChange.new( range: change[:range]&.yield_self {|range| [ range[:start].yield_self {|pos| Services::ContentChange::Position.new(line: pos[:line] + 1, column: pos[:character]) }, diff --git a/lib/steep/server/interaction_worker.rb b/lib/steep/server/interaction_worker.rb index b7f27f657..f57d37ebe 100644 --- a/lib/steep/server/interaction_worker.rb +++ b/lib/steep/server/interaction_worker.rb @@ -164,7 +164,7 @@ def process_completion(job) case when target = project.target_for_source_path(job.path) file = service.source_files[job.path] or return - subtyping = service.signature_services[target.name].current_subtyping or return + subtyping = service.signature_services.fetch(target.name).current_subtyping or return provider = Services::CompletionProvider.new(source_text: file.content, path: job.path, subtyping: subtyping) items = begin @@ -193,12 +193,12 @@ def process_completion(job) case sig_service.status when Services::SignatureService::SyntaxErrorStatus, Services::SignatureService::AncestorErrorStatus if buffer = sig_service.latest_env.buffers.find {|buf| Pathname(buf.name) == Pathname(relative_path) } - dirs = sig_service.latest_env.signatures[buffer][0] + dirs = sig_service.latest_env.signatures.fetch(buffer)[0] else dirs = [] #: Array[RBS::AST::Directives::t] end else - signature = sig_service.files[relative_path].signature + signature = sig_service.files.fetch(relative_path).signature signature.is_a?(Array) or raise buffer, dirs, decls = signature @@ -219,7 +219,7 @@ def process_completion(job) end end - buffer = RBS::Buffer.new(name: relative_path, content: sig_service.files[relative_path].content) + buffer = RBS::Buffer.new(name: relative_path, content: sig_service.files.fetch(relative_path).content) prefix = Services::TypeNameCompletion::Prefix.parse(buffer, line: job.line, column: job.column) completion = Services::TypeNameCompletion.new(env: sig_service.latest_env, context: context, dirs: dirs) @@ -460,7 +460,7 @@ def process_signature_help(job) Steep.logger.tagged("##{__method__}") do if target = project.target_for_source_path(job.path) file = service.source_files[job.path] or return - subtyping = service.signature_services[target.name].current_subtyping or return + subtyping = service.signature_services.fetch(target.name).current_subtyping or return source = Source.parse(file.content, path: file.path, factory: subtyping.factory) .without_unrelated_defs(line: job.line, column: job.column) diff --git a/lib/steep/server/type_check_worker.rb b/lib/steep/server/type_check_worker.rb index 48baa6b4d..8fb561e08 100644 --- a/lib/steep/server/type_check_worker.rb +++ b/lib/steep/server/type_check_worker.rb @@ -222,7 +222,7 @@ def workspace_symbol_result(query) Steep.measure "Generating workspace symbol list for query=`#{query}`" do provider = Index::SignatureSymbolProvider.new(project: project, assignment: assignment) project.targets.each do |target| - index = service.signature_services[target.name].latest_rbs_index + index = service.signature_services.fetch(target.name).latest_rbs_index provider.indexes[target] = index end diff --git a/lib/steep/services/completion_provider.rb b/lib/steep/services/completion_provider.rb index 5a82b6602..0998963d6 100644 --- a/lib/steep/services/completion_provider.rb +++ b/lib/steep/services/completion_provider.rb @@ -105,9 +105,9 @@ class TypeNameItem < Struct.new(:env, :absolute_type_name, :relative_type_name, def decl case when absolute_type_name.interface? - env.interface_decls[absolute_type_name].decl + env.interface_decls.fetch(absolute_type_name).decl when absolute_type_name.alias? - env.type_alias_decls[absolute_type_name].decl + env.type_alias_decls.fetch(absolute_type_name).decl when absolute_type_name.class? case entry = env.module_class_entry(absolute_type_name) when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry @@ -127,11 +127,11 @@ def comments case when absolute_type_name.interface? - if comment = env.interface_decls[absolute_type_name].decl.comment + if comment = env.interface_decls.fetch(absolute_type_name).decl.comment comments << comment end when absolute_type_name.alias? - if comment = env.type_alias_decls[absolute_type_name].decl.comment + if comment = env.type_alias_decls.fetch(absolute_type_name).decl.comment comments << comment end when absolute_type_name.class? diff --git a/lib/steep/services/goto_service.rb b/lib/steep/services/goto_service.rb index c984b0245..5368d9925 100644 --- a/lib/steep/services/goto_service.rb +++ b/lib/steep/services/goto_service.rb @@ -97,7 +97,7 @@ def type_definition(path:, line:, column:) relative_path = project.relative_path(path) target = type_check.source_file?(relative_path) or return [] - source = type_check.source_files[relative_path] + source = type_check.source_files.fetch(relative_path) typing, signature = type_check_path(target: target, path: relative_path, content: source.content, line: line, column: column) typing or return [] @@ -163,7 +163,7 @@ def query_at(path:, line:, column:) case when target = type_check.source_file?(relative_path) - source = type_check.source_files[relative_path] + source = type_check.source_files.fetch(relative_path) typing, _signature = type_check_path(target: target, path: relative_path, content: source.content, line: line, column: column) if typing node, *parents = typing.source.find_nodes(line: line, column: column) @@ -284,7 +284,7 @@ def query_at(path:, line:, column:) end def type_check_path(target:, path:, content:, line:, column:) - signature_service = type_check.signature_services[target.name] + signature_service = type_check.signature_services.fetch(target.name) subtyping = signature_service.current_subtyping or return source = Source.parse(content, path: path, factory: subtyping.factory) source = source.without_unrelated_defs(line: line, column: column) diff --git a/lib/steep/services/hover_provider/rbs.rb b/lib/steep/services/hover_provider/rbs.rb index bd9785f38..1b7291f22 100644 --- a/lib/steep/services/hover_provider/rbs.rb +++ b/lib/steep/services/hover_provider/rbs.rb @@ -17,7 +17,7 @@ def project end def content_for(target:, path:, line:, column:) - service = self.service.signature_services[target.name] + service = self.service.signature_services.fetch(target.name) env = service.latest_env buffer = env.buffers.find {|buf| buf.name.to_s == path.to_s } or return diff --git a/lib/steep/services/hover_provider/ruby.rb b/lib/steep/services/hover_provider/ruby.rb index 61183665d..ff4fb8cde 100644 --- a/lib/steep/services/hover_provider/ruby.rb +++ b/lib/steep/services/hover_provider/ruby.rb @@ -65,14 +65,14 @@ def project def method_definition_for(factory, type_name, singleton_method: nil, instance_method: nil) case when instance_method - factory.definition_builder.build_instance(type_name).methods[instance_method] + factory.definition_builder.build_instance(type_name).methods.fetch(instance_method) when singleton_method methods = factory.definition_builder.build_singleton(type_name).methods if singleton_method == :new - methods[:new] || methods[:initialize] + methods[:new] || methods.fetch(:initialize) else - methods[singleton_method] + methods.fetch(singleton_method) end else raise "One of the instance_method or singleton_method is required" @@ -80,7 +80,7 @@ def method_definition_for(factory, type_name, singleton_method: nil, instance_me end def typecheck(target, path:, content:, line:, column:) - subtyping = service.signature_services[target.name].current_subtyping or return + subtyping = service.signature_services.fetch(target.name).current_subtyping or return source = Source.parse(content, path: path, factory: subtyping.factory) source = source.without_unrelated_defs(line: line, column: column) resolver = ::RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder) diff --git a/lib/steep/services/type_check_service.rb b/lib/steep/services/type_check_service.rb index 6c9d69c37..0b51ebc93 100644 --- a/lib/steep/services/type_check_service.rb +++ b/lib/steep/services/type_check_service.rb @@ -131,7 +131,7 @@ def signature_diagnostics signature_diagnostics = {} project.targets.each do |target| - service = signature_services[target.name] + service = signature_services.fetch(target.name) service.each_rbs_path do |path| signature_diagnostics[path] ||= [] @@ -142,13 +142,13 @@ def signature_diagnostics service.status.diagnostics.group_by {|diag| diag.location&.buffer&.name&.to_s }.each do |path_string, diagnostics| if path_string path = Pathname(path_string) - signature_diagnostics[path].push(*diagnostics) + signature_diagnostics.fetch(path).push(*diagnostics) end end when SignatureService::LoadedStatus validation_diagnostics = signature_validation_diagnostics[target.name] || {} validation_diagnostics.each do |path, diagnostics| - signature_diagnostics[path].push(*diagnostics) + signature_diagnostics.fetch(path).push(*diagnostics) end end end @@ -197,7 +197,7 @@ def update(changes:) def validate_signature(path:, target:) Steep.logger.tagged "#validate_signature(path=#{path})" do Steep.measure "validation" do - service = signature_services[target.name] + service = signature_services.fetch(target.name) raise unless target.possible_signature_file?(path) || service.env_rbs_paths.include?(path) @@ -264,7 +264,7 @@ def validate_signature(path:, target:) end end - signature_validation_diagnostics[target.name][path] = diagnostics + signature_validation_diagnostics.fetch(target.name)[path] = diagnostics end end end @@ -274,11 +274,11 @@ def typecheck_source(path:, target: project.target_for_source_path(path)) Steep.logger.tagged "#typecheck_source(path=#{path})" do Steep.measure "typecheck" do - signature_service = signature_services[target.name] + signature_service = signature_services.fetch(target.name) subtyping = signature_service.current_subtyping if subtyping - text = source_files[path].content + text = source_files.fetch(path).content file = type_check_file(target: target, subtyping: subtyping, path: path, text: text) { signature_service.latest_constant_resolver } source_files[path] = file @@ -291,11 +291,11 @@ def typecheck_source(path:, target: project.target_for_source_path(path)) def update_signature(changes:, requests:) Steep.logger.tagged "#update_signature" do project.targets.each do |target| - signature_service = signature_services[target.name] + signature_service = signature_services.fetch(target.name) signature_changes = changes.filter {|path, _| target.possible_signature_file?(path) } unless signature_changes.empty? - requests[target].signature_updated! + requests.fetch(target).signature_updated! signature_service.update(signature_changes) end end @@ -318,7 +318,7 @@ def update_sources(changes:, requests:) file = source_files[path] || SourceFile.no_data(path: path, content: "") content = changes.inject(file.content) {|text, change| change.apply_to(text) } source_files[path] = file.update_content(content) - requests[target].source_paths << path + requests.fetch(target).source_paths << path end end end diff --git a/lib/steep/signature/validator.rb b/lib/steep/signature/validator.rb index 46e1a6ef9..34468bcc1 100644 --- a/lib/steep/signature/validator.rb +++ b/lib/steep/signature/validator.rb @@ -130,7 +130,7 @@ def validate_type_application(type) ] when RBS::Types::Alias type_name = env.normalize_type_name?(type.name) or return - entry = env.type_alias_decls[type_name] + entry = env.type_alias_decls.fetch(type_name) [ type_name, @@ -485,7 +485,7 @@ def validate_ancestor_application(name, ancestor) location = case ancestor.source when :super - primary_decl = env.class_decls[name].primary.decl + primary_decl = env.class_decls.fetch(name).primary.decl primary_decl.is_a?(RBS::AST::Declarations::Class) or raise if super_class = primary_decl.super_class super_class.location @@ -594,7 +594,7 @@ def validate_one_global(name, entry) end end - def validate_one_alias(name, entry = env.type_alias_decls[name]) + def validate_one_alias(name, entry = env.type_alias_decls.fetch(name)) *, inner_most_outer_module = entry.outer if inner_most_outer_module class_type = AST::Types::Name::Singleton.new(name: inner_most_outer_module.name) diff --git a/lib/steep/source.rb b/lib/steep/source.rb index 6a13ad39c..6e520187c 100644 --- a/lib/steep/source.rb +++ b/lib/steep/source.rb @@ -88,7 +88,7 @@ def self.parse(source_code, path:, factory:) annotations.each do |annot| map[node] ||= [] - map[node] << annot + map.fetch(node) << annot end ignores = comments.filter_map do |comment| @@ -269,7 +269,7 @@ def self.construct_mapping(node:, annotations:, mapping:, line_range: nil) associated_annotations.each do |annot| mapping[node] ||= [] - mapping[node] << annot + mapping.fetch(node) << annot end annotations.replace(other_annotations) @@ -442,7 +442,7 @@ def without_unrelated_defs(line:, column:) annotations.each do |annot| mapping[node_] ||= [] - mapping[node_] << annot + mapping.fetch(node_) << annot end Source.new(buffer: buffer, path: path, node: node_, mapping: mapping, comments: comments, ignores: ignores) diff --git a/lib/steep/subtyping/check.rb b/lib/steep/subtyping/check.rb index 2c5c0255a..e585fb29c 100644 --- a/lib/steep/subtyping/check.rb +++ b/lib/steep/subtyping/check.rb @@ -1057,10 +1057,10 @@ def match_params(name, relation) sup_flat_kws.each do |name, _| if sub_flat_kws.key?(name) - pairs << [sub_flat_kws[name], sup_flat_kws[name]] + pairs << [sub_flat_kws.fetch(name), sup_flat_kws.fetch(name)] else if sub_params.rest_keywords - pairs << [sub_params.rest_keywords, sup_flat_kws[name]] + pairs << [sub_params.rest_keywords, sup_flat_kws.fetch(name)] else return failure end diff --git a/lib/steep/subtyping/constraints.rb b/lib/steep/subtyping/constraints.rb index db041d894..ad8eae20b 100644 --- a/lib/steep/subtyping/constraints.rb +++ b/lib/steep/subtyping/constraints.rb @@ -102,7 +102,7 @@ def add_var(*vars) end def add(var, sub_type: nil, super_type: nil, skip: false) - subs, supers, skips = dictionary[var] + subs, supers, skips = dictionary.fetch(var) if sub_type.is_a?(AST::Types::Logic::Base) sub_type = AST::Builtin.bool_type @@ -204,7 +204,7 @@ def upper_bound(var, skip: false) if skip upper_bound = upper_bound_types(var) else - _, upper_bound, _ = dictionary[var] + _, upper_bound, _ = dictionary.fetch(var) end case upper_bound.size @@ -320,12 +320,12 @@ def to_s end def lower_bound_types(var_name) - lower, _, _ = dictionary[var_name] + lower, _, _ = dictionary.fetch(var_name) lower end def upper_bound_types(var_name) - _, upper, skips = dictionary[var_name] + _, upper, skips = dictionary.fetch(var_name) case when upper.empty? diff --git a/lib/steep/type_construction.rb b/lib/steep/type_construction.rb index c1ee2a800..b37b1603b 100644 --- a/lib/steep/type_construction.rb +++ b/lib/steep/type_construction.rb @@ -2405,7 +2405,7 @@ def synthesize(node, hint: nil, condition: false) if hint.one_arg? if hint.type.params # Assumes Symbol#to_proc implementation - param_type = hint.type.params.required[0] + param_type = hint.type.params.required.fetch(0) case param_type when AST::Types::Any type = AST::Types::Any.instance @@ -2423,7 +2423,7 @@ def synthesize(node, hint: nil, condition: false) params: Interface::Function::Params.empty.with_first_param( Interface::Function::Params::PositionalParams::Required.new(param_type) ), - return_type: return_types[0], + return_type: return_types.fetch(0), location: nil ), block: nil, @@ -3479,13 +3479,13 @@ def try_special_method(node, receiver_type:, method_name:, method_overload:, arg decls = method_overload.method_decls(method_name).to_set case - when decl = decls.find {|decl| SPECIAL_METHOD_NAMES[:array_compact].include?(decl.method_name) } + when decl = decls.find {|decl| SPECIAL_METHOD_NAMES.fetch(:array_compact).include?(decl.method_name) } if arguments.empty? && !block_params # compact return_type = method_type.type.return_type if AST::Builtin::Array.instance_type?(return_type) # @type var return_type: AST::Types::Name::Instance - elem = return_type.args[0] + elem = return_type.args.fetch(0) type = AST::Builtin::Array.instance_type(unwrap(elem)) _, constr = add_typing(node, type: type) @@ -3502,14 +3502,14 @@ def try_special_method(node, receiver_type:, method_name:, method_overload:, arg return [call, constr] end end - when decl = decls.find {|decl| SPECIAL_METHOD_NAMES[:hash_compact].include?(decl.method_name) } + when decl = decls.find {|decl| SPECIAL_METHOD_NAMES.fetch(:hash_compact).include?(decl.method_name) } if arguments.empty? && !block_params # compact return_type = method_type.type.return_type if AST::Builtin::Hash.instance_type?(return_type) # @type var return_type: AST::Types::Name::Instance - key = return_type.args[0] - value = return_type.args[1] + key = return_type.args.fetch(0) + value = return_type.args.fetch(1) type = AST::Builtin::Hash.instance_type(key, unwrap(value)) _, constr = add_typing(node, type: type) @@ -3526,7 +3526,7 @@ def try_special_method(node, receiver_type:, method_name:, method_overload:, arg return [call, constr] end end - when decl = decls.find {|decl| SPECIAL_METHOD_NAMES[:lambda].include?(decl.method_name) } + when decl = decls.find {|decl| SPECIAL_METHOD_NAMES.fetch(:lambda).include?(decl.method_name) } if block_params # @type var node: Parser::AST::Node & Parser::AST::_BlockNode type, constr = type_lambda(node, params_node: block_params, body_node: block_body, type_hint: hint) @@ -3609,7 +3609,7 @@ def type_method_call(node, method_name:, receiver_type:, method:, arguments:, bl end if fails.one? - call, constr = fails[0] + call, constr = fails.fetch(0) constr.typing.save! @@ -3824,7 +3824,7 @@ def try_method_type(node, receiver_type:, method_name:, method_overload:, argume args_ = [] type_args.each_with_index do |type, index| - param = method_type.type_params[index] + param = method_type.type_params.fetch(index) if upper_bound = param.upper_bound if result = no_subtyping?(sub_type: type.value, super_type: upper_bound) @@ -4903,7 +4903,7 @@ def try_array_type(node, hint) case when AST::Builtin::Array.instance_type?(type) type.is_a?(AST::Types::Name::Instance) or raise - element_types << type.args[0] + element_types << type.args.fetch(0) when type.is_a?(AST::Types::Tuple) element_types.push(*type.types) else @@ -4946,10 +4946,10 @@ def type_hash_record(hash_node, record_type) value_type, constr = constr.synthesize(value_node, hint: hints[key]) if hints.key?(key) - hint_type = hints[key] + hint_type = hints.fetch(key) case when value_type.is_a?(AST::Types::Any) - value_type = hints[key] + value_type = hints.fetch(key) when hint_type.is_a?(AST::Types::Var) value_type = value_type end @@ -5024,8 +5024,8 @@ def type_hash(hash_node, hint:) constr.synthesize(elem_, hint: hint_hash).tap do |(type, _)| if AST::Builtin::Hash.instance_type?(type) # @type var type: AST::Types::Name::Instance - key_types << type.args[0] - value_types << type.args[1] + key_types << type.args.fetch(0) + value_types << type.args.fetch(1) end end end diff --git a/lib/steep/type_inference/context.rb b/lib/steep/type_inference/context.rb index 786f92989..661b102d0 100644 --- a/lib/steep/type_inference/context.rb +++ b/lib/steep/type_inference/context.rb @@ -121,7 +121,7 @@ def initialize(type_params, parent_context: nil) end def [](name) - table[name].upper_bound + table.fetch(name).upper_bound end def upper_bounds diff --git a/lib/steep/type_inference/method_params.rb b/lib/steep/type_inference/method_params.rb index ddb81f489..8ba8ea5f2 100644 --- a/lib/steep/type_inference/method_params.rb +++ b/lib/steep/type_inference/method_params.rb @@ -469,7 +469,7 @@ def self.build(node:, method_type:) has_error = false keywords.each do |keyword| - rest_types << (keyword_params.requireds[keyword] || keyword_params.optionals[keyword]) + rest_types << (keyword_params.requireds[keyword] || keyword_params.optionals.fetch(keyword)) has_error = true end keywords.clear diff --git a/lib/steep/type_inference/type_env.rb b/lib/steep/type_inference/type_env.rb index 02cd96f91..ec7b3f982 100644 --- a/lib/steep/type_inference/type_env.rb +++ b/lib/steep/type_inference/type_env.rb @@ -231,7 +231,7 @@ def join(*envs) envs.each do |env| all_lvar_types.each_key do |name| - all_lvar_types[name] << (env[name] || AST::Builtin.nil_type) + all_lvar_types.fetch(name) << (env[name] || AST::Builtin.nil_type) end end @@ -245,7 +245,7 @@ def join(*envs) .inject {|s1, s2| s1.intersection(s2) } || Set[] pure_call_updates = common_pure_nodes.each_with_object({}) do |node, hash| #$ Hash[Parser::AST::Node, [MethodCall::Typed, AST::Types::t]] - pairs = envs.map {|env| env.pure_method_calls[node] } + pairs = envs.map {|env| env.pure_method_calls.fetch(node) } refined_type = AST::Types::Union.build(types: pairs.map {|call, type| type || call.return_type }) # Any *pure_method_call* can be used because it's *pure*