diff --git a/lib/method_source/code_helpers.rb b/lib/method_source/code_helpers.rb index 6c1d53e..d29f85e 100644 --- a/lib/method_source/code_helpers.rb +++ b/lib/method_source/code_helpers.rb @@ -71,8 +71,7 @@ def complete_expression?(str) eval("BEGIN{throw :valid}\n#{str}") end - # Assert that a line which ends with a , or \ is incomplete. - str !~ /[,\\]\s*\z/ + no_ending_comma?(str) || backslashed_string?(str) rescue IncompleteExpression false ensure @@ -81,6 +80,32 @@ def complete_expression?(str) private + # Determine if a representation of a string as a string ends with comma. + # + # @param [String] The string to validate. + # @return [Boolean] Whether or not the string ends with comma + def no_ending_comma?(str) + str !~ /[,\\]\s*\z/ + end + + # Determine if a backslashed string as a string, + # after removing the matching backslashes, ends with + # comma or a backslash. + # + # @param [String] The string to validate. + # @return [Boolean] Whether or not the remaining string ends with + # comma or backslash. + # + # @example + # backslashed_string?("%\a\\") #=> true + # backslashed_string?("%\\\\") #=> true + # backslashed_string?("%\abc\\") #=> true + def backslashed_string?(str) + remaining_str = str[/%\\(.*)\\\s*\z/, 1] + + !remaining_str.nil? && remaining_str !~ /[,\\]\s*\z/ + end + # Get the first expression from the input. # # @param [Array] lines diff --git a/test/test_code_helpers.rb b/test/test_code_helpers.rb index ba83a63..e3e94ae 100644 --- a/test/test_code_helpers.rb +++ b/test/test_code_helpers.rb @@ -23,6 +23,16 @@ end end + [ + '%\a\\', + '%\abc\\', + '%\\\\', + ].each do |line| + it "should not complain on backslashed strings: #{line}" do + @tester.complete_expression?(line).should == true + end + end + [ ["end"], ["puts )("],