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 <gtest/gtest.h>
17 #include <algorithm>
18
19 #include "checker/ETSAnalyzer.h"
20 #include "checker/ETSchecker.h"
21 #include "compiler/core/compilerImpl.h"
22 #include "compiler/core/ETSCompiler.h"
23 #include "compiler/core/ETSemitter.h"
24 #include "compiler/core/ETSGen.h"
25 #include "compiler/core/regSpiller.h"
26 #include "compiler/lowering/phase.h"
27 #include "es2panda.h"
28 #include "mem/arena_allocator.h"
29 #include "mem/pool_manager.h"
30 #include "public/public.h"
31 #include "util/arktsconfig.h"
32 #include "util/generateBin.h"
33 #include "varbinder/ETSBinder.h"
34 #include "test/utils/panda_executable_path_getter.h"
35 #include "checker/types/globalTypesHolder.h"
36 #include "test/unit/union_normalisation_test.h"
37
38 using ark::es2panda::gtests::UnionNormalizationTest;
39
40 namespace ark::es2panda {
TEST_F(UnionNormalizationTest,UnionWithObject)41 TEST_F(UnionNormalizationTest, UnionWithObject)
42 {
43 // Test normalization: int | Object | string ==> Object
44 InitializeChecker("_.ets", "");
45
46 auto checker = Checker();
47 ASSERT(checker);
48
49 ArenaVector<checker::Type *> unionConstituents(checker->Allocator()->Adapter());
50 unionConstituents.emplace_back(checker->GlobalIntType());
51 unionConstituents.emplace_back(checker->GetGlobalTypesHolder()->GlobalETSObjectType());
52 unionConstituents.emplace_back(checker->GetGlobalTypesHolder()->GlobalETSStringBuiltinType());
53
54 // Create union type, which will be normalized inside creation function
55 auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
56 ASSERT_NE(normalizedType, nullptr);
57 ASSERT_TRUE(normalizedType->IsETSObjectType());
58 ASSERT_EQ(normalizedType, checker->GlobalETSObjectType());
59 }
60
TEST_F(UnionNormalizationTest,UnionWithIdenticalTypes1)61 TEST_F(UnionNormalizationTest, UnionWithIdenticalTypes1)
62 {
63 // Test normalization: number | Base | string | number ==> number | Base | string
64 InitializeChecker("_.ets", "class Base {}");
65
66 auto program = Program();
67 ASSERT(program);
68
69 auto *const baseType = FindClassType(program->VarBinder()->AsETSBinder(), "Base");
70 ASSERT_NE(baseType, nullptr);
71
72 auto checker = Checker();
73 ASSERT(checker);
74
75 ArenaVector<checker::Type *> unionConstituents(checker->Allocator()->Adapter());
76 unionConstituents.emplace_back(checker->GlobalDoubleType());
77 unionConstituents.emplace_back(baseType);
78 unionConstituents.emplace_back(checker->GlobalBuiltinETSStringType());
79 unionConstituents.emplace_back(checker->GlobalDoubleType());
80
81 // Create union type, which will be normalized inside creation function
82 auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
83 ASSERT_NE(normalizedType, nullptr);
84 ASSERT_TRUE(normalizedType->IsETSUnionType());
85 auto *const unionType = normalizedType->AsETSUnionType();
86 ASSERT_EQ(unionType->ConstituentTypes().size(), SIZE3);
87 ASSERT_EQ(unionType->ConstituentTypes().at(IDX0), checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType());
88 ASSERT_EQ(unionType->ConstituentTypes().at(IDX1), baseType);
89 ASSERT_EQ(unionType->ConstituentTypes().at(IDX2), checker->GlobalBuiltinETSStringType());
90 }
91
TEST_F(UnionNormalizationTest,DISABLED_UnionWithIdenticalTypes2)92 TEST_F(UnionNormalizationTest, DISABLED_UnionWithIdenticalTypes2)
93 {
94 // Test normalization: Base | int | Base | double | short | number ==> Base | number
95 InitializeChecker("_.ets", "class Base {}");
96
97 auto program = Program();
98 ASSERT(program);
99
100 auto *const baseType = FindClassType(program->VarBinder()->AsETSBinder(), "Base");
101 ASSERT_NE(baseType, nullptr);
102
103 auto checker = Checker();
104 ASSERT(checker);
105
106 ArenaVector<checker::Type *> unionConstituents(checker->Allocator()->Adapter());
107 unionConstituents.emplace_back(baseType);
108 unionConstituents.emplace_back(checker->GlobalIntType());
109 unionConstituents.emplace_back(baseType);
110 unionConstituents.emplace_back(checker->GlobalDoubleType());
111 unionConstituents.emplace_back(checker->GlobalShortType());
112 unionConstituents.emplace_back(checker->GlobalDoubleType());
113
114 // Create union type, which will be normalized inside creation function
115 auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
116 ASSERT_NE(normalizedType, nullptr);
117 ASSERT_TRUE(normalizedType->IsETSUnionType());
118 auto *const unionType = normalizedType->AsETSUnionType();
119 ASSERT_EQ(unionType->ConstituentTypes().size(), SIZE2);
120 ASSERT_EQ(unionType->ConstituentTypes().at(IDX0), baseType);
121 ASSERT_EQ(unionType->ConstituentTypes().at(IDX1), checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType());
122 }
123
TEST_F(UnionNormalizationTest,DISABLED_UnionWithNumeric1)124 TEST_F(UnionNormalizationTest, DISABLED_UnionWithNumeric1)
125 {
126 // Test normalization: boolean | int | double | short ==> boolean | double
127 InitializeChecker("_.ets", "");
128
129 auto checker = Checker();
130 ASSERT(checker);
131
132 ArenaVector<checker::Type *> unionConstituents(checker->Allocator()->Adapter());
133 unionConstituents.emplace_back(checker->GlobalETSBooleanType());
134 unionConstituents.emplace_back(checker->GlobalIntType());
135 unionConstituents.emplace_back(checker->GlobalDoubleType());
136 unionConstituents.emplace_back(checker->GlobalShortType());
137
138 // Create union type, which will be normalized inside creation function
139 auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
140 ASSERT_NE(normalizedType, nullptr);
141 ASSERT_TRUE(normalizedType->IsETSUnionType());
142 auto *const unionType = normalizedType->AsETSUnionType();
143 ASSERT_EQ(unionType->ConstituentTypes().size(), SIZE2);
144 ASSERT_EQ(unionType->ConstituentTypes().at(IDX0), checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType());
145 ASSERT_EQ(unionType->ConstituentTypes().at(IDX1), checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType());
146 }
147
TEST_F(UnionNormalizationTest,DISABLED_UnionWithNumeric2)148 TEST_F(UnionNormalizationTest, DISABLED_UnionWithNumeric2)
149 {
150 // Test normalization: string | int | Base | double | short ==> string | Base | double
151 InitializeChecker("_.ets", "class Base {}");
152
153 auto program = Program();
154 ASSERT(program);
155
156 auto *const baseType = FindClassType(program->VarBinder()->AsETSBinder(), "Base");
157 ASSERT_NE(baseType, nullptr);
158
159 auto checker = Checker();
160 ASSERT(checker);
161
162 ArenaVector<checker::Type *> unionConstituents(checker->Allocator()->Adapter());
163 unionConstituents.emplace_back(checker->GlobalBuiltinETSStringType());
164 unionConstituents.emplace_back(checker->GlobalIntType());
165 unionConstituents.emplace_back(baseType);
166 unionConstituents.emplace_back(checker->GlobalDoubleType());
167 unionConstituents.emplace_back(checker->GlobalShortType());
168
169 // Create union type, which will be normalized inside creation function
170 auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
171 ASSERT_NE(normalizedType, nullptr);
172 ASSERT_TRUE(normalizedType->IsETSUnionType());
173 auto *const unionType = normalizedType->AsETSUnionType();
174 ASSERT_EQ(unionType->ConstituentTypes().size(), SIZE3);
175 ASSERT_EQ(unionType->ConstituentTypes().at(IDX0), checker->GlobalBuiltinETSStringType());
176 ASSERT_EQ(unionType->ConstituentTypes().at(IDX1), baseType);
177 ASSERT_EQ(unionType->ConstituentTypes().at(IDX2), checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType());
178 }
179 } // namespace ark::es2panda
180