/******************************************************************************** * Copyright (c) 2025-2026 ZF Friedrichshafen AG * * This program and the accompanying materials are made available under the * terms of the Apache License Version 2.0 which is available at * https://www.apache.org/licenses/LICENSE-2.0 * * SPDX-License-Identifier: Apache-2.0 * * Contributors: * Erik Verhoeven - initial API and implementation ********************************************************************************/ #include "includes.h" #include "parser_test.h" #include "../../../sdv_executables/sdv_idl_compiler/parser.h" #include "../../../sdv_executables/sdv_idl_compiler/entities/exception_entity.cpp" using CParserExceptionTest = CParserTest; TEST_F(CParserExceptionTest, ForwardDeclaration) { // exception ; --> forward declaration EXPECT_TRUE(CParser("exception X1; exception X1 {};").Parse().Root()->Find("X1")); EXPECT_TRUE(CParser("exception X1 {}; exception X1;").Parse().Root()->Find("X1")); EXPECT_TRUE(CParser("exception X1; exception X1; exception X1; exception X1;").Parse().Root()->Find("X1")); EXPECT_TRUE(CParser("exception X1 {}; exception X1; exception X1; ").Parse().Root()->Find("X1")); EXPECT_THROW(CParser("exception X1 {}; exception X1; exception X1 {}; ").Parse(), CCompileException); EXPECT_THROW(CParser("exception X1; struct X1 {};").Parse(), CCompileException); } TEST_F(CParserExceptionTest, Definition) { // exception {...}; --> exception definition EXPECT_TRUE(CParser("exception X2 {};").Parse().Root()->Find("X2")); EXPECT_TRUE(CParser("exception X2 { int32 i; };").Parse().Root()->Find("X2")); EXPECT_TRUE(CParser("exception X2 { int32 i; };").Parse().Root()->Find("X2::i")); } TEST_F(CParserExceptionTest, DefinitionWithInheritance) { // exception : {...}; --> exception definition with inheritance EXPECT_TRUE(CParser("exception X3base {int32 i = 1;}; exception X3 : X3base {int32 j = 1;};").Parse().Root()->Find("X3::i")); EXPECT_THROW(CParser("exception X3base {int32 i = 1;}; struct S3 : X3base {int32 j = 1;};").Parse(), CCompileException); } TEST_F(CParserExceptionTest, VariableDeclaration) { // ; --> exception variable declaration EXPECT_TRUE(CParser("exception X{struct S4 {int32 i;}; S4 s4Value;};").Parse().Root()->Find("X::s4Value")); // exception ; --> exception variable declaration EXPECT_TRUE(CParser("exception X{struct S6 {int32 i;}; struct S6 s6Value;};").Parse().Root()->Find("X::s6Value")); } TEST_F(CParserExceptionTest, VarDeclarationAndAssignment) { // = {...}; --> exception variable declaration and assignment EXPECT_TRUE(CParser("exception X{struct S5 {int32 i;}; S5 s5Value = {10};};").Parse().Root()->Find("X::s5Value")); EXPECT_TRUE(CParser("exception X{struct S5b {int32 i = 11;}; S5b s5bValue = {10};};").Parse().Root()->Find("X::s5bValue")); // exception = {...}; --> exception variable declaration and assignment EXPECT_TRUE(CParser("exception X{struct S7 {int32 i;}; struct S7 s7Value = {10};};").Parse().Root()->Find("X::s7Value")); } TEST_F(CParserExceptionTest, DefinitionAndVariableDeclaration) { // exception {...} ; --> exception definition and variable declaration EXPECT_TRUE(CParser("exception X{struct S8 {int32 i;} s8Value;};").Parse().Root()->Find("X::s8Value")); } TEST_F(CParserExceptionTest, DefinitionWithInheritanceAndVariableDeclaration) { // exception : {...} ; --> exception definition with inheritance and variable declaration EXPECT_TRUE(CParser("exception X{struct S9base {int32 i;}; struct S9 : S9base {int32 j;} s9Value;};").Parse().Root()->Find("X::s9Value")); } TEST_F(CParserExceptionTest, DefinitionAndVariableDeclarationAndAssignment) { // exception {...} = {...}; --> exception definition, variable declaration and assignment EXPECT_TRUE(CParser("exception X{struct S10 {int32 i;} s10Value = {10};};").Parse().Root()->Find("X::s10Value")); } TEST_F(CParserExceptionTest, DefinitionWithInheritanceAndVariableDeclarationAndAssignment) { // exception : {...} = {...}; --> exception definition with inheritance, variable declaration and assignment EXPECT_TRUE(CParser("exception X{struct S11base {int32 i;}; struct S11 : S11base {int32 j;} s11Value = {{10}, 10};};").Parse().Root()->Find("X::s11Value")); EXPECT_TRUE(CParser("exception X{struct S11base {int32 i;}; struct S11 : S11base {} s11Value = {{10}};};").Parse().Root()->Find("X::s11Value")); } TEST_F(CParserExceptionTest, UnnamedDefinitionAndVariableDeclaration) { // exception {...} ; --> unnamed exception definition and variable declaration // NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard EXPECT_THROW(CParser("exception X{struct {int32 i;} s12Value;};").Parse(), CCompileException); } TEST_F(CParserExceptionTest, UnnamedDefinitionWithInheritanceAndVariableDeclaration) { // exception : {...} ; --> unnamed exception definition with inheritance and variable declaration // NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard EXPECT_THROW(CParser("exception X{struct S13base {int32 i;}; struct : S13base {int32 j;} s13Value;};").Parse(), CCompileException); } TEST_F(CParserExceptionTest, UnnamedDefinitionAndVariableDeclarationAndAssignment) { // exception {...} = {...}; --> unnamed exception definition, variable declaration and assignment // NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard EXPECT_THROW(CParser("exception X{struct {int32 i;} s14Value = {10};};").Parse(), CCompileException); } TEST_F(CParserExceptionTest, UnnamedDefinitionWithInheritanceAndVariableDeclarationAndAssignment) { // exception : {...} = {...}; --> unnamed exception definition with inheritance, variable declaration and assignment // NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard EXPECT_THROW(CParser("exception X{struct S15base {int32 i;}; struct : S15base {int32 j;} s15Value = {{10}, 10};};").Parse(), CCompileException); } TEST_F(CParserExceptionTest, ComplexCombinationWithStructTypedefMultiDimmensionalArrayDeclarations) { const char szCode[] = R"code( exception X { const int32 a = 2; typedef int32 intarray[a]; typedef intarray initintarray[3][1]; initintarray rgarray[4] = {{{{1,2}}, {{3,4}}, {{5,6}}}, {{{7,8}},{{9,10}}, {{a,b}}}, {{{13,14}}, {{15,16}}, {{17,18}}}, {{{19,20}},{{21,22}}, {{23,24}}} }; const int32 b = 4; }; )code"; CParser parser(szCode); EXPECT_NO_THROW(parser.Parse()); CEntityPtr ptrVar = parser.Root()->Find("X::rgarray"); ASSERT_TRUE(ptrVar); CDeclarationEntity* pVar = ptrVar->Get(); ASSERT_NE(pVar, nullptr); CValueNodePtr ptrVal = ptrVar->ValueRef(); ASSERT_TRUE(ptrVal); CArrayValueNode* pInitIntArrayVal = ptrVal->Get(); ASSERT_NE(pInitIntArrayVal, nullptr); EXPECT_EQ(pInitIntArrayVal->GetSize(), 4); CValueNodePtr ptrIntArrayVal = (*pInitIntArrayVal)[3]; ASSERT_TRUE(ptrIntArrayVal); CArrayValueNode* pIntArrayVal = ptrIntArrayVal->Get(); ASSERT_NE(pIntArrayVal, nullptr); EXPECT_EQ(pIntArrayVal->GetSize(), 3); CValueNodePtr ptrIntArrayVal_2 = (*pIntArrayVal)[2]; ASSERT_TRUE(ptrIntArrayVal_2); CArrayValueNode* pIntArrayVal_2 = ptrIntArrayVal_2->Get(); ASSERT_NE(pIntArrayVal_2, nullptr); EXPECT_EQ(pIntArrayVal_2->GetSize(), 1); CValueNodePtr ptrIntArrayVal_3 = (*pIntArrayVal_2)[0]; ASSERT_TRUE(ptrIntArrayVal_3); CArrayValueNode* pIntArrayVal_3 = ptrIntArrayVal_3->Get(); ASSERT_NE(pIntArrayVal_3, nullptr); EXPECT_EQ(pIntArrayVal_3->GetSize(), 2); CValueNodePtr ptrIntVal = (*pIntArrayVal_3)[1]; ASSERT_TRUE(ptrIntVal); CSimpleTypeValueNode* pIntVal = ptrIntVal->Get(); ASSERT_NE(pIntVal, nullptr); EXPECT_EQ(pIntVal->Variant().Get(), 24); }