1 /*
2 * Copyright (c) 2021-2024 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 #include "etsTypeReferencePart.h"
17
18 #include "checker/ETSchecker.h"
19 #include "checker/ets/typeRelationContext.h"
20 #include "checker/TSchecker.h"
21 #include "compiler/core/ETSGen.h"
22 #include "compiler/core/pandagen.h"
23 #include "ir/astDump.h"
24 #include "ir/srcDump.h"
25
26 namespace ark::es2panda::ir {
TransformChildren(const NodeTransformer & cb,std::string_view const transformationName)27 void ETSTypeReferencePart::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName)
28 {
29 if (auto *transformedNode = cb(name_); name_ != transformedNode) {
30 name_->SetTransformedNode(transformationName, transformedNode);
31 name_ = transformedNode->AsExpression();
32 }
33
34 if (typeParams_ != nullptr) {
35 if (auto *transformedNode = cb(typeParams_); typeParams_ != transformedNode) {
36 typeParams_->SetTransformedNode(transformationName, transformedNode);
37 typeParams_ = transformedNode->AsTSTypeParameterInstantiation();
38 }
39 }
40
41 if (prev_ != nullptr) {
42 if (auto *transformedNode = cb(prev_); prev_ != transformedNode) {
43 prev_->SetTransformedNode(transformationName, transformedNode);
44 prev_ = transformedNode->AsETSTypeReferencePart();
45 }
46 }
47 }
48
Iterate(const NodeTraverser & cb) const49 void ETSTypeReferencePart::Iterate(const NodeTraverser &cb) const
50 {
51 cb(name_);
52
53 if (typeParams_ != nullptr) {
54 cb(typeParams_);
55 }
56
57 if (prev_ != nullptr) {
58 cb(prev_);
59 }
60 }
61
Dump(ir::AstDumper * dumper) const62 void ETSTypeReferencePart::Dump(ir::AstDumper *dumper) const
63 {
64 dumper->Add({{"type", "ETSTypeReferencePart"},
65 {"name", name_},
66 {"typeParams", AstDumper::Optional(typeParams_)},
67 {"previous", AstDumper::Optional(prev_)}});
68 }
69
Dump(ir::SrcDumper * dumper) const70 void ETSTypeReferencePart::Dump(ir::SrcDumper *dumper) const
71 {
72 ASSERT(name_ != nullptr);
73 name_->Dump(dumper);
74 if (typeParams_ != nullptr) {
75 typeParams_->Dump(dumper);
76 }
77 }
78
Compile(compiler::PandaGen * pg) const79 void ETSTypeReferencePart::Compile(compiler::PandaGen *pg) const
80 {
81 pg->GetAstCompiler()->Compile(this);
82 }
Compile(compiler::ETSGen * etsg) const83 void ETSTypeReferencePart::Compile(compiler::ETSGen *etsg) const
84 {
85 etsg->GetAstCompiler()->Compile(this);
86 }
87
Check(checker::TSChecker * checker)88 checker::Type *ETSTypeReferencePart::Check(checker::TSChecker *checker)
89 {
90 return checker->GetAnalyzer()->Check(this);
91 }
92
Check(checker::ETSChecker * checker)93 checker::Type *ETSTypeReferencePart::Check(checker::ETSChecker *checker)
94 {
95 return checker->GetAnalyzer()->Check(this);
96 }
97
GetType(checker::ETSChecker * checker)98 checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker)
99 {
100 if (prev_ == nullptr) {
101 if (name_->IsIdentifier()) {
102 const auto ident = name_->AsIdentifier();
103 if ((ident->Variable() != nullptr) && (ident->Variable()->Declaration()->IsTypeAliasDecl())) {
104 SetTsType(checker->HandleTypeAlias(name_, typeParams_));
105 } else if (ident->Name() == compiler::Signatures::UNDEFINED) {
106 SetTsType(checker->GlobalETSUndefinedType());
107 } else if (ident->Name() == compiler::Signatures::NULL_LITERAL) {
108 SetTsType(checker->GlobalETSNullType());
109 } else if (ident->Name() == compiler::Signatures::PARTIAL_TYPE_NAME ||
110 ident->Name() == compiler::Signatures::READONLY_TYPE_NAME ||
111 ident->Name() == compiler::Signatures::REQUIRED_TYPE_NAME) {
112 SetTsType(checker->HandleUtilityTypeParameterNode(typeParams_, ident->Name().Utf8()));
113 }
114 }
115 if (TsType() == nullptr) {
116 checker::Type *baseType = checker->GetReferencedTypeBase(name_);
117
118 ASSERT(baseType != nullptr);
119 if (baseType->IsETSObjectType()) {
120 checker::InstantiationContext ctx(checker, baseType->AsETSObjectType(), typeParams_, Start());
121 SetTsType(ctx.Result());
122 } else {
123 SetTsType(baseType);
124 }
125 }
126 } else {
127 checker::Type *baseType = prev_->GetType(checker);
128 SetTsType(checker->GetReferencedTypeFromBase(baseType, name_));
129 }
130 return TsType();
131 }
132
Clone(ArenaAllocator * const allocator,AstNode * const parent)133 ETSTypeReferencePart *ETSTypeReferencePart::Clone(ArenaAllocator *const allocator, AstNode *const parent)
134 {
135 auto *const nameClone = name_ != nullptr ? name_->Clone(allocator, nullptr)->AsExpression() : nullptr;
136 auto *const typeParamsClone =
137 typeParams_ != nullptr ? typeParams_->Clone(allocator, nullptr)->AsTSTypeParameterInstantiation() : nullptr;
138 auto *const prevClone = prev_ != nullptr ? prev_->Clone(allocator, nullptr)->AsETSTypeReferencePart() : nullptr;
139 if (auto *const clone = allocator->New<ETSTypeReferencePart>(nameClone, typeParamsClone, prevClone);
140 clone != nullptr) {
141 if (nameClone != nullptr) {
142 nameClone->SetParent(clone);
143 }
144
145 if (typeParamsClone != nullptr) {
146 typeParamsClone->SetParent(clone);
147 }
148
149 if (prevClone != nullptr) {
150 prevClone->SetParent(clone);
151 }
152
153 if (parent != nullptr) {
154 clone->SetParent(parent);
155 }
156
157 clone->SetRange(Range());
158 return clone;
159 }
160
161 throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR);
162 }
163 } // namespace ark::es2panda::ir
164