13af6ab5fSopenharmony_ci/** 23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ci#include "destructuringContext.h" 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci#include "util/helpers.h" 193af6ab5fSopenharmony_ci#include "varbinder/scope.h" 203af6ab5fSopenharmony_ci#include "ir/typeNode.h" 213af6ab5fSopenharmony_ci#include "ir/expressions/identifier.h" 223af6ab5fSopenharmony_ci#include "ir/expressions/objectExpression.h" 233af6ab5fSopenharmony_ci#include "ir/expressions/assignmentExpression.h" 243af6ab5fSopenharmony_ci#include "ir/expressions/arrayExpression.h" 253af6ab5fSopenharmony_ci#include "ir/base/spreadElement.h" 263af6ab5fSopenharmony_ci#include "ir/base/property.h" 273af6ab5fSopenharmony_ci#include "ir/expression.h" 283af6ab5fSopenharmony_ci 293af6ab5fSopenharmony_cinamespace ark::es2panda::checker { 303af6ab5fSopenharmony_civoid DestructuringContext::Prepare(ir::TypeNode *typeAnnotation, ir::Expression *initializer, 313af6ab5fSopenharmony_ci const lexer::SourcePosition &loc) 323af6ab5fSopenharmony_ci{ 333af6ab5fSopenharmony_ci if (typeAnnotation != nullptr) { 343af6ab5fSopenharmony_ci typeAnnotation->Check(checker_); 353af6ab5fSopenharmony_ci Type *annotationType = typeAnnotation->GetType(checker_); 363af6ab5fSopenharmony_ci 373af6ab5fSopenharmony_ci if (initializer != nullptr) { 383af6ab5fSopenharmony_ci checker_->ElaborateElementwise(annotationType, initializer, loc); 393af6ab5fSopenharmony_ci } 403af6ab5fSopenharmony_ci 413af6ab5fSopenharmony_ci validateTypeAnnotation_ = true; 423af6ab5fSopenharmony_ci inferredType_ = annotationType; 433af6ab5fSopenharmony_ci return; 443af6ab5fSopenharmony_ci } 453af6ab5fSopenharmony_ci 463af6ab5fSopenharmony_ci if (initializer != nullptr) { 473af6ab5fSopenharmony_ci if (!initializer->IsObjectExpression()) { 483af6ab5fSopenharmony_ci validateObjectPatternInitializer_ = false; 493af6ab5fSopenharmony_ci } 503af6ab5fSopenharmony_ci 513af6ab5fSopenharmony_ci inferredType_ = initializer->Check(checker_); 523af6ab5fSopenharmony_ci } 533af6ab5fSopenharmony_ci} 543af6ab5fSopenharmony_ci 553af6ab5fSopenharmony_civoid DestructuringContext::HandleDestructuringAssignment(ir::Identifier *ident, Type *inferredType, Type *defaultType) 563af6ab5fSopenharmony_ci{ 573af6ab5fSopenharmony_ci if (ident->Variable() == nullptr) { 583af6ab5fSopenharmony_ci checker_->ThrowTypeError({"Cannot find name '", ident->Name(), "'."}, ident->Start()); 593af6ab5fSopenharmony_ci } 603af6ab5fSopenharmony_ci 613af6ab5fSopenharmony_ci varbinder::Variable *variable = ident->Variable(); 623af6ab5fSopenharmony_ci ASSERT(variable->TsType()); 633af6ab5fSopenharmony_ci 643af6ab5fSopenharmony_ci if (defaultType != nullptr && !checker_->IsTypeAssignableTo(defaultType, variable->TsType())) { 653af6ab5fSopenharmony_ci checker_->ThrowAssignmentError(defaultType, variable->TsType(), ident->Start()); 663af6ab5fSopenharmony_ci } 673af6ab5fSopenharmony_ci 683af6ab5fSopenharmony_ci if (inferredType != nullptr && !checker_->IsTypeAssignableTo(inferredType, variable->TsType())) { 693af6ab5fSopenharmony_ci checker_->ThrowAssignmentError(inferredType, variable->TsType(), ident->Start()); 703af6ab5fSopenharmony_ci } 713af6ab5fSopenharmony_ci} 723af6ab5fSopenharmony_ci 733af6ab5fSopenharmony_civoid DestructuringContext::SetInferredTypeForVariable(varbinder::Variable *var, Type *inferredType, 743af6ab5fSopenharmony_ci const lexer::SourcePosition &loc) 753af6ab5fSopenharmony_ci{ 763af6ab5fSopenharmony_ci ASSERT(var); 773af6ab5fSopenharmony_ci 783af6ab5fSopenharmony_ci if (!checker_->HasStatus(CheckerStatus::IN_CONST_CONTEXT)) { 793af6ab5fSopenharmony_ci inferredType = checker_->GetBaseTypeOfLiteralType(inferredType); 803af6ab5fSopenharmony_ci } 813af6ab5fSopenharmony_ci 823af6ab5fSopenharmony_ci if (var->TsType() != nullptr) { 833af6ab5fSopenharmony_ci checker_->IsTypeIdenticalTo(var->TsType(), inferredType, 843af6ab5fSopenharmony_ci {"Subsequent variable declaration must have the same type. Variable '", var->Name(), 853af6ab5fSopenharmony_ci "' must be of type '", var->TsType(), "', but here has type '", inferredType, 863af6ab5fSopenharmony_ci "'."}, 873af6ab5fSopenharmony_ci loc); 883af6ab5fSopenharmony_ci return; 893af6ab5fSopenharmony_ci } 903af6ab5fSopenharmony_ci 913af6ab5fSopenharmony_ci if (signatureInfo_ != nullptr) { 923af6ab5fSopenharmony_ci signatureInfo_->params.push_back(var->AsLocalVariable()); 933af6ab5fSopenharmony_ci signatureInfo_->minArgCount++; 943af6ab5fSopenharmony_ci } 953af6ab5fSopenharmony_ci 963af6ab5fSopenharmony_ci var->SetTsType(inferredType); 973af6ab5fSopenharmony_ci} 983af6ab5fSopenharmony_ci 993af6ab5fSopenharmony_civoid DestructuringContext::ValidateObjectLiteralType(ObjectType *objType, ir::ObjectExpression *objPattern) 1003af6ab5fSopenharmony_ci{ 1013af6ab5fSopenharmony_ci for (const auto *sourceProp : objType->Properties()) { 1023af6ab5fSopenharmony_ci const util::StringView &sourceName = sourceProp->Name(); 1033af6ab5fSopenharmony_ci bool found = false; 1043af6ab5fSopenharmony_ci 1053af6ab5fSopenharmony_ci for (const auto *targetProp : objPattern->Properties()) { 1063af6ab5fSopenharmony_ci if (targetProp->IsRestElement()) { 1073af6ab5fSopenharmony_ci continue; 1083af6ab5fSopenharmony_ci } 1093af6ab5fSopenharmony_ci 1103af6ab5fSopenharmony_ci ASSERT(targetProp->IsProperty()); 1113af6ab5fSopenharmony_ci const util::StringView &targetName = targetProp->AsProperty()->Key()->AsIdentifier()->Name(); 1123af6ab5fSopenharmony_ci 1133af6ab5fSopenharmony_ci if (sourceName == targetName) { 1143af6ab5fSopenharmony_ci found = true; 1153af6ab5fSopenharmony_ci break; 1163af6ab5fSopenharmony_ci } 1173af6ab5fSopenharmony_ci } 1183af6ab5fSopenharmony_ci 1193af6ab5fSopenharmony_ci if (!found) { 1203af6ab5fSopenharmony_ci checker_->ThrowTypeError({"Object literal may only specify known properties, and property '", sourceName, 1213af6ab5fSopenharmony_ci "' does not exist in the pattern."}, 1223af6ab5fSopenharmony_ci objPattern->Start()); 1233af6ab5fSopenharmony_ci } 1243af6ab5fSopenharmony_ci } 1253af6ab5fSopenharmony_ci} 1263af6ab5fSopenharmony_ci 1273af6ab5fSopenharmony_ci// Helper function to reduce HandleAssignmentPattern and pass code checker 1283af6ab5fSopenharmony_civoid DestructuringContext::HandleAssignmentPatternArrayPattern(ir::AssignmentExpression *assignmentPattern, 1293af6ab5fSopenharmony_ci Type *inferredType) 1303af6ab5fSopenharmony_ci{ 1313af6ab5fSopenharmony_ci ArrayDestructuringContext nextContext = ArrayDestructuringContext( 1323af6ab5fSopenharmony_ci {checker_, assignmentPattern->Left(), inAssignment_, convertTupleToArray_, nullptr, nullptr}); 1333af6ab5fSopenharmony_ci nextContext.SetInferredType(inferredType); 1343af6ab5fSopenharmony_ci nextContext.Start(); 1353af6ab5fSopenharmony_ci} 1363af6ab5fSopenharmony_ci 1373af6ab5fSopenharmony_ci// Helper function to reduce HandleAssignmentPattern and pass code checker 1383af6ab5fSopenharmony_civoid DestructuringContext::HandleAssignmentPatternIdentifier(ir::AssignmentExpression *assignmentPattern, 1393af6ab5fSopenharmony_ci Type *defaultType, Type *inferredType) 1403af6ab5fSopenharmony_ci{ 1413af6ab5fSopenharmony_ci if (validateTypeAnnotation_ && !checker_->IsTypeAssignableTo(defaultType, inferredType)) { 1423af6ab5fSopenharmony_ci checker_->ThrowAssignmentError(defaultType, inferredType, assignmentPattern->Left()->Start()); 1433af6ab5fSopenharmony_ci } 1443af6ab5fSopenharmony_ci 1453af6ab5fSopenharmony_ci SetInferredTypeForVariable(assignmentPattern->Left()->AsIdentifier()->Variable(), inferredType, 1463af6ab5fSopenharmony_ci assignmentPattern->Start()); 1473af6ab5fSopenharmony_ci} 1483af6ab5fSopenharmony_ci 1493af6ab5fSopenharmony_civoid DestructuringContext::HandleAssignmentPattern(ir::AssignmentExpression *assignmentPattern, Type *inferredType, 1503af6ab5fSopenharmony_ci bool validateDefault) 1513af6ab5fSopenharmony_ci{ 1523af6ab5fSopenharmony_ci if (!assignmentPattern->Left()->IsArrayPattern()) { 1533af6ab5fSopenharmony_ci checker_->RemoveStatus(CheckerStatus::FORCE_TUPLE); 1543af6ab5fSopenharmony_ci } 1553af6ab5fSopenharmony_ci 1563af6ab5fSopenharmony_ci Type *defaultType = assignmentPattern->Right()->Check(checker_); 1573af6ab5fSopenharmony_ci if (!checker_->HasStatus(CheckerStatus::IN_CONST_CONTEXT)) { 1583af6ab5fSopenharmony_ci defaultType = checker_->GetBaseTypeOfLiteralType(defaultType); 1593af6ab5fSopenharmony_ci } 1603af6ab5fSopenharmony_ci 1613af6ab5fSopenharmony_ci if (validateDefault && assignmentPattern->Right()->IsObjectExpression() && 1623af6ab5fSopenharmony_ci assignmentPattern->Left()->IsObjectPattern()) { 1633af6ab5fSopenharmony_ci ValidateObjectLiteralType(defaultType->AsObjectType(), assignmentPattern->Left()->AsObjectPattern()); 1643af6ab5fSopenharmony_ci } 1653af6ab5fSopenharmony_ci 1663af6ab5fSopenharmony_ci Type *initType = inferredType; 1673af6ab5fSopenharmony_ci checker_->AddStatus(CheckerStatus::FORCE_TUPLE); 1683af6ab5fSopenharmony_ci 1693af6ab5fSopenharmony_ci if (validateTypeAnnotation_) { 1703af6ab5fSopenharmony_ci if (inferredType == nullptr) { 1713af6ab5fSopenharmony_ci inferredType = checker_->GlobalUndefinedType(); 1723af6ab5fSopenharmony_ci } 1733af6ab5fSopenharmony_ci } else { 1743af6ab5fSopenharmony_ci if (inferredType == nullptr) { 1753af6ab5fSopenharmony_ci inferredType = defaultType; 1763af6ab5fSopenharmony_ci } else if (inferredType->IsUnionType()) { 1773af6ab5fSopenharmony_ci inferredType->AsUnionType()->AddConstituentType(defaultType, checker_->Relation()); 1783af6ab5fSopenharmony_ci } else { 1793af6ab5fSopenharmony_ci inferredType = checker_->CreateUnionType({inferredType, defaultType}); 1803af6ab5fSopenharmony_ci } 1813af6ab5fSopenharmony_ci } 1823af6ab5fSopenharmony_ci 1833af6ab5fSopenharmony_ci if (assignmentPattern->Left()->IsIdentifier()) { 1843af6ab5fSopenharmony_ci if (inAssignment_) { 1853af6ab5fSopenharmony_ci HandleDestructuringAssignment(assignmentPattern->Left()->AsIdentifier(), initType, defaultType); 1863af6ab5fSopenharmony_ci return; 1873af6ab5fSopenharmony_ci } 1883af6ab5fSopenharmony_ci 1893af6ab5fSopenharmony_ci HandleAssignmentPatternIdentifier(assignmentPattern, defaultType, inferredType); 1903af6ab5fSopenharmony_ci return; 1913af6ab5fSopenharmony_ci } 1923af6ab5fSopenharmony_ci 1933af6ab5fSopenharmony_ci if (assignmentPattern->Left()->IsArrayPattern()) { 1943af6ab5fSopenharmony_ci HandleAssignmentPatternArrayPattern(assignmentPattern, inferredType); 1953af6ab5fSopenharmony_ci return; 1963af6ab5fSopenharmony_ci } 1973af6ab5fSopenharmony_ci 1983af6ab5fSopenharmony_ci ASSERT(assignmentPattern->Left()->IsObjectPattern()); 1993af6ab5fSopenharmony_ci ObjectDestructuringContext nextContext = ObjectDestructuringContext( 2003af6ab5fSopenharmony_ci {checker_, assignmentPattern->Left(), inAssignment_, convertTupleToArray_, nullptr, nullptr}); 2013af6ab5fSopenharmony_ci nextContext.SetInferredType(inferredType); 2023af6ab5fSopenharmony_ci nextContext.Start(); 2033af6ab5fSopenharmony_ci} 2043af6ab5fSopenharmony_ci 2053af6ab5fSopenharmony_civoid ArrayDestructuringContext::ValidateInferredType() 2063af6ab5fSopenharmony_ci{ 2073af6ab5fSopenharmony_ci if (!inferredType_->IsArrayType() && !inferredType_->IsUnionType() && 2083af6ab5fSopenharmony_ci (!inferredType_->IsObjectType() || !inferredType_->AsObjectType()->IsTupleType())) { 2093af6ab5fSopenharmony_ci checker_->ThrowTypeError( 2103af6ab5fSopenharmony_ci {"Type ", inferredType_, " must have a '[Symbol.iterator]()' method that returns an iterator."}, 2113af6ab5fSopenharmony_ci id_->Start()); 2123af6ab5fSopenharmony_ci } 2133af6ab5fSopenharmony_ci 2143af6ab5fSopenharmony_ci if (inferredType_->IsUnionType()) { 2153af6ab5fSopenharmony_ci for (auto *it : inferredType_->AsUnionType()->ConstituentTypes()) { 2163af6ab5fSopenharmony_ci if (!it->IsArrayType() && (!it->IsObjectType() || !it->AsObjectType()->IsTupleType())) { 2173af6ab5fSopenharmony_ci checker_->ThrowTypeError( 2183af6ab5fSopenharmony_ci {"Type ", inferredType_, " must have a '[Symbol.iterator]()' method that returns an iterator."}, 2193af6ab5fSopenharmony_ci id_->Start()); 2203af6ab5fSopenharmony_ci } 2213af6ab5fSopenharmony_ci } 2223af6ab5fSopenharmony_ci } 2233af6ab5fSopenharmony_ci} 2243af6ab5fSopenharmony_ci 2253af6ab5fSopenharmony_ciType *ArrayDestructuringContext::GetTypeFromTupleByIndex(TupleType *tuple) 2263af6ab5fSopenharmony_ci{ 2273af6ab5fSopenharmony_ci util::StringView memberIndex = util::Helpers::ToStringView(checker_->Allocator(), index_); 2283af6ab5fSopenharmony_ci varbinder::Variable *memberVar = tuple->GetProperty(memberIndex, false); 2293af6ab5fSopenharmony_ci 2303af6ab5fSopenharmony_ci if (memberVar == nullptr) { 2313af6ab5fSopenharmony_ci return nullptr; 2323af6ab5fSopenharmony_ci } 2333af6ab5fSopenharmony_ci 2343af6ab5fSopenharmony_ci return memberVar->TsType(); 2353af6ab5fSopenharmony_ci} 2363af6ab5fSopenharmony_ci 2373af6ab5fSopenharmony_ciType *ArrayDestructuringContext::NextInferredType([[maybe_unused]] const util::StringView &searchName, bool throwError) 2383af6ab5fSopenharmony_ci{ 2393af6ab5fSopenharmony_ci if (inferredType_->IsArrayType()) { 2403af6ab5fSopenharmony_ci return inferredType_->AsArrayType()->ElementType(); 2413af6ab5fSopenharmony_ci } 2423af6ab5fSopenharmony_ci 2433af6ab5fSopenharmony_ci if (inferredType_->IsObjectType()) { 2443af6ab5fSopenharmony_ci ASSERT(inferredType_->AsObjectType()->IsTupleType()); 2453af6ab5fSopenharmony_ci Type *returnType = GetTypeFromTupleByIndex(inferredType_->AsObjectType()->AsTupleType()); 2463af6ab5fSopenharmony_ci 2473af6ab5fSopenharmony_ci if (returnType == nullptr && throwError) { 2483af6ab5fSopenharmony_ci if (!validateTypeAnnotation_ && checker_->HasStatus(CheckerStatus::IN_PARAMETER)) { 2493af6ab5fSopenharmony_ci return returnType; 2503af6ab5fSopenharmony_ci } 2513af6ab5fSopenharmony_ci 2523af6ab5fSopenharmony_ci checker_->ThrowTypeError({"Tuple type ", inferredType_, " of length ", 2533af6ab5fSopenharmony_ci inferredType_->AsObjectType()->AsTupleType()->FixedLength(), 2543af6ab5fSopenharmony_ci " has no element at index ", index_, "."}, 2553af6ab5fSopenharmony_ci id_->Start()); 2563af6ab5fSopenharmony_ci } 2573af6ab5fSopenharmony_ci 2583af6ab5fSopenharmony_ci return returnType; 2593af6ab5fSopenharmony_ci } 2603af6ab5fSopenharmony_ci 2613af6ab5fSopenharmony_ci ASSERT(inferredType_->IsUnionType()); 2623af6ab5fSopenharmony_ci 2633af6ab5fSopenharmony_ci ArenaVector<Type *> unionTypes(checker_->Allocator()->Adapter()); 2643af6ab5fSopenharmony_ci 2653af6ab5fSopenharmony_ci for (auto *type : inferredType_->AsUnionType()->ConstituentTypes()) { 2663af6ab5fSopenharmony_ci if (type->IsArrayType()) { 2673af6ab5fSopenharmony_ci unionTypes.push_back(type->AsArrayType()->ElementType()); 2683af6ab5fSopenharmony_ci continue; 2693af6ab5fSopenharmony_ci } 2703af6ab5fSopenharmony_ci 2713af6ab5fSopenharmony_ci ASSERT(type->IsObjectType() && type->AsObjectType()->IsTupleType()); 2723af6ab5fSopenharmony_ci Type *elementType = GetTypeFromTupleByIndex(type->AsObjectType()->AsTupleType()); 2733af6ab5fSopenharmony_ci 2743af6ab5fSopenharmony_ci if (elementType == nullptr) { 2753af6ab5fSopenharmony_ci continue; 2763af6ab5fSopenharmony_ci } 2773af6ab5fSopenharmony_ci 2783af6ab5fSopenharmony_ci unionTypes.push_back(elementType); 2793af6ab5fSopenharmony_ci } 2803af6ab5fSopenharmony_ci 2813af6ab5fSopenharmony_ci if (unionTypes.empty()) { 2823af6ab5fSopenharmony_ci if (throwError) { 2833af6ab5fSopenharmony_ci checker_->ThrowTypeError({"Property ", index_, " does not exist on type ", inferredType_, "."}, 2843af6ab5fSopenharmony_ci id_->Start()); 2853af6ab5fSopenharmony_ci } 2863af6ab5fSopenharmony_ci 2873af6ab5fSopenharmony_ci return nullptr; 2883af6ab5fSopenharmony_ci } 2893af6ab5fSopenharmony_ci 2903af6ab5fSopenharmony_ci return checker_->CreateUnionType(std::move(unionTypes)); 2913af6ab5fSopenharmony_ci} 2923af6ab5fSopenharmony_ci 2933af6ab5fSopenharmony_ciType *ArrayDestructuringContext::CreateArrayTypeForRest(UnionType *inferredType) 2943af6ab5fSopenharmony_ci{ 2953af6ab5fSopenharmony_ci ArenaVector<Type *> unionTypes(checker_->Allocator()->Adapter()); 2963af6ab5fSopenharmony_ci uint32_t savedIdx = index_; 2973af6ab5fSopenharmony_ci 2983af6ab5fSopenharmony_ci for (auto *it : inferredType->ConstituentTypes()) { 2993af6ab5fSopenharmony_ci if (it->IsArrayType()) { 3003af6ab5fSopenharmony_ci unionTypes.push_back(it->AsArrayType()->ElementType()); 3013af6ab5fSopenharmony_ci continue; 3023af6ab5fSopenharmony_ci } 3033af6ab5fSopenharmony_ci 3043af6ab5fSopenharmony_ci ASSERT(it->IsObjectType() && it->AsObjectType()->IsTupleType()); 3053af6ab5fSopenharmony_ci Type *tupleElementType = GetTypeFromTupleByIndex(it->AsObjectType()->AsTupleType()); 3063af6ab5fSopenharmony_ci 3073af6ab5fSopenharmony_ci while (tupleElementType != nullptr) { 3083af6ab5fSopenharmony_ci unionTypes.push_back(tupleElementType); 3093af6ab5fSopenharmony_ci index_++; 3103af6ab5fSopenharmony_ci tupleElementType = GetTypeFromTupleByIndex(it->AsObjectType()->AsTupleType()); 3113af6ab5fSopenharmony_ci } 3123af6ab5fSopenharmony_ci 3133af6ab5fSopenharmony_ci index_ = savedIdx; 3143af6ab5fSopenharmony_ci } 3153af6ab5fSopenharmony_ci 3163af6ab5fSopenharmony_ci Type *restArrayElementType = checker_->CreateUnionType(std::move(unionTypes)); 3173af6ab5fSopenharmony_ci return checker_->Allocator()->New<ArrayType>(restArrayElementType); 3183af6ab5fSopenharmony_ci} 3193af6ab5fSopenharmony_ci 3203af6ab5fSopenharmony_ciType *ArrayDestructuringContext::CreateTupleTypeForRest(TupleType *tuple) 3213af6ab5fSopenharmony_ci{ 3223af6ab5fSopenharmony_ci ObjectDescriptor *desc = checker_->Allocator()->New<ObjectDescriptor>(checker_->Allocator()); 3233af6ab5fSopenharmony_ci ArenaVector<ElementFlags> elementFlags(checker_->Allocator()->Adapter()); 3243af6ab5fSopenharmony_ci uint32_t savedIdx = index_; 3253af6ab5fSopenharmony_ci uint32_t iterIndex = 0; 3263af6ab5fSopenharmony_ci 3273af6ab5fSopenharmony_ci Type *tupleElementType = GetTypeFromTupleByIndex(tuple); 3283af6ab5fSopenharmony_ci 3293af6ab5fSopenharmony_ci while (tupleElementType != nullptr) { 3303af6ab5fSopenharmony_ci ElementFlags memberFlag = ElementFlags::REQUIRED; 3313af6ab5fSopenharmony_ci util::StringView memberIndex = util::Helpers::ToStringView(checker_->Allocator(), iterIndex); 3323af6ab5fSopenharmony_ci auto *memberVar = varbinder::Scope::CreateVar(checker_->Allocator(), memberIndex, 3333af6ab5fSopenharmony_ci varbinder::VariableFlags::PROPERTY, nullptr); 3343af6ab5fSopenharmony_ci memberVar->SetTsType(tupleElementType); 3353af6ab5fSopenharmony_ci elementFlags.push_back(memberFlag); 3363af6ab5fSopenharmony_ci desc->properties.push_back(memberVar); 3373af6ab5fSopenharmony_ci 3383af6ab5fSopenharmony_ci index_++; 3393af6ab5fSopenharmony_ci iterIndex++; 3403af6ab5fSopenharmony_ci 3413af6ab5fSopenharmony_ci tupleElementType = GetTypeFromTupleByIndex(tuple); 3423af6ab5fSopenharmony_ci } 3433af6ab5fSopenharmony_ci 3443af6ab5fSopenharmony_ci index_ = savedIdx; 3453af6ab5fSopenharmony_ci const checker::TupleTypeInfo tupleTypeInfo = {ElementFlags::REQUIRED, iterIndex, iterIndex, false}; 3463af6ab5fSopenharmony_ci return checker_->CreateTupleType(desc, std::move(elementFlags), tupleTypeInfo); 3473af6ab5fSopenharmony_ci} 3483af6ab5fSopenharmony_ci 3493af6ab5fSopenharmony_ciType *ArrayDestructuringContext::GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) 3503af6ab5fSopenharmony_ci{ 3513af6ab5fSopenharmony_ci if (inferredType_->IsArrayType()) { 3523af6ab5fSopenharmony_ci return inferredType_; 3533af6ab5fSopenharmony_ci } 3543af6ab5fSopenharmony_ci 3553af6ab5fSopenharmony_ci if (inferredType_->IsObjectType() && inferredType_->AsObjectType()->IsTupleType()) { 3563af6ab5fSopenharmony_ci return CreateTupleTypeForRest(inferredType_->AsObjectType()->AsTupleType()); 3573af6ab5fSopenharmony_ci } 3583af6ab5fSopenharmony_ci 3593af6ab5fSopenharmony_ci ASSERT(inferredType_->IsUnionType()); 3603af6ab5fSopenharmony_ci bool createArrayType = false; 3613af6ab5fSopenharmony_ci 3623af6ab5fSopenharmony_ci for (auto *it : inferredType_->AsUnionType()->ConstituentTypes()) { 3633af6ab5fSopenharmony_ci if (it->IsArrayType()) { 3643af6ab5fSopenharmony_ci createArrayType = true; 3653af6ab5fSopenharmony_ci break; 3663af6ab5fSopenharmony_ci } 3673af6ab5fSopenharmony_ci } 3683af6ab5fSopenharmony_ci 3693af6ab5fSopenharmony_ci if (createArrayType) { 3703af6ab5fSopenharmony_ci return CreateArrayTypeForRest(inferredType_->AsUnionType()); 3713af6ab5fSopenharmony_ci } 3723af6ab5fSopenharmony_ci 3733af6ab5fSopenharmony_ci ArenaVector<Type *> tupleUnion(checker_->Allocator()->Adapter()); 3743af6ab5fSopenharmony_ci 3753af6ab5fSopenharmony_ci for (auto *it : inferredType_->AsUnionType()->ConstituentTypes()) { 3763af6ab5fSopenharmony_ci ASSERT(it->IsObjectType() && it->AsObjectType()->IsTupleType()); 3773af6ab5fSopenharmony_ci Type *newTuple = CreateTupleTypeForRest(it->AsObjectType()->AsTupleType()); 3783af6ab5fSopenharmony_ci tupleUnion.push_back(newTuple); 3793af6ab5fSopenharmony_ci } 3803af6ab5fSopenharmony_ci 3813af6ab5fSopenharmony_ci return checker_->CreateUnionType(std::move(tupleUnion)); 3823af6ab5fSopenharmony_ci} 3833af6ab5fSopenharmony_ci 3843af6ab5fSopenharmony_civoid ArrayDestructuringContext::HandleRest(ir::SpreadElement *rest) 3853af6ab5fSopenharmony_ci{ 3863af6ab5fSopenharmony_ci Type *inferredRestType = GetRestType(rest->Start()); 3873af6ab5fSopenharmony_ci 3883af6ab5fSopenharmony_ci if (rest->Argument()->IsIdentifier()) { 3893af6ab5fSopenharmony_ci if (inAssignment_) { 3903af6ab5fSopenharmony_ci HandleDestructuringAssignment(rest->Argument()->AsIdentifier(), inferredRestType, nullptr); 3913af6ab5fSopenharmony_ci return; 3923af6ab5fSopenharmony_ci } 3933af6ab5fSopenharmony_ci 3943af6ab5fSopenharmony_ci SetInferredTypeForVariable(rest->Argument()->AsIdentifier()->Variable(), inferredRestType, rest->Start()); 3953af6ab5fSopenharmony_ci return; 3963af6ab5fSopenharmony_ci } 3973af6ab5fSopenharmony_ci 3983af6ab5fSopenharmony_ci if (rest->Argument()->IsArrayPattern()) { 3993af6ab5fSopenharmony_ci ArrayDestructuringContext nextContext = ArrayDestructuringContext( 4003af6ab5fSopenharmony_ci {checker_, rest->Argument(), inAssignment_, convertTupleToArray_, nullptr, nullptr}); 4013af6ab5fSopenharmony_ci nextContext.SetInferredType(inferredRestType); 4023af6ab5fSopenharmony_ci nextContext.Start(); 4033af6ab5fSopenharmony_ci return; 4043af6ab5fSopenharmony_ci } 4053af6ab5fSopenharmony_ci 4063af6ab5fSopenharmony_ci ASSERT(rest->Argument()->IsObjectPattern()); 4073af6ab5fSopenharmony_ci ObjectDestructuringContext nextContext = 4083af6ab5fSopenharmony_ci ObjectDestructuringContext({checker_, rest->Argument(), inAssignment_, convertTupleToArray_, nullptr, nullptr}); 4093af6ab5fSopenharmony_ci nextContext.SetInferredType(inferredRestType); 4103af6ab5fSopenharmony_ci nextContext.Start(); 4113af6ab5fSopenharmony_ci} 4123af6ab5fSopenharmony_ci 4133af6ab5fSopenharmony_ciType *ArrayDestructuringContext::ConvertTupleTypeToArrayTypeIfNecessary(ir::AstNode *node, Type *type) 4143af6ab5fSopenharmony_ci{ 4153af6ab5fSopenharmony_ci if (!convertTupleToArray_) { 4163af6ab5fSopenharmony_ci return type; 4173af6ab5fSopenharmony_ci } 4183af6ab5fSopenharmony_ci 4193af6ab5fSopenharmony_ci if (type == nullptr) { 4203af6ab5fSopenharmony_ci return type; 4213af6ab5fSopenharmony_ci } 4223af6ab5fSopenharmony_ci 4233af6ab5fSopenharmony_ci if (node->IsArrayPattern() || 4243af6ab5fSopenharmony_ci (node->IsAssignmentPattern() && node->AsAssignmentPattern()->Left()->IsArrayPattern())) { 4253af6ab5fSopenharmony_ci return type; 4263af6ab5fSopenharmony_ci } 4273af6ab5fSopenharmony_ci 4283af6ab5fSopenharmony_ci if (type->IsObjectType() && type->AsObjectType()->IsTupleType()) { 4293af6ab5fSopenharmony_ci return type->AsObjectType()->AsTupleType()->ConvertToArrayType(checker_); 4303af6ab5fSopenharmony_ci } 4313af6ab5fSopenharmony_ci 4323af6ab5fSopenharmony_ci return type; 4333af6ab5fSopenharmony_ci} 4343af6ab5fSopenharmony_ci 4353af6ab5fSopenharmony_cistatic void SetParameterType(ir::AstNode *parent, Type *type) 4363af6ab5fSopenharmony_ci{ 4373af6ab5fSopenharmony_ci parent->Iterate([type](ir::AstNode *childNode) -> void { 4383af6ab5fSopenharmony_ci if (childNode->IsIdentifier() && childNode->AsIdentifier()->Variable() != nullptr) { 4393af6ab5fSopenharmony_ci childNode->AsIdentifier()->Variable()->SetTsType(type); 4403af6ab5fSopenharmony_ci return; 4413af6ab5fSopenharmony_ci } 4423af6ab5fSopenharmony_ci 4433af6ab5fSopenharmony_ci SetParameterType(childNode, type); 4443af6ab5fSopenharmony_ci }); 4453af6ab5fSopenharmony_ci} 4463af6ab5fSopenharmony_ci 4473af6ab5fSopenharmony_civoid ArrayDestructuringContext::SetRemainingParameterTypes() 4483af6ab5fSopenharmony_ci{ 4493af6ab5fSopenharmony_ci do { 4503af6ab5fSopenharmony_ci auto *it = id_->AsArrayPattern()->Elements()[index_]; 4513af6ab5fSopenharmony_ci ASSERT(it); 4523af6ab5fSopenharmony_ci SetParameterType(it, checker_->GlobalAnyType()); 4533af6ab5fSopenharmony_ci } while (++index_ != id_->AsArrayPattern()->Elements().size()); 4543af6ab5fSopenharmony_ci} 4553af6ab5fSopenharmony_ci 4563af6ab5fSopenharmony_civoid ArrayDestructuringContext::HandleElement(ir::Expression *element, Type *nextInferredType) 4573af6ab5fSopenharmony_ci{ 4583af6ab5fSopenharmony_ci switch (element->Type()) { 4593af6ab5fSopenharmony_ci case ir::AstNodeType::IDENTIFIER: { 4603af6ab5fSopenharmony_ci if (inAssignment_) { 4613af6ab5fSopenharmony_ci HandleDestructuringAssignment(element->AsIdentifier(), nextInferredType, nullptr); 4623af6ab5fSopenharmony_ci break; 4633af6ab5fSopenharmony_ci } 4643af6ab5fSopenharmony_ci 4653af6ab5fSopenharmony_ci SetInferredTypeForVariable(element->AsIdentifier()->Variable(), nextInferredType, element->Start()); 4663af6ab5fSopenharmony_ci break; 4673af6ab5fSopenharmony_ci } 4683af6ab5fSopenharmony_ci case ir::AstNodeType::ARRAY_PATTERN: { 4693af6ab5fSopenharmony_ci ArrayDestructuringContext nextContext = 4703af6ab5fSopenharmony_ci ArrayDestructuringContext({checker_, element, inAssignment_, convertTupleToArray_, nullptr, nullptr}); 4713af6ab5fSopenharmony_ci nextContext.SetInferredType(nextInferredType); 4723af6ab5fSopenharmony_ci nextContext.Start(); 4733af6ab5fSopenharmony_ci break; 4743af6ab5fSopenharmony_ci } 4753af6ab5fSopenharmony_ci case ir::AstNodeType::OBJECT_PATTERN: { 4763af6ab5fSopenharmony_ci ObjectDestructuringContext nextContext = 4773af6ab5fSopenharmony_ci ObjectDestructuringContext({checker_, element, inAssignment_, convertTupleToArray_, nullptr, nullptr}); 4783af6ab5fSopenharmony_ci nextContext.SetInferredType(nextInferredType); 4793af6ab5fSopenharmony_ci nextContext.Start(); 4803af6ab5fSopenharmony_ci break; 4813af6ab5fSopenharmony_ci } 4823af6ab5fSopenharmony_ci case ir::AstNodeType::ASSIGNMENT_PATTERN: { 4833af6ab5fSopenharmony_ci HandleAssignmentPattern(element->AsAssignmentPattern(), nextInferredType, false); 4843af6ab5fSopenharmony_ci break; 4853af6ab5fSopenharmony_ci } 4863af6ab5fSopenharmony_ci case ir::AstNodeType::OMITTED_EXPRESSION: { 4873af6ab5fSopenharmony_ci break; 4883af6ab5fSopenharmony_ci } 4893af6ab5fSopenharmony_ci default: { 4903af6ab5fSopenharmony_ci UNREACHABLE(); 4913af6ab5fSopenharmony_ci } 4923af6ab5fSopenharmony_ci } 4933af6ab5fSopenharmony_ci} 4943af6ab5fSopenharmony_ci 4953af6ab5fSopenharmony_civoid ArrayDestructuringContext::Start() 4963af6ab5fSopenharmony_ci{ 4973af6ab5fSopenharmony_ci ASSERT(id_->IsArrayPattern()); 4983af6ab5fSopenharmony_ci 4993af6ab5fSopenharmony_ci ValidateInferredType(); 5003af6ab5fSopenharmony_ci 5013af6ab5fSopenharmony_ci util::StringView name = util::Helpers::ToStringView(checker_->Allocator(), 0); 5023af6ab5fSopenharmony_ci 5033af6ab5fSopenharmony_ci for (auto *it : id_->AsArrayPattern()->Elements()) { 5043af6ab5fSopenharmony_ci if (it->IsRestElement()) { 5053af6ab5fSopenharmony_ci HandleRest(it->AsRestElement()); 5063af6ab5fSopenharmony_ci break; 5073af6ab5fSopenharmony_ci } 5083af6ab5fSopenharmony_ci 5093af6ab5fSopenharmony_ci Type *nextInferredType = 5103af6ab5fSopenharmony_ci ConvertTupleTypeToArrayTypeIfNecessary(it, NextInferredType(name, !it->IsAssignmentPattern())); 5113af6ab5fSopenharmony_ci 5123af6ab5fSopenharmony_ci if (nextInferredType == nullptr && checker_->HasStatus(CheckerStatus::IN_PARAMETER)) { 5133af6ab5fSopenharmony_ci SetRemainingParameterTypes(); 5143af6ab5fSopenharmony_ci return; 5153af6ab5fSopenharmony_ci } 5163af6ab5fSopenharmony_ci 5173af6ab5fSopenharmony_ci if (convertTupleToArray_ && nextInferredType != nullptr && inferredType_->IsObjectType()) { 5183af6ab5fSopenharmony_ci ASSERT(inferredType_->AsObjectType()->IsTupleType()); 5193af6ab5fSopenharmony_ci 5203af6ab5fSopenharmony_ci varbinder::Variable *currentTupleElement = inferredType_->AsObjectType()->Properties()[index_]; 5213af6ab5fSopenharmony_ci 5223af6ab5fSopenharmony_ci if (currentTupleElement != nullptr) { 5233af6ab5fSopenharmony_ci currentTupleElement->SetTsType(nextInferredType); 5243af6ab5fSopenharmony_ci } 5253af6ab5fSopenharmony_ci } 5263af6ab5fSopenharmony_ci 5273af6ab5fSopenharmony_ci HandleElement(it, nextInferredType); 5283af6ab5fSopenharmony_ci index_++; 5293af6ab5fSopenharmony_ci } 5303af6ab5fSopenharmony_ci} 5313af6ab5fSopenharmony_ci 5323af6ab5fSopenharmony_civoid ObjectDestructuringContext::ValidateInferredType() 5333af6ab5fSopenharmony_ci{ 5343af6ab5fSopenharmony_ci if (!inferredType_->IsObjectType()) { 5353af6ab5fSopenharmony_ci return; 5363af6ab5fSopenharmony_ci } 5373af6ab5fSopenharmony_ci 5383af6ab5fSopenharmony_ci ValidateObjectLiteralType(inferredType_->AsObjectType(), id_->AsObjectPattern()); 5393af6ab5fSopenharmony_ci} 5403af6ab5fSopenharmony_ci 5413af6ab5fSopenharmony_civoid ObjectDestructuringContext::HandleRest(ir::SpreadElement *rest) 5423af6ab5fSopenharmony_ci{ 5433af6ab5fSopenharmony_ci Type *inferredRestType = GetRestType(rest->Start()); 5443af6ab5fSopenharmony_ci ASSERT(rest->Argument()->IsIdentifier()); 5453af6ab5fSopenharmony_ci 5463af6ab5fSopenharmony_ci if (inAssignment_) { 5473af6ab5fSopenharmony_ci HandleDestructuringAssignment(rest->Argument()->AsIdentifier(), inferredRestType, nullptr); 5483af6ab5fSopenharmony_ci return; 5493af6ab5fSopenharmony_ci } 5503af6ab5fSopenharmony_ci 5513af6ab5fSopenharmony_ci SetInferredTypeForVariable(rest->Argument()->AsIdentifier()->Variable(), inferredRestType, rest->Start()); 5523af6ab5fSopenharmony_ci} 5533af6ab5fSopenharmony_ci 5543af6ab5fSopenharmony_ciType *ObjectDestructuringContext::CreateObjectTypeForRest(ObjectType *objType) 5553af6ab5fSopenharmony_ci{ 5563af6ab5fSopenharmony_ci ObjectDescriptor *desc = checker_->Allocator()->New<ObjectDescriptor>(checker_->Allocator()); 5573af6ab5fSopenharmony_ci 5583af6ab5fSopenharmony_ci for (auto *it : objType->AsObjectType()->Properties()) { 5593af6ab5fSopenharmony_ci if (!it->HasFlag(varbinder::VariableFlags::INFERRED_IN_PATTERN)) { 5603af6ab5fSopenharmony_ci auto *memberVar = 5613af6ab5fSopenharmony_ci varbinder::Scope::CreateVar(checker_->Allocator(), it->Name(), varbinder::VariableFlags::NONE, nullptr); 5623af6ab5fSopenharmony_ci memberVar->SetTsType(it->TsType()); 5633af6ab5fSopenharmony_ci memberVar->AddFlag(it->Flags()); 5643af6ab5fSopenharmony_ci desc->properties.push_back(memberVar); 5653af6ab5fSopenharmony_ci } 5663af6ab5fSopenharmony_ci } 5673af6ab5fSopenharmony_ci 5683af6ab5fSopenharmony_ci Type *returnType = checker_->Allocator()->New<ObjectLiteralType>(desc); 5693af6ab5fSopenharmony_ci returnType->AsObjectType()->AddObjectFlag(ObjectFlags::RESOLVED_MEMBERS); 5703af6ab5fSopenharmony_ci return returnType; 5713af6ab5fSopenharmony_ci} 5723af6ab5fSopenharmony_ci 5733af6ab5fSopenharmony_ciType *ObjectDestructuringContext::GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) 5743af6ab5fSopenharmony_ci{ 5753af6ab5fSopenharmony_ci if (inferredType_->IsUnionType()) { 5763af6ab5fSopenharmony_ci ArenaVector<Type *> unionTypes(checker_->Allocator()->Adapter()); 5773af6ab5fSopenharmony_ci 5783af6ab5fSopenharmony_ci for (auto *it : inferredType_->AsUnionType()->ConstituentTypes()) { 5793af6ab5fSopenharmony_ci if (it->IsObjectType()) { 5803af6ab5fSopenharmony_ci unionTypes.push_back(CreateObjectTypeForRest(it->AsObjectType())); 5813af6ab5fSopenharmony_ci continue; 5823af6ab5fSopenharmony_ci } 5833af6ab5fSopenharmony_ci 5843af6ab5fSopenharmony_ci checker_->ThrowTypeError("Rest types may only be created from object types.", loc); 5853af6ab5fSopenharmony_ci } 5863af6ab5fSopenharmony_ci 5873af6ab5fSopenharmony_ci return checker_->CreateUnionType(std::move(unionTypes)); 5883af6ab5fSopenharmony_ci } 5893af6ab5fSopenharmony_ci 5903af6ab5fSopenharmony_ci if (inferredType_->IsObjectType()) { 5913af6ab5fSopenharmony_ci return CreateObjectTypeForRest(inferredType_->AsObjectType()); 5923af6ab5fSopenharmony_ci } 5933af6ab5fSopenharmony_ci 5943af6ab5fSopenharmony_ci checker_->ThrowTypeError("Rest types may only be created from object types.", loc); 5953af6ab5fSopenharmony_ci} 5963af6ab5fSopenharmony_ci 5973af6ab5fSopenharmony_ciType *ObjectDestructuringContext::ConvertTupleTypeToArrayTypeIfNecessary(ir::AstNode *node, Type *type) 5983af6ab5fSopenharmony_ci{ 5993af6ab5fSopenharmony_ci if (!convertTupleToArray_) { 6003af6ab5fSopenharmony_ci return type; 6013af6ab5fSopenharmony_ci } 6023af6ab5fSopenharmony_ci 6033af6ab5fSopenharmony_ci if (type == nullptr) { 6043af6ab5fSopenharmony_ci return type; 6053af6ab5fSopenharmony_ci } 6063af6ab5fSopenharmony_ci 6073af6ab5fSopenharmony_ci ASSERT(node->IsProperty()); 6083af6ab5fSopenharmony_ci 6093af6ab5fSopenharmony_ci ir::Property *property = node->AsProperty(); 6103af6ab5fSopenharmony_ci 6113af6ab5fSopenharmony_ci if (property->Value()->IsArrayPattern()) { 6123af6ab5fSopenharmony_ci return type; 6133af6ab5fSopenharmony_ci } 6143af6ab5fSopenharmony_ci 6153af6ab5fSopenharmony_ci if (property->Value()->IsAssignmentPattern() && 6163af6ab5fSopenharmony_ci property->Value()->AsAssignmentPattern()->Left()->IsArrayPattern()) { 6173af6ab5fSopenharmony_ci return type; 6183af6ab5fSopenharmony_ci } 6193af6ab5fSopenharmony_ci 6203af6ab5fSopenharmony_ci if (type->IsObjectType() && type->AsObjectType()->IsTupleType()) { 6213af6ab5fSopenharmony_ci return type->AsObjectType()->AsTupleType()->ConvertToArrayType(checker_); 6223af6ab5fSopenharmony_ci } 6233af6ab5fSopenharmony_ci 6243af6ab5fSopenharmony_ci return type; 6253af6ab5fSopenharmony_ci} 6263af6ab5fSopenharmony_ci 6273af6ab5fSopenharmony_ciType *ObjectDestructuringContext::NextInferredType([[maybe_unused]] const util::StringView &searchName, bool throwError) 6283af6ab5fSopenharmony_ci{ 6293af6ab5fSopenharmony_ci varbinder::Variable *prop = checker_->GetPropertyOfType(inferredType_, searchName, !throwError, 6303af6ab5fSopenharmony_ci varbinder::VariableFlags::INFERRED_IN_PATTERN); 6313af6ab5fSopenharmony_ci 6323af6ab5fSopenharmony_ci if (prop != nullptr) { 6333af6ab5fSopenharmony_ci prop->AddFlag(varbinder::VariableFlags::INFERRED_IN_PATTERN); 6343af6ab5fSopenharmony_ci return prop->TsType(); 6353af6ab5fSopenharmony_ci } 6363af6ab5fSopenharmony_ci 6373af6ab5fSopenharmony_ci if (inferredType_->IsObjectType()) { 6383af6ab5fSopenharmony_ci checker::ObjectType *objType = inferredType_->AsObjectType(); 6393af6ab5fSopenharmony_ci 6403af6ab5fSopenharmony_ci if (objType->StringIndexInfo() != nullptr) { 6413af6ab5fSopenharmony_ci return objType->StringIndexInfo()->GetType(); 6423af6ab5fSopenharmony_ci } 6433af6ab5fSopenharmony_ci } 6443af6ab5fSopenharmony_ci 6453af6ab5fSopenharmony_ci if (throwError) { 6463af6ab5fSopenharmony_ci checker_->ThrowTypeError({"Property ", searchName, " does not exist on type ", inferredType_, "."}, 6473af6ab5fSopenharmony_ci id_->Start()); 6483af6ab5fSopenharmony_ci } 6493af6ab5fSopenharmony_ci 6503af6ab5fSopenharmony_ci return nullptr; 6513af6ab5fSopenharmony_ci} 6523af6ab5fSopenharmony_ci 6533af6ab5fSopenharmony_civoid ObjectDestructuringContext::Start() 6543af6ab5fSopenharmony_ci{ 6553af6ab5fSopenharmony_ci ASSERT(id_->IsObjectPattern()); 6563af6ab5fSopenharmony_ci 6573af6ab5fSopenharmony_ci if (!id_->AsObjectPattern()->Properties().back()->IsRestElement() && validateObjectPatternInitializer_) { 6583af6ab5fSopenharmony_ci ValidateInferredType(); 6593af6ab5fSopenharmony_ci } 6603af6ab5fSopenharmony_ci 6613af6ab5fSopenharmony_ci for (auto *it : id_->AsObjectPattern()->Properties()) { 6623af6ab5fSopenharmony_ci switch (it->Type()) { 6633af6ab5fSopenharmony_ci case ir::AstNodeType::PROPERTY: { 6643af6ab5fSopenharmony_ci ir::Property *property = it->AsProperty(); 6653af6ab5fSopenharmony_ci 6663af6ab5fSopenharmony_ci if (property->IsComputed()) { 6673af6ab5fSopenharmony_ci // NOTE: aszilagyi. 6683af6ab5fSopenharmony_ci return; 6693af6ab5fSopenharmony_ci } 6703af6ab5fSopenharmony_ci 6713af6ab5fSopenharmony_ci Type *nextInferredType = ConvertTupleTypeToArrayTypeIfNecessary( 6723af6ab5fSopenharmony_ci it->AsProperty(), 6733af6ab5fSopenharmony_ci NextInferredType(property->Key()->AsIdentifier()->Name(), 6743af6ab5fSopenharmony_ci (!property->Value()->IsAssignmentPattern() || validateTypeAnnotation_))); 6753af6ab5fSopenharmony_ci 6763af6ab5fSopenharmony_ci if (property->Value()->IsIdentifier()) { 6773af6ab5fSopenharmony_ci if (inAssignment_) { 6783af6ab5fSopenharmony_ci HandleDestructuringAssignment(property->Value()->AsIdentifier(), nextInferredType, nullptr); 6793af6ab5fSopenharmony_ci break; 6803af6ab5fSopenharmony_ci } 6813af6ab5fSopenharmony_ci 6823af6ab5fSopenharmony_ci SetInferredTypeForVariable(property->Value()->AsIdentifier()->Variable(), nextInferredType, 6833af6ab5fSopenharmony_ci it->Start()); 6843af6ab5fSopenharmony_ci break; 6853af6ab5fSopenharmony_ci } 6863af6ab5fSopenharmony_ci 6873af6ab5fSopenharmony_ci if (property->Value()->IsArrayPattern()) { 6883af6ab5fSopenharmony_ci ArrayDestructuringContext nextContext = 6893af6ab5fSopenharmony_ci ArrayDestructuringContext({checker_, property->Value()->AsArrayPattern(), inAssignment_, 6903af6ab5fSopenharmony_ci convertTupleToArray_, nullptr, nullptr}); 6913af6ab5fSopenharmony_ci nextContext.SetInferredType(nextInferredType); 6923af6ab5fSopenharmony_ci nextContext.Start(); 6933af6ab5fSopenharmony_ci break; 6943af6ab5fSopenharmony_ci } 6953af6ab5fSopenharmony_ci 6963af6ab5fSopenharmony_ci if (property->Value()->IsObjectPattern()) { 6973af6ab5fSopenharmony_ci ObjectDestructuringContext nextContext = 6983af6ab5fSopenharmony_ci ObjectDestructuringContext({checker_, property->Value()->AsObjectPattern(), inAssignment_, 6993af6ab5fSopenharmony_ci convertTupleToArray_, nullptr, nullptr}); 7003af6ab5fSopenharmony_ci nextContext.SetInferredType(nextInferredType); 7013af6ab5fSopenharmony_ci nextContext.Start(); 7023af6ab5fSopenharmony_ci break; 7033af6ab5fSopenharmony_ci } 7043af6ab5fSopenharmony_ci 7053af6ab5fSopenharmony_ci ASSERT(property->Value()->IsAssignmentPattern()); 7063af6ab5fSopenharmony_ci HandleAssignmentPattern(property->Value()->AsAssignmentPattern(), nextInferredType, true); 7073af6ab5fSopenharmony_ci break; 7083af6ab5fSopenharmony_ci } 7093af6ab5fSopenharmony_ci case ir::AstNodeType::REST_ELEMENT: { 7103af6ab5fSopenharmony_ci HandleRest(it->AsRestElement()); 7113af6ab5fSopenharmony_ci break; 7123af6ab5fSopenharmony_ci } 7133af6ab5fSopenharmony_ci default: { 7143af6ab5fSopenharmony_ci UNREACHABLE(); 7153af6ab5fSopenharmony_ci } 7163af6ab5fSopenharmony_ci } 7173af6ab5fSopenharmony_ci } 7183af6ab5fSopenharmony_ci} 7193af6ab5fSopenharmony_ci} // namespace ark::es2panda::checker 720