Skip to content

Commit 1c4165c

Browse files
iahsfacebook-github-bot
authored andcommitted
Add cpp.indirection to type lowering mechanism
Summary: The implementation of cpp.indirection does not handle typedefs correctly. Lower the annotation onto the inner type of typedefs to unblock the codemod while this is fixed. Reviewed By: dtolnay Differential Revision: D69195637 fbshipit-source-id: 87e53baafa89ecb832bb188ea20ab81755aa5e8f
1 parent c7abd10 commit 1c4165c

File tree

1 file changed

+55
-40
lines changed

1 file changed

+55
-40
lines changed

thrift/compiler/sema/sema.cc

+55-40
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,51 @@ void update_annotations(
435435
node.reset_annotations(std::move(annotations));
436436
}
437437

438+
// Updates field or typedef's type field to hold annotations
439+
template <typename Node>
440+
void add_annotations_to_node_type(
441+
Node& node,
442+
std::map<std::string, std::string> annotations,
443+
t_program& program) {
444+
const t_type* node_type = node.get_type();
445+
446+
if (annotations.empty()) {
447+
if (!node_type->annotations().empty()) {
448+
update_annotations(const_cast<t_type&>(*node_type));
449+
}
450+
return;
451+
}
452+
453+
if (node_type->is_container() ||
454+
(node_type->is_typedef() &&
455+
static_cast<const t_typedef*>(node_type)->typedef_kind() !=
456+
t_typedef::kind::defined) ||
457+
(node_type->is_primitive_type() && !node_type->annotations().empty())) {
458+
// This is a new type we can modify in place
459+
update_annotations(const_cast<t_type&>(*node_type), std::move(annotations));
460+
} else if (node_type->is_primitive_type()) {
461+
// Copy type as we don't handle unnamed typedefs to base types :(
462+
auto unnamed = std::make_unique<t_primitive_type>(
463+
*static_cast<const t_primitive_type*>(node_type));
464+
for (auto& pair : annotations) {
465+
unnamed->set_annotation(pair.first, pair.second);
466+
}
467+
node.set_type(t_type_ref::from_ptr(unnamed.get()));
468+
program.add_unnamed_type(std::move(unnamed));
469+
} else {
470+
// Wrap in an unnamed typedef :(
471+
auto unnamed = t_typedef::make_unnamed(
472+
const_cast<t_program*>(node_type->get_program()),
473+
node_type->get_name(),
474+
t_type_ref::from_ptr(node_type));
475+
for (auto& pair : annotations) {
476+
unnamed->set_annotation(pair.first, pair.second);
477+
}
478+
node.set_type(t_type_ref::from_ptr(unnamed.get()));
479+
program.add_unnamed_typedef(std::move(unnamed));
480+
}
481+
}
482+
438483
void lower_deprecated_annotations(
439484
sema_context& ctx, mutator_context& mCtx, t_named& node) {
440485
if (auto cnst = node.find_structured_annotation_or_null(
@@ -494,6 +539,15 @@ void lower_deprecated_annotations(
494539
}
495540
}
496541

542+
// cpp.indirection does not handle typedefs correctly
543+
if (auto* typedf = dynamic_cast<t_typedef*>(&node);
544+
typedf && map.count("cpp.indirection")) {
545+
add_annotations_to_node_type(
546+
*typedf,
547+
{{"cpp.indirection", map.at("cpp.indirection").value}},
548+
mCtx.program());
549+
}
550+
497551
node.reset_annotations(std::move(map));
498552
} else {
499553
update_annotations(node);
@@ -540,46 +594,7 @@ void lower_type_annotations(
540594
}
541595
}
542596

543-
const t_type* node_type = node.get_type();
544-
545-
if (unstructured.empty()) {
546-
if (!node_type->annotations().empty()) {
547-
update_annotations(const_cast<t_type&>(*node_type));
548-
}
549-
return;
550-
}
551-
552-
if (node_type->is_container() ||
553-
(node_type->is_typedef() &&
554-
static_cast<const t_typedef*>(node_type)->typedef_kind() !=
555-
t_typedef::kind::defined) ||
556-
(node_type->is_primitive_type() && !node_type->annotations().empty())) {
557-
// This is a new type we can modify in place
558-
update_annotations(
559-
const_cast<t_type&>(*node_type), std::move(unstructured));
560-
} else if (node_type->is_primitive_type()) {
561-
// Copy type as we don't handle unnamed typedefs to base types :(
562-
auto& program = mctx.program();
563-
auto unnamed = std::make_unique<t_primitive_type>(
564-
*static_cast<const t_primitive_type*>(node_type));
565-
for (auto& pair : unstructured) {
566-
unnamed->set_annotation(pair.first, pair.second);
567-
}
568-
node.set_type(t_type_ref::from_ptr(unnamed.get()));
569-
program.add_unnamed_type(std::move(unnamed));
570-
} else {
571-
// Wrap in an unnamed typedef :(
572-
auto& program = mctx.program();
573-
auto unnamed = t_typedef::make_unnamed(
574-
const_cast<t_program*>(node_type->get_program()),
575-
node_type->get_name(),
576-
t_type_ref::from_ptr(node_type));
577-
for (auto& pair : unstructured) {
578-
unnamed->set_annotation(pair.first, pair.second);
579-
}
580-
node.set_type(t_type_ref::from_ptr(unnamed.get()));
581-
program.add_unnamed_typedef(std::move(unnamed));
582-
}
597+
add_annotations_to_node_type(node, std::move(unstructured), mctx.program());
583598
}
584599

585600
void inject_schema_const(sema_context& ctx, mutator_context&, t_program& prog) {

0 commit comments

Comments
 (0)