From 2bea3746b32a6512a65e88a07db0cbefd50ec610 Mon Sep 17 00:00:00 2001 From: Orlovsky Maxim Date: Thu, 18 Jul 2024 14:41:02 +0300 Subject: [PATCH] Title: Code check warnings Description: Need to fix codecheck in ets2panda/checker ets2panda/compiler/lowering/ets ets2panda/compiler/core ets2panda/compiler/core/emitter Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IAE0B3 Testing: ninja es2panda_tests Signed-off-by: Orlovsky Maxim --- ets2panda/checker/ETSAnalyzerHelpers.cpp | 3 +- ets2panda/checker/ETSchecker.h | 1 + ets2panda/checker/ets/helpers.cpp | 5 +- ets2panda/checker/ets/typeCreation.cpp | 49 ++-- ets2panda/checker/ts/typeCreation.cpp | 12 +- ets2panda/checker/types/ets/etsDynamicType.h | 3 +- ets2panda/checker/types/ets/etsObjectType.cpp | 96 +++++--- ets2panda/checker/types/ets/etsObjectType.h | 23 +- ets2panda/checker/types/ts/tupleType.cpp | 5 +- ets2panda/checker/types/ts/tupleType.h | 13 +- ets2panda/compiler/core/JSCompiler.cpp | 5 +- ets2panda/compiler/core/emitter.cpp | 60 ++--- ets2panda/compiler/core/emitter.h | 2 + ets2panda/compiler/core/pandagen.cpp | 195 +++++++++------ ets2panda/compiler/core/pandagen.h | 5 +- .../compiler/lowering/ets/lambdaLowering.cpp | 7 +- .../lowering/ets/objectIndexAccess.cpp | 17 +- .../compiler/lowering/ets/opAssignment.cpp | 19 +- .../compiler/lowering/ets/tupleLowering.cpp | 224 +++++++++++------- ets2panda/es2panda.cpp | 1 - ets2panda/ir/base/methodDefinition.h | 3 +- 21 files changed, 455 insertions(+), 293 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index db7db97c1e..1c69c3aa5d 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -476,7 +476,8 @@ checker::ETSObjectType *CreateSyntheticType(ETSChecker *checker, util::StringVie checker::ETSObjectType *lastObjectType, ir::Identifier *id) { auto *syntheticObjType = checker->Allocator()->New( - checker->Allocator(), syntheticName, syntheticName, id, checker::ETSObjectFlags::NO_OPTS, checker->Relation()); + checker->Allocator(), syntheticName, syntheticName, + std::make_tuple(id, checker::ETSObjectFlags::NO_OPTS, checker->Relation())); auto *classDecl = checker->Allocator()->New(syntheticName); varbinder::LocalVariable *var = diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index ffbf7ba718..b056da86f5 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -240,6 +240,7 @@ public: std::tuple CreateBuiltinArraySignatureInfo(ETSArrayType *arrayType, size_t dim); Signature *CreateBuiltinArraySignature(ETSArrayType *arrayType, size_t dim); IntType *CreateIntTypeFromType(Type *type); + std::tuple CheckForDynamicLang(ir::AstNode *declNode, util::StringView assemblerName); ETSObjectType *CreateNewETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags); Signature *CreateSignature(SignatureInfo *info, Type *returnType, ir::ScriptFunction *func); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 28419dd5fc..f5d202d592 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2942,8 +2942,9 @@ ETSObjectType *ETSChecker::GetImportSpecifierObjectType(ir::ETSImportDeclaration .View(); } - auto *moduleObjectType = Allocator()->New( - Allocator(), syntheticNames[0], assemblerName, ident, checker::ETSObjectFlags::CLASS, Relation()); + auto *moduleObjectType = + Allocator()->New(Allocator(), syntheticNames[0], assemblerName, + std::make_tuple(ident, checker::ETSObjectFlags::CLASS, Relation())); auto *rootDecl = Allocator()->New(syntheticNames[0]); varbinder::LocalVariable *rootVar = diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 2a145c54a9..ef6a390284 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -539,6 +539,31 @@ ETSObjectType *ETSChecker::CreateETSObjectType(util::StringView name, ir::AstNod return objType; } +std::tuple ETSChecker::CheckForDynamicLang(ir::AstNode *declNode, util::StringView assemblerName) +{ + Language lang(Language::Id::ETS); + bool hasDecl = false; + + if (declNode->IsClassDefinition()) { + auto *clsDef = declNode->AsClassDefinition(); + lang = clsDef->Language(); + hasDecl = clsDef->IsDeclare(); + } + + if (declNode->IsTSInterfaceDeclaration()) { + auto *ifaceDecl = declNode->AsTSInterfaceDeclaration(); + lang = ifaceDecl->Language(); + hasDecl = ifaceDecl->IsDeclare(); + } + + auto res = compiler::Signatures::Dynamic::LanguageFromType(assemblerName.Utf8()); + if (res) { + lang = *res; + } + + return std::make_tuple(lang, hasDecl); +} + ETSObjectType *ETSChecker::CreateNewETSObjectType(util::StringView name, ir::AstNode *declNode, ETSObjectFlags flags) { util::StringView assemblerName = name; @@ -573,32 +598,14 @@ ETSObjectType *ETSChecker::CreateNewETSObjectType(util::StringView name, ir::Ast .View(); } - Language lang(Language::Id::ETS); - bool hasDecl = false; - - if (declNode->IsClassDefinition()) { - auto *clsDef = declNode->AsClassDefinition(); - lang = clsDef->Language(); - hasDecl = clsDef->IsDeclare(); - } - - if (declNode->IsTSInterfaceDeclaration()) { - auto *ifaceDecl = declNode->AsTSInterfaceDeclaration(); - lang = ifaceDecl->Language(); - hasDecl = ifaceDecl->IsDeclare(); - } - - auto res = compiler::Signatures::Dynamic::LanguageFromType(assemblerName.Utf8()); - if (res) { - lang = *res; - } - + auto [lang, hasDecl] = CheckForDynamicLang(declNode, assemblerName); if (lang.IsDynamic()) { return Allocator()->New(Allocator(), name, assemblerName, declNode, flags, Relation(), lang, hasDecl); } - return Allocator()->New(Allocator(), name, assemblerName, declNode, flags, Relation()); + return Allocator()->New(Allocator(), name, assemblerName, + std::make_tuple(declNode, flags, Relation())); } std::tuple ETSChecker::CreateBuiltinArraySignatureInfo(ETSArrayType *arrayType, diff --git a/ets2panda/checker/ts/typeCreation.cpp b/ets2panda/checker/ts/typeCreation.cpp index 0823f3c244..aa8e49937c 100644 --- a/ets2panda/checker/ts/typeCreation.cpp +++ b/ets2panda/checker/ts/typeCreation.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2024 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 @@ -155,8 +155,9 @@ Type *TSChecker::CreateTupleType(ObjectDescriptor *desc, ArenaVectorstringIndexInfo = Allocator()->New(GlobalAnyType(), "x", readonly); checker::NamedTupleMemberPool namedMembers(Allocator()->Adapter()); - return Allocator()->New(desc, std::move(elementFlags), combinedFlags, minLength, fixedLength, readonly, - std::move(namedMembers)); + return Allocator()->New( + std::make_tuple(desc, std::move(elementFlags), combinedFlags, std::move(namedMembers)), minLength, fixedLength, + readonly); } Type *TSChecker::CreateTupleType(ObjectDescriptor *desc, ArenaVector &&elementFlags, @@ -165,7 +166,8 @@ Type *TSChecker::CreateTupleType(ObjectDescriptor *desc, ArenaVectorstringIndexInfo = Allocator()->New(GlobalAnyType(), "x", readonly); - return Allocator()->New(desc, std::move(elementFlags), combinedFlags, minLength, fixedLength, readonly, - std::move(namedMembers)); + return Allocator()->New( + std::make_tuple(desc, std::move(elementFlags), combinedFlags, std::move(namedMembers)), minLength, fixedLength, + readonly); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsDynamicType.h b/ets2panda/checker/types/ets/etsDynamicType.h index 41003dfafb..67708ec88f 100644 --- a/ets2panda/checker/types/ets/etsDynamicType.h +++ b/ets2panda/checker/types/ets/etsDynamicType.h @@ -24,7 +24,8 @@ public: explicit ETSDynamicType(ArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, ir::AstNode *declNode, ETSObjectFlags flags, TypeRelation *relation, Language lang, bool hasDecl) - : ETSObjectType(allocator, name, assemblerName, declNode, flags | ETSObjectFlags::DYNAMIC, relation), + : ETSObjectType(allocator, name, assemblerName, + std::make_tuple(declNode, flags | ETSObjectFlags::DYNAMIC, relation)), propertiesCache_ {allocator->Adapter()}, lang_(lang), hasDecl_(hasDecl) diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 88e7cd5c08..2abab9fe51 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -456,29 +456,27 @@ bool ETSObjectType::CastWideningNarrowing(TypeRelation *const relation, Type *co return false; } -bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const target) +bool ETSObjectType::TryCastByte(TypeRelation *const relation, Type *const target) { - if (!target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | - TypeFlag::FLOAT | TypeFlag::DOUBLE | TypeFlag::ETS_BOOLEAN)) { - return false; + if (target->HasTypeFlag(TypeFlag::BYTE)) { + conversion::Unboxing(relation, this); + return true; } - if (relation->IsIdenticalTo(this, target)) { + if (target->HasTypeFlag(TypeFlag::SHORT | TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE)) { + conversion::UnboxingWideningPrimitive(relation, this, target); return true; } - if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_BYTE)) { - if (target->HasTypeFlag(TypeFlag::BYTE)) { - conversion::Unboxing(relation, this); - return true; - } - if (target->HasTypeFlag(TypeFlag::SHORT | TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | - TypeFlag::DOUBLE)) { - conversion::UnboxingWideningPrimitive(relation, this, target); - return true; - } - if (target->HasTypeFlag(TypeFlag::CHAR)) { - conversion::UnboxingWideningNarrowingPrimitive(relation, this, target); - return true; - } + if (target->HasTypeFlag(TypeFlag::CHAR)) { + conversion::UnboxingWideningNarrowingPrimitive(relation, this, target); + return true; + } + return false; +} + +bool ETSObjectType::TryCastIntegral(TypeRelation *const relation, Type *const target) +{ + if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_BYTE) && TryCastByte(relation, target)) { + return true; } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_SHORT) && CastWideningNarrowing(relation, target, TypeFlag::SHORT, @@ -502,6 +500,11 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT)) { return true; } + return false; +} + +bool ETSObjectType::TryCastFloating(TypeRelation *const relation, Type *const target) +{ if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_FLOAT) && CastWideningNarrowing(relation, target, TypeFlag::FLOAT, TypeFlag::DOUBLE, TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG)) { @@ -513,27 +516,50 @@ bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const CastWideningNarrowing(relation, target, TypeFlag::DOUBLE, TypeFlag::NONE, narrowingFlags)) { return true; } + return false; +} + +bool ETSObjectType::TryCastUnboxable(TypeRelation *const relation, Type *const target) +{ + if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { + if (!target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::UNBOXABLE_TYPE)) { + conversion::WideningReference(relation, this, target->AsETSObjectType()); + return true; + } + auto unboxedTarget = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); + CastNumericObject(relation, unboxedTarget); + if (relation->IsTrue()) { + conversion::Boxing(relation, unboxedTarget); + return true; + } + conversion::WideningReference(relation, this, target->AsETSObjectType()); + return true; + } + conversion::Forbidden(relation); + return true; +} + +bool ETSObjectType::CastNumericObject(TypeRelation *const relation, Type *const target) +{ + if (!target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | + TypeFlag::FLOAT | TypeFlag::DOUBLE | TypeFlag::ETS_BOOLEAN)) { + return false; + } + if (relation->IsIdenticalTo(this, target)) { + return true; + } + if (TryCastIntegral(relation, target)) { + return true; + } + if (TryCastFloating(relation, target)) { + return true; + } if (this->HasObjectFlag(ETSObjectFlags::BUILTIN_BOOLEAN) && target->HasTypeFlag(TypeFlag::ETS_BOOLEAN)) { conversion::Unboxing(relation, this); return true; } if (this->HasObjectFlag(ETSObjectFlags::UNBOXABLE_TYPE)) { - if (target->HasTypeFlag(TypeFlag::ETS_OBJECT)) { - if (!target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::UNBOXABLE_TYPE)) { - conversion::WideningReference(relation, this, target->AsETSObjectType()); - return true; - } - auto unboxedTarget = relation->GetChecker()->AsETSChecker()->ETSBuiltinTypeAsPrimitiveType(target); - CastNumericObject(relation, unboxedTarget); - if (relation->IsTrue()) { - conversion::Boxing(relation, unboxedTarget); - return true; - } - conversion::WideningReference(relation, this, target->AsETSObjectType()); - return true; - } - conversion::Forbidden(relation); - return true; + return TryCastUnboxable(relation, target); } if (target->HasTypeFlag(TypeFlag::BYTE | TypeFlag::SHORT | TypeFlag::CHAR | TypeFlag::INT | TypeFlag::LONG | TypeFlag::FLOAT | TypeFlag::DOUBLE | TypeFlag::ETS_BOOLEAN)) { diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 52ada3c2b3..9e903dc63e 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -36,25 +36,25 @@ public: explicit ETSObjectType(ArenaAllocator *allocator) : ETSObjectType(allocator, ETSObjectFlags::NO_OPTS) {} explicit ETSObjectType(ArenaAllocator *allocator, ETSObjectFlags flags) - : ETSObjectType(allocator, "", "", nullptr, flags, nullptr) + : ETSObjectType(allocator, "", "", std::make_tuple(nullptr, flags, nullptr)) { } explicit ETSObjectType(ArenaAllocator *allocator, ETSObjectFlags flags, TypeRelation *relation) - : ETSObjectType(allocator, "", "", nullptr, flags, relation) + : ETSObjectType(allocator, "", "", std::make_tuple(nullptr, flags, relation)) { } explicit ETSObjectType(ArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, ir::AstNode *declNode, ETSObjectFlags flags) - : ETSObjectType(allocator, name, assemblerName, declNode, flags, nullptr, + : ETSObjectType(allocator, name, assemblerName, std::make_tuple(declNode, flags, nullptr), std::make_index_sequence(PropertyType::COUNT)> {}) { } explicit ETSObjectType(ArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, - ir::AstNode *declNode, ETSObjectFlags flags, TypeRelation *relation) - : ETSObjectType(allocator, name, assemblerName, declNode, flags, relation, + std::tuple info) + : ETSObjectType(allocator, name, assemblerName, info, std::make_index_sequence(PropertyType::COUNT)> {}) { } @@ -412,20 +412,20 @@ protected: private: template explicit ETSObjectType(ArenaAllocator *allocator, util::StringView name, util::StringView assemblerName, - ir::AstNode *declNode, ETSObjectFlags flags, TypeRelation *relation, + std::tuple info, [[maybe_unused]] std::index_sequence s) : Type(TypeFlag::ETS_OBJECT), allocator_(allocator), name_(name), assemblerName_(assemblerName), - declNode_(declNode), + declNode_(std::get(info)), interfaces_(allocator->Adapter()), reExports_(allocator->Adapter()), reExportAlias_(allocator->Adapter()), - flags_(flags), + flags_(std::get(info)), instantiationMap_(allocator->Adapter()), typeArguments_(allocator->Adapter()), - relation_(relation), + relation_(std::get(info)), constructSignatures_(allocator->Adapter()), properties_ {(void(IS), PropertyMap {allocator->Adapter()})...} { @@ -468,6 +468,11 @@ private: const Substitution *substitution); bool SubstituteTypeArgs(TypeRelation *relation, ArenaVector &newTypeArgs, const Substitution *substitution); + bool TryCastByte(TypeRelation *const relation, Type *const target); + bool TryCastIntegral(TypeRelation *const relation, Type *const target); + bool TryCastFloating(TypeRelation *const relation, Type *const target); + bool TryCastUnboxable(TypeRelation *const relation, Type *const target); + ArenaAllocator *allocator_; util::StringView name_; util::StringView assemblerName_; diff --git a/ets2panda/checker/types/ts/tupleType.cpp b/ets2panda/checker/types/ts/tupleType.cpp index d83c544631..130c533eff 100644 --- a/ets2panda/checker/types/ts/tupleType.cpp +++ b/ets2panda/checker/types/ts/tupleType.cpp @@ -163,7 +163,8 @@ Type *TupleType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, copiedElementFlags.push_back(it); } - return allocator->New(copiedDesc, std::move(copiedElementFlags), combinedFlags_, minLength_, - fixedLength_, readonly_, std::move(copiedNamedMemberPool)); + return allocator->New( + std::make_tuple(copiedDesc, std::move(copiedElementFlags), combinedFlags_, std::move(copiedNamedMemberPool)), + minLength_, fixedLength_, readonly_); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ts/tupleType.h b/ets2panda/checker/types/ts/tupleType.h index d774c0bd1d..94054af236 100644 --- a/ets2panda/checker/types/ts/tupleType.h +++ b/ets2panda/checker/types/ts/tupleType.h @@ -32,14 +32,15 @@ public: { } - TupleType(ObjectDescriptor *desc, ArenaVector &&elementFlags, ElementFlags combinedFlags, - uint32_t minLength, uint32_t fixedLength, bool readonly, NamedTupleMemberPool &&namedMembers) - : ObjectType(ObjectType::ObjectTypeKind::TUPLE, desc), - elementFlags_(std::move(elementFlags)), - combinedFlags_(combinedFlags), + TupleType( + std::tuple &&, ElementFlags, NamedTupleMemberPool &&> contents, + uint32_t minLength, uint32_t fixedLength, bool readonly) + : ObjectType(ObjectType::ObjectTypeKind::TUPLE, std::get(contents)), + elementFlags_(std::move(std::get &&>(contents))), + combinedFlags_(std::get(contents)), minLength_(minLength), fixedLength_(fixedLength), - namedMembers_(std::move(namedMembers)), + namedMembers_(std::move(std::get(contents))), readonly_(readonly) { if (readonly_) { diff --git a/ets2panda/compiler/core/JSCompiler.cpp b/ets2panda/compiler/core/JSCompiler.cpp index 2dc74215a5..ae5b98d36c 100644 --- a/ets2panda/compiler/core/JSCompiler.cpp +++ b/ets2panda/compiler/core/JSCompiler.cpp @@ -314,7 +314,8 @@ static void CompileMissingProperties(compiler::PandaGen *pg, const util::BitSet setter = accessor; } - pg->DefineGetterSetterByValue(node, dest, keyReg, getter, setter, prop->IsComputed()); + pg->DefineGetterSetterByValue(node, std::make_tuple(dest, keyReg, getter, setter), + prop->IsComputed()); break; } default: { @@ -1110,7 +1111,7 @@ void JSCompiler::CompileRemainingProperties(compiler::PandaGen *pg, const util:: setter = accessor; } - pg->DefineGetterSetterByValue(expr, objReg, key, getter, setter, prop->IsComputed()); + pg->DefineGetterSetterByValue(expr, std::make_tuple(objReg, key, getter, setter), prop->IsComputed()); break; } case ir::PropertyKind::INIT: { diff --git a/ets2panda/compiler/core/emitter.cpp b/ets2panda/compiler/core/emitter.cpp index 8baf0c7432..7c6a71d131 100644 --- a/ets2panda/compiler/core/emitter.cpp +++ b/ets2panda/compiler/core/emitter.cpp @@ -268,9 +268,10 @@ void FunctionEmitter::GenSourceFileDebugInfo(pandasm::Function *func) } static void GenLocalVariableInfo(pandasm::debuginfo::LocalVariable &variableDebug, varbinder::Variable *var, - uint32_t start, uint32_t varsLength, uint32_t totalRegsNum, - const ScriptExtension extension) + std::tuple info, const ScriptExtension extension) { + const auto [start, varsLength, totalRegsNum] = info; + variableDebug.name = var->Name().Mutf8(); if (extension == ScriptExtension::JS) { @@ -289,6 +290,35 @@ static void GenLocalVariableInfo(pandasm::debuginfo::LocalVariable &variableDebu variableDebug.length = static_cast(varsLength); } +void FunctionEmitter::GenScopeVariableInfoEnd(pandasm::Function *func, const varbinder::Scope *scope, uint32_t count, + uint32_t start) const +{ + const auto extension = cg_->VarBinder()->Program()->Extension(); + auto varsLength = static_cast(count - start + 1); + + if (scope->IsFunctionScope()) { + for (auto *param : scope->AsFunctionScope()->ParamScope()->Params()) { + auto &variableDebug = func->localVariableDebug.emplace_back(); + GenLocalVariableInfo(variableDebug, param, std::make_tuple(start, varsLength, cg_->TotalRegsNum()), + extension); + } + } + const auto &unsortedBindings = scope->Bindings(); + std::map bindings(unsortedBindings.begin(), + unsortedBindings.end()); + for (const auto &[_, variable] : bindings) { + (void)_; + if (!variable->IsLocalVariable() || variable->LexicalBound() || variable->Declaration()->IsParameterDecl() || + variable->Declaration()->IsTypeAliasDecl()) { + continue; + } + + auto &variableDebug = func->localVariableDebug.emplace_back(); + GenLocalVariableInfo(variableDebug, variable, std::make_tuple(start, varsLength, cg_->TotalRegsNum()), + extension); + } +} + void FunctionEmitter::GenScopeVariableInfo(pandasm::Function *func, const varbinder::Scope *scope) const { const auto *startIns = scope->ScopeStart(); @@ -297,35 +327,11 @@ void FunctionEmitter::GenScopeVariableInfo(pandasm::Function *func, const varbin uint32_t start = 0; uint32_t count = 0; - const auto extension = cg_->VarBinder()->Program()->Extension(); - for (const auto *it : cg_->Insns()) { if (startIns == it) { start = count; } else if (endIns == it) { - auto varsLength = static_cast(count - start + 1); - - if (scope->IsFunctionScope()) { - for (auto *param : scope->AsFunctionScope()->ParamScope()->Params()) { - auto &variableDebug = func->localVariableDebug.emplace_back(); - GenLocalVariableInfo(variableDebug, param, start, varsLength, cg_->TotalRegsNum(), extension); - } - } - const auto &unsortedBindings = scope->Bindings(); - std::map bindings(unsortedBindings.begin(), - unsortedBindings.end()); - for (const auto &[_, variable] : bindings) { - (void)_; - if (!variable->IsLocalVariable() || variable->LexicalBound() || - variable->Declaration()->IsParameterDecl() || variable->Declaration()->IsTypeAliasDecl()) { - continue; - } - - auto &variableDebug = func->localVariableDebug.emplace_back(); - GenLocalVariableInfo(variableDebug, variable, start, varsLength, cg_->TotalRegsNum(), extension); - } - - break; + GenScopeVariableInfoEnd(func, scope, count, start); } count++; diff --git a/ets2panda/compiler/core/emitter.h b/ets2panda/compiler/core/emitter.h index b952a719d3..48717db674 100644 --- a/ets2panda/compiler/core/emitter.h +++ b/ets2panda/compiler/core/emitter.h @@ -75,6 +75,8 @@ protected: void GenInstructionDebugInfo(const IRNode *ins, ark::pandasm::Ins *pandaIns); void GenFunctionInstructions(pandasm::Function *func); void GenScopeVariableInfo(pandasm::Function *func, const varbinder::Scope *scope) const; + void GenScopeVariableInfoEnd(pandasm::Function *func, const varbinder::Scope *scope, uint32_t count, + uint32_t start) const; void GenSourceFileDebugInfo(pandasm::Function *func); void GenFunctionCatchTables(ark::pandasm::Function *func); void GenVariablesDebugInfo(pandasm::Function *func); diff --git a/ets2panda/compiler/core/pandagen.cpp b/ets2panda/compiler/core/pandagen.cpp index d3598c81bb..b7195f8453 100644 --- a/ets2panda/compiler/core/pandagen.cpp +++ b/ets2panda/compiler/core/pandagen.cpp @@ -942,62 +942,77 @@ void PandaGen::Call1This(const ir::AstNode *node, VReg callee, VReg thisReg, VRe void PandaGen::Call(const ir::AstNode *node, VReg callee, VReg thisReg, const ArenaVector &arguments) { bool hasThis = !thisReg.IsInvalid(); + const auto call0Args = [this, hasThis](const ir::AstNode *n, VReg c, VReg thisR) { + if (hasThis) { + Call0This(n, c, thisR); + } else { + Sa().Emit(n); + } + }; + const auto call1Arg = [this, hasThis](const ir::AstNode *n, VReg c, VReg thisR, + const ArenaVector &args) { + const auto *arg0 = args[0]; + arg0->Compile(this); + + if (hasThis) { + Ra().Emit(n, c, thisR); + } else { + Ra().Emit(n, c); + } + }; + const auto call2Args = [this, hasThis](const ir::AstNode *n, VReg c, VReg thisR, + const ArenaVector &args) { + const auto *arg0 = args[0]; + arg0->Compile(this); + compiler::VReg arg0Reg = AllocReg(); + StoreAccumulator(arg0, arg0Reg); + + const auto *arg1 = args[1]; + arg1->Compile(this); + + if (hasThis) { + Ra().Emit(n, c, thisR, arg0Reg); + } else { + Ra().Emit(n, c, arg0Reg); + } + }; + const auto call3Args = [this, hasThis](const ir::AstNode *n, VReg c, VReg thisR, + const ArenaVector &args) { + const auto *arg0 = args[0]; + arg0->Compile(this); + compiler::VReg arg0Reg = AllocReg(); + StoreAccumulator(arg0, arg0Reg); + + const auto *arg1 = args[1]; + arg1->Compile(this); + compiler::VReg arg1Reg = AllocReg(); + StoreAccumulator(arg1, arg1Reg); + + const auto *arg2 = args[2]; + arg2->Compile(this); + + if (hasThis) { + Ra().Emit(n, c, thisR, arg0Reg, arg1Reg); + } else { + Ra().Emit(n, c, arg0Reg, arg1Reg); + } + }; switch (arguments.size()) { case 0: { // 0 args - if (hasThis) { - Call0This(node, callee, thisReg); - } else { - Sa().Emit(node); - } + call0Args(node, callee, thisReg); return; } case 1: { // 1 arg - const auto *arg0 = arguments[0]; - arg0->Compile(this); - - if (hasThis) { - Ra().Emit(node, callee, thisReg); - } else { - Ra().Emit(node, callee); - } + call1Arg(node, callee, thisReg, arguments); return; } case 2: { // 2 args - const auto *arg0 = arguments[0]; - arg0->Compile(this); - compiler::VReg arg0Reg = AllocReg(); - StoreAccumulator(arg0, arg0Reg); - - const auto *arg1 = arguments[1]; - arg1->Compile(this); - - if (hasThis) { - Ra().Emit(node, callee, thisReg, arg0Reg); - } else { - Ra().Emit(node, callee, arg0Reg); - } + call2Args(node, callee, thisReg, arguments); return; } case 3: { // 3 args - const auto *arg0 = arguments[0]; - arg0->Compile(this); - compiler::VReg arg0Reg = AllocReg(); - StoreAccumulator(arg0, arg0Reg); - - const auto *arg1 = arguments[1]; - arg1->Compile(this); - compiler::VReg arg1Reg = AllocReg(); - StoreAccumulator(arg1, arg1Reg); - - const auto *arg2 = arguments[2]; - arg2->Compile(this); - - if (hasThis) { - Ra().Emit(node, callee, thisReg, arg0Reg, arg1Reg); - } else { - Ra().Emit(node, callee, arg0Reg, arg1Reg); - } + call3Args(node, callee, thisReg, arguments); return; } default: { @@ -1041,32 +1056,41 @@ void PandaGen::CallTagged(const ir::AstNode *node, VReg callee, VReg thisReg, VReg arg0Reg = AllocReg(); StoreAccumulator(node, arg0Reg); + const auto call1 = [this, hasThis, arg0Reg](const ir::AstNode *n, VReg c, VReg thisR, + const ArenaVector &args) { + const auto *arg = args[0]; + arg->Compile(this); + + if (hasThis) { + Ra().Emit(n, c, thisR, arg0Reg); + } else { + Ra().Emit(n, c, arg0Reg); + } + }; + const auto call2 = [this, hasThis, arg0Reg](const ir::AstNode *n, VReg c, VReg thisR, + const ArenaVector &args) { + const auto *arg1 = args[0]; + arg1->Compile(this); + compiler::VReg arg1Reg = AllocReg(); + StoreAccumulator(arg1, arg1Reg); + + const auto *arg2 = args[1]; + arg2->Compile(this); + + if (hasThis) { + Ra().Emit(n, c, thisR, arg0Reg, arg1Reg); + } else { + Ra().Emit(n, c, arg0Reg, arg1Reg); + } + }; + switch (arguments.size()) { case 1: { - const auto *arg = arguments[0]; - arg->Compile(this); - - if (hasThis) { - Ra().Emit(node, callee, thisReg, arg0Reg); - } else { - Ra().Emit(node, callee, arg0Reg); - } + call1(node, callee, thisReg, arguments); return; } case 2: { // 2:2 args - const auto *arg1 = arguments[0]; - arg1->Compile(this); - compiler::VReg arg1Reg = AllocReg(); - StoreAccumulator(arg1, arg1Reg); - - const auto *arg2 = arguments[1]; - arg2->Compile(this); - - if (hasThis) { - Ra().Emit(node, callee, thisReg, arg0Reg, arg1Reg); - } else { - Ra().Emit(node, callee, arg0Reg, arg1Reg); - } + call2(node, callee, thisReg, arguments); return; } default: { @@ -1298,9 +1322,10 @@ void PandaGen::CopyDataProperties(const ir::AstNode *node, VReg dst, VReg src) Ra().Emit(node, dst, src); } -void PandaGen::DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg name, VReg getter, VReg setter, +void PandaGen::DefineGetterSetterByValue(const ir::AstNode *node, std::tuple registers, bool setName) { + const auto [obj, name, getter, setter] = registers; LoadConst(node, setName ? Constant::JS_TRUE : Constant::JS_FALSE); Ra().Emit(node, obj, name, getter, setter); } @@ -1316,14 +1341,8 @@ void PandaGen::CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx) Sa().Emit(node, util::Helpers::ToStringView(Allocator(), idx)); } -void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector &elements, VReg obj) +size_t PandaGen::HandleArrayLiterals(const ir::AstNode *node, const ArenaVector &elements) { - if (elements.empty()) { - CreateEmptyArray(node); - StoreAccumulator(node, obj); - return; - } - LiteralBuffer buf {}; size_t i = 0; @@ -1345,13 +1364,12 @@ void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector &elements, VReg obj) +{ + size_t i = 0; bool hasSpread = false; // This loop handles array elements until a spread element is encountered @@ -1411,6 +1429,25 @@ void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector &elements, VReg obj) +{ + if (elements.empty()) { + CreateEmptyArray(node); + StoreAccumulator(node, obj); + return; + } + + const auto i = HandleArrayLiterals(node, elements); + + StoreAccumulator(node, obj); + + if (i == elements.size()) { + return; + } + + HandleArraySpread(node, elements, obj); LoadAccumulator(node, obj); } diff --git a/ets2panda/compiler/core/pandagen.h b/ets2panda/compiler/core/pandagen.h index a843cc15c7..1537fbcae0 100644 --- a/ets2panda/compiler/core/pandagen.h +++ b/ets2panda/compiler/core/pandagen.h @@ -182,9 +182,10 @@ public: void CreateObjectHavingMethod(const ir::AstNode *node, uint32_t idx); void SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj); void CopyDataProperties(const ir::AstNode *node, VReg dst, VReg src); - void DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg name, VReg getter, VReg setter, - bool setName); + void DefineGetterSetterByValue(const ir::AstNode *node, std::tuple registers, bool setName); void CreateEmptyArray(const ir::AstNode *node); + size_t HandleArrayLiterals(const ir::AstNode *node, const ArenaVector &elements); + void HandleArraySpread(const ir::AstNode *node, const ArenaVector &elements, VReg obj); void CreateArray(const ir::AstNode *node, const ArenaVector &elements, VReg obj); void CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx); void StoreArraySpread(const ir::AstNode *node, VReg array, VReg index); diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 6eb673295e..a4c293ae85 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -700,7 +700,8 @@ static checker::Signature *GuessSignature(checker::ETSChecker *checker, ir::Expr } if (!ast->Parent()->IsCallExpression()) { - checker->ThrowTypeError({"Cannot deduce call signature"}, ast->Start()); + checker->ThrowTypeError( + std::initializer_list {"Cannot deduce call signature"}, ast->Start()); } auto &args = ast->Parent()->AsCallExpression()->Arguments(); @@ -721,7 +722,9 @@ static checker::Signature *GuessSignature(checker::ETSChecker *checker, ir::Expr } if (sigFound != nullptr) { // ambiguiuty - checker->ThrowTypeError({"Cannot deduce call signature"}, ast->Start()); + checker->ThrowTypeError( + std::initializer_list {"Cannot deduce call signature"}, + ast->Start()); } sigFound = sig; } diff --git a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp index efd5350a96..3299612930 100644 --- a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp +++ b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp @@ -112,14 +112,21 @@ bool ObjectIndexLowering::Perform(public_lib::Context *ctx, parser::Program *pro bool ObjectIndexLowering::Postcondition(public_lib::Context *ctx, const parser::Program *program) { + auto checkExternalPrograms = [this, ctx](const ArenaVector &programs) { + for (auto *p : programs) { + if (!Postcondition(ctx, p)) { + return false; + } + } + return true; + }; + if (ctx->config->options->CompilerOptions().compilationMode == CompilationMode::GEN_STD_LIB) { for (auto &[_, extPrograms] : program->ExternalSources()) { (void)_; - for (auto *extProg : extPrograms) { - if (!Postcondition(ctx, extProg)) { - return false; - } - } + if (!checkExternalPrograms(extPrograms)) { + return false; + }; } } diff --git a/ets2panda/compiler/lowering/ets/opAssignment.cpp b/ets2panda/compiler/lowering/ets/opAssignment.cpp index b00c314f8e..1e45a1cd3d 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.cpp +++ b/ets2panda/compiler/lowering/ets/opAssignment.cpp @@ -342,14 +342,21 @@ bool OpAssignmentLowering::Perform(public_lib::Context *ctx, parser::Program *pr bool OpAssignmentLowering::Postcondition(public_lib::Context *ctx, const parser::Program *program) { + auto checkExternalPrograms = [this, ctx](const ArenaVector &programs) { + for (auto *p : programs) { + if (!Postcondition(ctx, p)) { + return false; + } + } + return true; + }; + if (ctx->config->options->CompilerOptions().compilationMode == CompilationMode::GEN_STD_LIB) { - for (auto &[_, ext_programs] : program->ExternalSources()) { + for (auto &[_, extPrograms] : program->ExternalSources()) { (void)_; - for (auto *extProg : ext_programs) { - if (!Postcondition(ctx, extProg)) { - return false; - } - } + if (!checkExternalPrograms(extPrograms)) { + return false; + }; } } diff --git a/ets2panda/compiler/lowering/ets/tupleLowering.cpp b/ets2panda/compiler/lowering/ets/tupleLowering.cpp index ad0cf4cd12..984f66b1d5 100644 --- a/ets2panda/compiler/lowering/ets/tupleLowering.cpp +++ b/ets2panda/compiler/lowering/ets/tupleLowering.cpp @@ -29,6 +29,135 @@ #include "ir/ts/tsAsExpression.h" namespace ark::es2panda::compiler { +class TupleUpdateConverter { +public: + TupleUpdateConverter(checker::ETSChecker *const checker, ir::UpdateExpression *const update) + : checker_(checker), update_(update) + { + } + + std::optional CheckUpdateArgument() + { + auto *const argument = update_->Argument(); + const bool isArgumentMemberExpression = argument->IsMemberExpression(); + auto *const argumentType = + isArgumentMemberExpression ? argument->AsMemberExpression()->Object()->TsType() : nullptr; + + if ((argumentType == nullptr) || (!argumentType->IsETSTupleType())) { + return std::nullopt; + } + return {argumentType}; + } + + checker::Type *SetArgumentType(checker::Type *const argumentType) + { + auto *const savedType = argument_->TsType(); + argument_->SetTsType(argumentType->AsETSTupleType()->ElementType()); + return savedType; + } + + void ComputeTypes(checker::Type *const argumentType) + { + tupleTypeAtIdx_ = argumentType->AsETSTupleType()->GetTypeAtIndex( + checker_->GetTupleElementAccessValue(argument_->AsMemberExpression()->Property()->TsType(), + argument_->AsMemberExpression()->Property()->Start())); + + tupleElementTypeNode_ = checker_->AllocNode(argumentType->AsETSTupleType()->ElementType()); + tupleTypeAtIdxNode_ = checker_->AllocNode(tupleTypeAtIdx_); + } + + ArenaVector GenerateExpressions() + { + // Clone argument of update expression (conversion flag might be added to it, so we need to duplicate it to not + // make + // conversions on 'line 3', that belongs to 'line 1' ) + auto [memberExpr, argumentClone] = CloneArgument(argument_); + // -------------- + + // Generate temporary symbols + auto [gensym, tmpVar] = GenerateSymbol(tupleTypeAtIdx_); + auto [gensym2, tmpVar2] = GenerateSymbol(tupleTypeAtIdx_); + // -------------- + // make node: let gensym = tuple[n] as ; + auto *const gensymTsAs = checker_->AllocNode(argumentClone, tupleTypeAtIdxNode_, false); + auto *const tupleAsType = checker_->AllocNode( + gensym, gensymTsAs, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + // -------------- + + // make node: let gensym2 = (gensym)++; + auto *identClone = gensym->Clone(checker_->Allocator(), nullptr); + identClone->SetTsType(tmpVar->TsType()); + auto *gensymUpdate = + checker_->AllocNode(identClone, update_->OperatorType(), update_->IsPrefix()); + auto *const gensym2Assignment = checker_->AllocNode( + gensym2, gensymUpdate, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + // -------------- + + // make node: tuple[n] = (gensym as ) as ; + identClone = gensym->Clone(checker_->Allocator(), nullptr); + identClone->SetTsType(tmpVar->TsType()); + auto *gensymAs = checker_->AllocNode( + identClone, tupleTypeAtIdxNode_->Clone(checker_->Allocator(), nullptr), false); + auto *gensymAsTupleTypeAtIdx = checker_->AllocNode(gensymAs, tupleElementTypeNode_, false); + auto *const tupleAssignment = checker_->AllocNode( + argument_, gensymAsTupleTypeAtIdx, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + // -------------- + + // make node: gensym2 as ; + identClone = gensym2->Clone(checker_->Allocator(), nullptr); + identClone->SetTsType(tmpVar2->TsType()); + auto *const finalTupleNode = checker_->AllocNode( + identClone, tupleTypeAtIdxNode_->Clone(checker_->Allocator(), nullptr), false); + // -------------- + + // Construct sequence expression order + ArenaVector expressionList(checker_->Allocator()->Adapter()); + expressionList.push_back(tupleAsType); + expressionList.push_back(gensym2Assignment); + expressionList.push_back(tupleAssignment); + expressionList.push_back(finalTupleNode); + // -------------- + + return expressionList; + } + +private: + std::tuple GenerateSymbol(checker::Type *const type) const + { + auto *gensym = Gensym(checker_->Allocator()); + auto *const tmpVar = NearestScope(update_)->AddDecl( + checker_->Allocator(), gensym->Name(), varbinder::VariableFlags::LOCAL); + tmpVar->SetTsType(type); + gensym->SetVariable(tmpVar); + gensym->SetTsType(tmpVar->TsType()); + return std::make_tuple(gensym, tmpVar); + } + + std::tuple CloneArgument( + ir::Expression *const argument) const + { + auto *const memberExpr = argument->AsMemberExpression(); + auto *const argumentClone = memberExpr->Clone(checker_->Allocator(), memberExpr->Parent()); + argumentClone->Object()->SetTsType(memberExpr->Object()->TsType()); + if (argumentClone->Object()->IsIdentifier()) { + argumentClone->Object()->AsIdentifier()->SetVariable(memberExpr->Object()->AsIdentifier()->Variable()); + } + argumentClone->Property()->SetTsType(memberExpr->Property()->TsType()); + if (argumentClone->Property()->IsIdentifier()) { + argumentClone->Property()->AsIdentifier()->SetVariable(memberExpr->Property()->AsIdentifier()->Variable()); + } + argumentClone->SetTsType(memberExpr->TsType()); + return std::make_tuple(memberExpr, argumentClone); + }; + + checker::ETSChecker *const checker_; + ir::UpdateExpression *const update_; + ir::Expression *const argument_ {nullptr}; + checker::Type *tupleTypeAtIdx_ {nullptr}; + ir::OpaqueTypeNode *tupleElementTypeNode_ {nullptr}; + ir::OpaqueTypeNode *tupleTypeAtIdxNode_ {nullptr}; +}; + static ir::Expression *ConvertTupleUpdate(checker::ETSChecker *const checker, ir::UpdateExpression *const update) { // Converts `tuple[n]++` to @@ -49,111 +178,34 @@ static ir::Expression *ConvertTupleUpdate(checker::ETSChecker *const checker, ir // is already ), the boxing flag will be on the as expression, instead of the identifier, so // the identifier node won't be unboxed at 'line 2'. - // Check if argument of update expression is tuple - auto *const argument = update->Argument(); - const bool isArgumentMemberExpression = argument->IsMemberExpression(); - auto *const argumentType = - isArgumentMemberExpression ? argument->AsMemberExpression()->Object()->TsType() : nullptr; + auto converter = TupleUpdateConverter {checker, update}; - if ((argumentType == nullptr) || (!argumentType->IsETSTupleType())) { + // Check if argument of update expression is tuple + auto const argumentType = converter.CheckUpdateArgument(); + if (!argumentType) { return update; } // -------------- // Set tuple type to Object (because we'll need implicit boxing) - auto *const savedType = argument->TsType(); - argument->SetTsType(argumentType->AsETSTupleType()->ElementType()); + auto *const savedType = converter.SetArgumentType(*argumentType); // -------------- // Compute necessary types and OpaqueTypeNodes - auto *const tupleTypeAtIdx = argumentType->AsETSTupleType()->GetTypeAtIndex(checker->GetTupleElementAccessValue( - argument->AsMemberExpression()->Property()->TsType(), argument->AsMemberExpression()->Property()->Start())); - - auto *const tupleElementTypeNode = - checker->AllocNode(argumentType->AsETSTupleType()->ElementType()); - auto *const tupleTypeAtIdxNode = checker->AllocNode(tupleTypeAtIdx); - // -------------- - - // Clone argument of update expression (conversion flag might be added to it, so we need to duplicate it to not make - // conversions on 'line 3', that belongs to 'line 1' ) - auto *const memberExpr = argument->AsMemberExpression(); - auto *const argumentClone = memberExpr->Clone(checker->Allocator(), memberExpr->Parent()); - argumentClone->Object()->SetTsType(memberExpr->Object()->TsType()); - if (argumentClone->Object()->IsIdentifier()) { - argumentClone->Object()->AsIdentifier()->SetVariable(memberExpr->Object()->AsIdentifier()->Variable()); - } - argumentClone->Property()->SetTsType(memberExpr->Property()->TsType()); - if (argumentClone->Property()->IsIdentifier()) { - argumentClone->Property()->AsIdentifier()->SetVariable(memberExpr->Property()->AsIdentifier()->Variable()); - } - argumentClone->SetTsType(memberExpr->TsType()); - // -------------- - - // Generate temporary symbols - auto *gensym = Gensym(checker->Allocator()); - auto *const tmpVar = NearestScope(update)->AddDecl( - checker->Allocator(), gensym->Name(), varbinder::VariableFlags::LOCAL); - tmpVar->SetTsType(tupleTypeAtIdx); - gensym->SetVariable(tmpVar); - gensym->SetTsType(tmpVar->TsType()); - - auto *gensym2 = Gensym(checker->Allocator()); - auto *const tmpVar2 = NearestScope(update)->AddDecl( - checker->Allocator(), gensym2->Name(), varbinder::VariableFlags::LOCAL); - tmpVar2->SetTsType(tupleTypeAtIdx); - gensym2->SetVariable(tmpVar2); - gensym2->SetTsType(tmpVar2->TsType()); + converter.ComputeTypes(*argumentType); // -------------- - // make node: let gensym = tuple[n] as ; - auto *const gensymTsAs = checker->AllocNode(argumentClone, tupleTypeAtIdxNode, false); - auto *const tupleAsType = - checker->AllocNode(gensym, gensymTsAs, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - // -------------- - - // make node: let gensym2 = (gensym)++; - auto *identClone = gensym->Clone(checker->Allocator(), nullptr); - identClone->SetTsType(tmpVar->TsType()); - auto *gensymUpdate = - checker->AllocNode(identClone, update->OperatorType(), update->IsPrefix()); - auto *const gensym2Assignment = - checker->AllocNode(gensym2, gensymUpdate, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - // -------------- - - // make node: tuple[n] = (gensym as ) as ; - identClone = gensym->Clone(checker->Allocator(), nullptr); - identClone->SetTsType(tmpVar->TsType()); - auto *gensymAs = checker->AllocNode( - identClone, tupleTypeAtIdxNode->Clone(checker->Allocator(), nullptr), false); - auto *gensymAsTupleTypeAtIdx = checker->AllocNode(gensymAs, tupleElementTypeNode, false); - auto *const tupleAssignment = checker->AllocNode( - argument, gensymAsTupleTypeAtIdx, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - // -------------- - - // make node: gensym2 as ; - identClone = gensym2->Clone(checker->Allocator(), nullptr); - identClone->SetTsType(tmpVar2->TsType()); - auto *const finalTupleNode = checker->AllocNode( - identClone, tupleTypeAtIdxNode->Clone(checker->Allocator(), nullptr), false); - // -------------- - - // Construct sequence expression order - ArenaVector expressionList(checker->Allocator()->Adapter()); - expressionList.push_back(tupleAsType); - expressionList.push_back(gensym2Assignment); - expressionList.push_back(tupleAssignment); - expressionList.push_back(finalTupleNode); - // -------------- + auto expressions = converter.GenerateExpressions(); // Check the new sequence expression - auto *const sequenceExpr = checker->AllocNode(std::move(expressionList)); + auto *const sequenceExpr = checker->AllocNode(std::move(expressions)); sequenceExpr->SetParent(update->Parent()); sequenceExpr->Check(checker); // -------------- // Set back TsType of argument (not necessarily needed now, but there can be a phase later, that need to get the // right type of it) - argument->SetTsType(savedType); + [[maybe_unused]] auto _ = converter.SetArgumentType(savedType); // -------------- return sequenceExpr; diff --git a/ets2panda/es2panda.cpp b/ets2panda/es2panda.cpp index 6c42b535d4..f217db0a8f 100644 --- a/ets2panda/es2panda.cpp +++ b/ets2panda/es2panda.cpp @@ -28,7 +28,6 @@ template T DirName(T const &path, T const &delims = ark::os::file::File::GetPathDelim()) { std::size_t pos = path.find_last_of(delims); - if (pos == std::string::npos) { return "./"; } diff --git a/ets2panda/ir/base/methodDefinition.h b/ets2panda/ir/base/methodDefinition.h index 50f23a6528..e186c32328 100644 --- a/ets2panda/ir/base/methodDefinition.h +++ b/ets2panda/ir/base/methodDefinition.h @@ -47,7 +47,8 @@ public: baseOverloadMethod_(nullptr), asyncPairMethod_(nullptr) { - ASSERT(key_ != nullptr && value_ != nullptr); + ASSERT(key_ != nullptr); + ASSERT(value != nullptr); } // NOTE (csabahurton): these friend relationships can be removed once there are getters for private fields -- Gitee