* Copyright (c) 2021-2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <algorithm>
#include "checker/ETSAnalyzer.h"
#include "checker/ETSchecker.h"
#include "compiler/core/compilerImpl.h"
#include "compiler/core/ETSCompiler.h"
#include "compiler/core/ETSemitter.h"
#include "compiler/core/ETSGen.h"
#include "compiler/core/regSpiller.h"
#include "compiler/lowering/phase.h"
#include "es2panda.h"
#include "util/eheap.h"
#include "public/public.h"
#include "util/arktsconfig.h"
#include "util/generateBin.h"
#include "varbinder/ETSBinder.h"
#include "test/utils/panda_executable_path_getter.h"
#include "checker/types/globalTypesHolder.h"
#include "test/unit/union_normalisation_test.h"
using ark::es2panda::gtests::UnionNormalizationTest;
namespace ark::es2panda {
TEST_F(UnionNormalizationTest, UnionWithObject)
{
InitializeChecker("_.ets", "");
auto checker = Checker();
ASSERT(checker);
std::vector<checker::Type *> unionConstituents;
unionConstituents.emplace_back(checker->GlobalIntBuiltinType());
unionConstituents.emplace_back(checker->GetGlobalTypesHolder()->GlobalETSObjectType());
unionConstituents.emplace_back(checker->GetGlobalTypesHolder()->GlobalETSStringBuiltinType());
auto *const un = checker->CreateETSUnionType(std::move(unionConstituents));
ASSERT_TRUE(un->IsETSUnionType());
auto *const normalizedType = un->AsETSUnionType()->NormalizedType();
ASSERT_NE(normalizedType, nullptr);
ASSERT_TRUE(normalizedType->IsETSObjectType());
ASSERT_EQ(normalizedType, checker->GlobalETSObjectType());
}
TEST_F(UnionNormalizationTest, UnionWithIdenticalTypes1)
{
InitializeChecker("_.ets", "class Base {}");
auto program = Program();
ASSERT(program);
auto *const baseType = FindClassType(program->VarBinder()->AsETSBinder(), "Base");
ASSERT_NE(baseType, nullptr);
auto checker = Checker();
ASSERT(checker);
std::vector<checker::Type *> unionConstituents;
unionConstituents.emplace_back(checker->GlobalDoubleBuiltinType());
unionConstituents.emplace_back(baseType);
unionConstituents.emplace_back(checker->GlobalBuiltinETSStringType());
unionConstituents.emplace_back(checker->GlobalDoubleBuiltinType());
auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
ASSERT_NE(normalizedType, nullptr);
ASSERT_TRUE(normalizedType->IsETSUnionType());
auto *const unionType = normalizedType->AsETSUnionType();
ASSERT_EQ(unionType->ConstituentTypes().size(), SIZE3);
ASSERT_EQ(unionType->ConstituentTypes().at(IDX0), checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType());
ASSERT_EQ(unionType->ConstituentTypes().at(IDX1), baseType);
ASSERT_EQ(unionType->ConstituentTypes().at(IDX2), checker->GlobalBuiltinETSStringType());
}
TEST_F(UnionNormalizationTest, DISABLED_UnionWithIdenticalTypes2)
{
InitializeChecker("_.ets", "class Base {}");
auto program = Program();
ASSERT(program);
auto *const baseType = FindClassType(program->VarBinder()->AsETSBinder(), "Base");
ASSERT_NE(baseType, nullptr);
auto checker = Checker();
ASSERT(checker);
std::vector<checker::Type *> unionConstituents;
unionConstituents.emplace_back(baseType);
unionConstituents.emplace_back(checker->GlobalIntType());
unionConstituents.emplace_back(baseType);
unionConstituents.emplace_back(checker->GlobalDoubleType());
unionConstituents.emplace_back(checker->GlobalShortType());
unionConstituents.emplace_back(checker->GlobalDoubleType());
auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
ASSERT_NE(normalizedType, nullptr);
ASSERT_TRUE(normalizedType->IsETSUnionType());
auto *const unionType = normalizedType->AsETSUnionType();
ASSERT_EQ(unionType->ConstituentTypes().size(), SIZE2);
ASSERT_EQ(unionType->ConstituentTypes().at(IDX0), baseType);
ASSERT_EQ(unionType->ConstituentTypes().at(IDX1), checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType());
}
TEST_F(UnionNormalizationTest, DISABLED_UnionWithNumeric1)
{
InitializeChecker("_.ets", "");
auto checker = Checker();
ASSERT(checker);
std::vector<checker::Type *> unionConstituents;
unionConstituents.emplace_back(checker->GlobalETSBooleanType());
unionConstituents.emplace_back(checker->GlobalIntType());
unionConstituents.emplace_back(checker->GlobalDoubleType());
unionConstituents.emplace_back(checker->GlobalShortType());
auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
ASSERT_NE(normalizedType, nullptr);
ASSERT_TRUE(normalizedType->IsETSUnionType());
auto *const unionType = normalizedType->AsETSUnionType();
ASSERT_EQ(unionType->ConstituentTypes().size(), SIZE2);
ASSERT_EQ(unionType->ConstituentTypes().at(IDX0), checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType());
ASSERT_EQ(unionType->ConstituentTypes().at(IDX1), checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType());
}
TEST_F(UnionNormalizationTest, DISABLED_UnionWithNumeric2)
{
InitializeChecker("_.ets", "class Base {}");
auto program = Program();
ASSERT(program);
auto *const baseType = FindClassType(program->VarBinder()->AsETSBinder(), "Base");
ASSERT_NE(baseType, nullptr);
auto checker = Checker();
ASSERT(checker);
std::vector<checker::Type *> unionConstituents;
unionConstituents.emplace_back(checker->GlobalBuiltinETSStringType());
unionConstituents.emplace_back(checker->GlobalIntType());
unionConstituents.emplace_back(baseType);
unionConstituents.emplace_back(checker->GlobalDoubleType());
unionConstituents.emplace_back(checker->GlobalShortType());
auto *const normalizedType = checker->CreateETSUnionType(std::move(unionConstituents));
ASSERT_NE(normalizedType, nullptr);
ASSERT_TRUE(normalizedType->IsETSUnionType());
auto *const unionType = normalizedType->AsETSUnionType();
ASSERT_EQ(unionType->ConstituentTypes().size(), SIZE3);
ASSERT_EQ(unionType->ConstituentTypes().at(IDX0), checker->GlobalBuiltinETSStringType());
ASSERT_EQ(unionType->ConstituentTypes().at(IDX1), baseType);
ASSERT_EQ(unionType->ConstituentTypes().at(IDX2), checker->GetGlobalTypesHolder()->GlobalDoubleBuiltinType());
}
}