diff options
Diffstat (limited to 'lib/rubygems/request_set/lockfile')
| -rw-r--r-- | lib/rubygems/request_set/lockfile/parser.rb | 354 | ||||
| -rw-r--r-- | lib/rubygems/request_set/lockfile/tokenizer.rb | 112 |
2 files changed, 0 insertions, 466 deletions
diff --git a/lib/rubygems/request_set/lockfile/parser.rb b/lib/rubygems/request_set/lockfile/parser.rb deleted file mode 100644 index ebea940188..0000000000 --- a/lib/rubygems/request_set/lockfile/parser.rb +++ /dev/null @@ -1,354 +0,0 @@ -# frozen_string_literal: true -class Gem::RequestSet::Lockfile::Parser - ### - # Parses lockfiles - - def initialize tokenizer, set, platforms, filename = nil - @tokens = tokenizer - @filename = filename - @set = set - @platforms = platforms - end - - def parse - until @tokens.empty? do - token = get - - case token.type - when :section then - @tokens.skip :newline - - case token.value - when 'DEPENDENCIES' then - parse_DEPENDENCIES - when 'GIT' then - parse_GIT - when 'GEM' then - parse_GEM - when 'PATH' then - parse_PATH - when 'PLATFORMS' then - parse_PLATFORMS - else - token = get until @tokens.empty? or peek.first == :section - end - else - raise "BUG: unhandled token #{token.type} (#{token.value.inspect}) at line #{token.line} column #{token.column}" - end - end - end - - ## - # Gets the next token for a Lockfile - - def get expected_types = nil, expected_value = nil # :nodoc: - token = @tokens.shift - - if expected_types and not Array(expected_types).include? token.type then - unget token - - message = "unexpected token [#{token.type.inspect}, #{token.value.inspect}], " + - "expected #{expected_types.inspect}" - - raise Gem::RequestSet::Lockfile::ParseError.new message, token.column, token.line, @filename - end - - if expected_value and expected_value != token.value then - unget token - - message = "unexpected token [#{token.type.inspect}, #{token.value.inspect}], " + - "expected [#{expected_types.inspect}, " + - "#{expected_value.inspect}]" - - raise Gem::RequestSet::Lockfile::ParseError.new message, token.column, token.line, @filename - end - - token - end - - def parse_DEPENDENCIES # :nodoc: - while not @tokens.empty? and :text == peek.type do - token = get :text - - requirements = [] - - case peek[0] - when :bang then - get :bang - - requirements << pinned_requirement(token.value) - when :l_paren then - get :l_paren - - loop do - op = get(:requirement).value - version = get(:text).value - - requirements << "#{op} #{version}" - - break unless peek.type == :comma - - get :comma - end - - get :r_paren - - if peek[0] == :bang then - requirements.clear - requirements << pinned_requirement(token.value) - - get :bang - end - end - - @set.gem token.value, *requirements - - skip :newline - end - end - - def parse_GEM # :nodoc: - sources = [] - - while [:entry, 'remote'] == peek.first(2) do - get :entry, 'remote' - data = get(:text).value - skip :newline - - sources << Gem::Source.new(data) - end - - sources << Gem::Source.new(Gem::DEFAULT_HOST) if sources.empty? - - get :entry, 'specs' - - skip :newline - - set = Gem::Resolver::LockSet.new sources - last_specs = nil - - while not @tokens.empty? and :text == peek.type do - token = get :text - name = token.value - column = token.column - - case peek[0] - when :newline then - last_specs.each do |spec| - spec.add_dependency Gem::Dependency.new name if column == 6 - end - when :l_paren then - get :l_paren - - token = get [:text, :requirement] - type = token.type - data = token.value - - if type == :text and column == 4 then - version, platform = data.split '-', 2 - - platform = - platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY - - last_specs = set.add name, version, platform - else - dependency = parse_dependency name, data - - last_specs.each do |spec| - spec.add_dependency dependency - end - end - - get :r_paren - else - raise "BUG: unknown token #{peek}" - end - - skip :newline - end - - @set.sets << set - end - - def parse_GIT # :nodoc: - get :entry, 'remote' - repository = get(:text).value - - skip :newline - - get :entry, 'revision' - revision = get(:text).value - - skip :newline - - type = peek.type - value = peek.value - if type == :entry and %w[branch ref tag].include? value then - get - get :text - - skip :newline - end - - get :entry, 'specs' - - skip :newline - - set = Gem::Resolver::GitSet.new - set.root_dir = @set.install_dir - - last_spec = nil - - while not @tokens.empty? and :text == peek.type do - token = get :text - name = token.value - column = token.column - - case peek[0] - when :newline then - last_spec.add_dependency Gem::Dependency.new name if column == 6 - when :l_paren then - get :l_paren - - token = get [:text, :requirement] - type = token.type - data = token.value - - if type == :text and column == 4 then - last_spec = set.add_git_spec name, data, repository, revision, true - else - dependency = parse_dependency name, data - - last_spec.add_dependency dependency - end - - get :r_paren - else - raise "BUG: unknown token #{peek}" - end - - skip :newline - end - - @set.sets << set - end - - def parse_PATH # :nodoc: - get :entry, 'remote' - directory = get(:text).value - - skip :newline - - get :entry, 'specs' - - skip :newline - - set = Gem::Resolver::VendorSet.new - last_spec = nil - - while not @tokens.empty? and :text == peek.first do - token = get :text - name = token.value - column = token.column - - case peek[0] - when :newline then - last_spec.add_dependency Gem::Dependency.new name if column == 6 - when :l_paren then - get :l_paren - - token = get [:text, :requirement] - type = token.type - data = token.value - - if type == :text and column == 4 then - last_spec = set.add_vendor_gem name, directory - else - dependency = parse_dependency name, data - - last_spec.dependencies << dependency - end - - get :r_paren - else - raise "BUG: unknown token #{peek}" - end - - skip :newline - end - - @set.sets << set - end - - def parse_PLATFORMS # :nodoc: - while not @tokens.empty? and :text == peek.first do - name = get(:text).value - - @platforms << name - - skip :newline - end - end - - ## - # Parses the requirements following the dependency +name+ and the +op+ for - # the first token of the requirements and returns a Gem::Dependency object. - - def parse_dependency name, op # :nodoc: - return Gem::Dependency.new name, op unless peek[0] == :text - - version = get(:text).value - - requirements = ["#{op} #{version}"] - - while peek.type == :comma do - get :comma - op = get(:requirement).value - version = get(:text).value - - requirements << "#{op} #{version}" - end - - Gem::Dependency.new name, requirements - end - - private - - def skip type # :nodoc: - @tokens.skip type - end - - ## - # Peeks at the next token for Lockfile - - def peek # :nodoc: - @tokens.peek - end - - if [].respond_to? :flat_map - def pinned_requirement name # :nodoc: - requirement = Gem::Dependency.new name - specification = @set.sets.flat_map { |set| - set.find_all(requirement) - }.compact.first - - specification && specification.version - end - else # FIXME: remove when 1.8 is dropped - def pinned_requirement name # :nodoc: - requirement = Gem::Dependency.new name - specification = @set.sets.map { |set| - set.find_all(requirement) - }.flatten(1).compact.first - - specification && specification.version - end - end - - ## - # Ungets the last token retrieved by #get - - def unget token # :nodoc: - @tokens.unshift token - end -end diff --git a/lib/rubygems/request_set/lockfile/tokenizer.rb b/lib/rubygems/request_set/lockfile/tokenizer.rb deleted file mode 100644 index a758743dda..0000000000 --- a/lib/rubygems/request_set/lockfile/tokenizer.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: true -require 'rubygems/request_set/lockfile/parser' - -class Gem::RequestSet::Lockfile::Tokenizer - Token = Struct.new :type, :value, :column, :line - EOF = Token.new :EOF - - def self.from_file file - new File.read(file), file - end - - def initialize input, filename = nil, line = 0, pos = 0 - @line = line - @line_pos = pos - @tokens = [] - @filename = filename - tokenize input - end - - def make_parser set, platforms - Gem::RequestSet::Lockfile::Parser.new self, set, platforms, @filename - end - - def to_a - @tokens.map { |token| [token.type, token.value, token.column, token.line] } - end - - def skip type - @tokens.shift while not @tokens.empty? and peek.type == type - end - - ## - # Calculates the column (by byte) and the line of the current token based on - # +byte_offset+. - - def token_pos byte_offset # :nodoc: - [byte_offset - @line_pos, @line] - end - - def empty? - @tokens.empty? - end - - def unshift token - @tokens.unshift token - end - - def next_token - @tokens.shift - end - alias :shift :next_token - - def peek - @tokens.first || EOF - end - - private - - def tokenize input - require 'strscan' - s = StringScanner.new input - - until s.eos? do - pos = s.pos - - pos = s.pos if leading_whitespace = s.scan(/ +/) - - if s.scan(/[<|=>]{7}/) then - message = "your #{@filename} contains merge conflict markers" - column, line = token_pos pos - - raise Gem::RequestSet::Lockfile::ParseError.new message, column, line, @filename - end - - @tokens << - case - when s.scan(/\r?\n/) then - token = Token.new(:newline, nil, *token_pos(pos)) - @line_pos = s.pos - @line += 1 - token - when s.scan(/[A-Z]+/) then - if leading_whitespace then - text = s.matched - text += s.scan(/[^\s)]*/).to_s # in case of no match - Token.new(:text, text, *token_pos(pos)) - else - Token.new(:section, s.matched, *token_pos(pos)) - end - when s.scan(/([a-z]+):\s/) then - s.pos -= 1 # rewind for possible newline - Token.new(:entry, s[1], *token_pos(pos)) - when s.scan(/\(/) then - Token.new(:l_paren, nil, *token_pos(pos)) - when s.scan(/\)/) then - Token.new(:r_paren, nil, *token_pos(pos)) - when s.scan(/<=|>=|=|~>|<|>|!=/) then - Token.new(:requirement, s.matched, *token_pos(pos)) - when s.scan(/,/) then - Token.new(:comma, nil, *token_pos(pos)) - when s.scan(/!/) then - Token.new(:bang, nil, *token_pos(pos)) - when s.scan(/[^\s),!]*/) then - Token.new(:text, s.matched, *token_pos(pos)) - else - raise "BUG: can't create token for: #{s.string[s.pos..-1].inspect}" - end - end - - @tokens - end -end |
