lib/spoom/location.rb in spoom-1.3.3 vs lib/spoom/location.rb in spoom-1.4.0
- old
+ new
@@ -13,72 +13,127 @@
extend T::Sig
sig { params(location_string: String).returns(Location) }
def from_string(location_string)
file, rest = location_string.split(":", 2)
- raise LocationError, "Invalid location string: #{location_string}" unless file && rest
+ raise LocationError, "Invalid location string `#{location_string}`: missing file name" unless file
+ return new(file) if rest.nil?
+
start_line, rest = rest.split(":", 2)
- raise LocationError, "Invalid location string: #{location_string}" unless start_line && rest
+ if rest.nil?
+ start_line, end_line = T.must(start_line).split("-", 2)
+ raise LocationError, "Invalid location string `#{location_string}`: missing end line" unless end_line
+ return new(file, start_line: start_line.to_i, end_line: end_line.to_i) if end_line
+ end
+
start_column, rest = rest.split("-", 2)
- raise LocationError, "Invalid location string: #{location_string}" unless start_column && rest
+ raise LocationError, "Invalid location string `#{location_string}`: missing end line and column" if rest.nil?
end_line, end_column = rest.split(":", 2)
- raise LocationError, "Invalid location string: #{location_string}" unless end_line && end_column
+ raise LocationError,
+ "Invalid location string `#{location_string}`: missing end column" unless end_line && end_column
- new(file, start_line.to_i, start_column.to_i, end_line.to_i, end_column.to_i)
+ new(
+ file,
+ start_line: start_line.to_i,
+ start_column: start_column.to_i,
+ end_line: end_line.to_i,
+ end_column: end_column.to_i,
+ )
end
sig { params(file: String, location: Prism::Location).returns(Location) }
def from_prism(file, location)
- new(file, location.start_line, location.start_column, location.end_line, location.end_column)
+ new(
+ file,
+ start_line: location.start_line,
+ start_column: location.start_column,
+ end_line: location.end_line,
+ end_column: location.end_column,
+ )
end
end
sig { returns(String) }
attr_reader :file
- sig { returns(Integer) }
+ sig { returns(T.nilable(Integer)) }
attr_reader :start_line, :start_column, :end_line, :end_column
sig do
params(
file: String,
- start_line: Integer,
- start_column: Integer,
- end_line: Integer,
- end_column: Integer,
+ start_line: T.nilable(Integer),
+ start_column: T.nilable(Integer),
+ end_line: T.nilable(Integer),
+ end_column: T.nilable(Integer),
).void
end
- def initialize(file, start_line, start_column, end_line, end_column)
+ def initialize(file, start_line: nil, start_column: nil, end_line: nil, end_column: nil)
+ raise LocationError,
+ "Invalid location: end line is required if start line is provided" if start_line && !end_line
+ raise LocationError,
+ "Invalid location: start line is required if end line is provided" if !start_line && end_line
+ raise LocationError,
+ "Invalid location: end column is required if start column is provided" if start_column && !end_column
+ raise LocationError,
+ "Invalid location: start column is required if end column is provided" if !start_column && end_column
+ raise LocationError,
+ "Invalid location: lines are required if columns are provided" if start_column && !start_line
+
@file = file
@start_line = start_line
@start_column = start_column
@end_line = end_line
@end_column = end_column
end
sig { params(other: Location).returns(T::Boolean) }
def include?(other)
return false unless @file == other.file
- return false if @start_line > other.start_line
- return false if @start_line == other.start_line && @start_column > other.start_column
- return false if @end_line < other.end_line
- return false if @end_line == other.end_line && @end_column < other.end_column
+ return false if (@start_line || -Float::INFINITY) > (other.start_line || -Float::INFINITY)
+ return false if @start_line == other.start_line &&
+ (@start_column || -Float::INFINITY) > (other.start_column || -Float::INFINITY)
+ return false if (@end_line || Float::INFINITY) < (other.end_line || Float::INFINITY)
+ return false if @end_line == other.end_line &&
+ (@end_column || Float::INFINITY) < (other.end_column || Float::INFINITY)
true
end
sig { override.params(other: BasicObject).returns(T.nilable(Integer)) }
def <=>(other)
return unless Location === other
- to_s <=> other.to_s
+ comparison_array_self = [
+ @file,
+ @start_line || -Float::INFINITY,
+ @start_column || -Float::INFINITY,
+ @end_line || Float::INFINITY,
+ @end_column || Float::INFINITY,
+ ]
+
+ comparison_array_other = [
+ other.file,
+ other.start_line || -Float::INFINITY,
+ other.start_column || -Float::INFINITY,
+ other.end_line || Float::INFINITY,
+ other.end_column || Float::INFINITY,
+ ]
+
+ comparison_array_self <=> comparison_array_other
end
sig { returns(String) }
def to_s
- "#{@file}:#{@start_line}:#{@start_column}-#{@end_line}:#{@end_column}"
+ if @start_line && @start_column
+ "#{@file}:#{@start_line}:#{@start_column}-#{@end_line}:#{@end_column}"
+ elsif @start_line
+ "#{@file}:#{@start_line}-#{@end_line}"
+ else
+ @file
+ end
end
end
end