class Prism::Source
这表示一个已解析的 Ruby 代码的来源。它与位置结合使用,允许它们解析行号和源范围。
属性
offsets[R]
源代码中换行符字节偏移量的列表。
source[R]
此源对象表示的源代码。
start_line[R]
此源开始的行号。
公共类方法
for(source, start_line = 1, offsets = []) 点击切换源代码
使用给定的源代码创建一个新的源对象。此方法应替代 ‘new` 使用,如果源代码中不存在多字节字符,它将返回 `Source` 或专门且性能更高的 `ASCIISource`。
# File prism/parse_result.rb, line 12 def self.for(source, start_line = 1, offsets = []) if source.ascii_only? ASCIISource.new(source, start_line, offsets) elsif source.encoding == Encoding::BINARY source.force_encoding(Encoding::UTF_8) if source.valid_encoding? new(source, start_line, offsets) else # This is an extremely niche use case where the file is marked as # binary, contains multi-byte characters, and those characters are not # valid UTF-8. In this case we'll mark it as binary and fall back to # treating everything as a single-byte character. This _may_ cause # problems when asking for code units, but it appears to be the # cleanest solution at the moment. source.force_encoding(Encoding::BINARY) ASCIISource.new(source, start_line, offsets) end else new(source, start_line, offsets) end end
new(source, start_line = 1, offsets = []) 点击切换源代码
使用给定的源代码创建一个新的源对象。
# File prism/parse_result.rb, line 45 def initialize(source, start_line = 1, offsets = []) @source = source @start_line = start_line # set after parsing is done @offsets = offsets # set after parsing is done end
公共实例方法
character_column(byte_offset) 点击切换源代码
返回给定字节偏移量的字符列号。
# File prism/parse_result.rb, line 97 def character_column(byte_offset) character_offset(byte_offset) - character_offset(line_start(byte_offset)) end
character_offset(byte_offset) 点击切换源代码
返回给定字节偏移量的字符偏移量。
# File prism/parse_result.rb, line 92 def character_offset(byte_offset) (source.byteslice(0, byte_offset) or raise).length end
code_units_cache(encoding) 点击切换源代码
生成一个针对特定编码的缓存,用于计算代码单元偏移量。
# File prism/parse_result.rb, line 125 def code_units_cache(encoding) CodeUnitsCache.new(source, encoding) end
code_units_column(byte_offset, encoding) 点击切换源代码
返回给定字节偏移量的给定编码的代码单元列号。
# File prism/parse_result.rb, line 131 def code_units_column(byte_offset, encoding) code_units_offset(byte_offset, encoding) - code_units_offset(line_start(byte_offset), encoding) end
code_units_offset(byte_offset, encoding) 点击切换源代码
返回给定字节偏移量的文件起始偏移量,以给定编码的代码单元计数。
此方法已使用 UTF-8、UTF-16 和 UTF-32 进行测试。如果存在代码单元的概念,它与其它编码中的字符数量不同,则此处不捕获。
我们在此转换中有意将无效和未定义的字符替换为替换字符。发生这种情况有两个原因。首先,给定的字节偏移量可能不会出现在字符边界上。其次,源代码可能包含在给定编码中没有等效字符的字符。
# File prism/parse_result.rb, line 113 def code_units_offset(byte_offset, encoding) byteslice = (source.byteslice(0, byte_offset) or raise).encode(encoding, invalid: :replace, undef: :replace) if encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE byteslice.bytesize / 2 else byteslice.length end end
column(byte_offset) 点击切换源代码
返回给定字节偏移量的列号。
# File prism/parse_result.rb, line 87 def column(byte_offset) byte_offset - line_start(byte_offset) end
encoding() 点击切换源代码
返回源代码的编码,该编码由解析器的参数或编码魔术注释设置。
# File prism/parse_result.rb, line 53 def encoding source.encoding end
line(byte_offset) 点击切换源代码
通过偏移量进行二进制搜索,以查找给定字节偏移量的行号。
# File prism/parse_result.rb, line 70 def line(byte_offset) start_line + find_line(byte_offset) end
line_end(byte_offset) 点击切换源代码
返回与给定字节偏移量对应的行尾的字节偏移量。
# File prism/parse_result.rb, line 82 def line_end(byte_offset) offsets[find_line(byte_offset) + 1] || source.bytesize end
line_start(byte_offset) 点击切换源代码
返回与给定字节偏移量对应的行首的字节偏移量。
# File prism/parse_result.rb, line 76 def line_start(byte_offset) offsets[find_line(byte_offset)] end
lines() 点击切换源代码
将源代码的行作为字符串数组返回。
# File prism/parse_result.rb, line 58 def lines source.lines end
slice(byte_offset, length) 点击切换源代码
使用给定的字节偏移量和字节长度对源代码执行字节切片。
# File prism/parse_result.rb, line 64 def slice(byte_offset, length) source.byteslice(byte_offset, length) or raise end
私有实例方法
find_line(byte_offset) 点击切换源代码
通过偏移量进行二进制搜索,以查找给定字节偏移量的行号。
# File prism/parse_result.rb, line 139 def find_line(byte_offset) left = 0 right = offsets.length - 1 while left <= right mid = left + (right - left) / 2 return mid if (offset = offsets[mid]) == byte_offset if offset < byte_offset left = mid + 1 else right = mid - 1 end end left - 1 end