diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 9ed89b1c81af72a456d66b9069bef2c019f8e6d9..e18874df54edca2a85a540775a8fad35147825df 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -442,7 +442,7 @@ public: util::StringView GetContainingObjectNameFromSignature(Signature *signature); bool IsFunctionContainsSignature(ETSFunctionType *func_type, Signature *signature); void CheckFunctionContainsClashingSignature(const ETSFunctionType *func_type, Signature *signature); - bool IsTypeBuiltinType(Type *type); + bool IsTypeBuiltinType(const Type *type) const; bool IsReferenceType(const Type *type); const ir::AstNode *FindJumpTarget(ir::AstNodeType node_type, const ir::AstNode *node, const ir::Identifier *target); void ValidatePropertyAccess(varbinder::Variable *var, ETSObjectType *obj, const lexer::SourcePosition &pos); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 04df469225ede284785a409f48ccc2d3b3ee36f4..6ac324ecb739365060e2644a7cf7c46d9f8b34bc 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1432,7 +1432,7 @@ util::StringView ETSChecker::GetContainingObjectNameFromSignature(Signature *sig return {""}; } -bool ETSChecker::IsTypeBuiltinType(Type *type) +bool ETSChecker::IsTypeBuiltinType(const Type *type) const { if (!type->IsETSObjectType()) { return false; diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 391f54588ce9e0207ca381430e9c5e70461a690b..eba9f33f0258be02e945eb5d1db46440149a8e53 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -397,7 +397,7 @@ public: return invoke->TsType()->AsETSFunctionType(); } - ETSObjectFlags BuiltInKind() + ETSObjectFlags BuiltInKind() const { return static_cast(flags_ & ETSObjectFlags::BUILTIN_TYPE); } diff --git a/ets2panda/util/declgenEts2Ts.cpp b/ets2panda/util/declgenEts2Ts.cpp index 0d88da3963a678344dafa8beee2e60a5ee35c11e..589d1a8ea408015ac7e0ff8acde258d7c3ff120d 100644 --- a/ets2panda/util/declgenEts2Ts.cpp +++ b/ets2panda/util/declgenEts2Ts.cpp @@ -103,7 +103,7 @@ void TSDeclGen::ThrowError(const std::string_view message, const lexer::SourcePo lexer::LineIndex index(program_->SourceCode()); const lexer::SourceLocation loc = index.GetLocation(pos); - throw Error {ErrorType::GENERIC, program_->SourceFilePath().Utf8(), "declgen ts2ets: " + std::string(message), + throw Error {ErrorType::GENERIC, program_->SourceFilePath().Utf8(), "declgen ets2ts: " + std::string(message), loc.line, loc.col}; } @@ -149,46 +149,35 @@ void TSDeclGen::GenTypeNonNullish(const checker::Type *checker_type) checker_type->IsShortType() || checker_type->IsNumberType() || checker_type->IsLongType() || checker_type->IsFloatType() || checker_type->IsDoubleType()) { Out("number"); - return; - } - if (checker_type->IsETSBooleanType()) { + } else if (checker_type->IsETSBooleanType()) { Out("boolean"); - return; - } - if (checker_type->IsETSVoidType()) { + } else if (checker_type->IsETSVoidType()) { Out("void"); - return; - } - if (checker_type->IsETSStringType()) { + } else if (checker_type->IsETSStringType()) { Out("string"); - return; - } - if (checker_type->IsETSArrayType()) { + } else if (checker_type->IsETSArrayType()) { GenType(checker_type->AsETSArrayType()->ElementType()); Out("[]"); - return; - } - if (checker_type->IsETSEnumType()) { + } else if (checker_type->IsETSEnumType()) { GenEnumType(checker_type->AsETSEnumType()); - return; - } - if (checker_type->IsETSFunctionType()) { + } else if (checker_type->IsETSFunctionType()) { GenFunctionType(checker_type->AsETSFunctionType()); - return; - } - if (checker_type->IsETSObjectType()) { + } else if (checker_type->IsETSObjectType()) { + if (checker_->IsTypeBuiltinType(checker_type)) { + Out("number"); + return; + } GenObjectType(checker_type->AsETSObjectType()); - return; - } - + } else { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define TYPE_CHECKS(typeFlag, typeName) \ if (checker_type->Is##typeName()) { \ ThrowError("Unsupported type: '" #typeName); \ } - TYPE_MAPPING(TYPE_CHECKS) + TYPE_MAPPING(TYPE_CHECKS) #undef TYPE_CHECKS - UNREACHABLE(); + UNREACHABLE(); + } } void TSDeclGen::GenLiteral(const ir::Literal *literal) @@ -249,16 +238,29 @@ void TSDeclGen::GenFunctionType(const checker::ETSFunctionType *ets_function_typ const auto *sig_info = sig->GetSignatureInfo(); if (sig_info->rest_var != nullptr) { + if (!sig->Params().empty()) { + Out(", "); + } Out("...", sig_info->rest_var->Name().Mutf8(), ": "); GenType(sig_info->rest_var->TsType()); - Out("[]"); } Out(")"); - if (!is_constructor) { + if (is_constructor) { + if (state_.super != nullptr) { + Out("{ super(...{} as (ConstructorParametersTsType()); + Out(">)); }"); + } else { + Out(" {}"); + } + } else { Out(method_def != nullptr ? ": " : " => "); GenType(sig->ReturnType()); + if (method_def != nullptr && !state_.in_interface) { + Out(" { return {} as any; }"); + } } } } @@ -303,11 +305,16 @@ void TSDeclGen::GenObjectType(const checker::ETSObjectType *object_type) return; } - Out(object_type->Name()); + auto type_name = object_type->Name(); + if (type_name.Empty()) { + Warning("Object type name is empty"); + Out("any"); + } else { + Out(type_name); + } const auto &type_args = object_type->TypeArguments(); if (!type_args.empty()) { - Warning("Type arguments are not properly supported"); Out("<"); GenCommaSeparated(type_args, [this](checker::Type *arg) { GenType(arg); }); Out(">"); @@ -453,11 +460,12 @@ void TSDeclGen::GenClassDeclaration(const ir::ClassDeclaration *class_decl) } if (!state_.in_global_class) { - Out("export declare class ", class_name); + Out("class ", class_name); GenTypeParameters(class_def->TypeParams()); const auto *super = class_def->Super(); + state_.super = super; if (super != nullptr) { Out(" extends "); GenType(super->TsType()); @@ -485,7 +493,11 @@ void TSDeclGen::GenClassDeclaration(const ir::ClassDeclaration *class_decl) if (!state_.in_global_class) { Out("};"); OutEndl(); - Out("exports.", class_name, " = (globalThis as any).Panda.getClass('", state_.current_class_descriptor, "');"); + Out("(", class_name, " as any) = (globalThis as any).Panda.getClass('", state_.current_class_descriptor, "');"); + OutEndl(); + Out("export {", class_name, "};"); + OutEndl(); + Out("exports.", class_name, " = ", class_name, ";"); OutEndl(2); } } @@ -502,7 +514,7 @@ void TSDeclGen::GenMethodDeclaration(const ir::MethodDefinition *method_def) } if (state_.in_global_class) { - Out("export declare function "); + Out("function "); } else { Out(INDENT); GenModifier(method_def); @@ -523,11 +535,15 @@ void TSDeclGen::GenMethodDeclaration(const ir::MethodDefinition *method_def) OutEndl(); if (state_.in_global_class) { - Out("exports.", method_name, " = (globalThis as any).Panda.getFunction('", state_.current_class_descriptor, + Out("(", method_name, " as any) = (globalThis as any).Panda.getFunction('", state_.current_class_descriptor, "', '", method_name, "');"); + OutEndl(); + Out("export {", method_name, "};"); + OutEndl(); + Out("exports.", method_name, " = ", method_name, ";"); + OutEndl(); if (method_name == compiler::Signatures::INIT_METHOD) { - OutEndl(); - Out("exports.", method_name, "();"); + Out(method_name, "();"); } OutEndl(2); } @@ -548,6 +564,9 @@ void TSDeclGen::GenPropDeclaration(const ir::ClassProperty *class_prop) Out(": "); GenType(class_prop->TsType()); + if (!state_.in_interface) { + Out(" = {} as any"); + } Out(";"); OutEndl(); } diff --git a/ets2panda/util/declgenEts2Ts.h b/ets2panda/util/declgenEts2Ts.h index 0bed55d8273823841fd5b71aaf9f885753dc3fc2..48d16635e1df59481e16cf88afbe0ba59c69f624 100644 --- a/ets2panda/util/declgenEts2Ts.h +++ b/ets2panda/util/declgenEts2Ts.h @@ -87,6 +87,7 @@ private: } struct GenState { + const ir::Expression *super {nullptr}; bool in_interface {false}; bool in_global_class {false}; std::string current_class_descriptor {};