Przeglądaj źródła

Fix autoupdate handling of carriage return (#4840)

Switching from RE2 to StrReplaceAll because it seems a fair fit for what
actually needs to be done here. Also pick up \t for visibility reasons.

This came up because clangd's LSP-related APIs print carriage returns.
Jon Ross-Perkins 1 rok temu
rodzic
commit
aec951d7c3

+ 1 - 0
testing/file_test/BUILD

@@ -19,6 +19,7 @@ cc_library(
         "//common:check",
         "//common:ostream",
         "//common:raw_string_ostream",
+        "@abseil-cpp//absl/strings",
         "@abseil-cpp//absl/strings:string_view",
         "@llvm-project//llvm:Support",
         "@re2",

+ 11 - 9
testing/file_test/autoupdate.cpp

@@ -6,6 +6,7 @@
 
 #include <fstream>
 
+#include "absl/strings/str_replace.h"
 #include "absl/strings/string_view.h"
 #include "common/check.h"
 #include "common/ostream.h"
@@ -158,12 +159,6 @@ auto FileTestAutoupdater::BuildCheckLines(llvm::StringRef output,
     lines.pop_back();
   }
 
-  // `{{` and `[[` are escaped as a regex matcher.
-  static RE2 double_brace_re(R"(\{\{)");
-  static RE2 double_square_bracket_re(R"(\[\[)");
-  // End-of-line whitespace is replaced with a regex matcher to make it visible.
-  static RE2 end_of_line_whitespace_re(R"((\s+)$)");
-
   // The default file number for when no specific file is found.
   int default_file_number = 0;
 
@@ -182,9 +177,16 @@ auto FileTestAutoupdater::BuildCheckLines(llvm::StringRef output,
       check_line.append(line);
     }
 
-    RE2::Replace(&check_line, double_brace_re, R"({{\\{\\{}})");
-    RE2::Replace(&check_line, double_square_bracket_re, R"({{\\[\\[}})");
-    RE2::Replace(&check_line, end_of_line_whitespace_re, R"({{\1}})");
+    // \r and \t are invisible characters worth marking.
+    // {{ and [[ are autoupdate syntax which we need to escape.
+    check_line = absl::StrReplaceAll(check_line, {{"\r", R"({{\r}})"},
+                                                  {"\t", R"({{\t}})"},
+                                                  {"{{", R"({{\{\{}})"},
+                                                  {"[[", R"({{\[\[}})"}});
+    // Add an empty regex to call out end-of-line whitespace.
+    if (check_line.ends_with(' ')) {
+      check_line.append("{{}}");
+    }
 
     // Ignore TEST_TMPDIR in output.
     if (auto pos = check_line.find(tmpdir); pos != std::string::npos) {

+ 14 - 0
testing/file_test/file_test_base_test.cpp

@@ -185,6 +185,19 @@ static auto TestNoLineNumber(TestParams& params)
   return {{.success = true}};
 }
 
+// Prints and returns expected results for escaping.carbon.
+static auto TestEscaping(TestParams& params)
+    -> ErrorOr<FileTestBaseTest::RunResult> {
+  params.error_stream << "carriage return\r\n"
+                         "{one brace}\n"
+                         "{{two braces}}\n"
+                         "[one bracket]\n"
+                         "[[two brackets]]\n"
+                         "end of line whitespace   \n"
+                         "\ttabs\t\n";
+  return {{.success = true}};
+}
+
 // Prints and returns expected results for stdin.carbon.
 static auto TestStdin(TestParams& params)
     -> ErrorOr<FileTestBaseTest::RunResult> {
@@ -268,6 +281,7 @@ auto FileTestBaseTest::Run(
           filename.string())
           .Case("alternating_files.carbon", &TestAlternatingFiles)
           .Case("capture_console_output.carbon", &TestCaptureConsoleOutput)
+          .Case("escaping.carbon", &TestEscaping)
           .Case("example.carbon", &TestExample)
           .Case("fail_example.carbon", &TestFailExample)
           .Case("file_only_re_one_file.carbon", &TestFileOnlyREOneFile)

+ 19 - 0
testing/file_test/testdata/escaping.carbon

@@ -0,0 +1,19 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// SET-CAPTURE-CONSOLE-OUTPUT
+// AUTOUPDATE
+// TIP: To test this file alone, run:
+// TIP:   bazel test //testing/file_test:file_test_base_test --test_arg=--file_tests=testing/file_test/testdata/escaping.carbon
+// TIP: To dump output, run:
+// TIP:   bazel run //testing/file_test:file_test_base_test -- --dump_output --file_tests=testing/file_test/testdata/escaping.carbon
+// CHECK:STDERR: carriage return{{\r}}
+// CHECK:STDERR: {one brace}
+// CHECK:STDERR: {{\{\{}}two braces}}
+// CHECK:STDERR: [one bracket]
+// CHECK:STDERR: {{\[\[}}two brackets]]
+// CHECK:STDERR: end of line whitespace   {{}}
+// CHECK:STDERR: {{\t}}tabs{{\t}}
+
+// CHECK:STDOUT: 2 args: `default_args`, `escaping.carbon`

BIN
toolchain/lex/testdata/string_literals.carbon