lib/tailor/lexer/token.rb
require 'ripper'
require_relative 'lexer_constants'
require_relative '../logger'
class Tailor
class Lexer < ::Ripper::Lexer
# Helper methods for tokens that are parsed by {Tailor::Lexer}.
class Token < String
include Tailor::LexerConstants
include Tailor::Logger::Mixin
# @param [String] the_token
# @param [Hash] options
def initialize(the_token, options={})
super(the_token)
@options = options
end
# Checks if +self+ is in +{KEYWORDS_TO_INDENT}+.
#
# @return [Boolean]
def keyword_to_indent?
KEYWORDS_TO_INDENT.include? self
end
# Checks if +self+ is in +{CONTINUATION_KEYWORDS}+.
#
# @return [Boolean]
def continuation_keyword?
CONTINUATION_KEYWORDS.include? self
end
# @return [Boolean]
def ends_with_newline?
self =~ /\n$/
end
# Checks if +self+ is "do" and +@options[:loop_with_do] is true.
#
# @return [Boolean]
def do_is_for_a_loop?
self == 'do' && @options[:loop_with_do]
end
# @return [Boolean]
def screaming_snake_case?
self =~ /[A-Z].*_/
end
# @return [Boolean]
def contains_capital_letter?
self =~ /[A-Z]/
end
# @return [Boolean]
def contains_hard_tab?
self =~ /\t/
end
# Checks the current line to see if +self+ is being used as a modifier.
#
# @return [Boolean] True if there's a modifier in the current line that
# is the same type as +token+.
def modifier_keyword?
return false unless keyword_to_indent?
line_of_text = @options[:full_line_of_text]
log "Line of text: #{line_of_text}"
catch(:result) do
sexp_line = Ripper.sexp(line_of_text)
if sexp_line.nil?
msg = 'sexp line was nil. '
msg << 'Perhaps that line is part of a multi-line statement?'
log msg
log 'Trying again with the last char removed from the line...'
line_of_text.chop!
sexp_line = Ripper.sexp(line_of_text)
end
if sexp_line.nil?
log 'sexp line was nil again.'
log 'Trying 1 more time with the last char removed from the line...'
line_of_text.chop!
sexp_line = Ripper.sexp(line_of_text)
end
if sexp_line.is_a? Array
log "sexp_line.flatten: #{sexp_line.flatten}"
log "sexp_line.last.first: #{sexp_line.last.first}"
begin
throw(:result, sexp_line.flatten.compact.any? do |s|
s == MODIFIERS[self]
end)
rescue NoMethodError
end
end
end
end
# @return [Boolean]
def fake_backslash_line_end?
self =~ /^# TAILOR REMOVED BACKSLASH\n?$/
end
end
end
end