in unsupported/tools/rustgen/rustgen.cpp [374:481]
static void genConvert() {
llvh::outs() << "pub unsafe fn cvt_node_ptr<'parser, 'gc>(\n"
" cvt: &mut Converter<'parser>, \n"
" gc: &'gc ast::GCLock, \n"
" n: NodePtr) -> &'gc ast::Node<'gc> {\n";
llvh::outs() << " let nr = n.as_ref();\n"
" let range = ast::SourceRange {\n"
" file: cvt.file_id,\n"
" start: cvt.cvt_smloc(nr.source_range.start),\n"
" end: ast::SourceLoc::invalid(),\n"
" };\n"
"\n";
llvh::outs() << " let res = match nr.kind {\n";
auto genStruct = [](const TreeClass &cls) {
if (cls.sentinel != SentinelType::None)
return;
if (strncmp(cls.name.c_str(), "Cover", 5) == 0)
return;
llvh::outs() << " NodeKind::" << cls.name << " => {\n";
// Declare all the fields as local vars to avoid multiple borrows
// of the context.
for (const auto &fld : cls.fields) {
llvh::outs() << " let " << fld.rustName() << " = ";
bool close = true;
switch (fld.type) {
case FieldType::NodeString:
llvh::outs() << "cvt_string" << (fld.optional ? "_opt" : "") << "(";
break;
case FieldType::NodeLabel:
if ((cls.name == "UnaryExpression" && fld.name == "operator") ||
(cls.name == "BinaryExpression" && fld.name == "operator") ||
(cls.name == "LogicalExpression" && fld.name == "operator") ||
(cls.name == "UpdateExpression" && fld.name == "operator") ||
(cls.name == "VariableDeclaration" && fld.name == "kind") ||
(cls.name == "Property" && fld.name == "kind") ||
(cls.name == "MethodDefinition" && fld.name == "kind") ||
(cls.name == "ImportDeclaration" && fld.name == "importKind") ||
(cls.name == "ImportSpecifier" && fld.name == "importKind") ||
(cls.name == "ExportNamedDeclaration" &&
fld.name == "exportKind") ||
(cls.name == "ExportAllDeclaration" &&
fld.name == "exportKind") ||
(cls.name == "AssignmentExpression" && fld.name == "operator"))
llvh::outs() << "cvt_enum(";
else
llvh::outs() << "cvt.cvt_label" << (fld.optional ? "_opt" : "")
<< "(gc, ";
break;
case FieldType::Boolean:
case FieldType::Number:
default:
close = false;
break;
case FieldType::NodePtr:
llvh::outs() << "cvt_node_ptr" << (fld.optional ? "_opt" : "")
<< "(cvt, gc, ";
break;
case FieldType::NodeList:
llvh::outs() << "cvt_node_list" << (fld.optional ? "_opt" : "")
<< "(cvt, gc, ";
break;
}
llvh::outs() << "hermes_get_" << cls.name << "_" << fld.name << "(n)";
if (close)
llvh::outs() << ")";
llvh::outs() << ";\n";
}
llvh::outs()
<< " let mut template = ast::template::" << cls.name << " {\n"
<< " metadata: ast::TemplateMetadata {range, ..Default::default()},\n";
for (const auto &fld : cls.fields) {
// Shorthand initialization of each field.
llvh::outs() << " " << fld.rustName() << ",\n";
}
llvh::outs()
<< " };\n" // kind
" template.metadata.range.end = cvt.cvt_smloc(nr.source_range.end.pred());\n"
<< " ast::builder::" << cls.name
<< "::build_template(gc, template)\n"
<< " }\n"; // match block
};
for (const auto &cls : treeClasses_) {
if (cls.sentinel != SentinelType::None)
continue;
genStruct(cls);
}
llvh::outs()
<< " _ => {\n"
" cvt.report_invalid_node(gc, n, range);\n"
" let template = ast::template::Empty {\n"
" metadata: ast::TemplateMetadata {range, ..Default::default()}\n"
" };\n"
" ast::builder::Empty::build_template(gc, template)\n"
" }\n"
" };\n\n";
llvh::outs() << " res\n";
llvh::outs() << "}\n";
}