@@ -58,16 +58,26 @@ def self.for(source, start_line, offsets)
5858 # The line number where this source starts.
5959 attr_reader :start_line #: Integer
6060
61- # The list of newline byte offsets in the source code.
62- attr_reader :offsets #: Array[Integer]
61+ # The list of newline byte offsets in the source code. When initialized from
62+ # the C extension, this may be a packed binary string of uint32_t values
63+ # that is lazily unpacked on first access.
64+ #--
65+ #: () -> Array[Integer]
66+ def offsets
67+ offsets = @offsets
68+ return offsets if offsets . is_a? ( Array )
69+ @offsets = offsets . unpack ( "L*" )
70+ end
6371
64- # Create a new source object with the given source code.
72+ # Create a new source object with the given source code. The offsets
73+ # parameter can be either an Array of Integer byte offsets or a packed
74+ # binary string of uint32_t values (from the C extension).
6575 #--
66- #: (String source, Integer start_line, Array[Integer] offsets) -> void
76+ #: (String source, Integer start_line, Array[Integer] | String offsets) -> void
6777 def initialize ( source , start_line , offsets )
6878 @source = source
69- @start_line = start_line # set after parsing is done
70- @offsets = offsets # set after parsing is done
79+ @start_line = start_line
80+ @offsets = offsets
7181 end
7282
7383 # Replace the value of start_line with the given value.
@@ -81,7 +91,7 @@ def replace_start_line(start_line)
8191 #--
8292 #: (Array[Integer] offsets) -> void
8393 def replace_offsets ( offsets )
84- @offsets . replace ( offsets )
94+ @offsets = offsets
8595 end
8696
8797 # Returns the encoding of the source code, which is set by parameters to the
0 commit comments