diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp index 01d16758d4595307200813b8c8be3e96f7a5850f..37051e45a95d7c3da7749e7ea945d9713c110397 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp @@ -1036,13 +1036,13 @@ void TSDeclGen::GenImportDeclaration(const ir::ETSImportDeclaration *importDecla auto source = importDeclaration->Source()->Str().Mutf8(); source = RemoveModuleExtensionName(source); const auto specifierFirst = specifiers[0]; - const auto typeStr = importDeclaration->IsTypeKind() ? "type " : ""; + bool isTypeKind = importDeclaration->IsTypeKind(); if (specifierFirst->IsImportNamespaceSpecifier()) { GenNamespaceImport(specifierFirst, source); } else if (specifierFirst->IsImportDefaultSpecifier()) { - GenDefaultImport(specifierFirst, source, typeStr); + GenDefaultImport(specifierFirst, source, isTypeKind); } else if (specifierFirst->IsImportSpecifier()) { - GenNamedImports(importDeclaration, specifiers, source, typeStr); + GenNamedImports(importDeclaration, specifiers, isTypeKind); } } @@ -1058,45 +1058,78 @@ void TSDeclGen::GenNamespaceImport(const ir::AstNode *specifier, const std::stri OutEndlDts(); } -void TSDeclGen::GenDefaultImport(const ir::AstNode *specifier, const std::string &source, const std::string &typeStr) +void TSDeclGen::GenDefaultImport(const ir::AstNode *specifier, const std::string &source, bool isTypeKind) { const auto local = specifier->AsImportDefaultSpecifier()->Local()->Name(); - OutTs("import ", typeStr, local, " from \"", source, "\";"); + if (specifier->AsImportDefaultSpecifier()->Local()->Variable() && + specifier->AsImportDefaultSpecifier()->Local()->Variable()->Declaration() && + specifier->AsImportDefaultSpecifier()->Local()->Variable()->Declaration()->Node() && + specifier->AsImportDefaultSpecifier()->Local()->Variable()->Declaration()->Node()->IsTSInterfaceDeclaration()) { + OutTs("import type ", local, " from \"", source, "\";"); + } else { + OutTs(isTypeKind ? "import type " : "import ", local, " from \"", source, "\";"); + } OutEndlTs(); if (importSet_.find(local.Mutf8()) == importSet_.end()) { return; } - OutDts("import ", typeStr, local, " from \"", source, "\";"); + OutDts(isTypeKind ? "import type " : "import ", local, " from \"", source, "\";"); OutEndlDts(); } void TSDeclGen::GenNamedImports(const ir::ETSImportDeclaration *importDeclaration, - const ArenaVector &specifiers, const std::string &source, - const std::string &typeStr) + const ArenaVector &specifiers, bool isTypeKind) +{ + if (specifiers.empty()) { + return; + } + std::vector interfaceSpecifiers; + std::vector normalSpecifiers; + SeparateInterfaceSpecifiers(specifiers, interfaceSpecifiers, normalSpecifiers); + + GenTsImportStatement(interfaceSpecifiers, importDeclaration, true); + GenTsImportStatement(normalSpecifiers, importDeclaration); + + auto importSpecifiers = FilterValidImportSpecifiers(specifiers); + GenDtsImportStatement(importSpecifiers, importDeclaration, isTypeKind); +} + +void TSDeclGen::GenTsImportStatement(std::vector &specifiers, + const ir::ETSImportDeclaration *importDeclaration, bool isInterface) { if (specifiers.empty()) { return; } - OutTs("import ", typeStr, "{ "); + + auto source = importDeclaration->Source()->Str().Mutf8(); + source = RemoveModuleExtensionName(source); + OutTs(isInterface ? "import type" : "import", " { "); + GenSeparated( specifiers, - [this, &importDeclaration](ir::AstNode *specifier) { - GenSingleNamedImport(specifier, importDeclaration, true); - }, + [this, importDeclaration](ir::AstNode *specifier) { GenSingleNamedImport(specifier, importDeclaration, true); }, ", ", true, false); - OutTs(" } from \"", source, "\";"); - OutEndlTs(); - auto importSpecifiers = FilterValidImportSpecifiers(specifiers); - if (importSpecifiers.empty()) { + + OutTs(" } from \"", source, "\";\n"); +} + +void TSDeclGen::GenDtsImportStatement(std::vector &specifiers, + const ir::ETSImportDeclaration *importDeclaration, bool isTypeKind) +{ + if (specifiers.empty()) { return; } - OutDts("import ", typeStr, "{ "); + + auto source = importDeclaration->Source()->Str().Mutf8(); + source = RemoveModuleExtensionName(source); + OutDts(isTypeKind ? "import type" : "import", " { "); + GenSeparated( - importSpecifiers, - [this, &importDeclaration](ir::AstNode *specifier) { GenSingleNamedImport(specifier, importDeclaration); }, + specifiers, + [this, importDeclaration](ir::AstNode *specifier) { GenSingleNamedImport(specifier, importDeclaration); }, ", "); - OutDts(" } from \"", source, "\";"); - OutEndlDts(); + + OutDts(" } from \"", source, "\";\n"); } void TSDeclGen::GenSingleNamedImport(ir::AstNode *specifier, const ir::ETSImportDeclaration *importDeclaration, @@ -1137,48 +1170,115 @@ void TSDeclGen::GenReExportDeclaration(const ir::ETSReExportDeclaration *reExpor return; } const auto &specifiers = importDeclaration->Specifiers(); - if (specifiers.size() == 1 && specifiers[0]->IsImportNamespaceSpecifier()) { - const auto local = specifiers[0]->AsImportNamespaceSpecifier()->Local()->Name(); + + if (specifiers.size() == 1 && GenNamespaceReExportDeclaration(specifiers[0], importDeclaration)) { + return; + } + + bool isTypeKind = reExportDeclaration->IsExportedType(); + std::vector interfaceSpecifiers; + std::vector normalSpecifiers; + SeparateInterfaceSpecifiers(specifiers, interfaceSpecifiers, normalSpecifiers); + + GenDtsReExportStatement(specifiers, importDeclaration, isTypeKind); + + GenTsReExportStatement(interfaceSpecifiers, importDeclaration, true); + GenTsReExportStatement(normalSpecifiers, importDeclaration); +} + +bool TSDeclGen::GenNamespaceReExportDeclaration(const ir::AstNode *specifier, + const ir::ETSImportDeclaration *importDeclaration) +{ + if (specifier->IsImportNamespaceSpecifier()) { + const auto local = specifier->AsImportNamespaceSpecifier()->Local()->Name(); if (local.Empty()) { - OutDts("export * from \"", importDeclaration->Source()->Str().Mutf8(), "\";"); - OutEndlDts(); - OutTs("export * from \"", importDeclaration->Source()->Str().Mutf8(), "\";"); - OutEndlTs(); - return; + auto source = importDeclaration->Source()->Str().Mutf8(); + source = RemoveModuleExtensionName(source); + OutDts("export * from \"", source, "\";\n"); + OutTs("export * from \"", source, "\";\n"); + return true; + } + } + return false; +} + +void TSDeclGen::SeparateInterfaceSpecifiers(const ArenaVector &specifiers, + std::vector &interfaceSpecifiers, + std::vector &normalSpecifiers) +{ + for (auto *specifier : specifiers) { + if (!specifier->IsImportSpecifier()) { + continue; + } + if (specifier->AsImportSpecifier()->Imported()->Variable() && + specifier->AsImportSpecifier()->Imported()->Variable()->Declaration() && + specifier->AsImportSpecifier()->Imported()->Variable()->Declaration()->Node() && + specifier->AsImportSpecifier()->Imported()->Variable()->Declaration()->Node()->IsTSInterfaceDeclaration()) { + interfaceSpecifiers.push_back(specifier); + } else { + normalSpecifiers.push_back(specifier); } } - OutDts("export { "); - OutTs("export { "); +} + +void TSDeclGen::GenSingleNamedReExport(ir::AstNode *specifier, const ir::ETSImportDeclaration *importDeclaration, + bool isGlueCode) +{ + if (specifier->IsImportSpecifier()) { + const auto local = specifier->AsImportSpecifier()->Local()->Name().Mutf8(); + const auto imported = specifier->AsImportSpecifier()->Imported()->Name().Mutf8(); + importSet_.insert(local); + if (local != imported) { + isGlueCode ? OutTs(imported, " as ", local) : OutDts(imported, " as ", local); + } else { + isGlueCode ? OutTs(local) : OutDts(local); + } + } else if (specifier->IsImportNamespaceSpecifier()) { + const auto local = specifier->AsImportNamespaceSpecifier()->Local()->Name().Mutf8(); + importSet_.insert(local); + isGlueCode ? OutTs(local) : OutDts(local); + } else { + LogError(diagnostic::IMPORT_SPECIFIERS_SUPPORT, {}, importDeclaration->Start()); + } +} + +void TSDeclGen::GenDtsReExportStatement(const ArenaVector &specifiers, + const ir::ETSImportDeclaration *importDeclaration, bool isTypeKind) +{ + if (specifiers.empty()) { + return; + } + + auto source = importDeclaration->Source()->Str().Mutf8(); + source = RemoveModuleExtensionName(source); + OutDts(isTypeKind ? "export type" : "export", " { "); + GenSeparated( specifiers, - [this, &importDeclaration](ir::AstNode *specifier) { - if (specifier->IsImportSpecifier()) { - const auto local = specifier->AsImportSpecifier()->Local()->Name().Mutf8(); - const auto imported = specifier->AsImportSpecifier()->Imported()->Name().Mutf8(); - importSet_.insert(local); - if (local != imported) { - OutDts(imported, " as ", local); - OutTs(imported, " as ", local); - } else { - OutDts(local); - OutTs(local); - } - } else if (specifier->IsImportNamespaceSpecifier()) { - const auto local = specifier->AsImportNamespaceSpecifier()->Local()->Name(); - importSet_.insert(local.Mutf8()); - OutDts(local); - OutTs(local); - } else { - LogError(diagnostic::IMPORT_SPECIFIERS_SUPPORT, {}, importDeclaration->Start()); - } - }, - ", ", true); + [this, importDeclaration](ir::AstNode *specifier) { GenSingleNamedReExport(specifier, importDeclaration); }, + ", "); + + OutDts(" } from \"", source, "\";\n"); +} +void TSDeclGen::GenTsReExportStatement(const std::vector &specifiers, + const ir::ETSImportDeclaration *importDeclaration, bool isInterface) +{ + if (specifiers.empty()) { + return; + } auto source = importDeclaration->Source()->Str().Mutf8(); - OutDts(" } from \"", source, "\";"); - OutEndlDts(); - OutTs(" } from \"", source, "\";"); - OutEndlTs(); + source = RemoveModuleExtensionName(source); + OutTs(isInterface ? "export type" : "export", " { "); + + GenSeparated( + specifiers, + [this, importDeclaration](ir::AstNode *specifier) { + GenSingleNamedReExport(specifier, importDeclaration, true); + }, + ", ", true, false); + + OutTs(" } from \"", source, "\";\n"); } std::string TSDeclGen::ReplaceETSGLOBAL(const std::string &typeName) @@ -1365,10 +1465,12 @@ void TSDeclGen::ProcessETSFunctionType(const ir::ETSFunctionType *etsFunction) bool inUnionBody = !state_.inUnionBodyStack.empty() && state_.inUnionBodyStack.top(); OutDts(inUnionBody ? "((" : "("); GenSeparated(etsFunction->Params(), [this](ir::Expression *param) { - const auto paramName = param->AsETSParameterExpression()->Name(); - OutDts(paramName.Is("=t") ? "this" : paramName, ": "); - ProcessTypeAnnotationType(param->AsETSParameterExpression()->TypeAnnotation(), - param->AsETSParameterExpression()->TypeAnnotation()->TsType()); + const auto paramExpr = param->AsETSParameterExpression(); + const auto paramName = paramExpr->Name(); + const bool isRestParam = paramExpr->IsRestParameter(); + const bool isOptional = paramExpr->IsOptional(); + OutDts(isRestParam ? "..." : "", paramName.Is("=t") ? "this" : paramName, isOptional ? "?: " : ": "); + ProcessTypeAnnotationType(paramExpr->TypeAnnotation(), paramExpr->TypeAnnotation()->TsType()); }); OutDts(") => "); ProcessTypeAnnotationType(etsFunction->ReturnType(), etsFunction->ReturnType()->TsType()); diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.h b/ets2panda/declgen_ets2ts/declgenEts2Ts.h index fc580114dbb24890da1bee7db07cecb8fdc4768f..ccd20774e55ee7389999a8b4c17fbdc2f216ae5b 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.h +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.h @@ -119,13 +119,27 @@ private: void GenImportDeclaration(const ir::ETSImportDeclaration *importDeclaration); void GenNamespaceImport(const ir::AstNode *specifier, const std::string &source); - void GenDefaultImport(const ir::AstNode *specifier, const std::string &source, const std::string &typeStr); + void GenDefaultImport(const ir::AstNode *specifier, const std::string &source, bool isTypeKind = false); void GenNamedImports(const ir::ETSImportDeclaration *importDeclaration, - const ArenaVector &specifiers, const std::string &source, - const std::string &typeStr); + const ArenaVector &specifiers, bool isTypeKind = false); + void GenDtsImportStatement(std::vector &specifiers, + const ir::ETSImportDeclaration *importDeclaration, bool isTypeKind = false); + void GenTsImportStatement(std::vector &specifiers, const ir::ETSImportDeclaration *importDeclaration, + bool isInterface = false); void GenSingleNamedImport(ir::AstNode *specifier, const ir::ETSImportDeclaration *importDeclaration, bool isGlueCode = false); void GenReExportDeclaration(const ir::ETSReExportDeclaration *reExportDeclaration); + bool GenNamespaceReExportDeclaration(const ir::AstNode *specifier, + const ir::ETSImportDeclaration *importDeclaration); + void SeparateInterfaceSpecifiers(const ArenaVector &specifiers, + std::vector &interfaceSpecifiers, + std::vector &normalSpecifiers); + void GenDtsReExportStatement(const ArenaVector &specifiers, + const ir::ETSImportDeclaration *importDeclaration, bool isTypeKind = false); + void GenTsReExportStatement(const std::vector &specifiers, + const ir::ETSImportDeclaration *importDeclaration, bool isInterface = false); + void GenSingleNamedReExport(ir::AstNode *specifier, const ir::ETSImportDeclaration *importDeclaration, + bool isGlueCode = false); void GenTypeAliasDeclaration(const ir::TSTypeAliasDeclaration *typeAlias); void GenEnumDeclaration(const ir::ClassProperty *enumMember); void GenInterfaceDeclaration(const ir::TSInterfaceDeclaration *interfaceDecl); diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index fcfad7919bcd7293ae17b44326864965e5da8672..ed1e1bc05031382b9f3e754acc749f8316123a19 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -1343,6 +1343,7 @@ std::pair ETSParser::ParseMemberModifi Lexer()->Rewind(savedPos); } memberModifiers |= ir::ModifierFlags::EXPORT; + memberModifiers |= ir::ModifierFlags::EXPORT_TYPE; } else { memberModifiers |= ir::ModifierFlags::EXPORT; }