1 /*
2 * Copyright (c) 2021-2025 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 "etsNewArrayInstanceExpression.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
24 namespace ark::es2panda::ir {
TransformChildren(const NodeTransformer & cb,std::string_view const transformationName)25 void ETSNewArrayInstanceExpression::TransformChildren(const NodeTransformer &cb,
26 std::string_view const transformationName)
27 {
28 if (auto *transformedNode = cb(typeReference_); typeReference_ != transformedNode) {
29 typeReference_->SetTransformedNode(transformationName, transformedNode);
30 typeReference_ = static_cast<TypeNode *>(transformedNode);
31 }
32
33 if (auto *transformedNode = cb(dimension_); dimension_ != transformedNode) {
34 dimension_->SetTransformedNode(transformationName, transformedNode);
35 dimension_ = transformedNode->AsExpression();
36 }
37 }
38
Iterate(const NodeTraverser & cb) const39 void ETSNewArrayInstanceExpression::Iterate(const NodeTraverser &cb) const
40 {
41 cb(typeReference_);
42 cb(dimension_);
43 }
44
Dump(ir::AstDumper * dumper) const45 void ETSNewArrayInstanceExpression::Dump(ir::AstDumper *dumper) const
46 {
47 dumper->Add(
48 {{"type", "ETSNewArrayInstanceExpression"}, {"typeReference", typeReference_}, {"dimension", dimension_}});
49 }
50
Dump(ir::SrcDumper * dumper) const51 void ETSNewArrayInstanceExpression::Dump(ir::SrcDumper *dumper) const
52 {
53 dumper->Add("new ");
54 ES2PANDA_ASSERT(typeReference_);
55 typeReference_->Dump(dumper);
56 ES2PANDA_ASSERT(dimension_);
57 dumper->Add("[");
58 dimension_->Dump(dumper);
59 dumper->Add("]");
60 }
61
Compile(compiler::PandaGen * pg) const62 void ETSNewArrayInstanceExpression::Compile(compiler::PandaGen *pg) const
63 {
64 pg->GetAstCompiler()->Compile(this);
65 }
Compile(compiler::ETSGen * etsg) const66 void ETSNewArrayInstanceExpression::Compile(compiler::ETSGen *etsg) const
67 {
68 etsg->GetAstCompiler()->Compile(this);
69 }
70
Check(checker::TSChecker * checker)71 checker::Type *ETSNewArrayInstanceExpression::Check(checker::TSChecker *checker)
72 {
73 return checker->GetAnalyzer()->Check(this);
74 }
75
Check(checker::ETSChecker * checker)76 checker::VerifiedType ETSNewArrayInstanceExpression::Check(checker::ETSChecker *checker)
77 {
78 return {this, checker->GetAnalyzer()->Check(this)};
79 }
80
Clone(ArenaAllocator * const allocator,AstNode * const parent)81 ETSNewArrayInstanceExpression *ETSNewArrayInstanceExpression::Clone(ArenaAllocator *const allocator,
82 AstNode *const parent)
83 {
84 auto *const typeRef = typeReference_ != nullptr ? typeReference_->Clone(allocator, nullptr) : nullptr;
85 auto *const dimension = dimension_ != nullptr ? dimension_->Clone(allocator, nullptr)->AsExpression() : nullptr;
86 auto *const clone = allocator->New<ETSNewArrayInstanceExpression>(typeRef, dimension);
87 ES2PANDA_ASSERT(clone);
88
89 if (typeRef != nullptr) {
90 typeRef->SetParent(clone);
91 }
92
93 if (dimension != nullptr) {
94 dimension->SetParent(clone);
95 }
96
97 if (parent != nullptr) {
98 clone->SetParent(parent);
99 }
100
101 clone->defaultConstructorSignature_ = defaultConstructorSignature_;
102 clone->SetRange(Range());
103
104 return clone;
105 }
106
ClearPreferredType()107 void ETSNewArrayInstanceExpression::ClearPreferredType()
108 {
109 SetPreferredType(nullptr);
110 SetTsType(nullptr);
111 TypeReference()->SetBoxingUnboxingFlags(BoxingUnboxingFlags::NONE);
112 }
113
SetPreferredTypeBasedOnFuncParam(checker::ETSChecker * checker,checker::Type * param,checker::TypeRelationFlag flags)114 void ETSNewArrayInstanceExpression::SetPreferredTypeBasedOnFuncParam(checker::ETSChecker *checker, checker::Type *param,
115 checker::TypeRelationFlag flags)
116 {
117 // NOTE (mmartin): This needs a complete solution
118 if (preferredType_ != nullptr) {
119 return;
120 }
121
122 if (!param->IsETSArrayType()) {
123 return;
124 }
125
126 auto *elementType = param->AsETSArrayType()->ElementType();
127
128 auto assignCtx =
129 checker::AssignmentContext(checker->Relation(), typeReference_, typeReference_->GetType(checker), elementType,
130 typeReference_->Start(), std::nullopt, checker::TypeRelationFlag::NO_THROW | flags);
131 if (assignCtx.IsAssignable()) {
132 SetPreferredType(param);
133 }
134 }
135 } // namespace ark::es2panda::ir
136