• 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 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