From b33d85bc6f89efdf26fa4945b5fbe6fa2785af8b Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:09:21 -0500 Subject: [PATCH 01/11] Rewrite `ExecResult` as a bare Ruby class Signed-off-by: Alexandre Terrasa --- lib/spoom/context/exec.rb | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/spoom/context/exec.rb b/lib/spoom/context/exec.rb index b0ac3ab7..fcb177ba 100644 --- a/lib/spoom/context/exec.rb +++ b/lib/spoom/context/exec.rb @@ -4,11 +4,26 @@ require "shellwords" module Spoom - class ExecResult < T::Struct - const :out, String - const :err, T.nilable(String) - const :status, T::Boolean - const :exit_code, Integer + class ExecResult + #: String + attr_reader :out + + #: String? + attr_reader :err + + #: bool + attr_reader :status + + #: Integer + attr_reader :exit_code + + #: (out: String, status: bool, exit_code: Integer, ?err: String?) -> void + def initialize(out:, status:, exit_code:, err: nil) + @out = out + @err = err + @status = status + @exit_code = exit_code + end #: -> String def to_s From 9961d3630b7b111498c6aff79ecebfa8d5633ebd Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:09:36 -0500 Subject: [PATCH 02/11] Rewrite `Git::Commit` as a bare Ruby class Signed-off-by: Alexandre Terrasa --- lib/spoom/context/git.rb | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/spoom/context/git.rb b/lib/spoom/context/git.rb index 74847fc3..26cc5544 100644 --- a/lib/spoom/context/git.rb +++ b/lib/spoom/context/git.rb @@ -3,7 +3,7 @@ module Spoom module Git - class Commit < T::Struct + class Commit class << self # Parse a line formatted as `%h %at` into a `Commit` #: (String string) -> Commit? @@ -16,8 +16,17 @@ def parse_line(string) end end - const :sha, String - const :time, Time + #: String + attr_reader :sha + + #: Time + attr_reader :time + + #: (sha: String, time: Time) -> void + def initialize(sha:, time:) + @sha = sha + @time = time + end #: -> Integer def timestamp From 6ec9346367bf9de60bfb3c7d56d17daad223694f Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:09:46 -0500 Subject: [PATCH 03/11] Rewrite `ColorPalette` as a bare Ruby class Signed-off-by: Alexandre Terrasa --- lib/spoom/cli/srb/coverage.rb | 10 ++++---- lib/spoom/coverage/d3.rb | 48 ++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/lib/spoom/cli/srb/coverage.rb b/lib/spoom/cli/srb/coverage.rb index fe008b56..24009ace 100644 --- a/lib/spoom/cli/srb/coverage.rb +++ b/lib/spoom/cli/srb/coverage.rb @@ -156,11 +156,11 @@ def report end.filter(&:commit_timestamp).sort_by!(&:commit_timestamp) palette = Spoom::Coverage::D3::ColorPalette.new( - ignore: options[:color_ignore], - false: options[:color_false], - true: options[:color_true], - strict: options[:color_strict], - strong: options[:color_strong], + ignore_color: options[:color_ignore], + false_color: options[:color_false], + true_color: options[:color_true], + strict_color: options[:color_strict], + strong_color: options[:color_strong], ) report = Spoom::Coverage.report(context, snapshots, palette: palette) diff --git a/lib/spoom/coverage/d3.rb b/lib/spoom/coverage/d3.rb index f863623f..76ccdbad 100644 --- a/lib/spoom/coverage/d3.rb +++ b/lib/spoom/coverage/d3.rb @@ -63,17 +63,17 @@ def header_script(palette) function strictnessColor(strictness) { switch(strictness) { case "ignore": - return "#{palette.ignore}"; + return "#{palette.ignore_color}"; case "false": - return "#{palette.false}"; + return "#{palette.false_color}"; case "true": - return "#{palette.true}"; + return "#{palette.true_color}"; case "strict": - return "#{palette.strict}"; + return "#{palette.strict_color}"; case "strong": - return "#{palette.strong}"; + return "#{palette.strong_color}"; } - return "#{palette.false}"; + return "#{palette.false_color}"; } function toPercent(value, sum) { @@ -98,12 +98,36 @@ def header_script(palette) end end - class ColorPalette < T::Struct - prop :ignore, String - prop :false, String - prop :true, String - prop :strict, String - prop :strong, String + class ColorPalette + #: String + attr_accessor :ignore_color + + #: String + attr_accessor :false_color + + #: String + attr_accessor :true_color + + #: String + attr_accessor :strict_color + + #: String + attr_accessor :strong_color + + #: ( + #| ignore_color: String, + #| false_color: String, + #| true_color: String, + #| strict_color: String, + #| strong_color: String + #| ) -> void + def initialize(ignore_color:, false_color:, true_color:, strict_color:, strong_color:) + @ignore_color = ignore_color + @false_color = false_color + @true_color = true_color + @strict_color = strict_color + @strong_color = strong_color + end end end end From c5ee14380dad68b745b9a2945a7ec3bde14d317e Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:11:10 -0500 Subject: [PATCH 04/11] Rewrite `FileTree::Node` as a bare Ruby class Signed-off-by: Alexandre Terrasa --- lib/spoom/file_tree.rb | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/spoom/file_tree.rb b/lib/spoom/file_tree.rb index c135d6b9..d705f26b 100644 --- a/lib/spoom/file_tree.rb +++ b/lib/spoom/file_tree.rb @@ -73,15 +73,27 @@ def print(out: $stdout, colors: true) end # A node representing either a file or a directory inside a FileTree - class Node < T::Struct + class Node # Node parent or `nil` if the node is a root one - const :parent, T.nilable(Node) + #: Node? + attr_reader :parent # File or dir name - const :name, String + + #: String + attr_reader :name # Children of this node (if not empty, it means it's a dir) - const :children, T::Hash[String, Node], default: {} + + #: Hash[String, Node] + attr_reader :children + + #: (name: String, ?parent: Node?, ?children: Hash[String, Node]) -> void + def initialize(name:, parent: nil, children: {}) + @parent = parent + @name = name + @children = children + end # Full path to this node from root #: -> String From bf075aec09e8c35dfeac69ef112d060dd3247a96 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:14:38 -0500 Subject: [PATCH 05/11] Rewrite `Snapshot` as a bare Ruby class Signed-off-by: Alexandre Terrasa --- lib/spoom/coverage/snapshot.rb | 168 ++++++++++++++++++++++++++++----- 1 file changed, 147 insertions(+), 21 deletions(-) diff --git a/lib/spoom/coverage/snapshot.rb b/lib/spoom/coverage/snapshot.rb index 44e19797..b07ec2b9 100644 --- a/lib/spoom/coverage/snapshot.rb +++ b/lib/spoom/coverage/snapshot.rb @@ -3,26 +3,126 @@ module Spoom module Coverage - class Snapshot < T::Struct - prop :timestamp, Integer, default: Time.new.getutc.to_i - prop :version_static, T.nilable(String), default: nil - prop :version_runtime, T.nilable(String), default: nil - prop :duration, Integer, default: 0 - prop :commit_sha, T.nilable(String), default: nil - prop :commit_timestamp, T.nilable(Integer), default: nil - prop :files, Integer, default: 0 - prop :rbi_files, Integer, default: 0 - prop :modules, Integer, default: 0 - prop :classes, Integer, default: 0 - prop :singleton_classes, Integer, default: 0 - prop :methods_without_sig, Integer, default: 0 - prop :methods_with_sig, Integer, default: 0 - prop :calls_untyped, Integer, default: 0 - prop :calls_typed, Integer, default: 0 - prop :sigils, T::Hash[String, Integer], default: Hash.new(0) - prop :methods_with_sig_excluding_rbis, Integer, default: 0 - prop :methods_without_sig_excluding_rbis, Integer, default: 0 - prop :sigils_excluding_rbis, T::Hash[String, Integer], default: Hash.new(0) + class Snapshot + #: Integer + attr_accessor :timestamp + + #: String? + attr_accessor :version_static + + #: String? + attr_accessor :version_runtime + + #: Integer + attr_accessor :duration + + #: String? + attr_accessor :commit_sha + + #: Integer? + attr_accessor :commit_timestamp + + #: Integer + attr_accessor :files + + #: Integer + attr_accessor :rbi_files + + #: Integer + attr_accessor :modules + + #: Integer + attr_accessor :classes + + #: Integer + attr_accessor :singleton_classes + + #: Integer + attr_accessor :methods_without_sig + + #: Integer + attr_accessor :methods_with_sig + + #: Integer + attr_accessor :calls_untyped + + #: Integer + attr_accessor :calls_typed + + #: Hash[String, Integer] + attr_accessor :sigils + + #: Integer + attr_accessor :methods_with_sig_excluding_rbis + + #: Integer + attr_accessor :methods_without_sig_excluding_rbis + + #: Hash[String, Integer] + attr_accessor :sigils_excluding_rbis + + #: ( + #| ?timestamp: Integer, + #| ?version_static: String?, + #| ?version_runtime: String?, + #| ?duration: Integer, + #| ?commit_sha: String?, + #| ?commit_timestamp: Integer?, + #| ?files: Integer, + #| ?rbi_files: Integer, + #| ?modules: Integer, + #| ?classes: Integer, + #| ?singleton_classes: Integer, + #| ?methods_without_sig: Integer, + #| ?methods_with_sig: Integer, + #| ?calls_untyped: Integer, + #| ?calls_typed: Integer, + #| ?sigils: Hash[String, Integer], + #| ?methods_with_sig_excluding_rbis: Integer, + #| ?methods_without_sig_excluding_rbis: Integer, + #| ?sigils_excluding_rbis: Hash[String, Integer], + #| ) -> void + def initialize( + timestamp: Time.new.getutc.to_i, + version_static: nil, + version_runtime: nil, + duration: 0, + commit_sha: nil, + commit_timestamp: nil, + files: 0, + rbi_files: 0, + modules: 0, + classes: 0, + singleton_classes: 0, + methods_without_sig: 0, + methods_with_sig: 0, + calls_untyped: 0, + calls_typed: 0, + sigils: Hash.new(0), + methods_with_sig_excluding_rbis: 0, + methods_without_sig_excluding_rbis: 0, + sigils_excluding_rbis: Hash.new(0) + ) + @timestamp = timestamp + @version_static = version_static + @version_runtime = version_runtime + @duration = duration + @commit_sha = commit_sha + @commit_timestamp = commit_timestamp + @files = files + @rbi_files = rbi_files + @modules = modules + @classes = classes + @singleton_classes = singleton_classes + @methods_without_sig = methods_without_sig + @methods_with_sig = methods_with_sig + @calls_untyped = calls_untyped + @calls_typed = calls_typed + @sigils = sigils + @methods_with_sig_excluding_rbis = methods_with_sig_excluding_rbis + @methods_without_sig_excluding_rbis = methods_without_sig_excluding_rbis + @sigils_excluding_rbis = sigils_excluding_rbis + end # The strictness name as found in the Sorbet metrics file STRICTNESSES = ["ignore", "false", "true", "strict", "strong", "stdlib"].freeze #: Array[String] @@ -35,7 +135,33 @@ def print(out: $stdout, colors: true, indent_level: 0) #: (*untyped arg) -> String def to_json(*arg) - serialize.to_json(*arg) + to_h #: untyped + .to_json(*arg) + end + + #: -> Hash[String, untyped] + def to_h + { + "timestamp" => timestamp, + "version_static" => version_static, + "version_runtime" => version_runtime, + "duration" => duration, + "commit_sha" => commit_sha, + "commit_timestamp" => commit_timestamp, + "files" => files, + "rbi_files" => rbi_files, + "modules" => modules, + "classes" => classes, + "singleton_classes" => singleton_classes, + "methods_with_sig" => methods_with_sig, + "methods_without_sig" => methods_without_sig, + "calls_typed" => calls_typed, + "calls_untyped" => calls_untyped, + "sigils" => sigils, + "methods_with_sig_excluding_rbis" => methods_with_sig_excluding_rbis, + "methods_without_sig_excluding_rbis" => methods_without_sig_excluding_rbis, + "sigils_excluding_rbis" => sigils_excluding_rbis, + } end class << self From 4eaca13d540be15dda6e352814f0453239651c96 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:15:26 -0500 Subject: [PATCH 06/11] Rewrite `Deadcode::Definition` as a bare Ruby class Signed-off-by: Alexandre Terrasa --- lib/spoom/deadcode/definition.rb | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/spoom/deadcode/definition.rb b/lib/spoom/deadcode/definition.rb index 7b4d3226..7933649a 100644 --- a/lib/spoom/deadcode/definition.rb +++ b/lib/spoom/deadcode/definition.rb @@ -4,7 +4,7 @@ module Spoom module Deadcode # A definition is a class, module, method, constant, etc. being defined in the code - class Definition < T::Struct + class Definition class Kind < T::Enum enums do AttrReader = new("attr_reader") @@ -27,11 +27,29 @@ class Status < T::Enum end end - const :kind, Kind - const :name, String - const :full_name, String - const :location, Location - const :status, Status, default: Status::DEAD + #: Kind + attr_reader :kind + + #: String + attr_reader :name + + #: String + attr_reader :full_name + + #: Location + attr_reader :location + + #: Status + attr_reader :status + + #: (kind: Kind, name: String, full_name: String, location: Location, ?status: Status) -> void + def initialize(kind:, name:, full_name:, location:, status: Status::DEAD) + @kind = kind + @name = name + @full_name = full_name + @location = location + @status = status + end # Kind From dfcc5b1fb09e9b8e3d0215cd74952bc17b4a030f Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:16:02 -0500 Subject: [PATCH 07/11] Rewrite `Deadcode::Send` as a bare Ruby class Signed-off-by: Alexandre Terrasa --- lib/spoom/deadcode/send.rb | 42 +++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/lib/spoom/deadcode/send.rb b/lib/spoom/deadcode/send.rb index 32eecdea..22025212 100644 --- a/lib/spoom/deadcode/send.rb +++ b/lib/spoom/deadcode/send.rb @@ -4,13 +4,41 @@ module Spoom module Deadcode # An abstraction to simplify handling of Prism::CallNode nodes. - class Send < T::Struct - const :node, Prism::CallNode - const :name, String - 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 + class Send + #: Prism::CallNode + attr_reader :node + + #: String + attr_reader :name + + #: Prism::Node? + attr_reader :recv + + #: Array[Prism::Node] + attr_reader :args + + #: Prism::Node? + attr_reader :block + + #: Location + attr_reader :location + + #: ( + #| node: Prism::CallNode, + #| name: String, + #| location: Location, + #| ?recv: Prism::Node?, + #| ?args: Array[Prism::Node], + #| ?block: Prism::Node? + #| ) -> void + def initialize(node:, name:, location:, recv: nil, args: [], block: nil) + @node = node + @name = name + @recv = recv + @args = args + @block = block + @location = location + end #: [T] (Class[T] arg_type) { (T arg) -> void } -> void def each_arg(arg_type, &block) From cea0f3c3078a45feb3519772bd64796369ca7eff Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:16:36 -0500 Subject: [PATCH 08/11] Rewrite `Deadcode::Reference` as a bare Ruby class Signed-off-by: Alexandre Terrasa --- lib/spoom/model/reference.rb | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/spoom/model/reference.rb b/lib/spoom/model/reference.rb index 63130ce9..a10192c8 100644 --- a/lib/spoom/model/reference.rb +++ b/lib/spoom/model/reference.rb @@ -7,7 +7,7 @@ class Model # # Constants could be classes, modules, or actual constants. # Methods could be accessors, instance or class methods, aliases, etc. - class Reference < T::Struct + class Reference class Kind < T::Enum enums do Constant = new("constant") @@ -27,9 +27,21 @@ def method(name, location) end end - const :kind, Kind - const :name, String - const :location, Spoom::Location + #: Kind + attr_reader :kind + + #: String + attr_reader :name + + #: Spoom::Location + attr_reader :location + + #: (kind: Kind, name: String, location: Spoom::Location) -> void + def initialize(kind:, name:, location:) + @kind = kind + @name = name + @location = location + end #: -> bool def constant? From 0a27ad96070e854f7d50327502d14f02506d391c Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:20:31 -0500 Subject: [PATCH 09/11] Rewrite `LSP` structs as a bare Ruby classes Signed-off-by: Alexandre Terrasa --- lib/spoom/sorbet/lsp/base.rb | 1 - lib/spoom/sorbet/lsp/structures.rb | 161 +++++++++++++++++++++++------ 2 files changed, 127 insertions(+), 35 deletions(-) diff --git a/lib/spoom/sorbet/lsp/base.rb b/lib/spoom/sorbet/lsp/base.rb index a07d6e04..2e6132e0 100644 --- a/lib/spoom/sorbet/lsp/base.rb +++ b/lib/spoom/sorbet/lsp/base.rb @@ -4,7 +4,6 @@ module Spoom module LSP # Base messaging - # We don't use T::Struct for those so we can subclass them # A general message as defined by JSON-RPC. # diff --git a/lib/spoom/sorbet/lsp/structures.rb b/lib/spoom/sorbet/lsp/structures.rb index 35717359..94cb58a0 100644 --- a/lib/spoom/sorbet/lsp/structures.rb +++ b/lib/spoom/sorbet/lsp/structures.rb @@ -13,11 +13,20 @@ module PrintableSymbol def accept_printer(printer) = raise NotImplementedError, "Abstract method called" end - class Hover < T::Struct + class Hover include PrintableSymbol - const :contents, String - const :range, T.nilable(Range) + #: String + attr_reader :contents + + #: Range? + attr_reader :range + + #: (contents: String, ?range: Range?) -> void + def initialize(contents:, range: nil) + @contents = contents + @range = range + end class << self #: (Hash[untyped, untyped] json) -> Hover @@ -42,11 +51,20 @@ def to_s end end - class Position < T::Struct + class Position include PrintableSymbol - const :line, Integer - const :char, Integer + #: Integer + attr_reader :line + + #: Integer + attr_reader :char + + #: (line: Integer, char: Integer) -> void + def initialize(line:, char:) + @line = line + @char = char + end class << self #: (Hash[untyped, untyped] json) -> Position @@ -70,18 +88,27 @@ def to_s end end - class Range < T::Struct + class Range include PrintableSymbol - const :start, Position - const :end, Position + #: Position + attr_reader :start_pos + + #: Position + attr_reader :end_pos + + #: (start_pos: Position, end_pos: Position) -> void + def initialize(start_pos:, end_pos:) + @start_pos = start_pos + @end_pos = end_pos + end class << self #: (Hash[untyped, untyped] json) -> Range def from_json(json) Range.new( - start: Position.from_json(json["start"]), - end: Position.from_json(json["end"]), + start_pos: Position.from_json(json["start"]), + end_pos: Position.from_json(json["end"]), ) end end @@ -89,22 +116,31 @@ def from_json(json) # @override #: (SymbolPrinter printer) -> void def accept_printer(printer) - printer.print_object(start) + printer.print_object(start_pos) printer.print_colored("-", Color::LIGHT_BLACK) - printer.print_object(self.end) + printer.print_object(end_pos) end #: -> String def to_s - "#{start}-#{self.end}" + "#{start_pos}-#{end_pos}" end end - class Location < T::Struct + class Location include PrintableSymbol - const :uri, String - const :range, LSP::Range + #: String + attr_reader :uri + + #: Range + attr_reader :range + + #: (uri: String, range: Range) -> void + def initialize(uri:, range:) + @uri = uri + @range = range + end class << self #: (Hash[untyped, untyped] json) -> Location @@ -129,12 +165,26 @@ def to_s end end - class SignatureHelp < T::Struct + class SignatureHelp include PrintableSymbol - const :label, T.nilable(String) - const :doc, Object # TODO - const :params, T::Array[T.untyped] # TODO + #: String? + attr_reader :label + + # TODO + #: Object + attr_reader :doc + + # TODO + #: Array[untyped] + attr_reader :params + + #: (doc: Object, params: Array[untyped], ?label: String?) -> void + def initialize(doc:, params:, label: nil) + @label = label + @doc = doc + @params = params + end class << self #: (Hash[untyped, untyped] json) -> SignatureHelp @@ -162,13 +212,28 @@ def to_s end end - class Diagnostic < T::Struct + class Diagnostic include PrintableSymbol - const :range, LSP::Range - const :code, Integer - const :message, String - const :information, Object + #: Range + attr_reader :range + + #: Integer + attr_reader :code + + #: String + attr_reader :message + + #: Object + attr_reader :information + + #: (range: Range, code: Integer, message: String, information: Object) -> void + def initialize(range:, code:, message:, information:) + @range = range + @code = code + @message = message + @information = information + end class << self #: (Hash[untyped, untyped] json) -> Diagnostic @@ -194,15 +259,43 @@ def to_s end end - class DocumentSymbol < T::Struct + class DocumentSymbol include PrintableSymbol - const :name, String - const :detail, T.nilable(String) - const :kind, Integer - const :location, T.nilable(Location) - const :range, T.nilable(Range) - const :children, T::Array[DocumentSymbol] + #: String + attr_reader :name + + #: String? + attr_reader :detail + + #: Integer + attr_reader :kind + + #: Location? + attr_reader :location + + #: Range? + attr_reader :range + + #: Array[DocumentSymbol] + attr_reader :children + + #: ( + #| name: String, + #| kind: Integer, + #| children: Array[DocumentSymbol], + #| ?detail: String?, + #| ?location: Location?, + #| ?range: Range? + #| ) -> void + def initialize(name:, kind:, children:, detail: nil, location: nil, range: nil) + @name = name + @detail = detail + @kind = kind + @location = location + @range = range + @children = children + end class << self #: (Hash[untyped, untyped] json) -> DocumentSymbol @@ -221,7 +314,7 @@ def from_json(json) # @override #: (SymbolPrinter printer) -> void def accept_printer(printer) - h = serialize.hash + h = hash return if printer.seen.include?(h) printer.seen.add(h) From 80a1d3676062284701d52262be152fc4dd5332ba Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:26:24 -0500 Subject: [PATCH 10/11] Enable Sorbet/ForbidTStruct cop Signed-off-by: Alexandre Terrasa --- .rubocop.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index e95c5e02..0d2bd08e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -32,3 +32,6 @@ Sorbet/TrueSigil: Sorbet/EnforceSigilOrder: Enabled: true + +Sorbet/ForbidTStruct: + Enabled: true From f53e5d557b81eb59506fa063065e89a2fe776f9a Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Thu, 8 Jan 2026 11:45:48 -0500 Subject: [PATCH 11/11] Update exported RBI Signed-off-by: Alexandre Terrasa --- rbi/spoom.rbi | 445 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 362 insertions(+), 83 deletions(-) diff --git a/rbi/spoom.rbi b/rbi/spoom.rbi index 13bdac0d..74804a12 100644 --- a/rbi/spoom.rbi +++ b/rbi/spoom.rbi @@ -652,12 +652,42 @@ class Spoom::Coverage::D3::CircleMap::Sigils < ::Spoom::Coverage::D3::CircleMap def tree_node_to_json(node); end end -class Spoom::Coverage::D3::ColorPalette < ::T::Struct - prop :ignore, ::String - prop :false, ::String - prop :true, ::String - prop :strict, ::String - prop :strong, ::String +class Spoom::Coverage::D3::ColorPalette + sig do + params( + ignore_color: ::String, + false_color: ::String, + true_color: ::String, + strict_color: ::String, + strong_color: ::String + ).void + end + def initialize(ignore_color:, false_color:, true_color:, strict_color:, strong_color:); end + + sig { returns(::String) } + def false_color; end + + def false_color=(_arg0); end + + sig { returns(::String) } + def ignore_color; end + + def ignore_color=(_arg0); end + + sig { returns(::String) } + def strict_color; end + + def strict_color=(_arg0); end + + sig { returns(::String) } + def strong_color; end + + def strong_color=(_arg0); end + + sig { returns(::String) } + def true_color; end + + def true_color=(_arg0); end end class Spoom::Coverage::D3::Pie < ::Spoom::Coverage::D3::Base @@ -875,33 +905,136 @@ class Spoom::Coverage::Report < ::Spoom::Coverage::Page def header_html; end end -class Spoom::Coverage::Snapshot < ::T::Struct - prop :timestamp, ::Integer, default: T.unsafe(nil) - prop :version_static, T.nilable(::String), default: T.unsafe(nil) - prop :version_runtime, T.nilable(::String), default: T.unsafe(nil) - prop :duration, ::Integer, default: T.unsafe(nil) - prop :commit_sha, T.nilable(::String), default: T.unsafe(nil) - prop :commit_timestamp, T.nilable(::Integer), default: T.unsafe(nil) - prop :files, ::Integer, default: T.unsafe(nil) - prop :rbi_files, ::Integer, default: T.unsafe(nil) - prop :modules, ::Integer, default: T.unsafe(nil) - prop :classes, ::Integer, default: T.unsafe(nil) - prop :singleton_classes, ::Integer, default: T.unsafe(nil) - prop :methods_without_sig, ::Integer, default: T.unsafe(nil) - prop :methods_with_sig, ::Integer, default: T.unsafe(nil) - prop :calls_untyped, ::Integer, default: T.unsafe(nil) - prop :calls_typed, ::Integer, default: T.unsafe(nil) - prop :sigils, T::Hash[::String, ::Integer], default: T.unsafe(nil) - prop :methods_with_sig_excluding_rbis, ::Integer, default: T.unsafe(nil) - prop :methods_without_sig_excluding_rbis, ::Integer, default: T.unsafe(nil) - prop :sigils_excluding_rbis, T::Hash[::String, ::Integer], default: T.unsafe(nil) +class Spoom::Coverage::Snapshot + sig do + params( + timestamp: ::Integer, + version_static: T.nilable(::String), + version_runtime: T.nilable(::String), + duration: ::Integer, + commit_sha: T.nilable(::String), + commit_timestamp: T.nilable(::Integer), + files: ::Integer, + rbi_files: ::Integer, + modules: ::Integer, + classes: ::Integer, + singleton_classes: ::Integer, + methods_without_sig: ::Integer, + methods_with_sig: ::Integer, + calls_untyped: ::Integer, + calls_typed: ::Integer, + sigils: T::Hash[::String, ::Integer], + methods_with_sig_excluding_rbis: ::Integer, + methods_without_sig_excluding_rbis: ::Integer, + sigils_excluding_rbis: T::Hash[::String, ::Integer] + ).void + end + def initialize(timestamp: T.unsafe(nil), version_static: T.unsafe(nil), version_runtime: T.unsafe(nil), duration: T.unsafe(nil), commit_sha: T.unsafe(nil), commit_timestamp: T.unsafe(nil), files: T.unsafe(nil), rbi_files: T.unsafe(nil), modules: T.unsafe(nil), classes: T.unsafe(nil), singleton_classes: T.unsafe(nil), methods_without_sig: T.unsafe(nil), methods_with_sig: T.unsafe(nil), calls_untyped: T.unsafe(nil), calls_typed: T.unsafe(nil), sigils: T.unsafe(nil), methods_with_sig_excluding_rbis: T.unsafe(nil), methods_without_sig_excluding_rbis: T.unsafe(nil), sigils_excluding_rbis: T.unsafe(nil)); end + + sig { returns(::Integer) } + def calls_typed; end + + def calls_typed=(_arg0); end + + sig { returns(::Integer) } + def calls_untyped; end + + def calls_untyped=(_arg0); end + + sig { returns(::Integer) } + def classes; end + + def classes=(_arg0); end + + sig { returns(T.nilable(::String)) } + def commit_sha; end + + def commit_sha=(_arg0); end + + sig { returns(T.nilable(::Integer)) } + def commit_timestamp; end + + def commit_timestamp=(_arg0); end + + sig { returns(::Integer) } + def duration; end + + def duration=(_arg0); end + + sig { returns(::Integer) } + def files; end + + def files=(_arg0); end + + sig { returns(::Integer) } + def methods_with_sig; end + + def methods_with_sig=(_arg0); end + + sig { returns(::Integer) } + def methods_with_sig_excluding_rbis; end + + def methods_with_sig_excluding_rbis=(_arg0); end + + sig { returns(::Integer) } + def methods_without_sig; end + + def methods_without_sig=(_arg0); end + + sig { returns(::Integer) } + def methods_without_sig_excluding_rbis; end + + def methods_without_sig_excluding_rbis=(_arg0); end + + sig { returns(::Integer) } + def modules; end + + def modules=(_arg0); end sig { params(out: T.any(::IO, ::StringIO), colors: T::Boolean, indent_level: ::Integer).void } def print(out: T.unsafe(nil), colors: T.unsafe(nil), indent_level: T.unsafe(nil)); end + sig { returns(::Integer) } + def rbi_files; end + + def rbi_files=(_arg0); end + + sig { returns(T::Hash[::String, ::Integer]) } + def sigils; end + + def sigils=(_arg0); end + + sig { returns(T::Hash[::String, ::Integer]) } + def sigils_excluding_rbis; end + + def sigils_excluding_rbis=(_arg0); end + + sig { returns(::Integer) } + def singleton_classes; end + + def singleton_classes=(_arg0); end + + sig { returns(::Integer) } + def timestamp; end + + def timestamp=(_arg0); end + + sig { returns(T::Hash[::String, T.untyped]) } + def to_h; end + sig { params(arg: T.untyped).returns(::String) } def to_json(*arg); end + sig { returns(T.nilable(::String)) } + def version_runtime; end + + def version_runtime=(_arg0); end + + sig { returns(T.nilable(::String)) } + def version_static; end + + def version_static=(_arg0); end + class << self sig { params(json: ::String).returns(::Spoom::Coverage::Snapshot) } def from_json(json); end @@ -955,12 +1088,17 @@ end Spoom::Deadcode::DEFAULT_CUSTOM_PLUGINS_PATH = T.let(T.unsafe(nil), String) Spoom::Deadcode::DEFAULT_PLUGINS = T.let(T.unsafe(nil), Set) -class Spoom::Deadcode::Definition < ::T::Struct - const :kind, ::Spoom::Deadcode::Definition::Kind - const :name, ::String - const :full_name, ::String - const :location, ::Spoom::Location - const :status, ::Spoom::Deadcode::Definition::Status, default: T.unsafe(nil) +class Spoom::Deadcode::Definition + sig do + params( + kind: ::Spoom::Deadcode::Definition::Kind, + name: ::String, + full_name: ::String, + location: ::Spoom::Location, + status: ::Spoom::Deadcode::Definition::Status + ).void + end + def initialize(kind:, name:, full_name:, location:, status: T.unsafe(nil)); end sig { void } def alive!; end @@ -983,18 +1121,33 @@ class Spoom::Deadcode::Definition < ::T::Struct sig { returns(T::Boolean) } def dead?; end + sig { returns(::String) } + def full_name; end + sig { void } def ignored!; end sig { returns(T::Boolean) } def ignored?; end + sig { returns(::Spoom::Deadcode::Definition::Kind) } + def kind; end + + sig { returns(::Spoom::Location) } + def location; end + sig { returns(T::Boolean) } def method?; end sig { returns(T::Boolean) } def module?; end + sig { returns(::String) } + def name; end + + sig { returns(::Spoom::Deadcode::Definition::Status) } + def status; end + sig { params(args: T.untyped).returns(::String) } def to_json(*args); end end @@ -1511,13 +1664,24 @@ class Spoom::Deadcode::Remover::NodeRemover def transform_sig(node, name:, kind:); end end -class Spoom::Deadcode::Send < ::T::Struct - const :node, ::Prism::CallNode - const :name, ::String - const :recv, T.nilable(::Prism::Node), default: T.unsafe(nil) - const :args, T::Array[::Prism::Node], default: T.unsafe(nil) - const :block, T.nilable(::Prism::Node), default: T.unsafe(nil) - const :location, ::Spoom::Location +class Spoom::Deadcode::Send + sig do + params( + node: ::Prism::CallNode, + name: ::String, + location: ::Spoom::Location, + recv: T.nilable(::Prism::Node), + args: T::Array[::Prism::Node], + block: T.nilable(::Prism::Node) + ).void + end + def initialize(node:, name:, location:, recv: T.unsafe(nil), args: T.unsafe(nil), block: T.unsafe(nil)); end + + sig { returns(T::Array[::Prism::Node]) } + def args; end + + sig { returns(T.nilable(::Prism::Node)) } + def block; end sig do type_parameters(:T) @@ -1530,15 +1694,37 @@ class Spoom::Deadcode::Send < ::T::Struct sig { params(block: T.proc.params(key: ::Prism::Node, value: T.nilable(::Prism::Node)).void).void } def each_arg_assoc(&block); end + + sig { returns(::Spoom::Location) } + def location; end + + sig { returns(::String) } + def name; end + + sig { returns(::Prism::CallNode) } + def node; end + + sig { returns(T.nilable(::Prism::Node)) } + def recv; end end class Spoom::Error < ::StandardError; end -class Spoom::ExecResult < ::T::Struct - const :out, ::String - const :err, T.nilable(::String) - const :status, T::Boolean - const :exit_code, ::Integer +class Spoom::ExecResult + sig { params(out: ::String, status: T::Boolean, exit_code: ::Integer, err: T.nilable(::String)).void } + def initialize(out:, status:, exit_code:, err: T.unsafe(nil)); end + + sig { returns(T.nilable(::String)) } + def err; end + + sig { returns(::Integer) } + def exit_code; end + + sig { returns(::String) } + def out; end + + sig { returns(T::Boolean) } + def status; end sig { returns(::String) } def to_s; end @@ -1654,10 +1840,24 @@ class Spoom::FileTree::CollectStrictnesses < ::Spoom::FileTree::Visitor def visit_node(node); end end -class Spoom::FileTree::Node < ::T::Struct - const :parent, T.nilable(::Spoom::FileTree::Node) - const :name, ::String - const :children, T::Hash[::String, ::Spoom::FileTree::Node], default: T.unsafe(nil) +class Spoom::FileTree::Node + sig do + params( + name: ::String, + parent: T.nilable(::Spoom::FileTree::Node), + children: T::Hash[::String, ::Spoom::FileTree::Node] + ).void + end + def initialize(name:, parent: T.unsafe(nil), children: T.unsafe(nil)); end + + sig { returns(T::Hash[::String, ::Spoom::FileTree::Node]) } + def children; end + + sig { returns(::String) } + def name; end + + sig { returns(T.nilable(::Spoom::FileTree::Node)) } + def parent; end sig { returns(::String) } def path; end @@ -1697,9 +1897,15 @@ end module Spoom::Git; end -class Spoom::Git::Commit < ::T::Struct - const :sha, ::String - const :time, ::Time +class Spoom::Git::Commit + sig { params(sha: ::String, time: ::Time).void } + def initialize(sha:, time:); end + + sig { returns(::String) } + def sha; end + + sig { returns(::Time) } + def time; end sig { returns(::Integer) } def timestamp; end @@ -1766,17 +1972,27 @@ class Spoom::LSP::Client def type_definitions(uri, line, column); end end -class Spoom::LSP::Diagnostic < ::T::Struct +class Spoom::LSP::Diagnostic include ::Spoom::LSP::PrintableSymbol - const :range, ::Spoom::LSP::Range - const :code, ::Integer - const :message, ::String - const :information, ::Object + sig { params(range: ::Spoom::LSP::Range, code: ::Integer, message: ::String, information: ::Object).void } + def initialize(range:, code:, message:, information:); end sig { override.params(printer: ::Spoom::LSP::SymbolPrinter).void } def accept_printer(printer); end + sig { returns(::Integer) } + def code; end + + sig { returns(::Object) } + def information; end + + sig { returns(::String) } + def message; end + + sig { returns(::Spoom::LSP::Range) } + def range; end + sig { returns(::String) } def to_s; end @@ -1786,22 +2002,45 @@ class Spoom::LSP::Diagnostic < ::T::Struct end end -class Spoom::LSP::DocumentSymbol < ::T::Struct +class Spoom::LSP::DocumentSymbol include ::Spoom::LSP::PrintableSymbol - const :name, ::String - const :detail, T.nilable(::String) - const :kind, ::Integer - const :location, T.nilable(::Spoom::LSP::Location) - const :range, T.nilable(::Spoom::LSP::Range) - const :children, T::Array[::Spoom::LSP::DocumentSymbol] + sig do + params( + name: ::String, + kind: ::Integer, + children: T::Array[::Spoom::LSP::DocumentSymbol], + detail: T.nilable(::String), + location: T.nilable(::Spoom::LSP::Location), + range: T.nilable(::Spoom::LSP::Range) + ).void + end + def initialize(name:, kind:, children:, detail: T.unsafe(nil), location: T.unsafe(nil), range: T.unsafe(nil)); end sig { override.params(printer: ::Spoom::LSP::SymbolPrinter).void } def accept_printer(printer); end + sig { returns(T::Array[::Spoom::LSP::DocumentSymbol]) } + def children; end + + sig { returns(T.nilable(::String)) } + def detail; end + + sig { returns(::Integer) } + def kind; end + sig { returns(::String) } def kind_string; end + sig { returns(T.nilable(::Spoom::LSP::Location)) } + def location; end + + sig { returns(::String) } + def name; end + + sig { returns(T.nilable(::Spoom::LSP::Range)) } + def range; end + sig { returns(::String) } def to_s; end @@ -1832,15 +2071,21 @@ class Spoom::LSP::Error::Diagnostics < ::Spoom::LSP::Error end end -class Spoom::LSP::Hover < ::T::Struct +class Spoom::LSP::Hover include ::Spoom::LSP::PrintableSymbol - const :contents, ::String - const :range, T.nilable(T::Range[T.untyped]) + sig { params(contents: ::String, range: T.nilable(::Spoom::LSP::Range)).void } + def initialize(contents:, range: T.unsafe(nil)); end sig { override.params(printer: ::Spoom::LSP::SymbolPrinter).void } def accept_printer(printer); end + sig { returns(::String) } + def contents; end + + sig { returns(T.nilable(::Spoom::LSP::Range)) } + def range; end + sig { returns(::String) } def to_s; end @@ -1850,18 +2095,24 @@ class Spoom::LSP::Hover < ::T::Struct end end -class Spoom::LSP::Location < ::T::Struct +class Spoom::LSP::Location include ::Spoom::LSP::PrintableSymbol - const :uri, ::String - const :range, ::Spoom::LSP::Range + sig { params(uri: ::String, range: ::Spoom::LSP::Range).void } + def initialize(uri:, range:); end sig { override.params(printer: ::Spoom::LSP::SymbolPrinter).void } def accept_printer(printer); end + sig { returns(::Spoom::LSP::Range) } + def range; end + sig { returns(::String) } def to_s; end + sig { returns(::String) } + def uri; end + class << self sig { params(json: T::Hash[T.untyped, T.untyped]).returns(::Spoom::LSP::Location) } def from_json(json); end @@ -1890,15 +2141,21 @@ class Spoom::LSP::Notification < ::Spoom::LSP::Message def params; end end -class Spoom::LSP::Position < ::T::Struct +class Spoom::LSP::Position include ::Spoom::LSP::PrintableSymbol - const :line, ::Integer - const :char, ::Integer + sig { params(line: ::Integer, char: ::Integer).void } + def initialize(line:, char:); end sig { override.params(printer: ::Spoom::LSP::SymbolPrinter).void } def accept_printer(printer); end + sig { returns(::Integer) } + def char; end + + sig { returns(::Integer) } + def line; end + sig { returns(::String) } def to_s; end @@ -1915,15 +2172,21 @@ module Spoom::LSP::PrintableSymbol def accept_printer(printer); end end -class Spoom::LSP::Range < ::T::Struct +class Spoom::LSP::Range include ::Spoom::LSP::PrintableSymbol - const :start, ::Spoom::LSP::Position - const :end, ::Spoom::LSP::Position + sig { params(start_pos: ::Spoom::LSP::Position, end_pos: ::Spoom::LSP::Position).void } + def initialize(start_pos:, end_pos:); end sig { override.params(printer: ::Spoom::LSP::SymbolPrinter).void } def accept_printer(printer); end + sig { returns(::Spoom::LSP::Position) } + def end_pos; end + + sig { returns(::Spoom::LSP::Position) } + def start_pos; end + sig { returns(::String) } def to_s; end @@ -1960,16 +2223,24 @@ class Spoom::LSP::ResponseError < ::Spoom::LSP::Error end end -class Spoom::LSP::SignatureHelp < ::T::Struct +class Spoom::LSP::SignatureHelp include ::Spoom::LSP::PrintableSymbol - const :label, T.nilable(::String) - const :doc, ::Object - const :params, T::Array[T.untyped] + sig { params(doc: ::Object, params: T::Array[T.untyped], label: T.nilable(::String)).void } + def initialize(doc:, params:, label: T.unsafe(nil)); end sig { override.params(printer: ::Spoom::LSP::SymbolPrinter).void } def accept_printer(printer); end + sig { returns(::Object) } + def doc; end + + sig { returns(T.nilable(::String)) } + def label; end + + sig { returns(T::Array[T.untyped]) } + def params; end + sig { returns(::String) } def to_s; end @@ -2257,17 +2528,25 @@ class Spoom::Model::Property < ::Spoom::Model::SymbolDef def visibility; end end -class Spoom::Model::Reference < ::T::Struct - const :kind, ::Spoom::Model::Reference::Kind - const :name, ::String - const :location, ::Spoom::Location +class Spoom::Model::Reference + sig { params(kind: ::Spoom::Model::Reference::Kind, name: ::String, location: ::Spoom::Location).void } + def initialize(kind:, name:, location:); end sig { returns(T::Boolean) } def constant?; end + sig { returns(::Spoom::Model::Reference::Kind) } + def kind; end + + sig { returns(::Spoom::Location) } + def location; end + sig { returns(T::Boolean) } def method?; end + sig { returns(::String) } + def name; end + class << self sig { params(name: ::String, location: ::Spoom::Location).returns(::Spoom::Model::Reference) } def constant(name, location); end