Skip to content

Commit c249a97

Browse files
vitautfacebook-github-bot
authored andcommitted
Migrate away from legacy Thrift compiler API
Summary: `parse_and_get_program` is a legacy API that has a number of problems: * It takes stringly-typed arguments, most of which are ignored. * It may return an invalid AST (missing includes, unresolved types) which is not obvious at the call sites. * It claims to not run mutators which doesn't make sense since mutation is an important part of semantic analysis and should be run e.g. for type inference. Migrate two of its few uses to `parse_ast` in preparation for removal. Reviewed By: rmakheja Differential Revision: D68496448 fbshipit-source-id: 8479a1a566d3d037ead19448a8b06cfc4a088a71
1 parent 91810fe commit c249a97

File tree

4 files changed

+56
-18
lines changed

4 files changed

+56
-18
lines changed

third-party/thrift/src/thrift/compiler/codemod/codemod.cc

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <fmt/core.h>
1818
#include <thrift/compiler/codemod/codemod.h>
1919
#include <thrift/compiler/compiler.h>
20+
#include <thrift/compiler/parse/parse_ast.h>
21+
#include <thrift/compiler/sema/sema_context.h>
2022

2123
namespace apache::thrift::compiler {
2224

@@ -29,12 +31,27 @@ int run_codemod(
2931
return 1;
3032
}
3133

34+
// Parse command-line arguments.
35+
auto parsing_params = compiler::parsing_params();
36+
auto sema_params = compiler::sema_params();
37+
std::optional<std::string> filename = detail::parse_command_line_args(
38+
{argv, argv + argc}, parsing_params, sema_params);
39+
if (!filename) {
40+
return 1;
41+
}
42+
parsing_params.allow_missing_includes = true;
43+
sema_params.skip_lowering_annotations = true;
44+
45+
// Parse the Thrift file.
3246
auto source_mgr = source_manager();
33-
auto program_bundle = parse_and_get_program(
34-
source_mgr, std::vector<std::string>(argv, argv + argc));
47+
auto diags = make_diagnostics_printer(source_mgr);
48+
auto program_bundle =
49+
parse_ast(source_mgr, diags, *filename, parsing_params, &sema_params);
3550
if (!program_bundle) {
3651
return 1;
3752
}
53+
54+
// Run the codemod.
3855
codemod(source_mgr, *program_bundle->root_program());
3956
return 0;
4057
}

third-party/thrift/src/thrift/compiler/codemod/test/file_manager_test.cc

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,39 +19,36 @@
1919
#include <gtest/gtest.h>
2020
#include <thrift/compiler/ast/t_program_bundle.h>
2121
#include <thrift/compiler/codemod/file_manager.h>
22-
#include <thrift/compiler/compiler.h>
22+
#include <thrift/compiler/parse/parse_ast.h>
2323
#include <thrift/compiler/source_location.h>
2424

25-
namespace apache::thrift::compiler::codemod {
26-
27-
namespace {
28-
29-
using ::testing::Eq;
30-
using ::testing::IsTrue;
3125
using ::testing::NotNull;
3226
using ::testing::StrEq;
3327
using std::literals::string_view_literals::operator""sv;
3428

35-
static const std::string kVirtualFileName("virtual/path/file1.thrift");
29+
namespace apache::thrift::compiler::codemod {
30+
namespace {
31+
32+
const std::string test_file_name = "virtual/path/file1.thrift";
3633

37-
static const std::string kVirtualFileContents(R"(
34+
const std::string test_file_contents = R"(
3835
package "test.module"
3936
4037
namespace java test.module
4138
4239
struct Foo {
4340
1: optional i32 bar;
4441
}
45-
)");
42+
)";
4643
} // namespace
4744

4845
class FileManagerTest : public ::testing::Test {
4946
protected:
5047
void SetUp() override {
51-
source_ = source_manager_.add_virtual_file(
52-
kVirtualFileName, kVirtualFileContents);
53-
program_bundle_ = parse_and_get_program(
54-
source_manager_, {"<virtual compiler>", kVirtualFileName});
48+
source_ =
49+
source_manager_.add_virtual_file(test_file_name, test_file_contents);
50+
auto diags = make_diagnostics_printer(source_manager_);
51+
program_bundle_ = parse_ast(source_manager_, diags, test_file_name, {});
5552
ASSERT_THAT(program_bundle_, NotNull());
5653

5754
file_manager_ = std::make_unique<file_manager>(
@@ -65,9 +62,9 @@ class FileManagerTest : public ::testing::Test {
6562
};
6663

6764
TEST_F(FileManagerTest, old_content) {
68-
// NOTE: comparison is done via underlying data() using STREQ because the text
65+
// NOTE: comparison is done via underlying data() using StrEq because the text
6966
// in the source manager is explicitly null-terminated.
70-
EXPECT_THAT(file_manager_->old_content().data(), StrEq(kVirtualFileContents));
67+
EXPECT_THAT(file_manager_->old_content().data(), StrEq(test_file_contents));
7168
}
7269

7370
TEST_F(FileManagerTest, add_include) {

third-party/thrift/src/thrift/compiler/compiler.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,19 @@ std::unique_ptr<t_program_bundle> parse_and_mutate(
839839

840840
} // namespace
841841

842+
std::optional<std::string> detail::parse_command_line_args(
843+
const std::vector<std::string>& args,
844+
parsing_params& parsing_params,
845+
sema_params& sema_params) {
846+
gen_params gen_params = {};
847+
gen_params.targets.emplace_back(); // Avoid the need to pass --gen.
848+
diagnostic_params diag_params = {};
849+
auto filename =
850+
parse_args(args, parsing_params, gen_params, diag_params, sema_params);
851+
return filename.empty() ? std::nullopt
852+
: std::make_optional(std::move(filename));
853+
}
854+
842855
std::pair<std::unique_ptr<t_program_bundle>, diagnostic_results>
843856
parse_and_mutate_program(
844857
source_manager& sm,

third-party/thrift/src/thrift/compiler/compiler.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,24 @@
1717
#pragma once
1818

1919
#include <memory>
20+
#include <optional>
2021
#include <string>
2122
#include <vector>
2223

2324
#include <thrift/compiler/diagnostic.h>
2425
#include <thrift/compiler/parse/parse_ast.h> // parsing_params
2526

2627
namespace apache::thrift::compiler {
28+
namespace detail {
29+
30+
// Parses command-line arguments and returns the input file name if successful;
31+
// otherwise returns an empty optional.
32+
[[nodiscard]] std::optional<std::string> parse_command_line_args(
33+
const std::vector<std::string>& args,
34+
parsing_params& parsing_params,
35+
sema_params& sema_params);
36+
37+
} // namespace detail
2738

2839
class t_program_bundle;
2940

0 commit comments

Comments
 (0)