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_TYPESCIRPT_CORE_DESTRUCTURING_CONTEXT_H 17 #define ES2PANDA_TYPESCIRPT_CORE_DESTRUCTURING_CONTEXT_H 18 19 #include <typescript/checker.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(Checker * checker,const ir::Expression * id,bool inAssignment,bool convertTupleToArray,const ir::Expression * typeAnnotation,const ir::Expression * initializer)34 DestructuringContext(Checker *checker, const ir::Expression *id, bool inAssignment, bool convertTupleToArray, 35 const ir::Expression *typeAnnotation, const ir::Expression *initializer) 36 : checker_(checker), id_(id), inAssignment_(inAssignment), convertTupleToArray_(convertTupleToArray) 37 { 38 Prepare(typeAnnotation, initializer, id->Start()); 39 } 40 SetInferedType(Type * type)41 void SetInferedType(Type *type) 42 { 43 inferedType_ = type; 44 } 45 SetSignatureInfo(SignatureInfo * info)46 void SetSignatureInfo(SignatureInfo *info) 47 { 48 signatureInfo_ = info; 49 } 50 InferedType()51 Type *InferedType() 52 { 53 return inferedType_; 54 } 55 56 void ValidateObjectLiteralType(ObjectType *objType, const ir::ObjectExpression *objPattern); 57 void HandleDestructuringAssignment(const ir::Identifier *ident, Type *inferedType, Type *defaultType); 58 void HandleAssignmentPattern(const ir::AssignmentExpression *assignmentPattern, Type *inferedType, 59 bool validateDefault); 60 void HandleIdentifierPattern(const ir::AssignmentExpression *assignmentPattern, Type *initType, 61 Type *inferedType, Type *defaultType); 62 void SetInferedTypeForVariable(binder::Variable *var, Type *inferedType, const lexer::SourcePosition &loc); 63 void Prepare(const ir::Expression *typeAnnotation, const ir::Expression *initializer, 64 const lexer::SourcePosition &loc); 65 66 DEFAULT_COPY_SEMANTIC(DestructuringContext); 67 DEFAULT_MOVE_SEMANTIC(DestructuringContext); 68 virtual ~DestructuringContext() = default; 69 70 virtual void Start() = 0; 71 virtual void ValidateInferedType() = 0; 72 virtual Type *NextInferedType([[maybe_unused]] const util::StringView &searchName, bool throwError) = 0; 73 virtual void HandleRest(const ir::SpreadElement *rest) = 0; 74 virtual Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) = 0; 75 virtual Type *ConvertTupleTypeToArrayTypeIfNecessary(const ir::AstNode *node, Type *type) = 0; 76 77 protected: 78 Checker *checker_; 79 const ir::Expression *id_; 80 bool inAssignment_; 81 bool convertTupleToArray_; 82 Type *inferedType_ {nullptr}; 83 SignatureInfo *signatureInfo_ {nullptr}; 84 bool validateObjectPatternInitializer_ {true}; 85 bool validateTypeAnnotation_ {false}; 86 }; 87 88 class ArrayDestructuringContext : public DestructuringContext { 89 public: ArrayDestructuringContext(Checker * checker,const ir::Expression * id,bool inAssignment,bool convertTupleToArray,const ir::Expression * typeAnnotation,const ir::Expression * initializer)90 ArrayDestructuringContext(Checker *checker, const ir::Expression *id, bool inAssignment, bool convertTupleToArray, 91 const ir::Expression *typeAnnotation, const ir::Expression *initializer) 92 : DestructuringContext(checker, id, inAssignment, convertTupleToArray, typeAnnotation, initializer) 93 { 94 } 95 96 Type *GetTypeFromTupleByIndex(TupleType *tuple); 97 Type *CreateArrayTypeForRest(UnionType *inferedType); 98 Type *CreateTupleTypeForRest(TupleType *tuple); 99 void SetRemainingPatameterTypes(); 100 101 void Start() override; 102 void ValidateInferedType() override; 103 Type *NextInferedType([[maybe_unused]] const util::StringView &searchName, bool throwError) override; 104 void HandleRest(const ir::SpreadElement *rest) override; 105 Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) override; 106 Type *ConvertTupleTypeToArrayTypeIfNecessary(const ir::AstNode *node, Type *type) override; 107 108 private: 109 uint32_t index_ {0}; 110 }; 111 112 class ObjectDestructuringContext : public DestructuringContext { 113 public: ObjectDestructuringContext(Checker * checker,const ir::Expression * id,bool inAssignment,bool convertTupleToArray,const ir::Expression * typeAnnotation,const ir::Expression * initializer)114 ObjectDestructuringContext(Checker *checker, const ir::Expression *id, bool inAssignment, bool convertTupleToArray, 115 const ir::Expression *typeAnnotation, const ir::Expression *initializer) 116 : DestructuringContext(checker, id, inAssignment, convertTupleToArray, typeAnnotation, initializer) 117 { 118 } 119 120 Type *CreateObjectTypeForRest(ObjectType *objType); 121 122 void Start() override; 123 void ValidateInferedType() override; 124 Type *NextInferedType([[maybe_unused]] const util::StringView &searchName, bool throwError) override; 125 void HandleRest(const ir::SpreadElement *rest) override; 126 Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) override; 127 Type *ConvertTupleTypeToArrayTypeIfNecessary(const ir::AstNode *node, Type *type) override; 128 }; 129 } // namespace panda::es2panda::checker 130 131 #endif 132