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