summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/prism.rb8
-rw-r--r--lib/prism/debug.rb8
-rw-r--r--lib/prism/ffi.rb198
-rw-r--r--lib/prism/lex_compat.rb8
4 files changed, 133 insertions, 89 deletions
diff --git a/lib/prism.rb b/lib/prism.rb
index 86cdadcdad..350febcaa8 100644
--- a/lib/prism.rb
+++ b/lib/prism.rb
@@ -35,13 +35,15 @@ module Prism
private_constant :LexRipper
# :call-seq:
- # Prism::lex_compat(source, filepath = "") -> Array
+ # Prism::lex_compat(source, **options) -> Array
#
# Returns an array of tokens that closely resembles that of the Ripper lexer.
# The only difference is that since we don't keep track of lexer state in the
# same way, it's going to always return the NONE state.
- def self.lex_compat(source, filepath = "")
- LexCompat.new(source, filepath).result
+ #
+ # For supported options, see Prism::parse.
+ def self.lex_compat(source, **options)
+ LexCompat.new(source, **options).result
end
# :call-seq:
diff --git a/lib/prism/debug.rb b/lib/prism/debug.rb
index f573d0958d..f5d19dc3df 100644
--- a/lib/prism/debug.rb
+++ b/lib/prism/debug.rb
@@ -187,13 +187,5 @@ module Prism
def self.newlines(source)
Prism.parse(source).source.offsets
end
-
- # :call-seq:
- # Debug::parse_serialize_file(filepath) -> dumped
- #
- # For the given file, parse the AST and dump it to a string.
- def self.parse_serialize_file(filepath)
- parse_serialize_file_metadata(filepath, [filepath.bytesize, filepath.b, 0].pack("LA*L"))
- end
end
end
diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb
index 170ca8b8d7..61ece6a641 100644
--- a/lib/prism/ffi.rb
+++ b/lib/prism/ffi.rb
@@ -167,15 +167,6 @@ module Prism
end
end
end
-
- # Dump the given source into a serialized format.
- def self.dump_internal(source, source_size, filepath)
- PrismBuffer.with do |buffer|
- metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath
- pm_parse_serialize(source, source_size, buffer.pointer, metadata)
- buffer.read
- end
- end
end
# Mark the LibRubyParser module as private as it should only be called through
@@ -185,93 +176,152 @@ module Prism
# The version constant is set by reading the result of calling pm_version.
VERSION = LibRubyParser.pm_version.read_string
- # Mirror the Prism.dump API by using the serialization API.
- def self.dump(code, filepath = nil)
- LibRubyParser.dump_internal(code, code.bytesize, filepath)
- end
+ class << self
+ # Mirror the Prism.dump API by using the serialization API.
+ def dump(code, **options)
+ LibRubyParser::PrismBuffer.with do |buffer|
+ LibRubyParser.pm_parse_serialize(code, code.bytesize, buffer.pointer, dump_options(options))
+ buffer.read
+ end
+ end
- # Mirror the Prism.dump_file API by using the serialization API.
- def self.dump_file(filepath)
- LibRubyParser::PrismString.with(filepath) do |string|
- LibRubyParser.dump_internal(string.source, string.length, filepath)
+ # Mirror the Prism.dump_file API by using the serialization API.
+ def dump_file(filepath, **options)
+ LibRubyParser::PrismString.with(filepath) do |string|
+ dump(string.read, **options, filepath: filepath)
+ end
end
- end
- # Mirror the Prism.lex API by using the serialization API.
- def self.lex(code, filepath = nil)
- LibRubyParser::PrismBuffer.with do |buffer|
- LibRubyParser.pm_lex_serialize(code, code.bytesize, filepath, buffer.pointer)
- Serialize.load_tokens(Source.new(code), buffer.read)
+ # Mirror the Prism.lex API by using the serialization API.
+ def lex(code, **options)
+ LibRubyParser::PrismBuffer.with do |buffer|
+ LibRubyParser.pm_lex_serialize(code, code.bytesize, dump_options(options), buffer.pointer)
+ Serialize.load_tokens(Source.new(code), buffer.read)
+ end
end
- end
- # Mirror the Prism.lex_file API by using the serialization API.
- def self.lex_file(filepath)
- LibRubyParser::PrismString.with(filepath) do |string|
- lex(string.read, filepath)
+ # Mirror the Prism.lex_file API by using the serialization API.
+ def lex_file(filepath, **options)
+ LibRubyParser::PrismString.with(filepath) do |string|
+ lex(string.read, **options, filepath: filepath)
+ end
end
- end
- # Mirror the Prism.parse API by using the serialization API.
- def self.parse(code, filepath = nil)
- Prism.load(code, dump(code, filepath))
- end
+ # Mirror the Prism.parse API by using the serialization API.
+ def parse(code, **options)
+ Prism.load(code, dump(code, **options))
+ end
- # Mirror the Prism.parse_file API by using the serialization API. This uses
- # native strings instead of Ruby strings because it allows us to use mmap when
- # it is available.
- def self.parse_file(filepath)
- LibRubyParser::PrismString.with(filepath) do |string|
- parse(string.read, filepath)
+ # Mirror the Prism.parse_file API by using the serialization API. This uses
+ # native strings instead of Ruby strings because it allows us to use mmap when
+ # it is available.
+ def parse_file(filepath, **options)
+ LibRubyParser::PrismString.with(filepath) do |string|
+ parse(string.read, **options, filepath: filepath)
+ end
end
- end
- # Mirror the Prism.parse_comments API by using the serialization API.
- def self.parse_comments(code, filepath = nil)
- LibRubyParser::PrismBuffer.with do |buffer|
- metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath
- LibRubyParser.pm_parse_serialize_comments(code, code.bytesize, buffer.pointer, metadata)
+ # Mirror the Prism.parse_comments API by using the serialization API.
+ def parse_comments(code, **options)
+ LibRubyParser::PrismBuffer.with do |buffer|
+ LibRubyParser.pm_parse_serialize_comments(code, code.bytesize, buffer.pointer, dump_options(options))
- source = Source.new(code)
- loader = Serialize::Loader.new(source, buffer.read)
+ source = Source.new(code)
+ loader = Serialize::Loader.new(source, buffer.read)
- loader.load_header
- loader.load_force_encoding
- loader.load_comments
+ loader.load_header
+ loader.load_force_encoding
+ loader.load_comments
+ end
end
- end
- # Mirror the Prism.parse_file_comments API by using the serialization
- # API. This uses native strings instead of Ruby strings because it allows us
- # to use mmap when it is available.
- def self.parse_file_comments(filepath)
- LibRubyParser::PrismString.with(filepath) do |string|
- parse_comments(string.read, filepath)
+ # Mirror the Prism.parse_file_comments API by using the serialization
+ # API. This uses native strings instead of Ruby strings because it allows us
+ # to use mmap when it is available.
+ def parse_file_comments(filepath, **options)
+ LibRubyParser::PrismString.with(filepath) do |string|
+ parse_comments(string.read, **options, filepath: filepath)
+ end
end
- end
- # Mirror the Prism.parse_lex API by using the serialization API.
- def self.parse_lex(code, filepath = nil)
- LibRubyParser::PrismBuffer.with do |buffer|
- metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath
- LibRubyParser.pm_parse_lex_serialize(code, code.bytesize, buffer.pointer, metadata)
+ # Mirror the Prism.parse_lex API by using the serialization API.
+ def parse_lex(code, **options)
+ LibRubyParser::PrismBuffer.with do |buffer|
+ LibRubyParser.pm_parse_lex_serialize(code, code.bytesize, buffer.pointer, dump_options(options))
- source = Source.new(code)
- loader = Serialize::Loader.new(source, buffer.read)
+ source = Source.new(code)
+ loader = Serialize::Loader.new(source, buffer.read)
- tokens = loader.load_tokens
- node, comments, magic_comments, errors, warnings = loader.load_nodes
+ tokens = loader.load_tokens
+ node, comments, magic_comments, errors, warnings = loader.load_nodes
- tokens.each { |token,| token.value.force_encoding(loader.encoding) }
+ tokens.each { |token,| token.value.force_encoding(loader.encoding) }
+ ParseResult.new([node, tokens], comments, magic_comments, errors, warnings, source)
+ end
+ end
- ParseResult.new([node, tokens], comments, magic_comments, errors, warnings, source)
+ # Mirror the Prism.parse_lex_file API by using the serialization API.
+ def parse_lex_file(filepath, **options)
+ LibRubyParser::PrismString.with(filepath) do |string|
+ parse_lex(string.read, **options, filepath: filepath)
+ end
end
- end
- # Mirror the Prism.parse_lex_file API by using the serialization API.
- def self.parse_lex_file(filepath)
- LibRubyParser::PrismString.with(filepath) do |string|
- parse_lex(string.read, filepath)
+ private
+
+ # Convert the given options into a serialized options string.
+ def dump_options(options)
+ template = +""
+ values = []
+
+ template << "L"
+ if (filepath = options[:filepath])
+ values.push(filepath.bytesize, filepath.b)
+ template << "A*"
+ else
+ values << 0
+ end
+
+ template << "L"
+ values << options.fetch(:line, 0)
+
+ template << "L"
+ if (encoding = options[:encoding])
+ name = encoding.name
+ values.push(name.bytesize, name.b)
+ template << "A*"
+ else
+ values << 0
+ end
+
+ template << "C"
+ values << (options.fetch(:frozen_string_literal, false) ? 1 : 0)
+
+ template << "C"
+ values << (options.fetch(:suppress_warnings, false) ? 1 : 0)
+
+ template << "L"
+ if (scopes = options[:scopes])
+ values << scopes.length
+
+ scopes.each do |scope|
+ template << "L"
+ values << scope.length
+
+ scope.each do |local|
+ name = local.name
+ template << "L"
+ values << name.bytesize
+
+ template << "A*"
+ values << name.b
+ end
+ end
+ else
+ values << 0
+ end
+
+ values.pack(template)
end
end
end
diff --git a/lib/prism/lex_compat.rb b/lib/prism/lex_compat.rb
index c1f5cfe944..b6d12053a0 100644
--- a/lib/prism/lex_compat.rb
+++ b/lib/prism/lex_compat.rb
@@ -594,11 +594,11 @@ module Prism
private_constant :Heredoc
- attr_reader :source, :filepath
+ attr_reader :source, :options
- def initialize(source, filepath = "")
+ def initialize(source, **options)
@source = source
- @filepath = filepath || ""
+ @options = options
end
def result
@@ -607,7 +607,7 @@ module Prism
state = :default
heredoc_stack = [[]]
- result = Prism.lex(source, filepath: @filepath)
+ result = Prism.lex(source, **options)
result_value = result.value
previous_state = nil