From 5d232694cdb659f60371f1ca5bef7d230b221020 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Wed, 19 Jun 2024 17:53:39 -0400 Subject: [PATCH] Move reference creation to Index Signed-off-by: Alexandre Terrasa --- lib/spoom/deadcode/index.rb | 11 +++- lib/spoom/deadcode/indexer.rb | 65 ++++++++------------ lib/spoom/deadcode/plugins/action_mailer.rb | 2 +- lib/spoom/deadcode/plugins/actionpack.rb | 6 +- lib/spoom/deadcode/plugins/active_model.rb | 10 +-- lib/spoom/deadcode/plugins/active_record.rb | 6 +- lib/spoom/deadcode/plugins/active_support.rb | 2 +- lib/spoom/deadcode/plugins/graphql.rb | 4 +- lib/spoom/deadcode/plugins/ruby.rb | 14 ++--- lib/spoom/deadcode/send.rb | 1 + test/spoom/deadcode/plugins/base_test.rb | 2 +- 11 files changed, 59 insertions(+), 64 deletions(-) diff --git a/lib/spoom/deadcode/index.rb b/lib/spoom/deadcode/index.rb index 944439eb..c959ba61 100644 --- a/lib/spoom/deadcode/index.rb +++ b/lib/spoom/deadcode/index.rb @@ -29,9 +29,14 @@ def define(definition) (@definitions[definition.name] ||= []) << definition end - sig { params(reference: Reference).void } - def reference(reference) - (@references[reference.name] ||= []) << reference + sig { params(name: String, location: Location).void } + def reference_constant(name, location) + (@references[name] ||= []) << Reference.new(name: name, kind: Reference::Kind::Constant, location: location) + end + + sig { params(name: String, location: Location).void } + def reference_method(name, location) + (@references[name] ||= []) << Reference.new(name: name, kind: Reference::Kind::Method, location: location) end # Mark all definitions having a reference of the same name as `alive` diff --git a/lib/spoom/deadcode/indexer.rb b/lib/spoom/deadcode/indexer.rb index 0f75f273..13e8a873 100644 --- a/lib/spoom/deadcode/indexer.rb +++ b/lib/spoom/deadcode/indexer.rb @@ -26,12 +26,12 @@ def initialize(path, source, index, plugins: []) sig { override.params(node: Prism::AliasMethodNode).void } def visit_alias_method_node(node) - reference_method(node.old_name.slice, node) + @index.reference_method(node.old_name.slice, node_location(node)) end sig { override.params(node: Prism::AndNode).void } def visit_and_node(node) - reference_method(node.operator_loc.slice, node) + @index.reference_method(node.operator_loc.slice, node_location(node)) super end @@ -40,7 +40,7 @@ def visit_block_argument_node(node) expression = node.expression case expression when Prism::SymbolNode - reference_method(expression.unescaped, expression) + @index.reference_method(expression.unescaped, node_location(node)) else visit(expression) end @@ -49,24 +49,24 @@ def visit_block_argument_node(node) sig { override.params(node: Prism::CallAndWriteNode).void } def visit_call_and_write_node(node) visit(node.receiver) - reference_method(node.read_name.to_s, node) - reference_method(node.write_name.to_s, node) + @index.reference_method(node.read_name.to_s, node_location(node)) + @index.reference_method(node.write_name.to_s, node_location(node)) visit(node.value) end sig { override.params(node: Prism::CallOperatorWriteNode).void } def visit_call_operator_write_node(node) visit(node.receiver) - reference_method(node.read_name.to_s, node) - reference_method(node.write_name.to_s, node) + @index.reference_method(node.read_name.to_s, node_location(node)) + @index.reference_method(node.write_name.to_s, node_location(node)) visit(node.value) end sig { override.params(node: Prism::CallOrWriteNode).void } def visit_call_or_write_node(node) visit(node.receiver) - reference_method(node.read_name.to_s, node) - reference_method(node.write_name.to_s, node) + @index.reference_method(node.read_name.to_s, node_location(node)) + @index.reference_method(node.write_name.to_s, node_location(node)) visit(node.value) end @@ -79,6 +79,7 @@ def visit_call_node(node) recv: node.receiver, args: node.arguments&.arguments || [], block: node.block, + location: node_location(node), ), ) end @@ -92,19 +93,19 @@ def visit_class_node(node) sig { override.params(node: Prism::ConstantAndWriteNode).void } def visit_constant_and_write_node(node) - reference_constant(node.name.to_s, node) + @index.reference_constant(node.name.to_s, node_location(node)) visit(node.value) end sig { override.params(node: Prism::ConstantOperatorWriteNode).void } def visit_constant_operator_write_node(node) - reference_constant(node.name.to_s, node) + @index.reference_constant(node.name.to_s, node_location(node)) visit(node.value) end sig { override.params(node: Prism::ConstantOrWriteNode).void } def visit_constant_or_write_node(node) - reference_constant(node.name.to_s, node) + @index.reference_constant(node.name.to_s, node_location(node)) visit(node.value) end @@ -113,7 +114,7 @@ def visit_constant_path_node(node) parent = node.parent visit(parent) if parent - reference_constant(node.name.to_s, node) + @index.reference_constant(node.name.to_s, node_location(node)) end sig { override.params(node: Prism::ConstantPathWriteNode).void } @@ -124,7 +125,7 @@ def visit_constant_path_write_node(node) sig { override.params(node: Prism::ConstantReadNode).void } def visit_constant_read_node(node) - reference_constant(node.name.to_s, node) + @index.reference_constant(node.name.to_s, node_location(node)) end sig { override.params(node: Prism::ConstantWriteNode).void } @@ -135,31 +136,31 @@ def visit_constant_write_node(node) sig { override.params(node: Prism::LocalVariableAndWriteNode).void } def visit_local_variable_and_write_node(node) name = node.name.to_s - reference_method(name, node) - reference_method("#{name}=", node) + @index.reference_method(name, node_location(node)) + @index.reference_method("#{name}=", node_location(node)) visit(node.value) end sig { override.params(node: Prism::LocalVariableOperatorWriteNode).void } def visit_local_variable_operator_write_node(node) name = node.name.to_s - reference_method(name, node) - reference_method("#{name}=", node) + @index.reference_method(name, node_location(node)) + @index.reference_method("#{name}=", node_location(node)) visit(node.value) end sig { override.params(node: Prism::LocalVariableOrWriteNode).void } def visit_local_variable_or_write_node(node) name = node.name.to_s - reference_method(name, node) - reference_method("#{name}=", node) + @index.reference_method(name, node_location(node)) + @index.reference_method("#{name}=", node_location(node)) visit(node.value) end sig { override.params(node: Prism::LocalVariableWriteNode).void } def visit_local_variable_write_node(node) visit(node.value) - reference_method("#{node.name}=", node) + @index.reference_method("#{node.name}=", node_location(node)) end sig { override.params(node: Prism::ModuleNode).void } @@ -173,7 +174,7 @@ def visit_multi_write_node(node) node.lefts.each do |const| case const when Prism::LocalVariableTargetNode - reference_method("#{const.name}=", node) + @index.reference_method("#{const.name}=", node_location(node)) end end visit(node.value) @@ -181,7 +182,7 @@ def visit_multi_write_node(node) sig { override.params(node: Prism::OrNode).void } def visit_or_node(node) - reference_method(node.operator_loc.slice, node) + @index.reference_method(node.operator_loc.slice, node_location(node)) super end @@ -193,31 +194,19 @@ def visit_send(send) plugin.internal_on_send(self, send) end - reference_method(send.name, send.node) + @index.reference_method(send.name, send.location) case send.name when "<", ">", "<=", ">=" # For comparison operators, we also reference the `<=>` method - reference_method("<=>", send.node) + @index.reference_method("<=>", send.location) end visit_all(send.args) visit(send.block) end - # Reference indexing - - sig { params(name: String, node: Prism::Node).void } - def reference_constant(name, node) - @index.reference(Reference.new(name: name, kind: Reference::Kind::Constant, location: node_location(node))) - end - - sig { params(name: String, node: Prism::Node).void } - def reference_method(name, node) - @index.reference(Reference.new(name: name, kind: Reference::Kind::Method, location: node_location(node))) - end - - # Node utils + private sig { params(node: Prism::Node).returns(Location) } def node_location(node) diff --git a/lib/spoom/deadcode/plugins/action_mailer.rb b/lib/spoom/deadcode/plugins/action_mailer.rb index 193c8537..c6b6552c 100644 --- a/lib/spoom/deadcode/plugins/action_mailer.rb +++ b/lib/spoom/deadcode/plugins/action_mailer.rb @@ -12,7 +12,7 @@ def on_send(indexer, send) return unless send.recv.nil? && ActionPack::CALLBACKS.include?(send.name) send.each_arg(Prism::SymbolNode) do |arg| - indexer.reference_method(arg.unescaped, send.node) + @index.reference_method(arg.unescaped, send.location) end end end diff --git a/lib/spoom/deadcode/plugins/actionpack.rb b/lib/spoom/deadcode/plugins/actionpack.rb index 32d8b0de..fdf775ef 100644 --- a/lib/spoom/deadcode/plugins/actionpack.rb +++ b/lib/spoom/deadcode/plugins/actionpack.rb @@ -42,7 +42,7 @@ def on_send(indexer, send) arg = send.args.first case arg when Prism::SymbolNode - indexer.reference_method(arg.unescaped, send.node) + @index.reference_method(arg.unescaped, send.location) end send.each_arg_assoc do |key, value| @@ -50,9 +50,9 @@ def on_send(indexer, send) case key when "if", "unless" - indexer.reference_method(value.slice.delete_prefix(":"), send.node) if value + @index.reference_method(value.slice.delete_prefix(":"), send.location) if value else - indexer.reference_constant(camelize(key), send.node) + @index.reference_constant(camelize(key), send.location) end end end diff --git a/lib/spoom/deadcode/plugins/active_model.rb b/lib/spoom/deadcode/plugins/active_model.rb index b8f3cfda..43f2d0e8 100644 --- a/lib/spoom/deadcode/plugins/active_model.rb +++ b/lib/spoom/deadcode/plugins/active_model.rb @@ -17,26 +17,26 @@ def on_send(indexer, send) case send.name when "attribute", "attributes" send.each_arg(Prism::SymbolNode) do |arg| - indexer.reference_method(arg.unescaped, send.node) + @index.reference_method(arg.unescaped, send.location) end when "validate", "validates", "validates!", "validates_each" send.each_arg(Prism::SymbolNode) do |arg| - indexer.reference_method(arg.unescaped, send.node) + @index.reference_method(arg.unescaped, send.location) end send.each_arg_assoc do |key, value| key = key.slice.delete_suffix(":") case key when "if", "unless" - indexer.reference_method(value.slice.delete_prefix(":"), send.node) if value + @index.reference_method(value.slice.delete_prefix(":"), send.location) if value else - indexer.reference_constant(camelize(key), send.node) + @index.reference_constant(camelize(key), send.location) end end when "validates_with" arg = send.args.first if arg.is_a?(Prism::SymbolNode) - indexer.reference_constant(arg.unescaped, send.node) + @index.reference_constant(arg.unescaped, send.location) end end end diff --git a/lib/spoom/deadcode/plugins/active_record.rb b/lib/spoom/deadcode/plugins/active_record.rb index 6301b5a6..885c4016 100644 --- a/lib/spoom/deadcode/plugins/active_record.rb +++ b/lib/spoom/deadcode/plugins/active_record.rb @@ -74,7 +74,7 @@ class ActiveRecord < Base def on_send(indexer, send) if send.recv.nil? && CALLBACKS.include?(send.name) send.each_arg(Prism::SymbolNode) do |arg| - indexer.reference_method(arg.unescaped, send.node) + @index.reference_method(arg.unescaped, send.location) end return end @@ -85,7 +85,7 @@ def on_send(indexer, send) when *CRUD_METHODS send.each_arg_assoc do |key, _value| key = key.slice.delete_suffix(":") - indexer.reference_method("#{key}=", send.node) + @index.reference_method("#{key}=", send.location) end when *ARRAY_METHODS send.each_arg(Prism::ArrayNode) do |arg| @@ -96,7 +96,7 @@ def on_send(indexer, send) next unless assoc.is_a?(Prism::AssocNode) key = assoc.key.slice.delete_suffix(":") - indexer.reference_method("#{key}=", send.node) + @index.reference_method("#{key}=", send.location) end end end diff --git a/lib/spoom/deadcode/plugins/active_support.rb b/lib/spoom/deadcode/plugins/active_support.rb index d7f61e1c..2b39e123 100644 --- a/lib/spoom/deadcode/plugins/active_support.rb +++ b/lib/spoom/deadcode/plugins/active_support.rb @@ -23,7 +23,7 @@ def on_send(indexer, send) return unless send.recv.nil? && SETUP_AND_TEARDOWN_METHODS.include?(send.name) send.each_arg(Prism::SymbolNode) do |arg| - indexer.reference_method(T.must(arg.value), send.node) + @index.reference_method(T.must(arg.value), send.location) end end end diff --git a/lib/spoom/deadcode/plugins/graphql.rb b/lib/spoom/deadcode/plugins/graphql.rb index 341e9063..dc57f877 100644 --- a/lib/spoom/deadcode/plugins/graphql.rb +++ b/lib/spoom/deadcode/plugins/graphql.rb @@ -31,14 +31,14 @@ def on_send(indexer, send) arg = send.args.first return unless arg.is_a?(Prism::SymbolNode) - indexer.reference_method(arg.unescaped, send.node) + @index.reference_method(arg.unescaped, send.location) send.each_arg_assoc do |key, value| key = key.slice.delete_suffix(":") next unless key == "resolver_method" next unless value - indexer.reference_method(value.slice.delete_prefix(":"), send.node) + @index.reference_method(value.slice.delete_prefix(":"), send.location) end end end diff --git a/lib/spoom/deadcode/plugins/ruby.rb b/lib/spoom/deadcode/plugins/ruby.rb index 7b1e3c4e..0374ed39 100644 --- a/lib/spoom/deadcode/plugins/ruby.rb +++ b/lib/spoom/deadcode/plugins/ruby.rb @@ -24,29 +24,29 @@ class Ruby < Base def on_send(indexer, send) case send.name when "const_defined?", "const_get", "const_source_location" - reference_symbol_as_constant(indexer, send, T.must(send.args.first)) + reference_symbol_as_constant(send, T.must(send.args.first)) when "send", "__send__", "try" arg = send.args.first - indexer.reference_method(arg.unescaped, send.node) if arg.is_a?(Prism::SymbolNode) + @index.reference_method(arg.unescaped, send.location) if arg.is_a?(Prism::SymbolNode) when "alias_method" last_arg = send.args.last if last_arg.is_a?(Prism::SymbolNode) || last_arg.is_a?(Prism::StringNode) - indexer.reference_method(last_arg.unescaped, send.node) + @index.reference_method(last_arg.unescaped, send.location) end end end private - sig { params(indexer: Indexer, send: Send, node: Prism::Node).void } - def reference_symbol_as_constant(indexer, send, node) + sig { params(send: Send, node: Prism::Node).void } + def reference_symbol_as_constant(send, node) case node when Prism::SymbolNode - indexer.reference_constant(node.unescaped, send.node) + @index.reference_constant(node.unescaped, send.location) when Prism::StringNode node.unescaped.split("::").each do |name| - indexer.reference_constant(name, send.node) unless name.empty? + @index.reference_constant(name, send.location) unless name.empty? end end end diff --git a/lib/spoom/deadcode/send.rb b/lib/spoom/deadcode/send.rb index 45e39259..d8f2309a 100644 --- a/lib/spoom/deadcode/send.rb +++ b/lib/spoom/deadcode/send.rb @@ -12,6 +12,7 @@ class Send < T::Struct const :recv, T.nilable(Prism::Node), default: nil const :args, T::Array[Prism::Node], default: [] const :block, T.nilable(Prism::Node), default: nil + const :location, Location sig do type_parameters(:T) diff --git a/test/spoom/deadcode/plugins/base_test.rb b/test/spoom/deadcode/plugins/base_test.rb index 9a6e4fdd..7248c61e 100644 --- a/test/spoom/deadcode/plugins/base_test.rb +++ b/test/spoom/deadcode/plugins/base_test.rb @@ -104,7 +104,7 @@ def on_send(indexer, send) return if send.args.empty? method_name = send.args.first.slice.delete_prefix(":") - indexer.reference_method(method_name, send.node) + @index.reference_method(method_name, send.location) end end