123456789_123456789_123456789_123456789_123456789_

Class: Prism::LibRubyParser::PrismSource

Do not use. This class is for internal use only.
Relationships & Source Files
Inherits: Object
Defined in: lib/prism/ffi.rb

Overview

This object represents source code to be parsed. For strings it wraps a pointer directly; for files it uses a pm_source_t under the hood.

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(pointer, length, from_string) ⇒ PrismSource

[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 189

def initialize(pointer, length, from_string)
  @pointer = pointer
  @length = length
  @from_string = from_string
end

Class Method Details

.with_file(filepath)

Yields a PrismSource to the given block, backed by a pm_source_t.

Raises:

  • (TypeError)
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 215

def self.with_file(filepath)
  raise TypeError unless filepath.is_a?(String)

  # On Windows and Mac, it's expected that filepaths will be encoded in
  # UTF-8. If they are not, we need to convert them to UTF-8 before
  # passing them into pm_source_mapped_new.
  if PLATFORM_EXPECTS_UTF8 && (encoding = filepath.encoding) != Encoding::ASCII_8BIT && encoding != Encoding::UTF_8
    filepath = filepath.encode(Encoding::UTF_8)
  end

  FFI::MemoryPointer.new(:int) do |result_ptr|
    pm_source = LibRubyParser.pm_source_mapped_new(filepath, 0, result_ptr)

    case SOURCE_INIT_RESULT[result_ptr.read_int]
    when :PM_SOURCE_INIT_SUCCESS
      pointer = LibRubyParser.pm_source_source(pm_source)
      length = LibRubyParser.pm_source_length(pm_source)
      return yield new(pointer, length, false)
    when :PM_SOURCE_INIT_ERROR_GENERIC
      raise SystemCallError.new(filepath, FFI.errno)
    when :PM_SOURCE_INIT_ERROR_DIRECTORY
      raise Errno::EISDIR.new(filepath)
    when :PM_SOURCE_INIT_ERROR_NON_REGULAR
      # Fall back to reading the file through Ruby IO for non-regular
      # files (pipes, character devices, etc.)
      return with_string(File.read(filepath)) { |string| yield string }
    else
      raise "Unknown error initializing pm_source_t: #{result_ptr.read_int}"
    end
  ensure
    LibRubyParser.pm_source_free(pm_source) if pm_source && !pm_source.null?
  end
end

.with_string(string)

Yields a PrismSource backed by the given string to the block.

Raises:

  • (TypeError)
[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 201

def self.with_string(string)
  raise TypeError unless string.is_a?(String)

  length = string.bytesize
  # + 1 to never get an address of 0, which pm_parser_init() asserts
  FFI::MemoryPointer.new(:char, length + 1, false) do |pointer|
    pointer.write_string(string)
    # since we have the extra byte we might as well \0-terminate
    pointer.put_char(length, 0)
    return yield new(pointer, length, true)
  end
end

Instance Attribute Details

#length (readonly)

[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 187

attr_reader :pointer, :length

#pointer (readonly)

[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 187

attr_reader :pointer, :length

Instance Method Details

#read

[ GitHub ]

  
# File 'lib/prism/ffi.rb', line 195

def read
  raise "should use the original String instead" if @from_string
  @pointer.read_string(@length)
end