// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "testimplicitconversions.h" #include "testutil.h" #include #include #include #include #include #include void TestImplicitConversions::testWithPrivateCtors() { const char cppCode[] = "\ class B;\n\ class C;\n\ class A {\n\ A(const B&);\n\ public:\n\ A(const C&);\n\ };\n\ class B {};\n\ class C {};\n"; const char xmlCode[] = "\ \n\ \n\ \n\ \n\ \n"; QScopedPointer builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(builder); AbstractMetaClassList classes = builder->classes(); QCOMPARE(classes.size(), 3); const auto classA = AbstractMetaClass::findClass(classes, "A"); const auto classC = AbstractMetaClass::findClass(classes, "C"); const auto implicitConvs = classA->implicitConversions(); QCOMPARE(implicitConvs.size(), 1); QCOMPARE(implicitConvs.constFirst()->arguments().constFirst().type().typeEntry(), classC->typeEntry()); } void TestImplicitConversions::testWithModifiedVisibility() { const char cppCode[] = "\ class B;\n\ class A {\n\ public:\n\ A(const B&);\n\ };\n\ class B {};\n"; const char xmlCode[] = R"( )"; QScopedPointer builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(builder); AbstractMetaClassList classes = builder->classes(); QCOMPARE(classes.size(), 2); const auto classA = AbstractMetaClass::findClass(classes, "A"); const auto classB = AbstractMetaClass::findClass(classes, "B"); const auto implicitConvs = classA->implicitConversions(); QCOMPARE(implicitConvs.size(), 1); QCOMPARE(implicitConvs.constFirst()->arguments().constFirst().type().typeEntry(), classB->typeEntry()); } void TestImplicitConversions::testWithAddedCtor() { const char cppCode[] = "\ class B;\n\ class A {\n\ public:\n\ A(const B&);\n\ };\n\ class B {};\n\ class C {};\n"; const char xmlCode[] = "\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n"; QScopedPointer builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(builder); AbstractMetaClassList classes = builder->classes(); QCOMPARE(classes.size(), 3); const auto classA = AbstractMetaClass::findClass(classes, "A"); auto implicitConvs = classA->implicitConversions(); QCOMPARE(implicitConvs.size(), 2); // Added constructors with custom types should never result in implicit converters. const auto classB = AbstractMetaClass::findClass(classes, "B"); implicitConvs = classB->implicitConversions(); QCOMPARE(implicitConvs.size(), 0); } void TestImplicitConversions::testWithExternalConversionOperator() { const char cppCode[] = "\ class A {};\n\ struct B {\n\ operator A() const;\n\ };\n"; const char xmlCode[] = "\n\ \n\ \n\ \n\ \n"; QScopedPointer builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(builder); AbstractMetaClassList classes = builder->classes(); QCOMPARE(classes.size(), 2); const auto classA = AbstractMetaClass::findClass(classes, "A"); const auto classB = AbstractMetaClass::findClass(classes, "B"); const auto implicitConvs = classA->implicitConversions(); QCOMPARE(implicitConvs.size(), 1); const auto &externalConvOps = classA->externalConversionOperators(); QCOMPARE(externalConvOps.size(), 1); AbstractMetaFunctionCPtr convOp; for (const auto &func : classB->functions()) { if (func->isConversionOperator()) convOp = func; } QVERIFY(convOp); QCOMPARE(implicitConvs.constFirst(), convOp); } QTEST_APPLESS_MAIN(TestImplicitConversions)