From bebc3f399d0253bf622462dde147c1fb59f0fc95 Mon Sep 17 00:00:00 2001 From: schneems Date: Wed, 17 Nov 2021 11:20:48 -0600 Subject: [PATCH] Handle shorthand syntax in explanations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When performing a performance test on https://github.com/kddnewton/syntax_tree/blob/50f9fc1b815156bdde53f13d4f250d9522f15e64/test/syntax_tree_test.rb I noticed a strange output. The explain syntax indicated that it was missing a bracket when I had only deleted an `end`: ``` $ time DEAD_END_TIMEOUT=10 ./exe/dead_end spec/fixtures/syntax_tree.rb.txt --> /Users/rschneeman/Documents/projects/dead_end/spec/fixtures/syntax_tree.rb.txt Unmatched `]', missing `[' ? Unmatched keyword, missing `end' ? 6 class SyntaxTree < Ripper 170 def self.parse(source) 174 end 176 private ❯ 754 def on_args_add(arguments, argument) ❯ 776 class ArgsAddBlock ❯ 810 end 9233 end DEAD_END_TIMEOUT=10 ./exe/dead_end spec/fixtures/syntax_tree.rb.txt 1.63s user 0.07s system 99% cpu 1.703 total ``` The cause was this line: ``` node.is_a?(Op) && %w[| ||].include?(node.value) && ``` With the `%w[]` syntax the lexer tokenizes `%w[` which *since it doesn't match `[`) is not counted. This commit corrects that logic by explicitly looking for the last character of these events. --- CHANGELOG.md | 2 ++ lib/dead_end/left_right_lex_count.rb | 11 +++++++++++ spec/unit/explain_syntax_spec.rb | 12 ++++++++++++ 3 files changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e3565c..578fb39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## HEAD (unreleased) +- Fix explanation involving shorthand syntax for literals like `%w[]` and `%Q{}` (https://github.com/zombocom/dead_end/pull/116) + ## 3.0.2 - Fix windows filename detection (https://github.com/zombocom/dead_end/pull/114) diff --git a/lib/dead_end/left_right_lex_count.rb b/lib/dead_end/left_right_lex_count.rb index 1430ac8..3b71ade 100644 --- a/lib/dead_end/left_right_lex_count.rb +++ b/lib/dead_end/left_right_lex_count.rb @@ -61,6 +61,17 @@ def count_lex(lex) # ^^^ # 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"` diff --git a/spec/unit/explain_syntax_spec.rb b/spec/unit/explain_syntax_spec.rb index a9ea9af..5d0905b 100644 --- a/spec/unit/explain_syntax_spec.rb +++ b/spec/unit/explain_syntax_spec.rb @@ -4,6 +4,18 @@ module DeadEnd RSpec.describe "ExplainSyntax" do + it "handles %w[]" do + source = <<~EOM + node.is_a?(Op) && %w[| ||].include?(node.value) && + EOM + + explain = ExplainSyntax.new( + code_lines: CodeLine.from_source(source) + ).call + + expect(explain.missing).to eq([]) + end + it "doesn't falsely identify strings or symbols as critical chars" do source = <<~EOM a = ['(', '{', '[', '|']