* Copyright (c) 2021-2026 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.
*/
#ifndef ES2PANDA_COMPILER_CORE_ETS_EMITTER_H
#define ES2PANDA_COMPILER_CORE_ETS_EMITTER_H
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "annotation.h"
#include "assembly-literals.h"
#include "emitter.h"
namespace ark::es2panda::parser {
class Program;
}
namespace ark::es2panda::varbinder {
class RecordTable;
}
namespace ark::es2panda::ir {
class ClassDefinition;
}
namespace ark::es2panda::checker {
class ETSObjectType;
class ETSArrayType;
class Signature;
}
namespace ark::pandasm {
struct Field;
struct Record;
class ItemMetadata;
class AnnotationData;
}
namespace ark::es2panda::compiler {
using LiteralArrayPair = std::pair<std::string, std::vector<pandasm::LiteralArray::Literal>>;
using LiteralArrayVector = std::vector<LiteralArrayPair>;
class ETSFunctionEmitter : public FunctionEmitter {
public:
ETSFunctionEmitter(const CodeGen *cg, ProgramElement *programElement) : FunctionEmitter(cg, programElement) {}
~ETSFunctionEmitter() override = default;
NO_COPY_SEMANTIC(ETSFunctionEmitter);
NO_MOVE_SEMANTIC(ETSFunctionEmitter);
static bool IsEmissionRequired(ir::ScriptFunction *func, parser::Program *globalProgram);
protected:
pandasm::Function *GenFunctionSignature() override;
void GenFunctionAnnotations(pandasm::Function *func) override;
void GenVariableSignature(pandasm::debuginfo::LocalVariable &variableDebug,
varbinder::LocalVariable *variable) const override;
void GenSourceFileDebugInfo(pandasm::Function *func) override;
};
namespace detail {
class EmitterDependencies;
}
class ETSEmitter : public Emitter {
public:
explicit ETSEmitter(const public_lib::Context *context);
~ETSEmitter() override;
NO_COPY_SEMANTIC(ETSEmitter);
NO_MOVE_SEMANTIC(ETSEmitter);
void EmitRecords() override;
std::unordered_map<std::string, std::unique_ptr<ark::pandasm::Program>> EmitRecordsSimultIncMode();
void AddProgramElement(ProgramElement *programElement) override;
bool IsETSEmitter() override
{
return true;
}
static std::string NormalizePathSeparators(std::string_view path);
static std::string GetNormalizedSourceFilePath(const public_lib::Context *context);
static std::string GetNormalizedSourceFilePath(const CodeGen *cg);
std::vector<pandasm::AnnotationData> GenCustomAnnotations(
const ArenaVector<ir::AnnotationUsage *> &annotationUsages, const std::string &baseName);
pandasm::AnnotationData GenAnnotationAsync(ir::ScriptFunction *scriptFunc);
std::string const &AddDependence(std::string const &str);
void SetupDependenciesForTheProgram(const parser::Program *prg);
void GenSyntheticRuntimeTypeRecord(util::StringView assemblerType);
private:
pandasm::Program *GetOrCreatePandasmProgram(const parser::Program *prg);
detail::EmitterDependencies *GetOrCreateDependenciesForTheProgram(const parser::Program *prg);
void EmitRecordsImpl(bool isIncrementalBuild = false);
void EmitRecordTable(varbinder::RecordTable *table, bool programIsExternal, bool traverseExternals);
void GenGlobalArrayRecord(const checker::ETSArrayType *arrayType);
std::vector<pandasm::AnnotationData> GenAnnotations(const ir::ClassDefinition *classDef);
void GenClassRecord(const ir::ClassDefinition *classDef, bool external);
pandasm::AnnotationElement ProcessArrayType(const ir::ClassProperty *prop, std::string &baseName,
const ir::Expression *init);
pandasm::AnnotationElement GenCustomAnnotationElement(const ir::ClassProperty *prop, std::string &baseName);
pandasm::AnnotationData GenCustomAnnotation(ir::AnnotationUsage *anno, std::string &baseName);
void ProcessArrayElement(const ir::Expression *elem, std::vector<pandasm::LiteralArray::Literal> &literals,
std::string &baseName, LiteralArrayVector &result);
LiteralArrayVector CreateLiteralArray(std::string &baseName, const ir::Expression *array);
void CreateLiteralArrayProp(const ir::ClassProperty *prop, std::string &baseName, pandasm::Field &field);
void GenCustomAnnotationProp(const ir::ClassProperty *prop, std::string &baseName, pandasm::Record &record,
bool external);
void GenCustomAnnotationRecord(const ir::AnnotationDeclaration *annoDecl, std::string &baseName, bool external);
void GenEnumRecord(const ir::TSEnumDeclaration *enumDecl, bool external);
void GenInterfaceRecord(const ir::TSInterfaceDeclaration *interfaceDecl, bool external);
void EmitDefaultFieldValue(pandasm::Field &classField, const ir::Expression *init);
void GenClassField(const ir::ClassProperty *prop, pandasm::Record &classRecord, bool external);
void GenMethodDefinition(ir::MethodDefinition const *method, bool external);
void GenFunction(ir::ScriptFunction const *scriptFunc, bool external);
void GenClassInheritedFields(const checker::ETSObjectType *baseType, pandasm::Record &classRecord);
pandasm::AnnotationData GenAnnotationModule(const ir::ClassDefinition *classDef);
pandasm::AnnotationData GenAnnotationFunctionalReference(const ir::ClassDefinition *classDef);
ir::MethodDefinition *FindAsyncImpl(ir::ScriptFunction *asyncFunc);
void ProcessArrayExpression(std::string &baseName, LiteralArrayVector &result,
std::vector<pandasm::LiteralArray::Literal> &literals, const ir::Expression *elem);
thread_local static detail::EmitterDependencies *dependencies_;
std::unordered_map<std::string_view, pandasm::Program *> prgMaps_;
std::unordered_map<std::string_view, detail::EmitterDependencies *> depMaps_;
};
}
#endif