/*
* Copyright (c) 2024-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Autogenerated file -- DO NOT EDIT!
// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-non-const-parameter)
// NOLINTBEGIN(readability-function-size, readability-magic-numbers)
% Enums::enums&.each do |name, enum|
% if enum.flags&.length > 0
extern "C" __attribute__((unused)) <%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %> E2pToIr<%= name %>(Es2panda<%= name %> e2pFlags)
{
% if enum.type == 'unsigned'
% if enum.flags.length <= 32 || enum.type == "int"
auto irFlags = (<%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %>)0U;
% enum.flags&.each do |flag|
irFlags |= (e2pFlags & Es2panda<%= name %>::<%= enum.name_to_upper_snake %>_<%= flag %>) != 0 ? <%= enum.namespace %><%=
if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %>::<%= flag %> : (<%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %>)0U;
% end
% else
auto irFlags = (<%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %>)0U;
% enum.flags&.each_with_index do |flag, index|
irFlags |= (e2pFlags & <%= if index > 0 then "(uint64_t)1U << " +
(index - 1).to_s + "U" else "(uint64_t)0U" end %>) != 0 ? <%=
enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %>::<%= flag %> : (<%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %>)0U;
% end
% end
return irFlags;
% else
switch(e2pFlags)
{
% enum.flags&.each do |flag|
case Es2panda<%= name %>::<%= enum.name_to_upper_snake %>_<%= flag %>:
return <%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %>::<%= flag %>;
% end
default:
ES2PANDA_UNREACHABLE();
}
%end
}
% end
%end
% Enums::enums&.each do |name, enum|
% if enum.flags&.length > 0
extern "C" __attribute__((unused)) Es2panda<%= name %> IrToE2p<%= name %>(<%=
enum.namespace %><%= if enum.parent_class_name then
"::" + enum.parent_class_name end %>::<%= name %> irFlags)
{
% if enum.type == 'unsigned'
Es2panda<%= name %> e2pFlags {(Es2panda<%= name %>)0U};
% if enum.flags.length <= 32 || enum.type == "int"
% enum.flags&.each do |flag|
e2pFlags = static_cast<Es2panda<%= name %>>((irFlags & <%= enum.namespace %><%= if enum.parent_class_name then
"::" + enum.parent_class_name end %>::<%= name %>::<%= flag
%>) != 0 ? e2pFlags | Es2panda<%= name %>::<%= enum.name_to_upper_snake %>_<%= flag %> : e2pFlags);
% end
% else
% enum.flags&.each_with_index do |flag, index|
e2pFlags = static_cast<Es2panda<%= name %>>((irFlags & <%= enum.namespace %><%= if enum.parent_class_name then
"::" + enum.parent_class_name end %>::<%= name %>::<%= flag
%>) != 0 ? e2pFlags | <%= if index > 0 then "(uint64_t)1U << " + (index - 1).to_s + "U"
else "(uint64_t)0U" end %> : e2pFlags);
% end
% end
return e2pFlags;
% else
switch(irFlags)
{
% enum.flags&.each do |flag|
case <%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name
end %>::<%= name %>::<%= flag %>:
return Es2panda<%= name %>::<%= enum.name_to_upper_snake %>_<%= flag %>;
% end
default:
ES2PANDA_UNREACHABLE();
}
% end
}
%end
% end
// NOLINTEND(readability-function-size, readability-magic-numbers)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define IS(public_name, e2p_name) \
extern "C" bool Is##public_name(es2panda_AstNode *ast) \
{ \
auto *node = reinterpret_cast<ir::AstNode *>(ast); \
return node->Is##e2p_name(); \
}
% Es2pandaLibApi::ast_nodes&.each do |ast_node|
% if ast_node != "AstNode" && ast_node != "TypeNode"
IS(<%= ast_node %>, <%= ast_node %>)
% end
% end
#undef IS
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define IS(public_name, e2p_name) \
extern "C" bool ScopeIs##public_name(es2panda_Scope *scope) \
{ \
auto *e2p_scope = reinterpret_cast<varbinder::Scope *>(scope); \
return e2p_scope->Is##e2p_name(); \
}
% Es2pandaLibApi::scopes&.each do |scope|
% if scope != "Scope"
IS(<%= scope %>, <%= scope %>)
% end
% end
#undef IS
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define IS(public_name, e2p_name) \
extern "C" bool TypeIs##public_name(es2panda_Type *type) \
{ \
auto *e2p_type = reinterpret_cast<checker::Type *>(type); \
return e2p_type->Is##e2p_name(); \
}
% Es2pandaLibApi::ast_types&.each do |type|
% if type != "Type"
IS(<%= type %>, <%= type %>)
% end
% end
#undef IS
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define IS(public_name, e2p_name) \
extern "C" bool VariableIs##public_name(es2panda_Variable *variable) \
{ \
auto *e2p_variable = reinterpret_cast<varbinder::Variable *>(variable); \
return e2p_variable->Is##e2p_name(); \
}
% Es2pandaLibApi::ast_variables&.each do |variable|
% if variable[1] != "Variable"
IS(<%= variable[1] %>, <%= variable[1] %>)
% end
% end
#undef IS
// NOLINTNEXTLINE(readability-function-size)
char const *AstNodeName(es2panda_AstNode *ast)
{
% Es2pandaLibApi::ast_nodes&.each do |ast_node|
% unless ["AstNode", "Expression", "Statement", "TypeNode"].include?(ast_node)
if(Is<%= ast_node %>(ast)) {
return "<%= ast_node %>";
}
% end
% end
if(IsExpression(ast)) {
return "Expression";
}
if(IsStatement(ast)) {
return "Statement";
}
return "Unknown AstNode";
}
// NOLINTBEGIN(performance-for-range-copy, readability-identifier-naming)
% Es2pandaLibApi::classes&.each do |namespaceName, namespaceClasses|
% namespaceClasses&.each do |className, classData|
% classData.class_constructors&.each_with_index do |constructor, index|
/* <%= constructor["raw_decl"] %> */
extern "C" <%= classData.constructor_type().lib_type_to_str()
%>Create<%= className + constructor["overload"]
%>([[maybe_unused]] es2panda_Context *context
<%= constructor["args"]&.map { |arg| if arg.lib_args_to_str.strip() != "" then
", " + "[[maybe_unused]] " + arg.lib_args_to_str end }&.join("") %>)
{
% constructor["args"]&.each do |arg|
<%= arg.lib_cast["expression"] %>
% end
auto *ctx = reinterpret_cast<Context *>(context);
auto *ctxAllocator = ctx->allocator;
% if classData.constructor_type().lib_type_to_str() == "es2panda_AstNode *"
auto *astNode = (<%= classData.constructor_cast["start"]
%><%= constructor["args"]&.map { |arg| arg.lib_cast["var_name"] }&.join(", ") %>)<%=
classData.constructor_cast["end"] %>;
astNode->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP);
return reinterpret_cast<<%= classData.constructor_type().lib_type_to_str()
%>>(astNode);
% elsif
return reinterpret_cast<<%= classData.constructor_type().lib_type_to_str()
%>>(<%= classData.constructor_cast["start"]
%><%= constructor["args"]&.map { |arg| arg.lib_cast["var_name"] }&.join(", ") %>)<%=
classData.constructor_cast["end"] %>;
% end
}
% if classData.updater_allowed()
/* Updater */
extern "C" <%= classData.constructor_type().lib_type_to_str()
%>Update<%= className + constructor["overload"]
%>([[maybe_unused]] es2panda_Context *context, es2panda_AstNode *original
<%= constructor["args"]&.map { |arg| if arg.lib_args_to_str.strip() != "" then
", " + "[[maybe_unused]] " + arg.lib_args_to_str end }&.join("") %>)
{
{
auto *prog = const_cast<parser::Program *>(reinterpret_cast<ir::AstNode *>(original)->Program());
if(prog != nullptr) {
prog->SetProgramModified(true);
}
}
% constructor["args"]&.each do |arg|
<%= arg.lib_cast["expression"] %>
% end
auto *ctx = reinterpret_cast<Context *>(context);
auto *ctxAllocator = ctx->allocator;
auto newE2pNode = <%= classData.constructor_cast["start"]
%><%= constructor["args"]&.map { |arg| arg.lib_cast["var_name"] }&.join(", ") %><%=
classData.constructor_cast["end"] %>;
auto *e2pOriginal = reinterpret_cast<ir::AstNode *>(original);
newE2pNode->SetOriginalNode(e2pOriginal);
newE2pNode->SetParent(e2pOriginal->Parent());
newE2pNode->SetRange(e2pOriginal->Range());
% if classData.constructor_type().lib_type_to_str() == "es2panda_AstNode *"
newE2pNode->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP);
% end
% if className + constructor["overload"] == "MethodDefinition"
for (auto overload : e2pOriginal->AsMethodDefinition()->Overloads()) {
overload->SetBaseOverloadMethod(newE2pNode);
}
newE2pNode->AsMethodDefinition()->SetBaseOverloadMethod(e2pOriginal->AsMethodDefinition()->BaseOverloadMethod());
if (e2pOriginal->AsMethodDefinition()->BaseOverloadMethod() != nullptr) {
auto originalOverloads = e2pOriginal->AsMethodDefinition()->BaseOverloadMethod()->Overloads();
for (auto &overload : originalOverloads) {
if (overload == e2pOriginal) {
overload = newE2pNode;
}
}
e2pOriginal->AsMethodDefinition()->BaseOverloadMethod()->SetOverloads(std::move(originalOverloads));
}
auto oriOverloads = e2pOriginal->AsMethodDefinition()->Overloads();
newE2pNode->AsMethodDefinition()->SetOverloads(std::move(oriOverloads));
% end
% if className == "AssignmentExpression"
if (e2pOriginal->AsAssignmentExpression()->IsIgnoreConstAssign()) {
newE2pNode->SetIgnoreConstAssign();
}
% end
% if className == "AssignmentExpression"
if (e2pOriginal->AsAssignmentExpression()->IsIgnoreConstAssign()) {
newE2pNode->SetIgnoreConstAssign();
}
% end
return reinterpret_cast<<%= classData.constructor_type().lib_type_to_str()
%>>(newE2pNode);
}
%end # updater end
% end # constructors end
% classData.class_methods&.each_with_index do |method_info, index|
/* <%= method_info["raw_decl"] %> */
extern "C" <%= method_info["return_type"].lib_type_to_str %><%= className + method_info["overload_name"]
%>([[maybe_unused]] es2panda_Context *context<%= if classData.call_cast["call_var_str"]
then ", " + classData.call_cast["call_var_str"] end %><%=
method_info["args"]&.map { |arg| if arg.lib_args_to_str.strip() != "" then
", " + "[[maybe_unused]] " + arg.lib_args_to_str end}&.join("") %>/*return_args:*/<%= method_info["return_arg_to_str"] %>)
{
% if method_info['get_modifier'] == 'set' && classData.updater_allowed()
{
auto *prog = const_cast<parser::Program *>(reinterpret_cast<ir::AstNode *>(<%= classData.call_cast['call_var']['name'] %>)->Program());
if (prog != nullptr) {
prog->SetProgramModified(true);
}
}
% end
% method_info["args"]&.each do |arg|
<%= arg.lib_cast["expression"] %>
% end
<%= method_info["return_expr"] %>
}
% end # methods end
% end
% end # classes end
% Es2pandaLibApi::structs&.each do |structName, structData|
% structData.struct_getters&.each_with_index do |method_info, index|
extern "C" <%= method_info["return_type"].lib_type_to_str %><%= structName + method_info["name"]
%>([[maybe_unused]] es2panda_Context *context<%= if structData.call_cast["call_var_str"]
then structData.call_cast["call_var_str"] end %>/*return_args:*/<%= method_info["return_arg_to_str"] %>)
{
% method_info["args"]&.each do |arg|
<%= arg.lib_cast["expression"] %>
% end
<%= method_info["return_expr"] %>
}
% end # getters end
% end # structs end
% Es2pandaLibApi::print_stats
// NOLINTEND(performance-for-range-copy, readability-identifier-naming)
// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-non-const-parameter)