Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Use Hash#fetch instead of Hash#[] to resolve type errors #1286

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/steep/expectations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion lib/steep/interface/shape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down
2 changes: 1 addition & 1 deletion lib/steep/server/change_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel a bit strange about the combination of Hash#fetch and Array#<<...

range: change[:range]&.yield_self {|range|
[
range[:start].yield_self {|pos| Services::ContentChange::Position.new(line: pos[:line] + 1, column: pos[:character]) },
Expand Down
10 changes: 5 additions & 5 deletions lib/steep/server/interaction_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion lib/steep/server/type_check_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 4 additions & 4 deletions lib/steep/services/completion_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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?
Expand Down
6 changes: 3 additions & 3 deletions lib/steep/services/goto_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 []
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion lib/steep/services/hover_provider/rbs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions lib/steep/services/hover_provider/ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,22 @@ 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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also a bit strange. The left hand is #[], but the right hand is #fetch. It's a little difficult to understand the behavior for me.

else
methods[singleton_method]
methods.fetch(singleton_method)
end
else
raise "One of the instance_method or singleton_method is required"
end
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)
Expand Down
20 changes: 10 additions & 10 deletions lib/steep/services/type_check_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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] ||= []
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions lib/steep/signature/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions lib/steep/source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions lib/steep/subtyping/check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions lib/steep/subtyping/constraints.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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?
Expand Down
Loading