diff --git a/es2panda/compiler/base/lexenv.cpp b/es2panda/compiler/base/lexenv.cpp index f199cf3b007f14399be6e1cd3c83fd3e374b3fca..cf3451d569fe4a9eb832bc1e30aae834bef7f054 100644 --- a/es2panda/compiler/base/lexenv.cpp +++ b/es2panda/compiler/base/lexenv.cpp @@ -114,19 +114,21 @@ static void ExpandStoreNormalVar(PandaGen *pg, const ir::AstNode *node, const bi } auto context = pg->Context(); - if (context->IsTypeExtractorEnabled()) { - auto typeIndex = context->TypeRecorder()->GetVariableTypeIndex(local); - if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - pg->StoreAccumulatorWithType(node, typeIndex, localReg); - DCOUT << "[LOG]Local vreg in variable has type index: " << local->Name() << "@" << - local << " | " << typeIndex << std::endl; + if (context->IsTypeExtractorEnabled() && pg->TypedVars().count(local) == 0U) { + auto fn = [&pg, &node, &local, &localReg](auto typeIndex, const auto &tag) { + if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { + pg->StoreAccumulatorWithType(node, typeIndex, localReg); + pg->TypedVars().emplace(local); + DCOUT << "[LOG]Local vreg in " << tag << " has type index: " << local->Name() << + "@" << local << " | " << typeIndex << std::endl; + return true; + } + return false; + }; + if (fn(context->TypeRecorder()->GetVariableTypeIndex(local), "variable")) { return; } - typeIndex = context->TypeRecorder()->GetNodeTypeIndex(node); - if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - pg->StoreAccumulatorWithType(node, typeIndex, localReg); - DCOUT << "[LOG]Local vreg in declnode has type index: " << local->Name() << "@" << - local << " | " << typeIndex << std::endl; + if (fn(context->TypeRecorder()->GetNodeTypeIndex(node), "declnode")) { return; } DCOUT << "[WARNING]Local vreg lose type index: " << local->Name() << "@" << local << std::endl; diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 23fab34a877d7145e483364c859282cc2c550f1c..567ddb418bf9b23f5f7c49cbd3219d7b510e1dd6 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -16,9 +16,6 @@ #include "pandagen.h" #include -#include -#include -#include #include #include #include @@ -45,6 +42,9 @@ #include #include #include +#include +#include +#include namespace panda::es2panda::compiler { @@ -1835,20 +1835,20 @@ void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t RegScope rs(this); VReg value = AllocReg(); if (context_->IsTypeExtractorEnabled()) { - auto typeIndex = context_->TypeRecorder()->GetVariableTypeIndex(local); - if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - StoreAccumulatorWithType(node, typeIndex, value); - DCOUT << "[LOG]Lexical vreg in variable has type index: " << local->Name() << "@" << - local << " | " << typeIndex << std::endl; - StoreLexicalVar(node, level, slot, value); + auto fn = [&node, &level, &slot, &local, &value, this](auto typeIndex, const auto &tag) { + if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { + StoreAccumulatorWithType(node, typeIndex, value); + DCOUT << "[LOG]Lexical vreg in " << tag << " has type index: " << local->Name() << + "@" << local << " | " << typeIndex << std::endl; + StoreLexicalVar(node, level, slot, value); + return true; + } + return false; + }; + if (fn(context_->TypeRecorder()->GetVariableTypeIndex(local), "variable")) { return; } - typeIndex = context_->TypeRecorder()->GetNodeTypeIndex(node); - if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - StoreAccumulatorWithType(node, typeIndex, value); - DCOUT << "[LOG]Lexical vreg in declnode has type index: " << local->Name() << "@" << - local << " | " << typeIndex << std::endl; - StoreLexicalVar(node, level, slot, value); + if (fn(context_->TypeRecorder()->GetNodeTypeIndex(node), "declnode")) { return; } DCOUT << "[WARNING]Lexical vreg lose type index: " << local->Name() << "@" << local << std::endl; diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index ff98829d149df539b46d0183d3db48db9cc57824..8cf666701e13c4b81295b053c01fcea65dca4131 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -86,6 +86,7 @@ public: rootNode_(scope->Node()), insns_(allocator_->Adapter()), typedInsns_(allocator_->Adapter()), + typedVars_(allocator_->Adapter()), catchList_(allocator_->Adapter()), strings_(allocator_->Adapter()), buffStorage_(allocator_->Adapter()), @@ -156,6 +157,16 @@ public: return typedInsns_; } + ArenaUnorderedSet &TypedVars() + { + return typedVars_; + } + + const ArenaUnorderedSet &TypedVars() const + { + return typedVars_; + } + std::pair &TypedFunc() { return typedFunc_; @@ -501,6 +512,7 @@ private: const ir::AstNode *rootNode_; ArenaList insns_; ArenaMap typedInsns_; + ArenaUnorderedSet typedVars_; std::pair typedFunc_ {}; ArenaVector catchList_; ArenaSet strings_; diff --git a/es2panda/test/type_extractor/testcases_with_assert/test-function.ts b/es2panda/test/type_extractor/testcases_with_assert/test-function.ts new file mode 100644 index 0000000000000000000000000000000000000000..abf3ff9e0be87cf0c8ee5bd03e171dd06c49cb5a --- /dev/null +++ b/es2panda/test/type_extractor/testcases_with_assert/test-function.ts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +declare function AssertType(value:any, type:string):void; +{ + function p(num : number) : any { + if (num == 1) { + return 1; + } + return 2 + p(num - 1); + } + + let a : number = 1; + for (let i : number = 0 ; i < 10; i++) { + AssertType(a, "any"); + a = a + p(10); + } +}