класс SyntaxSuggest::LeftRightLexCount
Find несоответствия синтаксиса на основе подсчета лексем
Используется для обнаружения отсутствующих пар элементов, каждый ключевой символ нуждается в окончании, каждая ‘{’ нуждается в ‘}’ и т. д.
Пример:
left_right = LeftRightLexCount.new
left_right.count_kw
left_right.missing.first
# => "end"
left_right = LeftRightLexCount.new
source = "{ a: b, c: d" # Note missing '}'
LexAll.new(source: source).each do |lex|
left_right.count_lex(lex)
end
left_right.missing.first
# => "}"
Константы
- PAIRS
Публичные методы класса
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 25
def initialize
@kw_count = 0
@end_count = 0
@count_for_char = {
"{" => 0,
"}" => 0,
"[" => 0,
"]" => 0,
"(" => 0,
")" => 0,
"|" => 0
}
end Публичные методы экземпляра
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 44 def count_end @end_count += 1 end
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 101 def count_for_char(char) @count_for_char[char] end
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 40 def count_kw @kw_count += 1 end
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 58
def count_lex(lex)
case lex.type
when :on_tstring_content
# ^^^
# Means it's a string or a symbol `"{"` rather than being
# part of a data structure (like a hash) `{ a: b }`
# ignore it.
when :on_words_beg, :on_symbos_beg, :on_qwords_beg,
:on_qsymbols_beg, :on_regexp_beg, :on_tstring_beg
# ^^^
# Handle shorthand syntaxes like `%Q{ i am a string }`
#
# The start token will be the full thing `%Q{` but we
# need to count it as if it's a `{`. Any token
# can be used
char = lex.token[-1]
@count_for_char[char] += 1 if @count_for_char.key?(char)
when :on_embexpr_beg
# ^^^
# Embedded string expressions like `"#{foo} <-embed"`
# are parsed with chars:
#
# `#{` as :on_embexpr_beg
# `}` as :on_embexpr_end
#
# We cannot ignore both :on_emb_expr_beg and :on_embexpr_end
# because sometimes the lexer thinks something is an embed
# string end, when it is not like `lol = }` (no clue why).
#
# When we see `#{` count it as a `{` or we will
# have a mis-match count.
#
case lex.token
when "\#{"
@count_for_char["{"] += 1
end
else
@end_count += 1 if lex.is_end?
@kw_count += 1 if lex.is_kw?
@count_for_char[lex.token] += 1 if @count_for_char.key?(lex.token)
end
end Подсчет символов исходного кода
Пример:
left_right = LeftRightLexCount.new
left_right.count_lex(LexValue.new(1, :on_lbrace, "{", Ripper::EXPR_BEG))
left_right.count_for_char("{")
# => 1
left_right.count_for_char("}")
# => 0
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 110 def missing out = missing_pairs out << missing_pipe out << missing_keyword_end out.compact! out end
Возвращает массив отсутствующих символов синтаксиса или ‘“end”` или `“keyword”`
left_right.missing # => ["}"]
Приватные методы экземпляра
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 148
def missing_keyword_end
case @kw_count <=> @end_count
when 1
"end"
when 0
nil
when -1
"keyword"
end
end Ключевые слова нуждаются в окончаниях, а окончания — в ключевых словах
Если у нас больше ключевых слов, то отсутствует «end»; если у нас больше «end»-ов, то отсутствует ключевое слово
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 131
def missing_pairs
PAIRS.map do |(left, right)|
case @count_for_char[left] <=> @count_for_char[right]
when 1
right
when 0
nil
when -1
left
end
end
end Открывающие символы, такие как ‘{’, нуждаются в закрывающих символах, таких как `}`.
При обнаружении несоответствия в подсчете предлагается отсутствующий член.
Например, если есть 3 ‘}` и только две `{`, возвращается `“{”`
Исходный код
# File lib/syntax_suggest/left_right_lex_count.rb, line 162
def missing_pipe
if @count_for_char["|"].odd?
"|"
end
end Символы «|» встречаются парами. Если количество символов «|» нечетно, значит, один отсутствует
Ruby Core © 1993–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.