From 82849abd4400800fcc4132a6f34ae0ae9b5fca43 Mon Sep 17 00:00:00 2001 From: Shai Szulanski Date: Thu, 30 Jan 2025 18:00:53 -0800 Subject: [PATCH] Handle quotes in annotations codemod Summary: We encounter this for cpp.methods, which sometimes injects constructors with default string arguments Reviewed By: yoney Differential Revision: D68931171 fbshipit-source-id: 928c9a104f0bce14d2f76cca89c668f86484f264 --- .../compiler/codemod/structure_annotations.cc | 18 +++++++++++++++++- .../codemod/structure_annotations_test.py | 4 ++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/thrift/compiler/codemod/structure_annotations.cc b/thrift/compiler/codemod/structure_annotations.cc index 1f4c774e692..fbcc26d7243 100644 --- a/thrift/compiler/codemod/structure_annotations.cc +++ b/thrift/compiler/codemod/structure_annotations.cc @@ -33,6 +33,22 @@ bool is_container(const t_type& type) { return true_type && true_type->is_container(); } +std::string quote(std::string_view str) { + if (str.find('"') == std::string::npos) { + return fmt::format("\"{}\"", str); + } else if (str.find('\'') == std::string::npos) { + return fmt::format("'{}'", str); + } else { + std::string out(str); + size_t start_pos = 0; + while ((start_pos = out.find('"', start_pos)) != std::string::npos) { + out.replace(start_pos, 1, "\\\""); + start_pos += 2; + } + return fmt::format("\"{}\"", out); + } +} + class structure_annotations { public: structure_annotations(source_manager& sm, t_program& program) @@ -516,7 +532,7 @@ class structure_annotations { std::vector annotations_for_catch_all_strs; for (const auto& [name, value] : annotations_for_catch_all) { annotations_for_catch_all_strs.push_back( - fmt::format(R"("{}": "{}")", name, value)); + fmt::format(R"("{}": {})", name, quote(value))); } to_add.insert(fmt::format( "@thrift.DeprecatedUnvalidatedAnnotations{{items = {{{}}}}}", diff --git a/thrift/compiler/codemod/structure_annotations_test.py b/thrift/compiler/codemod/structure_annotations_test.py index 549f032692b..5340204a6c6 100644 --- a/thrift/compiler/codemod/structure_annotations_test.py +++ b/thrift/compiler/codemod/structure_annotations_test.py @@ -489,7 +489,7 @@ def test_remaining(self): include "thrift.thrift" struct S { - 1: i32 field1 (foo); + 1: i32 field1 (foo, quote = '"', both_quotes = "'\\"'"); }(foo, bar = "baz") typedef i32 (foo, hs.type = "hs") T (bar = "baz", hs.category = "value") @@ -530,7 +530,7 @@ def test_remaining(self): @thrift.DeprecatedUnvalidatedAnnotations{items = {"bar": "baz", "foo": "1"}} struct S { - @thrift.DeprecatedUnvalidatedAnnotations{items = {"foo": "1"}} + @thrift.DeprecatedUnvalidatedAnnotations{items = {"both_quotes": "'\\"'", "foo": "1", "quote": '"'}} 1: i32 field1 ; }