From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- cli_ure/CliLibrary_cli_basetypes.mk | 35 + cli_ure/CliLibrary_cli_ure.mk | 35 + cli_ure/CliNativeLibrary_cli_cppuhelper.mk | 27 + cli_ure/CliUnoApi_cli_uretypes.mk | 24 + cli_ure/CustomTarget_cli_ure_assemblies.mk | 55 + cli_ure/Executable_climaker.mk | 50 + cli_ure/Library_cli_cppuhelper_native.mk | 51 + cli_ure/Library_cli_uno.mk | 40 + cli_ure/Makefile | 7 + cli_ure/Module_cli_ure.mk | 28 + cli_ure/Package_cli_basetypes_copy.mk | 18 + cli_ure/README.md | 7 + cli_ure/qa/climaker/ClimakerTestCase.java | 91 + cli_ure/qa/climaker/climaker.cs | 1478 +++++++++++++ cli_ure/qa/climaker/makefile.mk | 126 ++ cli_ure/qa/climaker/testobjects.cs | 579 +++++ cli_ure/qa/climaker/types.idl | 477 ++++ cli_ure/qa/versioning/readme.txt | 19 + cli_ure/readme.txt | 263 +++ cli_ure/source/basetypes/assembly.cs | 21 + cli_ure/source/basetypes/cli_basetypes_config | 11 + cli_ure/source/basetypes/uno/Any.cs | 202 ++ cli_ure/source/basetypes/uno/BoundAttribute.cs | 37 + cli_ure/source/basetypes/uno/ExceptionAttribute.cs | 61 + cli_ure/source/basetypes/uno/OnewayAttribute.cs | 34 + .../basetypes/uno/ParameterizedTypeAttribute.cs | 59 + cli_ure/source/basetypes/uno/PolymorphicType.cs | 434 ++++ .../source/basetypes/uno/TypeArgumentsAttribute.cs | 75 + .../basetypes/uno/TypeParametersAttribute.cs | 56 + cli_ure/source/climaker/climaker_app.cxx | 675 ++++++ cli_ure/source/climaker/climaker_emit.cxx | 2279 ++++++++++++++++++++ cli_ure/source/climaker/climaker_share.h | 258 +++ cli_ure/source/cliuno.snk | Bin 0 -> 596 bytes cli_ure/source/native/assembly.cxx | 26 + cli_ure/source/native/cli_cppuhelper_config | 11 + cli_ure/source/native/native_bootstrap.cxx | 297 +++ cli_ure/source/native/native_share.h | 112 + cli_ure/source/native/path.cxx | 48 + cli_ure/source/scripts/increment_version.pl | 273 +++ cli_ure/source/scripts/subst_template.pl | 124 ++ cli_ure/source/uno_bridge/README.txt | 20 + cli_ure/source/uno_bridge/cli_base.h | 171 ++ cli_ure/source/uno_bridge/cli_bridge.cxx | 321 +++ cli_ure/source/uno_bridge/cli_bridge.h | 113 + cli_ure/source/uno_bridge/cli_data.cxx | 1929 +++++++++++++++++ cli_ure/source/uno_bridge/cli_environment.cxx | 168 ++ cli_ure/source/uno_bridge/cli_environment.h | 105 + cli_ure/source/uno_bridge/cli_proxy.cxx | 1105 ++++++++++ cli_ure/source/uno_bridge/cli_proxy.h | 294 +++ cli_ure/source/uno_bridge/cli_uno.cxx | 277 +++ cli_ure/source/ure/assembly.cs | 21 + cli_ure/source/ure/cli_ure_config | 11 + cli_ure/source/ure/uno/util/DisposeGuard.cs | 50 + cli_ure/source/ure/uno/util/WeakAdapter.cs | 111 + cli_ure/source/ure/uno/util/WeakBase.cs | 135 ++ cli_ure/source/ure/uno/util/WeakComponentBase.cs | 185 ++ cli_ure/unotypes/cli_uretypes_config | 11 + cli_ure/version/incversions.txt | 34 + cli_ure/version/version.txt | 38 + 59 files changed, 13602 insertions(+) create mode 100644 cli_ure/CliLibrary_cli_basetypes.mk create mode 100644 cli_ure/CliLibrary_cli_ure.mk create mode 100644 cli_ure/CliNativeLibrary_cli_cppuhelper.mk create mode 100644 cli_ure/CliUnoApi_cli_uretypes.mk create mode 100644 cli_ure/CustomTarget_cli_ure_assemblies.mk create mode 100644 cli_ure/Executable_climaker.mk create mode 100644 cli_ure/Library_cli_cppuhelper_native.mk create mode 100644 cli_ure/Library_cli_uno.mk create mode 100644 cli_ure/Makefile create mode 100644 cli_ure/Module_cli_ure.mk create mode 100644 cli_ure/Package_cli_basetypes_copy.mk create mode 100644 cli_ure/README.md create mode 100644 cli_ure/qa/climaker/ClimakerTestCase.java create mode 100644 cli_ure/qa/climaker/climaker.cs create mode 100644 cli_ure/qa/climaker/makefile.mk create mode 100644 cli_ure/qa/climaker/testobjects.cs create mode 100644 cli_ure/qa/climaker/types.idl create mode 100644 cli_ure/qa/versioning/readme.txt create mode 100644 cli_ure/readme.txt create mode 100644 cli_ure/source/basetypes/assembly.cs create mode 100644 cli_ure/source/basetypes/cli_basetypes_config create mode 100644 cli_ure/source/basetypes/uno/Any.cs create mode 100644 cli_ure/source/basetypes/uno/BoundAttribute.cs create mode 100644 cli_ure/source/basetypes/uno/ExceptionAttribute.cs create mode 100644 cli_ure/source/basetypes/uno/OnewayAttribute.cs create mode 100644 cli_ure/source/basetypes/uno/ParameterizedTypeAttribute.cs create mode 100644 cli_ure/source/basetypes/uno/PolymorphicType.cs create mode 100644 cli_ure/source/basetypes/uno/TypeArgumentsAttribute.cs create mode 100644 cli_ure/source/basetypes/uno/TypeParametersAttribute.cs create mode 100644 cli_ure/source/climaker/climaker_app.cxx create mode 100644 cli_ure/source/climaker/climaker_emit.cxx create mode 100644 cli_ure/source/climaker/climaker_share.h create mode 100644 cli_ure/source/cliuno.snk create mode 100644 cli_ure/source/native/assembly.cxx create mode 100644 cli_ure/source/native/cli_cppuhelper_config create mode 100644 cli_ure/source/native/native_bootstrap.cxx create mode 100644 cli_ure/source/native/native_share.h create mode 100644 cli_ure/source/native/path.cxx create mode 100644 cli_ure/source/scripts/increment_version.pl create mode 100644 cli_ure/source/scripts/subst_template.pl create mode 100644 cli_ure/source/uno_bridge/README.txt create mode 100644 cli_ure/source/uno_bridge/cli_base.h create mode 100644 cli_ure/source/uno_bridge/cli_bridge.cxx create mode 100644 cli_ure/source/uno_bridge/cli_bridge.h create mode 100644 cli_ure/source/uno_bridge/cli_data.cxx create mode 100644 cli_ure/source/uno_bridge/cli_environment.cxx create mode 100644 cli_ure/source/uno_bridge/cli_environment.h create mode 100644 cli_ure/source/uno_bridge/cli_proxy.cxx create mode 100644 cli_ure/source/uno_bridge/cli_proxy.h create mode 100644 cli_ure/source/uno_bridge/cli_uno.cxx create mode 100644 cli_ure/source/ure/assembly.cs create mode 100644 cli_ure/source/ure/cli_ure_config create mode 100644 cli_ure/source/ure/uno/util/DisposeGuard.cs create mode 100644 cli_ure/source/ure/uno/util/WeakAdapter.cs create mode 100644 cli_ure/source/ure/uno/util/WeakBase.cs create mode 100644 cli_ure/source/ure/uno/util/WeakComponentBase.cs create mode 100644 cli_ure/unotypes/cli_uretypes_config create mode 100644 cli_ure/version/incversions.txt create mode 100644 cli_ure/version/version.txt (limited to 'cli_ure') diff --git a/cli_ure/CliLibrary_cli_basetypes.mk b/cli_ure/CliLibrary_cli_basetypes.mk new file mode 100644 index 000000000..30f284fd5 --- /dev/null +++ b/cli_ure/CliLibrary_cli_basetypes.mk @@ -0,0 +1,35 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +include $(SRCDIR)/cli_ure/version/version.txt + +$(eval $(call gb_CliLibrary_CliLibrary,cli_basetypes)) + +$(eval $(call gb_CliLibrary_set_configfile,cli_basetypes,cli_ure/source/basetypes/cli_basetypes_config,cli_ure/version/version.txt)) + +$(eval $(call gb_CliLibrary_set_keyfile,cli_basetypes,$(SRCDIR)/cli_ure/source/cliuno.snk)) + +$(eval $(call gb_CliLibrary_set_policy,cli_basetypes,$(CLI_BASETYPES_POLICY_ASSEMBLY),$(CLI_BASETYPES_POLICY_VERSION))) + +$(eval $(call gb_CliLibrary_add_csfiles,cli_basetypes,\ + cli_ure/source/basetypes/uno/Any \ + cli_ure/source/basetypes/uno/BoundAttribute \ + cli_ure/source/basetypes/uno/ExceptionAttribute \ + cli_ure/source/basetypes/uno/OnewayAttribute \ + cli_ure/source/basetypes/uno/ParameterizedTypeAttribute \ + cli_ure/source/basetypes/uno/PolymorphicType \ + cli_ure/source/basetypes/uno/TypeArgumentsAttribute \ + cli_ure/source/basetypes/uno/TypeParametersAttribute \ +)) + +$(eval $(call gb_CliLibrary_add_generated_csfiles,cli_basetypes,\ + CustomTarget/cli_ure/source/basetypes/assembly \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/CliLibrary_cli_ure.mk b/cli_ure/CliLibrary_cli_ure.mk new file mode 100644 index 000000000..1f320a02d --- /dev/null +++ b/cli_ure/CliLibrary_cli_ure.mk @@ -0,0 +1,35 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +include $(SRCDIR)/cli_ure/version/version.txt + +$(eval $(call gb_CliLibrary_CliLibrary,cli_ure)) + +$(eval $(call gb_CliLibrary_set_configfile,cli_ure,cli_ure/source/ure/cli_ure_config,cli_ure/version/version.txt)) + +$(eval $(call gb_CliLibrary_set_keyfile,cli_ure,$(SRCDIR)/cli_ure/source/cliuno.snk)) + +$(eval $(call gb_CliLibrary_set_policy,cli_ure,$(CLI_URE_POLICY_ASSEMBLY),$(CLI_URE_POLICY_VERSION))) + +$(eval $(call gb_CliLibrary_use_assemblies,cli_ure,\ + cli_uretypes \ +)) + +$(eval $(call gb_CliLibrary_add_csfiles,cli_ure,\ + cli_ure/source/ure/uno/util/DisposeGuard \ + cli_ure/source/ure/uno/util/WeakAdapter \ + cli_ure/source/ure/uno/util/WeakBase \ + cli_ure/source/ure/uno/util/WeakComponentBase \ +)) + +$(eval $(call gb_CliLibrary_add_generated_csfiles,cli_ure,\ + CustomTarget/cli_ure/source/ure/assembly \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/CliNativeLibrary_cli_cppuhelper.mk b/cli_ure/CliNativeLibrary_cli_cppuhelper.mk new file mode 100644 index 000000000..0fa516714 --- /dev/null +++ b/cli_ure/CliNativeLibrary_cli_cppuhelper.mk @@ -0,0 +1,27 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +include $(SRCDIR)/cli_ure/version/version.txt + +$(eval $(call gb_CliNativeLibrary_CliNativeLibrary,cli_cppuhelper)) + +$(eval $(call gb_CliNativeLibrary_wrap_library,cli_cppuhelper,cli_cppuhelper)) + +$(eval $(call gb_CliNativeLibrary_set_configfile,cli_cppuhelper,cli_ure/source/native/cli_cppuhelper_config,cli_ure/version/version.txt)) + +$(eval $(call gb_CliNativeLibrary_set_keyfile,cli_cppuhelper,$(SRCDIR)/cli_ure/source/cliuno.snk)) + +$(eval $(call gb_CliNativeLibrary_set_policy,cli_cppuhelper,$(CLI_CPPUHELPER_POLICY_ASSEMBLY),$(CLI_CPPUHELPER_POLICY_VERSION))) + +$(eval $(call gb_CliNativeLibrary_use_assemblies,cli_cppuhelper,\ + cli_ure \ + cli_uretypes \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/CliUnoApi_cli_uretypes.mk b/cli_ure/CliUnoApi_cli_uretypes.mk new file mode 100644 index 000000000..c8bceb55b --- /dev/null +++ b/cli_ure/CliUnoApi_cli_uretypes.mk @@ -0,0 +1,24 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +include $(SRCDIR)/cli_ure/version/version.txt + +$(eval $(call gb_CliUnoApi_CliUnoApi,cli_uretypes)) + +$(eval $(call gb_CliUnoApi_set_assembly_version,cli_uretypes,$(CLI_URETYPES_NEW_VERSION))) + +$(eval $(call gb_CliUnoApi_set_configfile,cli_uretypes,cli_ure/unotypes/cli_uretypes_config,cli_ure/version/version.txt)) + +$(eval $(call gb_CliUnoApi_set_keyfile,cli_uretypes,$(SRCDIR)/cli_ure/source/cliuno.snk)) + +$(eval $(call gb_CliUnoApi_set_policy,cli_uretypes,$(CLI_URETYPES_POLICY_ASSEMBLY),$(CLI_URETYPES_POLICY_VERSION))) + +$(eval $(call gb_CliUnoApi_wrap_api,cli_uretypes,udkapi)) + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/CustomTarget_cli_ure_assemblies.mk b/cli_ure/CustomTarget_cli_ure_assemblies.mk new file mode 100644 index 000000000..260a52b25 --- /dev/null +++ b/cli_ure/CustomTarget_cli_ure_assemblies.mk @@ -0,0 +1,55 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +cli_ure_source_MAKEFILE := $(lastword $(MAKEFILE_LIST)) + +include $(SRCDIR)/cli_ure/version/version.txt + +$(eval $(call gb_CustomTarget_CustomTarget,cli_ure/source)) + +$(call gb_CustomTarget_get_target,cli_ure/source) : \ + $(call gb_CustomTarget_get_workdir,cli_ure/source)/basetypes/assembly.cs \ + $(call gb_CustomTarget_get_workdir,cli_ure/source)/native/assembly.cxx \ + $(call gb_CustomTarget_get_workdir,cli_ure/source)/ure/assembly.cs + +$(call gb_CustomTarget_get_workdir,cli_ure/source)/basetypes/assembly.cs : \ + $(SRCDIR)/cli_ure/source/basetypes/assembly.cs \ + $(SRCDIR)/cli_ure/version/version.txt \ + $(cli_ure_source_MAKEFILE) \ + | $(call gb_CustomTarget_get_workdir,cli_ure/source)/basetypes/.dir + +$(call gb_CustomTarget_get_workdir,cli_ure/source)/native/assembly.cxx : \ + $(SRCDIR)/cli_ure/source/native/assembly.cxx \ + $(SRCDIR)/cli_ure/version/version.txt \ + $(cli_ure_source_MAKEFILE) \ + | $(call gb_CustomTarget_get_workdir,cli_ure/source)/native/.dir + +$(call gb_CustomTarget_get_workdir,cli_ure/source)/ure/assembly.cs : \ + $(SRCDIR)/cli_ure/source/ure/assembly.cs \ + $(SRCDIR)/cli_ure/version/version.txt \ + $(cli_ure_source_MAKEFILE) \ + | $(call gb_CustomTarget_get_workdir,cli_ure/source)/ure/.dir + +$(call gb_CustomTarget_get_workdir,cli_ure/source)/basetypes/assembly.cs : + sed -e "s/@CLI_BASETYPES_NEW_VERSION@/$(CLI_BASETYPES_NEW_VERSION)/g" \ + < $< > $@.tmp && \ + mv $@.tmp $@ + +# TODO use macros for this +$(call gb_CustomTarget_get_workdir,cli_ure/source)/native/assembly.cxx : + sed -e "s/@CLI_CPPUHELPER_NEW_VERSION@/$(CLI_CPPUHELPER_NEW_VERSION)/g" \ + < $< > $@.tmp && \ + mv $@.tmp $@ + +$(call gb_CustomTarget_get_workdir,cli_ure/source)/ure/assembly.cs : + sed -e "s/@CLI_URE_NEW_VERSION@/$(CLI_URE_NEW_VERSION)/g" \ + < $< > $@.tmp && \ + mv $@.tmp $@ + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/Executable_climaker.mk b/cli_ure/Executable_climaker.mk new file mode 100644 index 000000000..f0769b627 --- /dev/null +++ b/cli_ure/Executable_climaker.mk @@ -0,0 +1,50 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Executable_Executable,climaker)) + +$(eval $(call gb_Executable_use_package,climaker,\ + cli_basetypes_copy \ +)) + +$(eval $(call gb_Executable_add_cxxclrflags,climaker,\ + -LN \ + -wd4715 \ +)) + +$(eval $(call gb_Executable_add_ldflags,climaker,\ + -ignore:4248 \ +)) + +$(eval $(call gb_Executable_use_internal_bootstrap_api,climaker,\ + udkapi \ +)) + +$(eval $(call gb_Executable_use_libraries,climaker,\ + cppu \ + cppuhelper \ + sal \ + salhelper \ + unoidl \ +)) + +$(eval $(call gb_Executable_use_system_win32_libs,climaker,\ + mscoree \ + msvcmrt \ +)) + +$(eval $(call gb_Executable_add_cxxclrobjects,climaker,\ + cli_ure/source/climaker/climaker_app \ + cli_ure/source/climaker/climaker_emit \ +)) + +$(call gb_Executable_get_headers_target,climaker) : \ + $(call gb_CliLibrary_get_target,cli_basetypes) + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/Library_cli_cppuhelper_native.mk b/cli_ure/Library_cli_cppuhelper_native.mk new file mode 100644 index 000000000..bb230fb01 --- /dev/null +++ b/cli_ure/Library_cli_cppuhelper_native.mk @@ -0,0 +1,51 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +include $(SRCDIR)/cli_ure/version/version.txt + +$(eval $(call gb_Library_Assembly,cli_cppuhelper)) + +$(eval $(call gb_Library_add_ldflags,cli_cppuhelper,\ + -ignore:4248 \ + -keyfile:$(SRCDIR)/cli_ure/source/cliuno.snk \ +)) + +$(eval $(call gb_Library_add_ldflags,cli_cppuhelper,\ + -delayload:$(call gb_Library_get_filename,cppuhelper) \ + -delayload:$(call gb_Library_get_filename,cppu) \ + -delayload:$(call gb_Library_get_filename,sal) \ +)) + +$(eval $(call gb_Library_use_internal_bootstrap_api,cli_cppuhelper,\ + udkapi \ +)) + +$(eval $(call gb_Library_use_libraries,cli_cppuhelper,\ + cppu \ + cppuhelper \ + sal \ +)) + +$(eval $(call gb_Library_use_system_win32_libs,cli_cppuhelper,\ + advapi32 \ + delayimp \ + mscoree \ + msvcmrt \ +)) + +$(eval $(call gb_Library_add_cxxclrobjects,cli_cppuhelper,\ + cli_ure/source/native/native_bootstrap \ + cli_ure/source/native/path \ +)) + +$(eval $(call gb_Library_add_generated_cxxclrobjects,cli_cppuhelper,\ + CustomTarget/cli_ure/source/native/assembly \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/Library_cli_uno.mk b/cli_ure/Library_cli_uno.mk new file mode 100644 index 000000000..75eadae72 --- /dev/null +++ b/cli_ure/Library_cli_uno.mk @@ -0,0 +1,40 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Library_Library,cli_uno)) + +$(eval $(call gb_Library_add_ldflags,cli_uno,\ + -ignore:4248 \ +)) + +$(eval $(call gb_Library_use_udk_api,cli_uno)) + +$(eval $(call gb_Library_use_libraries,cli_uno,\ + cppu \ + sal \ +)) + +$(eval $(call gb_Library_use_system_win32_libs,cli_uno,\ + mscoree \ + msvcmrt \ +)) + +$(eval $(call gb_Library_add_cxxclrobjects,cli_uno,\ + cli_ure/source/uno_bridge/cli_bridge \ + cli_ure/source/uno_bridge/cli_data \ + cli_ure/source/uno_bridge/cli_environment \ + cli_ure/source/uno_bridge/cli_proxy \ + cli_ure/source/uno_bridge/cli_uno \ +)) + +$(call gb_Library_get_headers_target,cli_uno) :| \ + $(call gb_CliLibrary_get_target,cli_ure) \ + $(call gb_CliUnoApi_get_target,cli_uretypes) + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/Makefile b/cli_ure/Makefile new file mode 100644 index 000000000..ccb1c85a0 --- /dev/null +++ b/cli_ure/Makefile @@ -0,0 +1,7 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- + +module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) + +include $(module_directory)/../solenv/gbuild/partial_build.mk + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/Module_cli_ure.mk b/cli_ure/Module_cli_ure.mk new file mode 100644 index 000000000..3730ebdc7 --- /dev/null +++ b/cli_ure/Module_cli_ure.mk @@ -0,0 +1,28 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Module_Module,cli_ure)) + +ifeq ($(COM),MSC) +ifneq ($(CPUNAME),AARCH64) +$(eval $(call gb_Module_add_targets,cli_ure,\ + CliLibrary_cli_basetypes \ + CliLibrary_cli_ure \ + CliNativeLibrary_cli_cppuhelper \ + CliUnoApi_cli_uretypes \ + CustomTarget_cli_ure_assemblies \ + Executable_climaker \ + Library_cli_cppuhelper_native \ + Library_cli_uno \ + Package_cli_basetypes_copy \ +)) +endif +endif + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/Package_cli_basetypes_copy.mk b/cli_ure/Package_cli_basetypes_copy.mk new file mode 100644 index 000000000..75abab150 --- /dev/null +++ b/cli_ure/Package_cli_basetypes_copy.mk @@ -0,0 +1,18 @@ + +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Package_Package,cli_basetypes_copy,$(INSTROOT))) + +# duplicate copy to work around CLR DLL finding brain damage +$(eval $(call gb_Package_add_files,cli_basetypes_copy,$(SDKDIRNAME)/bin,\ + $(LIBO_URE_LIB_FOLDER)/cli_basetypes.dll \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/cli_ure/README.md b/cli_ure/README.md new file mode 100644 index 000000000..b6f27e7c6 --- /dev/null +++ b/cli_ure/README.md @@ -0,0 +1,7 @@ +# Common Language Infrastructure (CLI) UNO Runtime Environment + +Support assemblies and tools for the MS .NET UNO binding. + +## See also + +`[git:cli_ure/readme.txt]` diff --git a/cli_ure/qa/climaker/ClimakerTestCase.java b/cli_ure/qa/climaker/ClimakerTestCase.java new file mode 100644 index 000000000..b90c3844b --- /dev/null +++ b/cli_ure/qa/climaker/ClimakerTestCase.java @@ -0,0 +1,91 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ +package climaker; + + +import complexlib.ComplexTestCase; + + +public class ClimakerTestCase extends ComplexTestCase +{ + @Override + public String[] getTestMethodNames() + { + // TODO think about trigger of sub-tests from outside + return new String[] + { + "checkGeneratedCLITypes" + }; + } + + public void checkGeneratedCLITypes() + { + try + { + String testProgram = System.getProperty("cli_ure_test"); + if (testProgram == null || testProgram.length() == 0) + failed("Check the make file. Java must be called with -Dcli_ure_test=pathtoexe"); + Process proc = null; + try{ + + proc = Runtime.getRuntime().exec(testProgram); + new Reader(proc.getInputStream()); + new Reader(proc.getErrorStream()); + + } catch(Exception e) + { + System.out.println("\n ###" + e.getMessage() + "\n"); + + } + proc.waitFor(); + int retVal = proc.exitValue(); + if (retVal != 0) + failed("Tests for generated CLI code failed."); + } catch( java.lang.Exception e) + { + failed("Unexpected exception."); + } + + } +} + + +/* This read from an InputStream and discards the data. + */ +class Reader extends Thread +{ + private final java.io.InputStream is; + public Reader(java.io.InputStream stream) + { + is = stream; + start(); + } + + @Override + public void run() + { + try + { + byte[] buf = new byte[1024]; + while (-1 != is.read(buf)) {} + } + catch (java.io.IOException exc) + { + } + } +} diff --git a/cli_ure/qa/climaker/climaker.cs b/cli_ure/qa/climaker/climaker.cs new file mode 100644 index 000000000..1fcc53513 --- /dev/null +++ b/cli_ure/qa/climaker/climaker.cs @@ -0,0 +1,1478 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; +using System.Reflection; +using System.Diagnostics; +using uno; + + +using unoidl.test.cliure.climaker; +//using unoidl.com.sun.star.uno; +using ucss=unoidl.com.sun.star; + +/** This class is for testing the generated code in the uno services + */ + +public class Context: ucss.uno.XComponentContext +{ + public enum test_kind { + NORMAL, + NO_FACTORY, + TEST_EXCEPTION, + CREATION_FAILED + } + + public Context(test_kind k, params object[] args) + { + kind = k; + factory = new Factory(k, args); + } + + public ucss.lang.XMultiComponentFactory getServiceManager() + { + if (kind == test_kind.NO_FACTORY) + return null; + return factory; + } + + public Any getValueByName(string Name) + { + if (kind == test_kind.NORMAL) + { + if (Name == "/singletons/unoidl.test.cliure.climaker.S4") + { + Component c = new Component(this); + return new Any(typeof(object), c); + } + } + else if (kind == test_kind.CREATION_FAILED) + { + return new Any(); + } + return new Any(); + } + + class Factory: ucss.lang.XMultiComponentFactory + { + public Factory(Context.test_kind k, params object[] args) { + kind2 = k; + if (k == Context.test_kind.TEST_EXCEPTION) + exception = (ucss.uno.Exception) args[0]; + } + public object createInstanceWithArgumentsAndContext( + string ServiceSpecifier, + uno.Any[] Arguments, + unoidl.com.sun.star.uno.XComponentContext Context) { + switch (kind2) { + case test_kind.NORMAL: + return new Component(Context, Arguments); + case test_kind.CREATION_FAILED : + return null; + case test_kind.TEST_EXCEPTION: + throw exception; + default: + throw new Exception("Factory not properly initialized"); + } + } + public object createInstanceWithContext( + string aServiceSpecifier, + unoidl.com.sun.star.uno.XComponentContext Context) { + switch (kind2) { + case test_kind.NORMAL: + return new Component(Context); + case test_kind.CREATION_FAILED: + return null; + case test_kind.TEST_EXCEPTION: + throw exception; + default: + throw new Exception("Factory not properly initialized"); + } + } + + public string[] getAvailableServiceNames() + { + return new string[]{}; + } + ucss.uno.Exception exception; + test_kind kind2; + } + + + Factory factory; + test_kind kind; +} + + +public class Logger +{ + String m_sFunction; + int m_nErrors; + public Logger() { + } + + public String Function + { + set + { + m_sFunction = value; + } + get + { + return m_sFunction; + } + } + + public void assure(bool b) { + if (b == false) + { + Console.WriteLine(m_sFunction + " failed!"); + m_nErrors++; + } + } + + public void printStatus() { + Console.WriteLine("\n====================================="); + + + String msg; + if (m_nErrors > 0) + msg = "Test failed! " + m_nErrors.ToString() + " Errors."; + else + msg = "Test succeeded!"; + + Console.WriteLine(msg + "\n====================================="); + } + + public int Errors + { + get + { + return m_nErrors; + } + } +} + +public sealed class Test +{ + public static int Main(String[] args) + { + +// System.Diagnostics.Debugger.Launch(); + try + { + Logger log = new Logger(); + Test t = new Test(); + t.testEnum1(log); + t.testEnum2(log); + t.testPolyStruct(log); + t.testEmptyStruct2(log); + t.testFullStruct2(log); + t.testS1(log); + t.testSingletons(log); + t.testAttributes(log); + t.testPolyStructAttributes(log); + t.testPolymorphicType(log); + t.testInterface(log); + t.testAny(log); + log.printStatus(); + if (log.Errors == 0) + return 0; + return -1; + } + catch(Exception e) + { + Console.Write(e.Message); + } + return -1; + + } + + + public void testEnum1(Logger l) { + l.Function = "testEnum1"; + l.assure(((int)Enum1.VALUE1) == -100); + l.assure(((int)Enum1.VALUE2) == 100); + } + + public void testEnum2(Logger l) { + l.Function = "testEnum2"; + l.assure( ((int) Enum2.VALUE0) == 0); + l.assure( ((int) Enum2.VALUE1) == 1); + l.assure( ((int) Enum2.VALUE2) == 2); + l.assure( ((int) Enum2.VALUE4) == 4); + } + + public void testPolyStruct(Logger l) { + l.Function = "testPolyStruct"; + PolyStruct s = new PolyStruct(); + l.assure(s.member1 == null); + l.assure(s.member2 == 0); + s = new PolyStruct("ABC", 5); + l.assure(s.member1.Equals("ABC")); + l.assure(s.member2 == 5); + } + + public void testEmptyStruct2(Logger l) { + l.Function = "testEmptyStruct2"; + Struct2 s = new Struct2(); + l.assure(s.p1 == false); + l.assure(s.p2 == 0); + l.assure(s.p3 == 0); + l.assure(s.p4 == 0); + l.assure(s.p5 == 0); + l.assure(s.p6 == 0); + l.assure(s.p7 == 0); + l.assure(s.p8 == 0); + l.assure(s.p9 == 0.0f); + l.assure(s.p10 == 0.0); + l.assure(s.p11 == '\u0000'); + l.assure(s.p12.Equals("")); + l.assure(s.p13.Equals(typeof(void))); + l.assure(s.p14.Equals(Any.VOID)); + l.assure(s.p15 == Enum2.VALUE0); + l.assure(s.p16.member1 == 0); + l.assure(s.p17 == null); + l.assure(s.p18 == null); + l.assure(s.t1 == false); + l.assure(s.t2 == 0); + l.assure(s.t3 == 0); + l.assure(s.t4 == 0); + l.assure(s.t5 == 0); + l.assure(s.t6 == 0); + l.assure(s.t7 == 0); + l.assure(s.t8 == 0); + l.assure(s.t9 == 0.0f); + l.assure(s.t10 == 0.0); + l.assure(s.t11 == '\u0000'); + l.assure(s.t12.Equals("")); + l.assure(s.t13.Equals(typeof(void))); + l.assure(s.t14.Equals(Any.VOID)); + l.assure(s.t15 == Enum2.VALUE0); + l.assure(s.t16.member1 == 0); + l.assure(s.t17 == null); + l.assure(s.t18 == null); + l.assure(s.a1.Length == 0); + l.assure(s.a2.Length == 0); + l.assure(s.a3.Length == 0); + l.assure(s.a4.Length == 0); + l.assure(s.a5.Length == 0); + l.assure(s.a6.Length == 0); + l.assure(s.a7.Length == 0); + l.assure(s.a8.Length == 0); + l.assure(s.a9.Length == 0); + l.assure(s.a10.Length == 0); + l.assure(s.a11.Length == 0); + l.assure(s.a12.Length == 0); + l.assure(s.a13.Length == 0); + l.assure(s.a14.Length == 0); + l.assure(s.a15.Length == 0); + l.assure(s.a16.Length == 0); + l.assure(s.a17.Length == 0); + l.assure(s.a18.Length == 0); + l.assure(s.aa1.Length == 0); + l.assure(s.aa2.Length == 0); + l.assure(s.aa3.Length == 0); + l.assure(s.aa4.Length == 0); + l.assure(s.aa5.Length == 0); + l.assure(s.aa6.Length == 0); + l.assure(s.aa7.Length == 0); + l.assure(s.aa8.Length == 0); + l.assure(s.aa9.Length == 0); + l.assure(s.aa10.Length == 0); + l.assure(s.aa11.Length == 0); + l.assure(s.aa12.Length == 0); + l.assure(s.aa13.Length == 0); + l.assure(s.aa14.Length == 0); + l.assure(s.aa15.Length == 0); + l.assure(s.aa16.Length == 0); + l.assure(s.aa17.Length == 0); + l.assure(s.aa18.Length == 0); + l.assure(s.at1.Length == 0); + l.assure(s.at2.Length == 0); + l.assure(s.at3.Length == 0); + l.assure(s.at4.Length == 0); + l.assure(s.at5.Length == 0); + l.assure(s.at6.Length == 0); + l.assure(s.at7.Length == 0); + l.assure(s.at8.Length == 0); + l.assure(s.at9.Length == 0); + l.assure(s.at10.Length == 0); + l.assure(s.at11.Length == 0); + l.assure(s.at12.Length == 0); + l.assure(s.at13.Length == 0); + l.assure(s.at14.Length == 0); + l.assure(s.at15.Length == 0); + l.assure(s.at16.Length == 0); + l.assure(s.at17.Length == 0); + l.assure(s.at18.Length == 0); + } + + public void testFullStruct2(Logger l) { + //TODO: + Struct2 s = new Struct2( + true, (byte) 1, (short) 2, (ushort) 3, 4, 5, 6L, 7L, 0.8f, 0.9d, 'A', + "BCD", typeof(ulong), new Any(22), Enum2.VALUE4, + new Struct1(1), null, null, false, (byte) 0, (short) 0, (ushort) 0, + 0, 0, 0L, 0L, 0.0f, 0.0, '\u0000', "", typeof(void), Any.VOID, + Enum2.VALUE0, new Struct1(), null, null, + new bool[] { false, true }, new byte[] { (byte) 1, (byte) 2 }, + new short[0], new ushort[0], new int[0], new uint[0], + new long[0], new ulong[0], new float[0], new double[0], new char[0], + new String[0], new Type[0], new Any[0], new Enum2[0], + new Struct1[] { new Struct1(1), new Struct1(2) }, new Object[0], + new ucss.uno.XNamingService[0], new bool[0][], new byte[0][], + new short[0][], new ushort[0][], new int[0][], new uint[0][], + new long[0][], new ulong[0][], new float[0][], new double[0][], + new char[0][], new String[0][], new Type[0][], new Any[0][], + new Enum2[0][], new Struct1[0][], new Object[0][], + new ucss.uno.XNamingService[0][], new bool[0][], new byte[0][], + new short[0][], new ushort[0][], new int[0][], new uint[0][], + new long[0][], new ulong[0][], new float[0][], new double[0][], + new char[0][], new String[0][], new Type[0][], new Any[0][], + new Enum2[0][], new Struct1[0][], new Object[0][], + new ucss.uno.XNamingService[0][]); + l.assure(s.p1 == true); + l.assure(s.p2 == 1); + l.assure(s.p3 == 2); + l.assure(s.p4 == 3); + l.assure(s.p5 == 4); + l.assure(s.p6 == 5); + l.assure(s.p7 == 6); + l.assure(s.p8 == 7); + l.assure(s.p9 == 0.8f); + l.assure(s.p10 == 0.9); + l.assure(s.p11 == 'A'); + l.assure(s.p12.Equals("BCD")); + l.assure(s.p13.Equals(typeof(ulong))); + l.assure(s.p14.Equals(new Any(22))); + l.assure(s.p15 == Enum2.VALUE4); + l.assure(s.p16.member1 == 1); + l.assure(s.p17 == null); + l.assure(s.p18 == null); + l.assure(s.t1 == false); + l.assure(s.t2 == 0); + l.assure(s.t3 == 0); + l.assure(s.t4 == 0); + l.assure(s.t5 == 0); + l.assure(s.t6 == 0); + l.assure(s.t7 == 0); + l.assure(s.t8 == 0); + l.assure(s.t9 == 0.0f); + l.assure(s.t10 == 0.0); + l.assure(s.t11 == '\u0000'); + l.assure(s.t12.Equals("")); + l.assure(s.t13.Equals(typeof(void))); + l.assure(s.t14.Equals(Any.VOID)); + l.assure(s.t15 == Enum2.VALUE0); + l.assure(s.t16.member1 == 0); + l.assure(s.t17 == null); + l.assure(s.t18 == null); + l.assure(s.a1.Length == 2); + l.assure(s.a1[0] == false); + l.assure(s.a1[1] == true); + l.assure(s.a2.Length == 2); + l.assure(s.a2[0] == 1); + l.assure(s.a2[1] == 2); + l.assure(s.a3.Length == 0); + l.assure(s.a4.Length == 0); + l.assure(s.a5.Length == 0); + l.assure(s.a6.Length == 0); + l.assure(s.a7.Length == 0); + l.assure(s.a8.Length == 0); + l.assure(s.a9.Length == 0); + l.assure(s.a10.Length == 0); + l.assure(s.a11.Length == 0); + l.assure(s.a12.Length == 0); + l.assure(s.a13.Length == 0); + l.assure(s.a14.Length == 0); + l.assure(s.a15.Length == 0); + l.assure(s.a16.Length == 2); + l.assure(s.a16[0].member1 == 1); + l.assure(s.a16[1].member1 == 2); + l.assure(s.a17.Length == 0); + l.assure(s.a18.Length == 0); + l.assure(s.aa1.Length == 0); + l.assure(s.aa2.Length == 0); + l.assure(s.aa3.Length == 0); + l.assure(s.aa4.Length == 0); + l.assure(s.aa5.Length == 0); + l.assure(s.aa6.Length == 0); + l.assure(s.aa7.Length == 0); + l.assure(s.aa8.Length == 0); + l.assure(s.aa9.Length == 0); + l.assure(s.aa10.Length == 0); + l.assure(s.aa11.Length == 0); + l.assure(s.aa12.Length == 0); + l.assure(s.aa13.Length == 0); + l.assure(s.aa14.Length == 0); + l.assure(s.aa15.Length == 0); + l.assure(s.aa16.Length == 0); + l.assure(s.aa17.Length == 0); + l.assure(s.aa18.Length == 0); + l.assure(s.at1.Length == 0); + l.assure(s.at2.Length == 0); + l.assure(s.at3.Length == 0); + l.assure(s.at4.Length == 0); + l.assure(s.at5.Length == 0); + l.assure(s.at6.Length == 0); + l.assure(s.at7.Length == 0); + l.assure(s.at8.Length == 0); + l.assure(s.at9.Length == 0); + l.assure(s.at10.Length == 0); + l.assure(s.at11.Length == 0); + l.assure(s.at12.Length == 0); + l.assure(s.at13.Length == 0); + l.assure(s.at14.Length == 0); + l.assure(s.at15.Length == 0); + l.assure(s.at16.Length == 0); + l.assure(s.at17.Length == 0); + l.assure(s.at18.Length == 0); + } + + public void testS1(Logger l) { + l.Function = "testS1"; + object obj = new Object(); + ucss.uno.RuntimeException excRuntime = + new ucss.uno.RuntimeException("RuntimeException", obj); + ucss.uno.Exception excException = + new ucss.uno.Exception("Exception", obj); + ucss.lang.IllegalAccessException excIllegalAccess = + new ucss.lang.IllegalAccessException("IllegalAccessException", obj); + ucss.uno.DeploymentException excDeployment = + new ucss.uno.DeploymentException("DeploymentException", obj); + ucss.lang.InvalidListenerException excInvalidListener = + new ucss.lang.InvalidListenerException("ListenerException", obj); + + /* create1 does not specify exceptions. Therefore RuntimeExceptions + fly through and other exceptions cause a DeploymentException. + */ + try { + S1.create1(new Context(Context.test_kind.TEST_EXCEPTION, excRuntime)); + } catch (ucss.uno.RuntimeException e) { + l.assure(e.Message == excRuntime.Message + && e.Context == obj); + } catch (System.Exception) { + l.assure(false); + } + + Context c = new Context(Context.test_kind.TEST_EXCEPTION, excException); + try { + S1.create1(c); + } catch (ucss.uno.DeploymentException e) { + //The message of the original exception should be contained + // in the Deploymentexception + l.assure(e.Message.IndexOf(excException.Message) != -1 && e.Context == c); + } catch (System.Exception) { + l.assure(false); + } + + /* create2 specifies many exceptions, including RuntimeException and Exception. + Because Exception is specified all exceptions are allowed, hence all thrown + exceptions fly through. + */ + try { + S1.create2(new Context(Context.test_kind.TEST_EXCEPTION, excRuntime)); + } catch (ucss.uno.RuntimeException e) { + l.assure(e.Message == excRuntime.Message + && e.Context == obj); + } catch (System.Exception) { + l.assure(false); + } + + try { + S1.create2(new Context(Context.test_kind.TEST_EXCEPTION, excIllegalAccess)); + } catch (ucss.lang.IllegalAccessException e) { + l.assure(e.Message == excIllegalAccess.Message + && e.Context == obj); + } catch (System.Exception) { + l.assure(false); + } + + try { + S1.create2(new Context(Context.test_kind.TEST_EXCEPTION, excException)); + } catch (ucss.uno.Exception e) { + l.assure(e.Message == excException.Message + && e.Context == obj); + } catch (System.Exception) { + l.assure(false); + } + + /* create3 specifies exceptions but no com.sun.star.uno.Exception. RuntimeException + and derived fly through. Other specified exceptions are rethrown and all other + exceptions cause a DeploymentException. + */ + try { + S1.create3(new Context(Context.test_kind.TEST_EXCEPTION, excDeployment), + new Any[]{}); + } catch (ucss.uno.DeploymentException e) { + l.assure(e.Message == excDeployment.Message + && e.Context == obj); + } catch (System.Exception) { + l.assure(false); + } + + try { + S1.create3(new Context(Context.test_kind.TEST_EXCEPTION, excIllegalAccess), + new Any[0]); + } catch (ucss.lang.IllegalAccessException e) { + l.assure(e.Message == excIllegalAccess.Message + && e.Context == obj); + } catch (System.Exception) { + l.assure(false); + } + + c = new Context(Context.test_kind.TEST_EXCEPTION, excInvalidListener); + try { + S1.create3(c, new Any[0]); + } catch (ucss.uno.DeploymentException e) { + l.assure(e.Message.IndexOf(excInvalidListener.Message) != -1 + && e.Context == c); + } catch (System.Exception) { + l.assure(false); + } + + /* test the case when the context cannot provide a service manager. + */ + try { + S1.create2(new Context(Context.test_kind.NO_FACTORY)); + } catch (ucss.uno.DeploymentException e) { + l.assure(e.Message.Length > 0); + } catch (System.Exception) { + l.assure(false); + } + + /* When the service manager returns a null pointer then a DeploymentException + * is to be thrown. + */ + try { + S1.create2(new Context(Context.test_kind.CREATION_FAILED)); + } catch (ucss.uno.DeploymentException e) { + l.assure(e.Message.Length > 0); + } catch (System.Exception) { + l.assure(false); + } + + + /** Test creation of components and if the passing of parameters works. + */ + c = new Context(Context.test_kind.NORMAL); + try { + XTest xTest = S1.create1(c); + Component cobj = (Component) xTest; + l.assure(cobj.Args[0].Value == c); + + Any a1 = new Any("bla"); + Any a2 = new Any(3.14f); + Any a3 = new Any(3.145d); + xTest = S1.create2(c, a1, a2, a3); + cobj = (Component) xTest; + l.assure(cobj.Args[0].Value == c + && a1.Equals(cobj.Args[1]) + && a2.Equals(cobj.Args[2]) + && a3.Equals(cobj.Args[3])); + + bool b1 = true; + byte b2 = 1; + short b3 = 2; + ushort b4 = 3; + int b5 = 4; + uint b6 = 5; + long b7 = 6; + ulong b8 = 7; + float b9 = 0.8f; + double b10 = 0.9; + char b11 = 'A'; + string b12 = "BCD"; + Type b13 = typeof(ulong); + Any b14 = new Any(22); + Enum2 b15 = Enum2.VALUE4; + Struct1 b16 = new Struct1(1); + PolyStruct b17 = new PolyStruct('A', 1); + PolyStruct b18 = new PolyStruct(new Any(true), 1); + object b19 = new uno.util.WeakComponentBase(); + ucss.lang.XComponent b20 = (ucss.lang.XComponent) b19; + bool b21 = b1; + byte b22 = b2; + short b23 = b3; + ushort b24 = b4; + int b25 = b5; + uint b26 = b6; + long b27 = b7; + ulong b28 = b8; + float b29 = b9; + double b30 = b10; + char b31 = b11; + string b32 = b12; + Type b33 = b13; + Any b34 = b14; + Enum2 b35 = b15; + Struct1 b36 = b16; + object b37 = b19; + ucss.lang.XComponent b38 = b20; + bool[] b39 = new bool[] { false, true }; + byte[] b40 = new byte[] { (byte) 1, (byte) 2 }; + short[] b41 = new short[] { (short) 123, (short) 456}; + ushort[] b42 = new ushort[] { (ushort) 789, (ushort) 101}; + int[] b43 = new int[] {1, 2, 3}; + uint[] b44 = new uint[] {4, 5, 6}; + long[] b45 = new long[] {7,8,9}; + ulong[] b46 = new ulong[] {123, 4356}; + float[] b47 = new float[] {2435f,87f}; + double[] b48 = new double[] {234d,45.2134d}; + char[] b49 = new char[] {'\u1234', 'A'}; + string[] b50 = new string[] {"a","bc"}; + Type[] b51 = new Type[] {typeof(int), typeof(long)}; + Any[] b52 = new Any[] {new Any(1), new Any("adf")}; + Enum2[] b53 = new Enum2[] {Enum2.VALUE2}; + Struct1[] b54 = new Struct1[] {new Struct1(11), new Struct1(22)}; + object[] b55 = new object[0]; + ucss.lang.XComponent[] b56 = new ucss.lang.XComponent[]{ + new uno.util.WeakComponentBase(), new uno.util.WeakComponentBase()}; + bool[][] b57 = new bool[][] {new bool[]{true,false}, new bool[] {true}}; + byte[][] b58 = new byte[][]{new byte[] {(byte) 1}, new byte[]{(byte) 2}}; + short[][] b59 = new short[][] {new short[]{(short)6, (short)7}, new short[] {(short)9}}; + ushort[][] b60 = new ushort[][] { new ushort[]{(ushort) 11}}; + int[][] b61 = new int[][] {new int[]{1}, new int[]{2,3}, new int[]{4,5,6}}; + uint[][] b62 = new uint[][] {new uint[]{10U}, new uint[]{20U,30U}, new uint[]{40U,50U,60}}; + long[][] b63 = new long[][] {new long[]{10L}, new long[]{20L,30}, new long[]{40,50,60}}; + ulong[][] b64 = new ulong[][] { new ulong[]{10L}, new ulong[]{20L, 30L}, new ulong[]{40,50,60}}; + float[][] b65 = new float[][] {new float[]{10f}, new float[]{20f,30f}, new float[]{40f,50f,60f}}; + double[][] b66 = new double[][]{new double[]{10d}, new double[]{20d,30d}}; + char[][] b67 = new char[][] {new char[]{'a'}, new char[]{'b', 'c'}}; + string[][] b68 = new String[][] {new string[]{"a"}, new string[]{"ad", "lkj"}}; + Type[][] b69 = new Type[][] {new Type[]{typeof(byte), typeof(long)}, new Type[]{typeof(Any)}}; + Any[][] b70 = new Any[][] {new Any[]{new Any(1f), new Any(2d)}, new Any[]{new Any(34U)}}; + Enum2[][] b71 = new Enum2[][] {new Enum2[]{Enum2.VALUE2}}; + Struct1[][] b72 = new Struct1[][] {new Struct1[]{new Struct1(2), new Struct1(3)}}; + object[][] b73 = new Object[0][]; + ucss.lang.XComponent[][] b74 = new uno.util.WeakComponentBase[0][]; + bool[][] b75 = b57; + byte[][] b76 = b58; + short[][] b77 = b59; + ushort[][] b78 = b60; + int[][] b79 = b61; + uint[][] b80 = b62; + long[][] b81 = b63; + ulong[][] b82 = b64; + float[][] b83 = b65; + double[][] b84 = b66; + char[][] b85 = b67; + String[][] b86 = b68; + Type[][] b87 =b69; + Any[][] b88 = b70; + Enum2[][] b89 = b71; + Struct1[][] b90 = b72; + Object[][] b91 = b73; + ucss.lang.XComponent[][] b92 = b74; + + xTest = S1.create5( + c, + b1, b2, b3, b4, b5, b6, b7 ,b8, b9, b10, + b11, b12, b13, + b14, + b15, b16, b17, b18, b19, b20, + b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, + b31, b32, b33, + b34, + b35, b36, b37, b38, b39, b40, + b41, b42, b43, b44, b45, b46, b47, b48, b49, b50, + b51, b52, b53, b54, b55, b56, b57, b58, b59, b60, + b61, b62, b63, b64, b65, b66, b67, b68, b69, b70, + b71, b72, b73, b74, b75, b76, b77, b78, b79, b80, + b81, b82, b83, b84, b85, b86, b87, b88, b89, b90, + b91, b92 + ); + + cobj = (Component) xTest; + l.assure(cobj.Args[0].Value == c); + l.assure(b1.Equals(cobj.Args[1].Value)); + l.assure(b2.Equals(cobj.Args[2].Value)); + l.assure(b3.Equals(cobj.Args[3].Value)); + l.assure(b4.Equals(cobj.Args[4].Value)); + l.assure(b5.Equals(cobj.Args[5].Value)); + l.assure(b6.Equals(cobj.Args[6].Value)); + l.assure(b7.Equals(cobj.Args[7].Value)); + l.assure(b8.Equals(cobj.Args[8].Value)); + l.assure(b9.Equals(cobj.Args[9].Value)); + l.assure(b10.Equals(cobj.Args[10].Value)); + l.assure(b11.Equals(cobj.Args[11].Value)); + l.assure(b12.Equals(cobj.Args[12].Value)); + l.assure(b13.Equals(cobj.Args[13].Value)); + //Anys are not wrapped by the generated code + l.assure(b14.Equals(cobj.Args[14])); + l.assure(b15.Equals(cobj.Args[15].Value)); + l.assure(b16.Equals(cobj.Args[16].Value)); + l.assure(b17.Equals(cobj.Args[17].Value)); + l.assure(b18.Equals(cobj.Args[18].Value)); + l.assure(b19.Equals(cobj.Args[19].Value)); + l.assure(b20.Equals(cobj.Args[20].Value)); + l.assure(b21.Equals(cobj.Args[21].Value)); + l.assure(b22.Equals(cobj.Args[22].Value)); + l.assure(b23.Equals(cobj.Args[23].Value)); + l.assure(b24.Equals(cobj.Args[24].Value)); + l.assure(b25.Equals(cobj.Args[25].Value)); + l.assure(b26.Equals(cobj.Args[26].Value)); + l.assure(b27.Equals(cobj.Args[27].Value)); + l.assure(b28.Equals(cobj.Args[28].Value)); + l.assure(b29.Equals(cobj.Args[29].Value)); + l.assure(b30.Equals(cobj.Args[30].Value)); + l.assure(b31.Equals(cobj.Args[31].Value)); + l.assure(b32.Equals(cobj.Args[32].Value)); + l.assure(b33.Equals(cobj.Args[33].Value)); + //Anys are not wrapped by the generated code + l.assure(b34.Equals(cobj.Args[34])); + l.assure(b35.Equals(cobj.Args[35].Value)); + l.assure(b36.Equals(cobj.Args[36].Value)); + l.assure(b37.Equals(cobj.Args[37].Value)); + l.assure(b38.Equals(cobj.Args[38].Value)); + l.assure(b39.Equals(cobj.Args[39].Value)); + l.assure(b40.Equals(cobj.Args[40].Value)); + l.assure(b41.Equals(cobj.Args[41].Value)); + l.assure(b42.Equals(cobj.Args[42].Value)); + l.assure(b43.Equals(cobj.Args[43].Value)); + l.assure(b44.Equals(cobj.Args[44].Value)); + l.assure(b45.Equals(cobj.Args[45].Value)); + l.assure(b46.Equals(cobj.Args[46].Value)); + l.assure(b47.Equals(cobj.Args[47].Value)); + l.assure(b48.Equals(cobj.Args[48].Value)); + l.assure(b49.Equals(cobj.Args[49].Value)); + l.assure(b50.Equals(cobj.Args[50].Value)); + l.assure(b51.Equals(cobj.Args[51].Value)); + l.assure(b52.Equals(cobj.Args[52].Value)); + l.assure(b53.Equals(cobj.Args[53].Value)); + l.assure(b54.Equals(cobj.Args[54].Value)); + l.assure(b55.Equals(cobj.Args[55].Value)); + l.assure(b56.Equals(cobj.Args[56].Value)); + l.assure(b57.Equals(cobj.Args[57].Value)); + l.assure(b58.Equals(cobj.Args[58].Value)); + l.assure(b59.Equals(cobj.Args[59].Value)); + l.assure(b60.Equals(cobj.Args[60].Value)); + l.assure(b61.Equals(cobj.Args[61].Value)); + l.assure(b62.Equals(cobj.Args[62].Value)); + l.assure(b63.Equals(cobj.Args[63].Value)); + l.assure(b64.Equals(cobj.Args[64].Value)); + l.assure(b65.Equals(cobj.Args[65].Value)); + l.assure(b66.Equals(cobj.Args[66].Value)); + l.assure(b67.Equals(cobj.Args[67].Value)); + l.assure(b68.Equals(cobj.Args[68].Value)); + l.assure(b69.Equals(cobj.Args[69].Value)); + l.assure(b70.Equals(cobj.Args[70].Value)); + l.assure(b71.Equals(cobj.Args[71].Value)); + l.assure(b72.Equals(cobj.Args[72].Value)); + l.assure(b73.Equals(cobj.Args[73].Value)); + l.assure(b74.Equals(cobj.Args[74].Value)); + l.assure(b75.Equals(cobj.Args[75].Value)); + l.assure(b76.Equals(cobj.Args[76].Value)); + l.assure(b77.Equals(cobj.Args[77].Value)); + l.assure(b78.Equals(cobj.Args[78].Value)); + l.assure(b79.Equals(cobj.Args[79].Value)); + l.assure(b80.Equals(cobj.Args[80].Value)); + l.assure(b81.Equals(cobj.Args[81].Value)); + l.assure(b82.Equals(cobj.Args[82].Value)); + l.assure(b83.Equals(cobj.Args[83].Value)); + l.assure(b84.Equals(cobj.Args[84].Value)); + l.assure(b85.Equals(cobj.Args[85].Value)); + l.assure(b86.Equals(cobj.Args[86].Value)); + l.assure(b87.Equals(cobj.Args[87].Value)); + l.assure(b88.Equals(cobj.Args[88].Value)); + l.assure(b89.Equals(cobj.Args[89].Value)); + l.assure(b90.Equals(cobj.Args[90].Value)); + l.assure(b91.Equals(cobj.Args[91].Value)); + l.assure(b92.Equals(cobj.Args[92].Value)); + + } catch (Exception) { + l.assure(false); + } + + //test + c = new Context(Context.test_kind.NORMAL); + try { + + PolyStruct2 arg1 = new PolyStruct2(typeof(PolyStruct2), 1); + PolyStruct2 arg2 = new PolyStruct2(new Any(true), 1); + PolyStruct2 arg3 = new PolyStruct2(true, 1); + PolyStruct2 arg4 = new PolyStruct2((Byte)8, 1); + PolyStruct2 arg5 = new PolyStruct2('c', 1); + PolyStruct2 arg6 = new PolyStruct2((Int16)10, 1); + PolyStruct2 arg7 = new PolyStruct2(11, 1); + PolyStruct2 arg8 = new PolyStruct2(12L, 1); + PolyStruct2 arg9 = new PolyStruct2("Hello", 1); + PolyStruct2 arg10 = new PolyStruct2(1.3, 1); + PolyStruct2 arg11 = new PolyStruct2(1.3d, 1); + PolyStruct2 arg12 = new PolyStruct2(new Object(), 1); + PolyStruct2 arg13 = new PolyStruct2(new uno.util.WeakComponentBase(), 1); + PolyStruct2 arg14 = new PolyStruct2( + new PolyStruct('A', 1), 1); + PolyStruct2 arg15 = new PolyStruct2( + new PolyStruct(new PolyStruct('A',1),1),1); + PolyStruct arg16 = new PolyStruct("Hallo", 1); + PolyStruct arg17 = new PolyStruct( + new PolyStruct('A',1),1); + + Type[] arType = {typeof(PolyStruct), typeof(PolyStruct2)}; + PolyStruct2 arg101 = new PolyStruct2(arType,1); + PolyStruct2 arg102 = new PolyStruct2( + new Any[] {new Any(true)},1); + PolyStruct2 arg103 = new PolyStruct2(new bool[]{true}, 1); + PolyStruct2 arg104 = new PolyStruct2(new byte[] { (byte) 1}, 1); + PolyStruct2 arg105 = new PolyStruct2(new char[] {'\u1234', 'A'}, 1); + PolyStruct2 arg106 = new PolyStruct2(new short[] {(short)1}, 1); + PolyStruct2 arg107 = new PolyStruct2(new int[] {1}, 1); + PolyStruct2 arg108 = new PolyStruct2(new long[] {1}, 1); + PolyStruct2 arg109 = new PolyStruct2(new string[]{"Hallo"}, 1); + PolyStruct2 arg110 = new PolyStruct2(new float[]{1.3f}, 1); + PolyStruct2 arg111 = new PolyStruct2(new double[] {1.3d}, 1); + PolyStruct2 arg112 = new PolyStruct2( + new Object[] { new Object()}, 1); + PolyStruct2 arg113 = new PolyStruct2( + new uno.util.WeakComponentBase[] { + new uno.util.WeakComponentBase()}, 1); + PolyStruct2 arg114 = new PolyStruct2( + new PolyStruct[]{ + new PolyStruct('A',1)} ,1); + PolyStruct2 arg115 = new PolyStruct2( + new PolyStruct[] { + new PolyStruct( new PolyStruct2('A',1),1)} + ,1); + PolyStruct2 arg201 = new PolyStruct2(new char[][] { new char[]{'A'}, + new char[]{'B'}}, 1); + + PolyStruct2[] arg301 = new PolyStruct2[] {new PolyStruct2('A', 1)}; + PolyStruct2[] arg302 = new PolyStruct2[] {new PolyStruct2( + new PolyStruct('A', 1), 1)}; + PolyStruct2[] arg303 = new PolyStruct2[] {new PolyStruct2( + new PolyStruct(new PolyStruct('A',1),1),1)}; + PolyStruct[] arg304 = new PolyStruct[] {new PolyStruct("Hallo", 1)}; + PolyStruct[] arg305 = new PolyStruct[] {new PolyStruct( + new PolyStruct('A',1),1)}; + + PolyStruct2[][] arg401 = new PolyStruct2[][] {new PolyStruct2[] {new PolyStruct2('A', 1)}}; + PolyStruct2[][] arg402 = new PolyStruct2[][] {new PolyStruct2[] {new PolyStruct2( + new PolyStruct('A', 1), 1)}}; + PolyStruct2[][] arg403 = new PolyStruct2[][] {new PolyStruct2[] {new PolyStruct2( + new PolyStruct(new PolyStruct('A',1),1),1)}}; + PolyStruct[][] arg404 = new PolyStruct[][] {new PolyStruct[] {new PolyStruct("Hallo", 1)}}; + PolyStruct[][] arg405 = new PolyStruct[][] {new PolyStruct[] {new PolyStruct( + new PolyStruct('A',1),1)}}; + + + XTest xTest = S1.create6(c, + arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10, + arg11,arg12,arg13,arg14,arg15,arg16,arg17, + arg101,arg102,arg103,arg104,arg105,arg106,arg107,arg108,arg109,arg110, + arg111,arg112,arg113,arg114,arg115, + arg201, + arg301, arg302, arg303, arg304, arg305, + arg401, arg402, arg403, arg404, arg405); + Component cobj = (Component) xTest; + l.assure(cobj.Args[0].Value == c); + //arg1 - arg17 + string sType = ((PolymorphicType) cobj.Args[1].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[2].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[3].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[4].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[5].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[6].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[7].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[8].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[9].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[10].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[11].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[12].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[13].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[14].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2>"); + sType = ((PolymorphicType) cobj.Args[15].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2<" + + "unoidl.test.cliure.climaker.PolyStruct<" + + "unoidl.test.cliure.climaker.PolyStruct<" + + "System.Char,uno.Any>,System.String>>"); + sType = ((PolymorphicType) cobj.Args[16].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct<" + + "System.String,unoidl.test.cliure.climaker.PolyStruct<" + + "System.Char,unoidl.test.cliure.climaker.PolyStruct2<" + + "uno.Any>>>"); + sType = ((PolymorphicType) cobj.Args[17].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct<" + + "unoidl.test.cliure.climaker.PolyStruct," + + "unoidl.test.cliure.climaker.PolyStruct2>"); + //arg101 - arg115 + sType = ((PolymorphicType) cobj.Args[18].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[19].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[20].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[21].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[22].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[23].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[24].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[25].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[26].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[27].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[28].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[29].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[30].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2"); + sType = ((PolymorphicType) cobj.Args[31].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2<" + + "unoidl.test.cliure.climaker.PolyStruct[]>"); + sType = ((PolymorphicType) cobj.Args[32].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2<" + + "unoidl.test.cliure.climaker.PolyStruct<" + + "unoidl.test.cliure.climaker.PolyStruct2<" + + "System.Char>,uno.Any[]>[]>"); + //arg 201 + sType = ((PolymorphicType) cobj.Args[33].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2<" + + "System.Char[][]>"); + //arg 301 - arg305 + sType = ((PolymorphicType) cobj.Args[34].Type).PolymorphicName; + l.assure (sType == "unoidl.test.cliure.climaker.PolyStruct2[]"); + sType = ((PolymorphicType) cobj.Args[35].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2>[]"); + sType = ((PolymorphicType) cobj.Args[36].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2<" + + "unoidl.test.cliure.climaker.PolyStruct<" + + "unoidl.test.cliure.climaker.PolyStruct<" + + "System.Char,uno.Any>,System.String>>[]"); + sType = ((PolymorphicType) cobj.Args[37].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct<" + + "System.String,unoidl.test.cliure.climaker.PolyStruct<" + + "System.Char,unoidl.test.cliure.climaker.PolyStruct2<" + + "uno.Any>>>[]"); + sType = ((PolymorphicType) cobj.Args[38].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct<" + + "unoidl.test.cliure.climaker.PolyStruct," + + "unoidl.test.cliure.climaker.PolyStruct2>[]"); + //arg 401 - arg405 + sType = ((PolymorphicType) cobj.Args[39].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2[][]"); + sType = ((PolymorphicType) cobj.Args[40].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2<" + + "unoidl.test.cliure.climaker.PolyStruct>[][]"); + sType = ((PolymorphicType) cobj.Args[41].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct2<" + + "unoidl.test.cliure.climaker.PolyStruct<" + + "unoidl.test.cliure.climaker.PolyStruct<" + + "System.Char,uno.Any>,System.String>>[][]"); + sType = ((PolymorphicType) cobj.Args[42].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct<" + + "System.String,unoidl.test.cliure.climaker.PolyStruct<" + + "System.Char,unoidl.test.cliure.climaker.PolyStruct2<" + + "uno.Any>>>[][]"); + sType = ((PolymorphicType) cobj.Args[43].Type).PolymorphicName; + l.assure( sType == "unoidl.test.cliure.climaker.PolyStruct<" + + "unoidl.test.cliure.climaker.PolyStruct," + + "unoidl.test.cliure.climaker.PolyStruct2>[][]"); + + + + + } + catch (Exception) + { + l.assure(false); + } + } + + void testSingletons(Logger l) + { + l.Function = "testSingletons"; + Context c = new Context(Context.test_kind.NORMAL); + try { + XTest obj = S4.get(c); + l.assure(obj != null); + } catch (Exception) { + l.assure(false); + } + + /** Case context fails to provide singleton, a DeploymentException should be thrown. + */ + c = new Context(Context.test_kind.CREATION_FAILED); + try { + XTest obj = S4.get(c); + l.assure(obj != null); + } catch (ucss.uno.DeploymentException e) { + Type t = typeof(unoidl.test.cliure.climaker.S4); + l.assure( e.Message.IndexOf(t.FullName) != -1); + } catch (System.Exception) { + l.assure(false); + } + } + + void testAttributes(Logger l) + { + l.Function = "testAttributes"; + //oneway attribute + Type typeXTest = typeof(unoidl.test.cliure.climaker.XTest); + object[] arAttr = typeXTest.GetMethod("testOneway").GetCustomAttributes(false); + if (arAttr.Length == 1) + l.assure(typeof(uno.OnewayAttribute).Equals(arAttr[0].GetType())); + else + l.assure(false); + + //test exceptions + arAttr = typeXTest.GetMethod("testExceptions").GetCustomAttributes(false); + if (arAttr.Length == 1 && arAttr[0].GetType() == typeof(uno.ExceptionAttribute)) + { + uno.ExceptionAttribute attr = arAttr[0] as uno.ExceptionAttribute; + if (attr != null && attr.Raises.Length == 2) + { + l.assure(attr.Raises[0] == typeof(unoidl.com.sun.star.uno.Exception)); + l.assure(attr.Raises[1] == typeof(unoidl.com.sun.star.lang.ClassNotFoundException)); + } + else + l.assure(false); + } + else + l.assure(false); + + //function test must not have the oneway attribute and Exception attribute + arAttr = typeXTest.GetMethod("test").GetCustomAttributes(false); + l.assure(arAttr.Length == 0); + + //test exceptions on service constructor methods + Type typeS1 = typeof(unoidl.test.cliure.climaker.S1); + arAttr = typeS1.GetMethod("create3").GetCustomAttributes(false); + if (arAttr.Length == 1 && arAttr[0].GetType() == typeof(uno.ExceptionAttribute)) + { + uno.ExceptionAttribute attr = arAttr[0] as uno.ExceptionAttribute; + if (attr != null && attr.Raises.Length == 4) + { + l.assure(attr.Raises[0] == typeof(unoidl.com.sun.star.uno.RuntimeException)); + l.assure(attr.Raises[1] == typeof(unoidl.com.sun.star.lang.ClassNotFoundException)); + l.assure(attr.Raises[2] == typeof(unoidl.com.sun.star.lang.IllegalAccessException)); + l.assure(attr.Raises[3] == typeof(unoidl.com.sun.star.uno.DeploymentException)); + } + else + l.assure(false); + } + else + l.assure(false); + + //create1 does not have exceptions + arAttr = typeS1.GetMethod("create1").GetCustomAttributes(false); + l.assure(arAttr.Length == 0); + + //test exceptions of UNO interface attributes + arAttr = typeXTest.GetProperty("A3").GetGetMethod().GetCustomAttributes(false); + if (arAttr.Length == 1) + { + uno.ExceptionAttribute attr = arAttr[0] as uno.ExceptionAttribute; + if (attr != null && attr.Raises.Length == 2) + { + l.assure(attr.Raises[0] == typeof(unoidl.com.sun.star.uno.Exception)); + l.assure(attr.Raises[1] == typeof(unoidl.com.sun.star.lang.ClassNotFoundException)); + } + else + l.assure(false); + } + else + l.assure(false); + + arAttr = typeXTest.GetProperty("A3").GetSetMethod().GetCustomAttributes(false); + if (arAttr.Length == 1) + { + uno.ExceptionAttribute attr = arAttr[0] as uno.ExceptionAttribute; + if (attr != null && attr.Raises.Length == 1) + l.assure(attr.Raises[0] == typeof(unoidl.com.sun.star.uno.RuntimeException)); + else + l.assure(false); + } + else + l.assure(false); + + //attribute A1 must have the ExceptionAttribute + l.assure(typeXTest.GetProperty("A1").GetGetMethod().GetCustomAttributes(false).Length == 0); + l.assure(typeXTest.GetProperty("A1").GetSetMethod().GetCustomAttributes(false).Length == 0); + + //Test BoundAttribute + BoundAttribute bound = (BoundAttribute) Attribute.GetCustomAttribute( + typeXTest.GetProperty("A1"), typeof(BoundAttribute)); + l.assure(bound != null); + + bound = (BoundAttribute) Attribute.GetCustomAttribute( + typeXTest.GetProperty("A3"), typeof(BoundAttribute)); + l.assure(bound == null); + } + + void testPolyStructAttributes(Logger l) + { + l.Function = "testPolyStructAttributes"; + //Test polymorphic struct + Type typeStruct = typeof(unoidl.test.cliure.climaker.PolyStruct); + object[] arAttr = typeStruct.GetCustomAttributes(false); + if (arAttr.Length == 1) + { + try { + uno.TypeParametersAttribute attr = (uno.TypeParametersAttribute) arAttr[0]; + string[] arNames = new string[]{"if", "else"}; + l.assure(attr != null && attr.Parameters.ToString().Equals(arNames.ToString())); + }catch(Exception ) { + l.assure(false); + } + } + else + l.assure(false); + l.assure(typeof(unoidl.test.cliure.climaker.Struct1).GetCustomAttributes(false).Length == 0); + //member of a polymorphic struct with a parameterized type have also an attribute + arAttr = typeStruct.GetField("member1").GetCustomAttributes(false); + if (arAttr.Length == 1) + { + uno.ParameterizedTypeAttribute attr = arAttr[0] as uno.ParameterizedTypeAttribute; + l.assure(attr != null && attr.Type == "if"); + } + else + l.assure(false); + + + //test instantiated polymorphic struct: return value +// Type typeXTest = typeof(XTest); +// arAttr = typeXTest.GetMethod("testPolyStruct").ReturnTypeCustomAttributes.GetCustomAttributes(false); +// if (arAttr.Length == 1) +// { +// uno.TypeArgumentsAttribute attr = arAttr[0] as uno.TypeArgumentsAttribute; +// l.assure(attr != null && attr.Arguments.Length == 2 +// &&attr.Arguments[0] == typeof(char) +// && attr.Arguments[1] == typeof(int)); +// } +// else +// l.assure(false); +// arAttr = typeXTest.GetMethod("testPolyStruct").GetCustomAttributes(false); + } + +// private XComponentContext context; + + void testPolymorphicType(Logger l) + { + l.Function = "testPolymorphicType"; + string name = "unoidl.test.cliure.climaker.PolyStruct"; + + uno.PolymorphicType t1 = PolymorphicType.GetType( + typeof(unoidl.test.cliure.climaker.PolyStruct), name); + + uno.PolymorphicType t2 = PolymorphicType.GetType( + typeof(unoidl.test.cliure.climaker.PolyStruct ), name); + + l.assure(t1 == t2); + l.assure(t1.PolymorphicName == name); + l.assure(t1.OriginalType == typeof(unoidl.test.cliure.climaker.PolyStruct)); + + } + + void testInterface(Logger l) + { + l.Function = "testInterface"; + try { + Context c = new Context(Context.test_kind.NORMAL); + XTest obj = S1.create1(c); + bool aBool = true; + byte aByte = 0xff; + short aShort = 0x7fff; + ushort aUShort = 0xffff; + int aInt = 0x7fffffff; + uint aUInt = 0xffffffff; + long aLong = 0x7fffffffffffffff; + ulong aULong = 0xffffffffffffffff; + float aFloat = 0.314f; + double aDouble = 0.314d; + char aChar = 'A'; + string aString = "Hello World"; + Type aType = typeof(XTest); + Any aAny = new Any(typeof(XTest), obj); + Enum2 aEnum2 = Enum2.VALUE2; + Struct1 aStruct1 = new Struct1(); + object aXInterface = new object(); + ucss.lang.XComponent aXComponent = (ucss.lang.XComponent) obj; + bool[] aSeqBool = {true, false, true}; + + obj.inParameters(aBool, aByte, aShort, aUShort, + aInt, aUInt, aLong, aULong, + aFloat, aDouble, aChar, aString, + aType, aAny,aEnum2, aStruct1, + aXInterface, aXComponent, aSeqBool); + + bool outBool; + byte outByte; + short outShort; + ushort outUShort; + int outInt; + uint outUInt; + long outLong; + ulong outULong; + float outFloat; + double outDouble; + char outChar; + string outString; + Type outType; + Any outAny; + Enum2 outEnum2; + Struct1 outStruct1; + object outXInterface; + ucss.lang.XComponent outXComponent; + bool[] outSeqBool; + + obj.outParameters(out outBool, out outByte, out outShort, out outUShort, + out outInt, out outUInt, out outLong, out outULong, + out outFloat, out outDouble, out outChar, out outString, + out outType, out outAny, out outEnum2, out outStruct1, + out outXInterface, out outXComponent, out outSeqBool); + + l.assure(aBool == outBool); + l.assure(aByte == outByte); + l.assure(aShort == outShort); + l.assure(aUShort == outUShort); + l.assure(aInt == outInt); + l.assure(aUInt == outUInt); + l.assure(aLong == outLong); + l.assure(aULong == outULong); + l.assure(aFloat == outFloat); + l.assure(aDouble == outDouble); + l.assure(aChar == outChar); + l.assure(aString == outString); + l.assure(aType == outType); + l.assure(aAny.Equals(outAny)); + l.assure(aEnum2 == outEnum2); + l.assure(aStruct1 == outStruct1); + l.assure(aXInterface == outXInterface); + l.assure(aXComponent == outXComponent); + l.assure(aSeqBool == outSeqBool); + + bool inoutBool = false; + byte inoutByte = 10; + short inoutShort = 11; + ushort inoutUShort = 12; + int inoutInt = 13; + uint inoutUInt = 14; + long inoutLong = 15; + ulong inoutULong = 16; + float inoutFloat = 4.134f; + double inoutDouble = 5.135; + char inoutChar = 'B'; + string inoutString = "Hello Hamburg"; + Type inoutType = typeof(int); + Any inoutAny = new Any(inoutInt); + Enum2 inoutEnum2 = Enum2.VALUE4; + Struct1 inoutStruct1 = new Struct1(); + object inoutXInterface = new object(); + ucss.lang.XComponent inoutXComponent = (ucss.lang.XComponent) S1.create1(c); + bool[] inoutSeqBool = {false, true, false}; + + + obj.inoutParameters(ref inoutBool, ref inoutByte, ref inoutShort, ref inoutUShort, + ref inoutInt, ref inoutUInt, ref inoutLong, ref inoutULong, + ref inoutFloat, ref inoutDouble, ref inoutChar, ref inoutString, + ref inoutType, ref inoutAny, ref inoutEnum2, ref inoutStruct1, + ref inoutXInterface, ref inoutXComponent, ref inoutSeqBool); + + l.assure(aBool == inoutBool); + l.assure(aByte == inoutByte); + l.assure(aShort == inoutShort); + l.assure(aUShort == inoutUShort); + l.assure(aInt == inoutInt); + l.assure(aUInt == inoutUInt); + l.assure(aLong == inoutLong); + l.assure(aULong == inoutULong); + l.assure(aFloat == inoutFloat); + l.assure(aDouble == inoutDouble); + l.assure(aChar == inoutChar); + l.assure(aString == inoutString); + l.assure(aType == inoutType); + l.assure(aAny.Equals(inoutAny)); + l.assure(aEnum2 == inoutEnum2); + l.assure(aStruct1 == inoutStruct1); + l.assure(aXInterface == inoutXInterface); + l.assure(aXComponent == inoutXComponent); + l.assure(aSeqBool == inoutSeqBool); + + + //now check the return values + obj.inParameters(aBool, aByte, aShort, aUShort, + aInt, aUInt, aLong, aULong, + aFloat, aDouble, aChar, aString, + aType, aAny,aEnum2, aStruct1, + aXInterface, aXComponent, aSeqBool); + + l.assure(obj.retBoolean() == aBool); + l.assure(obj.retByte() == aByte); + l.assure(obj.retShort() == aShort); + l.assure(obj.retUShort() == aUShort); + l.assure(obj.retLong() == aInt); + l.assure(obj.retULong() == aUInt); + l.assure(obj.retHyper() == aLong); + l.assure(obj.retUHyper() == aULong); + l.assure(obj.retFloat() == aFloat); + l.assure(obj.retDouble() == aDouble); + l.assure(obj.retChar() == aChar); + l.assure(obj.retString() == aString); + l.assure(obj.retType() == aType); + l.assure(obj.retAny().Equals(aAny)); + l.assure(obj.retEnum() == aEnum2); + l.assure(obj.retStruct1() == aStruct1); + l.assure(obj.retXInterface() == aXInterface); + l.assure(obj.retXComponent() == aXComponent); + l.assure(obj.retSeqBool() == aSeqBool); + + + obj = S1.create1(c); + obj.attrBoolean = true; + l.assure(obj.attrBoolean == true); + obj.attrByte = aByte; + l.assure(obj.attrByte == aByte); + obj.attrShort = aShort; + l.assure(obj.attrShort == aShort); + obj.attrUShort = aUShort; + l.assure(obj.attrUShort == aUShort); + obj.attrLong = aInt; + l.assure(obj.attrLong == aInt); + obj.attrULong = aUInt; + l.assure(obj.attrULong == aUInt); + obj.attrHyper = aLong; + l.assure(obj.attrHyper == aLong); + obj.attrUHyper = aULong; + l.assure(obj.attrUHyper == aULong); + obj.attrFloat = aFloat; + l.assure(obj.attrFloat == aFloat); + obj.attrDouble = aDouble; + l.assure(obj.attrDouble == aDouble); + obj.attrChar = aChar; + l.assure(obj.attrChar == aChar); + obj.attrString = aString; + l.assure(obj.attrString == aString); + obj.attrType = aType; + l.assure(obj.attrType == aType); + obj.attrAny = aAny; + l.assure(obj.attrAny.Equals(aAny)); + obj.attrEnum2 = aEnum2; + l.assure(obj.attrEnum2 == aEnum2); + obj.attrStruct1 = aStruct1; + l.assure(obj.attrStruct1 == aStruct1); + obj.attrXInterface = aXInterface; + l.assure(obj.attrXInterface == aXInterface); + obj.attrXComponent = aXComponent; + l.assure(obj.attrXComponent == aXComponent); + obj.attrSeqBoolean = aSeqBool; + l.assure(obj.attrSeqBoolean == aSeqBool); + } catch (Exception ) + { + l.assure(false); + } + } + + public void testAny(Logger l) + { + l.Function = "testAny"; + //create any with valid and invalid arguments + try + { + Any a = new Any(null, null); + l.assure(false); + } + catch(System.Exception e) + { + l.assure(e.Message.IndexOf("Any") != -1); + } + try + { + Any a = new Any(typeof(int), null); + l.assure(false); + } + catch(System.Exception e) + { + l.assure(e.Message.IndexOf("Any") != -1); + } + + + try + { + Any a = new Any(typeof(unoidl.com.sun.star.uno.XComponentContext), null); + a = new Any('a'); + a = new Any((sbyte)1); + } + catch (System.Exception) + { + l.assure(false); + } + + //test polymorphic struct + try + { + Any a = new Any(typeof(unoidl.test.cliure.climaker.PolyStruct), + new PolyStruct()); + l.assure(false); + } + catch (System.Exception e) + { + l.assure(e.Message.IndexOf("Any") != -1); + } + try + { + Any a = new Any(uno.PolymorphicType.GetType( + typeof(unoidl.test.cliure.climaker.PolyStruct), + "unoidl.test.cliure.climaker.PolyStruct"), + new PolyStruct('A', 10)); + } + catch (System.Exception ) + { + l.assure(false); + } + + //test Any.Equals + + Any aVoid = Any.VOID; + l.assure(aVoid.Equals((object) Any.VOID)); + l.assure(aVoid.Equals(Any.VOID)); + + l.assure(aVoid.Equals(new Any("")) == false); + + Any a1 = new Any(10); + Any a2 = a1; + l.assure(a1.Equals(a2)); + + a1 = new Any(typeof(unoidl.com.sun.star.uno.XComponentContext), null); + l.assure(a1.Equals(a2) == false); + a2 = a1; + l.assure(a1.Equals(a2)); + l.assure(a1.Equals(null) == false); + l.assure(a1.Equals(new object()) == false); + } +} diff --git a/cli_ure/qa/climaker/makefile.mk b/cli_ure/qa/climaker/makefile.mk new file mode 100644 index 000000000..b979a0486 --- /dev/null +++ b/cli_ure/qa/climaker/makefile.mk @@ -0,0 +1,126 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you 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 . +# + +PRJ := ..$/.. +PRJNAME := cli_ure +TARGET := test_climaker +PACKAGE = climaker + +#we use the climaker which is build by this project +CLIMAKER*=$(WRAPCMD) $(BIN)$/climaker +.INCLUDE: settings.mk + + +#----- compile .java files ----------------------------------------- + +JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar +JAVAFILES = ClimakerTestCase.java +JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) + +#----- make a jar from compiled files ------------------------------ + +MAXLINELENGTH = 100000 + +JARCLASSDIRS = $(PACKAGE) +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE + + + +CSCFLAGS = -incr +.IF "$(debug)" != "" +CSCFLAGS += -checked+ -define:DEBUG -define:TRACE -debug+ +.ELSE +CSCFLAGS += -optimize+ +.ENDIF + + +OUTDIR=$(BIN)$/qa$/climaker +EXETARGET=$(OUTDIR)$/test_climaker.exe + +ALLTAR: $(EXETARGET) + +CSFILES = climaker.cs testobjects.cs + + +$(EXETARGET): $(CSFILES) $(OUTDIR)$/cli_test_types.dll + $(GNUCOPY) -p $(BIN)$/cli_cppuhelper.dll $(OUTDIR)$/cli_cppuhelper.dll + $(GNUCOPY) -p $(BIN)$/cli_uretypes.dll $(OUTDIR)$/cli_uretypes.dll + $(GNUCOPY) -p $(BIN)$/cli_basetypes.dll $(OUTDIR)$/cli_basetypes.dll + $(GNUCOPY) -p $(BIN)$/cli_ure.dll $(OUTDIR)$/cli_ure.dll + $(GNUCOPY) -p $(BIN)$/climaker.exe $(OUTDIR) + $(CSC) $(CSCFLAGS) -target:exe -out:$(EXETARGET) \ + -reference:$(BIN)$/cli_ure.dll \ + -reference:$(BIN)$/cli_uretypes.dll \ + -reference:$(BIN)$/cli_basetypes.dll \ + -reference:$(OUTDIR)$/cli_test_types.dll \ + $(CSFILES) + + + +#----------------------------------------------------------------------------- +CLIMAKERFLAGS = +.IF "$(debug)" != "" +CLIMAKERFLAGS += --verbose +.ENDIF + + + + +$(OUTDIR)$/types.urd: types.idl + - $(MKDIR) $(OUTDIR) + $(IDLC) -O$(OUTDIR) -I$(SOLARIDLDIR) -cid -we $< + +$(OUTDIR)$/types.rdb: $(OUTDIR)$/types.urd + - rm $@ + $(REGMERGE) $@ /UCR $< + +$(OUTDIR)$/cli_test_types.dll: $(OUTDIR)$/types.rdb $(BIN)$/climaker.exe $(BIN)$/cli_uretypes.dll + $(CLIMAKER) $(CLIMAKERFLAGS) --out $@ \ + -r $(BIN)$/cli_uretypes.dll \ + -X $(SOLARBINDIR)$/types.rdb \ + $(OUTDIR)$/types.rdb + + + +.IF "$(depend)" == "" +ALL: ALLTAR +.ELSE +ALL: ALLDEP +.ENDIF + +.INCLUDE: target.mk + +# --- Parameters for the test -------------------------------------- + +# test base is java complex +CT_TESTBASE = -TestBase java_complex + +# test looks something like the.full.package.TestName +CT_TEST = -o $(PACKAGE:s\$/\.\).$(JAVAFILES:b) + +# start the runner application +CT_APP = org.openoffice.Runner + +CT_NOOFFICE = -NoOffice +# --- Targets ------------------------------------------------------ + +RUN: + java -cp $(CLASSPATH) -Dcli_ure_test=$(EXETARGET) $(CT_APP) $(CT_NOOFFICE) $(CT_TESTBASE) $(CT_TEST) + +run: RUN diff --git a/cli_ure/qa/climaker/testobjects.cs b/cli_ure/qa/climaker/testobjects.cs new file mode 100644 index 000000000..664b0d0e2 --- /dev/null +++ b/cli_ure/qa/climaker/testobjects.cs @@ -0,0 +1,579 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; +using System.Reflection; +using System.Diagnostics; +using uno; + +using unoidl.test.cliure.climaker; +//using unoidl.com.sun.star.uno; +using ucss=unoidl.com.sun.star; + + +/* To create this component, the class context (in this assembly) can be used. When + createInstanceWithArgumentsAndContext is called on the service manager + then the arguments are passed into the ctor. +*/ +class Component:uno.util.WeakComponentBase, XTest +{ + public Component(ucss.uno.XComponentContext ctx) { + m_args = new Any[] {new Any(typeof(ucss.uno.XComponentContext), ctx)}; + m_A2 = 0; + m_A4 = 0; + } + + public Component(ucss.uno.XComponentContext ctx, uno.Any[] args) { + m_args = new Any[args.Length + 1]; + m_args[0] = new Any(typeof(ucss.uno.XComponentContext), ctx); + for (int i = 0; i < args.Length; i ++) { + m_args[i+1] = args[i]; + } + } + + public Any[] Args { + get + { + return m_args; + } + } + + // XTest + public int A1 { + get { + return m_A1; + } + set { + m_A1 = value; + } + } + + public int A2 { + get { + return m_A2; + } + } + + public int A3 { + get { + return m_A3; + } + set { + m_A3 = value; + } + } + + public int A4 { + get { + return m_A4; + } + } + + public bool test() { + return true; + } + + public void testOneway() + { + } + + public void testExceptions() + { + } + + public PolyStruct testPolyStruct(PolyStruct val) + { + return val; + } + + public void inParameters(bool aBool, byte aByte, + short aShort, ushort aUShort, + int aInt, uint aUInt, + long aLong, ulong aULong, + float aFloat, double aDouble, + char aChar, string aString, + Type aType, uno.Any aAny, + Enum2 aEnum, Struct1 aStruct, + object aXInterface, + unoidl.com.sun.star.lang.XComponent aXComponent, + bool[] seqBool) + { + m_Bool = aBool; + m_Byte = aByte; + m_Short = aShort; + m_UShort = aUShort; + m_Int = aInt; + m_UInt = aUInt; + m_Long = aLong; + m_ULong = aULong; + m_Float = aFloat; + m_Double = aDouble; + m_Char = aChar; + m_String = aString; + m_Type = aType; + m_Any = aAny; + m_Enum2 = aEnum; + m_Struct1 = aStruct; + m_XInterface = aXInterface; + m_XComponent = aXComponent; + m_seqBool = seqBool; + + } + + public void outParameters(out bool aBool, out byte aByte, + out short aShort, out ushort aUShort, + out int aInt, out uint aUInt, + out long aLong, out ulong aULong, + out float aFloat, out double aDouble, + out char aChar, out string aString, + out Type aType, out uno.Any aAny, + out Enum2 aEnum, out Struct1 aStruct, + out object aXInterface, + out unoidl.com.sun.star.lang.XComponent aXComponent, + out bool[] seqBool) + { + aBool = m_Bool; + aByte = m_Byte; + aShort = m_Short; + aUShort = m_UShort; + aInt = m_Int; + aUInt = m_UInt; + aLong = m_Long; + aULong = m_ULong; + aFloat = m_Float; + aDouble = m_Double; + aChar = m_Char; + aString = m_String; + aType = m_Type; + aAny = m_Any; + aEnum = m_Enum2; + aStruct = m_Struct1; + aXInterface = m_XInterface; + aXComponent = m_XComponent; + seqBool = m_seqBool; + + } + + //returns the values which have been set in a previous call + //to this function or inParameters. + public void inoutParameters(ref bool aBool, ref byte aByte, + ref short aShort, ref ushort aUShort, + ref int aInt, ref uint aUInt, + ref long aLong, ref ulong aULong, + ref float aFloat, ref double aDouble, + ref char aChar, ref string aString, + ref Type aType, ref uno.Any aAny, + ref Enum2 aEnum, ref Struct1 aStruct, + ref object aXInterface, + ref unoidl.com.sun.star.lang.XComponent aXComponent, + ref bool[] seqBool) + { + bool _bool = aBool; + aBool = m_Bool; + m_Bool = _bool; + + byte _byte = aByte; + aByte = m_Byte; + m_Byte = _byte; + + short _short = aShort; + aShort = m_Short; + m_Short = _short; + + ushort _ushort = aUShort; + aUShort = m_UShort; + m_UShort = _ushort; + + int _int = aInt; + aInt = m_Int; + m_Int = _int; + + uint _uint = aUInt; + aUInt = m_UInt; + m_UInt = _uint; + + long _long = aLong; + aLong = m_Long; + m_Long = _long; + + ulong _ulong = aULong; + aULong = m_ULong; + m_ULong = _ulong; + + float _f = aFloat; + aFloat = m_Float; + m_Float = _f; + + double _d = aDouble; + aDouble = m_Double; + m_Double = _d; + + char _char = aChar; + aChar = m_Char; + m_Char = _char; + + string _string = aString; + aString = m_String; + m_String = _string; + + Type _type = aType; + aType = m_Type; + m_Type = _type; + + Any _any = aAny; + aAny = m_Any; + m_Any = _any; + + Enum2 _enum2 = aEnum; + aEnum = m_Enum2; + m_Enum2 = _enum2; + + Struct1 _struct1 = aStruct; + aStruct = m_Struct1; + m_Struct1 = _struct1; + + object _obj = aXInterface; + aXInterface = m_XInterface; + m_XInterface = _obj; + + ucss.lang.XComponent _xcomp = aXComponent; + aXComponent = m_XComponent; + m_XComponent = _xcomp; + + bool[] _seq = seqBool; + seqBool = m_seqBool; + m_seqBool = _seq; + } + + public bool retBoolean() + { + return m_Bool; + } + + public byte retByte() + { + return m_Byte; + } + + public short retShort() + { + return m_Short; + } + + public ushort retUShort() + { + return m_UShort; + } + + public int retLong() + { + return m_Int; + } + + public uint retULong() + { + return m_UInt; + } + + public long retHyper() + { + return m_Long; + } + + public ulong retUHyper() + { + return m_ULong; + } + + public float retFloat() + { + return m_Float; + } + + public double retDouble() + { + return m_Double; + } + + public char retChar() + { + return m_Char; + } + + public string retString() + { + return m_String; + } + + public Type retType() + { + return m_Type; + } + + public uno.Any retAny() + { + return m_Any; + } + + public Enum2 retEnum() + { + return m_Enum2; + } + public Struct1 retStruct1() + { + return m_Struct1; + } + + public object retXInterface() + { + return m_XInterface; + } + + public unoidl.com.sun.star.lang.XComponent retXComponent() + { + return m_XComponent; + } + + public bool[] retSeqBool() + { + return m_seqBool; + } + + public bool attrBoolean + { + get { + return m_Bool; + } + set { + m_Bool = value; + } + } + + public byte attrByte + { + get { + return m_Byte; + } + set { + m_Byte = value; + } + } + + public short attrShort + { + get { + return m_Short; + } + set { + m_Short = value; + } + } + + public ushort attrUShort + { + get { + return m_UShort; + } + set { + m_UShort = value; + } + } + + public int attrLong + { + get { + return m_Int; + } + set { + m_Int = value; + } + } + + public uint attrULong + { + get { + return m_UInt; + } + set { + m_UInt = value; + } + } + + public long attrHyper + { + get { + return m_Long; + } + set { + m_Long = value; + } + } + + public ulong attrUHyper + { + get { + return m_ULong; + } + set { + m_ULong = value; + } + } + + public float attrFloat + { + get { + return m_Float; + } + set { + m_Float = value; + } + } + + public double attrDouble + { + get { + return m_Double; + } + set { + m_Double = value; + } + } + + public char attrChar + { + get { + return m_Char; + } + set { + m_Char = value; + } + } + + public string attrString + { + get { + return m_String; + } + set { + m_String = value; + } + } + + public Type attrType + { + get { + return m_Type; + } + set { + m_Type = value; + } + } + + public Any attrAny + { + get { + return m_Any; + } + set { + m_Any = value; + } + } + + public Enum2 attrEnum2 + { + get { + return m_Enum2; + } + set { + m_Enum2 = value; + } + } + + public Struct1 attrStruct1 + { + get { + return m_Struct1; + } + set { + m_Struct1 = value; + } + } + + public object attrXInterface + { + get { + return m_XInterface; + } + set { + m_XInterface = value; + } + } + + public ucss.lang.XComponent attrXComponent + { + get { + return m_XComponent; + } + set { + m_XComponent = value; + } + } + + public bool[] attrSeqBoolean + { + get { + return m_seqBool; + } + set { + m_seqBool = value; + } + } + + + + + + Any[] m_args; + int m_A1; + int m_A2; + int m_A3; + int m_A4; + + bool m_Bool; + byte m_Byte; + short m_Short; + ushort m_UShort; + int m_Int; + uint m_UInt; + long m_Long; + ulong m_ULong; + float m_Float; + double m_Double; + char m_Char; + string m_String; + Type m_Type; + Any m_Any; + Enum2 m_Enum2; + Struct1 m_Struct1; + object m_XInterface; + unoidl.com.sun.star.lang.XComponent m_XComponent; + bool[] m_seqBool; + +} + + diff --git a/cli_ure/qa/climaker/types.idl b/cli_ure/qa/climaker/types.idl new file mode 100644 index 000000000..c9bb612dd --- /dev/null +++ b/cli_ure/qa/climaker/types.idl @@ -0,0 +1,477 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +module test { module cliure { module climaker { + +enum Enum1 { VALUE1 = -100, VALUE2 = 100 }; + +enum Enum2 { VALUE0 = 0, VALUE1 = 1, VALUE2 = 2, VALUE4 = 4 }; + +struct Struct1 { long member1; }; + +struct PolyStruct { + if member1; + long member2; +}; + +struct PolyStruct2 { + a member1; + long member2; +}; + +struct PolyStruct3 { + a member1; + b member2; +}; + +interface XTest { + boolean test(); + + [attribute, bound] long A1; + [attribute, bound, readonly] long A2; + [attribute] long A3 { + get raises + (com::sun::star::uno::Exception, + com::sun::star::lang::ClassNotFoundException); + set raises (com::sun::star::uno::RuntimeException); + }; + [attribute, readonly] long A4 { + get raises (com::sun::star::uno::DeploymentException); + }; + + void testOneway(); + + void testExceptions() + raises( com::sun::star::uno::Exception, + com::sun::star::lang::ClassNotFoundException); + + + PolyStruct testPolyStruct([in] PolyStruct val); + + + void inParameters([in] boolean aBool, [in] byte aByte, [in] short aShort, + [in] unsigned short aUShort, [in] long aLong, [in] unsigned long aULong, + [in] hyper aHyper, [in] unsigned hyper aUHyper, [in] float aFloat, + [in] double aDouble, [in] char aChar, [in] string aString, + [in] type aType, [in] any aAny, [in] Enum2 aEnum, [in] Struct1 aStruct, + [in] com::sun::star::uno::XInterface aXInterface, + [in] com::sun::star::lang::XComponent aXComponent, + [in] sequence seqBool); + + void outParameters([out] boolean aBool, [out] byte aByte, [out] short aShort, + [out] unsigned short aUShort, [out] long aLong, [out] unsigned long aULong, + [out] hyper aHyper, [out] unsigned hyper aUHyper, [out] float aFloat, + [out] double aDouble, [out] char aChar, [out] string aString, + [out] type aType, [out] any aAny, [out] Enum2 aEnum, [out] Struct1 aStruct, + [out] com::sun::star::uno::XInterface aXInterface, + [out] com::sun::star::lang::XComponent aXComponent, + [out] sequence seqBool); + + void inoutParameters([inout] boolean aBool, [inout] byte aByte, [inout] short aShort, + [inout] unsigned short aUShort, [inout] long aLong, + [inout] unsigned long aULong, + [inout] hyper aHyper, [inout] unsigned hyper aUHyper, + [inout] float aFloat, + [inout] double aDouble, [inout] char aChar, [inout] string aString, + [inout] type aType, [inout] any aAny, [inout] Enum2 aEnum, + [inout] Struct1 aStruct, + [inout] com::sun::star::uno::XInterface aXInterface, + [inout] com::sun::star::lang::XComponent aXComponent, + [inout] sequence seqBool); + boolean retBoolean(); + byte retByte(); + short retShort(); + unsigned short retUShort(); + long retLong(); + unsigned long retULong(); + hyper retHyper(); + unsigned hyper retUHyper(); + float retFloat(); + double retDouble(); + char retChar(); + string retString(); + type retType(); + any retAny(); + Enum2 retEnum(); + Struct1 retStruct1(); + com::sun::star::uno::XInterface retXInterface(); + com::sun::star::lang::XComponent retXComponent(); + sequence retSeqBool(); + + [attribute] boolean attrBoolean; + [attribute] byte attrByte; + [attribute] short attrShort; + [attribute] unsigned short attrUShort; + [attribute] long attrLong; + [attribute] unsigned long attrULong; + [attribute] hyper attrHyper; + [attribute] unsigned hyper attrUHyper; + [attribute] float attrFloat; + [attribute] double attrDouble; + [attribute] char attrChar; + [attribute] string attrString; + [attribute] type attrType; + [attribute] any attrAny; + [attribute] Enum2 attrEnum2; + [attribute] Struct1 attrStruct1; + [attribute] com::sun::star::uno::XInterface attrXInterface; + [attribute] com::sun::star::lang::XComponent attrXComponent; + [attribute] sequence attrSeqBoolean; + }; + +typedef boolean Boolean; +typedef byte Byte; +typedef short Short; +typedef unsigned short UnsignedShort; +typedef long Long; +typedef unsigned long UnsignedLong; +typedef hyper Hyper; +typedef unsigned hyper UnsignedHyper; +typedef float Float; +typedef double Double; +typedef char Char; +typedef string String; +typedef type Type; +typedef any Any; +typedef Enum2 Enum; +typedef Struct1 Struct; +typedef com::sun::star::uno::XInterface XInterface; +typedef com::sun::star::uno::XNamingService XNamingService; +typedef com::sun::star::lang::XComponent XComponent; + +typedef sequence< Boolean > SequenceBoolean; +typedef sequence< Byte > SequenceByte; +typedef sequence< Short > SequenceShort; +typedef sequence< UnsignedShort > SequenceUnsignedShort; +typedef sequence< Long > SequenceLong; +typedef sequence< UnsignedLong > SequenceUnsignedLong; +typedef sequence< Hyper > SequenceHyper; +typedef sequence< UnsignedHyper > SequenceUnsignedHyper; +typedef sequence< Float > SequenceFloat; +typedef sequence< Double > SequenceDouble; +typedef sequence< Char > SequenceChar; +typedef sequence< String > SequenceString; +typedef sequence< Type > SequenceType; +typedef sequence< Any > SequenceAny; +typedef sequence< Enum > SequenceEnum; +typedef sequence< Struct > SequenceStruct; +typedef sequence< XInterface > SequenceXInterface; +typedef sequence< XNamingService > SequenceXNamingService; +typedef sequence< XComponent > SequenceXComponent; + +struct Struct2 { + boolean p1; + byte p2; + short p3; + unsigned short p4; + long p5; + unsigned long p6; + hyper p7; + unsigned hyper p8; + float p9; + double p10; + char p11; + string p12; + type p13; + any p14; + Enum2 p15; + Struct1 p16; + com::sun::star::uno::XInterface p17; + com::sun::star::uno::XNamingService p18; + Boolean t1; + Byte t2; + Short t3; + UnsignedShort t4; + Long t5; + UnsignedLong t6; + Hyper t7; + UnsignedHyper t8; + Float t9; + Double t10; + Char t11; + String t12; + Type t13; + Any t14; + Enum t15; + Struct t16; + XInterface t17; + XNamingService t18; + sequence< boolean > a1; + sequence< byte > a2; + sequence< short > a3; + sequence< unsigned short > a4; + sequence< long > a5; + sequence< unsigned long > a6; + sequence< hyper > a7; + sequence< unsigned hyper > a8; + sequence< float > a9; + sequence< double > a10; + sequence< char > a11; + sequence< string > a12; + sequence< type > a13; + sequence< any > a14; + sequence< Enum2 > a15; + sequence< Struct1 > a16; + sequence< com::sun::star::uno::XInterface > a17; + sequence< com::sun::star::uno::XNamingService > a18; + sequence< sequence< boolean > > aa1; + sequence< sequence< byte > > aa2; + sequence< sequence< short > > aa3; + sequence< sequence< unsigned short > > aa4; + sequence< sequence< long > > aa5; + sequence< sequence< unsigned long > > aa6; + sequence< sequence< hyper > > aa7; + sequence< sequence< unsigned hyper > > aa8; + sequence< sequence< float > > aa9; + sequence< sequence< double > > aa10; + sequence< sequence< char > > aa11; + sequence< sequence< string > > aa12; + sequence< sequence< type > > aa13; + sequence< sequence< any > > aa14; + sequence< sequence< Enum2 > > aa15; + sequence< sequence< Struct1 > > aa16; + sequence< sequence< com::sun::star::uno::XInterface > > aa17; + sequence< sequence< com::sun::star::uno::XNamingService > > aa18; + sequence< SequenceBoolean > at1; + sequence< SequenceByte > at2; + sequence< SequenceShort > at3; + sequence< SequenceUnsignedShort > at4; + sequence< SequenceLong > at5; + sequence< SequenceUnsignedLong > at6; + sequence< SequenceHyper > at7; + sequence< SequenceUnsignedHyper > at8; + sequence< SequenceFloat > at9; + sequence< SequenceDouble > at10; + sequence< SequenceChar > at11; + sequence< SequenceString > at12; + sequence< SequenceType > at13; + sequence< SequenceAny > at14; + sequence< SequenceEnum > at15; + sequence< SequenceStruct > at16; + sequence< SequenceXInterface > at17; + sequence< SequenceXNamingService > at18; +}; + +struct Struct3 +{ + XTest iTest; +}; + +struct Struct4: Struct3 +{ + long n; +}; + +struct Struct5 +{ + Struct3 m; + Struct4 n; +}; + +struct Struct6 +{ + Struct4 m; +}; + +struct Struct7 +{ + sequence > seqseqStruct6; +}; + +service S1: XTest { + create1(); + + create2([in] any... create2) + raises (com::sun::star::uno::RuntimeException, + com::sun::star::lang::ClassNotFoundException, + com::sun::star::uno::Exception, + com::sun::star::lang::IllegalAccessException, + com::sun::star::uno::DeploymentException); + + create3([in] sequence S1) + raises (com::sun::star::uno::RuntimeException, + com::sun::star::lang::ClassNotFoundException, + com::sun::star::lang::IllegalAccessException, + com::sun::star::uno::DeploymentException); + + create4([in] long javamaker, [in] long S1, [in] long create4); + + create5( + [in] boolean p1, + [in] byte p2, + [in] short p3, + [in] unsigned short p4, + [in] long p5, + [in] unsigned long p6, + [in] hyper p7, + [in] unsigned hyper p8, + [in] float p9, + [in] double p10, + [in] char p11, + [in] string p12, + [in] type p13, + [in] any p14, + [in] Enum2 p15, + [in] Struct1 p16, + [in] PolyStruct p17, + [in] PolyStruct p18, + [in] com::sun::star::uno::XInterface p19, + [in] com::sun::star::lang::XComponent p20, + [in] Boolean t1, + [in] Byte t2, + [in] Short t3, + [in] UnsignedShort t4, + [in] Long t5, + [in] UnsignedLong t6, + [in] Hyper t7, + [in] UnsignedHyper t8, + [in] Float t9, + [in] Double t10, + [in] Char t11, + [in] String t12, + [in] Type t13, + [in] Any t14, + [in] Enum t15, + [in] Struct t16, + [in] XInterface t17, + [in] XComponent t18, + [in] sequence< boolean > a1, + [in] sequence< byte > a2, + [in] sequence< short > a3, + [in] sequence< unsigned short > a4, + [in] sequence< long > a5, + [in] sequence< unsigned long > a6, + [in] sequence< hyper > a7, + [in] sequence< unsigned hyper > a8, + [in] sequence< float > a9, + [in] sequence< double > a10, + [in] sequence< char > a11, + [in] sequence< string > a12, + [in] sequence< type > a13, + [in] sequence< any > a14, + [in] sequence< Enum2 > a15, + [in] sequence< Struct1 > a16, + [in] sequence< com::sun::star::uno::XInterface > a17, + [in] sequence< com::sun::star::lang::XComponent > a18, + [in] sequence< sequence< boolean > > aa1, + [in] sequence< sequence< byte > > aa2, + [in] sequence< sequence< short > > aa3, + [in] sequence< sequence< unsigned short > > aa4, + [in] sequence< sequence< long > > aa5, + [in] sequence< sequence< unsigned long > > aa6, + [in] sequence< sequence< hyper > > aa7, + [in] sequence< sequence< unsigned hyper > > aa8, + [in] sequence< sequence< float > > aa9, + [in] sequence< sequence< double > > aa10, + [in] sequence< sequence< char > > aa11, + [in] sequence< sequence< string > > aa12, + [in] sequence< sequence< type > > aa13, + [in] sequence< sequence< any > > aa14, + [in] sequence< sequence< Enum2 > > aa15, + [in] sequence< sequence< Struct1 > > aa16, + [in] sequence< sequence< com::sun::star::uno::XInterface > > aa17, + [in] sequence< sequence< com::sun::star::lang::XComponent > > aa18, + [in] sequence< SequenceBoolean > at1, + [in] sequence< SequenceByte > at2, + [in] sequence< SequenceShort > at3, + [in] sequence< SequenceUnsignedShort > at4, + [in] sequence< SequenceLong > at5, + [in] sequence< SequenceUnsignedLong > at6, + [in] sequence< SequenceHyper > at7, + [in] sequence< SequenceUnsignedHyper > at8, + [in] sequence< SequenceFloat > at9, + [in] sequence< SequenceDouble > at10, + [in] sequence< SequenceChar > at11, + [in] sequence< SequenceString > at12, + [in] sequence< SequenceType > at13, + [in] sequence< SequenceAny > at14, + [in] sequence< SequenceEnum > at15, + [in] sequence< SequenceStruct > at16, + [in] sequence< SequenceXInterface > at17, + [in] sequence< SequenceXComponent > at18 + ); + + create6( + [in] PolyStruct2 arg1, + [in] PolyStruct2 arg2, + [in] PolyStruct2 arg3, + [in] PolyStruct2 arg4, + [in] PolyStruct2 arg5, + [in] PolyStruct2 arg6, + [in] PolyStruct2 arg7, + [in] PolyStruct2 arg8, + [in] PolyStruct2 arg9, + [in] PolyStruct2 arg10, + [in] PolyStruct2 arg11, + [in] PolyStruct2 arg12, + [in] PolyStruct2 arg13, + [in] PolyStruct2 > arg14, + [in] PolyStruct2,string> > arg15, + [in] PolyStruct > > arg16, + [in] PolyStruct, PolyStruct2 > arg17, + [in] PolyStruct2 > arg101, + [in] PolyStruct2 > arg102, + [in] PolyStruct2 > arg103, + [in] PolyStruct2 > arg104, + [in] PolyStruct2 > arg105, + [in] PolyStruct2 > arg106, + [in] PolyStruct2 > arg107, + [in] PolyStruct2 > arg108, + [in] PolyStruct2 > arg109, + [in] PolyStruct2 > arg110, + [in] PolyStruct2 > arg111, + [in] PolyStruct2 > arg112, + [in] PolyStruct2 > arg113, + [in] PolyStruct2 > > > arg114, + [in] PolyStruct2, sequence > > > arg115, + [in] PolyStruct2 > > arg201, + [in] sequence > arg301, + [in] sequence > > arg302, + [in] sequence,string> > > arg303, + [in] sequence > > > arg304, + [in] sequence, PolyStruct2 > > arg305, + [in] sequence > > arg401, + [in] sequence > > >arg402, + [in] sequence,string> > > > arg403, + [in] sequence > > > > arg404, + [in] sequence, PolyStruct2 > > > arg405 + + ); +}; + +service S2: XTest; + +service S3 { interface XTest; }; + +singleton S4: XTest; + +singleton S5 { service S2; }; + + +}; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/qa/versioning/readme.txt b/cli_ure/qa/versioning/readme.txt new file mode 100644 index 000000000..dfb2f3ccf --- /dev/null +++ b/cli_ure/qa/versioning/readme.txt @@ -0,0 +1,19 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you 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 . +# + +This test has moved to testtools/source/cliversioning testtools/qa/cliversioning diff --git a/cli_ure/readme.txt b/cli_ure/readme.txt new file mode 100644 index 000000000..47b2df91d --- /dev/null +++ b/cli_ure/readme.txt @@ -0,0 +1,263 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you 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 . +# + +Adapting version after a release of an office +============================================= +After a release the entries in cli_ure/version/version.txt must be changed to reflect the versions +of the assemblies at the time of the release. Please refer to the document at +http://udk.openoffice.org/common/man/spec/assemblyversioning.html +for more information about versioning of assemblies. + + +Step 1: Remove old office installations. + +To do this, deinstall all offices, +and make sure that there are no assemblies installed in the Global Assembly Cache (GAC). The GAC +is contained in C:\Windows\assembly. Change C:\Windows according to your windows installation. +Use the Windows Explorer to view the contents of the GAC. Are there any of the following assemblies +installed: + +cli_uretypes.dll +cli_basetypes.dll +cli_cppuhelper.dll +cli_ure.dll +cli_oootypes.dll (build in unoil) + +policy.x.y.cli_uretypes.dll +policy.x.y.cli_basetypes.dll +policy.x.y.cli_ure.dll +policy.x.y.cli_cppuhelper.dll +policy.x.y.cli_oootypes.dll (build in unoil) + +The "x" and "y" in the names of the policy assemblies are to be replaces by version numbers. At the +time of writing the real names are: + +policy.1.0.cli_uretypes.dll +policy.1.0.cli_basetypes.dll +policy.1.0.cli_ure.dll +policy.1.0.cli_cppuhelper.dll +policy.1.0.cli_ootypes.dll (build in unoil) + +After deinstalling the offices, there should none of them remain in the GAC. If there are some, then +try to remove them by clicking on them and choosing uninstall. + +Step 2: Install the office of the last release (respin when using staroffice) + +Step 3: Determine the versions of the assemblies + +Use the Windows Explorer to view the contents of the Windows\assembly directory. Locate the assemblies +and policy assemblies. See step 1 for the names of those assemblies. Take down the version number as +can be found in the version column, which is usually right next to the name column. + +Step 4: Changing the versions in the cli_ure module. + +Open the file cli_ure\version\version.txt. +The file contains name/value pairs, such as:CLI_URETYPES_NEW_VERSION=1.0.3.0. +The first part of the names represent the assembly which they are referring to. So obviously +entries starting with CLI_URETYPES refer to the cli_uretypes.dll. Entries which contain the part "POLICY" refer +to the policy assembly. For example: +CLI_URETYPES_POLICY_VERSION refers to the policy assembly for cli_uretypes which is named +policy.1.0.cli_uretypes.dll + +The versions may already have been incremented because someone has changed code after the +last release. So if a version from version.txt is greater than the one of the respective +assembly in the GAC then leave it at that. + +The values have to be adjusted as follows: + +XYZ_NEW_VERSION : increase the value of the version +GAC. "XYZ_" would be "CLI_URETYPES", "CLI_URE", etc. +XYZ_OLD_VERSION : must be changes so that the right version part is one less than +XYZ_NEW_VERSION. For example + +CLI_URETYPES_NEW_VERSION=1.0.[3].0 +CLI_URETYPES_OLD_VERSION=1.0.0.0-1.0.[2].0 + +The affected part is marked by the brackets. + +XYZ_POLICY_VERSION: change the version according to the version of the policy assembly from the +GAC. + +XYZ_POLICY_ASSEMBLY: remain unchanged. + +Commit the changes and rebuild the project. + +Step 5: Changing the versions in the unoil module + +The unoil module builds the cli_oootypes.dll which contains the office types (offapi). Change the contents +of unoil/climaker/version.txt similar to the versions.txt in this module. Then rebuild the module + + +The automatic test in cli_ure/qa/versioning should be extended. See the readme.txt in that directory +for more information. + + + + + + + +How does the version mechanism works +==================================== + +The assemblies which are build in this project have a strong name and hence a version. The version should +be increased whenever something was fixed or the code has changed in any way. For further information +have a look at +http://udk.openoffice.org/common/man/spec/assemblyversioning.html + +The versions of all assemblies are contained in cli_ure/version/version.txt. This is the place where +the versions are changed. This will happen under two circumstances. First, the versions are +adjusted AFTER an office was released. The version.txt must then contain the versions at the +time of the release. Second, when something was fixed. Then a version should be changed unless +this has already be done for the next release. Please look at the document mentioned further +above. + +If new published UNO types have been added since the last release (product update) then the +minor version of cli_uretypes.dll should be incremented. When building the version directory, a script +is run that recognizes this and writes a cliureversion.mk file in the bin directory. +cliureversion.mk contains all the entries of version.txt. The versions have been incremented +by the script. The script obtains the information of new types from unotype_statistics.txt +which is build in offapi. + +The contents of cliureversion.mk is used when building the assemblies in this project. It +is also delivered so that instset_native (or instsetoo_native) can use it when building +the installation sets. + + +The contents of version.txt +=========================== +The entries in version.txt are needed for building the assemblies and for building the +installation set (msi database). + +For every assembly exist four +entries. For example: + +CLI_URETYPES_NEW_VERSION=1.0.3.0 +CLI_URETYPES_OLD_VERSION=1.0.0.0-1.0.2.0 +CLI_URETYPES_POLICY_VERSION=3.0.0.0 +CLI_URETYPES_POLICY_ASSEMBLY=policy.1.0.cli_uretypes + +The meaning of these entries is the following: + +CLI_URETYPES_NEW_VERSION represents the current version of the assembly. + +CLI_URETYPES_OLD_VERSION represents a range of former versions (which were compatible). +It has to be placed in the +cli_uretypes.config XML file which is part of the policy assembly. This is done automatically. +The XYZ_OLD_VERSION and XYZ_NEW_VERSION values are used for the binding redirection of +the policy file. + +CLI_URETYPES_POLICY_VERSION represents the version of the policy file. + +CLI_URETYPES_POLICY_ASSEMBLY represents the name of the policy file. + +Please refer to the document at +http://udk.openoffice.org/common/man/spec/assemblyversioning.html +about how the versions have to look like. + +When the minor version is changed, which is the third number from the left, the +"old version" and the policy version must be changed as well. Using the former example, +an incremented version would look like this: +CLI_URETYPES_NEW_VERSION=1.0.4.0 +CLI_URETYPES_OLD_VERSION=1.0.0.0-1.0.3.0 +CLI_URETYPES_POLICY_VERSION=4.0.0.0 +CLI_URETYPES_POLICY_ASSEMBLY=policy.1.0.cli_uretypes + +If the major version changed we would have these values: +CLI_URETYPES_NEW_VERSION=2.0.0.0 +CLI_URETYPES_OLD_VERSION=2.0.0.0-2.0.0.0 +CLI_URETYPES_POLICY_VERSION=1.0.0.0 +CLI_URETYPES_POLICY_ASSEMBLY=policy.2.0.cli_uretypes + +Because a change of a major is only done if the code has changed incompatibly, we must not +redirect old client code to the new assembly. Actually we would not need a policy file here. +The name of the policy file has changed as well so as to refer to the new version. Since +the name is new and refers to the version 2 of cli_uretypes, we can start with the policy version +from 1. + +The next compatible change would require to change the version to these: +CLI_URETYPES_NEW_VERSION=2.0.1.0 +CLI_URETYPES_OLD_VERSION=2.0.0.0-2.0.1.0 +CLI_URETYPES_POLICY_VERSION=2.0.0.0 +CLI_URETYPES_POLICY_ASSEMBLY=policy.2.0.cli_uretypes + + +Automatic incrementation of the version +======================================= +Currently switched off! See cli_ure/version/makefile.mk +The automatic incrementation of the version this is done when new published types have been +introduce between two releases.In cli_ure/version/makefile.mk the script +cli_ure/source/scripts/increment_version.pl +is run which creates the cliureversion.mk with the new versions. This automatism only changes +the version parts which have the meaning of a compatible change. Which versions are to be +incremented is contained in cli_ure/version/incversions.txt. It contains, for example these entries: + +CLI_URETYPES_NEW_VERSION +CLI_URETYPES_OLD_VERSION +CLI_URETYPES_POLICY_VERSION + +The names are exactly the same as in version.txt. The script knows how to increase the version +of the different types: + +Entries ending on _NEW_VERSION: The third number from the left is incremented. +Entries ending on _OLD_VERSION: The third number from the left of the second version is incremented. +Entries ending on _POLICY_VERSION: The first number from the left is incremented. + +For example, the versions in version.txt are: +CLI_URETYPES_NEW_VERSION=1.0.4.0 +CLI_URETYPES_OLD_VERSION=1.0.0.0-1.0.3.0 +CLI_URETYPES_POLICY_VERSION=4.0.0.0 + +If new types have been added the script would create these entries in cliureversion.mk +CLI_URETYPES_NEW_VERSION=1.0.5.0 +CLI_URETYPES_OLD_VERSION=1.0.0.0-1.0.4.0 +CLI_URETYPES_POLICY_VERSION=5.0.0.0 + +As one can see from the incversions.txt, the versions of the cli_ure.dll and cli_cppuhelper.dll +are also changed. This is because these are dependent on cli_uretypes.dll. + + +Further notes on increasing the assembly versions +================================ +Changing a version for one assembly means changing +at least the XYZ_NEW_VERSION, XYZ_OLD_VERSION and XYZ_POLICY_VERSION. In case of an incompatible +change, that is one of the first two numbers of the version has been changed, the XYZ_POLICY_ASSEMBLY +must also be changed. + +When changing a version of an assembly then the versions of the assemblies which depend on it should +be changed as well. For example, when changing the version of cli_uretypes.dll, then the versions of +cli_ure.dll and cli_cppuhelper.dll should be changed as well. One can use idlasm.exe to see which +assemblies are referenced by an assembly. The information is contained in the assemblie's manifest. + +If one would not change the versions of the dependent dlls then one would risk that an assembly +has the same old version but references a different assembly. For example, say we have a +cli_uretypes.dll with version 1 and a cli_ure.dll with version 1. cli_ure.dll references version 1 of +cli_uretypes.dll. Now the version of cli_uretypes.dll changes to version 2 and its policy assembly is +adapted so that all code that uses version 1 now uses version 2. This would also allow cli_ure.dll +o run with the new cli_uretypes.dll. If now cli_ure.dll is build, then it would reference +cli_uretypes.dll version 2, because our build environment does not keep the older assembly. The old +cli_uretypes.dll version 1 was replaced by version 2. cli_ure.dll now references cli_uretypes.dll version 2 +but still has the old version. + + + +rebasing of assemblies +======================================================= +Neither assemblies nor policy assemblies may be rebased. This would +make the signature invalid. Therefore all assemblies must be contained +in postprocess/rebase/no_rebase.txt diff --git a/cli_ure/source/basetypes/assembly.cs b/cli_ure/source/basetypes/assembly.cs new file mode 100644 index 000000000..ac99fffd8 --- /dev/null +++ b/cli_ure/source/basetypes/assembly.cs @@ -0,0 +1,21 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +[assembly:System.Reflection.AssemblyDescription( "CLI-UNO: Language Binding specific types" )] +[assembly:System.Reflection.AssemblyCompany( "OpenOffice.org" )] +[assembly:System.Reflection.AssemblyVersion( "@CLI_BASETYPES_NEW_VERSION@" )] diff --git a/cli_ure/source/basetypes/cli_basetypes_config b/cli_ure/source/basetypes/cli_basetypes_config new file mode 100644 index 000000000..44ef60600 --- /dev/null +++ b/cli_ure/source/basetypes/cli_basetypes_config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/cli_ure/source/basetypes/uno/Any.cs b/cli_ure/source/basetypes/uno/Any.cs new file mode 100644 index 000000000..ea44d0f3b --- /dev/null +++ b/cli_ure/source/basetypes/uno/Any.cs @@ -0,0 +1,202 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; +using System.Text; + +namespace uno +{ + +/** This class can be used as a base class for UNO objects. + It implements the capability to be kept weakly + (unoidl.com.sun.star.uno.XWeak) and it implements + unoidl.com.sun.star.lang.XTypeProvider which is necessary for + using the object from StarBasic. +*/ +public struct Any +{ + private object _value; + private Type _type; + + public static Any VOID = new Any(typeof(void), null); + + private static void checkArgs(Type type, Object value) + { + //value can only be null if type == void + if (type == null + || (value == null + && type != typeof(void) + && type != typeof(object) + && type.IsInterface == false)) + throw new System.Exception( + "uno.Any: Constructor called with illegal arguments!"); + //If value is a polymorphic struct then type must be + //uno.Polymorphic + if (value != null) + { + TypeParametersAttribute t = (TypeParametersAttribute) Attribute.GetCustomAttribute( + value.GetType(), typeof(TypeParametersAttribute)); + if (t != null && !(type is PolymorphicType)) + throw new System.Exception( + "uno.Any: The value has a polymorphic type but the type argument is not " + + "uno.PolymorphicType. Please use the constructor Any(Type, object) and " + + "supply a uno.PolymorphicType as type argument!"); + } + } + + /** constructs an instance. + +

If the arguments are invalid then an exception is thrown.

+ @exception System.Exception + */ + public Any(Type type, object value) + { + checkArgs(type, value); + _type = type; + _value = value; + } + + /** sets the type and value. +

If the arguments ar invalid then an exception is thrown.

+ @exception System.Exception + */ + public void setValue(Type type, object value) + { + checkArgs(type, value); + _type = type; + _value = value; + } + + public Type Type + { + get + { + if (_type == null) + _type = typeof(void); + return _type; + } + } + + public Object Value + { + get + { + return _value; + } + } + + public Any(char value): this(typeof(char), value) + { + } + + public Any(bool value): this(typeof(bool), value) + { + } + + public Any(byte value): this(typeof(byte), value) + { + } + + public Any(short value): this(typeof(short), value) + { + } + + public Any(ushort value): this(typeof(ushort), value) + { + } + + public Any(int value): this(typeof(int), value) + { + } + + public Any(uint value): this(typeof(uint), value) + { + } + + public Any(long value): this(typeof(long), value) + { + } + + public Any(ulong value): this(typeof(ulong), value) + { + } + + public Any(float value): this(typeof(float), value) + { + } + + public Any(double value): this(typeof(double), value) + { + } + + public Any(Type value): this(typeof(Type), value) + { + } + + public Any(string value): this(typeof(string), value) + { + } + + public override string ToString() + { + StringBuilder msg = new StringBuilder("uno.Any { Type= "); + msg.Append(Type.ToString()); + msg.Append(", Value="); + msg.Append(Value.ToString()); + msg.Append("}"); + return msg.ToString(); + } + + public bool hasValue() + { + if (Type == null || Type == typeof(void)) + return false; + return true; + } + + public override bool Equals(object obj) + { + if (obj != null) + { + try + { + return Equals((Any) obj); + } + catch (InvalidCastException) + { + } + } + return false; + } + + public bool Equals(Any obj) + { + return Type.Equals(obj.Type) + && (Value == null ? + obj.Value == null : + Value.Equals(obj.Value)); + } + + public override int GetHashCode() + { + return Type.GetHashCode() ^ (Value != null ? Value.GetHashCode() : 0); + } +} + +} + diff --git a/cli_ure/source/basetypes/uno/BoundAttribute.cs b/cli_ure/source/basetypes/uno/BoundAttribute.cs new file mode 100644 index 000000000..d89925739 --- /dev/null +++ b/cli_ure/source/basetypes/uno/BoundAttribute.cs @@ -0,0 +1,37 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; + + +namespace uno +{ +/** is used to mark UNO interface attributes as "bound". + +

It corresponds to PropertyAttribute::BOUND. +

+ UNO interface attributes are mapped to CLI properties. + */ +[AttributeUsage(AttributeTargets.Property, Inherited=false)] +public sealed class BoundAttribute: System.Attribute +{ +} + +} + diff --git a/cli_ure/source/basetypes/uno/ExceptionAttribute.cs b/cli_ure/source/basetypes/uno/ExceptionAttribute.cs new file mode 100644 index 000000000..1c8847b44 --- /dev/null +++ b/cli_ure/source/basetypes/uno/ExceptionAttribute.cs @@ -0,0 +1,61 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; + + +namespace uno +{ +/** is used to mark a UNO method to throw exceptions. + +

A method can be an ordinary interface method, a get or set method from + an interface attribute, or the constructor methods of service creator + classes. If there are no exceptions specified for a method then this + attribute should not be applied. Because a + RuntimeException + can always be thrown it is not specified. Hence no + ExceptionAttribute + should be applied in that case.

+ */ +[AttributeUsage(AttributeTargets.Method, Inherited=false)] +public sealed class ExceptionAttribute: System.Attribute +{ + /** initializes an instance with the specified values. + + @param raises + array of types of Exceptions which are declared in UNOIDL. + It must not be null. + */ + public ExceptionAttribute(Type[] raises) + { + m_raises = raises; + } + + public Type[] Raises + { + get + { + return m_raises; + } + } + + private Type[] m_raises; +} + +} + diff --git a/cli_ure/source/basetypes/uno/OnewayAttribute.cs b/cli_ure/source/basetypes/uno/OnewayAttribute.cs new file mode 100644 index 000000000..ed8ad85ff --- /dev/null +++ b/cli_ure/source/basetypes/uno/OnewayAttribute.cs @@ -0,0 +1,34 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; + + +namespace uno +{ +/** is used to mark UNO interface methods as being one - way according to the + UNOIDL oneway attribute. +

+ */ +[AttributeUsage(AttributeTargets.Method, Inherited=false)] +public sealed class OnewayAttribute: System.Attribute +{ + +} +} + diff --git a/cli_ure/source/basetypes/uno/ParameterizedTypeAttribute.cs b/cli_ure/source/basetypes/uno/ParameterizedTypeAttribute.cs new file mode 100644 index 000000000..1ff37b280 --- /dev/null +++ b/cli_ure/source/basetypes/uno/ParameterizedTypeAttribute.cs @@ -0,0 +1,59 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; + + +namespace uno +{ +/** is used to mark a UNO entity to have a parameterized type. + +

Currently it is only applied to members of polymorphic structs. That is structs, + which have a type parameter list. +

+ + @see TypeParametersAttribute + */ +[AttributeUsage(AttributeTargets.Field, Inherited=false)] +public sealed class ParameterizedTypeAttribute: System.Attribute +{ + /** initializes an instance with the specified value. + + @param parameter + the name of parameter from the parameter list from + TypeParametersAttribute + It must not be null. + */ + public ParameterizedTypeAttribute(string parameter) + { + m_parameter = parameter; + } + + public string Type + { + get + { + return m_parameter; + } + } + + private string m_parameter; +} + +} + diff --git a/cli_ure/source/basetypes/uno/PolymorphicType.cs b/cli_ure/source/basetypes/uno/PolymorphicType.cs new file mode 100644 index 000000000..e996131fc --- /dev/null +++ b/cli_ure/source/basetypes/uno/PolymorphicType.cs @@ -0,0 +1,434 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; +using System.Collections; +using System.Reflection; +using System.Globalization; + +namespace uno { + + + +/** represents a polymorphic type. + + This class is used to carry type information for polymorphic struct types + and arrays of polymorphic struct types. These types would be easiest represented + with type templates, which are not available in .NET 1.1. Therefore + the System.Type cannot contain information about template parameters. To + retain this information we use PolymorphicType which directly inherits from + System.Type. The additional information about type parameters are passed + as simple string when creating an instance of PolymorphicType. Usually one + only needs a PolymorphicType when a polymporphic type is put into an + uno.Any. For example, let's assume there is a idl type PolyStruct: + + module test { + struct PolyStruct< T > + { + T member; + }; + }; + + Then one would use it in C# in this way: + + uno.Any myAny = new uno.Any( PolymorphicType.GetType( + typeof(PolyStruct), "unoidl.test.PolyStruct"), + new PolyStruct(true)); + + or if one has a sequence of polymorphic structs: + + uno.Any myAny = new uno.Any( PolymorphicType.GetType( + typeof(PolyStruct), "unoidl.test.PolyStruct[]"), + new PolyStruct[] {new PolyStruct(true)} ); + + + To get a new instance of PolymorphicType one uses the static method + PolymorphicType.GetType. The method ensures that there is only one instance + for each distinct name. For example, if GetType is called multiple times with + the name "unoidl.test.PolyStruct" then the same instance of + PolymorphicType is returned. This makes it possible to compare the instances + by reference, thas is using the operator "==". + + The polymorphic name, which is passed as second argument to PolymorphicType.GetType, + contains a list of type names. Only type names common + to all CLI languages can be used. That is, instead of using names, such as + char, int, float, the names System.Char, System.Int32 and + System.Single are to be used. Spaces are not allowed. + The name will always start with "unoidl", when the type was generated by climaker. + Here are a couple of possible strings: + + unoidl.test.PolyStruct + unoidl.test.PolyStruct + unoidl.test.PolyStruct[] + unoidl.test.PolyStruct> + unoidl.test.PolyStruct[]>[] + + In the future, when the CLI supports templates, we will probably adapt the cli-uno + bridge accordingly to use real template types. Then this class will become obsolete. + */ +public class PolymorphicType: Type +{ + private Type m_base; + private string m_type_name; + + private static Hashtable m_ht_types = Hashtable.Synchronized(new Hashtable(256)); + + /** provides a unique instance of this class. + + This function returns null if the specified type is no polymorphic struct. + + @param type + the type of the polymorphic struct. For example, created by + typeof(unoidl.com.sun.star.beans.Defaulted) + @param name + the full name of the struct (including the type list). + @return + null - the argument type is no valid polymorphic struct or
+ an instance of this class. + @exception System.ArgumentNullException + The argument was null. + */ + public static PolymorphicType GetType(Type type, string name) + { + if (name == null || type == null) + throw new ArgumentNullException( + "cli-uno: uno.PolymorphicType.GetType was called with a null argument"); + //check if the type is either an array of structs or a polymorphic struct. + if (type.IsArray) + { + Type elementType = type; + while ((elementType = elementType.GetElementType()).IsArray); + //unfortunately we cannot check if it is a real polymorphic struct here. + if ( ! elementType.IsClass) + return null; + + + } + else if (Attribute.GetCustomAttribute(type, typeof(uno.TypeParametersAttribute)) + == null) + { + return null; + } + + lock (m_ht_types.SyncRoot) + { + PolymorphicType t = (PolymorphicType) m_ht_types[name]; + if (t == null) + { + t = new PolymorphicType(type, name); + m_ht_types.Add(name, t); + } + return t; + } + } + + private PolymorphicType(Type type, string name) + { + m_type_name = name; + m_base = type; + } + + public string PolymorphicName + { + get + { + return m_type_name; + } + } + + public Type OriginalType + { + get + { + return m_base; + } + } + + + //implementations of abstract methods and properties from base class + public override string Name + { + get + { + return m_base.Name; + } + } + + public override Assembly Assembly + { + get + { + return m_base.Assembly; + } + } + + public override string AssemblyQualifiedName + { + get + { + return m_base.AssemblyQualifiedName; + } + } + + public override Type BaseType + { + get + { + return m_base.BaseType; + } + } + + public override string FullName + { + get + { + return m_base.FullName; + } + } + + public override Guid GUID + { + get + { + return m_base.GUID; + } + } + + public override Module Module + { + get + { + return m_base.Module; + } + } + + public override string Namespace + { + get + { + return m_base.Namespace; + } + } + + public override RuntimeTypeHandle TypeHandle + { + get + { + return m_base.TypeHandle; + } + } + + public override Type UnderlyingSystemType + { + get + { + return m_base.UnderlyingSystemType; + } + } + + public override Type DeclaringType + { + get + { + return m_base.DeclaringType; + } + } + + public override object[] GetCustomAttributes( + bool inherit) + { + return m_base.GetCustomAttributes(inherit); + } + + public override object[] GetCustomAttributes( + Type attributeType, + bool inherit) + { + return m_base.GetCustomAttributes(attributeType, inherit); + } + + public override bool IsDefined( + Type attributeType, + bool inherit) + { + return IsDefined(attributeType, inherit); + } + + protected override TypeAttributes GetAttributeFlagsImpl() + { + return m_base.Attributes; + } + + protected override ConstructorInfo GetConstructorImpl( + BindingFlags bindingAttr, + Binder binder, + CallingConventions callConvention, + Type[] types, + ParameterModifier[] modifiers) + { + return m_base.GetConstructor( + bindingAttr, binder, callConvention, types, modifiers); + } + + public override ConstructorInfo[] GetConstructors( + BindingFlags bindingAttr) + { + return m_base.GetConstructors(bindingAttr); + } + + public override Type GetElementType() + { + return m_base.GetElementType(); + } + + public override EventInfo GetEvent( + string name, + BindingFlags bindingAttr) + { + return m_base.GetEvent(name, bindingAttr); + } + + public override EventInfo[] GetEvents( + BindingFlags bindingAttr) + { + return m_base.GetEvents(bindingAttr); + } + + public override FieldInfo GetField( + string name, + BindingFlags bindingAttr) + { + return m_base.GetField(name, bindingAttr); + } + + public override FieldInfo[] GetFields( + BindingFlags bindingAttr) + { + return m_base.GetFields(bindingAttr); + } + + public override Type GetInterface( + string name, bool ignoreCase) + { + return m_base.GetInterface(name, ignoreCase); + } + + public override Type[] GetInterfaces() + { + return m_base.GetInterfaces(); + } + + public override MemberInfo[] GetMembers( + BindingFlags bindingAttr) + { + return m_base.GetMembers(bindingAttr); + } + + protected override MethodInfo GetMethodImpl( + string name, + BindingFlags bindingAttr, + Binder binder, + CallingConventions callConvention, + Type[] types, + ParameterModifier[] modifiers) + { + return m_base.GetMethod( + name, bindingAttr, binder, callConvention, types, modifiers); + } + + public override MethodInfo[] GetMethods( + BindingFlags bindingAttr) + { + return m_base.GetMethods(bindingAttr); + } + + public override Type GetNestedType( + string name, BindingFlags bindingAttr) + { + return m_base.GetNestedType(name, bindingAttr); + } + + public override Type[] GetNestedTypes( + BindingFlags bindingAttr) + { + return m_base.GetNestedTypes(bindingAttr); + } + + public override PropertyInfo[] GetProperties( + BindingFlags bindingAttr) + { + return m_base.GetProperties(bindingAttr); + } + + protected override PropertyInfo GetPropertyImpl( + string name, + BindingFlags bindingAttr, + Binder binder, + Type returnType, + Type[] types, + ParameterModifier[] modifiers) + { + return m_base.GetProperty( + name, bindingAttr, binder, returnType, types, modifiers); + } + + protected override bool HasElementTypeImpl() + { + return m_base.HasElementType; + } + + public override object InvokeMember( + string name, + BindingFlags invokeAttr, + Binder binder, + object target, + object[] args, + ParameterModifier[] modifiers, + CultureInfo culture, + string[] namedParameters) + { + return m_base.InvokeMember( + name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); + } + + protected override bool IsArrayImpl() + { + return m_base.IsArray; + } + + protected override bool IsByRefImpl() + { + return m_base.IsByRef; + } + + protected override bool IsCOMObjectImpl() + { + return m_base.IsCOMObject; + } + + protected override bool IsPointerImpl() + { + return m_base.IsPointer; + } + + protected override bool IsPrimitiveImpl() + { + return m_base.IsPrimitive; + } +} +} diff --git a/cli_ure/source/basetypes/uno/TypeArgumentsAttribute.cs b/cli_ure/source/basetypes/uno/TypeArgumentsAttribute.cs new file mode 100644 index 000000000..f2e8c8e39 --- /dev/null +++ b/cli_ure/source/basetypes/uno/TypeArgumentsAttribute.cs @@ -0,0 +1,75 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; + + +namespace uno +{ +/** is used to mark a parameterized UNO entity(i.e. struct) + to be an instantiation of a + template with the specified type arguments. + +

Currently only UNO structs can have type parameters.

+ +
+
+    [TypeParameters(new string[]{"T"})]
+    struct Foo {
+      [ParameterizedType("T")]
+      Object member;
+    }
+
+    public interface XFoo {
+       [return:TypeArguments(new string[]{typeof(char)})]
+       Foo func( [TypeArguments(new string[]{typeof(char)})] Foo f);
+    }
+    
+ + @see TypeParametersAttribute + @see ParameterizedTypeAttribute + */ +[AttributeUsage(AttributeTargets.ReturnValue + | AttributeTargets.Parameter + | AttributeTargets.Field, Inherited=false)] +public sealed class TypeArgumentsAttribute: System.Attribute +{ + /** initializes an instance with the specified value. + + @param parameters + arrayay of names representing the types. + It must not be null. + */ + public TypeArgumentsAttribute(Type[] arguments) + { + m_arguments = arguments; + } + + public Type[] Arguments + { + get + { + return m_arguments; + } + } + + private Type[] m_arguments; +} + +} + diff --git a/cli_ure/source/basetypes/uno/TypeParametersAttribute.cs b/cli_ure/source/basetypes/uno/TypeParametersAttribute.cs new file mode 100644 index 000000000..f6adebaa0 --- /dev/null +++ b/cli_ure/source/basetypes/uno/TypeParametersAttribute.cs @@ -0,0 +1,56 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +using System; + + +namespace uno +{ +/** is used to mark a UNO entity to have type parameters. + +

Currently it is only applied with polymorphic structs. That is structs, + which have a type parameter list. +

+ */ +[AttributeUsage(AttributeTargets.Class, Inherited=false)] +public sealed class TypeParametersAttribute: System.Attribute +{ + /** initializes an instance with the specified value. + + @param parameters + array of names representing the types. + It must not be null. + */ + public TypeParametersAttribute(string[] parameters) + { + m_parameters = parameters; + } + + public string[] Parameters + { + get + { + return m_parameters; + } + } + + private string[] m_parameters; +} + +} + diff --git a/cli_ure/source/climaker/climaker_app.cxx b/cli_ure/source/climaker/climaker_app.cxx new file mode 100644 index 000000000..7b9bc001a --- /dev/null +++ b/cli_ure/source/climaker/climaker_app.cxx @@ -0,0 +1,675 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +#include "sal/config.h" + +#include +#include +#include +#include + +#include "climaker_share.h" + +#include "sal/main.h" +#include "osl/process.h" +#include "osl/file.hxx" +#include "osl/thread.h" +#include "rtl/ustrbuf.hxx" +#include "cppuhelper/bootstrap.hxx" +#include "com/sun/star/lang/XComponent.hpp" +#include "com/sun/star/container/XHierarchicalNameAccess.hpp" +#include "com/sun/star/container/XSet.hpp" +#include "com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "unoidl/unoidl.hxx" + +using namespace ::std; +using namespace ::System::Reflection; + + +using namespace ::osl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace climaker +{ + + +static char const s_usingText [] = +"\n" +"using: climaker [registry-file-1 registry-file-2 ...]\n" +"\n" +"switches:\n" +" -O, --out output assembly file;\n" +" defaults to cli_unotypes.dll if more than one\n" +" registry-file is given, else .dll\n" +" -T, --types types to be generated (if none is given,\n" +" then all types of given registries are emitted\n" +" -X, --extra additional rdb to saturate referenced types in\n" +" given registry file(s); these types will not be\n" +" emitted into the output assembly file\n" +" -r, --reference reference metadata from assembly file\n" +" \n" +" -k, --keyfile keyfile needed for strong name\n" +" --assembly-version sets assembly version\n" +" --assembly-description sets assembly description text\n" +" --assembly-product sets assembly product name\n" +" --assembly-company sets assembly company\n" +" --assembly-copyright sets assembly copyright\n" +" --assembly-trademark sets assembly trademark\n" +" -v, --verbose verbose output to stdout\n" +" -h, --help this message\n" +"\n" +"example: climaker --out cli_mytypes.dll \\\n" +" --reference cli_uretypes.dll \\\n" +" --extra types.rdb \\\n" +" mytypes.rdb\n" +"\n"; + +struct OptionInfo +{ + char const * m_name; + sal_uInt32 m_name_length; + sal_Unicode m_short_option; + bool m_has_argument; +}; + +bool g_bVerbose = false; + + +static const OptionInfo s_option_infos [] = { + { RTL_CONSTASCII_STRINGPARAM("out"), 'O', true }, + { RTL_CONSTASCII_STRINGPARAM("types"), 'T', true }, + { RTL_CONSTASCII_STRINGPARAM("extra"), 'X', true }, + { RTL_CONSTASCII_STRINGPARAM("reference"), 'r', true }, + { RTL_CONSTASCII_STRINGPARAM("keyfile"), 'k', true }, + { RTL_CONSTASCII_STRINGPARAM("delaySign"), 'd', true }, + { RTL_CONSTASCII_STRINGPARAM("assembly-version"), '\0', true }, + { RTL_CONSTASCII_STRINGPARAM("assembly-description"), '\0', true }, + { RTL_CONSTASCII_STRINGPARAM("assembly-product"), '\0', true }, + { RTL_CONSTASCII_STRINGPARAM("assembly-company"), '\0', true }, + { RTL_CONSTASCII_STRINGPARAM("assembly-copyright"), '\0', true }, + { RTL_CONSTASCII_STRINGPARAM("assembly-trademark"), '\0', true }, + { RTL_CONSTASCII_STRINGPARAM("verbose"), 'v', false }, + { RTL_CONSTASCII_STRINGPARAM("help"), 'h', false } +}; + + +static OptionInfo const * get_option_info( + OUString const & opt, sal_Unicode copt = '\0' ) +{ + for ( sal_Int32 pos = 0; + pos < (sizeof (s_option_infos) / sizeof (OptionInfo)); + ++pos ) + { + OptionInfo const & option_info = s_option_infos[ pos ]; + + if (opt.getLength() > 0) + { + if (opt.equalsAsciiL( + option_info.m_name, option_info.m_name_length ) && + (copt == '\0' || copt == option_info.m_short_option)) + { + return &option_info; + } + } + else + { + OSL_ASSERT( copt != '\0' ); + if (copt == option_info.m_short_option) + { + return &option_info; + } + } + } + OSL_FAIL( + OUStringToOString( opt, osl_getThreadTextEncoding() ).getStr() ); + return 0; +} + + +static bool is_option( + OptionInfo const * option_info, sal_uInt32 * pIndex ) +{ + OSL_ASSERT( option_info != 0 ); + if (osl_getCommandArgCount() <= *pIndex) + return false; + + OUString arg; + osl_getCommandArg( *pIndex, &arg.pData ); + sal_Int32 len = arg.getLength(); + + if (len < 2 || arg[ 0 ] != '-') + return false; + + if (len == 2 && arg[ 1 ] == option_info->m_short_option) + { + ++(*pIndex); + return true; + } + if (arg[ 1 ] == '-' && rtl_ustr_ascii_compare( + arg.pData->buffer + 2, option_info->m_name ) == 0) + { + ++(*pIndex); + return true; + } + return false; +} + + +static inline bool read_option( + bool * flag, OptionInfo const * option_info, sal_uInt32 * pIndex ) +{ + bool ret = is_option( option_info, pIndex ); + if (ret) + *flag = true; + return ret; +} + + +static bool read_argument( + OUString * pValue, OptionInfo const * option_info, sal_uInt32 * pIndex ) +{ + if (is_option( option_info, pIndex )) + { + if (*pIndex < osl_getCommandArgCount()) + { + osl_getCommandArg( *pIndex, &pValue->pData ); + ++(*pIndex); + return true; + } + --(*pIndex); + } + return false; +} + + +static OUString const & path_get_working_dir() +{ + static OUString s_workingDir; + if (! s_workingDir.getLength()) + osl_getProcessWorkingDir( &s_workingDir.pData ); + return s_workingDir; +} + + +static OUString path_make_absolute_file_url( OUString const & path ) +{ + OUString file_url; + oslFileError rc = osl_getFileURLFromSystemPath( + path.pData, &file_url.pData ); + if (osl_File_E_None == rc) + { + OUString abs; + rc = osl_getAbsoluteFileURL( + path_get_working_dir().pData, file_url.pData, &abs.pData ); + if (osl_File_E_None == rc) + { + return abs; + } + else + { + throw RuntimeException( + "cannot make absolute: " + file_url ); + } + } + else + { + throw RuntimeException( + "cannot get file url from system path: " + path ); + } +} + +} + +using namespace ::climaker; + + +SAL_IMPLEMENT_MAIN() +{ + sal_uInt32 nCount = osl_getCommandArgCount(); + if (0 == nCount) + { + puts( s_usingText ); + return 0; + } + + int ret = 0; + css::uno::Reference< XComponentContext > xContext; + + try + { + OptionInfo const * info_help = + get_option_info( "help" ); + OptionInfo const * info_verbose = + get_option_info( "verbose" ); + OptionInfo const * info_out = + get_option_info( "out" ); + OptionInfo const * info_types = + get_option_info( "types" ); + OptionInfo const * info_reference = + get_option_info( "reference" ); + OptionInfo const * info_extra = + get_option_info( "extra" ); + OptionInfo const * info_keyfile = + get_option_info( "keyfile" ); + OptionInfo const * info_delaySign = + get_option_info( "delaySign" ); + OptionInfo const * info_version = + get_option_info( "assembly-version" ); + OptionInfo const * info_product = + get_option_info( "assembly-product" ); + OptionInfo const * info_description = + get_option_info( "assembly-description" ); + OptionInfo const * info_company = + get_option_info( "assembly-company" ); + OptionInfo const * info_copyright = + get_option_info( "assembly-copyright" ); + OptionInfo const * info_trademark = + get_option_info( "assembly-trademark" ); + + OUString output; + vector< OUString > mandatory_registries; + vector< OUString > extra_registries; + vector< OUString > extra_assemblies; + vector< OUString > explicit_types; + OUString version, product, description, company, copyright, trademark, + keyfile, delaySign; + + OUString cmd_arg; + for ( sal_uInt32 nPos = 0; nPos < nCount; ) + { + // options + if (is_option( info_help, &nPos )) + { + puts( s_usingText ); + return 0; + } + else if (read_argument( &cmd_arg, info_types, &nPos )) + { + sal_Int32 index = 0; + do + { + explicit_types.push_back( + cmd_arg.getToken( 0, ';', index ) ); + } + while (index >= 0); + } + else if (read_argument( &cmd_arg, info_extra, &nPos )) + { + extra_registries.push_back( + path_make_absolute_file_url( cmd_arg ) ); + } + else if (read_argument( &cmd_arg, info_reference, &nPos )) + { + extra_assemblies.push_back( + path_make_absolute_file_url( cmd_arg ) ); + } + else if (!read_option( &g_bVerbose, info_verbose, &nPos ) && + !read_argument( &output, info_out, &nPos ) && + !read_argument( &version, info_version, &nPos ) && + !read_argument( &description, info_description, &nPos ) && + !read_argument( &product, info_product, &nPos ) && + !read_argument( &company, info_company, &nPos ) && + !read_argument( ©right, info_copyright, &nPos ) && + !read_argument( &trademark, info_trademark, &nPos ) && + !read_argument( &keyfile, info_keyfile, &nPos ) && + !read_argument( &delaySign, info_delaySign, &nPos )) + { + osl_getCommandArg( nPos, &cmd_arg.pData ); + ++nPos; + cmd_arg = cmd_arg.trim(); + if (cmd_arg.getLength() > 0) + { + if (cmd_arg[ 0 ] == '-') // is option + { + OptionInfo const * option_info = 0; + if (cmd_arg.getLength() > 2 && + cmd_arg[ 1 ] == '-') + { + // long option + option_info = get_option_info( + cmd_arg.copy( 2 ), '\0' ); + } + else if (cmd_arg.getLength() == 2 && + cmd_arg[ 1 ] != '-') + { + // short option + option_info = get_option_info( + OUString(), cmd_arg[ 1 ] ); + } + if (option_info == 0) + { + throw RuntimeException("unknown option " + cmd_arg + "! Use climaker --help to print all options."); + } + else + { + OSL_FAIL( "unhandled valid option?!" ); + if (option_info->m_has_argument) + ++nPos; + } + } + else + { + mandatory_registries.push_back( + path_make_absolute_file_url( cmd_arg ) ); + } + } + } + } + + // bootstrap uno + xContext = ::cppu::defaultBootstrap_InitialComponentContext(); + css::uno::Reference< container::XHierarchicalNameAccess > xTDmgr( + xContext->getValueByName( + "/singletons/com.sun.star.reflection." + "theTypeDescriptionManager" ), + UNO_QUERY_THROW ); + + // The registries are consumed twice, once to insert them into the + // TypeDescriptionManager so that TypeEmitter can work on + // css.star.reflection.XTypeDescription representation, and once + // directly as unoidl::Provider instances to keep track which types are + // coming from the mandatory registries for the "no explicit types + // given" case (which iterates over the full TypeDescriptionManager + // now); a welcome clean-up would be to make TypeEmitter work on + // unoidl::Entity directly like the other codemakers: + css::uno::Reference< container::XSet > xSet( xTDmgr, UNO_QUERY_THROW ); + rtl::Reference unoidlMgr(new unoidl::Manager); + std::vector< rtl::Reference< unoidl::Provider > > unoidlMandatoryProvs; + for (auto& rRegistry : extra_registries) + { + xSet->insert(Any(rRegistry)); + unoidlMgr->addProvider(rRegistry); + } + for (auto& rRegistry : mandatory_registries) + { + xSet->insert(Any(rRegistry)); + rtl::Reference< unoidl::Provider > prov(unoidlMgr->addProvider(rRegistry)); + unoidlMandatoryProvs.push_back(prov); + } + + if (0 == output.getLength()) // no output file specified + { + // if only one rdb has been given, then take rdb name + if (1 == mandatory_registries.size()) + { + output = mandatory_registries[ 0 ]; + output = output.copy( output.lastIndexOf( '/' ) +1 ); + sal_Int32 dot = output.lastIndexOf( '.' ); + if (dot > 0) + output = output.copy( 0, dot ); + } + else + { + output = "cli_unotypes"; + } + } + output = path_make_absolute_file_url( output ); + sal_Int32 slash = output.lastIndexOf( '/' ); + OUString sys_output_dir; + if (FileBase::E_None != FileBase::getSystemPathFromFileURL( + output.copy( 0, slash ), sys_output_dir )) + { + throw RuntimeException( + "cannot get system path from file url " + + output.copy( 0, slash ) ); + } + OUString filename( output.copy( slash +1 ) ); + sal_Int32 dot = filename.lastIndexOf( '.' ); + OUString name( filename ); + if (dot < 0) // has no extension + filename += ".dll"; + else + name = name.copy( 0, dot ); + ::System::String ^ output_dir = ustring_to_String( sys_output_dir ); + ::System::String ^ output_file = ustring_to_String( filename ); + + //Get the key pair for making a strong name + StrongNameKeyPair^ kp = nullptr; + if (keyfile.getLength() > 0) + { + ::System::String ^ sKeyFile = ustring_to_String(keyfile); + try { + System::IO::FileStream^ fs = gcnew System::IO::FileStream( + sKeyFile, System::IO::FileMode::Open, + System::IO::FileAccess::Read, System::IO::FileShare::Read); + kp = gcnew StrongNameKeyPair(fs); + fs->Close(); + } + catch (System::IO::FileNotFoundException ^ ) + { + throw Exception("Could not find the keyfile. Verify the --keyfile argument!", 0); + } + } + else + { + if (g_bVerbose) + { + ::System::Console::Write( + "> no key file specified. Cannot create strong name!\n"); + } + } + // setup assembly info: xxx todo set more? e.g. avoid strong versioning + AssemblyName ^ assembly_name = gcnew AssemblyName(); + assembly_name->CodeBase = output_dir; + assembly_name->Name = gcnew ::System::String( + reinterpret_cast(name.getStr())); + if (kp != nullptr) + assembly_name->KeyPair= kp; + + if (version.getLength() != 0) + { + assembly_name->Version= + gcnew ::System::Version( ustring_to_String( version ) ); + } + + // app domain + ::System::AppDomain ^ current_appdomain = + ::System::AppDomain::CurrentDomain; + +// Weird warning from this statement +// warning C4538: 'cli::array ^' : const/volatile qualifiers on this type are not supported +// Could be a compiler bug, says http://stackoverflow.com/questions/12151060/seemingly-inappropriate-compilation-warning-with-c-cli +#pragma warning (push) +#pragma warning (disable: 4538) + // target assembly + Emit::AssemblyBuilder ^ assembly_builder = + current_appdomain->DefineDynamicAssembly( + assembly_name, Emit::AssemblyBuilderAccess::Save, output_dir ); +#pragma warning (pop) + + if (product.getLength() != 0) + { + cli::array< ::System::Type^>^ params = gcnew cli::array< ::System::Type^> (1); + cli::array< ::System::Object^>^args = gcnew cli::array< ::System::Object^>(1); + params[ 0 ] = ::System::String::typeid; + args[ 0 ] = ustring_to_String( product ); + assembly_builder->SetCustomAttribute( + gcnew Emit::CustomAttributeBuilder( + (AssemblyProductAttribute::typeid)->GetConstructor( + params ), args ) ); + } + if (description.getLength() != 0) + { + cli::array< ::System::Type^>^ params = gcnew cli::array< ::System::Type^>(1); + cli::array< ::System::Object^>^ args = gcnew cli::array< ::System::Object^>(1); + params[ 0 ] = ::System::String::typeid; + args[ 0 ] = ustring_to_String( description ); + assembly_builder->SetCustomAttribute( + gcnew Emit::CustomAttributeBuilder( + (AssemblyDescriptionAttribute::typeid)->GetConstructor( + params ), args ) ); + } + if (company.getLength() != 0) + { + cli::array< ::System::Type^>^ params = gcnew cli::array< ::System::Type^>(1); + cli::array< ::System::Object^>^ args = gcnew cli::array< ::System::Object^>(1); + params[ 0 ] = ::System::String::typeid; + args[ 0 ] = ustring_to_String( company ); + assembly_builder->SetCustomAttribute( + gcnew Emit::CustomAttributeBuilder( + (AssemblyCompanyAttribute::typeid)->GetConstructor( + params ), args ) ); + } + if (copyright.getLength() != 0) + { + cli::array< ::System::Type^>^ params = gcnew cli::array< ::System::Type^>(1); + cli::array< ::System::Object^>^ args = gcnew cli::array< ::System::Object^>(1); + params[ 0 ] = ::System::String::typeid; + args[ 0 ] = ustring_to_String( copyright ); + assembly_builder->SetCustomAttribute( + gcnew Emit::CustomAttributeBuilder( + (AssemblyCopyrightAttribute::typeid)->GetConstructor( + params ), args ) ); + } + if (trademark.getLength() != 0) + { + cli::array< ::System::Type^>^ params = gcnew cli::array< ::System::Type^>(1); + cli::array< ::System::Object^>^ args = gcnew cli::array< ::System::Object^>(1); + params[ 0 ] = ::System::String::typeid; + args[ 0 ] = ustring_to_String( trademark ); + assembly_builder->SetCustomAttribute( + gcnew Emit::CustomAttributeBuilder( + (AssemblyTrademarkAttribute::typeid)->GetConstructor( + params ), args ) ); + } + + // load extra assemblies + cli::array^ assemblies = + gcnew cli::array(extra_assemblies.size()); + for ( size_t pos = 0; pos < extra_assemblies.size(); ++pos ) + { + assemblies[ pos ] = Assembly::LoadFrom( + ustring_to_String( extra_assemblies[ pos ] ) ); + } + + // type emitter + TypeEmitter ^ type_emitter = gcnew TypeEmitter( + assembly_builder->DefineDynamicModule( output_file ), assemblies ); + // add handler resolving assembly's types + ::System::ResolveEventHandler ^ type_resolver = + gcnew ::System::ResolveEventHandler( + type_emitter, &TypeEmitter::type_resolve ); + current_appdomain->TypeResolve += type_resolver; + + // and emit types to it + if (explicit_types.empty()) + { + css::uno::Reference< reflection::XTypeDescriptionEnumeration > xTD_enum( + css::uno::Reference< reflection::XTypeDescriptionEnumerationAccess >( + xTDmgr, UNO_QUERY_THROW ) + ->createTypeDescriptionEnumeration( + OUString() /* all IDL modules */, + Sequence< TypeClass >() /* all classes of types */, + reflection::TypeDescriptionSearchDepth_INFINITE ) ); + while (xTD_enum->hasMoreElements()) + { + css::uno::Reference< reflection::XTypeDescription > td( + xTD_enum->nextTypeDescription()); + OUString name(td->getName()); + bool bEmit = std::any_of(unoidlMandatoryProvs.begin(), unoidlMandatoryProvs.end(), + [&name](rtl::Reference& rProv) { return rProv->findEntity(name).is(); }); + if (bEmit) { + type_emitter->get_type(td); + } + } + } + else + { + for ( size_t nPos = explicit_types.size(); nPos--; ) + { + type_emitter->get_type( + css::uno::Reference< reflection::XTypeDescription >( + xTDmgr->getByHierarchicalName( explicit_types[ nPos ] ), + UNO_QUERY_THROW ) ); + } + } + type_emitter->~TypeEmitter(); + + if (g_bVerbose) + { + ::System::Console::Write( + "> saving assembly {0}{1}{2}...", + output_dir, + gcnew ::System::String( + ::System::IO::Path::DirectorySeparatorChar, 1 ), + output_file ); + } + assembly_builder->Save( output_file ); + if (g_bVerbose) + { + ::System::Console::WriteLine( "ok." ); + } + current_appdomain->TypeResolve -= type_resolver; + } + catch (unoidl::NoSuchFileException & e) + { + std::cerr << "ERROR: No such file <" << e.getUri() << ">\n"; + return EXIT_FAILURE; + } + catch (unoidl::FileFormatException & e) + { + std::cerr + << "ERROR: Bad format of <" << e.getUri() << ">, \"" + << e.getDetail() << "\"\n"; + return EXIT_FAILURE; + } + catch (Exception & exc) + { + OString msg( + OUStringToOString( exc.Message, osl_getThreadTextEncoding() ) ); + fprintf( + stderr, "\n> error: %s\n> dying abnormally...\n", msg.getStr() ); + ret = 1; + } + catch (::System::Exception ^ exc) + { + OString msg( OUStringToOString( + String_to_ustring( exc->ToString() ), + osl_getThreadTextEncoding() ) ); + fprintf( + stderr, + "\n> error: .NET exception occurred: %s\n> dying abnormally...", + msg.getStr() ); + ret = 1; + } + + try + { + css::uno::Reference< lang::XComponent > xComp( xContext, UNO_QUERY ); + if (xComp.is()) + xComp->dispose(); + } + catch (Exception & exc) + { + OString msg( + OUStringToOString( exc.Message, osl_getThreadTextEncoding() ) ); + fprintf( + stderr, + "\n> error disposing component context: %s\n" + "> dying abnormally...\n", + msg.getStr() ); + ret = 1; + } + + return ret; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/climaker/climaker_emit.cxx b/cli_ure/source/climaker/climaker_emit.cxx new file mode 100644 index 000000000..e34a9b088 --- /dev/null +++ b/cli_ure/source/climaker/climaker_emit.cxx @@ -0,0 +1,2279 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +#include "climaker_share.h" + +#include "rtl/string.hxx" +#include "rtl/ustrbuf.hxx" +#include "com/sun/star/reflection/XIndirectTypeDescription.hpp" +#include "com/sun/star/reflection/XStructTypeDescription.hpp" +#include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp" +#include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp" +#include "com/sun/star/reflection/XInterfaceAttributeTypeDescription.hpp" +#include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp" +#include + +using namespace ::System::Reflection; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace climaker +{ +System::String^ mapUnoPolymorphicName(System::String^ unoName); + +static inline ::System::String ^ to_cts_name( + OUString const & uno_name ) +{ + return ustring_to_String("unoidl." + uno_name); +} + + +static inline ::System::Object ^ to_cli_constant( Any const & value ) +{ + switch (value.getValueTypeClass()) + { + case TypeClass_CHAR: + return ((::System::Char) *reinterpret_cast< sal_Unicode const * >( + value.getValue() )); + case TypeClass_BOOLEAN: + return ((::System::Boolean) + sal_False != *reinterpret_cast< sal_Bool const * >( + value.getValue() )); + case TypeClass_BYTE: + return ((::System::Byte) *reinterpret_cast< sal_Int8 const * >( + value.getValue() )); + case TypeClass_SHORT: + return ((::System::Int16) *reinterpret_cast< sal_Int16 const * >( + value.getValue() )); + case TypeClass_UNSIGNED_SHORT: + return ((::System::UInt16) *reinterpret_cast< sal_uInt16 const * >( + value.getValue() )); + case TypeClass_LONG: + return ((::System::Int32) *reinterpret_cast< sal_Int32 const * >( + value.getValue() )); + case TypeClass_UNSIGNED_LONG: + return ((::System::UInt32) *reinterpret_cast< sal_uInt32 const * >( + value.getValue() )); + case TypeClass_HYPER: + return ((::System::Int64) *reinterpret_cast< sal_Int64 const * >( + value.getValue() )); + case TypeClass_UNSIGNED_HYPER: + return ((::System::UInt64) *reinterpret_cast< sal_uInt64 const * >( + value.getValue() )); + case TypeClass_FLOAT: + return ((::System::Single) *reinterpret_cast< float const * >( + value.getValue() )); + case TypeClass_DOUBLE: + return ((::System::Double) *reinterpret_cast< double const * >( + value.getValue() )); + default: + throw RuntimeException( + "unexpected constant type " + + value.getValueType().getTypeName() ); + } +} + + +static inline void emit_ldarg( Emit::ILGenerator ^ code, ::System::Int32 index ) +{ + switch (index) + { + case 0: +#pragma warning (push) +#pragma warning (disable: 4538) // const/volatile qualifiers on this type are not supported + code->Emit( Emit::OpCodes::Ldarg_0 ); +#pragma warning (pop) + break; + case 1: + code->Emit( Emit::OpCodes::Ldarg_1 ); + break; + case 2: + code->Emit( Emit::OpCodes::Ldarg_2 ); + break; + case 3: + code->Emit( Emit::OpCodes::Ldarg_3 ); + break; + default: + if (index < 0x100) + code->Emit( Emit::OpCodes::Ldarg_S, (::System::Byte) index ); + else if (index < 0x8000) + code->Emit( Emit::OpCodes::Ldarg_S, (::System::Int16) index ); + else + code->Emit( Emit::OpCodes::Ldarg, index ); + break; + } +} + +void polymorphicStructNameToStructName(::System::String ^* sPolyName) +{ + if ((*sPolyName)->EndsWith(">") == false) + return; + + int index = (*sPolyName)->IndexOf('<'); + OSL_ASSERT(index != -1); + *sPolyName = (*sPolyName)->Substring(0, index); +} + + +System::String^ mapUnoTypeName(System::String ^ typeName) +{ + ::System::Text::StringBuilder^ buf= gcnew System::Text::StringBuilder(); + ::System::String ^ sUnoName = ::System::String::Copy(typeName); + //determine if the type is a sequence and its dimensions + int dims= 0; + if (typeName->StartsWith("["))//if (usUnoName[0] == '[') + { + int index= 1; + while (true) + { + if (typeName[index++] == ']')//if (usUnoName[index++] == ']') + dims++; + if (typeName[index++] != '[')//usUnoName[index++] != '[') + break; + } + sUnoName = sUnoName->Substring(index - 1);//usUnoName = usUnoName.copy(index - 1); + } + if (sUnoName->Equals(const_cast(Constants::sUnoBool))) + buf->Append(const_cast(Constants::sBoolean)); + else if (sUnoName->Equals(const_cast(Constants::sUnoChar))) + buf->Append(const_cast(Constants::sChar)); + else if (sUnoName->Equals(const_cast(Constants::sUnoByte))) + buf->Append(const_cast(Constants::sByte)); + else if (sUnoName->Equals(const_cast(Constants::sUnoShort))) + buf->Append(const_cast(Constants::sInt16)); + else if (sUnoName->Equals(const_cast(Constants::sUnoUShort))) + buf->Append(const_cast(Constants::sUInt16)); + else if (sUnoName->Equals(const_cast(Constants::sUnoLong))) + buf->Append(const_cast(Constants::sInt32)); + else if (sUnoName->Equals(const_cast(Constants::sUnoULong))) + buf->Append(const_cast(Constants::sUInt32)); + else if (sUnoName->Equals(const_cast(Constants::sUnoHyper))) + buf->Append(const_cast(Constants::sInt64)); + else if (sUnoName->Equals(const_cast(Constants::sUnoUHyper))) + buf->Append(const_cast(Constants::sUInt64)); + else if (sUnoName->Equals(const_cast(Constants::sUnoFloat))) + buf->Append(const_cast(Constants::sSingle)); + else if (sUnoName->Equals(const_cast(Constants::sUnoDouble))) + buf->Append(const_cast(Constants::sDouble)); + else if (sUnoName->Equals(const_cast(Constants::sUnoString))) + buf->Append(const_cast(Constants::sString)); + else if (sUnoName->Equals(const_cast(Constants::sUnoVoid))) + buf->Append(const_cast(Constants::sVoid)); + else if (sUnoName->Equals(const_cast(Constants::sUnoType))) + buf->Append(const_cast(Constants::sType)); + else if (sUnoName->Equals(const_cast(Constants::sUnoXInterface))) + buf->Append(const_cast(Constants::sObject)); + else if (sUnoName->Equals(const_cast(Constants::sUnoAny))) + { + buf->Append(const_cast(Constants::sAny)); + } + else + { + //put "unoidl." at the beginning + buf->Append(const_cast(Constants::sUnoidl)); + buf->Append(mapUnoPolymorphicName(sUnoName)); + } + // append [] + for (;dims--;) + buf->Append(const_cast(Constants::sBrackets)); + + return buf->ToString(); +} + + +/** For example, there is a uno type + com.sun.star.Foo. + The values in the type list + are uno types and are replaced by cli types, such as System.Char, + System.Int32, etc. + + Strings can be as complicated as this + test.MyStruct> + */ +System::String^ mapUnoPolymorphicName(System::String^ unoName) +{ + int index = unoName->IndexOf('<'); + if (index == -1) + return unoName; + + System::Text::StringBuilder ^ builder = + gcnew System::Text::StringBuilder(unoName->Substring(0, index +1 )); + + //Find the first occurrence of ',' + //If the parameter is a polymorphic struct then we need to ignore everything + //between the brackets because it can also contain commas + //get the type list within < and > + int endIndex = unoName->Length - 1; + index++; + int cur = index; + int countParams = 0; + while (cur <= endIndex) + { + System::Char c = unoName[cur]; + if (c == ',' || c == '>') + { + //insert a comma if needed + if (countParams != 0) + builder->Append(","); + countParams++; + System::String ^ sParam = unoName->Substring(index, cur - index); + //skip the comma + cur++; + //the index to the beginning of the next param + index = cur; + builder->Append(mapUnoTypeName(sParam)); + } + else if (c == '<') + { + cur++; + //continue until the matching '>' + int numNested = 0; + for (;;cur++) + { + System::Char curChar = unoName[cur]; + if (curChar == '<') + { + numNested ++; + } + else if (curChar == '>') + { + if (numNested > 0) + numNested--; + else + break; + } + } + } + cur++; + } + + builder->Append((System::Char) '>'); + return builder->ToString(); +} + + +Assembly ^ TypeEmitter::type_resolve( + ::System::Object ^, ::System::ResolveEventArgs ^ args ) +{ + ::System::String ^ cts_name = args->Name; + ::System::Type ^ ret_type = nullptr; + + iface_entry ^ entry = dynamic_cast< iface_entry ^ >(m_incomplete_ifaces[cts_name] ); + if (nullptr != entry) + ret_type = entry->m_type_builder; + + if (nullptr == ret_type) + { + sal_Int32 len = m_extra_assemblies->Length; + for ( sal_Int32 pos = 0; pos < len; ++pos ) + { + ret_type = m_extra_assemblies[ pos ]->GetType( + cts_name, false /* no exc */ ); + if (nullptr != ret_type) + { + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> resolving type {0} from {1}.", + cts_name, ret_type->Assembly->FullName ); + } + break; + } + } + } + if (nullptr != ret_type) + return ret_type->Assembly; + return nullptr; +} + + +::System::Type ^ TypeEmitter::get_type( + ::System::String ^ cts_name, bool throw_exc ) +{ + ::System::Type ^ ret_type = m_module_builder->GetType( cts_name, false ); + //We get the type from the ModuleBuilder even if the type is not complete + //but have been defined. + //if (ret_type == 0) + //{ + // iface_entry * entry = dynamic_cast< iface_entry * >( + // m_incomplete_ifaces->get_Item( cts_name ) ); + // if (0 != entry) + // ret_type = entry->m_type_builder; + //} + //try the cli_basetypes assembly + if (ret_type == nullptr) + { + ::System::Text::StringBuilder ^ builder = gcnew ::System::Text::StringBuilder(cts_name); + builder->Append(",cli_basetypes"); + ret_type = ::System::Type::GetType(builder->ToString()); + } + + if (ret_type == nullptr) + { + try + { + // may call on type_resolve() + return ::System::Type::GetType( cts_name, throw_exc ); + } + catch (::System::Exception^ exc) + { + //If the type is not found one may have forgotten to specify assemblies with + //additional types + ::System::Text::StringBuilder ^ sb = gcnew ::System::Text::StringBuilder(); + sb->Append(gcnew ::System::String("\nThe type ")); + sb->Append(cts_name); + sb->Append(gcnew ::System::String(" \n could not be found. Did you forget to " + "specify an additional assembly with the --reference option?\n")); + if (throw_exc) + throw gcnew ::System::Exception(sb->ToString(), exc); + } + } + else + { + return ret_type; + } +} + + +::System::Type ^ TypeEmitter::get_type_Exception() +{ + if (nullptr == m_type_Exception) + { + m_type_Exception = get_type( + "unoidl.com.sun.star.uno.Exception", false /* no exc */ ); + if (nullptr == m_type_Exception) + { + // define hardcoded type unoidl.com.sun.star.uno.Exception + Emit::TypeBuilder ^ type_builder = + m_module_builder->DefineType( + "unoidl.com.sun.star.uno.Exception", + (TypeAttributes) (TypeAttributes::Public | + TypeAttributes::BeforeFieldInit | + TypeAttributes::AnsiClass), + (::System::Exception::typeid) ); + Emit::FieldBuilder ^ field_Context = type_builder->DefineField( + "Context", (::System::Object::typeid), + FieldAttributes::Public ); + // default .ctor + type_builder->DefineDefaultConstructor( c_ctor_method_attr ); + // .ctor + array< ::System::Type^>^ param_types = + gcnew array< ::System::Type^>(2); + param_types[ 0 ] = ::System::String::typeid; + param_types[ 1 ] = ::System::Object::typeid; + Emit::ConstructorBuilder ^ ctor_builder = + type_builder->DefineConstructor( + c_ctor_method_attr, CallingConventions::Standard, + param_types ); + ctor_builder->DefineParameter( + 1, ParameterAttributes::In, "Message" ); + ctor_builder->DefineParameter( + 2, ParameterAttributes::In, "Context" ); + Emit::ILGenerator ^ code = ctor_builder->GetILGenerator(); + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( Emit::OpCodes::Ldarg_1 ); + param_types = gcnew array< ::System::Type^>(1); + param_types[ 0 ] = ::System::String::typeid; + code->Emit( + Emit::OpCodes::Call, + (::System::Exception::typeid) + ->GetConstructor( param_types ) ); + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( Emit::OpCodes::Ldarg_2 ); + code->Emit( Emit::OpCodes::Stfld, field_Context ); + code->Emit( Emit::OpCodes::Ret ); + + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting exception type " + "unoidl.com.sun.star.uno.Exception" ); + } + m_type_Exception = type_builder->CreateType(); + } + } + return m_type_Exception; +} + + +::System::Type ^ TypeEmitter::get_type_RuntimeException() +{ + if (nullptr == m_type_RuntimeException) + { + m_type_RuntimeException = get_type( + "unoidl.com.sun.star.uno.RuntimeException", false /* no exc */ ); + if (nullptr == m_type_RuntimeException) + { + // define hardcoded type unoidl.com.sun.star.uno.RuntimeException + ::System::Type ^ type_Exception = get_type_Exception(); + Emit::TypeBuilder ^ type_builder = + m_module_builder->DefineType( + "unoidl.com.sun.star.uno.RuntimeException", + (TypeAttributes) (TypeAttributes::Public | + TypeAttributes::BeforeFieldInit | + TypeAttributes::AnsiClass), + type_Exception ); + // default .ctor + type_builder->DefineDefaultConstructor( c_ctor_method_attr ); + // .ctor + array< ::System::Type^>^ param_types = + gcnew array< ::System::Type^>(2); + param_types[ 0 ] = ::System::String::typeid; + param_types[ 1 ] = ::System::Object::typeid; + Emit::ConstructorBuilder ^ ctor_builder = + type_builder->DefineConstructor( + c_ctor_method_attr, CallingConventions::Standard, + param_types ); + ctor_builder->DefineParameter( + 1, ParameterAttributes::In, "Message" ); + ctor_builder->DefineParameter( + 2, ParameterAttributes::In, "Context" ); + Emit::ILGenerator ^ code = ctor_builder->GetILGenerator(); + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( Emit::OpCodes::Ldarg_1 ); + code->Emit( Emit::OpCodes::Ldarg_2 ); + code->Emit( + Emit::OpCodes::Call, + type_Exception->GetConstructor( param_types ) ); + code->Emit( Emit::OpCodes::Ret ); + + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting exception type " + "unoidl.com.sun.star.uno.RuntimeException" ); + } + m_type_RuntimeException = type_builder->CreateType(); + } + } + return m_type_RuntimeException; +} + + +::System::Type ^ TypeEmitter::get_type( + Reference< reflection::XConstantTypeDescription > const & xType ) +{ + ::System::String ^ cts_name = to_cts_name( xType->getName() ); + ::System::Type ^ ret_type = get_type( cts_name, false /* no exc */ ); + if (nullptr == ret_type) + { + Reference< reflection::XConstantTypeDescription > xConstant( + xType, UNO_SET_THROW ); + ::System::Object ^ constant = + to_cli_constant( xConstant->getConstantValue() ); + Emit::TypeBuilder ^ type_builder = + m_module_builder->DefineType( + cts_name, + (TypeAttributes) (TypeAttributes::Public | + TypeAttributes::Sealed | + TypeAttributes::BeforeFieldInit | + TypeAttributes::AnsiClass) ); + + Emit::FieldBuilder ^ field_builder = type_builder->DefineField( + cts_name->Substring( cts_name->LastIndexOf( '.' ) +1 ), + constant->GetType(), + (FieldAttributes) (FieldAttributes::Public | + FieldAttributes::Static | + FieldAttributes::Literal) ); + field_builder->SetConstant( constant ); + + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting constant type {0}", cts_name ); + } + ret_type = type_builder->CreateType(); + } + return ret_type; +} + + +::System::Type ^ TypeEmitter::get_type( + Reference< reflection::XConstantsTypeDescription > const & xType ) +{ + ::System::String ^ cts_name = to_cts_name( xType->getName() ); + ::System::Type ^ ret_type = get_type( cts_name, false /* no exc */ ); + if (nullptr == ret_type) + { + Emit::TypeBuilder ^ type_builder = + m_module_builder->DefineType( + cts_name, + (TypeAttributes) (TypeAttributes::Public | + TypeAttributes::Sealed | + TypeAttributes::BeforeFieldInit | + TypeAttributes::AnsiClass) ); + + Sequence< Reference< + reflection::XConstantTypeDescription > > seq_constants( + xType->getConstants() ); + Reference< reflection::XConstantTypeDescription > const * constants = + seq_constants.getConstArray(); + sal_Int32 constants_length = seq_constants.getLength(); + for ( sal_Int32 constants_pos = 0; + constants_pos < constants_length; ++constants_pos ) + { + Reference< + reflection::XConstantTypeDescription > const & xConstant = + constants[ constants_pos ]; + ::System::Object ^ constant = + to_cli_constant( xConstant->getConstantValue() ); + ::System::String ^ uno_name = + ustring_to_String( xConstant->getName() ); + Emit::FieldBuilder ^ field_builder = type_builder->DefineField( + uno_name->Substring( uno_name->LastIndexOf( '.' ) +1 ), + constant->GetType(), + (FieldAttributes) (FieldAttributes::Public | + FieldAttributes::Static | + FieldAttributes::Literal) ); + field_builder->SetConstant( constant ); + } + + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting constants group type {0}", cts_name ); + } + ret_type = type_builder->CreateType(); + } + return ret_type; +} + + +::System::Type ^ TypeEmitter::get_type( + Reference< reflection::XEnumTypeDescription > const & xType ) +{ + ::System::String ^ cts_name = to_cts_name( xType->getName() ); + ::System::Type ^ ret_type = get_type( cts_name, false /* no exc */ ); + if (nullptr == ret_type) + { + // workaround enum builder bug + Emit::TypeBuilder ^ enum_builder = + m_module_builder->DefineType( + cts_name, + (TypeAttributes) (TypeAttributes::Public | + TypeAttributes::Sealed), + ::System::Enum::typeid ); + enum_builder->DefineField( + "value__", ::System::Int32::typeid, + (FieldAttributes) (FieldAttributes::Private | + FieldAttributes::SpecialName | + FieldAttributes::RTSpecialName) ); + Sequence< OUString > seq_enum_names( xType->getEnumNames() ); + Sequence< sal_Int32 > seq_enum_values( xType->getEnumValues() ); + sal_Int32 enum_length = seq_enum_names.getLength(); + OSL_ASSERT( enum_length == seq_enum_values.getLength() ); + OUString const * enum_names = seq_enum_names.getConstArray(); + sal_Int32 const * enum_values = seq_enum_values.getConstArray(); + for ( sal_Int32 enum_pos = 0; enum_pos < enum_length; ++enum_pos ) + { +// enum_builder->DefineLiteral( +// ustring_to_String( enum_names[ enum_pos ] ), +// __box ((::System::Int32) enum_values[ enum_pos ]) ); + Emit::FieldBuilder ^ field_builder = + enum_builder->DefineField( + ustring_to_String( enum_names[ enum_pos ] ), + enum_builder, + (FieldAttributes) (FieldAttributes::Public | + FieldAttributes::Static | + FieldAttributes::Literal) ); + field_builder->SetConstant( + ((::System::Int32) enum_values[ enum_pos ]) ); + } + + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting enum type {0}", cts_name ); + } + ret_type = enum_builder->CreateType(); + } + return ret_type; +} + + +::System::Type ^ TypeEmitter::get_type( + Reference< reflection::XCompoundTypeDescription > const & xType ) +{ + OUString uno_name( xType->getName() ); + if (TypeClass_EXCEPTION == xType->getTypeClass()) + { + if ( uno_name == "com.sun.star.uno.Exception" ) + { + return get_type_Exception(); + } + if ( uno_name == "com.sun.star.uno.RuntimeException" ) + { + return get_type_RuntimeException(); + } + } + ::System::String ^ cts_name = to_cts_name( uno_name ); + // if the struct is an instantiated polymorphic struct then we create the simple struct name + // For example: + // void func ([in] PolyStruct arg); + //PolyStruct will be converted to PolyStruct + polymorphicStructNameToStructName( & cts_name); + + ::System::Type ^ ret_type = get_type( cts_name, false /* no exc */ ); + if (nullptr == ret_type) + { + Reference< reflection::XCompoundTypeDescription > xBaseType( + xType->getBaseType(), UNO_QUERY ); + ::System::Type ^ base_type = (xBaseType.is() + ? get_type( xBaseType ) + : ::System::Object::typeid); + Emit::TypeBuilder ^ type_builder = + m_module_builder->DefineType( + cts_name, + (TypeAttributes) (TypeAttributes::Public | + TypeAttributes::BeforeFieldInit | + TypeAttributes::AnsiClass), + base_type ); + + + // insert to be completed + struct_entry ^ entry = gcnew struct_entry(); + xType->acquire(); + entry->m_xType = xType.get(); + entry->m_type_builder = type_builder; + entry->m_base_type = base_type; + m_incomplete_structs->Add( cts_name, entry ); + + // type is incomplete + ret_type = type_builder; + } + + //In case of an instantiated polymorphic struct we want to return a + //uno.PolymorphicType (inherits Type) rather than Type. This is needed for constructing + //the service code. We can only do that if the struct is completed. + if (m_generated_structs[cts_name]) + { + Reference< reflection::XStructTypeDescription> xStructTypeDesc( + xType, UNO_QUERY); + + if (xStructTypeDesc.is()) + { + Sequence< Reference< reflection::XTypeDescription > > seqTypeArgs = xStructTypeDesc->getTypeArguments(); + sal_Int32 numTypes = seqTypeArgs.getLength(); + if (numTypes > 0) + { + //it is an instantiated polymorphic struct + ::System::String ^ sCliName = mapUnoTypeName(ustring_to_String(xType->getName())); + ret_type = ::uno::PolymorphicType::GetType(ret_type, sCliName); + } + } + } + return ret_type; +} + + +::System::Type ^ TypeEmitter::get_type( + Reference< reflection::XInterfaceTypeDescription2 > const & xType ) +{ + OUString uno_name( xType->getName() ); + if ( uno_name == "com.sun.star.uno.XInterface" ) + { + return ::System::Object::typeid; + } + + ::System::String ^ cts_name = to_cts_name( xType->getName() ); + ::System::Type ^ ret_type = get_type( cts_name, false /* no exc */ ); + if (nullptr == ret_type) + { + Emit::TypeBuilder ^ type_builder; + + TypeAttributes attr = (TypeAttributes) (TypeAttributes::Public | + TypeAttributes::Interface | + TypeAttributes::Abstract | + TypeAttributes::AnsiClass); + + std::vector > vecBaseTypes; + Sequence > seqBaseTypes = + xType->getBaseTypes(); + if (seqBaseTypes.getLength() > 0) + { + for (int i = 0; i < seqBaseTypes.getLength(); i++) + { + Reference xIfaceTd = + resolveInterfaceTypedef(seqBaseTypes[i]); + + if ( xIfaceTd->getName() != "com.sun.star.uno.XInterface" ) + { + vecBaseTypes.push_back(xIfaceTd); + } + } + + array< ::System::Type^>^ base_interfaces = + gcnew array< ::System::Type^>( vecBaseTypes.size() ); + + int index = 0; + for (auto const & vecBaseType : vecBaseTypes) + { + base_interfaces[ index ] = get_type( vecBaseType ); + ++index; + } + type_builder = m_module_builder->DefineType( + cts_name, attr, nullptr, base_interfaces ); + } + else + { + ::System::Console::WriteLine( + "warning: IDL interface {0} is not derived from " + "com.sun.star.uno.XInterface!", + ustring_to_String( uno_name ) ); + + type_builder = m_module_builder->DefineType( cts_name, attr ); + } + + // insert to be completed + iface_entry ^ entry = gcnew iface_entry(); + xType->acquire(); + entry->m_xType = xType.get(); + entry->m_type_builder = type_builder; + m_incomplete_ifaces->Add( cts_name, entry ); + + // type is incomplete + ret_type = type_builder; + } + return ret_type; +} + + +::System::Type ^ TypeEmitter::get_type( + Reference< reflection::XServiceTypeDescription2 > const & xType ) +{ + if (xType->isSingleInterfaceBased() == sal_False) + return nullptr; + + System::String ^ cts_name = to_cts_name( xType->getName() ); + System::Type ^ ret_type = get_type( cts_name, false /* no exc */ ); + if (ret_type != nullptr) + return ret_type; + + TypeAttributes attr = (TypeAttributes) (TypeAttributes::Public | + TypeAttributes::Sealed | + TypeAttributes::BeforeFieldInit | + TypeAttributes::AnsiClass); + + Emit::TypeBuilder ^ type_builder = m_module_builder->DefineType( + cts_name, attr); + + // insert to be completed + service_entry ^ entry = gcnew service_entry(); + xType->acquire(); + entry->m_xType = xType.get(); + entry->m_type_builder = type_builder; + m_incomplete_services->Add(cts_name,entry ); + + return type_builder; +} + +::System::Type ^ TypeEmitter::get_type( + Reference const & xType ) +{ + if (xType->isInterfaceBased() == sal_False) + return nullptr; + + ::System::String^ cts_name = to_cts_name( xType->getName() ); + ::System::Type ^ ret_type = get_type( cts_name, false /* no exc */ ); + if (ret_type != nullptr) + return ret_type; + + TypeAttributes attr = static_cast( + TypeAttributes::Public | + TypeAttributes::Sealed | + TypeAttributes::BeforeFieldInit | + TypeAttributes::AnsiClass); + + Emit::TypeBuilder ^ type_builder = m_module_builder->DefineType( + cts_name, attr); + + // insert to be completed + singleton_entry ^ entry = gcnew singleton_entry(); + xType->acquire(); + entry->m_xType = xType.get(); + entry->m_type_builder = type_builder; + m_incomplete_singletons->Add(cts_name,entry ); + + return type_builder; + +} + + +::System::Type ^ TypeEmitter::complete_iface_type( iface_entry ^ entry ) +{ + Emit::TypeBuilder ^ type_builder = entry->m_type_builder; + reflection::XInterfaceTypeDescription2 * xType = entry->m_xType; + + Sequence > seqBaseTypes( xType->getBaseTypes() ); + if (seqBaseTypes.getLength() > 0) + { + for (int i = 0; i < seqBaseTypes.getLength(); i++) + { + //make sure we get the interface rather than a typedef + Reference aBaseType = + resolveInterfaceTypedef( seqBaseTypes[i]); + + if ( aBaseType->getName() != "com.sun.star.uno.XInterface" ) + { + ::System::String ^ basetype_name = to_cts_name( aBaseType->getName() ); + iface_entry ^ base_entry = dynamic_cast< iface_entry ^ >( + m_incomplete_ifaces[basetype_name] ); + if (nullptr != base_entry) + { + // complete uncompleted base type first + complete_iface_type( base_entry ); + } + } + } + } + + Sequence< + Reference< reflection::XInterfaceMemberTypeDescription > > seq_members( + xType->getMembers() ); + Reference< reflection::XInterfaceMemberTypeDescription > const * members = + seq_members.getConstArray(); + sal_Int32 members_length = seq_members.getLength(); + for ( sal_Int32 members_pos = 0; + members_pos < members_length; ++members_pos ) + { + Reference< + reflection::XInterfaceMemberTypeDescription > const & xMember = + members[ members_pos ]; + Sequence< Reference< reflection::XTypeDescription > > seq_exceptions; + Emit::MethodBuilder ^ method_builder; + + MethodAttributes c_method_attr = (MethodAttributes) + (MethodAttributes::Public | + MethodAttributes::Abstract | + MethodAttributes::Virtual | + MethodAttributes::NewSlot | + MethodAttributes::HideBySig); + + if (TypeClass_INTERFACE_METHOD == xMember->getTypeClass()) + { + Reference< reflection::XInterfaceMethodTypeDescription > xMethod( + xMember, UNO_QUERY_THROW ); + + Sequence< + Reference< reflection::XMethodParameter > > seq_parameters( + xMethod->getParameters() ); + sal_Int32 params_length = seq_parameters.getLength(); + array< ::System::Type^>^ param_types = + gcnew array< ::System::Type^>( params_length ); + Reference< reflection::XMethodParameter > const * parameters = + seq_parameters.getConstArray(); + // first determine all types + //Make the first param type as return type + sal_Int32 params_pos = 0; + for ( ; params_pos < params_length; ++params_pos ) + { + Reference< reflection::XMethodParameter > const & xParam = + parameters[ params_pos ]; + ::System::Type ^ param_type = get_type( xParam->getType() ); + ::System::String ^ param_type_name = param_type->FullName; + if (xParam->isOut()) + { + param_type = get_type( + ::System::String::Concat( + param_type_name, "&" ), true ); + } + param_types[ xParam->getPosition() ] = param_type; + } + + + // create method +// if (tb) +// method_builder = type_builder->DefineMethod( +// ustring_to_String( xMethod->getMemberName() ), +// c_method_attr, tb, +// param_types ); +// else + method_builder = type_builder->DefineMethod( + ustring_to_String( xMethod->getMemberName() ), + c_method_attr, get_type( xMethod->getReturnType() ), + param_types ); + // then define parameter infos + params_pos = 0; + for ( ; params_pos < params_length; ++params_pos ) + { + Reference< reflection::XMethodParameter > const & xParam = + parameters[ params_pos ]; + long param_flags = 0; + if (xParam->isIn()) + param_flags |= (long)ParameterAttributes::In; + if (xParam->isOut()) + param_flags |= (long)ParameterAttributes::Out; + OSL_ASSERT( 0 != param_flags ); + method_builder->DefineParameter( + xParam->getPosition() +1 /* starts with 1 */, + (ParameterAttributes) param_flags, + ustring_to_String( xParam->getName() ) ); + } + //Apply attribute TypeParametersAttribute to return value if it + //is a parameterized Type. Currently only structs can have parameters. + Reference xReturnStruct( + xMethod->getReturnType(), UNO_QUERY); + + if (xReturnStruct.is()) + { + Sequence > seq_type_args = + xReturnStruct->getTypeArguments(); + if (seq_type_args.getLength() != 0) + { + //get th ctor of the attribute + array< ::System::Type^>^ arCtor = {::System::Type::GetType("System.Type[]")}; + //Get the arguments for the attribute's ctor + Reference const * arXTypeArgs = + seq_type_args.getConstArray(); + int numTypes = seq_type_args.getLength(); + array< ::System::Type^>^ arCtsTypes = gcnew array< ::System::Type^>(numTypes); + for (int i = 0; i < numTypes; i++) + arCtsTypes[i] = get_type(arXTypeArgs[i]); + array< ::System::Object^>^ arArgs = {arCtsTypes}; + + Emit::CustomAttributeBuilder ^ attrBuilder = + gcnew Emit::CustomAttributeBuilder( + ::uno::TypeArgumentsAttribute::typeid + ->GetConstructor( arCtor), + arArgs); + + method_builder->SetCustomAttribute(attrBuilder); + } + } + + //define UNO exception attribute (exceptions)-------------------------------------- + Emit::CustomAttributeBuilder^ attrBuilder = + get_iface_method_exception_attribute(xMethod); + if (attrBuilder != nullptr) + method_builder->SetCustomAttribute(attrBuilder); + + // oneway attribute + if (xMethod->isOneway()) + { + array< ::System::Type^>^ arCtorOneway = gcnew array< ::System::Type^>(0); + array< ::System::Object^>^ arArgs = gcnew array< ::System::Object^>(0); + Emit::CustomAttributeBuilder ^ attrBuilder = + gcnew Emit::CustomAttributeBuilder( + ::uno::OnewayAttribute::typeid->GetConstructor( arCtorOneway), + arArgs); + method_builder->SetCustomAttribute(attrBuilder); + } + } + else // attribute + { + OSL_ASSERT( + TypeClass_INTERFACE_ATTRIBUTE == xMember->getTypeClass() ); + Reference< + reflection::XInterfaceAttributeTypeDescription2 > xAttribute( + xMember, UNO_QUERY_THROW ); + + MethodAttributes c_property_method_attr = (MethodAttributes) + (c_method_attr | MethodAttributes::SpecialName); + + ::System::Type ^ attribute_type = get_type( xAttribute->getType() ); + array< ::System::Type^>^ parameters = + gcnew array< ::System::Type^> ( 0 ); + + Emit::PropertyBuilder ^ property_builder = + type_builder->DefineProperty( + ustring_to_String( xAttribute->getMemberName() ), + PropertyAttributes::None, + attribute_type, parameters ); + + //set BoundAttribute, if necessary + if (xAttribute->isBound()) + { + ConstructorInfo ^ ctorBoundAttr = + ::uno::BoundAttribute::typeid->GetConstructor( + gcnew array(0)); + Emit::CustomAttributeBuilder ^ attrBuilderBound = + gcnew Emit::CustomAttributeBuilder( + ctorBoundAttr, gcnew array< ::System::Object^>(0)); + property_builder->SetCustomAttribute(attrBuilderBound); + } + + // getter + Emit::MethodBuilder ^ method_builder = + type_builder->DefineMethod( + ustring_to_String( "get_" + + xAttribute->getMemberName() ), + c_property_method_attr, attribute_type, parameters ); + + //define UNO exception attribute (exceptions)-------------------------------------- + Emit::CustomAttributeBuilder^ attrBuilder = + get_exception_attribute(xAttribute->getGetExceptions()); + if (attrBuilder != nullptr) + method_builder->SetCustomAttribute(attrBuilder); + + property_builder->SetGetMethod( method_builder ); + + if (! xAttribute->isReadOnly()) + { + // setter + parameters = gcnew array< ::System::Type^> ( 1 ); + parameters[ 0 ] = attribute_type; + method_builder = + type_builder->DefineMethod( + ustring_to_String( "set_" + + xAttribute->getMemberName() ), + c_property_method_attr, nullptr, parameters ); + // define parameter info + method_builder->DefineParameter( + 1 /* starts with 1 */, ParameterAttributes::In, "value" ); + //define UNO exception attribute (exceptions)-------------------------------------- + Emit::CustomAttributeBuilder^ attrBuilder = + get_exception_attribute(xAttribute->getSetExceptions()); + if (attrBuilder != nullptr) + method_builder->SetCustomAttribute(attrBuilder); + + property_builder->SetSetMethod( method_builder ); + } + } + } + + // remove from incomplete types map + ::System::String ^ cts_name = type_builder->FullName; + m_incomplete_ifaces->Remove( cts_name ); + xType->release(); + + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting interface type {0}", cts_name ); + } + return type_builder->CreateType(); +} + +::System::Type ^ TypeEmitter::complete_struct_type( struct_entry ^ entry ) +{ + OSL_ASSERT(entry); + ::System::String ^ cts_name = entry->m_type_builder->FullName; + + //Polymorphic struct, define uno.TypeParametersAttribute + //A polymorphic struct cannot have a basetype. + //When we create the template of the struct then we have no exact types + //and the name does not contain a parameter list + Sequence< OUString > seq_type_parameters; + Reference< reflection::XStructTypeDescription> xStructTypeDesc( + entry->m_xType, UNO_QUERY); + if (xStructTypeDesc.is()) + { + seq_type_parameters = xStructTypeDesc->getTypeParameters(); + int numTypes = 0; + if ((numTypes = seq_type_parameters.getLength()) > 0) + { + array< ::System::Object^>^ aArg = gcnew array< ::System::Object^>(numTypes); + for (int i = 0; i < numTypes; i++) + aArg[i] = ustring_to_String(seq_type_parameters.getConstArray()[i]); + array< ::System::Object^>^ args = {aArg}; + + array< ::System::Type^>^ arTypesCtor = + {::System::Type::GetType("System.String[]")}; + Emit::CustomAttributeBuilder ^ attrBuilder = + gcnew Emit::CustomAttributeBuilder( + ::uno::TypeParametersAttribute::typeid->GetConstructor(arTypesCtor), + args); + entry->m_type_builder->SetCustomAttribute(attrBuilder); + } + } + + // optional: lookup base type whether generated entry of this session + struct_entry ^ base_type_entry = nullptr; + if (nullptr != entry->m_base_type) + { + //ToDo maybe get from incomplete structs + base_type_entry = + dynamic_cast< struct_entry ^ >( + m_generated_structs[ + entry->m_base_type->FullName ] ); + } + + // members + Sequence< Reference< reflection::XTypeDescription > > seq_members( + entry->m_xType->getMemberTypes() ); + Sequence< OUString > seq_member_names( entry->m_xType->getMemberNames() ); + sal_Int32 members_length = seq_members.getLength(); + OSL_ASSERT( seq_member_names.getLength() == members_length ); + //check if we have a XTypeDescription for every member. If not then the user may + //have forgotten to specify additional rdbs with the --extra option. + Reference< reflection::XTypeDescription > const * pseq_members = + seq_members.getConstArray(); + OUString const * pseq_member_names = + seq_member_names.getConstArray(); + for (int i = 0; i < members_length; i++) + { + const OUString sType(entry->m_xType->getName()); + const OUString sMemberName(pseq_member_names[i]); + if ( ! pseq_members[i].is()) + throw RuntimeException("Missing type description . Check if you need to " + "specify additional RDBs with the --extra option. Type missing for: " + sType + + "::" + sMemberName,0); + } + + sal_Int32 all_members_length = 0; + sal_Int32 member_pos; + sal_Int32 type_param_pos = 0; + + // collect base types; wrong order + ::System::Collections::ArrayList ^ base_types_list = + gcnew ::System::Collections::ArrayList( 3 /* initial capacity */ ); + for (::System::Type ^ base_type_pos = entry->m_base_type; + ! base_type_pos->Equals( ::System::Object::typeid ); + base_type_pos = base_type_pos->BaseType ) + { + base_types_list->Add( base_type_pos ); + if (base_type_pos->Equals( ::System::Exception::typeid )) + { + // special Message member + all_members_length += 1; + break; // don't include System.Exception base classes + } + else + { + //ensure the base type is complete. Otherwise GetFields won't work + get_complete_struct(base_type_pos->FullName); + all_members_length += + base_type_pos->GetFields( + (BindingFlags) (BindingFlags::Instance | + BindingFlags::Public | + BindingFlags::DeclaredOnly) ) + ->Length; + } + } + + // create all_members arrays; right order + array< ::System::String^>^ all_member_names = + gcnew array< ::System::String^> (all_members_length + members_length ); + array< ::System::Type^>^ all_param_types = + gcnew array< ::System::Type^> (all_members_length + members_length ); + member_pos = 0; + for ( sal_Int32 pos = base_types_list->Count; pos--; ) + { + ::System::Type ^ base_type = safe_cast< ::System::Type ^ >( + base_types_list[pos] ); + if (base_type->Equals( ::System::Exception::typeid )) + { + all_member_names[ member_pos ] = "Message"; + all_param_types[ member_pos ] = ::System::String::typeid; + ++member_pos; + } + else + { + ::System::String ^ base_type_name = base_type->FullName; + + //ToDo m_generated_structs? + struct_entry ^ entry = + dynamic_cast< struct_entry ^ >( + m_generated_structs[base_type_name] ); + if (nullptr == entry) + { + // complete type + array^ fields = + base_type->GetFields( + (BindingFlags) (BindingFlags::Instance | + BindingFlags::Public | + BindingFlags::DeclaredOnly) ); + sal_Int32 len = fields->Length; + for ( sal_Int32 pos = 0; pos < len; ++pos ) + { + FieldInfo ^ field = fields[ pos ]; + all_member_names[ member_pos ] = field->Name; + all_param_types[ member_pos ] = field->FieldType; + ++member_pos; + } + } + else // generated during this session: + // members may be incomplete ifaces + { + sal_Int32 len = entry->m_member_names->Length; + for ( sal_Int32 pos = 0; pos < len; ++pos ) + { + all_member_names[ member_pos ] = + entry->m_member_names[ pos ]; + all_param_types[ member_pos ] = + entry->m_param_types[ pos ]; + ++member_pos; + } + } + } + } + OSL_ASSERT( all_members_length == member_pos ); + + // build up entry +// struct_entry * entry = new struct_entry(); + entry->m_member_names = gcnew array< ::System::String^> ( members_length ); + entry->m_param_types = gcnew array< ::System::Type^> ( members_length ); + + // add members + array^ members = gcnew array ( members_length ); + //Reference< reflection::XTypeDescription > const * pseq_members = + // seq_members.getConstArray(); + //OUString const * pseq_member_names = + // seq_member_names.getConstArray(); + + int curParamIndex = 0; //count the fields which have parameterized types + for ( member_pos = 0; member_pos < members_length; ++member_pos ) + { + ::System::String ^ field_name = + ustring_to_String( pseq_member_names[ member_pos ] ); + ::System::Type ^ field_type; + //Special handling of struct parameter types + bool bParameterizedType = false; + if (pseq_members[ member_pos ]->getTypeClass() == TypeClass_UNKNOWN) + { + bParameterizedType = true; + if (type_param_pos < seq_type_parameters.getLength()) + { + field_type = ::System::Object::typeid; + type_param_pos++; + } + else + { + throw RuntimeException( + "unexpected member type in " + entry->m_xType->getName() ); + } + } + else + { + field_type = get_type( pseq_members[ member_pos ] ); + + if (field_type->IsArray + && m_incomplete_structs[cts_name] + && !field_type->Namespace->Equals("System")) + { + //Find the value type. In case of sequence > find the actual value type + ::System::Type ^ value = field_type; + while ((value = value->GetElementType())->IsArray); + //If the value type is a struct then make sure it is fully created. + get_complete_struct(value->FullName); + field_type = get_type(pseq_members[member_pos]); + } + } + members[ member_pos ] = + entry->m_type_builder->DefineField( + field_name, field_type, FieldAttributes::Public ); + + //parameterized type (polymorphic struct) ? + if (bParameterizedType && xStructTypeDesc.is()) + { + //get the name + OSL_ASSERT(seq_type_parameters.getLength() > curParamIndex); + ::System::String^ sTypeName = ustring_to_String( + seq_type_parameters.getConstArray()[curParamIndex++]); + array< ::System::Object^>^ args = {sTypeName}; + //set ParameterizedTypeAttribute + array< ::System::Type^>^ arCtorTypes = {::System::String::typeid}; + + Emit::CustomAttributeBuilder ^ attrBuilder = + gcnew Emit::CustomAttributeBuilder( + ::uno::ParameterizedTypeAttribute::typeid + ->GetConstructor(arCtorTypes), + args); + + members[member_pos]->SetCustomAttribute(attrBuilder); + } + // add to all_members + all_member_names[ all_members_length + member_pos ] = field_name; + all_param_types[ all_members_length + member_pos ] = field_type; + // add to entry + entry->m_member_names[ member_pos ] = field_name; + entry->m_param_types[ member_pos ] = field_type; + } + all_members_length += members_length; + + // default .ctor + Emit::ConstructorBuilder ^ ctor_builder = + entry->m_type_builder->DefineConstructor( + c_ctor_method_attr, CallingConventions::Standard, + gcnew array< ::System::Type^> ( 0 ) ); + Emit::ILGenerator ^ code = ctor_builder->GetILGenerator(); + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( + Emit::OpCodes::Call, + nullptr == base_type_entry + ? entry->m_base_type->GetConstructor( gcnew array< ::System::Type^> ( 0 ) ) + : base_type_entry->m_default_ctor ); + // default initialize members + for ( member_pos = 0; member_pos < members_length; ++member_pos ) + { + FieldInfo ^ field = members[ member_pos ]; + ::System::Type ^ field_type = field->FieldType; + // ::System::Type * new_field_type = m_module_builder->GetType(field_type->FullName, false); + // default initialize: + // string, type, enum, sequence, struct, exception, any + if (field_type->Equals( ::System::String::typeid )) + { + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( Emit::OpCodes::Ldstr, "" ); + code->Emit( Emit::OpCodes::Stfld, field ); + } + else if (field_type->Equals( ::System::Type::typeid )) + { + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( + Emit::OpCodes::Ldtoken, ::System::Void::typeid ); + code->Emit( + Emit::OpCodes::Call, m_method_info_Type_GetTypeFromHandle ); + code->Emit( Emit::OpCodes::Stfld, field ); + } + else if (field_type->IsArray) + { + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( Emit::OpCodes::Ldc_I4_0 ); + code->Emit( + Emit::OpCodes::Newarr, field_type->GetElementType() ); + code->Emit( Emit::OpCodes::Stfld, field ); + } + else if (field_type->IsValueType) + { + if (field_type->FullName->Equals( "uno.Any" )) + { + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( Emit::OpCodes::Ldsfld, ::uno::Any::typeid->GetField("VOID")); + code->Emit( Emit::OpCodes::Stfld, field ); + } + } + else if (field_type->IsClass) + { + /* may be XInterface */ + if (! field_type->Equals( ::System::Object::typeid )) + { + // struct, exception + //make sure the struct is already complete. + get_complete_struct(field_type->FullName); + code->Emit( Emit::OpCodes::Ldarg_0 ); + code->Emit( + Emit::OpCodes::Newobj, + //GetConstructor requires that the member types of the object which is to be constructed are already known. + field_type->GetConstructor( + gcnew array< ::System::Type^> ( 0 ) ) ); + code->Emit( Emit::OpCodes::Stfld, field ); + } + } + } + code->Emit( Emit::OpCodes::Ret ); + entry->m_default_ctor = ctor_builder; + + // parameterized .ctor including all base members + ctor_builder = entry->m_type_builder->DefineConstructor( + c_ctor_method_attr, CallingConventions::Standard, all_param_types ); + for ( member_pos = 0; member_pos < all_members_length; ++member_pos ) + { + ctor_builder->DefineParameter( + member_pos +1 /* starts with 1 */, ParameterAttributes::In, + all_member_names[ member_pos ] ); + } + code = ctor_builder->GetILGenerator(); + // call base .ctor + code->Emit( Emit::OpCodes::Ldarg_0 ); // push this + sal_Int32 base_members_length = all_members_length - members_length; + array< ::System::Type^>^ param_types = + gcnew array< ::System::Type^> ( base_members_length ); + for ( member_pos = 0; member_pos < base_members_length; ++member_pos ) + { + emit_ldarg( code, member_pos +1 ); + param_types[ member_pos ] = all_param_types[ member_pos ]; + } + code->Emit( + Emit::OpCodes::Call, + nullptr == base_type_entry + ? entry->m_base_type->GetConstructor( param_types ) + : base_type_entry->m_ctor ); + // initialize members + for ( member_pos = 0; member_pos < members_length; ++member_pos ) + { + code->Emit( Emit::OpCodes::Ldarg_0 ); // push this + emit_ldarg( code, member_pos + base_members_length +1 ); + code->Emit( Emit::OpCodes::Stfld, members[ member_pos ] ); + } + code->Emit( Emit::OpCodes::Ret ); + entry->m_ctor = ctor_builder; + + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting {0} type {1}", + TypeClass_STRUCT == entry->m_xType->getTypeClass() + ? "struct" + : "exception", + cts_name); + } + // new entry + m_generated_structs->Add(cts_name, entry ); + ::System::Type ^ ret_type = entry->m_type_builder->CreateType(); + + // remove from incomplete types map + m_incomplete_structs->Remove( cts_name ); + entry->m_xType->release(); + + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting struct type {0}", cts_name); + } + return ret_type; +} + +//Examples of generated code +// public static XWeak constructor1(XComponentContext ctx) +// { +// XMultiComponentFactory factory = ctx.getServiceManager(); +// if (factory == null) +// throw new com.sun.star.uno.DeploymentException("bla", null); +// return (XWeak) factory.createInstanceWithContext("service_specifier", ctx); +// } +// public static XWeak constructor2(XComponentContext ctx, int a, int b, Any c) +// { +// XMultiComponentFactory factory = ctx.getServiceManager(); +// if (factory == null) +// throw new com.sun.star.uno.DeploymentException("bla", null); +// Any[] arAny = new Any[3]; +// arAny[0] = new Any(typeof(int), a); +// arAny[1] = new Any(typeof(int), b); +// arAny[2] = new Any(c.Type, c.Value); +// return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", arAny, ctx); +// } +// Notice that an any parameter is NOT wrapped by another any. Instead the new any is created with the type and value +// of the parameter. + +// public static XWeak constructor3(XComponentContext ctx, params Any[] c) +// { +// XMultiComponentFactory factory = ctx.getServiceManager(); +// if (factory == null) +// throw new com.sun.star.uno.DeploymentException("bla", null); +// return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", c, ctx); +// } +::System::Type ^ TypeEmitter::complete_service_type(service_entry ^ entry) +{ + Emit::TypeBuilder ^ type_builder = entry->m_type_builder; + reflection::XServiceTypeDescription2 * xServiceType = entry->m_xType; + + //Create the private default constructor + Emit::ConstructorBuilder^ ctor_builder = + type_builder->DefineConstructor( + (MethodAttributes) (MethodAttributes::Private | + MethodAttributes::HideBySig | + MethodAttributes::SpecialName | + MethodAttributes::RTSpecialName), + CallingConventions::Standard, nullptr); + + Emit::ILGenerator^ ilGen = ctor_builder->GetILGenerator(); + ilGen->Emit( Emit::OpCodes::Ldarg_0 ); // push this + ilGen->Emit( + Emit::OpCodes::Call, + type_builder->BaseType->GetConstructor(gcnew array< ::System::Type^>(0))); + ilGen->Emit( Emit::OpCodes::Ret ); + + + //Create the service constructors. + //obtain the interface which makes up this service, it is the return + //type of the constructor functions + Reference xIfaceType( + xServiceType->getInterface(), UNO_QUERY); + if (xIfaceType.is () == sal_False) + xIfaceType = resolveInterfaceTypedef(xServiceType->getInterface()); + System::Type ^ retType = get_type(xIfaceType); + + //Create the ConstructorInfo for a DeploymentException + ::System::Type ^ typeDeploymentExc = + get_type("unoidl.com.sun.star.uno.DeploymentException", true); + + array< ::System::Type^>^ arTypeCtor = {::System::String::typeid, + ::System::Object::typeid}; + ::System::Reflection::ConstructorInfo ^ ctorDeploymentException = + typeDeploymentExc->GetConstructor(arTypeCtor); + + Sequence > seqCtors = + xServiceType->getConstructors(); + + ::System::Type ^ type_uno_exception = get_type("unoidl.com.sun.star.uno.Exception", true); + + for (int i = seqCtors.getLength() - 1; i >= 0; i--) + { + bool bParameterArray = false; + ::System::Type ^ typeAny = ::uno::Any::typeid; + const Reference & ctorDes = + seqCtors[i]; + //obtain the parameter types + Sequence > seqParams = + ctorDes->getParameters(); + Reference const * arXParams = seqParams.getConstArray(); + sal_Int32 cParams = seqParams.getLength(); + array< ::System::Type^>^ arTypeParameters = gcnew array< ::System::Type^> (cParams + 1); + arTypeParameters[0] = get_type("unoidl.com.sun.star.uno.XComponentContext", true); + for (int iparam = 0; iparam != cParams; iparam++) + { + if (arXParams[iparam]->isRestParameter()) + arTypeParameters[iparam + 1] = array< ::uno::Any>::typeid; + else + arTypeParameters[iparam + 1] = get_type(arXParams[iparam]->getType()); + } + //The array arTypeParameters can contain: + //System.Type and uno.PolymorphicType. + //Passing PolymorphicType to MethodBuilder.DefineMethod will cause a problem. + //The exception will read something like no on information for parameter # d + //Maybe we need no override another Type method in PolymorphicType ... + //Until we have figured this out, we will create another array of System.Type which + //we pass on to DefineMethod. + array< ::System::Type^>^ arParamTypes = gcnew array< ::System::Type^> (cParams + 1); +// arParamTypes[0] = get_type("unoidl.com.sun.star.uno.XComponentContext", true); + for (int i = 0; i < cParams + 1; i++) + { + ::uno::PolymorphicType ^ pT = dynamic_cast< ::uno::PolymorphicType ^ >(arTypeParameters[i]); + if (pT) + arParamTypes[i] = pT->OriginalType; + else + arParamTypes[i] = arTypeParameters[i]; + } + //define method + System::String ^ ctorName; + if (ctorDes->isDefaultConstructor()) + ctorName = gcnew ::System::String("create"); + else + ctorName = ustring_to_String(ctorDes->getName()); + Emit::MethodBuilder^ method_builder = type_builder->DefineMethod( + ctorName, + static_cast(MethodAttributes::Public | MethodAttributes::HideBySig | + MethodAttributes::Static), + retType, +// arTypeParameters); + arParamTypes); + + //define UNO exception attribute (exceptions)-------------------------------------- + Emit::CustomAttributeBuilder^ attrBuilder = get_service_exception_attribute(ctorDes); + if (attrBuilder != nullptr) + method_builder->SetCustomAttribute(attrBuilder); + + + //define parameter attributes (paramarray), names etc. + //The first parameter is the XComponentContext, which cannot be obtained + //from reflection. + //The context is not part of the idl description + method_builder->DefineParameter( + 1, ParameterAttributes::In, "the_context"); + + array^ arParameterBuilder = + gcnew array (cParams); + for (int iparam = 0; iparam != cParams; iparam++) + { + Reference const & aParam = arXParams[iparam]; + ::System::String ^ sParamName = ustring_to_String(aParam->getName()); + + arParameterBuilder[iparam] = method_builder->DefineParameter( + iparam + 2, ParameterAttributes::In, sParamName); + + if (aParam->isRestParameter()) + { + bParameterArray = true; + //set the ParameterArrayAttribute + ::System::Reflection::ConstructorInfo^ ctor_info = + System::ParamArrayAttribute::typeid->GetConstructor( + gcnew array< ::System::Type^>(0)); + Emit::CustomAttributeBuilder ^ attr_builder = + gcnew Emit::CustomAttributeBuilder(ctor_info, gcnew array< ::System::Object^>(0)); + arParameterBuilder[iparam]->SetCustomAttribute(attr_builder); + break; + } + } + + Emit::ILGenerator ^ ilGen = method_builder->GetILGenerator(); + + //Define locals --------------------------------- + //XMultiComponentFactory + Emit::LocalBuilder^ local_factory = + ilGen->DeclareLocal( + get_type("unoidl.com.sun.star.lang.XMultiComponentFactory", true)); + + //The return type + Emit::LocalBuilder^ local_return_val = + ilGen->DeclareLocal(retType); + + //Obtain the XMultiComponentFactory and throw an exception if we do not get one + ilGen->Emit(Emit::OpCodes::Ldarg_0); + + ::System::Reflection::MethodInfo ^ methodGetServiceManager = get_type( + "unoidl.com.sun.star.uno.XComponentContext", true) + ->GetMethod("getServiceManager"); + ilGen->Emit(Emit::OpCodes::Callvirt, methodGetServiceManager); + ilGen->Emit(Emit::OpCodes::Stloc, local_factory); + ilGen->Emit(Emit::OpCodes::Ldloc, local_factory); + Emit::Label label1 = ilGen->DefineLabel(); + ilGen->Emit(Emit::OpCodes::Brtrue, label1); + //The string for the exception + ::System::Text::StringBuilder ^ strbuilder = gcnew ::System::Text::StringBuilder(256); + strbuilder->Append("The service "); + strbuilder->Append(to_cts_name(xServiceType->getName())); + strbuilder->Append(" could not be created. The context failed to supply the service manager."); + + ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString()); + ilGen->Emit(Emit::OpCodes::Ldarg_0); + ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException); + ilGen->Emit(Emit::OpCodes::Throw); + ilGen->MarkLabel(label1); + + //We create a try/ catch around the createInstanceWithContext, etc. functions + //There are 3 cases + //1. function do not specify exceptions. Then RuntimeExceptions are re-thrown and other + // exceptions produce a DeploymentException. + //2. function specify Exception. Then all exceptions fly through + //3. function specifies exceptions but no Exception. Then these are rethrown + // and other exceptions, except RuntimeException, produce a deployment exception. + //In case there are no parameters we call + //XMultiComponentFactory.createInstanceWithContext + + ::System::Collections::ArrayList ^ arExceptionTypes = + get_service_ctor_method_exceptions_reduced(ctorDes->getExceptions()); + if (arExceptionTypes->Contains( + type_uno_exception) == false) + { + ilGen->BeginExceptionBlock(); + } + if (cParams == 0) + { + ilGen->Emit(Emit::OpCodes::Ldloc, local_factory); + ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName())); + ilGen->Emit(Emit::OpCodes::Ldarg_0); + + ::System::Reflection::MethodInfo ^ methodCreate = + local_factory->LocalType->GetMethod("createInstanceWithContext"); + ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate); + } + else if(bParameterArray) + { + //Service constructor with parameter array + ilGen->Emit(Emit::OpCodes::Ldloc, local_factory); + ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName())); + ilGen->Emit(Emit::OpCodes::Ldarg_1); + ilGen->Emit(Emit::OpCodes::Ldarg_0); + ::System::Reflection::MethodInfo ^ methodCreate = + local_factory->LocalType->GetMethod("createInstanceWithArgumentsAndContext"); + ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate); + } + else + { + // Any param1, Any param2, etc. + // For each parameter,except the component context, and parameter array + // and Any is created. + array^ arLocalAny = gcnew array (cParams); + + for (int iParam = 0; iParam < cParams; iParam ++) + { + arLocalAny[iParam] = ilGen->DeclareLocal(typeAny); + } + + //Any[]. This array is filled with the created Anys which contain the parameters + //and the values contained in the parameter array + Emit::LocalBuilder ^ local_anyParams = + ilGen->DeclareLocal(array< ::uno::Any>::typeid); + + //Create the Any for every argument, except for the parameter array + //arLocalAny contains the LocalBuilder for all these parameters. + //we call the ctor Any(Type, Object) + //If the parameter is an Any then the Any is created with Any(param.Type, param.Value); + array< ::System::Type^>^ arTypesCtorAny = {::System::Type::typeid, + ::System::Object::typeid}; + ::System::Reflection::ConstructorInfo ^ ctorAny = + typeAny->GetConstructor( arTypesCtorAny); + ::System::Reflection::MethodInfo ^ methodAnyGetType = + typeAny->GetProperty("Type")->GetGetMethod(); + ::System::Reflection::MethodInfo ^ methodAnyGetValue = + typeAny->GetProperty("Value")->GetGetMethod(); + for (int i = 0; i < arLocalAny->Length; i ++) + { + //check if the parameter is a polymorphic struct + ::uno::PolymorphicType ^polyType = dynamic_cast< ::uno::PolymorphicType^ >(arTypeParameters[i+1]); + //arTypeParameters[i+1] = polyType->OriginalType; + if (polyType) + { + //It is a polymorphic struct + //Load the uninitialized local Any on which we will call the ctor + ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]); + // Call PolymorphicType PolymorphicType::GetType(Type t, String polyName) + // Prepare the first parameter + ilGen->Emit(Emit::OpCodes::Ldtoken, polyType->OriginalType); + array< ::System::Type^>^ arTypeParams = {::System::RuntimeTypeHandle::typeid}; + ilGen->Emit(Emit::OpCodes::Call, + ::System::Type::typeid->GetMethod( + "GetTypeFromHandle", arTypeParams)); + // Prepare the second parameter + ilGen->Emit(Emit::OpCodes::Ldstr, polyType->PolymorphicName); + // Make the actual call + array< ::System::Type^>^ arTypeParam_GetType = { + ::System::Type::typeid, ::System::String::typeid }; + ilGen->Emit(Emit::OpCodes::Call, + ::uno::PolymorphicType::typeid->GetMethod(gcnew System::String("GetType"), + arTypeParam_GetType)); + + //Stack is: localAny, PolymorphicType + //Call Any::Any(Type, Object) + //Prepare the second parameter for the any ctor + ilGen->Emit(Emit::OpCodes::Ldarg, i + 1); + // if the parameter is a value type then we need to box it, because + // the Any ctor takes an Object + if (arTypeParameters[i+1]->IsValueType) + ilGen->Emit(Emit::OpCodes::Box, arTypeParameters[i+1]); + ilGen->Emit(Emit::OpCodes::Call, ctorAny); + } + else if (arTypeParameters[i+1] == typeAny) + { + //Create the call new Any(param.Type,param,Value) + //Stack must be Any,Type,Value + //First load the Any which is to be constructed + ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]); + //Load the Type, which is obtained by calling param.Type + ilGen->Emit(Emit::OpCodes::Ldarga, i + 1); + ilGen->Emit(Emit::OpCodes::Call, methodAnyGetType); + //Load the Value, which is obtained by calling param.Value + ilGen->Emit(Emit::OpCodes::Ldarga, i + 1); + ilGen->Emit(Emit::OpCodes::Call, methodAnyGetValue); + //Call the Any ctor. + ilGen->Emit(Emit::OpCodes::Call, ctorAny); + } + else + { + ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]); + ilGen->Emit(Emit::OpCodes::Ldtoken, arTypeParameters[i+1]); + + array< ::System::Type^>^ arTypeParams = {::System::RuntimeTypeHandle::typeid}; + ilGen->Emit(Emit::OpCodes::Call, + ::System::Type::typeid->GetMethod( + "GetTypeFromHandle", arTypeParams)); + ilGen->Emit(Emit::OpCodes::Ldarg, i + 1); + // if the parameter is a value type then we need to box it, because + // the Any ctor takes an Object + if (arTypeParameters[i+1]->IsValueType) + ilGen->Emit(Emit::OpCodes::Box, arTypeParameters[i+1]); + ilGen->Emit(Emit::OpCodes::Call, ctorAny); + } + } + + //Create the Any[] that is passed to the + //createInstanceWithContext[AndArguments] function + ilGen->Emit(Emit::OpCodes::Ldc_I4, arLocalAny->Length); + ilGen->Emit(Emit::OpCodes::Newarr, typeAny); + ilGen->Emit(Emit::OpCodes::Stloc, local_anyParams); + + //Assign all anys created from the parameters + //array to the Any[] + for (int i = 0; i < arLocalAny->Length; i++) + { + ilGen->Emit(Emit::OpCodes::Ldloc, local_anyParams); + ilGen->Emit(Emit::OpCodes::Ldc_I4, i); + ilGen->Emit(Emit::OpCodes::Ldelema, typeAny); + ilGen->Emit(Emit::OpCodes::Ldloc, arLocalAny[i]); + ilGen->Emit(Emit::OpCodes::Stobj, typeAny); + } + // call createInstanceWithArgumentsAndContext + ilGen->Emit(Emit::OpCodes::Ldloc, local_factory); + ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName())); + ilGen->Emit(Emit::OpCodes::Ldloc, local_anyParams); + ilGen->Emit(Emit::OpCodes::Ldarg_0); + ::System::Reflection::MethodInfo ^ methodCreate = + local_factory->LocalType->GetMethod("createInstanceWithArgumentsAndContext"); + ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate); + } + //cast the object returned by the functions createInstanceWithContext or + //createInstanceWithArgumentsAndContext to the interface type + ilGen->Emit(Emit::OpCodes::Castclass, retType); + ilGen->Emit(Emit::OpCodes::Stloc, local_return_val); + + //catch exceptions thrown by createInstanceWithArgumentsAndContext and createInstanceWithContext + if (arExceptionTypes->Contains(type_uno_exception) == false) + { + // catch (unoidl.com.sun.star.uno.RuntimeException) {throw;} + ilGen->BeginCatchBlock(get_type("unoidl.com.sun.star.uno.RuntimeException", true)); + ilGen->Emit(Emit::OpCodes::Pop); + ilGen->Emit(Emit::OpCodes::Rethrow); + + //catch and rethrow all other defined Exceptions + for (int i = 0; i < arExceptionTypes->Count; i++) + { + ::System::Type ^ excType = safe_cast< ::System::Type^ >( + arExceptionTypes[i]); + if (excType->IsInstanceOfType( + get_type("unoidl.com.sun.star.uno.RuntimeException", true))) + {// we have a catch for RuntimeException already defined + continue; + } + + //catch Exception and rethrow + ilGen->BeginCatchBlock(excType); + ilGen->Emit(Emit::OpCodes::Pop); + ilGen->Emit(Emit::OpCodes::Rethrow); + } + //catch (unoidl.com.sun.star.uno.Exception) {throw DeploymentException...} + ilGen->BeginCatchBlock(type_uno_exception); + + //Define the local variable that keeps the exception + Emit::LocalBuilder ^ local_exception = ilGen->DeclareLocal( + type_uno_exception); + + //Store the exception + ilGen->Emit(Emit::OpCodes::Stloc, local_exception); + + //prepare the construction of the exception + strbuilder = gcnew ::System::Text::StringBuilder(256); + strbuilder->Append("The context (com.sun.star.uno.XComponentContext) failed to supply the service "); + strbuilder->Append(to_cts_name(xServiceType->getName())); + strbuilder->Append(": "); + + ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString()); + + //add to the string the Exception.Message + ilGen->Emit(Emit::OpCodes::Ldloc, local_exception); + ilGen->Emit(Emit::OpCodes::Callvirt, + type_uno_exception->GetProperty("Message")->GetGetMethod()); + array< ::System::Type^>^ arConcatParams = {System::String::typeid, + System::String::typeid}; + ilGen->Emit(Emit::OpCodes::Call, + System::String::typeid->GetMethod("Concat", arConcatParams)); + //load context argument + ilGen->Emit(Emit::OpCodes::Ldarg_0); + ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException); + ilGen->Emit(Emit::OpCodes::Throw);//Exception(typeDeploymentExc); + + ilGen->EndExceptionBlock(); + } + + + //Check if the service instance was created and threw an exception if not + Emit::Label label_service_created = ilGen->DefineLabel(); + ilGen->Emit(Emit::OpCodes::Ldloc, local_return_val); + ilGen->Emit(Emit::OpCodes::Brtrue_S, label_service_created); + + strbuilder = gcnew ::System::Text::StringBuilder(256); + strbuilder->Append("The context (com.sun.star.uno.XComponentContext) failed to supply the service "); + strbuilder->Append(to_cts_name(xServiceType->getName())); + strbuilder->Append("."); + ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString()); + ilGen->Emit(Emit::OpCodes::Ldarg_0); + ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException); + ilGen->Emit(Emit::OpCodes::Throw);//Exception(typeDeploymentExc); + + ilGen->MarkLabel(label_service_created); + ilGen->Emit(Emit::OpCodes::Ldloc, local_return_val); + ilGen->Emit(Emit::OpCodes::Ret); + + } + // remove from incomplete types map + ::System::String ^ cts_name = type_builder->FullName; + m_incomplete_services->Remove( cts_name ); + xServiceType->release(); + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting service type {0}", cts_name ); + } + return type_builder->CreateType(); +} + + +Emit::CustomAttributeBuilder^ TypeEmitter::get_service_exception_attribute( + const Reference & ctorDes ) +{ + return get_exception_attribute(ctorDes->getExceptions()); +} + +Emit::CustomAttributeBuilder^ TypeEmitter::get_iface_method_exception_attribute( + const Reference< reflection::XInterfaceMethodTypeDescription >& xMethod ) +{ + + const Sequence > seqTD = xMethod->getExceptions(); + int len = seqTD.getLength(); + Sequence > seqCTD(len); + Reference * arCTD = seqCTD.getArray(); + for (int i = 0; i < len; i++) + arCTD[i] = Reference(seqTD[i], UNO_QUERY_THROW); + return get_exception_attribute(seqCTD); +} + +Emit::CustomAttributeBuilder^ TypeEmitter::get_exception_attribute( + + const Sequence >& seq_exceptionsTd ) +{ + Emit::CustomAttributeBuilder ^ attr_builder = nullptr; + + Reference< reflection::XCompoundTypeDescription > const * exceptions = + seq_exceptionsTd.getConstArray(); + + array< ::System::Type^>^ arTypesCtor = {::System::Type::GetType("System.Type[]")}; + ConstructorInfo ^ ctor_ExceptionAttribute = + ::uno::ExceptionAttribute::typeid->GetConstructor(arTypesCtor); + + sal_Int32 exc_length = seq_exceptionsTd.getLength(); + if (exc_length != 0) // opt + { + array< ::System::Type^>^ exception_types = + gcnew array< ::System::Type^> ( exc_length ); + for ( sal_Int32 exc_pos = 0; exc_pos < exc_length; ++exc_pos ) + { + Reference< reflection::XCompoundTypeDescription > const & xExc = + exceptions[ exc_pos ]; + exception_types[ exc_pos ] = get_type( xExc ); + } + array< ::System::Object^>^ args = {exception_types}; + attr_builder = gcnew Emit::CustomAttributeBuilder( + ctor_ExceptionAttribute, args ); + } + return attr_builder; +} + + +::System::Type ^ TypeEmitter::complete_singleton_type(singleton_entry ^ entry) +{ + Emit::TypeBuilder ^ type_builder = entry->m_type_builder; + reflection::XSingletonTypeDescription2 * xSingletonType = entry->m_xType; + ::System::String^ sSingletonName = to_cts_name(xSingletonType->getName()); + + //Create the private default constructor + Emit::ConstructorBuilder^ ctor_builder = + type_builder->DefineConstructor( + static_cast(MethodAttributes::Private | + MethodAttributes::HideBySig | + MethodAttributes::SpecialName | + MethodAttributes::RTSpecialName), + CallingConventions::Standard, nullptr); + + Emit::ILGenerator^ ilGen = ctor_builder->GetILGenerator(); + ilGen->Emit( Emit::OpCodes::Ldarg_0 ); // push this + ilGen->Emit( + Emit::OpCodes::Call, + type_builder->BaseType->GetConstructor(gcnew array< ::System::Type^>(0))); + ilGen->Emit( Emit::OpCodes::Ret ); + + + //obtain the interface which makes up this service, it is the return + //type of the constructor functions + Reference xIfaceType( + xSingletonType->getInterface(), UNO_QUERY); + if (xIfaceType.is () == sal_False) + xIfaceType = resolveInterfaceTypedef(xSingletonType->getInterface()); + System::Type ^ retType = get_type(xIfaceType); + + //define method + array< ::System::Type^>^ arTypeParameters = {get_type("unoidl.com.sun.star.uno.XComponentContext", true)}; + Emit::MethodBuilder^ method_builder = type_builder->DefineMethod( + gcnew System::String("get"), + static_cast(MethodAttributes::Public | MethodAttributes::HideBySig | + MethodAttributes::Static), + retType, + arTypeParameters); + + +// method_builder->SetCustomAttribute(get_service_ctor_method_attribute(ctorDes)); + + //The first parameter is the XComponentContext, which cannot be obtained + //from reflection. + //The context is not part of the idl description + method_builder->DefineParameter(1, ParameterAttributes::In, "the_context"); + + + ilGen = method_builder->GetILGenerator(); + //Define locals --------------------------------- + // Any, returned by XComponentContext.getValueByName + Emit::LocalBuilder^ local_any = + ilGen->DeclareLocal(::uno::Any::typeid); + + //Call XContext::getValueByName + ilGen->Emit(Emit::OpCodes::Ldarg_0); + // build the singleton name : /singleton/unoidl.com.sun.star.XXX + ::System::Text::StringBuilder^ sBuilder = + gcnew ::System::Text::StringBuilder("/singletons/"); + sBuilder->Append(sSingletonName); + ilGen->Emit(Emit::OpCodes::Ldstr, sBuilder->ToString()); + + ::System::Reflection::MethodInfo ^ methodGetValueByName = + get_type("unoidl.com.sun.star.uno.XComponentContext", true)->GetMethod("getValueByName"); + ilGen->Emit(Emit::OpCodes::Callvirt, methodGetValueByName); + ilGen->Emit(Emit::OpCodes::Stloc_0); + + //Contains the returned Any a value? + ilGen->Emit(Emit::OpCodes::Ldloca_S, local_any); + ::System::Reflection::MethodInfo ^ methodHasValue = + ::uno::Any::typeid->GetMethod("hasValue"); + ilGen->Emit(Emit::OpCodes::Call, methodHasValue); + + //If not, then throw a DeploymentException + Emit::Label label_singleton_exists = ilGen->DefineLabel(); + ilGen->Emit(Emit::OpCodes::Brtrue_S, label_singleton_exists); + sBuilder = gcnew ::System::Text::StringBuilder( + "Component context fails to supply singleton "); + sBuilder->Append(sSingletonName); + sBuilder->Append(" of type "); + sBuilder->Append(retType->FullName); + sBuilder->Append("."); + ilGen->Emit(Emit::OpCodes::Ldstr, sBuilder->ToString()); + ilGen->Emit(Emit::OpCodes::Ldarg_0); + array< ::System::Type^>^ arTypesCtorDeploymentException = { + ::System::String::typeid, ::System::Object::typeid}; + ilGen->Emit(Emit::OpCodes::Newobj, + get_type("unoidl.com.sun.star.uno.DeploymentException",true) + ->GetConstructor(arTypesCtorDeploymentException)); + ilGen->Emit(Emit::OpCodes::Throw); + ilGen->MarkLabel(label_singleton_exists); + + //Cast the singleton contained in the Any to the expected interface and return it. + ilGen->Emit(Emit::OpCodes::Ldloca_S, local_any); + ilGen->Emit(Emit::OpCodes::Call, ::uno::Any::typeid->GetProperty("Value")->GetGetMethod()); + ilGen->Emit(Emit::OpCodes::Castclass, retType); + ilGen->Emit(Emit::OpCodes::Ret); + + // remove from incomplete types map + ::System::String ^ cts_name = type_builder->FullName; + m_incomplete_singletons->Remove( cts_name ); + xSingletonType->release(); + if (g_bVerbose) + { + ::System::Console::WriteLine( + "> emitting singleton type {0}", cts_name ); + } + return type_builder->CreateType(); +} + + +::System::Type ^ TypeEmitter::get_type( + Reference< reflection::XTypeDescription > const & xType ) +{ + switch (xType->getTypeClass()) + { + case TypeClass_VOID: + return ::System::Void::typeid; + case TypeClass_CHAR: + return ::System::Char::typeid; + case TypeClass_BOOLEAN: + return ::System::Boolean::typeid; + case TypeClass_BYTE: + return ::System::Byte::typeid; + case TypeClass_SHORT: + return ::System::Int16::typeid; + case TypeClass_UNSIGNED_SHORT: + return ::System::UInt16::typeid; + case TypeClass_LONG: + return ::System::Int32::typeid; + case TypeClass_UNSIGNED_LONG: + return ::System::UInt32::typeid; + case TypeClass_HYPER: + return ::System::Int64::typeid; + case TypeClass_UNSIGNED_HYPER: + return ::System::UInt64::typeid; + case TypeClass_FLOAT: + return ::System::Single::typeid; + case TypeClass_DOUBLE: + return ::System::Double::typeid; + case TypeClass_STRING: + return ::System::String::typeid; + case TypeClass_TYPE: + return ::System::Type::typeid; + case TypeClass_ANY: + return ::uno::Any::typeid; + case TypeClass_ENUM: + return get_type( Reference< reflection::XEnumTypeDescription >( + xType, UNO_QUERY_THROW ) ); + case TypeClass_TYPEDEF: + // unwind typedefs + return get_type( + Reference< reflection::XIndirectTypeDescription >( + xType, UNO_QUERY_THROW )->getReferencedType() ); + case TypeClass_STRUCT: + case TypeClass_EXCEPTION: + return get_type( + Reference< reflection::XCompoundTypeDescription >( + xType, UNO_QUERY_THROW ) ); + case TypeClass_SEQUENCE: + { + ::System::Type ^ element_type = get_type( + Reference< reflection::XIndirectTypeDescription >( + xType, UNO_QUERY_THROW )->getReferencedType() ); + ::System::Type ^ retType = get_type( + ::System::String::Concat( + element_type->FullName, "[]" ), true ); + + ::uno::PolymorphicType ^ pt = dynamic_cast< ::uno::PolymorphicType ^ >(element_type); + if (pt) + { + ::System::String ^ sName = ::System::String::Concat(pt->PolymorphicName, "[]"); + retType = ::uno::PolymorphicType::GetType(retType, sName); + } + return retType; + } + case TypeClass_INTERFACE: + return get_type( + Reference< reflection::XInterfaceTypeDescription2 >( + xType, UNO_QUERY_THROW ) ); + case TypeClass_CONSTANT: + return get_type( + Reference< reflection::XConstantTypeDescription >( + xType, UNO_QUERY_THROW ) ); + case TypeClass_CONSTANTS: + return get_type( + Reference< reflection::XConstantsTypeDescription >( + xType, UNO_QUERY_THROW ) ); + case TypeClass_SERVICE: + return get_type( + Reference< reflection::XServiceTypeDescription2 >( + xType, UNO_QUERY_THROW) ); + case TypeClass_SINGLETON: + return get_type( + Reference< reflection::XSingletonTypeDescription2 >( + xType, UNO_QUERY_THROW) ); + case TypeClass_MODULE: + // ignore these + return nullptr; + default: + throw RuntimeException( + "unexpected type " + xType->getName() ); + } +} + + +::System::Type ^ TypeEmitter::get_complete_struct( ::System::String ^ sName) +{ + struct_entry ^ pStruct = safe_cast< struct_entry ^>( + m_incomplete_structs[sName]); + if (pStruct) + { + complete_struct_type(pStruct); + } + //get_type will asked the module builder for the type or otherwise all known assemblies. + return get_type(sName, true); +} +TypeEmitter::~TypeEmitter() +{ + while (true) + { + ::System::Collections::IDictionaryEnumerator ^ enumerator = + m_incomplete_ifaces->GetEnumerator(); + if (! enumerator->MoveNext()) + break; + complete_iface_type( + safe_cast< iface_entry ^ >( enumerator->Value ) ); + } + + while (true) + { + ::System::Collections::IDictionaryEnumerator ^ enumerator = + m_incomplete_structs->GetEnumerator(); + if (! enumerator->MoveNext()) + break; + complete_struct_type( + safe_cast< struct_entry ^ >( enumerator->Value ) ); + } + + + while (true) + { + ::System::Collections::IDictionaryEnumerator ^ enumerator = + m_incomplete_services->GetEnumerator(); + if (! enumerator->MoveNext()) + break; + complete_service_type( + safe_cast< service_entry ^ >( enumerator->Value ) ); + } + + while (true) + { + ::System::Collections::IDictionaryEnumerator ^ enumerator = + m_incomplete_singletons->GetEnumerator(); + if (! enumerator->MoveNext()) + break; + complete_singleton_type( + safe_cast< singleton_entry ^ >( enumerator->Value ) ); + } +} + +TypeEmitter::TypeEmitter( + ::System::Reflection::Emit::ModuleBuilder ^ module_builder, + array< ::System::Reflection::Assembly^>^ extra_assemblies ) + : m_module_builder( module_builder ), + m_extra_assemblies( extra_assemblies ), + m_method_info_Type_GetTypeFromHandle( nullptr ), + m_type_Exception( nullptr ), + m_type_RuntimeException( nullptr ), + m_incomplete_ifaces( gcnew ::System::Collections::Hashtable() ), + m_incomplete_structs( gcnew ::System::Collections::Hashtable() ), + m_incomplete_services(gcnew ::System::Collections::Hashtable() ), + m_incomplete_singletons(gcnew ::System::Collections::Hashtable() ), + m_generated_structs( gcnew ::System::Collections::Hashtable() ) +{ + array< ::System::Type^>^ param_types = gcnew array< ::System::Type^> ( 1 ); + param_types[ 0 ] = ::System::RuntimeTypeHandle::typeid; + m_method_info_Type_GetTypeFromHandle = + ::System::Type::typeid + ->GetMethod( "GetTypeFromHandle", param_types ); +} + +::System::Collections::ArrayList ^ TypeEmitter::get_service_ctor_method_exceptions_reduced( + const Sequence > & seqExceptionsTd) +{ + if (seqExceptionsTd.getLength() == 0) + return gcnew ::System::Collections::ArrayList(); + + ::System::Collections::ArrayList ^ arTypes = gcnew ::System::Collections::ArrayList(); + for (int i = 0; i < seqExceptionsTd.getLength(); i++) + arTypes->Add(get_type(to_cts_name(seqExceptionsTd[i]->getName()), true)); + + int start = 0; + while (true) + { + bool bRemove = false; + for (int i = start; i < arTypes->Count; i++) + { + ::System::Type ^ t = safe_cast< ::System::Type^ >(arTypes[i]); + for (int j = 0; j < arTypes->Count; j++) + { + if (t->IsSubclassOf(safe_cast< ::System::Type^ >(arTypes[j]))) + { + arTypes->RemoveAt(i); + bRemove = true; + break; + } + } + if (bRemove) + break; + start++; + } + + if (bRemove == false) + break; + } + return arTypes; +} + + +css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > +resolveInterfaceTypedef( + const css::uno::Reference& type) +{ + Reference + xIfaceTd(type, UNO_QUERY); + + if (xIfaceTd.is()) + return xIfaceTd; + + Reference xIndTd( + type, UNO_QUERY_THROW); + + return resolveInterfaceTypedef(xIndTd->getReferencedType()); +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/climaker/climaker_share.h b/cli_ure/source/climaker/climaker_share.h new file mode 100644 index 000000000..ed7ab256a --- /dev/null +++ b/cli_ure/source/climaker/climaker_share.h @@ -0,0 +1,258 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +#using + +#include + +#include "osl/diagnose.h" +#include "com/sun/star/reflection/XConstantTypeDescription.hpp" +#include "com/sun/star/reflection/XConstantsTypeDescription.hpp" +#include "com/sun/star/reflection/XEnumTypeDescription.hpp" +#include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp" +#include "com/sun/star/reflection/XCompoundTypeDescription.hpp" +#include "com/sun/star/reflection/XServiceTypeDescription2.hpp" +#include "com/sun/star/reflection/XSingletonTypeDescription2.hpp" +#include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp" + + +namespace climaker +{ + + +extern bool g_bVerbose; + +ref struct Constants +{ + static ::System::String ^ sUnoVoid = "void"; + static ::System::String ^ sUnoType = "type"; + static ::System::String ^ sUnoAny = "any"; + static ::System::String ^ sUnoBool = "boolean"; + static ::System::String ^ sUnoByte = "byte"; + static ::System::String ^ sUnoChar = "char"; + static ::System::String ^ sUnoShort = "short"; + static ::System::String ^ sUnoUShort = "unsigned short"; + static ::System::String ^ sUnoLong = "long"; + static ::System::String ^ sUnoULong = "unsigned long"; + static ::System::String ^ sUnoHyper = "hyper"; + static ::System::String ^ sUnoUHyper = "unsigned hyper"; + static ::System::String ^ sUnoString = "string"; + static ::System::String ^ sUnoFloat = "float"; + static ::System::String ^ sUnoDouble = "double"; + static ::System::String ^ sUnoXInterface = "com.sun.star.uno.XInterface"; + static ::System::String ^ sBrackets = "[]"; + + static System::String^ sObject = "System.Object"; + static System::String^ sType = "System.Type"; + static System::String^ sUnoidl = "unoidl."; + static System::String^ sVoid = "System.Void"; + static System::String^ sAny = "uno.Any"; + static System::String^ sBoolean = "System.Boolean"; + static System::String^ sChar = "System.Char"; + static System::String^ sByte = "System.Byte"; + static System::String^ sInt16 = "System.Int16"; + static System::String^ sUInt16 = "System.UInt16"; + static System::String^ sInt32 = "System.Int32"; + static System::String^ sUInt32 = "System.UInt32"; + static System::String^ sInt64 = "System.Int64"; + static System::String^ sUInt64 = "System.UInt64"; + static System::String^ sString = "System.String"; + static System::String^ sSingle = "System.Single"; + static System::String^ sDouble = "System.Double"; + static System::String^ sComma = gcnew System::String(","); + +}; + + +inline ::System::String ^ ustring_to_String( OUString const & ustr ) +{ + return gcnew ::System::String( + reinterpret_cast(ustr.getStr()), 0, ustr.getLength()); +} + + +inline OUString String_to_ustring( ::System::String ^ str ) +{ + OSL_ASSERT( sizeof (wchar_t) == sizeof (sal_Unicode) ); + pin_ptr chars = PtrToStringChars( str ); + return OUString(reinterpret_cast(chars), str->Length); +} + +/* If the argument type is a typedef for an interface then the interface + type description is returned, otherwise an exception is thrown. +*/ +css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > +resolveInterfaceTypedef(const css::uno::Reference& type); + +static ::System::Reflection::MethodAttributes c_ctor_method_attr = +(::System::Reflection::MethodAttributes) + (::System::Reflection::MethodAttributes::Public | + ::System::Reflection::MethodAttributes::HideBySig | + ::System::Reflection::MethodAttributes::SpecialName | + ::System::Reflection::MethodAttributes::RTSpecialName + /* | xxx todo: ??? compiler does not know Instance ??? + ::System::Reflection::MethodAttributes::Instance*/); + + +ref class TypeEmitter : public ::System::IDisposable +{ + ::System::Reflection::Emit::ModuleBuilder ^ m_module_builder; + array< ::System::Reflection::Assembly^>^ m_extra_assemblies; + + ::System::Reflection::MethodInfo ^ m_method_info_Type_GetTypeFromHandle; + + ::System::Type ^ m_type_Exception; + ::System::Type ^ get_type_Exception(); + ::System::Type ^ m_type_RuntimeException; + ::System::Type ^ get_type_RuntimeException(); + + ::System::Reflection::Emit::CustomAttributeBuilder^ get_service_exception_attribute( + const css::uno::Reference & ctorDesc); + ::System::Reflection::Emit::CustomAttributeBuilder^ get_iface_method_exception_attribute( + const css::uno::Reference< css::reflection::XInterfaceMethodTypeDescription >& xMethod ); + ::System::Reflection::Emit::CustomAttributeBuilder^ get_exception_attribute( + const css::uno::Sequence >& seq_exceptionsTd ); +/* Creates ::System::Type object for UNO exceptions. The UNO exceptions are + obtained by + css::reflection::XServiceConstructorDescription::getExceptions + In a first step the respective CLI types are created. Then it is examined + if a Type represents a super class of another class. If so the Type of the + derived class is discarded. For example there are a uno RuntimeException and + a DeploymentException which inherits RuntimeException. Then only the cli Type + of the RuntimeException is returned. + The purpose of this function is to provide exceptions for which catch blocks + are generated in the service constructor code. + + It is always an instance of an ArrayList returned, even if the sequence argument + does not contain elements. + */ + ::System::Collections::ArrayList ^ get_service_ctor_method_exceptions_reduced( + const css::uno::Sequence< + css::uno::Reference > & seqExceptionsTd); + + + ref class iface_entry + { + public: + css::reflection::XInterfaceTypeDescription2 * m_xType; + ::System::Reflection::Emit::TypeBuilder ^ m_type_builder; + }; + ::System::Collections::Hashtable ^ m_incomplete_ifaces; + ::System::Type ^ complete_iface_type( iface_entry ^ entry ); + + ref class struct_entry + { + public: + css::reflection::XCompoundTypeDescription * m_xType; + ::System::Reflection::Emit::TypeBuilder ^ m_type_builder; + ::System::Type ^ m_base_type; + + array< ::System::String^>^ m_member_names; + array< ::System::Type^>^ m_param_types; + ::System::Reflection::ConstructorInfo ^ m_default_ctor; + ::System::Reflection::ConstructorInfo ^ m_ctor; + }; + ::System::Collections::Hashtable ^ m_incomplete_structs; + ::System::Type ^ complete_struct_type( struct_entry ^ entry ); + + /* returns the type for the name. If it is a struct then it may + complete the struct if not already done. This also refers to its + base types. + + @param sName + the full name of the type. + @return the type object for sName. Not necessarily a struct. + */ + ::System::Type ^ get_complete_struct( ::System::String ^ sName); + + ref class service_entry + { + public: + ::System::Reflection::Emit::TypeBuilder ^ m_type_builder; + css::reflection::XServiceTypeDescription2 * m_xType; + }; + ::System::Collections::Hashtable ^ m_incomplete_services; + ::System::Type ^ complete_service_type(service_entry ^ entry); + + ref class singleton_entry + { + public: + ::System::Reflection::Emit::TypeBuilder ^ m_type_builder; + css::reflection::XSingletonTypeDescription2 * m_xType; + }; + + + ::System::Collections::Hashtable ^ m_incomplete_singletons; + ::System::Type ^ complete_singleton_type(singleton_entry ^ entry); + + + ::System::Collections::Hashtable ^ m_generated_structs; + + ::System::Type ^ get_type( + ::System::String ^ cli_name, bool throw_exc ); + ::System::Type ^ get_type( + css::uno::Reference< + css::reflection::XConstantTypeDescription > const & xType ); + ::System::Type ^ get_type( + css::uno::Reference< + css::reflection::XConstantsTypeDescription > const & xType ); + ::System::Type ^ get_type( + css::uno::Reference< + css::reflection::XEnumTypeDescription > const & xType ); + /* returns the type for a struct or exception. In case of a polymorphic struct it may + return a ::uno::PolymorphicType (cli_basetypes.dll) only if the struct is already + complete. + */ + ::System::Type ^ get_type( + css::uno::Reference< + css::reflection::XCompoundTypeDescription > const & xType ); + ::System::Type ^ get_type( + css::uno::Reference< + css::reflection::XInterfaceTypeDescription2 > const & xType ); + ::System::Type ^ get_type( + css::uno::Reference< + css::reflection::XSingletonTypeDescription2 > const & xType ); + + /* + May return NULL if the service description is an obsolete. See + description of + com.sun.star.reflection.XServiceTypeDescription2.isSingleInterfaceBased + */ + ::System::Type ^ get_type( + css::uno::Reference< + css::reflection::XServiceTypeDescription2 > const & xType ); +public: + TypeEmitter( + ::System::Reflection::Emit::ModuleBuilder ^ module_builder, + array< ::System::Reflection::Assembly^>^ assemblies ); + // must be called to finish up uncompleted types + ~TypeEmitter(); + + ::System::Reflection::Assembly ^ type_resolve( + ::System::Object ^ sender, ::System::ResolveEventArgs ^ args ); + + ::System::Type ^ get_type( + css::uno::Reference< + css::reflection::XTypeDescription > const & xType ); +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/cliuno.snk b/cli_ure/source/cliuno.snk new file mode 100644 index 000000000..938f16939 Binary files /dev/null and b/cli_ure/source/cliuno.snk differ diff --git a/cli_ure/source/native/assembly.cxx b/cli_ure/source/native/assembly.cxx new file mode 100644 index 000000000..75e33e8c7 --- /dev/null +++ b/cli_ure/source/native/assembly.cxx @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +[assembly:System::Reflection::AssemblyProduct("CLI-UNO Language Binding")]; +[assembly:System::Reflection::AssemblyDescription("CLI-UNO Helper Library")]; +[assembly:System::Reflection::AssemblyDelaySign(true)]; +[assembly:System::Reflection::AssemblyCompany("OpenOffice.org")]; +[assembly:System::Reflection::AssemblyVersion("@CLI_CPPUHELPER_NEW_VERSION@")]; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/native/cli_cppuhelper_config b/cli_ure/source/native/cli_cppuhelper_config new file mode 100644 index 000000000..627a3a564 --- /dev/null +++ b/cli_ure/source/native/cli_cppuhelper_config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/cli_ure/source/native/native_bootstrap.cxx b/cli_ure/source/native/native_bootstrap.cxx new file mode 100644 index 000000000..f26a634c2 --- /dev/null +++ b/cli_ure/source/native/native_bootstrap.cxx @@ -0,0 +1,297 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +#include "native_share.h" + +#include "rtl/bootstrap.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "cppuhelper/bootstrap.hxx" +#include +#include +#define WIN32_LEAN_AND_MEAN +#include +#include + +#define INSTALL_PATH L"Software\\LibreOffice\\UNO\\InstallPath" +#define UNO_PATH L"UNO_PATH" + +namespace { + +/* Gets the installation path from the Windows Registry for the specified + registry key. + + @param hroot open handle to predefined root registry key + @param subKeyName name of the subkey to open + + @return the installation path or nullptr, if no installation was found or + if an error occurred +*/ +WCHAR* getPathFromRegistryKey( HKEY hroot, LPCWSTR subKeyName ) +{ + // open the specified registry key + HKEY hkey; + if ( RegOpenKeyExW( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS ) + return nullptr; + + struct CloseKeyGuard { + HKEY m_hkey; + ~CloseKeyGuard() { RegCloseKey( m_hkey ); } + } aCloseKeyGuard{hkey}; + + // find the type and size of the default value + DWORD type; + DWORD size; + if ( RegQueryValueExW( hkey, nullptr, nullptr, &type, nullptr, &size ) != ERROR_SUCCESS ) + return nullptr; + + // get memory to hold the default value + std::unique_ptr data(new WCHAR[size]); + + // read the default value + if ( RegQueryValueExW( hkey, nullptr, nullptr, &type, reinterpret_cast(data.get()), &size ) != ERROR_SUCCESS ) + return nullptr; + + return data.release(); +} + +/* Returns the path to the program folder of the brand layer, + for example C:/Program Files/LibreOffice/program + This path is either obtained from the environment variable UNO_PATH + or the registry item "Software\\LibreOffice\\UNO\\InstallPath" + either in HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE + The return value must be freed with delete[] +*/ +WCHAR* getInstallPath() +{ + std::unique_ptr szInstallPath; + + DWORD cChars = GetEnvironmentVariableW(UNO_PATH, nullptr, 0); + if (cChars > 0) + { + szInstallPath.reset(new WCHAR[cChars]); + cChars = GetEnvironmentVariableW(UNO_PATH, szInstallPath.get(), cChars); + // If PATH is not set then it is no error + if (cChars == 0) + return nullptr; + } + + if (! szInstallPath) + { + szInstallPath.reset(getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH )); + if (! szInstallPath) + { + // read the key's default value from HKEY_LOCAL_MACHINE + szInstallPath.reset(getPathFromRegistryKey( HKEY_LOCAL_MACHINE, INSTALL_PATH )); + } + } + return szInstallPath.release(); +} + +/* We extend the path to contain the install folder, + so that components can use osl_loadModule with arguments, such as + "reg3.dll". That is, the arguments are only the library names. +*/ +void extendPath(LPCWSTR szPath) +{ + if (!szPath) + return; + + std::unique_ptr sEnvPath; + DWORD cChars = GetEnvironmentVariableW(L"PATH", nullptr, 0); + if (cChars > 0) + { + sEnvPath.reset(new WCHAR[cChars]); + cChars = GetEnvironmentVariableW(L"PATH", sEnvPath.get(), cChars); + // If PATH is not set then it is no error + if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) + return; + } + // Prepare the new PATH. Add the directory at the front. + // Note also adding ';' + std::unique_ptr sNewPath(new WCHAR[lstrlenW(sEnvPath.get()) + lstrlenW(szPath) + 2]); + lstrcpyW(sNewPath.get(), szPath); + if (lstrlenW(sEnvPath.get())) + { + lstrcatW(sNewPath.get(), L";"); + lstrcatW(sNewPath.get(), sEnvPath.get()); + } + SetEnvironmentVariableW(L"PATH", sNewPath.get()); +} + +HMODULE loadFromPath(LPCSTR sLibName) +{ + if (!sLibName) + return nullptr; + + // Convert the ansi file name to wchar_t* + int size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sLibName, -1, nullptr, 0); + if (size == 0) + return nullptr; + std::unique_ptr wsLibName(new WCHAR[size]); + if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sLibName, -1, wsLibName.get(), size)) + return nullptr; + + std::unique_ptr szPath(getInstallPath()); + if (!szPath) + return nullptr; + + extendPath(szPath.get()); + + std::unique_ptr szFullPath(new WCHAR[lstrlenW(wsLibName.get()) + lstrlenW(szPath.get()) + 2]); + lstrcpyW(szFullPath.get(), szPath.get()); + lstrcatW(szFullPath.get(), L"\\"); + lstrcatW(szFullPath.get(), wsLibName.get()); + HMODULE handle = LoadLibraryW(szFullPath.get()); + return handle; +} + +/* Hook for delayed loading of libraries which this library is linked with. + This is a failure hook. That is, it is only called when the loading of + a library failed. It will be called when loading of cppuhelper failed. + Because we extend the PATH to the install folder while this function is + executed (see extendPath), all other libraries are found. +*/ +extern "C" FARPROC WINAPI delayLoadHook( + unsigned int dliNotify, + PDelayLoadInfo pdli + ) +{ + if (dliNotify == dliFailLoadLib) + { + HANDLE h = loadFromPath(pdli->szDll); + return reinterpret_cast(h); + } + return nullptr; +} +} + +ExternC +const PfnDliHook __pfnDliFailureHook2 = delayLoadHook; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace uno +{ +namespace util +{ + +/** Bootstrapping native UNO. + + Bootstrapping requires the existence of many libraries which are contained + in an URE installation. To find and load these libraries the Windows + registry keys HKEY_CURRENT_USER\Software\LibreOffice\Layer\URE\1 + and HKEY_LOCAL_MACHINE\Software\LibreOffice\Layer\URE\1 are examined. + These contain a named value UREINSTALLLOCATION which holds a path to the URE + installation folder. +*/ +public ref class Bootstrap sealed +{ + inline Bootstrap() {} + +public: + + /** Bootstraps the initial component context from a native UNO installation. + + @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext() + */ + static ::unoidl::com::sun::star::uno::XComponentContext ^ + defaultBootstrap_InitialComponentContext(); + + /** Bootstraps the initial component context from a native UNO installation. + + @param ini_file + a file URL of an ini file, e.g. uno.ini/unorc. (The ini file must + reside next to the cppuhelper library) + @param bootstrap_parameters + bootstrap parameters (maybe null) + + @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext() + */ + static ::unoidl::com::sun::star::uno::XComponentContext ^ + defaultBootstrap_InitialComponentContext( + ::System::String ^ ini_file, + ::System::Collections::IDictionaryEnumerator ^ + bootstrap_parameters ); + + /** Bootstraps the initial component context from a native UNO installation. + + @see cppuhelper/bootstrap.hxx:bootstrap() + */ + static ::unoidl::com::sun::star::uno::XComponentContext ^ + bootstrap(); +}; + + +::unoidl::com::sun::star::uno::XComponentContext ^ +Bootstrap::defaultBootstrap_InitialComponentContext( + ::System::String ^ ini_file, + ::System::Collections::IDictionaryEnumerator ^ bootstrap_parameters ) +{ + if (nullptr != bootstrap_parameters) + { + bootstrap_parameters->Reset(); + while (bootstrap_parameters->MoveNext()) + { + OUString key( + String_to_ustring( safe_cast< ::System::String ^ >( + bootstrap_parameters->Key ) ) ); + OUString value( + String_to_ustring( safe_cast< ::System::String ^ >( + bootstrap_parameters->Value ) ) ); + + ::rtl::Bootstrap::set( key, value ); + } + } + + // bootstrap native uno + Reference< XComponentContext > xContext; + if (nullptr == ini_file) + { + xContext = ::cppu::defaultBootstrap_InitialComponentContext(); + } + else + { + xContext = ::cppu::defaultBootstrap_InitialComponentContext( + String_to_ustring( safe_cast< ::System::String ^ >( ini_file ) ) ); + } + + return safe_cast< ::unoidl::com::sun::star::uno::XComponentContext ^ >( + to_cli( xContext ) ); +} + + +::unoidl::com::sun::star::uno::XComponentContext ^ +Bootstrap::defaultBootstrap_InitialComponentContext() +{ + return defaultBootstrap_InitialComponentContext( nullptr, nullptr ); +} + +::unoidl::com::sun::star::uno::XComponentContext ^ Bootstrap::bootstrap() +{ + Reference xContext = ::cppu::bootstrap(); + return safe_cast< ::unoidl::com::sun::star::uno::XComponentContext ^ >( + to_cli( xContext ) ); + +} + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/native/native_share.h b/cli_ure/source/native/native_share.h new file mode 100644 index 000000000..f733d2558 --- /dev/null +++ b/cli_ure/source/native/native_share.h @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +#using "cli_ure.dll" +#using "cli_uretypes.dll" + +#include "rtl/ustring.hxx" +#include +#include "uno/mapping.hxx" + +#include + + +namespace uno +{ +namespace util +{ + + +inline ::System::String ^ ustring_to_String( OUString const & ustr ) +{ + return gcnew ::System::String( + reinterpret_cast(ustr.getStr()), 0, ustr.getLength()); +} + +inline OUString String_to_ustring( ::System::String ^ str ) +{ + OSL_ASSERT( sizeof (wchar_t) == sizeof (sal_Unicode) ); + pin_ptr chars = PtrToStringChars( str ); + return OUString(reinterpret_cast(chars), str->Length); +} + +template< typename T > +inline ::System::Object ^ to_cli( + css::uno::Reference< T > const & x ) +{ + css::uno::Mapping mapping( + CPPU_CURRENT_LANGUAGE_BINDING_NAME, UNO_LB_CLI ); + OSL_ASSERT( mapping.is() ); + if (! mapping.is()) + { + throw css::uno::RuntimeException( + "cannot get mapping from C++ to CLI!", + css::uno::Reference< + css::uno::XInterface >() ); + } + + intptr_t intptr = + reinterpret_cast< intptr_t >( + mapping.mapInterface( x.get(), cppu::UnoType::get() ) ); + ::System::Runtime::InteropServices::GCHandle ^ handle = ::System::Runtime::InteropServices::GCHandle::FromIntPtr(::System::IntPtr(intptr)); + ::System::Object ^ ret = handle->Target; + handle->Free(); + return ret; +} + +template< typename T > +inline void to_uno( + css::uno::Reference< T > * pRet, ::System::Object ^ x ) +{ + css::uno::Mapping mapping( + UNO_LB_CLI, CPPU_CURRENT_LANGUAGE_BINDING_NAME ); + OSL_ASSERT( mapping.is() ); + if (! mapping.is()) + { + throw css::uno::RuntimeException( + "cannot get mapping from CLI to C++!", + css::uno::Reference< + css::uno::XInterface >() ); + } + + ::System::Runtime::InteropServices::GCHandle handle( + ::System::Runtime::InteropServices::GCHandle::Alloc( x ) ); + T * ret = 0; + mapping.mapInterface( + reinterpret_cast< void ** >( &ret ), + reinterpret_cast< void * >( + ::System::Runtime::InteropServices::GCHandle::op_Explicit( handle ) +#if defined _WIN64 + .ToInt64() +#elif defined _WIN32 + .ToInt32() +#else +#error ERROR: either _WIN64 or _WIN32 must be defined + ERROR: either _WIN64 or _WIN32 must be defined +#endif + ), + cppu::UnoType::get() ); + handle.Free(); + pRet->set( ret, SAL_NO_ACQUIRE /* takeover ownership */ ); +} + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/native/path.cxx b/cli_ure/source/native/path.cxx new file mode 100644 index 000000000..6fae51314 --- /dev/null +++ b/cli_ure/source/native/path.cxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +#include "sal/config.h" + +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#include + +#include "sal/types.h" + +namespace cli_ure { + +SAL_DLLPUBLIC_EXPORT WCHAR * filename(WCHAR * path) { + WCHAR * f = path; + for (WCHAR * p = path;;) { + switch (*p++) { + case L'\0': + return f; + case L'\\': + f = p; + break; + } + } +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/scripts/increment_version.pl b/cli_ure/source/scripts/increment_version.pl new file mode 100644 index 000000000..df0c677a8 --- /dev/null +++ b/cli_ure/source/scripts/increment_version.pl @@ -0,0 +1,273 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you 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 . +# + +use warnings; +use strict; +use diagnostics; + +sub trim; +sub readIncVersions($); +sub processLine($$); +sub checkName($); +sub incrementNewVersion($); +sub incrementOldVersion($); +sub incrementPolicyVersion($); +my $usage = +"The tool increments the minor version of assemblies and the major version of ". +"the respective policy files. This is only done if new uno types have been added since". +"the last product update. This information is obtained from the file which is passed as ". +"argument changedTypes. The names in the version file must have a particular form. ". +"They must end on one of following terms: NEW_VERSION, OLD_VERSION, POLICY_VERSION\n". +"If no new published types have been added then no output, argument newVersions, is written". +"Usage is: \n increment_version.pl oldVersions incVersions newVersions changedTypes\n\n". +"oldVersion: Contains name value pairs, which are used for forming the config files of ". +"the policy assemblies, for building the assemblies. \n\n". +"incVersions: File containing the names of which the versions are to be incremented. ". +"Every line may only contain one name. The names must exactly match those from the ". +"oldVersion file.\n\n". +"newVersions: Contains all entries from oldVersions, but the values of the names,". +"which occur in selection, have been incremented.\n\n". +"changedTypes: File that contains the information if new published types have been added ". +"since the last product update.\n\n" ; + +my $sNameForm = +"The names must end on one of these names: NEW_VERSION, OLD_VERSION, POLICY_VERSION\n". +"For example, valid names are: \n". +"CLI_URETYPES_NEW_VERSION\nCLI_URETYPES_OLD_VERSION\nCLI_URETYPES_POLICY_VERSION\n"; + +if (scalar @ARGV < 3) { + print $usage; + exit -1; +} + +-e "$ARGV[0]" or die "Error: wrong arguments. \n".$usage; +-e "$ARGV[1]" or die "Error: wrong arguments. \n".$usage; +#-e "$ARGV[3]" or die "Error: wrong arguments. \n".$usage; + +# DISABLED: always increment +#check if new types have been added since last release. +#If not, then there is nothing to be done. +#read in oldVersions line by line and apply the increment operation +#open TYPES, "$ARGV[3]" or die "Cannot open to $ARGV[3] $!"; + +my $newTypes; + +#We look for the line that contains the number of new types +#while() +#{ +# if (/New and published types/i) +# { +# $_ =~ /=\s*(\d+)/; +# if ( ! defined $1) +# { +# print "\n###$ARGV[3] contains an invalid entry for 'New and published types'. \n\n"; +# exit -1; +# } +# $newTypes = $1; +# } +#} + +#Check if changeTypes contained the line we are looking for +#if (! defined $newTypes) +#{ +# print "\n###$ARGV[3] does not contain entry about the new types ". +# "or we are looking for the wrong string! \n\n"; +# exit -1; +#} + +#if ( $newTypes == 0) +#{ +# print "\nNo new UNO types since las product update.\n"; +# exit 0; +#} +#else +#{ +# print "\nNew UNO types were added since last release. The version will be increased.\n\n"; +#} + +#read in incVersions in a list +my @incVersions = readIncVersions($ARGV[1]); +#print "@incVersions"; + +#read in oldVersions line by line and apply the increment operation +open OLDVERSION, "$ARGV[0]" or die "Cannot open to $ARGV[0] $!"; + +#open file we want to write to +open NEWVERSION, "> $ARGV[2]" or die "Cannot write to $ARGV[2] $!"; + +print NEWVERSION processLine($_, @incVersions) while(); + +close NEWVERSION; +close OLDVERSION; + +exit 0; + +sub processLine($$) +{ + my $line = $_[0]; + #skip empty lines + my $trimmed; + return $line if (length($trimmed = trim($line)) == 0); + #Skip comment symbol: # + return $line if ($trimmed =~ /^#/); + + #Get the left part of '=' + my $i = index($line, "="); + if( $i == -1) + { + print "Error: No '=' found in line:,: \n $line \n"; + exit -1; + } + my $name = substr($line, 0, $i); + $name = trim($name); + #We do not check the names here because the file can contain + #other names, e.g. CLI_URETYPES_POLICY_ASSEMBLY + if (length($name) == 0) { + print "Wrong line in $ARGV[0]\n", $sNameForm; + exit -1; + } + my $value = substr($line, $i + 1); + $value = trim($value); + + #Check if the entry shall be incremented, this information is in the second + #argument + my $found; + for(@incVersions) { + if ($_ eq $name) { + $found = 1; + last; + } + } + if ( ! defined($found)) { + return $line; + } + + #Check if the name represents a version we need to change + if ($name =~ /NEW_VERSION$/) + { + $value = incrementNewVersion($value); + } + elsif ($name =~ /OLD_VERSION$/) + { + $value = incrementOldVersion($value); + } + elsif ($name =~ /POLICY_VERSION$/) + { + $value = incrementPolicyVersion($value); + } + else + { + #other name which we ignore + return $line; + } + return "${name}=${value}\n"; +} + +#The value of a new version has the form x.x.x.x +#We increment the third position from the left. +#Te argument must already be trimmed. +sub incrementNewVersion($) +{ + my @parts = split /\./,$_[0]; + if (scalar @parts != 4) + { + print "Error, no valid version given in $ARGV[0]\n. A 'new version' has four parts."; + exit -1; + } + $parts[2]++; + #build the version string and return + return "$parts[0].$parts[1].$parts[2].$parts[3]"; +} + +#The value of a new version has the form x.x.x.x-x.x.x.x +#We increment the third position of the second part. +#Te argument must already be trimmed. +sub incrementOldVersion($) +{ + my @parts = split /[\.-]/,$_[0]; + if (scalar @parts != 8) + { + print "Error, no valid version given in $ARGV[0]\n. A 'old version' has the form +x.x.x.x-x.x.x.x\n."; + exit -1; + } + $parts[6]++; + return "$parts[0].$parts[1].$parts[2].$parts[3]-$parts[4].$parts[5].$parts[6].$parts[7]"; + return $_[0]; +} + +sub incrementPolicyVersion($) +{ + my @parts = split /\./,$_[0]; + if (scalar @parts != 4) + { + print "Error, no valid version given in $ARGV[0]\n. A 'policy version' has four parts."; + exit -1; + } + $parts[0]++; + #build the version string and return + return "$parts[0].$parts[1].$parts[2].$parts[3]"; +} + + +sub readIncVersions($) +{ + open INC, $_[0] or die "Could not open $_[0] $!"; + my $arg = $_[0]; + my @names; + + while() + { + chomp; + #Skip empty lines + my $line; + if (length($line = trim($_)) == 0) { + next; + } + #Skip comment symbol: # + if ($line =~ /^#/) { + next; + } + if (!checkName($line)) { + print "Wrong entry in file $_[0]\n", $sNameForm; + exit -1; + } + push @names, $line; + } + print "No entries found in $arg\n" if(scalar @names == 0); + return @names; +} + +#The argument must already be trimmed +#returns 1 if ok +sub checkName($) +{ + my $name = $_[0]; + if ( $name !~/NEW_VERSION$|OLD_VERSION$|POLICY_VERSION$/) { + return 0; + } + return 1; +} + +sub trim($) +{ + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} diff --git a/cli_ure/source/scripts/subst_template.pl b/cli_ure/source/scripts/subst_template.pl new file mode 100644 index 000000000..b3f90fef6 --- /dev/null +++ b/cli_ure/source/scripts/subst_template.pl @@ -0,0 +1,124 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you 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 . +# + +use warnings; +use strict; +use diagnostics; + +sub trim; +sub readRedirectionValues($); + +my $usage = + "Usage is: \n subst_template.pl configTemplate redirections policyConfig + + configTemplate: The config file which is used for the policy assembly. It + contains place holders for the binding redirection. + + redirections: file containing the values for oldVersion and newVersion tags + which are used in the BindingRedirect element of the config files. + + policyConfig: Name of the file in which we want to write the config file. +"; + + +if (scalar @ARGV < 3) { + print $usage; + exit -1; +} + + +my %redirectionValue = readRedirectionValues($ARGV[1]); +#print "|$_| |$redirectionValue{$_}|\n", for keys %redirectionValue; + + +#Read config file in which we will replace the versions +$/ = undef; +open TEMPLATE, $ARGV[0] or die $!; +my $templ =