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#ifndef ES2PANDA_COMPILER_CHECKER_ETS_ASSIGN_ANALYZER_H 173af6ab5fSopenharmony_ci#define ES2PANDA_COMPILER_CHECKER_ETS_ASSIGN_ANALYZER_H 183af6ab5fSopenharmony_ci 193af6ab5fSopenharmony_ci#include "checker/ETSchecker.h" 203af6ab5fSopenharmony_ci#include "checker/ets/baseAnalyzer.h" 213af6ab5fSopenharmony_ci 223af6ab5fSopenharmony_ci#include "utils/arena_containers.h" 233af6ab5fSopenharmony_ci 243af6ab5fSopenharmony_cinamespace ark::es2panda::ir { 253af6ab5fSopenharmony_ciclass AstNode; 263af6ab5fSopenharmony_ci} // namespace ark::es2panda::ir 273af6ab5fSopenharmony_ci 283af6ab5fSopenharmony_cinamespace ark::es2panda::checker { 293af6ab5fSopenharmony_ci 303af6ab5fSopenharmony_ciclass Set { 313af6ab5fSopenharmony_cipublic: 323af6ab5fSopenharmony_ci Set() = default; 333af6ab5fSopenharmony_ci ~Set() = default; 343af6ab5fSopenharmony_ci 353af6ab5fSopenharmony_ci DEFAULT_COPY_SEMANTIC(Set); 363af6ab5fSopenharmony_ci DEFAULT_NOEXCEPT_MOVE_SEMANTIC(Set); 373af6ab5fSopenharmony_ci 383af6ab5fSopenharmony_ci void Reset(); 393af6ab5fSopenharmony_ci bool IsReset(); 403af6ab5fSopenharmony_ci void Incl(const int id); 413af6ab5fSopenharmony_ci void InclRange(const int start, const int limit); 423af6ab5fSopenharmony_ci void ExcludeFrom(const int start); 433af6ab5fSopenharmony_ci void Excl(const int id); 443af6ab5fSopenharmony_ci bool IsMember(const int id) const; 453af6ab5fSopenharmony_ci Set &AndSet(const Set &xs); 463af6ab5fSopenharmony_ci Set &OrSet(const Set &xs); 473af6ab5fSopenharmony_ci Set &DiffSet(const Set &xs); 483af6ab5fSopenharmony_ci int Next(const int id); 493af6ab5fSopenharmony_ci 503af6ab5fSopenharmony_ciprotected: 513af6ab5fSopenharmony_ci void InternalAndSet(const Set &xs); 523af6ab5fSopenharmony_ci 533af6ab5fSopenharmony_ciprivate: 543af6ab5fSopenharmony_ci bool reset_ {}; 553af6ab5fSopenharmony_ci std::set<int> nodes_ {}; 563af6ab5fSopenharmony_ci}; 573af6ab5fSopenharmony_ci 583af6ab5fSopenharmony_ciclass AssignPendingExit : public PendingExit { 593af6ab5fSopenharmony_cipublic: 603af6ab5fSopenharmony_ci explicit AssignPendingExit(const ir::AstNode *node, Set &inits, Set &uninits) 613af6ab5fSopenharmony_ci : PendingExit(node), inits_(&inits), uninits_(&uninits) 623af6ab5fSopenharmony_ci { 633af6ab5fSopenharmony_ci exitInits_ = inits; 643af6ab5fSopenharmony_ci exitUninits_ = uninits; 653af6ab5fSopenharmony_ci } 663af6ab5fSopenharmony_ci ~AssignPendingExit() override = default; 673af6ab5fSopenharmony_ci 683af6ab5fSopenharmony_ci DEFAULT_COPY_SEMANTIC(AssignPendingExit); 693af6ab5fSopenharmony_ci DEFAULT_NOEXCEPT_MOVE_SEMANTIC(AssignPendingExit); 703af6ab5fSopenharmony_ci 713af6ab5fSopenharmony_ci void ResolveJump() override 723af6ab5fSopenharmony_ci { 733af6ab5fSopenharmony_ci inits_->AndSet(exitInits_); 743af6ab5fSopenharmony_ci uninits_->AndSet(exitUninits_); 753af6ab5fSopenharmony_ci } 763af6ab5fSopenharmony_ci 773af6ab5fSopenharmony_ci // NOLINTBEGIN(misc-non-private-member-variables-in-classes,readability-identifier-naming) 783af6ab5fSopenharmony_ci Set *inits_; 793af6ab5fSopenharmony_ci Set *uninits_; 803af6ab5fSopenharmony_ci Set exitInits_; 813af6ab5fSopenharmony_ci Set exitUninits_; 823af6ab5fSopenharmony_ci // NOLINTEND(misc-non-private-member-variables-in-classes,readability-identifier-naming) 833af6ab5fSopenharmony_ci}; 843af6ab5fSopenharmony_ci 853af6ab5fSopenharmony_ciusing NodeId = int; 863af6ab5fSopenharmony_ciusing NodeIdMap = ArenaMap<const ir::AstNode *, NodeId>; 873af6ab5fSopenharmony_ci 883af6ab5fSopenharmony_ciclass AssignAnalyzer : public BaseAnalyzer<AssignPendingExit> { 893af6ab5fSopenharmony_cipublic: 903af6ab5fSopenharmony_ci explicit AssignAnalyzer(ETSChecker *checker); 913af6ab5fSopenharmony_ci void Analyze(const ir::AstNode *node); 923af6ab5fSopenharmony_ci 933af6ab5fSopenharmony_ci void MarkDead() override; 943af6ab5fSopenharmony_ci 953af6ab5fSopenharmony_ciprivate: 963af6ab5fSopenharmony_ci // node visitors 973af6ab5fSopenharmony_ci void AnalyzeNodes(const ir::AstNode *node); 983af6ab5fSopenharmony_ci void AnalyzeNode(const ir::AstNode *node); 993af6ab5fSopenharmony_ci bool AnalyzeStmtNode1(const ir::AstNode *node); 1003af6ab5fSopenharmony_ci bool AnalyzeStmtNode2(const ir::AstNode *node); 1013af6ab5fSopenharmony_ci bool AnalyzeExprNode1(const ir::AstNode *node); 1023af6ab5fSopenharmony_ci bool AnalyzeExprNode2(const ir::AstNode *node); 1033af6ab5fSopenharmony_ci void AnalyzeStat(const ir::AstNode *node); 1043af6ab5fSopenharmony_ci void AnalyzeStats(const ArenaVector<ir::Statement *> &stats); 1053af6ab5fSopenharmony_ci void AnalyzeBlock(const ir::BlockStatement *blockStmt); 1063af6ab5fSopenharmony_ci void AnalyzeStructDecl(const ir::ETSStructDeclaration *structDecl); 1073af6ab5fSopenharmony_ci void AnalyzeClassDecl(const ir::ClassDeclaration *classDecl); 1083af6ab5fSopenharmony_ci void AnalyzeClassDef(const ir::ClassDefinition *classDef); 1093af6ab5fSopenharmony_ci void ProcessClassDefStaticFields(const ir::ClassDefinition *classDef); 1103af6ab5fSopenharmony_ci void CheckAnonymousClassCtor(const ir::ClassDefinition *classDef); 1113af6ab5fSopenharmony_ci void AnalyzeMethodDef(const ir::MethodDefinition *methodDef); 1123af6ab5fSopenharmony_ci void AnalyzeVarDef(const ir::VariableDeclaration *varDef); 1133af6ab5fSopenharmony_ci void AnalyzeDoLoop(const ir::DoWhileStatement *doWhileStmt); 1143af6ab5fSopenharmony_ci void AnalyzeWhileLoop(const ir::WhileStatement *whileStmt); 1153af6ab5fSopenharmony_ci void AnalyzeForLoop(const ir::ForUpdateStatement *forStmt); 1163af6ab5fSopenharmony_ci void AnalyzeForOfLoop(const ir::ForOfStatement *forOfStmt); 1173af6ab5fSopenharmony_ci void AnalyzeIf(const ir::IfStatement *ifStmt); 1183af6ab5fSopenharmony_ci void AnalyzeLabelled(const ir::LabelledStatement *labelledStmt); 1193af6ab5fSopenharmony_ci void AnalyzeSwitch(const ir::SwitchStatement *switchStmt); 1203af6ab5fSopenharmony_ci void AnalyzeTry(const ir::TryStatement *tryStmt); 1213af6ab5fSopenharmony_ci void AnalyzeBreak(const ir::BreakStatement *breakStmt); 1223af6ab5fSopenharmony_ci void AnalyzeContinue(const ir::ContinueStatement *contStmt); 1233af6ab5fSopenharmony_ci void AnalyzeReturn(const ir::ReturnStatement *retStmt); 1243af6ab5fSopenharmony_ci void AnalyzeThrow(const ir::ThrowStatement *throwStmt); 1253af6ab5fSopenharmony_ci void AnalyzeAssert(const ir::AssertStatement *assertStmt); 1263af6ab5fSopenharmony_ci void AnalyzeExpr(const ir::AstNode *node); 1273af6ab5fSopenharmony_ci void AnalyzeExprs(const ArenaVector<ir::Expression *> &exprs); 1283af6ab5fSopenharmony_ci void AnalyzeCond(const ir::AstNode *node); 1293af6ab5fSopenharmony_ci void AnalyzeAssignExpr(const ir::AssignmentExpression *assignExpr); 1303af6ab5fSopenharmony_ci void AnalyzeBinaryExpr(const ir::BinaryExpression *binExpr); 1313af6ab5fSopenharmony_ci void AnalyzeCallExpr(const ir::CallExpression *callExpr); 1323af6ab5fSopenharmony_ci void AnalyzeCondExpr(const ir::ConditionalExpression *condExpr); 1333af6ab5fSopenharmony_ci void AnalyzeId(const ir::Identifier *id); 1343af6ab5fSopenharmony_ci void AnalyzeMemberExpr(const ir::MemberExpression *membExpr); 1353af6ab5fSopenharmony_ci void AnalyzeNewClass(const ir::ETSNewClassInstanceExpression *newClass); 1363af6ab5fSopenharmony_ci void AnalyzeUnaryExpr(const ir::UnaryExpression *unaryExpr); 1373af6ab5fSopenharmony_ci void AnalyzeUpdateExpr(const ir::UpdateExpression *updateExpr); 1383af6ab5fSopenharmony_ci void AnalyzeArrowFunctionExpr(const ir::ArrowFunctionExpression *arrowFuncExpr); 1393af6ab5fSopenharmony_ci 1403af6ab5fSopenharmony_ci // utils 1413af6ab5fSopenharmony_ci void Warning(std::string_view message, const lexer::SourcePosition &pos); 1423af6ab5fSopenharmony_ci void Warning(std::initializer_list<TypeErrorMessageElement> list, const lexer::SourcePosition &pos); 1433af6ab5fSopenharmony_ci bool Trackable(const ir::AstNode *node) const; 1443af6ab5fSopenharmony_ci bool IsConstUninitializedField(const ir::AstNode *node) const; 1453af6ab5fSopenharmony_ci bool IsConstUninitializedStaticField(const ir::AstNode *node) const; 1463af6ab5fSopenharmony_ci void NewVar(const ir::AstNode *node); 1473af6ab5fSopenharmony_ci void LetInit(const ir::AstNode *node); 1483af6ab5fSopenharmony_ci void CheckInit(const ir::AstNode *node); 1493af6ab5fSopenharmony_ci void Split(bool setToNull); 1503af6ab5fSopenharmony_ci void Merge(); 1513af6ab5fSopenharmony_ci void CheckPendingExits(bool inMethod); 1523af6ab5fSopenharmony_ci NodeId GetNodeId(const ir::AstNode *node) const; 1533af6ab5fSopenharmony_ci util::StringView GetVariableType(const ir::AstNode *node) const; 1543af6ab5fSopenharmony_ci util::StringView GetVariableName(const ir::AstNode *node) const; 1553af6ab5fSopenharmony_ci const lexer::SourcePosition &GetVariablePosition(const ir::AstNode *node) const; 1563af6ab5fSopenharmony_ci const ir::AstNode *GetDeclaringNode(const ir::AstNode *node); 1573af6ab5fSopenharmony_ci varbinder::Variable *GetBoundVariable(const ir::AstNode *node); 1583af6ab5fSopenharmony_ci bool VariableHasDefaultValue(const ir::AstNode *node); 1593af6ab5fSopenharmony_ci 1603af6ab5fSopenharmony_ci ETSChecker *checker_; 1613af6ab5fSopenharmony_ci Set inits_ {}; 1623af6ab5fSopenharmony_ci Set uninits_ {}; 1633af6ab5fSopenharmony_ci Set uninitsTry_ {}; 1643af6ab5fSopenharmony_ci Set initsWhenTrue_ {}; 1653af6ab5fSopenharmony_ci Set initsWhenFalse_ {}; 1663af6ab5fSopenharmony_ci Set uninitsWhenTrue_ {}; 1673af6ab5fSopenharmony_ci Set uninitsWhenFalse_ {}; 1683af6ab5fSopenharmony_ci ArenaVector<const ir::AstNode *> varDecls_; 1693af6ab5fSopenharmony_ci const ir::ClassDefinition *globalClass_ {}; 1703af6ab5fSopenharmony_ci const ir::ClassDefinition *classDef_ {}; 1713af6ab5fSopenharmony_ci bool globalClassIsVisited_ {}; 1723af6ab5fSopenharmony_ci int classFirstAdr_ {}; 1733af6ab5fSopenharmony_ci int firstNonGlobalAdr_ {}; 1743af6ab5fSopenharmony_ci int firstAdr_ {}; 1753af6ab5fSopenharmony_ci int nextAdr_ {}; 1763af6ab5fSopenharmony_ci int returnAdr_ {}; 1773af6ab5fSopenharmony_ci bool isInitialConstructor_ {}; 1783af6ab5fSopenharmony_ci NodeIdMap nodeIdMap_; 1793af6ab5fSopenharmony_ci int numErrors_ {}; 1803af6ab5fSopenharmony_ci ArenaSet<const ir::AstNode *> foundErrors_; 1813af6ab5fSopenharmony_ci}; 1823af6ab5fSopenharmony_ci 1833af6ab5fSopenharmony_ci} // namespace ark::es2panda::checker 1843af6ab5fSopenharmony_ci 1853af6ab5fSopenharmony_ci#endif 186