• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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