From 67480301d29b39a6f2744c8422c7535423c6e313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Fri, 17 Dec 2021 01:13:43 +0100 Subject: [PATCH] Revert "Formatter: Escape non-printable characters in literals (#11520)" This reverts commit bd827662e62ab2e2cc7f8b3df8b9f42f768c9617. --- spec/compiler/formatter/formatter_spec.cr | 43 +----------------- src/compiler/crystal/tools/formatter.cr | 54 ++++------------------- 2 files changed, 11 insertions(+), 86 deletions(-) diff --git a/spec/compiler/formatter/formatter_spec.cr b/spec/compiler/formatter/formatter_spec.cr index 08b876d004d1..6ea82782d924 100644 --- a/spec/compiler/formatter/formatter_spec.cr +++ b/spec/compiler/formatter/formatter_spec.cr @@ -450,49 +450,10 @@ describe Crystal::Formatter do assert_format "__DIR__", "__DIR__" assert_format "__LINE__", "__LINE__" - assert_format %("\\0\\"\#\a\b\r\n\t\v\f\e\\xFF"), %("\\0\\"\#\\a\\b\\r\n\t\\v\\f\\e\\xFF") - assert_format %("\u00AD\uF8FF\u202A"), %("\\u00AD\\uF8FF\\u202A") - assert_format %("\\0\\"\#\a\b\r\n\t\v\f\e\\xFF\#{nil}"), %("\\0\\"\#\\a\\b\\r\n\t\\v\\f\\e\\xFF\#{nil}") - assert_format %("\u00AD\uF8FF\u202A\#{nil}"), %("\\u00AD\\uF8FF\\u202A\#{nil}") - assert_format %(:"\\0\\"\#\a\b\r\n\t\v\f\e\\xFF"), %(:"\\0\\"\#\\a\\b\\r\n\t\\v\\f\\e\\xFF") - assert_format %(:"\u00AD\uF8FF\u202A"), %(:"\\u00AD\\uF8FF\\u202A") - assert_format %(<<-HERE\n\\0"\#\a\b\r\n\t\v\f\e\\xFF\nHERE), %(<<-HERE\n\\0"\#\\a\\b\\r\n\t\\v\\f\\e\\xFF\nHERE) - assert_format %(<<-HERE\n\u00AD\uF8FF\u202A\nHERE), %(<<-HERE\n\\u00AD\\uF8FF\\u202A\nHERE) - assert_format %q("\\0\\\"\#\a\b\n\r\t\v\f\e\\xFF") + assert_format %q("\\\"\#\a\b\n\r\t\v\f\e") assert_format %q("\a\c\b\d"), %q("\ac\bd") - assert_format %q("\\0\\\"\#\a\b\n\r\t#{foo}\v\f\e\\xFF") + assert_format %q("\\\"\#\a\b\n\r\t#{foo}\v\f\e") assert_format %q("\a\c#{foo}\b\d"), %q("\ac#{foo}\bd") - assert_format %(%w(\\0\\"\#\a\b\r\n\t\v\f\e\\xFF)), %(%w(\\0\\"\#\\a\\b \\e\\xFF)) - assert_format %(%w(\u00AD\uF8FF\u202A)), %(%w(\\u00AD\\uF8FF\\u202A)) - assert_format %(%i(\\0\\"\#\a\b\r\n\t\v\f\e\\xFF)), %(%i(\\0\\"\#\\a\\b \\e\\xFF)) - assert_format %(%i(\u00AD\uF8FF\u202A)), %(%i(\\u00AD\\uF8FF\\u202A)) - - assert_format %("\\u0061\\u{61}\\u0009\\u{9}") - - assert_format "'\\''" - assert_format "'\\0'" - assert_format "'\\u0000'" - assert_format "'\\\\'" - assert_format "'\a'", "'\\a'" - assert_format "'\b'", "'\\b'" - assert_format "'\r'", "'\\r'" - assert_format "'\n'", "'\\n'" - assert_format "'\t'", "'\\t'" - assert_format "'\v'", "'\\v'" - assert_format "'\f'", "'\\f'" - assert_format "'\e'", "'\\e'" - assert_format "'\u00AD'", "'\\u00AD'" - assert_format "'\uF8FF'", "'\\uF8FF'" - assert_format "'\u202A'", "'\\u202A'" - assert_format "'青'" - assert_format "'\\u9752'" - assert_format "'\\u9752'" - assert_format "'\u{110BD}'", "'\\u{110BD}'" - assert_format "'\u{1F48E}'", "'\u{1F48E}'" - assert_format "'\\u0061'" - assert_format "'\\u{61}'" - assert_format "'\\u0009'" - assert_format "'\\u{9}'" assert_format %("\#{foo = 1\n}"), %("\#{foo = 1}") assert_format %("\#{\n foo = 1\n}") diff --git a/src/compiler/crystal/tools/formatter.cr b/src/compiler/crystal/tools/formatter.cr index ee0ce1acaffc..cb0f726c6fc7 100644 --- a/src/compiler/crystal/tools/formatter.cr +++ b/src/compiler/crystal/tools/formatter.cr @@ -432,14 +432,7 @@ module Crystal def visit(node : CharLiteral) check :CHAR - if @token.raw[1].printable? - # Keep original format when printable. - # This makes sure that printable representations of non-printable characters stay unmodified. - # Example: `'\u0009'` must not be converted to `'\t'`. - write @token.raw - else - write node.value.inspect - end + write @token.raw next_token false @@ -447,7 +440,7 @@ module Crystal def visit(node : SymbolLiteral) check :SYMBOL - write_string @token + write @token.raw next_token false @@ -467,39 +460,6 @@ module Crystal false end - def write_string(token) - string = if token.invalid_escape - token.value.as(String) - else - token.raw - end - - write escape_nonprintable(string) - end - - # Escapes non-printable characters in *string*. - # This is similar to `String#inspect` except `\n` and `\t` characters are - # printed literally. These control characters should not be escaped to keep - # the code formating intact. - def escape_nonprintable(string) - String.build do |io| - string.each_char do |char| - case char - when '\a' then io << "\\a" - when '\b' then io << "\\b" - when '\e' then io << "\\e" - when '\v' then io << "\\v" - when '\f' then io << "\\f" - when '\r' then io << "\\r" - when '\n', '\t', .printable? - io << char - else - char.unicode_escape(io) - end - end - end - end - def visit(node : StringLiteral) column = @column @@ -518,7 +478,11 @@ module Crystal while true case @token.type when :STRING - write_string @token + if @token.invalid_escape + write @token.value + else + write @token.raw + end next_string_token when :INTERPOLATION_START # This is the case of #{__DIR__} @@ -633,7 +597,7 @@ module Crystal else loop do check :STRING - write_string @token + write @token.invalid_escape ? @token.value : @token.raw next_string_token # On heredoc, pieces of contents are combined due to removing indentation. @@ -806,7 +770,7 @@ module Crystal case @token.type when :STRING write " " unless first || has_space_newline - write_string @token + write @token.raw first = false when :STRING_ARRAY_END write @token.raw