diff --git a/lib/spoom.rb b/lib/spoom.rb index 81f7cb82..30d312a2 100644 --- a/lib/spoom.rb +++ b/lib/spoom.rb @@ -22,3 +22,5 @@ class Error < StandardError; end require "spoom/sorbet" require "spoom/cli" require "spoom/version" + +require "spoom/ext/prism_types" diff --git a/lib/spoom/ext/prism_types.rb b/lib/spoom/ext/prism_types.rb new file mode 100644 index 00000000..2187aa12 --- /dev/null +++ b/lib/spoom/ext/prism_types.rb @@ -0,0 +1,14 @@ +# typed: strict +# frozen_string_literal: true + +module Spoom + module PrismTypes + # Ideally this would just be in a shim in `sorbet/rbi/shims/prism.rbi`, but that causes + # `bundle exec tapioca gem spoom` to fail. It Spoom's translator to rewrite the RBS signature comments into Sigs, + # which try to access the `Prism::AnyScopeNode` constant. + # Because shims aren't executed, no such constant exists at runtime, and the Sig raises a NameError. + # + # So instead, we define it here, where the translator can reify it into a real Sorbet `T.type_alias` at runtime. + #: type anyScopeNode = ::Prism::ClassNode | ::Prism::ModuleNode | ::Prism::SingletonClassNode + end +end diff --git a/lib/spoom/sorbet/metrics/code_metrics_visitor.rb b/lib/spoom/sorbet/metrics/code_metrics_visitor.rb index b6ed0f66..4066954d 100644 --- a/lib/spoom/sorbet/metrics/code_metrics_visitor.rb +++ b/lib/spoom/sorbet/metrics/code_metrics_visitor.rb @@ -147,7 +147,7 @@ def visit_call_node(node) private - #: (Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode) { -> void } -> void + #: (PrismTypes::anyScopeNode) { -> void } -> void def visit_scope(node, &block) key = node_key(node) @counters.increment(key) @@ -216,7 +216,7 @@ def collect_last_srb_sigs sigs end - #: (Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode) -> String + #: (PrismTypes::anyScopeNode) -> String def node_key(node) case node when Prism::ClassNode diff --git a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb index 2528ffe5..74979c7d 100644 --- a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb +++ b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb @@ -199,7 +199,7 @@ def apply_overloads_strategy(signatures, method_name:, location:) end end - #: (Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode) -> void + #: (PrismTypes::anyScopeNode) -> void def apply_class_annotations(node) comments = node_rbs_comments(node) return if comments.empty? @@ -324,7 +324,7 @@ def apply_member_annotations(annotations, sig) end end - #: (Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode, Regexp) -> bool + #: (PrismTypes::anyScopeNode, Regexp) -> bool def already_extends?(node, constant_regex) node.child_nodes.any? do |c| next false unless c.is_a?(Prism::CallNode) diff --git a/lib/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments.rb b/lib/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments.rb index 619454e2..c6cc2c70 100644 --- a/lib/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments.rb +++ b/lib/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments.rb @@ -134,7 +134,7 @@ def visit_constant_write_node(node) private - #: (Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode) { -> void } -> void + #: (PrismTypes::anyScopeNode) { -> void } -> void def visit_scope(node, &block) old_class_annotations = @class_annotations @class_annotations = [] @@ -229,7 +229,7 @@ def visit_extend(node) end end - #: (Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode, Prism::CallNode) -> void + #: (PrismTypes::anyScopeNode, Prism::CallNode) -> void def apply_class_annotation(parent, node) unless node.message == "abstract!" || node.message == "interface!" || node.message == "sealed!" || node.message == "final!" || node.message == "requires_ancestor" diff --git a/rbi/spoom.rbi b/rbi/spoom.rbi index a66ee297..308e511e 100644 --- a/rbi/spoom.rbi +++ b/rbi/spoom.rbi @@ -2572,6 +2572,8 @@ class Spoom::Printer def printt; end end +module Spoom::PrismTypes; end +Spoom::PrismTypes::AnyScopeNode = T.type_alias { T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode) } module Spoom::RBS; end class Spoom::RBS::Annotation < ::Spoom::RBS::Comment; end