summaryrefslogtreecommitdiff
path: root/lib/diff/lcs.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/diff/lcs.rb')
-rw-r--r--lib/diff/lcs.rb43
1 files changed, 26 insertions, 17 deletions
diff --git a/lib/diff/lcs.rb b/lib/diff/lcs.rb
index 63888a1..7e8c473 100644
--- a/lib/diff/lcs.rb
+++ b/lib/diff/lcs.rb
@@ -1,4 +1,7 @@
# frozen_string_literal: true
+# typed: true
+
+require 'sorbet-runtime'
module Diff; end unless defined? Diff # rubocop:disable Style/Documentation
@@ -50,6 +53,9 @@ module Diff; end unless defined? Diff # rubocop:disable Style/Documentation
# a b c a x b y c z
module Diff::LCS
VERSION = '1.4.4'
+
+ SequenceT = T.type_alias { T.any(Diff::LCS, Enumerable, String) }
+ CallbacksT = T.type_alias { T.nilable(Module) }
end
require 'diff/lcs/callbacks'
@@ -85,14 +91,14 @@ module Diff::LCS # rubocop:disable Style/Documentation
# Traverses the discovered longest common subsequences between +self+ and
# +other+. See Diff::LCS#traverse_sequences.
def traverse_sequences(other, callbacks = nil, &block)
- traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block)
+ Diff::LCS.traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block)
end
# Traverses the discovered longest common subsequences between +self+ and
# +other+ using the alternate, balanced algorithm. See
# Diff::LCS#traverse_balanced.
def traverse_balanced(other, callbacks = nil, &block)
- traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block)
+ Diff::LCS.traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block)
end
# Attempts to patch +self+ with the provided +patchset+. A new sequence based
@@ -121,7 +127,7 @@ module Diff::LCS # rubocop:disable Style/Documentation
# the sequence this is used on supports #replace, the value of +self+ will be
# replaced. See Diff::LCS#patch. Does no patch direction autodiscovery.
def patch_me(patchset)
- if respond_to? :replace
+ if respond_to?(:replace)
replace(patch!(patchset))
else
patch!(patchset)
@@ -132,7 +138,7 @@ module Diff::LCS # rubocop:disable Style/Documentation
# If the sequence this is used on supports #replace, the value of +self+ will
# be replaced. See Diff::LCS#unpatch. Does no patch direction autodiscovery.
def unpatch_me(patchset)
- if respond_to? :replace
+ if respond_to?(:replace)
replace(unpatch!(patchset))
else
unpatch!(patchset)
@@ -140,8 +146,8 @@ module Diff::LCS # rubocop:disable Style/Documentation
end
end
-class << Diff::LCS
- def lcs(seq1, seq2, &block) #:yields seq1[i] for each matched:
+module Diff::LCS # rubocop:disable Style/Documentation
+ def self.lcs(seq1, seq2, &block) #:yields seq1[i] for each matched:
matches = Diff::LCS::Internals.lcs(seq1, seq2)
ret = []
string = seq1.kind_of? String
@@ -165,7 +171,7 @@ class << Diff::LCS
# Class argument is provided for +callbacks+, #diff will attempt to
# initialise it. If the +callbacks+ object (possibly initialised) responds to
# #finish, it will be called.
- def diff(seq1, seq2, callbacks = nil, &block) # :yields diff changes:
+ def self.diff(seq1, seq2, callbacks = nil, &block) # :yields diff changes:
diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks, &block)
end
@@ -197,7 +203,7 @@ class << Diff::LCS
# # insert
# end
# end
- def sdiff(seq1, seq2, callbacks = nil, &block) #:yields diff changes:
+ def self.sdiff(seq1, seq2, callbacks = nil, &block) #:yields diff changes:
diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks, &block)
end
@@ -281,17 +287,20 @@ class << Diff::LCS
# <tt>callbacks#discard_b</tt> will be called after the end of the sequence
# is reached, if +a+ has not yet reached the end of +A+ or +b+ has not yet
# reached the end of +B+.
- def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks) #:yields change events:
+ sig { params(seq1: SequenceT, seq2: SequenceT, callbacks: CallbacksT).returns(Array) }
+ def self.traverse_sequences(seq1, seq2, callbacks = nil) #:yields change events:
callbacks ||= Diff::LCS::SequenceCallbacks
matches = Diff::LCS::Internals.lcs(seq1, seq2)
run_finished_a = run_finished_b = false
- string = seq1.kind_of?(String)
+ string = String === seq1 # rubocop:disable Style/CaseEquality
- a_size = seq1.size
- b_size = seq2.size
+ a_size = seq1.count
+ b_size = seq2.count
ai = bj = 0
+ event = T.let(nil, T.nilable(Diff::LCS::ContextChange))
+
(0..matches.size).each do |i|
b_line = matches[i]
@@ -299,7 +308,7 @@ class << Diff::LCS
bx = string ? seq2[bj, 1] : seq2[bj]
if b_line.nil?
- unless ax.nil? or (string and ax.empty?)
+ unless ax.nil? or (string and T.must(ax).empty?)
event = Diff::LCS::ContextChange.new('-', i, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_a(event)
@@ -472,7 +481,7 @@ class << Diff::LCS
#
# Note that +i+ and +j+ may not be the same index position, even if +a+ and
# +b+ are considered to be pointing to matching or changed elements.
- def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
+ def self.traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
matches = Diff::LCS::Internals.lcs(seq1, seq2)
a_size = seq1.size
b_size = seq2.size
@@ -621,7 +630,7 @@ class << Diff::LCS
# containing either Diff::LCS::Change objects (or a subclass) or the array
# representations of those objects. Prior to application, array
# representations of Diff::LCS::Change objects will be reified.
- def patch(src, patchset, direction = nil)
+ def self.patch(src, patchset, direction = nil)
# Normalize the patchset.
has_changes, patchset = Diff::LCS::Internals.analyze_patchset(patchset)
@@ -725,13 +734,13 @@ class << Diff::LCS
# Given a set of patchset, convert the current version to the prior version.
# Does no auto-discovery.
- def unpatch!(src, patchset)
+ def self.unpatch!(src, patchset)
patch(src, patchset, :unpatch)
end
# Given a set of patchset, convert the current version to the next version.
# Does no auto-discovery.
- def patch!(src, patchset)
+ def self.patch!(src, patchset)
patch(src, patchset, :patch)
end
end