2026-03-27 14:12:49 +01:00
/********************************************************************************
* 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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2025-11-04 13:28:06 +01:00
# include "includes.h"
# include "parser_test.h"
# include "../../../sdv_executables/sdv_idl_compiler/parser.h"
# include "../../../sdv_executables/sdv_idl_compiler/entities/definition_entity.h"
# include "../../../sdv_executables/sdv_idl_compiler/entities/struct_entity.h"
# include "../../../sdv_executables/sdv_idl_compiler/entities/variable_entity.h"
# include "../../../sdv_executables/sdv_idl_compiler/entities/declaration_entity.h"
# include "../../../sdv_executables/sdv_idl_compiler/entities/entity_value.h"
using CParserExtensionTest = CParserTest ;
TEST_F ( CParserExtensionTest , InterfaceType )
{
// Check the use of the interface_t and the interface_id types.
EXPECT_TRUE ( CParser ( " interface I{void func(in interface_t ifc);}; " ) . Parse ( ) . Root ( ) - > Find ( " I::func " ) ) ;
EXPECT_TRUE ( CParser ( " struct S{interface_t ifc;}; " ) . Parse ( ) . Root ( ) - > Find ( " S::ifc " ) ) ;
EXPECT_TRUE ( CParser ( " interface I{void func(in interface_id id);}; " ) . Parse ( ) . Root ( ) - > Find ( " I::func " ) ) ;
EXPECT_TRUE ( CParser ( " struct S{interface_id id;}; " ) . Parse ( ) . Root ( ) - > Find ( " S::id " ) ) ;
EXPECT_TRUE ( CParser ( " interface I{}; struct S{I ifc = null;}; " ) . Parse ( ) . Root ( ) - > Find ( " S::ifc " ) ) ;
EXPECT_THROW ( CParser ( " struct interface_t{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
EXPECT_THROW ( CParser ( " struct interface_id{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
EXPECT_THROW ( CParser ( " struct null{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env ;
std : : vector < std : : string > vec = { " idl_compiler_test " , " --interface_type- " } ;
env = CIdlCompilerEnvironment ( vec ) ;
EXPECT_FALSE ( env . InterfaceTypeExtension ( ) ) ;
EXPECT_THROW ( CParser ( " interface I{void func(in interface_t ifc);}; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_THROW ( CParser ( " struct S{interface_t ifc;}; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_THROW ( CParser ( " interface I{void func(in interface_id id);}; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_THROW ( CParser ( " struct S{interface_id id;}; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_THROW ( CParser ( " interface I{}; struct S{I ifc = null;}; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_TRUE ( CParser ( " struct interface_t{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " interface_t " ) ) ; // available as def name
EXPECT_TRUE ( CParser ( " struct interface_id{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " interface_id " ) ) ; // available as def name
EXPECT_TRUE ( CParser ( " struct null{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " null " ) ) ; // available as def name
}
TEST_F ( CParserExtensionTest , ExceptionId )
{
// Check the use of the exception_id type.
EXPECT_TRUE ( CParser ( " struct S{ exception_id id; }; " ) . Parse ( ) . Root ( ) - > Find ( " S::id " ) ) ;
EXPECT_THROW ( CParser ( " struct exception_id{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env ;
std : : vector < std : : string > vec = { " idl_compiler_test " , " --exception_type- " } ;
env = CIdlCompilerEnvironment ( vec ) ;
EXPECT_FALSE ( env . ExceptionTypeExtension ( ) ) ;
EXPECT_THROW ( CParser ( " struct S{ exception_id id; }; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_TRUE ( CParser ( " struct exception_id{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " exception_id " ) ) ; // available as def name
}
TEST_F ( CParserExtensionTest , PointerType )
{
// Check the use of the pointer type.
EXPECT_TRUE ( CParser ( " struct S{ pointer<uint8> ptr; }; " ) . Parse ( ) . Root ( ) - > Find ( " S::ptr " ) ) ;
EXPECT_THROW ( CParser ( " struct pointer{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env ;
std : : vector < std : : string > vec = { " idl_compiler_test " , " --pointer_type- " } ;
env = CIdlCompilerEnvironment ( vec ) ;
EXPECT_FALSE ( env . PointerTypeExtension ( ) ) ;
EXPECT_THROW ( CParser ( " struct S{ pointer<uint8> ptr; }; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_TRUE ( CParser ( " struct pointer{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " pointer " ) ) ; // available as def name
}
TEST_F ( CParserExtensionTest , UnicodeCharType )
{
// Check the use of the pointer type.
EXPECT_TRUE ( CParser ( " struct S{ char16 c16; }; " ) . Parse ( ) . Root ( ) - > Find ( " S::c16 " ) ) ;
EXPECT_TRUE ( CParser ( " struct S{ char32 c32; }; " ) . Parse ( ) . Root ( ) - > Find ( " S::c32 " ) ) ;
EXPECT_THROW ( CParser ( " struct char16{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
EXPECT_THROW ( CParser ( " struct char32{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env ;
std : : vector < std : : string > vec = { " idl_compiler_test " , " --unicode_char- " } ;
env = CIdlCompilerEnvironment ( vec ) ;
EXPECT_FALSE ( env . UnicodeExtension ( ) ) ;
EXPECT_THROW ( CParser ( " struct S{ char16 c16; }; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_THROW ( CParser ( " struct S{ char32 c32; }; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_TRUE ( CParser ( " struct char16{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " char16 " ) ) ; // available as def name
EXPECT_TRUE ( CParser ( " struct char32{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " char32 " ) ) ; // available as def name
}
TEST_F ( CParserExtensionTest , UnicodeStringType )
{
// Check the use of the pointer type.
EXPECT_TRUE ( CParser ( " struct S{ u8string ss8; }; " ) . Parse ( ) . Root ( ) - > Find ( " S::ss8 " ) ) ;
EXPECT_TRUE ( CParser ( " struct S{ u16string ss16; }; " ) . Parse ( ) . Root ( ) - > Find ( " S::ss16 " ) ) ;
EXPECT_TRUE ( CParser ( " struct S{ u32string ss32; }; " ) . Parse ( ) . Root ( ) - > Find ( " S::ss32 " ) ) ;
EXPECT_THROW ( CParser ( " struct u8string{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
EXPECT_THROW ( CParser ( " struct u16string{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
EXPECT_THROW ( CParser ( " struct u32string{}; " ) . Parse ( ) , CCompileException ) ; // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env ;
std : : vector < std : : string > vec = { " idl_compiler_test " , " --unicode_char- " } ;
env = CIdlCompilerEnvironment ( vec ) ;
EXPECT_FALSE ( env . UnicodeExtension ( ) ) ;
EXPECT_THROW ( CParser ( " struct S{ u8string ss8; }; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_THROW ( CParser ( " struct S{ u16string ss16; }; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_THROW ( CParser ( " struct S{ u32string ss32; }; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_TRUE ( CParser ( " struct u8string{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " u8string " ) ) ; // available as def name
EXPECT_TRUE ( CParser ( " struct u16string{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " u16string " ) ) ; // available as def name
EXPECT_TRUE ( CParser ( " struct u32string{}; " , env ) . Parse ( ) . Root ( ) - > Find ( " u32string " ) ) ; // available as def name
}
TEST_F ( CParserExtensionTest , CaseSensitivity )
{
// Disable case sensitivity
CIdlCompilerEnvironment env ;
std : : vector < std : : string > vec = { " idl_compiler_test " , " --case_sensitive- " } ;
env = CIdlCompilerEnvironment ( vec ) ;
EXPECT_FALSE ( env . CaseSensitiveTypeExtension ( ) ) ;
// Use identical keyword only differencing in case
EXPECT_TRUE ( CParser ( " struct Struct{}; " ) . Parse ( ) . Root ( ) - > Find ( " Struct " ) ) ;
EXPECT_THROW ( CParser ( " struct Struct{}; " , env ) . Parse ( ) , CCompileException ) ;
// Use identical identifiers only differencing in case
EXPECT_THROW ( CParser ( " struct S{ int32 i; int32 i;}; " ) . Parse ( ) , CCompileException ) ; // Case sensitive; two vars
EXPECT_THROW ( CParser ( " struct S{ int32 i; int32 i;}; " , env ) . Parse ( ) , CCompileException ) ; // Case insensitive; two vars
EXPECT_NO_THROW ( CParser ( " struct S { int32 i; int32 I; }; " ) . Parse ( ) ) ; // Case sensitive; two vars differ in case
EXPECT_THROW ( CParser ( " struct S { int32 i; int32 I; }; " , env ) . Parse ( ) , CCompileException ) ; // Case insensitive; two vars differ in case
EXPECT_NO_THROW ( CParser ( " struct S{}; struct S2{ S s; }; " ) . Parse ( ) ) ; // Case sensitive; def and decl differ in scope and case
EXPECT_NO_THROW ( CParser ( " struct S{}; struct S2{ S s; }; " , env ) . Parse ( ) ) ; // Case insensitive; def and decl differ in scope and case
}
TEST_F ( CParserExtensionTest , ContextDependentNames )
{
// Disable context dependent names
std : : vector < std : : string > vecNoContextDeptNamesCaseSensitive = { " idl_compiler_test " , " --context_names- " } ;
std : : vector < std : : string > vecNoContextDeptNamesCaseInsensitive = { " idl_compiler_test " , " --context_names- " , " --case_sensitive- " } ;
CIdlCompilerEnvironment envNoContextDeptNamesCaseSensitive ( vecNoContextDeptNamesCaseSensitive ) ;
CIdlCompilerEnvironment envNoContextDeptNamesCaseInsensitive ( vecNoContextDeptNamesCaseInsensitive ) ;
EXPECT_FALSE ( envNoContextDeptNamesCaseSensitive . ContextDependentNamesExtension ( ) ) ;
EXPECT_FALSE ( envNoContextDeptNamesCaseInsensitive . ContextDependentNamesExtension ( ) ) ;
EXPECT_FALSE ( envNoContextDeptNamesCaseInsensitive . CaseSensitiveTypeExtension ( ) ) ;
// Use identical identifiers only differencing in case
EXPECT_NO_THROW ( CParser ( " struct S2{ struct S{}; S s;}; " ) . Parse ( ) ) ; // Case sensitive; reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S2{ struct S{}; S s;}; " , envNoContextDeptNamesCaseSensitive ) . Parse ( ) ) ; // Case sensitive; reuse allowed
EXPECT_THROW ( CParser ( " struct S2{ struct S{}; S s;}; " , envNoContextDeptNamesCaseInsensitive ) . Parse ( ) , CCompileException ) ; // Names differ in case only; no reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S2{ struct S{}; S S;}; " ) . Parse ( ) ) ; // Context differs; reuse allowed
EXPECT_THROW ( CParser ( " struct S2{ struct S{}; S S;}; " , envNoContextDeptNamesCaseSensitive ) . Parse ( ) , CCompileException ) ; // Identical names; no reuse allowed
EXPECT_THROW ( CParser ( " struct S2{ struct S{}; S S;}; " , envNoContextDeptNamesCaseInsensitive ) . Parse ( ) , CCompileException ) ; // Identical names; no reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S2{ int16 s; struct S{};}; " ) . Parse ( ) ) ; // Case sensitive; reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S2{ int16 s; struct S{};}; " , envNoContextDeptNamesCaseSensitive ) . Parse ( ) ) ; // Case sensitive; reuse allowed
EXPECT_THROW ( CParser ( " struct S2{ int16 s; struct S{};}; " , envNoContextDeptNamesCaseInsensitive ) . Parse ( ) , CCompileException ) ; // Names differ in case only; no reuse allowed
EXPECT_THROW ( CParser ( " struct S2{ struct S{}; typedef int16 S;}; " ) . Parse ( ) , CCompileException ) ; // Identical names with no context change; no reuse allowed
EXPECT_THROW ( CParser ( " struct S2{ struct S{}; typedef int16 S;}; " , envNoContextDeptNamesCaseSensitive ) . Parse ( ) , CCompileException ) ; // Identical names; no reuse allowed
EXPECT_THROW ( CParser ( " struct S2{ struct S{}; typedef int16 S;}; " , envNoContextDeptNamesCaseInsensitive ) . Parse ( ) , CCompileException ) ; // Identical names; no reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S{ int16 attribute;}; " ) . Parse ( ) ) ; // Context differs; reuse allowed
EXPECT_THROW ( CParser ( " struct S{ int16 attribute;}; " , envNoContextDeptNamesCaseSensitive ) . Parse ( ) , CCompileException ) ; // Keyword is reserved; no reuse allowed
EXPECT_THROW ( CParser ( " struct S{ int16 attribute;}; " , envNoContextDeptNamesCaseInsensitive ) . Parse ( ) , CCompileException ) ; // Keyword is reserved; no reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S{ int16 Attribute;}; " ) . Parse ( ) ) ; // Context differs; reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S{ int16 Attribute;}; " , envNoContextDeptNamesCaseSensitive ) . Parse ( ) ) ; // Case sensitive; reuse allowed
EXPECT_THROW ( CParser ( " struct S{ int16 Attribute;}; " , envNoContextDeptNamesCaseInsensitive ) . Parse ( ) , CCompileException ) ; // Keyword name differs in case only; no reuse allowed
EXPECT_THROW ( CParser ( " struct S{ struct attribute{};}; " ) . Parse ( ) , CCompileException ) ; // Keyword is reserved; reuse allowed
EXPECT_THROW ( CParser ( " struct S{ struct attribute{};}; " , envNoContextDeptNamesCaseSensitive ) . Parse ( ) , CCompileException ) ; // Keyword is reserved; no reuse allowed
EXPECT_THROW ( CParser ( " struct S{ struct attribute{};}; " , envNoContextDeptNamesCaseInsensitive ) . Parse ( ) , CCompileException ) ; // Keyword is reserved; no reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S{ struct Attribute{};}; " ) . Parse ( ) ) ; // Case sensitive; reuse allowed
EXPECT_NO_THROW ( CParser ( " struct S{ struct Attribute{};}; " , envNoContextDeptNamesCaseSensitive ) . Parse ( ) ) ; // Case sensitive; reuse allowed
EXPECT_THROW ( CParser ( " struct S{ struct Attribute{};}; " , envNoContextDeptNamesCaseInsensitive ) . Parse ( ) , CCompileException ) ; // Keyword name differs in case only; no reuse allowed
}
TEST_F ( CParserExtensionTest , MultiDimArray )
{
// Disable multi dimensional arrays
CIdlCompilerEnvironment env ;
std : : vector < std : : string > vec = { " idl_compiler_test " , " --multi_dimensional_array- " } ;
env = CIdlCompilerEnvironment ( vec ) ;
EXPECT_FALSE ( env . MultiDimArrayExtension ( ) ) ;
// Declare arrays
EXPECT_NO_THROW ( CParser ( " const int16 rguiArr[1] = { 10 }; " ) . Parse ( ) ) ;
EXPECT_NO_THROW ( CParser ( " const int16 rguiArr[1] = { 10 }; " , env ) . Parse ( ) ) ;
EXPECT_NO_THROW ( CParser ( " struct S { int16 rguiArr[1]; }; " ) . Parse ( ) ) ;
EXPECT_NO_THROW ( CParser ( " struct S { int16 rguiArr[1]; }; " , env ) . Parse ( ) ) ;
EXPECT_NO_THROW ( CParser ( " const int16 rguiArr[1][1] = { { 10 } }; " ) . Parse ( ) ) ;
EXPECT_THROW ( CParser ( " const int16 rguiArr[1][1] = { { 10 } }; " , env ) . Parse ( ) , CCompileException ) ;
EXPECT_NO_THROW ( CParser ( " struct S { int16 rguiArr[1][1]; }; " ) . Parse ( ) ) ;
EXPECT_THROW ( CParser ( " struct S { int16 rguiArr[1][1]; }; " , env ) . Parse ( ) , CCompileException ) ;
}