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 SetInferedTypeForVariable(binder::Variable *var, Type *inferedType, const lexer::SourcePosition &loc); 61 void Prepare(const ir::Expression *typeAnnotation, const ir::Expression *initializer, 62 const lexer::SourcePosition &loc); 63 64 DEFAULT_COPY_SEMANTIC(DestructuringContext); 65 DEFAULT_MOVE_SEMANTIC(DestructuringContext); 66 virtual ~DestructuringContext() = default; 67 68 virtual void Start() = 0; 69 virtual void ValidateInferedType() = 0; 70 virtual Type *NextInferedType([[maybe_unused]] const util::StringView &searchName, bool throwError) = 0; 71 virtual void HandleRest(const ir::SpreadElement *rest) = 0; 72 virtual Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) = 0; 73 virtual Type *ConvertTupleTypeToArrayTypeIfNecessary(const ir::AstNode *node, Type *type) = 0; 74 75 protected: 76 Checker *checker_; 77 const ir::Expression *id_; 78 bool inAssignment_; 79 bool convertTupleToArray_; 80 Type *inferedType_ {nullptr}; 81 SignatureInfo *signatureInfo_ {nullptr}; 82 bool validateObjectPatternInitializer_ {true}; 83 bool validateTypeAnnotation_ {false}; 84 }; 85 86 class ArrayDestructuringContext : public DestructuringContext { 87 public: ArrayDestructuringContext(Checker * checker,const ir::Expression * id,bool inAssignment,bool convertTupleToArray,const ir::Expression * typeAnnotation,const ir::Expression * initializer)88 ArrayDestructuringContext(Checker *checker, const ir::Expression *id, bool inAssignment, bool convertTupleToArray, 89 const ir::Expression *typeAnnotation, const ir::Expression *initializer) 90 : DestructuringContext(checker, id, inAssignment, convertTupleToArray, typeAnnotation, initializer) 91 { 92 } 93 94 Type *GetTypeFromTupleByIndex(TupleType *tuple); 95 Type *CreateArrayTypeForRest(UnionType *inferedType); 96 Type *CreateTupleTypeForRest(TupleType *tuple); 97 void SetRemainingPatameterTypes(); 98 99 void Start() override; 100 void ValidateInferedType() override; 101 Type *NextInferedType([[maybe_unused]] const util::StringView &searchName, bool throwError) override; 102 void HandleRest(const ir::SpreadElement *rest) override; 103 Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) override; 104 Type *ConvertTupleTypeToArrayTypeIfNecessary(const ir::AstNode *node, Type *type) override; 105 106 private: 107 uint32_t index_ {0}; 108 }; 109 110 class ObjectDestructuringContext : public DestructuringContext { 111 public: ObjectDestructuringContext(Checker * checker,const ir::Expression * id,bool inAssignment,bool convertTupleToArray,const ir::Expression * typeAnnotation,const ir::Expression * initializer)112 ObjectDestructuringContext(Checker *checker, const ir::Expression *id, bool inAssignment, bool convertTupleToArray, 113 const ir::Expression *typeAnnotation, const 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 ValidateInferedType() override; 122 Type *NextInferedType([[maybe_unused]] const util::StringView &searchName, bool throwError) override; 123 void HandleRest(const ir::SpreadElement *rest) override; 124 Type *GetRestType([[maybe_unused]] const lexer::SourcePosition &loc) override; 125 Type *ConvertTupleTypeToArrayTypeIfNecessary(const ir::AstNode *node, Type *type) override; 126 }; 127 } // namespace panda::es2panda::checker 128 129 #endif 130