1 /** 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ES2PANDA_CHECKER_TS_DESTRUCTURING_CONTEXT_H 17 #define ES2PANDA_CHECKER_TS_DESTRUCTURING_CONTEXT_H 18 19 #include "checker/TSchecker.h" 20 #include "ir/expression.h" 21 22 #include <macros.h> 23 24 namespace panda::es2panda::ir { 25 class Expression; 26 class SpreadElement; 27 } // namespace panda::es2panda::ir 28 29 namespace panda::es2panda::checker { 30 class Type; 31 32 class DestructuringContext { 33 public: DestructuringContext(TSChecker * checker,ir::Expression * id,bool inAssignment,bool convertTupleToArray,ir::TypeNode * typeAnnotation,ir::Expression * initializer)34 DestructuringContext(TSChecker *checker, ir::Expression *id, bool inAssignment, bool convertTupleToArray, 35 ir::TypeNode *typeAnnotation, ir::Expression *initializer) 36 : checker_(checker), id_(id), inAssignment_(inAssignment), convertTupleToArray_(convertTupleToArray) 37 { 38 Prepare(typeAnnotation, initializer, id->Start()); 39 } 40 SetInferredType(Type * type)41 void SetInferredType(Type *type) 42 { 43 inferredType_ = type; 44 } 45 SetSignatureInfo(SignatureInfo * info)46 void SetSignatureInfo(SignatureInfo *info) 47 { 48 signatureInfo_ = info; 49 } 50 InferredType()51 Type *InferredType() 52 { 53 return inferredType_; 54 } 55 56 void ValidateObjectLiteralType(ObjectType *objType, ir::ObjectExpression *objPattern); 57 void HandleDestructuringAssignment(ir::Identifier *ident, Type *inferredType, Type *defaultType); 58 void HandleAssignmentPattern(ir::AssignmentExpression *assignmentPattern, Type *inferredType, bool validateDefault); 59 void SetInferredTypeForVariable(varbinder::Variable *var, Type *inferredType, const lexer::SourcePosition &loc); 60 void Prepare(ir::TypeNode *typeAnnotation, ir::Expression *initializer, const lexer::SourcePosition &loc); 61 62 DEFAULT_COPY_SEMANTIC(DestructuringContext); 63 DEFAULT_MOVE_SEMANTIC(DestructuringContext); 64 ~DestructuringContext() = default; 65 66 virtual void Start() = 0; 67 virtual void ValidateInferredType() = 0; 68 virtual Type *NextInferredType([[maybe_unused]] const util::StringView &searchName, bool throwError) = 0; 69 virtual void HandleRest(ir::SpreadElement *rest) = 0; 70 virtual Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) = 0; 71 virtual Type *ConvertTupleTypeToArrayTypeIfNecessary(ir::AstNode *node, Type *type) = 0; 72 73 protected: 74 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 75 TSChecker *checker_; 76 ir::Expression *id_; 77 bool inAssignment_; 78 bool convertTupleToArray_; 79 Type *inferredType_ {}; 80 SignatureInfo *signatureInfo_ {}; 81 bool validateObjectPatternInitializer_ {true}; 82 bool validateTypeAnnotation_ {}; 83 // NOLINTEND(misc-non-private-member-variables-in-classes) 84 }; 85 86 class ArrayDestructuringContext : public DestructuringContext { 87 public: ArrayDestructuringContext(TSChecker * checker,ir::Expression * id,bool inAssignment,bool convertTupleToArray,ir::TypeNode * typeAnnotation,ir::Expression * initializer)88 ArrayDestructuringContext(TSChecker *checker, ir::Expression *id, bool inAssignment, bool convertTupleToArray, 89 ir::TypeNode *typeAnnotation, ir::Expression *initializer) 90 : DestructuringContext(checker, id, inAssignment, convertTupleToArray, typeAnnotation, initializer) 91 { 92 } 93 94 Type *GetTypeFromTupleByIndex(TupleType *tuple); 95 Type *CreateArrayTypeForRest(UnionType *inferredType); 96 Type *CreateTupleTypeForRest(TupleType *tuple); 97 void SetRemainingParameterTypes(); 98 99 void Start() override; 100 void ValidateInferredType() override; 101 Type *NextInferredType([[maybe_unused]] const util::StringView &searchName, bool throwError) override; 102 void HandleRest(ir::SpreadElement *rest) override; 103 Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) override; 104 Type *ConvertTupleTypeToArrayTypeIfNecessary(ir::AstNode *node, Type *type) override; 105 106 private: 107 uint32_t index_ {0}; 108 }; 109 110 class ObjectDestructuringContext : public DestructuringContext { 111 public: ObjectDestructuringContext(TSChecker * checker,ir::Expression * id,bool inAssignment,bool convertTupleToArray,ir::TypeNode * typeAnnotation,ir::Expression * initializer)112 ObjectDestructuringContext(TSChecker *checker, ir::Expression *id, bool inAssignment, bool convertTupleToArray, 113 ir::TypeNode *typeAnnotation, ir::Expression *initializer) 114 : DestructuringContext(checker, id, inAssignment, convertTupleToArray, typeAnnotation, initializer) 115 { 116 } 117 118 Type *CreateObjectTypeForRest(ObjectType *objType); 119 120 void Start() override; 121 void ValidateInferredType() override; 122 Type *NextInferredType([[maybe_unused]] const util::StringView &searchName, bool throwError) override; 123 void HandleRest(ir::SpreadElement *rest) override; 124 Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) override; 125 Type *ConvertTupleTypeToArrayTypeIfNecessary(ir::AstNode *node, Type *type) override; 126 }; 127 } // namespace panda::es2panda::checker 128 129 #endif 130