From 63a05d7983724e59b5cbd65fa0891521d94082ba Mon Sep 17 00:00:00 2001 From: Vivien Voros Date: Wed, 25 Oct 2023 16:12:28 +0200 Subject: [PATCH] Compile logic is moved to JSCompiler and ETSCompiler classes. Check logic with their helper functions is moved to TSAnalyzer and ETSAnalyzer classes. TSLiteralType, TSParenthesizedType, TSTypeLiteral, TSUnionType, TSArrayType, TSNonNullExpression, TSNeverKeyword, TSBigintKeyword. Linked Internal issue: 13840 Change-Id: I111c8cafa568e3d8cb85aa3b05c2801b5dca7296 Signed-off-by: Vivien Voros --- ets2panda/checker/ETSAnalyzer.cpp | 44 ++++++++++------------ ets2panda/checker/TSAnalyzer.cpp | 50 +++++++++++++++---------- ets2panda/compiler/core/ETSCompiler.cpp | 50 ++++++++++++++++--------- ets2panda/compiler/core/JSCompiler.cpp | 24 ++++-------- ets2panda/ir/ts/tsArrayType.cpp | 18 ++++++--- ets2panda/ir/ts/tsArrayType.h | 10 +++++ ets2panda/ir/ts/tsBigintKeyword.cpp | 16 ++++++-- ets2panda/ir/ts/tsBigintKeyword.h | 1 + ets2panda/ir/ts/tsLiteralType.cpp | 17 +++++++-- ets2panda/ir/ts/tsLiteralType.h | 1 + ets2panda/ir/ts/tsNeverKeyword.cpp | 16 ++++++-- ets2panda/ir/ts/tsNeverKeyword.h | 1 + ets2panda/ir/ts/tsNonNullExpression.cpp | 45 +++++----------------- ets2panda/ir/ts/tsNonNullExpression.h | 6 +++ ets2panda/ir/ts/tsParenthesizedType.cpp | 17 +++++++-- ets2panda/ir/ts/tsParenthesizedType.h | 8 +++- ets2panda/ir/ts/tsTypeLiteral.cpp | 23 +++++++----- ets2panda/ir/ts/tsTypeLiteral.h | 1 + ets2panda/ir/ts/tsUnionType.cpp | 21 +++++++---- ets2panda/ir/ts/tsUnionType.h | 1 + 20 files changed, 219 insertions(+), 151 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index ec729cf229..73f62a4190 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -20,16 +20,7 @@ #include "checker/ETSchecker.h" #include "checker/ets/castingContext.h" #include "checker/ets/typeRelationContext.h" -#include "ir/base/catchClause.h" -#include "ir/base/classProperty.h" -#include "ir/base/classStaticBlock.h" -#include "ir/expressions/identifier.h" -#include "ir/expressions/objectExpression.h" -#include "ir/expressions/arrayExpression.h" -#include "ir/statements/blockStatement.h" -#include "ir/statements/returnStatement.h" #include "util/helpers.h" - namespace panda::es2panda::checker { ETSChecker *ETSAnalyzer::GetETSChecker() const @@ -957,8 +948,9 @@ checker::Type *ETSAnalyzer::Check(ir::TSAnyKeyword *node) const checker::Type *ETSAnalyzer::Check(ir::TSArrayType *node) const { - (void)node; - UNREACHABLE(); + ETSChecker *checker = GetETSChecker(); + node->element_type_->Check(checker); + return nullptr; } checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const @@ -967,9 +959,8 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const UNREACHABLE(); } -checker::Type *ETSAnalyzer::Check(ir::TSBigintKeyword *node) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TSBigintKeyword *node) const { - (void)node; UNREACHABLE(); } @@ -1069,9 +1060,8 @@ checker::Type *ETSAnalyzer::Check(ir::TSIntersectionType *node) const UNREACHABLE(); } -checker::Type *ETSAnalyzer::Check(ir::TSLiteralType *node) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TSLiteralType *node) const { - (void)node; UNREACHABLE(); } @@ -1099,16 +1089,23 @@ checker::Type *ETSAnalyzer::Check(ir::TSNamedTupleMember *node) const UNREACHABLE(); } -checker::Type *ETSAnalyzer::Check(ir::TSNeverKeyword *node) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TSNeverKeyword *node) const { - (void)node; UNREACHABLE(); } checker::Type *ETSAnalyzer::Check(ir::TSNonNullExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSChecker *checker = GetETSChecker(); + auto expr_type = expr->expr_->Check(checker); + + if (!expr_type->IsNullish()) { + checker->ThrowTypeError("Bad operand type, the operand of the non-null expression must be a nullable type", + expr->Expr()->Start()); + } + + expr->SetTsType(expr_type->IsNullish() ? checker->GetNonNullishType(expr_type) : expr_type); + return expr->TsType(); } checker::Type *ETSAnalyzer::Check(ir::TSNullKeyword *node) const @@ -1135,9 +1132,8 @@ checker::Type *ETSAnalyzer::Check(ir::TSParameterProperty *expr) const UNREACHABLE(); } -checker::Type *ETSAnalyzer::Check(ir::TSParenthesizedType *node) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TSParenthesizedType *node) const { - (void)node; UNREACHABLE(); } @@ -1177,9 +1173,8 @@ checker::Type *ETSAnalyzer::Check(ir::TSTypeAssertion *expr) const UNREACHABLE(); } -checker::Type *ETSAnalyzer::Check(ir::TSTypeLiteral *node) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TSTypeLiteral *node) const { - (void)node; UNREACHABLE(); } @@ -1231,9 +1226,8 @@ checker::Type *ETSAnalyzer::Check(ir::TSUndefinedKeyword *node) const UNREACHABLE(); } -checker::Type *ETSAnalyzer::Check(ir::TSUnionType *node) const +checker::Type *ETSAnalyzer::Check([[maybe_unused]] ir::TSUnionType *node) const { - (void)node; UNREACHABLE(); } diff --git a/ets2panda/checker/TSAnalyzer.cpp b/ets2panda/checker/TSAnalyzer.cpp index d3e96e821f..6190e3b84d 100644 --- a/ets2panda/checker/TSAnalyzer.cpp +++ b/ets2panda/checker/TSAnalyzer.cpp @@ -18,7 +18,6 @@ #include "checker/TSchecker.h" #include "checker/ts/destructuringContext.h" #include "util/helpers.h" - namespace panda::es2panda::checker { TSChecker *TSAnalyzer::GetTSChecker() const @@ -673,8 +672,9 @@ checker::Type *TSAnalyzer::Check(ir::TSAnyKeyword *node) const checker::Type *TSAnalyzer::Check(ir::TSArrayType *node) const { - (void)node; - UNREACHABLE(); + TSChecker *checker = GetTSChecker(); + node->element_type_->Check(checker); + return nullptr; } checker::Type *TSAnalyzer::Check(ir::TSAsExpression *expr) const @@ -683,10 +683,9 @@ checker::Type *TSAnalyzer::Check(ir::TSAsExpression *expr) const UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::TSBigintKeyword *node) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSBigintKeyword *node) const { - (void)node; - UNREACHABLE(); + return nullptr; } checker::Type *TSAnalyzer::Check(ir::TSBooleanKeyword *node) const @@ -787,8 +786,9 @@ checker::Type *TSAnalyzer::Check(ir::TSIntersectionType *node) const checker::Type *TSAnalyzer::Check(ir::TSLiteralType *node) const { - (void)node; - UNREACHABLE(); + TSChecker *checker = GetTSChecker(); + node->GetType(checker); + return nullptr; } checker::Type *TSAnalyzer::Check(ir::TSMappedType *node) const @@ -815,15 +815,13 @@ checker::Type *TSAnalyzer::Check(ir::TSNamedTupleMember *node) const UNREACHABLE(); } -checker::Type *TSAnalyzer::Check(ir::TSNeverKeyword *node) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSNeverKeyword *node) const { - (void)node; - UNREACHABLE(); + return nullptr; } -checker::Type *TSAnalyzer::Check(ir::TSNonNullExpression *expr) const +checker::Type *TSAnalyzer::Check([[maybe_unused]] ir::TSNonNullExpression *expr) const { - (void)expr; UNREACHABLE(); } @@ -853,8 +851,9 @@ checker::Type *TSAnalyzer::Check(ir::TSParameterProperty *expr) const checker::Type *TSAnalyzer::Check(ir::TSParenthesizedType *node) const { - (void)node; - UNREACHABLE(); + TSChecker *checker = GetTSChecker(); + node->type_->Check(checker); + return nullptr; } checker::Type *TSAnalyzer::Check(ir::TSQualifiedName *expr) const @@ -895,8 +894,16 @@ checker::Type *TSAnalyzer::Check(ir::TSTypeAssertion *expr) const checker::Type *TSAnalyzer::Check(ir::TSTypeLiteral *node) const { - (void)node; - UNREACHABLE(); + TSChecker *checker = GetTSChecker(); + + for (auto *it : node->Members()) { + it->Check(checker); + } + + checker::Type *type = node->GetType(checker); + checker->CheckIndexConstraints(type); + + return nullptr; } checker::Type *TSAnalyzer::Check(ir::TSTypeOperator *node) const @@ -949,8 +956,13 @@ checker::Type *TSAnalyzer::Check(ir::TSUndefinedKeyword *node) const checker::Type *TSAnalyzer::Check(ir::TSUnionType *node) const { - (void)node; - UNREACHABLE(); + TSChecker *checker = GetTSChecker(); + for (auto *it : node->Types()) { + it->Check(checker); + } + + node->GetType(checker); + return nullptr; } checker::Type *TSAnalyzer::Check(ir::TSUnknownKeyword *node) const diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 46dd096ae8..fb340ac0ad 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -20,7 +20,6 @@ #include "compiler/base/lreference.h" #include "compiler/core/ETSGen.h" #include "compiler/function/functionBuilder.h" - namespace panda::es2panda::compiler { ETSGen *ETSCompiler::GetETSGen() const @@ -684,9 +683,8 @@ void ETSCompiler::Compile(const ir::TSAnyKeyword *node) const UNREACHABLE(); } -void ETSCompiler::Compile(const ir::TSArrayType *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSArrayType *node) const { - (void)node; UNREACHABLE(); } @@ -696,9 +694,8 @@ void ETSCompiler::Compile(const ir::TSAsExpression *expr) const UNREACHABLE(); } -void ETSCompiler::Compile(const ir::TSBigintKeyword *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSBigintKeyword *node) const { - (void)node; UNREACHABLE(); } @@ -798,9 +795,8 @@ void ETSCompiler::Compile(const ir::TSIntersectionType *node) const UNREACHABLE(); } -void ETSCompiler::Compile(const ir::TSLiteralType *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSLiteralType *node) const { - (void)node; UNREACHABLE(); } @@ -828,16 +824,39 @@ void ETSCompiler::Compile(const ir::TSNamedTupleMember *node) const UNREACHABLE(); } -void ETSCompiler::Compile(const ir::TSNeverKeyword *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSNeverKeyword *node) const { - (void)node; UNREACHABLE(); } void ETSCompiler::Compile(const ir::TSNonNullExpression *expr) const { - (void)expr; - UNREACHABLE(); + ETSGen *etsg = GetETSGen(); + compiler::RegScope rs(etsg); + + expr->Expr()->Compile(etsg); + + if (!etsg->GetAccumulatorType()->IsNullishOrNullLike()) { + return; + } + + if (etsg->GetAccumulatorType()->IsETSNullLike()) { + etsg->EmitNullishException(expr); + return; + } + + auto arg = etsg->AllocReg(); + etsg->StoreAccumulator(expr, arg); + etsg->LoadAccumulator(expr, arg); + + auto end_label = etsg->AllocLabel(); + + etsg->BranchIfNotNullish(expr, end_label); + etsg->EmitNullishException(expr); + + etsg->SetLabel(expr, end_label); + etsg->LoadAccumulator(expr, arg); + etsg->ConvertToNonNullish(expr); } void ETSCompiler::Compile(const ir::TSNullKeyword *node) const @@ -864,9 +883,8 @@ void ETSCompiler::Compile(const ir::TSParameterProperty *expr) const UNREACHABLE(); } -void ETSCompiler::Compile(const ir::TSParenthesizedType *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSParenthesizedType *node) const { - (void)node; UNREACHABLE(); } @@ -906,9 +924,8 @@ void ETSCompiler::Compile(const ir::TSTypeAssertion *expr) const UNREACHABLE(); } -void ETSCompiler::Compile(const ir::TSTypeLiteral *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSTypeLiteral *node) const { - (void)node; UNREACHABLE(); } @@ -960,9 +977,8 @@ void ETSCompiler::Compile(const ir::TSUndefinedKeyword *node) const UNREACHABLE(); } -void ETSCompiler::Compile(const ir::TSUnionType *node) const +void ETSCompiler::Compile([[maybe_unused]] const ir::TSUnionType *node) const { - (void)node; UNREACHABLE(); } diff --git a/ets2panda/compiler/core/JSCompiler.cpp b/ets2panda/compiler/core/JSCompiler.cpp index 10a894d364..e82028046e 100644 --- a/ets2panda/compiler/core/JSCompiler.cpp +++ b/ets2panda/compiler/core/JSCompiler.cpp @@ -969,9 +969,8 @@ void JSCompiler::Compile(const ir::TSAnyKeyword *node) const UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSArrayType *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSArrayType *node) const { - (void)node; UNREACHABLE(); } @@ -981,9 +980,8 @@ void JSCompiler::Compile(const ir::TSAsExpression *expr) const UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSBigintKeyword *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSBigintKeyword *node) const { - (void)node; UNREACHABLE(); } @@ -1083,9 +1081,8 @@ void JSCompiler::Compile(const ir::TSIntersectionType *node) const UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSLiteralType *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSLiteralType *node) const { - (void)node; UNREACHABLE(); } @@ -1113,15 +1110,13 @@ void JSCompiler::Compile(const ir::TSNamedTupleMember *node) const UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSNeverKeyword *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSNeverKeyword *node) const { - (void)node; UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSNonNullExpression *expr) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSNonNullExpression *expr) const { - (void)expr; UNREACHABLE(); } @@ -1149,9 +1144,8 @@ void JSCompiler::Compile(const ir::TSParameterProperty *expr) const UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSParenthesizedType *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSParenthesizedType *node) const { - (void)node; UNREACHABLE(); } @@ -1191,9 +1185,8 @@ void JSCompiler::Compile(const ir::TSTypeAssertion *expr) const UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSTypeLiteral *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSTypeLiteral *node) const { - (void)node; UNREACHABLE(); } @@ -1245,9 +1238,8 @@ void JSCompiler::Compile(const ir::TSUndefinedKeyword *node) const UNREACHABLE(); } -void JSCompiler::Compile(const ir::TSUnionType *node) const +void JSCompiler::Compile([[maybe_unused]] const ir::TSUnionType *node) const { - (void)node; UNREACHABLE(); } diff --git a/ets2panda/ir/ts/tsArrayType.cpp b/ets2panda/ir/ts/tsArrayType.cpp index 725b911850..7233ca4ab5 100644 --- a/ets2panda/ir/ts/tsArrayType.cpp +++ b/ets2panda/ir/ts/tsArrayType.cpp @@ -15,6 +15,8 @@ #include "tsArrayType.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "checker/TSchecker.h" #include "checker/ETSchecker.h" @@ -35,12 +37,19 @@ void TSArrayType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSArrayType"}, {"elementType", element_type_}}); } -void TSArrayType::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void TSArrayType::Compile([[maybe_unused]] compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} + +void TSArrayType::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} checker::Type *TSArrayType::Check([[maybe_unused]] checker::TSChecker *checker) { - element_type_->Check(checker); - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *TSArrayType::GetType([[maybe_unused]] checker::TSChecker *checker) @@ -50,8 +59,7 @@ checker::Type *TSArrayType::GetType([[maybe_unused]] checker::TSChecker *checker checker::Type *TSArrayType::Check(checker::ETSChecker *checker) { - element_type_->Check(checker); - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *TSArrayType::GetType(checker::ETSChecker *checker) diff --git a/ets2panda/ir/ts/tsArrayType.h b/ets2panda/ir/ts/tsArrayType.h index add9c0e33b..63c0795822 100644 --- a/ets2panda/ir/ts/tsArrayType.h +++ b/ets2panda/ir/ts/tsArrayType.h @@ -18,6 +18,11 @@ #include "ir/typeNode.h" +namespace panda::es2panda::checker { +class ETSAnalyzer; +class TSAnalyzer; +} // namespace panda::es2panda::checker + namespace panda::es2panda::ir { class TSArrayType : public TypeNode { public: @@ -28,10 +33,15 @@ public: return element_type_; } + // TODO (vivienvoros): these friend relationships can be removed once there are getters for private fields + friend class checker::TSAnalyzer; + friend class checker::ETSAnalyzer; + void TransformChildren(const NodeTransformer &cb) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsBigintKeyword.cpp b/ets2panda/ir/ts/tsBigintKeyword.cpp index 0d50b96a5a..baa374d669 100644 --- a/ets2panda/ir/ts/tsBigintKeyword.cpp +++ b/ets2panda/ir/ts/tsBigintKeyword.cpp @@ -15,6 +15,9 @@ #include "tsBigintKeyword.h" +#include "checker/ETSchecker.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "checker/TSchecker.h" @@ -27,11 +30,18 @@ void TSBigintKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSBigIntKeyword"}}); } -void TSBigintKeyword::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void TSBigintKeyword::Compile([[maybe_unused]] compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} +void TSBigintKeyword::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} checker::Type *TSBigintKeyword::Check([[maybe_unused]] checker::TSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *TSBigintKeyword::GetType([[maybe_unused]] checker::TSChecker *checker) @@ -41,6 +51,6 @@ checker::Type *TSBigintKeyword::GetType([[maybe_unused]] checker::TSChecker *che checker::Type *TSBigintKeyword::Check([[maybe_unused]] checker::ETSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsBigintKeyword.h b/ets2panda/ir/ts/tsBigintKeyword.h index 61fe591e04..9405c449a3 100644 --- a/ets2panda/ir/ts/tsBigintKeyword.h +++ b/ets2panda/ir/ts/tsBigintKeyword.h @@ -27,6 +27,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsLiteralType.cpp b/ets2panda/ir/ts/tsLiteralType.cpp index 08db35d343..44d05c36f5 100644 --- a/ets2panda/ir/ts/tsLiteralType.cpp +++ b/ets2panda/ir/ts/tsLiteralType.cpp @@ -15,6 +15,8 @@ #include "tsLiteralType.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "checker/TSchecker.h" @@ -34,12 +36,19 @@ void TSLiteralType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSLiteralType"}, {"literal", literal_}}); } -void TSLiteralType::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void TSLiteralType::Compile([[maybe_unused]] compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} + +void TSLiteralType::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} checker::Type *TSLiteralType::Check([[maybe_unused]] checker::TSChecker *checker) { - GetType(checker); - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *TSLiteralType::GetType([[maybe_unused]] checker::TSChecker *checker) @@ -54,6 +63,6 @@ checker::Type *TSLiteralType::GetType([[maybe_unused]] checker::TSChecker *check checker::Type *TSLiteralType::Check([[maybe_unused]] checker::ETSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsLiteralType.h b/ets2panda/ir/ts/tsLiteralType.h index 9569ef3828..ee3e8e1455 100644 --- a/ets2panda/ir/ts/tsLiteralType.h +++ b/ets2panda/ir/ts/tsLiteralType.h @@ -32,6 +32,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsNeverKeyword.cpp b/ets2panda/ir/ts/tsNeverKeyword.cpp index 92b64c3dae..ee52a42c6b 100644 --- a/ets2panda/ir/ts/tsNeverKeyword.cpp +++ b/ets2panda/ir/ts/tsNeverKeyword.cpp @@ -15,6 +15,8 @@ #include "tsNeverKeyword.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "checker/TSchecker.h" @@ -27,11 +29,19 @@ void TSNeverKeyword::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSNeverKeyword"}}); } -void TSNeverKeyword::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void TSNeverKeyword::Compile([[maybe_unused]] compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} + +void TSNeverKeyword::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} checker::Type *TSNeverKeyword::Check([[maybe_unused]] checker::TSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *TSNeverKeyword::GetType([[maybe_unused]] checker::TSChecker *checker) @@ -41,6 +51,6 @@ checker::Type *TSNeverKeyword::GetType([[maybe_unused]] checker::TSChecker *chec checker::Type *TSNeverKeyword::Check([[maybe_unused]] checker::ETSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsNeverKeyword.h b/ets2panda/ir/ts/tsNeverKeyword.h index 20053e4aa2..35d4aa449f 100644 --- a/ets2panda/ir/ts/tsNeverKeyword.h +++ b/ets2panda/ir/ts/tsNeverKeyword.h @@ -27,6 +27,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsNonNullExpression.cpp b/ets2panda/ir/ts/tsNonNullExpression.cpp index 3ce576cef4..ac49f17ac8 100644 --- a/ets2panda/ir/ts/tsNonNullExpression.cpp +++ b/ets2panda/ir/ts/tsNonNullExpression.cpp @@ -16,7 +16,9 @@ #include "tsNonNullExpression.h" #include "checker/ETSchecker.h" +#include "checker/TSchecker.h" #include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" namespace panda::es2panda::ir { @@ -35,52 +37,23 @@ void TSNonNullExpression::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSNonNullExpression"}, {"expression", expr_}}); } -void TSNonNullExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void TSNonNullExpression::Compile([[maybe_unused]] compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} void TSNonNullExpression::Compile(compiler::ETSGen *etsg) const { - compiler::RegScope rs(etsg); - - expr_->Compile(etsg); - - if (!etsg->GetAccumulatorType()->IsNullishOrNullLike()) { - return; - } - - if (etsg->GetAccumulatorType()->IsETSNullLike()) { - etsg->EmitNullishException(this); - return; - } - - auto arg = etsg->AllocReg(); - etsg->StoreAccumulator(this, arg); - etsg->LoadAccumulator(this, arg); - - auto end_label = etsg->AllocLabel(); - - etsg->BranchIfNotNullish(this, end_label); - etsg->EmitNullishException(this); - - etsg->SetLabel(this, end_label); - etsg->LoadAccumulator(this, arg); - etsg->ConvertToNonNullish(this); + etsg->GetAstCompiler()->Compile(this); } checker::Type *TSNonNullExpression::Check([[maybe_unused]] checker::TSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *TSNonNullExpression::Check(checker::ETSChecker *checker) { - auto expr_type = expr_->Check(checker); - - if (!expr_type->IsNullish()) { - checker->ThrowTypeError("Bad operand type, the operand of the non-null expression must be a nullable type", - expr_->Start()); - } - - SetTsType(expr_type->IsNullish() ? checker->GetNonNullishType(expr_type) : expr_type); - return TsType(); + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsNonNullExpression.h b/ets2panda/ir/ts/tsNonNullExpression.h index 22910a2211..0819a97fe4 100644 --- a/ets2panda/ir/ts/tsNonNullExpression.h +++ b/ets2panda/ir/ts/tsNonNullExpression.h @@ -18,11 +18,17 @@ #include "ir/expression.h" +namespace panda::es2panda::checker { +class ETSAnalyzer; +} // namespace panda::es2panda::checker namespace panda::es2panda::ir { class TSNonNullExpression : public Expression { public: explicit TSNonNullExpression(Expression *expr) : Expression(AstNodeType::TS_NON_NULL_EXPRESSION), expr_(expr) {} + // TODO (vivienvoros): these friend relationships can be removed once there are getters for private fields + friend class checker::ETSAnalyzer; + const Expression *Expr() const { return expr_; diff --git a/ets2panda/ir/ts/tsParenthesizedType.cpp b/ets2panda/ir/ts/tsParenthesizedType.cpp index ba224d1c70..04012a2b20 100644 --- a/ets2panda/ir/ts/tsParenthesizedType.cpp +++ b/ets2panda/ir/ts/tsParenthesizedType.cpp @@ -15,6 +15,8 @@ #include "tsParenthesizedType.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "checker/TSchecker.h" @@ -34,12 +36,19 @@ void TSParenthesizedType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSParenthesizedType"}, {"typeAnnotation", type_}}); } -void TSParenthesizedType::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void TSParenthesizedType::Compile([[maybe_unused]] compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} + +void TSParenthesizedType::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} checker::Type *TSParenthesizedType::Check([[maybe_unused]] checker::TSChecker *checker) { - type_->Check(checker); - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *TSParenthesizedType::GetType([[maybe_unused]] checker::TSChecker *checker) @@ -54,6 +63,6 @@ checker::Type *TSParenthesizedType::GetType([[maybe_unused]] checker::TSChecker checker::Type *TSParenthesizedType::Check([[maybe_unused]] checker::ETSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsParenthesizedType.h b/ets2panda/ir/ts/tsParenthesizedType.h index 8175be3978..5818aa2e43 100644 --- a/ets2panda/ir/ts/tsParenthesizedType.h +++ b/ets2panda/ir/ts/tsParenthesizedType.h @@ -17,12 +17,17 @@ #define ES2PANDA_IR_TS_PARENT_TYPE_H #include "ir/typeNode.h" - +namespace panda::es2panda::checker { +class TSAnalyzer; +} // namespace panda::es2panda::checker namespace panda::es2panda::ir { class TSParenthesizedType : public TypeNode { public: explicit TSParenthesizedType(TypeNode *type) : TypeNode(AstNodeType::TS_PARENT_TYPE), type_(type) {} + // TODO (vivienvoros): these friend relationships can be removed once there are getters for private fields + friend class checker::TSAnalyzer; + const Expression *Type() const { return type_; @@ -32,6 +37,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsTypeLiteral.cpp b/ets2panda/ir/ts/tsTypeLiteral.cpp index 48fdf07d86..9f9471ab8f 100644 --- a/ets2panda/ir/ts/tsTypeLiteral.cpp +++ b/ets2panda/ir/ts/tsTypeLiteral.cpp @@ -15,6 +15,8 @@ #include "tsTypeLiteral.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" #include "varbinder/variable.h" @@ -42,18 +44,19 @@ void TSTypeLiteral::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSTypeLiteral"}, {"members", members_}}); } -void TSTypeLiteral::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} - -checker::Type *TSTypeLiteral::Check(checker::TSChecker *checker) +void TSTypeLiteral::Compile([[maybe_unused]] compiler::PandaGen *pg) const { - for (auto *it : members_) { - it->Check(checker); - } + pg->GetAstCompiler()->Compile(this); +} - checker::Type *type = GetType(checker); - checker->CheckIndexConstraints(type); +void TSTypeLiteral::Compile(compiler::ETSGen *etsg) const +{ + etsg->GetAstCompiler()->Compile(this); +} - return nullptr; +checker::Type *TSTypeLiteral::Check(checker::TSChecker *checker) +{ + return checker->GetAnalyzer()->Check(this); } checker::Type *TSTypeLiteral::GetType(checker::TSChecker *checker) @@ -72,6 +75,6 @@ checker::Type *TSTypeLiteral::GetType(checker::TSChecker *checker) checker::Type *TSTypeLiteral::Check([[maybe_unused]] checker::ETSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } } // namespace panda::es2panda::ir diff --git a/ets2panda/ir/ts/tsTypeLiteral.h b/ets2panda/ir/ts/tsTypeLiteral.h index 9f0cb0a1b7..a91e051a93 100644 --- a/ets2panda/ir/ts/tsTypeLiteral.h +++ b/ets2panda/ir/ts/tsTypeLiteral.h @@ -35,6 +35,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; diff --git a/ets2panda/ir/ts/tsUnionType.cpp b/ets2panda/ir/ts/tsUnionType.cpp index 6a55683ea6..802d5d65c7 100644 --- a/ets2panda/ir/ts/tsUnionType.cpp +++ b/ets2panda/ir/ts/tsUnionType.cpp @@ -16,6 +16,8 @@ #include "tsUnionType.h" #include "checker/TSchecker.h" +#include "compiler/core/ETSGen.h" +#include "compiler/core/pandagen.h" #include "ir/astDump.h" namespace panda::es2panda::ir { @@ -38,21 +40,24 @@ void TSUnionType::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "TSUnionType"}, {"types", types_}}); } -void TSUnionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const {} +void TSUnionType::Compile([[maybe_unused]] compiler::PandaGen *pg) const +{ + pg->GetAstCompiler()->Compile(this); +} -checker::Type *TSUnionType::Check([[maybe_unused]] checker::TSChecker *checker) +void TSUnionType::Compile(compiler::ETSGen *etsg) const { - for (auto *it : types_) { - it->Check(checker); - } + etsg->GetAstCompiler()->Compile(this); +} - GetType(checker); - return nullptr; +checker::Type *TSUnionType::Check([[maybe_unused]] checker::TSChecker *checker) +{ + return checker->GetAnalyzer()->Check(this); } checker::Type *TSUnionType::Check([[maybe_unused]] checker::ETSChecker *checker) { - return nullptr; + return checker->GetAnalyzer()->Check(this); } checker::Type *TSUnionType::GetType(checker::TSChecker *checker) diff --git a/ets2panda/ir/ts/tsUnionType.h b/ets2panda/ir/ts/tsUnionType.h index feaa03b282..aa31b0ba6e 100644 --- a/ets2panda/ir/ts/tsUnionType.h +++ b/ets2panda/ir/ts/tsUnionType.h @@ -35,6 +35,7 @@ public: void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; + void Compile(compiler::ETSGen *etsg) const override; checker::Type *Check([[maybe_unused]] checker::TSChecker *checker) override; checker::Type *Check([[maybe_unused]] checker::ETSChecker *checker) override; checker::Type *GetType([[maybe_unused]] checker::TSChecker *checker) override; -- Gitee