1*54c06456SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*54c06456SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*54c06456SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*54c06456SAndrew Rist  * distributed with this work for additional information
6*54c06456SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*54c06456SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*54c06456SAndrew Rist  * "License"); you may not use this file except in compliance
9*54c06456SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*54c06456SAndrew Rist  *
11*54c06456SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*54c06456SAndrew Rist  *
13*54c06456SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*54c06456SAndrew Rist  * software distributed under the License is distributed on an
15*54c06456SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*54c06456SAndrew Rist  * KIND, either express or implied.  See the License for the
17*54c06456SAndrew Rist  * specific language governing permissions and limitations
18*54c06456SAndrew Rist  * under the License.
19*54c06456SAndrew Rist  *
20*54c06456SAndrew Rist  *************************************************************/
21*54c06456SAndrew Rist 
22*54c06456SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_cli_ure.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "climaker_share.h"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "rtl/string.hxx"
30cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
31cdf0e10cSrcweir #include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
32cdf0e10cSrcweir #include "com/sun/star/reflection/XStructTypeDescription.hpp"
33cdf0e10cSrcweir #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
34cdf0e10cSrcweir #include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
35cdf0e10cSrcweir #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription.hpp"
36cdf0e10cSrcweir #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
37cdf0e10cSrcweir #include <vector>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir using namespace ::System::Reflection;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir using namespace ::rtl;
42cdf0e10cSrcweir using namespace ::com::sun::star;
43cdf0e10cSrcweir using namespace ::com::sun::star::uno;
44cdf0e10cSrcweir 
45cdf0e10cSrcweir namespace climaker
46cdf0e10cSrcweir {
47cdf0e10cSrcweir System::String* mapUnoPolymorphicName(System::String* unoName);
48cdf0e10cSrcweir //------------------------------------------------------------------------------
to_cts_name(OUString const & uno_name)49cdf0e10cSrcweir static inline ::System::String * to_cts_name(
50cdf0e10cSrcweir     OUString const & uno_name )
51cdf0e10cSrcweir {
52cdf0e10cSrcweir     OUStringBuffer buf( 7 + uno_name.getLength() );
53cdf0e10cSrcweir     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unoidl.") );
54cdf0e10cSrcweir     buf.append( uno_name );
55cdf0e10cSrcweir     return ustring_to_String( buf.makeStringAndClear() );
56cdf0e10cSrcweir }
57cdf0e10cSrcweir 
58cdf0e10cSrcweir //------------------------------------------------------------------------------
to_cli_constant(Any const & value)59cdf0e10cSrcweir static inline ::System::Object * to_cli_constant( Any const & value )
60cdf0e10cSrcweir {
61cdf0e10cSrcweir     switch (value.getValueTypeClass())
62cdf0e10cSrcweir     {
63cdf0e10cSrcweir     case TypeClass_CHAR:
64cdf0e10cSrcweir         return __box
65cdf0e10cSrcweir             ((::System::Char) *reinterpret_cast< sal_Unicode const * >(
66cdf0e10cSrcweir                 value.getValue() ));
67cdf0e10cSrcweir     case TypeClass_BOOLEAN:
68cdf0e10cSrcweir         return __box
69cdf0e10cSrcweir             ((::System::Boolean)
70cdf0e10cSrcweir              sal_False != *reinterpret_cast< sal_Bool const * >(
71cdf0e10cSrcweir                  value.getValue() ));
72cdf0e10cSrcweir     case TypeClass_BYTE:
73cdf0e10cSrcweir         return __box
74cdf0e10cSrcweir             ((::System::Byte) *reinterpret_cast< sal_Int8 const * >(
75cdf0e10cSrcweir                 value.getValue() ));
76cdf0e10cSrcweir     case TypeClass_SHORT:
77cdf0e10cSrcweir         return __box
78cdf0e10cSrcweir             ((::System::Int16) *reinterpret_cast< sal_Int16 const * >(
79cdf0e10cSrcweir                 value.getValue() ));
80cdf0e10cSrcweir     case TypeClass_UNSIGNED_SHORT:
81cdf0e10cSrcweir         return __box
82cdf0e10cSrcweir             ((::System::UInt16) *reinterpret_cast< sal_uInt16 const * >(
83cdf0e10cSrcweir                 value.getValue() ));
84cdf0e10cSrcweir     case TypeClass_LONG:
85cdf0e10cSrcweir         return __box
86cdf0e10cSrcweir             ((::System::Int32) *reinterpret_cast< sal_Int32 const * >(
87cdf0e10cSrcweir                 value.getValue() ));
88cdf0e10cSrcweir     case TypeClass_UNSIGNED_LONG:
89cdf0e10cSrcweir         return __box
90cdf0e10cSrcweir             ((::System::UInt32) *reinterpret_cast< sal_uInt32 const * >(
91cdf0e10cSrcweir                 value.getValue() ));
92cdf0e10cSrcweir     case TypeClass_HYPER:
93cdf0e10cSrcweir         return __box
94cdf0e10cSrcweir             ((::System::Int64) *reinterpret_cast< sal_Int64 const * >(
95cdf0e10cSrcweir                 value.getValue() ));
96cdf0e10cSrcweir     case TypeClass_UNSIGNED_HYPER:
97cdf0e10cSrcweir         return __box
98cdf0e10cSrcweir             ((::System::UInt64) *reinterpret_cast< sal_uInt64 const * >(
99cdf0e10cSrcweir                 value.getValue() ));
100cdf0e10cSrcweir     case TypeClass_FLOAT:
101cdf0e10cSrcweir         return __box
102cdf0e10cSrcweir             ((::System::Single) *reinterpret_cast< float const * >(
103cdf0e10cSrcweir                 value.getValue() ));
104cdf0e10cSrcweir     case TypeClass_DOUBLE:
105cdf0e10cSrcweir         return __box
106cdf0e10cSrcweir             ((::System::Double) *reinterpret_cast< double const * >(
107cdf0e10cSrcweir                 value.getValue() ));
108cdf0e10cSrcweir     default:
109cdf0e10cSrcweir         throw RuntimeException(
110cdf0e10cSrcweir             OUSTR("unexpected constant type ") +
111cdf0e10cSrcweir             value.getValueType().getTypeName(),
112cdf0e10cSrcweir             Reference< XInterface >() );
113cdf0e10cSrcweir     }
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir //------------------------------------------------------------------------------
emit_ldarg(Emit::ILGenerator * code,::System::Int32 index)117cdf0e10cSrcweir static inline void emit_ldarg( Emit::ILGenerator * code, ::System::Int32 index )
118cdf0e10cSrcweir {
119cdf0e10cSrcweir     switch (index)
120cdf0e10cSrcweir     {
121cdf0e10cSrcweir     case 0:
122cdf0e10cSrcweir         code->Emit( Emit::OpCodes::Ldarg_0 );
123cdf0e10cSrcweir         break;
124cdf0e10cSrcweir     case 1:
125cdf0e10cSrcweir         code->Emit( Emit::OpCodes::Ldarg_1 );
126cdf0e10cSrcweir         break;
127cdf0e10cSrcweir     case 2:
128cdf0e10cSrcweir         code->Emit( Emit::OpCodes::Ldarg_2 );
129cdf0e10cSrcweir         break;
130cdf0e10cSrcweir     case 3:
131cdf0e10cSrcweir         code->Emit( Emit::OpCodes::Ldarg_3 );
132cdf0e10cSrcweir         break;
133cdf0e10cSrcweir     default:
134cdf0e10cSrcweir         if (index < 0x100)
135cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_S, (::System::Byte) index );
136cdf0e10cSrcweir         else if (index < 0x8000)
137cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_S, (::System::Int16) index );
138cdf0e10cSrcweir         else
139cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg, index );
140cdf0e10cSrcweir         break;
141cdf0e10cSrcweir     }
142cdf0e10cSrcweir }
143cdf0e10cSrcweir 
polymorphicStructNameToStructName(::System::String ** sPolyName)144cdf0e10cSrcweir void polymorphicStructNameToStructName(::System::String ** sPolyName)
145cdf0e10cSrcweir {
146cdf0e10cSrcweir     if ((*sPolyName)->EndsWith(S">") == false)
147cdf0e10cSrcweir         return;
148cdf0e10cSrcweir 
149cdf0e10cSrcweir     int index = (*sPolyName)->IndexOf('<');
150cdf0e10cSrcweir     OSL_ASSERT(index != -1);
151cdf0e10cSrcweir     *sPolyName = (*sPolyName)->Substring(0, index);
152cdf0e10cSrcweir }
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 
mapUnoTypeName(System::String * typeName)155cdf0e10cSrcweir System::String* mapUnoTypeName(System::String * typeName)
156cdf0e10cSrcweir {
157cdf0e10cSrcweir 	::System::Text::StringBuilder* buf= new System::Text::StringBuilder();
158cdf0e10cSrcweir 	::System::String * sUnoName = ::System::String::Copy(typeName);
159cdf0e10cSrcweir     //determine if the type is a sequence and its dimensions
160cdf0e10cSrcweir     int dims= 0;
161cdf0e10cSrcweir     if (typeName->StartsWith(S"["))//if (usUnoName[0] == '[')
162cdf0e10cSrcweir     {
163cdf0e10cSrcweir         int index= 1;
164cdf0e10cSrcweir         while (true)
165cdf0e10cSrcweir         {
166cdf0e10cSrcweir             if (typeName->get_Chars(index++) == ']')//if (usUnoName[index++] == ']')
167cdf0e10cSrcweir                 dims++;
168cdf0e10cSrcweir             if (typeName->get_Chars(index++) != '[')//usUnoName[index++] != '[')
169cdf0e10cSrcweir                 break;
170cdf0e10cSrcweir         }
171cdf0e10cSrcweir         sUnoName = sUnoName->Substring(index - 1);//usUnoName = usUnoName.copy(index - 1);
172cdf0e10cSrcweir     }
173cdf0e10cSrcweir 	if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoBool)))
174cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sBoolean));
175cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoChar)))
176cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sChar));
177cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoByte)))
178cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sByte));
179cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoShort)))
180cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sInt16));
181cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoUShort)))
182cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sUInt16));
183cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoLong)))
184cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sInt32));
185cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoULong)))
186cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sUInt32));
187cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoHyper)))
188cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sInt64));
189cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoUHyper)))
190cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sUInt64));
191cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoFloat)))
192cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sSingle));
193cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoDouble)))
194cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sDouble));
195cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoString)))
196cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sString));
197cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoVoid)))
198cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sVoid));
199cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoType)))
200cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sType));
201cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoXInterface)))
202cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sObject));
203cdf0e10cSrcweir     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoAny)))
204cdf0e10cSrcweir     {
205cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sAny));
206cdf0e10cSrcweir     }
207cdf0e10cSrcweir     else
208cdf0e10cSrcweir     {
209cdf0e10cSrcweir         //put "unoidl." at the beginning
210cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sUnoidl));
211cdf0e10cSrcweir         buf->Append(mapUnoPolymorphicName(sUnoName));
212cdf0e10cSrcweir     }
213cdf0e10cSrcweir     // apend []
214cdf0e10cSrcweir     for (;dims--;)
215cdf0e10cSrcweir         buf->Append(const_cast<System::String*>(Constants::sBrackets));
216cdf0e10cSrcweir 
217cdf0e10cSrcweir     return buf->ToString();
218cdf0e10cSrcweir }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir 
221cdf0e10cSrcweir /** For example, there is a uno type
222cdf0e10cSrcweir     com.sun.star.Foo<char, long>.
223cdf0e10cSrcweir     The values in the type list
224cdf0e10cSrcweir     are uno types and are replaced by cli types, such as System.Char,
225cdf0e10cSrcweir     System.Int32, etc.
226cdf0e10cSrcweir 
227cdf0e10cSrcweir 	Strings can be as complicated as this
228cdf0e10cSrcweir 	test.MyStruct<char,test.MyStruct<long, []string>>
229cdf0e10cSrcweir  */
mapUnoPolymorphicName(System::String * unoName)230cdf0e10cSrcweir System::String* mapUnoPolymorphicName(System::String* unoName)
231cdf0e10cSrcweir {
232cdf0e10cSrcweir     int index = unoName->IndexOf('<');
233cdf0e10cSrcweir     if (index == -1)
234cdf0e10cSrcweir         return unoName;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir     System::Text::StringBuilder * builder =
237cdf0e10cSrcweir         new System::Text::StringBuilder(unoName->Substring(0, index +1 ));
238cdf0e10cSrcweir 
239cdf0e10cSrcweir 	//Find the first occurrence of ','
240cdf0e10cSrcweir 	//If the parameter is a polymorphic struct then we neede to ignore everything
241cdf0e10cSrcweir 	//between the brackets because it can also contain commas
242cdf0e10cSrcweir     //get the type list within < and >
243cdf0e10cSrcweir 	int endIndex = unoName->Length - 1;
244cdf0e10cSrcweir 	index++;
245cdf0e10cSrcweir 	int cur = index;
246cdf0e10cSrcweir 	int countParams = 0;
247cdf0e10cSrcweir 	while (cur <= endIndex)
248cdf0e10cSrcweir 	{
249cdf0e10cSrcweir 		System::Char c = unoName->Chars[cur];
250cdf0e10cSrcweir 		if (c == ',' || c == '>')
251cdf0e10cSrcweir 		{
252cdf0e10cSrcweir 			//insert a comma if needed
253cdf0e10cSrcweir 			if (countParams != 0)
254cdf0e10cSrcweir 				builder->Append(S",");
255cdf0e10cSrcweir 			countParams++;
256cdf0e10cSrcweir 			System::String * sParam = unoName->Substring(index, cur - index);
257cdf0e10cSrcweir 			//skip the comma
258cdf0e10cSrcweir 			cur++;
259cdf0e10cSrcweir 			//the the index to the beginning of the next param
260cdf0e10cSrcweir 			index = cur;
261cdf0e10cSrcweir 			builder->Append(mapUnoTypeName(sParam));
262cdf0e10cSrcweir 		}
263cdf0e10cSrcweir 		else if (c == '<')
264cdf0e10cSrcweir 		{
265cdf0e10cSrcweir 			cur++;
266cdf0e10cSrcweir 			//continue until the matching '>'
267cdf0e10cSrcweir 			int numNested = 0;
268cdf0e10cSrcweir 			for (;;cur++)
269cdf0e10cSrcweir 			{
270cdf0e10cSrcweir 				System::Char curChar = unoName->Chars[cur];
271cdf0e10cSrcweir 				if (curChar == '<')
272cdf0e10cSrcweir 				{
273cdf0e10cSrcweir 					numNested ++;
274cdf0e10cSrcweir 				}
275cdf0e10cSrcweir 				else if (curChar == '>')
276cdf0e10cSrcweir 				{
277cdf0e10cSrcweir 					if (numNested > 0)
278cdf0e10cSrcweir 						numNested--;
279cdf0e10cSrcweir 					else
280cdf0e10cSrcweir 						break;
281cdf0e10cSrcweir 				}
282cdf0e10cSrcweir 			}
283cdf0e10cSrcweir 		}
284cdf0e10cSrcweir 		cur++;
285cdf0e10cSrcweir 	}
286cdf0e10cSrcweir 
287cdf0e10cSrcweir     builder->Append((System::Char) '>');
288cdf0e10cSrcweir     return builder->ToString();
289cdf0e10cSrcweir }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 
293cdf0e10cSrcweir //______________________________________________________________________________
type_resolve(::System::Object *,::System::ResolveEventArgs * args)294cdf0e10cSrcweir Assembly * TypeEmitter::type_resolve(
295cdf0e10cSrcweir     ::System::Object *, ::System::ResolveEventArgs * args )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir     ::System::String * cts_name = args->get_Name();
298cdf0e10cSrcweir     ::System::Type * ret_type = m_module_builder->GetType(
299cdf0e10cSrcweir         cts_name, false /* no exc */ );
300cdf0e10cSrcweir     if (0 == ret_type)
301cdf0e10cSrcweir     {
302cdf0e10cSrcweir         iface_entry * entry = dynamic_cast< iface_entry * >(
303cdf0e10cSrcweir             m_incomplete_ifaces->get_Item( cts_name ) );
304cdf0e10cSrcweir         if (0 != entry)
305cdf0e10cSrcweir             ret_type = entry->m_type_builder;
306cdf0e10cSrcweir     }
307cdf0e10cSrcweir     if (0 == ret_type)
308cdf0e10cSrcweir     {
309cdf0e10cSrcweir         sal_Int32 len = m_extra_assemblies->get_Length();
310cdf0e10cSrcweir         for ( sal_Int32 pos = 0; pos < len; ++pos )
311cdf0e10cSrcweir         {
312cdf0e10cSrcweir             ret_type = m_extra_assemblies[ pos ]->GetType(
313cdf0e10cSrcweir                 cts_name, false /* no exc */ );
314cdf0e10cSrcweir             if (0 != ret_type)
315cdf0e10cSrcweir             {
316cdf0e10cSrcweir                 if (g_verbose)
317cdf0e10cSrcweir                 {
318cdf0e10cSrcweir                     ::System::Console::WriteLine(
319cdf0e10cSrcweir                         "> resolving type {0} from {1}.",
320cdf0e10cSrcweir                         cts_name, ret_type->get_Assembly()->get_FullName() );
321cdf0e10cSrcweir                 }
322cdf0e10cSrcweir                 break;
323cdf0e10cSrcweir             }
324cdf0e10cSrcweir         }
325cdf0e10cSrcweir     }
326cdf0e10cSrcweir     if (0 != ret_type)
327cdf0e10cSrcweir         return ret_type->get_Assembly();
328cdf0e10cSrcweir     return 0;
329cdf0e10cSrcweir }
330cdf0e10cSrcweir 
331cdf0e10cSrcweir //______________________________________________________________________________
get_type(::System::String * cts_name,bool throw_exc)332cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
333cdf0e10cSrcweir     ::System::String * cts_name, bool throw_exc )
334cdf0e10cSrcweir {
335cdf0e10cSrcweir     ::System::Type * ret_type = m_module_builder->GetType( cts_name, false );
336cdf0e10cSrcweir     //We get the type from the ModuleBuilder even if the type is not complete
337cdf0e10cSrcweir     //but have been defined.
338cdf0e10cSrcweir     //if (ret_type == 0)
339cdf0e10cSrcweir     //{
340cdf0e10cSrcweir     //    iface_entry * entry = dynamic_cast< iface_entry * >(
341cdf0e10cSrcweir     //        m_incomplete_ifaces->get_Item( cts_name ) );
342cdf0e10cSrcweir     //    if (0 != entry)
343cdf0e10cSrcweir     //        ret_type = entry->m_type_builder;
344cdf0e10cSrcweir     //}
345cdf0e10cSrcweir         //try the cli_basetypes assembly
346cdf0e10cSrcweir     if (ret_type == 0)
347cdf0e10cSrcweir     {
348cdf0e10cSrcweir         ::System::Text::StringBuilder * builder = new ::System::Text::StringBuilder(cts_name);
349cdf0e10cSrcweir         builder->Append(S",cli_basetypes");
350cdf0e10cSrcweir         ret_type = ::System::Type::GetType(builder->ToString());
351cdf0e10cSrcweir     }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir     if (ret_type == 0)
354cdf0e10cSrcweir     {
355cdf0e10cSrcweir 		try
356cdf0e10cSrcweir 		{
357cdf0e10cSrcweir 			// may call on type_resolve()
358cdf0e10cSrcweir 			return ::System::Type::GetType( cts_name, throw_exc );
359cdf0e10cSrcweir 		}
360cdf0e10cSrcweir 		catch (::System::Exception* exc)
361cdf0e10cSrcweir 		{
362cdf0e10cSrcweir 			//If the type is not found one may have forgotten to specify assemblies with
363cdf0e10cSrcweir 			//additional types
364cdf0e10cSrcweir 			::System::Text::StringBuilder * sb = new ::System::Text::StringBuilder();
365cdf0e10cSrcweir 			sb->Append(new ::System::String(S"\nThe type "));
366cdf0e10cSrcweir 			sb->Append(cts_name);
367cdf0e10cSrcweir 			sb->Append(new ::System::String(S" \n could not be found. Did you forget to " \
368cdf0e10cSrcweir 				S"specify an additional assembly with the --reference option?\n"));
369cdf0e10cSrcweir 			if (throw_exc)
370cdf0e10cSrcweir 				throw new ::System::Exception(sb->ToString(), exc);
371cdf0e10cSrcweir 		}
372cdf0e10cSrcweir     }
373cdf0e10cSrcweir     else
374cdf0e10cSrcweir     {
375cdf0e10cSrcweir         return ret_type;
376cdf0e10cSrcweir     }
377cdf0e10cSrcweir }
378cdf0e10cSrcweir 
379cdf0e10cSrcweir //______________________________________________________________________________
get_type_Exception()380cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type_Exception()
381cdf0e10cSrcweir {
382cdf0e10cSrcweir     if (0 == m_type_Exception)
383cdf0e10cSrcweir     {
384cdf0e10cSrcweir         m_type_Exception = get_type(
385cdf0e10cSrcweir             S"unoidl.com.sun.star.uno.Exception", false /* no exc */ );
386cdf0e10cSrcweir         if (0 == m_type_Exception)
387cdf0e10cSrcweir         {
388cdf0e10cSrcweir             // define hardcoded type unoidl.com.sun.star.uno.Exception
389cdf0e10cSrcweir             Emit::TypeBuilder * type_builder =
390cdf0e10cSrcweir                 m_module_builder->DefineType(
391cdf0e10cSrcweir                       S"unoidl.com.sun.star.uno.Exception",
392cdf0e10cSrcweir                       (TypeAttributes) (TypeAttributes::Public |
393cdf0e10cSrcweir                                         TypeAttributes::BeforeFieldInit |
394cdf0e10cSrcweir                                         TypeAttributes::AnsiClass),
395cdf0e10cSrcweir                       __typeof (::System::Exception) );
396cdf0e10cSrcweir             Emit::FieldBuilder * field_Context = type_builder->DefineField(
397cdf0e10cSrcweir                 S"Context", __typeof (::System::Object),
398cdf0e10cSrcweir                 FieldAttributes::Public );
399cdf0e10cSrcweir             // default .ctor
400cdf0e10cSrcweir             type_builder->DefineDefaultConstructor( c_ctor_method_attr );
401cdf0e10cSrcweir             // .ctor
402cdf0e10cSrcweir             ::System::Type * param_types[] =
403cdf0e10cSrcweir                   new ::System::Type *[ 2 ];
404cdf0e10cSrcweir             param_types[ 0 ] = __typeof (::System::String);
405cdf0e10cSrcweir             param_types[ 1 ] = __typeof (::System::Object);
406cdf0e10cSrcweir             Emit::ConstructorBuilder * ctor_builder =
407cdf0e10cSrcweir                 type_builder->DefineConstructor(
408cdf0e10cSrcweir                     c_ctor_method_attr, CallingConventions::Standard,
409cdf0e10cSrcweir                     param_types );
410cdf0e10cSrcweir             ctor_builder->DefineParameter(
411cdf0e10cSrcweir                 1, ParameterAttributes::In, S"Message" );
412cdf0e10cSrcweir             ctor_builder->DefineParameter(
413cdf0e10cSrcweir                 2, ParameterAttributes::In, S"Context" );
414cdf0e10cSrcweir             Emit::ILGenerator * code = ctor_builder->GetILGenerator();
415cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_0 );
416cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_1 );
417cdf0e10cSrcweir             param_types = new ::System::Type * [ 1 ];
418cdf0e10cSrcweir             param_types[ 0 ] = __typeof (::System::String);
419cdf0e10cSrcweir             code->Emit(
420cdf0e10cSrcweir                 Emit::OpCodes::Call,
421cdf0e10cSrcweir                 __typeof (::System::Exception)
422cdf0e10cSrcweir                   ->GetConstructor( param_types ) );
423cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_0 );
424cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_2 );
425cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Stfld, field_Context );
426cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ret );
427cdf0e10cSrcweir 
428cdf0e10cSrcweir             if (g_verbose)
429cdf0e10cSrcweir             {
430cdf0e10cSrcweir                 ::System::Console::WriteLine(
431cdf0e10cSrcweir                     "> emitting exception type "
432cdf0e10cSrcweir                     "unoidl.com.sun.star.uno.Exception" );
433cdf0e10cSrcweir             }
434cdf0e10cSrcweir             m_type_Exception = type_builder->CreateType();
435cdf0e10cSrcweir         }
436cdf0e10cSrcweir     }
437cdf0e10cSrcweir     return m_type_Exception;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir //______________________________________________________________________________
get_type_RuntimeException()441cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type_RuntimeException()
442cdf0e10cSrcweir {
443cdf0e10cSrcweir     if (0 == m_type_RuntimeException)
444cdf0e10cSrcweir     {
445cdf0e10cSrcweir         m_type_RuntimeException = get_type(
446cdf0e10cSrcweir             S"unoidl.com.sun.star.uno.RuntimeException", false /* no exc */ );
447cdf0e10cSrcweir         if (0 == m_type_RuntimeException)
448cdf0e10cSrcweir         {
449cdf0e10cSrcweir             // define hardcoded type unoidl.com.sun.star.uno.RuntimeException
450cdf0e10cSrcweir             ::System::Type * type_Exception = get_type_Exception();
451cdf0e10cSrcweir             Emit::TypeBuilder * type_builder =
452cdf0e10cSrcweir                   m_module_builder->DefineType(
453cdf0e10cSrcweir                       S"unoidl.com.sun.star.uno.RuntimeException",
454cdf0e10cSrcweir                       (TypeAttributes) (TypeAttributes::Public |
455cdf0e10cSrcweir                                         TypeAttributes::BeforeFieldInit |
456cdf0e10cSrcweir                                         TypeAttributes::AnsiClass),
457cdf0e10cSrcweir                       type_Exception );
458cdf0e10cSrcweir             // default .ctor
459cdf0e10cSrcweir             type_builder->DefineDefaultConstructor( c_ctor_method_attr );
460cdf0e10cSrcweir             // .ctor
461cdf0e10cSrcweir             ::System::Type * param_types [] =
462cdf0e10cSrcweir                   new ::System::Type * [ 2 ];
463cdf0e10cSrcweir             param_types[ 0 ] = __typeof (::System::String);
464cdf0e10cSrcweir             param_types[ 1 ] = __typeof (::System::Object);
465cdf0e10cSrcweir             Emit::ConstructorBuilder * ctor_builder =
466cdf0e10cSrcweir                 type_builder->DefineConstructor(
467cdf0e10cSrcweir                     c_ctor_method_attr, CallingConventions::Standard,
468cdf0e10cSrcweir                     param_types );
469cdf0e10cSrcweir             ctor_builder->DefineParameter(
470cdf0e10cSrcweir                 1, ParameterAttributes::In, S"Message" );
471cdf0e10cSrcweir             ctor_builder->DefineParameter(
472cdf0e10cSrcweir                 2, ParameterAttributes::In, S"Context" );
473cdf0e10cSrcweir             Emit::ILGenerator * code = ctor_builder->GetILGenerator();
474cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_0 );
475cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_1 );
476cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_2 );
477cdf0e10cSrcweir             code->Emit(
478cdf0e10cSrcweir                 Emit::OpCodes::Call,
479cdf0e10cSrcweir                 type_Exception->GetConstructor( param_types ) );
480cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ret );
481cdf0e10cSrcweir 
482cdf0e10cSrcweir             if (g_verbose)
483cdf0e10cSrcweir             {
484cdf0e10cSrcweir                 ::System::Console::WriteLine(
485cdf0e10cSrcweir                     "> emitting exception type "
486cdf0e10cSrcweir                     "unoidl.com.sun.star.uno.RuntimeException" );
487cdf0e10cSrcweir             }
488cdf0e10cSrcweir             m_type_RuntimeException = type_builder->CreateType();
489cdf0e10cSrcweir         }
490cdf0e10cSrcweir     }
491cdf0e10cSrcweir     return m_type_RuntimeException;
492cdf0e10cSrcweir }
493cdf0e10cSrcweir 
494cdf0e10cSrcweir //______________________________________________________________________________
get_type(Reference<reflection::XConstantTypeDescription> const & xType)495cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
496cdf0e10cSrcweir     Reference< reflection::XConstantTypeDescription > const & xType )
497cdf0e10cSrcweir {
498cdf0e10cSrcweir     ::System::String * cts_name = to_cts_name( xType->getName() );
499cdf0e10cSrcweir     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
500cdf0e10cSrcweir     if (0 == ret_type)
501cdf0e10cSrcweir     {
502cdf0e10cSrcweir         Reference< reflection::XConstantTypeDescription > xConstant(
503cdf0e10cSrcweir             xType, UNO_QUERY_THROW );
504cdf0e10cSrcweir         ::System::Object * constant =
505cdf0e10cSrcweir               to_cli_constant( xConstant->getConstantValue() );
506cdf0e10cSrcweir         Emit::TypeBuilder * type_builder =
507cdf0e10cSrcweir             m_module_builder->DefineType(
508cdf0e10cSrcweir                 cts_name,
509cdf0e10cSrcweir                 (TypeAttributes) (TypeAttributes::Public |
510cdf0e10cSrcweir                                   TypeAttributes::Sealed |
511cdf0e10cSrcweir                                   TypeAttributes::BeforeFieldInit |
512cdf0e10cSrcweir                                   TypeAttributes::AnsiClass) );
513cdf0e10cSrcweir 
514cdf0e10cSrcweir         Emit::FieldBuilder * field_builder = type_builder->DefineField(
515cdf0e10cSrcweir             cts_name->Substring( cts_name->LastIndexOf( '.' ) +1 ),
516cdf0e10cSrcweir             constant->GetType(),
517cdf0e10cSrcweir             (FieldAttributes) (FieldAttributes::Public |
518cdf0e10cSrcweir                                FieldAttributes::Static |
519cdf0e10cSrcweir                                FieldAttributes::Literal) );
520cdf0e10cSrcweir         field_builder->SetConstant( constant );
521cdf0e10cSrcweir 
522cdf0e10cSrcweir         if (g_verbose)
523cdf0e10cSrcweir         {
524cdf0e10cSrcweir             ::System::Console::WriteLine(
525cdf0e10cSrcweir                 "> emitting constant type {0}", cts_name );
526cdf0e10cSrcweir         }
527cdf0e10cSrcweir         ret_type = type_builder->CreateType();
528cdf0e10cSrcweir     }
529cdf0e10cSrcweir     return ret_type;
530cdf0e10cSrcweir }
531cdf0e10cSrcweir 
532cdf0e10cSrcweir //______________________________________________________________________________
get_type(Reference<reflection::XConstantsTypeDescription> const & xType)533cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
534cdf0e10cSrcweir     Reference< reflection::XConstantsTypeDescription > const & xType )
535cdf0e10cSrcweir {
536cdf0e10cSrcweir     ::System::String * cts_name = to_cts_name( xType->getName() );
537cdf0e10cSrcweir     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
538cdf0e10cSrcweir     if (0 == ret_type)
539cdf0e10cSrcweir     {
540cdf0e10cSrcweir         Emit::TypeBuilder * type_builder =
541cdf0e10cSrcweir             m_module_builder->DefineType(
542cdf0e10cSrcweir                 cts_name,
543cdf0e10cSrcweir                 (TypeAttributes) (TypeAttributes::Public |
544cdf0e10cSrcweir                                   TypeAttributes::Sealed |
545cdf0e10cSrcweir                                   TypeAttributes::BeforeFieldInit |
546cdf0e10cSrcweir                                   TypeAttributes::AnsiClass) );
547cdf0e10cSrcweir 
548cdf0e10cSrcweir         Sequence< Reference<
549cdf0e10cSrcweir             reflection::XConstantTypeDescription > > seq_constants(
550cdf0e10cSrcweir                 xType->getConstants() );
551cdf0e10cSrcweir         Reference< reflection::XConstantTypeDescription > const * constants =
552cdf0e10cSrcweir             seq_constants.getConstArray();
553cdf0e10cSrcweir         sal_Int32 constants_length = seq_constants.getLength();
554cdf0e10cSrcweir         for ( sal_Int32 constants_pos = 0;
555cdf0e10cSrcweir               constants_pos < constants_length; ++constants_pos )
556cdf0e10cSrcweir         {
557cdf0e10cSrcweir             Reference<
558cdf0e10cSrcweir                 reflection::XConstantTypeDescription > const & xConstant =
559cdf0e10cSrcweir                 constants[ constants_pos ];
560cdf0e10cSrcweir             ::System::Object * constant =
561cdf0e10cSrcweir                   to_cli_constant( xConstant->getConstantValue() );
562cdf0e10cSrcweir             ::System::String * uno_name =
563cdf0e10cSrcweir                   ustring_to_String( xConstant->getName() );
564cdf0e10cSrcweir             Emit::FieldBuilder * field_builder = type_builder->DefineField(
565cdf0e10cSrcweir                 uno_name->Substring( uno_name->LastIndexOf( '.' ) +1 ),
566cdf0e10cSrcweir                 constant->GetType(),
567cdf0e10cSrcweir                 (FieldAttributes) (FieldAttributes::Public |
568cdf0e10cSrcweir                                    FieldAttributes::Static |
569cdf0e10cSrcweir                                    FieldAttributes::Literal) );
570cdf0e10cSrcweir             field_builder->SetConstant( constant );
571cdf0e10cSrcweir         }
572cdf0e10cSrcweir 
573cdf0e10cSrcweir         if (g_verbose)
574cdf0e10cSrcweir         {
575cdf0e10cSrcweir             ::System::Console::WriteLine(
576cdf0e10cSrcweir                 "> emitting constants group type {0}", cts_name );
577cdf0e10cSrcweir         }
578cdf0e10cSrcweir         ret_type = type_builder->CreateType();
579cdf0e10cSrcweir     }
580cdf0e10cSrcweir     return ret_type;
581cdf0e10cSrcweir }
582cdf0e10cSrcweir 
583cdf0e10cSrcweir //______________________________________________________________________________
get_type(Reference<reflection::XEnumTypeDescription> const & xType)584cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
585cdf0e10cSrcweir     Reference< reflection::XEnumTypeDescription > const & xType )
586cdf0e10cSrcweir {
587cdf0e10cSrcweir     ::System::String * cts_name = to_cts_name( xType->getName() );
588cdf0e10cSrcweir     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
589cdf0e10cSrcweir     if (0 == ret_type)
590cdf0e10cSrcweir     {
591cdf0e10cSrcweir //         Emit::EnumBuilder * enum_builder =
592cdf0e10cSrcweir //             m_module_builder->DefineEnum(
593cdf0e10cSrcweir //                 cts_name,
594cdf0e10cSrcweir //                 (TypeAttributes) (TypeAttributes::Public |
595cdf0e10cSrcweir // //                                   TypeAttributes::Sealed |
596cdf0e10cSrcweir //                                   TypeAttributes::AnsiClass),
597cdf0e10cSrcweir //                 __typeof (::System::Int32) );
598cdf0e10cSrcweir         // workaround enum builder bug
599cdf0e10cSrcweir         Emit::TypeBuilder * enum_builder =
600cdf0e10cSrcweir             m_module_builder->DefineType(
601cdf0e10cSrcweir                 cts_name,
602cdf0e10cSrcweir                 (TypeAttributes) (TypeAttributes::Public |
603cdf0e10cSrcweir                                   TypeAttributes::Sealed),
604cdf0e10cSrcweir                 __typeof (::System::Enum) );
605cdf0e10cSrcweir         enum_builder->DefineField(
606cdf0e10cSrcweir             S"value__", __typeof (::System::Int32),
607cdf0e10cSrcweir             (FieldAttributes) (FieldAttributes::Private |
608cdf0e10cSrcweir                                FieldAttributes::SpecialName |
609cdf0e10cSrcweir                                FieldAttributes::RTSpecialName) );
610cdf0e10cSrcweir         Sequence< OUString > seq_enum_names( xType->getEnumNames() );
611cdf0e10cSrcweir         Sequence< sal_Int32 > seq_enum_values( xType->getEnumValues() );
612cdf0e10cSrcweir         sal_Int32 enum_length = seq_enum_names.getLength();
613cdf0e10cSrcweir         OSL_ASSERT( enum_length == seq_enum_values.getLength() );
614cdf0e10cSrcweir         OUString const * enum_names = seq_enum_names.getConstArray();
615cdf0e10cSrcweir         sal_Int32 const * enum_values = seq_enum_values.getConstArray();
616cdf0e10cSrcweir         for ( sal_Int32 enum_pos = 0; enum_pos < enum_length; ++enum_pos )
617cdf0e10cSrcweir         {
618cdf0e10cSrcweir //             enum_builder->DefineLiteral(
619cdf0e10cSrcweir //                 ustring_to_String( enum_names[ enum_pos ] ),
620cdf0e10cSrcweir //                 __box ((::System::Int32) enum_values[ enum_pos ]) );
621cdf0e10cSrcweir             Emit::FieldBuilder * field_builder =
622cdf0e10cSrcweir                 enum_builder->DefineField(
623cdf0e10cSrcweir                     ustring_to_String( enum_names[ enum_pos ] ),
624cdf0e10cSrcweir                     enum_builder,
625cdf0e10cSrcweir                     (FieldAttributes) (FieldAttributes::Public |
626cdf0e10cSrcweir                                        FieldAttributes::Static |
627cdf0e10cSrcweir                                        FieldAttributes::Literal) );
628cdf0e10cSrcweir             field_builder->SetConstant(
629cdf0e10cSrcweir                 __box ((::System::Int32) enum_values[ enum_pos ]) );
630cdf0e10cSrcweir         }
631cdf0e10cSrcweir 
632cdf0e10cSrcweir         if (g_verbose)
633cdf0e10cSrcweir         {
634cdf0e10cSrcweir             ::System::Console::WriteLine(
635cdf0e10cSrcweir                 "> emitting enum type {0}", cts_name );
636cdf0e10cSrcweir         }
637cdf0e10cSrcweir         ret_type = enum_builder->CreateType();
638cdf0e10cSrcweir     }
639cdf0e10cSrcweir     return ret_type;
640cdf0e10cSrcweir }
641cdf0e10cSrcweir 
642cdf0e10cSrcweir //______________________________________________________________________________
get_type(Reference<reflection::XCompoundTypeDescription> const & xType)643cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
644cdf0e10cSrcweir     Reference< reflection::XCompoundTypeDescription > const & xType )
645cdf0e10cSrcweir {
646cdf0e10cSrcweir     OUString uno_name( xType->getName() );
647cdf0e10cSrcweir     if (TypeClass_EXCEPTION == xType->getTypeClass())
648cdf0e10cSrcweir     {
649cdf0e10cSrcweir         if (uno_name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
650cdf0e10cSrcweir                                        "com.sun.star.uno.Exception") ))
651cdf0e10cSrcweir         {
652cdf0e10cSrcweir             return get_type_Exception();
653cdf0e10cSrcweir         }
654cdf0e10cSrcweir         if (uno_name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
655cdf0e10cSrcweir                                        "com.sun.star.uno.RuntimeException") ))
656cdf0e10cSrcweir         {
657cdf0e10cSrcweir             return get_type_RuntimeException();
658cdf0e10cSrcweir         }
659cdf0e10cSrcweir     }
660cdf0e10cSrcweir     ::System::String * cts_name = to_cts_name( uno_name );
661cdf0e10cSrcweir     // if the struct is an instantiated polymorpic struct then we create the simple struct name
662cdf0e10cSrcweir     // For example:
663cdf0e10cSrcweir     // void func ([in] PolyStruct<boolean> arg);
664cdf0e10cSrcweir     //PolyStruct<boolean> will be converted to PolyStruct
665cdf0e10cSrcweir     polymorphicStructNameToStructName( & cts_name);
666cdf0e10cSrcweir 
667cdf0e10cSrcweir     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
668cdf0e10cSrcweir     if (0 == ret_type)
669cdf0e10cSrcweir     {
670cdf0e10cSrcweir         Reference< reflection::XCompoundTypeDescription > xBaseType(
671cdf0e10cSrcweir             xType->getBaseType(), UNO_QUERY );
672cdf0e10cSrcweir         ::System::Type * base_type = (xBaseType.is()
673cdf0e10cSrcweir                                       ? get_type( xBaseType )
674cdf0e10cSrcweir                                       : __typeof (::System::Object));
675cdf0e10cSrcweir         Emit::TypeBuilder * type_builder =
676cdf0e10cSrcweir             m_module_builder->DefineType(
677cdf0e10cSrcweir                 cts_name,
678cdf0e10cSrcweir                 (TypeAttributes) (TypeAttributes::Public |
679cdf0e10cSrcweir                                   TypeAttributes::BeforeFieldInit |
680cdf0e10cSrcweir                                   TypeAttributes::AnsiClass),
681cdf0e10cSrcweir                 base_type );
682cdf0e10cSrcweir 
683cdf0e10cSrcweir 
684cdf0e10cSrcweir          // insert to be completed
685cdf0e10cSrcweir         struct_entry * entry = new struct_entry();
686cdf0e10cSrcweir         xType->acquire();
687cdf0e10cSrcweir         entry->m_xType = xType.get();
688cdf0e10cSrcweir         entry->m_type_builder = type_builder;
689cdf0e10cSrcweir         entry->m_base_type = base_type;
690cdf0e10cSrcweir         m_incomplete_structs->Add( cts_name, entry );
691cdf0e10cSrcweir 
692cdf0e10cSrcweir         // type is incomplete
693cdf0e10cSrcweir         ret_type = type_builder;
694cdf0e10cSrcweir     }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir     //In case of an instantiated polymorphic struct we want to return a
697cdf0e10cSrcweir     //uno.PolymorphicType (inherits Type) rather then Type. This is neaded for constructing
698cdf0e10cSrcweir     //the service code. We can only do that if the struct is completed.
699cdf0e10cSrcweir     if (m_generated_structs->get_Item(cts_name))
700cdf0e10cSrcweir     {
701cdf0e10cSrcweir         Reference< reflection::XStructTypeDescription> xStructTypeDesc(
702cdf0e10cSrcweir             xType, UNO_QUERY);
703cdf0e10cSrcweir 
704cdf0e10cSrcweir         if (xStructTypeDesc.is())
705cdf0e10cSrcweir         {
706cdf0e10cSrcweir             Sequence< Reference< reflection::XTypeDescription > > seqTypeArgs = xStructTypeDesc->getTypeArguments();
707cdf0e10cSrcweir             sal_Int32 numTypes = seqTypeArgs.getLength();
708cdf0e10cSrcweir             if (numTypes > 0)
709cdf0e10cSrcweir             {
710cdf0e10cSrcweir                 //it is an instantiated polymorphic struct
711cdf0e10cSrcweir                 ::System::String * sCliName = mapUnoTypeName(ustring_to_String(xType->getName()));
712cdf0e10cSrcweir                 ret_type = ::uno::PolymorphicType::GetType(ret_type, sCliName);
713cdf0e10cSrcweir             }
714cdf0e10cSrcweir         }
715cdf0e10cSrcweir     }
716cdf0e10cSrcweir     return ret_type;
717cdf0e10cSrcweir }
718cdf0e10cSrcweir 
719cdf0e10cSrcweir //______________________________________________________________________________
get_type(Reference<reflection::XInterfaceTypeDescription2> const & xType)720cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
721cdf0e10cSrcweir     Reference< reflection::XInterfaceTypeDescription2 > const & xType )
722cdf0e10cSrcweir {
723cdf0e10cSrcweir     OUString uno_name( xType->getName() );
724cdf0e10cSrcweir     if (uno_name.equalsAsciiL(
725cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ))
726cdf0e10cSrcweir     {
727cdf0e10cSrcweir         return __typeof (::System::Object);
728cdf0e10cSrcweir     }
729cdf0e10cSrcweir 
730cdf0e10cSrcweir     ::System::String * cts_name = to_cts_name( xType->getName() );
731cdf0e10cSrcweir     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
732cdf0e10cSrcweir     if (0 == ret_type)
733cdf0e10cSrcweir     {
734cdf0e10cSrcweir         Emit::TypeBuilder * type_builder;
735cdf0e10cSrcweir 
736cdf0e10cSrcweir         TypeAttributes attr = (TypeAttributes) (TypeAttributes::Public |
737cdf0e10cSrcweir                                                 TypeAttributes::Interface |
738cdf0e10cSrcweir                                                 TypeAttributes::Abstract |
739cdf0e10cSrcweir                                                 TypeAttributes::AnsiClass);
740cdf0e10cSrcweir 
741cdf0e10cSrcweir         std::vector<Reference<reflection::XInterfaceTypeDescription2> > vecBaseTypes;
742cdf0e10cSrcweir         Sequence<Reference< reflection::XTypeDescription > > seqBaseTypes =
743cdf0e10cSrcweir             xType->getBaseTypes();
744cdf0e10cSrcweir         if (seqBaseTypes.getLength() > 0)
745cdf0e10cSrcweir         {
746cdf0e10cSrcweir             for (int i = 0; i < seqBaseTypes.getLength(); i++)
747cdf0e10cSrcweir             {
748cdf0e10cSrcweir                 Reference<reflection::XInterfaceTypeDescription2> xIfaceTd =
749cdf0e10cSrcweir                     resolveInterfaceTypedef(seqBaseTypes[i]);
750cdf0e10cSrcweir 
751cdf0e10cSrcweir                 if (xIfaceTd->getName().equalsAsciiL(
752cdf0e10cSrcweir                         RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ) == sal_False)
753cdf0e10cSrcweir                 {
754cdf0e10cSrcweir                     vecBaseTypes.push_back(xIfaceTd);
755cdf0e10cSrcweir                 }
756cdf0e10cSrcweir             }
757cdf0e10cSrcweir 
758cdf0e10cSrcweir             ::System::Type * base_interfaces [] =
759cdf0e10cSrcweir                   new ::System::Type * [ vecBaseTypes.size() ];
760cdf0e10cSrcweir 
761cdf0e10cSrcweir             typedef std::vector<Reference<reflection::XInterfaceTypeDescription2> >::const_iterator it;
762cdf0e10cSrcweir             int index = 0;
763cdf0e10cSrcweir             for (it i = vecBaseTypes.begin(); i != vecBaseTypes.end(); i++, index++)
764cdf0e10cSrcweir                 base_interfaces[ index ] = get_type( *i );
765cdf0e10cSrcweir             type_builder = m_module_builder->DefineType(
766cdf0e10cSrcweir                 cts_name, attr, 0, base_interfaces );
767cdf0e10cSrcweir         }
768cdf0e10cSrcweir         else
769cdf0e10cSrcweir         {
770cdf0e10cSrcweir             ::System::Console::WriteLine(
771cdf0e10cSrcweir                 "warning: IDL interface {0} is not derived from "
772cdf0e10cSrcweir                 "com.sun.star.uno.XInterface!",
773cdf0e10cSrcweir                 ustring_to_String( uno_name ) );
774cdf0e10cSrcweir 
775cdf0e10cSrcweir             type_builder = m_module_builder->DefineType( cts_name, attr );
776cdf0e10cSrcweir         }
777cdf0e10cSrcweir 
778cdf0e10cSrcweir         // insert to be completed
779cdf0e10cSrcweir         iface_entry * entry = new iface_entry();
780cdf0e10cSrcweir         xType->acquire();
781cdf0e10cSrcweir         entry->m_xType = xType.get();
782cdf0e10cSrcweir         entry->m_type_builder = type_builder;
783cdf0e10cSrcweir         m_incomplete_ifaces->Add( cts_name, entry );
784cdf0e10cSrcweir 
785cdf0e10cSrcweir         // type is incomplete
786cdf0e10cSrcweir         ret_type = type_builder;
787cdf0e10cSrcweir     }
788cdf0e10cSrcweir     return ret_type;
789cdf0e10cSrcweir }
790cdf0e10cSrcweir 
791cdf0e10cSrcweir 
792cdf0e10cSrcweir //______________________________________________________________________________
get_type(Reference<reflection::XServiceTypeDescription2> const & xType)793cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
794cdf0e10cSrcweir     Reference< reflection::XServiceTypeDescription2 > const & xType )
795cdf0e10cSrcweir {
796cdf0e10cSrcweir     if (xType->isSingleInterfaceBased() == sal_False)
797cdf0e10cSrcweir         return NULL;
798cdf0e10cSrcweir 
799cdf0e10cSrcweir     System::String * cts_name = to_cts_name( xType->getName() );
800cdf0e10cSrcweir     System::Type * ret_type = get_type( cts_name, false /* no exc */ );
801cdf0e10cSrcweir     if (ret_type != NULL)
802cdf0e10cSrcweir         return ret_type;
803cdf0e10cSrcweir 
804cdf0e10cSrcweir     TypeAttributes attr = (TypeAttributes) (TypeAttributes::Public |
805cdf0e10cSrcweir                                             TypeAttributes::Sealed |
806cdf0e10cSrcweir                                             TypeAttributes::BeforeFieldInit |
807cdf0e10cSrcweir                                             TypeAttributes::AnsiClass);
808cdf0e10cSrcweir 
809cdf0e10cSrcweir     Emit::TypeBuilder * type_builder = m_module_builder->DefineType(
810cdf0e10cSrcweir         cts_name, attr);
811cdf0e10cSrcweir 
812cdf0e10cSrcweir     // insert to be completed
813cdf0e10cSrcweir     service_entry * entry = new service_entry();
814cdf0e10cSrcweir     xType->acquire();
815cdf0e10cSrcweir     entry->m_xType = xType.get();
816cdf0e10cSrcweir     entry->m_type_builder = type_builder;
817cdf0e10cSrcweir     m_incomplete_services->Add(cts_name,entry );
818cdf0e10cSrcweir 
819cdf0e10cSrcweir     return type_builder;
820cdf0e10cSrcweir }
821cdf0e10cSrcweir 
get_type(Reference<reflection::XSingletonTypeDescription2> const & xType)822cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
823cdf0e10cSrcweir     Reference<reflection::XSingletonTypeDescription2 > const & xType )
824cdf0e10cSrcweir {
825cdf0e10cSrcweir     if (xType->isInterfaceBased() == sal_False)
826cdf0e10cSrcweir         return NULL;
827cdf0e10cSrcweir 
828cdf0e10cSrcweir     ::System::String* cts_name = to_cts_name( xType->getName() );
829cdf0e10cSrcweir     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
830cdf0e10cSrcweir     if (ret_type != NULL)
831cdf0e10cSrcweir         return ret_type;
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     TypeAttributes attr = static_cast<TypeAttributes>(
834cdf0e10cSrcweir         TypeAttributes::Public |
835cdf0e10cSrcweir         TypeAttributes::Sealed |
836cdf0e10cSrcweir         TypeAttributes::BeforeFieldInit |
837cdf0e10cSrcweir         TypeAttributes::AnsiClass);
838cdf0e10cSrcweir 
839cdf0e10cSrcweir     Emit::TypeBuilder * type_builder = m_module_builder->DefineType(
840cdf0e10cSrcweir         cts_name, attr);
841cdf0e10cSrcweir 
842cdf0e10cSrcweir     // insert to be completed
843cdf0e10cSrcweir     singleton_entry * entry = new singleton_entry();
844cdf0e10cSrcweir     xType->acquire();
845cdf0e10cSrcweir     entry->m_xType = xType.get();
846cdf0e10cSrcweir     entry->m_type_builder = type_builder;
847cdf0e10cSrcweir     m_incomplete_singletons->Add(cts_name,entry );
848cdf0e10cSrcweir 
849cdf0e10cSrcweir     return type_builder;
850cdf0e10cSrcweir 
851cdf0e10cSrcweir }
852cdf0e10cSrcweir 
853cdf0e10cSrcweir //______________________________________________________________________________
complete_iface_type(iface_entry * entry)854cdf0e10cSrcweir ::System::Type * TypeEmitter::complete_iface_type( iface_entry * entry )
855cdf0e10cSrcweir {
856cdf0e10cSrcweir     Emit::TypeBuilder * type_builder = entry->m_type_builder;
857cdf0e10cSrcweir     reflection::XInterfaceTypeDescription2 * xType = entry->m_xType;
858cdf0e10cSrcweir 
859cdf0e10cSrcweir     Sequence<Reference< reflection::XTypeDescription > > seqBaseTypes( xType->getBaseTypes() );
860cdf0e10cSrcweir     if (seqBaseTypes.getLength() > 0)
861cdf0e10cSrcweir     {
862cdf0e10cSrcweir         for (int i = 0; i < seqBaseTypes.getLength(); i++)
863cdf0e10cSrcweir         {
864cdf0e10cSrcweir             //make sure we get the interface rather then a typedef
865cdf0e10cSrcweir             Reference<reflection::XInterfaceTypeDescription2> aBaseType =
866cdf0e10cSrcweir                 resolveInterfaceTypedef( seqBaseTypes[i]);
867cdf0e10cSrcweir 
868cdf0e10cSrcweir             if (aBaseType->getName().equalsAsciiL(
869cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ) == sal_False)
870cdf0e10cSrcweir             {
871cdf0e10cSrcweir                 ::System::String * basetype_name = to_cts_name( aBaseType->getName() );
872cdf0e10cSrcweir                 iface_entry * base_entry = dynamic_cast< iface_entry * >(
873cdf0e10cSrcweir                     m_incomplete_ifaces->get_Item( basetype_name ) );
874cdf0e10cSrcweir                 if (0 != base_entry)
875cdf0e10cSrcweir                 {
876cdf0e10cSrcweir                 // complete uncompleted base type first
877cdf0e10cSrcweir                     complete_iface_type( base_entry );
878cdf0e10cSrcweir                 }
879cdf0e10cSrcweir             }
880cdf0e10cSrcweir         }
881cdf0e10cSrcweir     }
882cdf0e10cSrcweir 
883cdf0e10cSrcweir     Sequence<
884cdf0e10cSrcweir         Reference< reflection::XInterfaceMemberTypeDescription > > seq_members(
885cdf0e10cSrcweir             xType->getMembers() );
886cdf0e10cSrcweir     Reference< reflection::XInterfaceMemberTypeDescription > const * members =
887cdf0e10cSrcweir         seq_members.getConstArray();
888cdf0e10cSrcweir     sal_Int32 members_length = seq_members.getLength();
889cdf0e10cSrcweir     for ( sal_Int32 members_pos = 0;
890cdf0e10cSrcweir           members_pos < members_length; ++members_pos )
891cdf0e10cSrcweir     {
892cdf0e10cSrcweir         Reference<
893cdf0e10cSrcweir             reflection::XInterfaceMemberTypeDescription > const & xMember =
894cdf0e10cSrcweir             members[ members_pos ];
895cdf0e10cSrcweir         Sequence< Reference< reflection::XTypeDescription > > seq_exceptions;
896cdf0e10cSrcweir         Emit::MethodBuilder * method_builder;
897cdf0e10cSrcweir 
898cdf0e10cSrcweir         const MethodAttributes c_method_attr = (MethodAttributes)
899cdf0e10cSrcweir             (MethodAttributes::Public |
900cdf0e10cSrcweir              MethodAttributes::Abstract |
901cdf0e10cSrcweir              MethodAttributes::Virtual |
902cdf0e10cSrcweir              MethodAttributes::NewSlot |
903cdf0e10cSrcweir              MethodAttributes::HideBySig);
904cdf0e10cSrcweir //#if defined(_MSC_VER) && (_MSC_VER < 1400)
905cdf0e10cSrcweir //             MethodAttributes::Instance);
906cdf0e10cSrcweir //#else
907cdf0e10cSrcweir //	     Instance);
908cdf0e10cSrcweir //#endif
909cdf0e10cSrcweir 
910cdf0e10cSrcweir         if (TypeClass_INTERFACE_METHOD == xMember->getTypeClass())
911cdf0e10cSrcweir         {
912cdf0e10cSrcweir             Reference< reflection::XInterfaceMethodTypeDescription > xMethod(
913cdf0e10cSrcweir                 xMember, UNO_QUERY_THROW );
914cdf0e10cSrcweir 
915cdf0e10cSrcweir             Sequence<
916cdf0e10cSrcweir                 Reference< reflection::XMethodParameter > > seq_parameters(
917cdf0e10cSrcweir                     xMethod->getParameters() );
918cdf0e10cSrcweir             sal_Int32 params_length = seq_parameters.getLength();
919cdf0e10cSrcweir             ::System::Type * param_types [] =
920cdf0e10cSrcweir                   new ::System::Type * [ params_length ];
921cdf0e10cSrcweir             Reference< reflection::XMethodParameter > const * parameters =
922cdf0e10cSrcweir                 seq_parameters.getConstArray();
923cdf0e10cSrcweir             // first determine all types
924cdf0e10cSrcweir             //Make the first param type as return type
925cdf0e10cSrcweir             sal_Int32 params_pos = 0;
926cdf0e10cSrcweir             for ( ; params_pos < params_length; ++params_pos )
927cdf0e10cSrcweir             {
928cdf0e10cSrcweir                 Reference< reflection::XMethodParameter > const & xParam =
929cdf0e10cSrcweir                     parameters[ params_pos ];
930cdf0e10cSrcweir                 ::System::Type * param_type = get_type( xParam->getType() );
931cdf0e10cSrcweir                 ::System::String * param_type_name = param_type->get_FullName();
932cdf0e10cSrcweir                 if (xParam->isOut())
933cdf0e10cSrcweir                 {
934cdf0e10cSrcweir                     param_type = get_type(
935cdf0e10cSrcweir                         ::System::String::Concat(
936cdf0e10cSrcweir                             param_type_name, S"&" ), true );
937cdf0e10cSrcweir                 }
938cdf0e10cSrcweir                 param_types[ xParam->getPosition() ] = param_type;
939cdf0e10cSrcweir             }
940cdf0e10cSrcweir 
941cdf0e10cSrcweir 
942cdf0e10cSrcweir             // create method
943cdf0e10cSrcweir //             if (tb)
944cdf0e10cSrcweir //                 method_builder = type_builder->DefineMethod(
945cdf0e10cSrcweir //                 ustring_to_String( xMethod->getMemberName() ),
946cdf0e10cSrcweir //                 c_method_attr, tb,
947cdf0e10cSrcweir //                 param_types );
948cdf0e10cSrcweir //             else
949cdf0e10cSrcweir                 method_builder = type_builder->DefineMethod(
950cdf0e10cSrcweir                     ustring_to_String( xMethod->getMemberName() ),
951cdf0e10cSrcweir                     c_method_attr, get_type( xMethod->getReturnType() ),
952cdf0e10cSrcweir                     param_types );
953cdf0e10cSrcweir             // then define parameter infos
954cdf0e10cSrcweir             params_pos = 0;
955cdf0e10cSrcweir             for ( ; params_pos < params_length; ++params_pos )
956cdf0e10cSrcweir             {
957cdf0e10cSrcweir                 Reference< reflection::XMethodParameter > const & xParam =
958cdf0e10cSrcweir                     parameters[ params_pos ];
959cdf0e10cSrcweir                 long param_flags = 0;
960cdf0e10cSrcweir                 if (xParam->isIn())
961cdf0e10cSrcweir                     param_flags |= ParameterAttributes::In;
962cdf0e10cSrcweir                 if (xParam->isOut())
963cdf0e10cSrcweir                     param_flags |= ParameterAttributes::Out;
964cdf0e10cSrcweir                 OSL_ASSERT( 0 != param_flags );
965cdf0e10cSrcweir                 method_builder->DefineParameter(
966cdf0e10cSrcweir                     xParam->getPosition() +1 /* starts with 1 */,
967cdf0e10cSrcweir                     (ParameterAttributes) param_flags,
968cdf0e10cSrcweir                     ustring_to_String( xParam->getName() ) );
969cdf0e10cSrcweir             }
970cdf0e10cSrcweir             //Apply attribute TypeParametersAttribute to return value if it
971cdf0e10cSrcweir             //is a parameterized Type. Currently only structs can have parameters.
972cdf0e10cSrcweir             Reference<reflection::XStructTypeDescription> xReturnStruct(
973cdf0e10cSrcweir                 xMethod->getReturnType(), UNO_QUERY);
974cdf0e10cSrcweir 
975cdf0e10cSrcweir             if (xReturnStruct.is())
976cdf0e10cSrcweir             {
977cdf0e10cSrcweir                 Sequence<Reference<reflection::XTypeDescription> > seq_type_args =
978cdf0e10cSrcweir                     xReturnStruct->getTypeArguments();
979cdf0e10cSrcweir                 if (seq_type_args.getLength() != 0)
980cdf0e10cSrcweir                 {
981cdf0e10cSrcweir                     //get th ctor of the attribute
982cdf0e10cSrcweir                     ::System::Type * arCtor[] = {::System::Type::GetType(S"System.Type[]")};
983cdf0e10cSrcweir                     //Get the arguments for the attribute's ctor
984cdf0e10cSrcweir                     Reference<reflection::XTypeDescription> const * arXTypeArgs =
985cdf0e10cSrcweir                         seq_type_args.getConstArray();
986cdf0e10cSrcweir                     int numTypes = seq_type_args.getLength();
987cdf0e10cSrcweir                     ::System::Type * arCtsTypes[] = new ::System::Type*[numTypes];
988cdf0e10cSrcweir                     for (int i = 0; i < numTypes; i++)
989cdf0e10cSrcweir                         arCtsTypes[i] = get_type(arXTypeArgs[i]);
990cdf0e10cSrcweir                     ::System::Object * arArgs[] = {arCtsTypes};
991cdf0e10cSrcweir 
992cdf0e10cSrcweir 					Emit::CustomAttributeBuilder * attrBuilder =
993cdf0e10cSrcweir                         new Emit::CustomAttributeBuilder(
994cdf0e10cSrcweir                             __typeof(::uno::TypeArgumentsAttribute)
995cdf0e10cSrcweir                             ->GetConstructor( arCtor),
996cdf0e10cSrcweir                             arArgs);
997cdf0e10cSrcweir 
998cdf0e10cSrcweir                     method_builder->SetCustomAttribute(attrBuilder);
999cdf0e10cSrcweir                 }
1000cdf0e10cSrcweir             }
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir             //define UNO exception attribute (exceptions)--------------------------------------
1003cdf0e10cSrcweir             Emit::CustomAttributeBuilder* attrBuilder =
1004cdf0e10cSrcweir                 get_iface_method_exception_attribute(xMethod);
1005cdf0e10cSrcweir             if (attrBuilder != NULL)
1006cdf0e10cSrcweir                 method_builder->SetCustomAttribute(attrBuilder);
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir             // oneway attribute
1009cdf0e10cSrcweir             if (xMethod->isOneway())
1010cdf0e10cSrcweir             {
1011cdf0e10cSrcweir                 ::System::Type * arCtorOneway[] = new ::System::Type*[0];
1012cdf0e10cSrcweir                 ::System::Object * arArgs[] = new ::System::Object*[0];
1013cdf0e10cSrcweir                 Emit::CustomAttributeBuilder * attrBuilder =
1014cdf0e10cSrcweir                     new Emit::CustomAttributeBuilder(
1015cdf0e10cSrcweir                         __typeof(::uno::OnewayAttribute)->GetConstructor( arCtorOneway),
1016cdf0e10cSrcweir                         arArgs);
1017cdf0e10cSrcweir                 method_builder->SetCustomAttribute(attrBuilder);
1018cdf0e10cSrcweir             }
1019cdf0e10cSrcweir         }
1020cdf0e10cSrcweir         else // attribute
1021cdf0e10cSrcweir         {
1022cdf0e10cSrcweir             OSL_ASSERT(
1023cdf0e10cSrcweir                 TypeClass_INTERFACE_ATTRIBUTE == xMember->getTypeClass() );
1024cdf0e10cSrcweir             Reference<
1025cdf0e10cSrcweir                 reflection::XInterfaceAttributeTypeDescription2 > xAttribute(
1026cdf0e10cSrcweir                     xMember, UNO_QUERY_THROW );
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir             const MethodAttributes c_property_method_attr = (MethodAttributes)
1029cdf0e10cSrcweir                 (c_method_attr | MethodAttributes::SpecialName);
1030cdf0e10cSrcweir 
1031cdf0e10cSrcweir             ::System::Type * attribute_type = get_type( xAttribute->getType() );
1032cdf0e10cSrcweir             ::System::Type * parameters [] =
1033cdf0e10cSrcweir                   new ::System::Type * [ 0 ];
1034cdf0e10cSrcweir 
1035cdf0e10cSrcweir             Emit::PropertyBuilder * property_builder =
1036cdf0e10cSrcweir                 type_builder->DefineProperty(
1037cdf0e10cSrcweir                     ustring_to_String( xAttribute->getMemberName() ),
1038cdf0e10cSrcweir                     PropertyAttributes::None,
1039cdf0e10cSrcweir                     attribute_type, parameters );
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir             //set BoundAttribute, if necessary
1042cdf0e10cSrcweir             if (xAttribute->isBound())
1043cdf0e10cSrcweir             {
1044cdf0e10cSrcweir                 ConstructorInfo * ctorBoundAttr =
1045cdf0e10cSrcweir                     __typeof(::uno::BoundAttribute)->GetConstructor(
1046cdf0e10cSrcweir                         new System::Type*[0]);
1047cdf0e10cSrcweir                 Emit::CustomAttributeBuilder * attrBuilderBound =
1048cdf0e10cSrcweir                     new Emit::CustomAttributeBuilder(
1049cdf0e10cSrcweir                         ctorBoundAttr, new ::System::Object*[0]);
1050cdf0e10cSrcweir                 property_builder->SetCustomAttribute(attrBuilderBound);
1051cdf0e10cSrcweir             }
1052cdf0e10cSrcweir 
1053cdf0e10cSrcweir             // getter
1054cdf0e10cSrcweir             Emit::MethodBuilder * method_builder =
1055cdf0e10cSrcweir                 type_builder->DefineMethod(
1056cdf0e10cSrcweir                     ustring_to_String( OUSTR("get_") +
1057cdf0e10cSrcweir                                        xAttribute->getMemberName() ),
1058cdf0e10cSrcweir                     c_property_method_attr, attribute_type, parameters );
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir            //define UNO exception attribute (exceptions)--------------------------------------
1061cdf0e10cSrcweir             Emit::CustomAttributeBuilder* attrBuilder =
1062cdf0e10cSrcweir                 get_exception_attribute(xAttribute->getGetExceptions());
1063cdf0e10cSrcweir             if (attrBuilder != NULL)
1064cdf0e10cSrcweir                 method_builder->SetCustomAttribute(attrBuilder);
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir             property_builder->SetGetMethod( method_builder );
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir             if (! xAttribute->isReadOnly())
1069cdf0e10cSrcweir             {
1070cdf0e10cSrcweir                 // setter
1071cdf0e10cSrcweir                 parameters = new ::System::Type * [ 1 ];
1072cdf0e10cSrcweir                 parameters[ 0 ] = attribute_type;
1073cdf0e10cSrcweir                 method_builder =
1074cdf0e10cSrcweir                     type_builder->DefineMethod(
1075cdf0e10cSrcweir                         ustring_to_String( OUSTR("set_") +
1076cdf0e10cSrcweir                                            xAttribute->getMemberName() ),
1077cdf0e10cSrcweir                         c_property_method_attr, 0, parameters );
1078cdf0e10cSrcweir                 // define parameter info
1079cdf0e10cSrcweir                 method_builder->DefineParameter(
1080cdf0e10cSrcweir                     1 /* starts with 1 */, ParameterAttributes::In, S"value" );
1081cdf0e10cSrcweir                 //define UNO exception attribute (exceptions)--------------------------------------
1082cdf0e10cSrcweir                 Emit::CustomAttributeBuilder* attrBuilder =
1083cdf0e10cSrcweir                     get_exception_attribute(xAttribute->getSetExceptions());
1084cdf0e10cSrcweir                 if (attrBuilder != NULL)
1085cdf0e10cSrcweir                     method_builder->SetCustomAttribute(attrBuilder);
1086cdf0e10cSrcweir 
1087cdf0e10cSrcweir                 property_builder->SetSetMethod( method_builder );
1088cdf0e10cSrcweir             }
1089cdf0e10cSrcweir         }
1090cdf0e10cSrcweir     }
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir     // remove from incomplete types map
1093cdf0e10cSrcweir     ::System::String * cts_name = type_builder->get_FullName();
1094cdf0e10cSrcweir     m_incomplete_ifaces->Remove( cts_name );
1095cdf0e10cSrcweir     xType->release();
1096cdf0e10cSrcweir 
1097cdf0e10cSrcweir     if (g_verbose)
1098cdf0e10cSrcweir     {
1099cdf0e10cSrcweir         ::System::Console::WriteLine(
1100cdf0e10cSrcweir             "> emitting interface type {0}", cts_name );
1101cdf0e10cSrcweir     }
1102cdf0e10cSrcweir     return type_builder->CreateType();
1103cdf0e10cSrcweir }
1104cdf0e10cSrcweir 
complete_struct_type(struct_entry * entry)1105cdf0e10cSrcweir ::System::Type * TypeEmitter::complete_struct_type( struct_entry * entry )
1106cdf0e10cSrcweir {
1107cdf0e10cSrcweir      OSL_ASSERT(entry);
1108cdf0e10cSrcweir     ::System::String * cts_name = entry->m_type_builder->get_FullName();
1109cdf0e10cSrcweir 
1110cdf0e10cSrcweir     //Polymorphic struct, define uno.TypeParametersAttribute
1111cdf0e10cSrcweir     //A polymorphic struct cannot have a basetype.
1112cdf0e10cSrcweir     //When we create the template of the struct then we have no exact types
1113cdf0e10cSrcweir     //and the name does not contain a parameter list
1114cdf0e10cSrcweir     Sequence< OUString > seq_type_parameters;
1115cdf0e10cSrcweir     Reference< reflection::XStructTypeDescription> xStructTypeDesc(
1116cdf0e10cSrcweir         entry->m_xType, UNO_QUERY);
1117cdf0e10cSrcweir     if (xStructTypeDesc.is())
1118cdf0e10cSrcweir     {
1119cdf0e10cSrcweir         seq_type_parameters = xStructTypeDesc->getTypeParameters();
1120cdf0e10cSrcweir         int numTypes = 0;
1121cdf0e10cSrcweir         if ((numTypes = seq_type_parameters.getLength()) > 0)
1122cdf0e10cSrcweir         {
1123cdf0e10cSrcweir             ::System::Object * aArg[] = new ::System::Object*[numTypes];
1124cdf0e10cSrcweir             for (int i = 0; i < numTypes; i++)
1125cdf0e10cSrcweir                 aArg[i] = ustring_to_String(seq_type_parameters.getConstArray()[i]);
1126cdf0e10cSrcweir             ::System::Object * args[] = {aArg};
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir             ::System::Type * arTypesCtor[] =
1129cdf0e10cSrcweir             {::System::Type::GetType(S"System.String[]")};
1130cdf0e10cSrcweir             Emit::CustomAttributeBuilder * attrBuilder =
1131cdf0e10cSrcweir                 new Emit::CustomAttributeBuilder(
1132cdf0e10cSrcweir                 __typeof(::uno::TypeParametersAttribute)->GetConstructor(arTypesCtor),
1133cdf0e10cSrcweir                 args);
1134cdf0e10cSrcweir             entry->m_type_builder->SetCustomAttribute(attrBuilder);
1135cdf0e10cSrcweir         }
1136cdf0e10cSrcweir     }
1137cdf0e10cSrcweir 
1138cdf0e10cSrcweir     // optional: lookup base type whether generated entry of this session
1139cdf0e10cSrcweir     struct_entry * base_type_entry = 0;
1140cdf0e10cSrcweir     if (0 != entry->m_base_type)
1141cdf0e10cSrcweir     {
1142cdf0e10cSrcweir         //ToDo maybe get from incomplete structs
1143cdf0e10cSrcweir         base_type_entry =
1144cdf0e10cSrcweir             dynamic_cast< struct_entry * >(
1145cdf0e10cSrcweir                 m_generated_structs->get_Item(
1146cdf0e10cSrcweir                     entry->m_base_type->get_FullName() ) );
1147cdf0e10cSrcweir     }
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir         // members
1150cdf0e10cSrcweir     Sequence< Reference< reflection::XTypeDescription > > seq_members(
1151cdf0e10cSrcweir         entry->m_xType->getMemberTypes() );
1152cdf0e10cSrcweir     Sequence< OUString > seq_member_names( entry->m_xType->getMemberNames() );
1153cdf0e10cSrcweir     sal_Int32 members_length = seq_members.getLength();
1154cdf0e10cSrcweir     OSL_ASSERT( seq_member_names.getLength() == members_length );
1155cdf0e10cSrcweir 	//check if we have a XTypeDescription for every member. If not then the user may
1156cdf0e10cSrcweir 	//have forgotten to specify additional rdbs with the --extra option.
1157cdf0e10cSrcweir     Reference< reflection::XTypeDescription > const * pseq_members =
1158cdf0e10cSrcweir 	        seq_members.getConstArray();
1159cdf0e10cSrcweir     OUString const * pseq_member_names =
1160cdf0e10cSrcweir         seq_member_names.getConstArray();
1161cdf0e10cSrcweir 	for (int i = 0; i < members_length; i++)
1162cdf0e10cSrcweir 	{
1163cdf0e10cSrcweir 		const OUString sType(entry->m_xType->getName());
1164cdf0e10cSrcweir 		const OUString sMemberName(pseq_member_names[i]);
1165cdf0e10cSrcweir 		if ( ! pseq_members[i].is())
1166cdf0e10cSrcweir 			throw RuntimeException(OUSTR("Missing type description . Check if you need to " \
1167cdf0e10cSrcweir 			"specify additional RDBs with the --extra option. Type missing for: ") +  sType +
1168cdf0e10cSrcweir 			OUSTR("::") + sMemberName,0);
1169cdf0e10cSrcweir 	}
1170cdf0e10cSrcweir 
1171cdf0e10cSrcweir     sal_Int32 all_members_length = 0;
1172cdf0e10cSrcweir     sal_Int32 member_pos;
1173cdf0e10cSrcweir     sal_Int32 type_param_pos = 0;
1174cdf0e10cSrcweir 
1175cdf0e10cSrcweir     // collect base types; wrong order
1176cdf0e10cSrcweir     ::System::Collections::ArrayList * base_types_list =
1177cdf0e10cSrcweir             new ::System::Collections::ArrayList( 3 /* initial capacity */ );
1178cdf0e10cSrcweir     for (::System::Type * base_type_pos = entry->m_base_type;
1179cdf0e10cSrcweir         ! base_type_pos->Equals( __typeof (::System::Object) );
1180cdf0e10cSrcweir         base_type_pos = base_type_pos->get_BaseType() )
1181cdf0e10cSrcweir     {
1182cdf0e10cSrcweir         base_types_list->Add( base_type_pos );
1183cdf0e10cSrcweir         if (base_type_pos->Equals( __typeof (::System::Exception) ))
1184cdf0e10cSrcweir         {
1185cdf0e10cSrcweir             // special Message member
1186cdf0e10cSrcweir             all_members_length += 1;
1187cdf0e10cSrcweir             break; // don't include System.Exception base classes
1188cdf0e10cSrcweir         }
1189cdf0e10cSrcweir         else
1190cdf0e10cSrcweir         {
1191cdf0e10cSrcweir             //ensure the base type is complete. Otherwise GetFields won't work
1192cdf0e10cSrcweir             get_complete_struct(base_type_pos->get_FullName());
1193cdf0e10cSrcweir             all_members_length +=
1194cdf0e10cSrcweir                 base_type_pos->GetFields(
1195cdf0e10cSrcweir                 (BindingFlags) (BindingFlags::Instance |
1196cdf0e10cSrcweir                 BindingFlags::Public |
1197cdf0e10cSrcweir                 BindingFlags::DeclaredOnly) )
1198cdf0e10cSrcweir                 ->get_Length();
1199cdf0e10cSrcweir         }
1200cdf0e10cSrcweir     }
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir     // create all_members arrays; right order
1203cdf0e10cSrcweir     ::System::String * all_member_names[] =
1204cdf0e10cSrcweir         new ::System::String * [all_members_length + members_length ];
1205cdf0e10cSrcweir     ::System::Type * all_param_types[] =
1206cdf0e10cSrcweir         new ::System::Type * [all_members_length + members_length ];
1207cdf0e10cSrcweir     member_pos = 0;
1208cdf0e10cSrcweir     for ( sal_Int32 pos = base_types_list->get_Count(); pos--; )
1209cdf0e10cSrcweir     {
1210cdf0e10cSrcweir         ::System::Type * base_type = __try_cast< ::System::Type * >(
1211cdf0e10cSrcweir             base_types_list->get_Item( pos ) );
1212cdf0e10cSrcweir         if (base_type->Equals( __typeof (::System::Exception) ))
1213cdf0e10cSrcweir         {
1214cdf0e10cSrcweir             all_member_names[ member_pos ] = S"Message";
1215cdf0e10cSrcweir             all_param_types[ member_pos ] = __typeof (::System::String);
1216cdf0e10cSrcweir             ++member_pos;
1217cdf0e10cSrcweir         }
1218cdf0e10cSrcweir         else
1219cdf0e10cSrcweir         {
1220cdf0e10cSrcweir             ::System::String * base_type_name = base_type->get_FullName();
1221cdf0e10cSrcweir 
1222cdf0e10cSrcweir             //ToDo m_generated_structs?
1223cdf0e10cSrcweir             struct_entry * entry =
1224cdf0e10cSrcweir                 dynamic_cast< struct_entry * >(
1225cdf0e10cSrcweir                 m_generated_structs->get_Item( base_type_name ) );
1226cdf0e10cSrcweir             if (0 == entry)
1227cdf0e10cSrcweir             {
1228cdf0e10cSrcweir                 // complete type
1229cdf0e10cSrcweir                 FieldInfo * fields [] =
1230cdf0e10cSrcweir                     base_type->GetFields(
1231cdf0e10cSrcweir                     (BindingFlags) (BindingFlags::Instance |
1232cdf0e10cSrcweir                     BindingFlags::Public |
1233cdf0e10cSrcweir                     BindingFlags::DeclaredOnly) );
1234cdf0e10cSrcweir                 sal_Int32 len = fields->get_Length();
1235cdf0e10cSrcweir                 for ( sal_Int32 pos = 0; pos < len; ++pos )
1236cdf0e10cSrcweir                 {
1237cdf0e10cSrcweir                     FieldInfo * field = fields[ pos ];
1238cdf0e10cSrcweir                     all_member_names[ member_pos ] = field->get_Name();
1239cdf0e10cSrcweir                     all_param_types[ member_pos ] = field->get_FieldType();
1240cdf0e10cSrcweir                     ++member_pos;
1241cdf0e10cSrcweir                 }
1242cdf0e10cSrcweir             }
1243cdf0e10cSrcweir             else // generated during this session:
1244cdf0e10cSrcweir                 // members may be incomplete ifaces
1245cdf0e10cSrcweir             {
1246cdf0e10cSrcweir                 sal_Int32 len = entry->m_member_names->get_Length();
1247cdf0e10cSrcweir                 for ( sal_Int32 pos = 0; pos < len; ++pos )
1248cdf0e10cSrcweir                 {
1249cdf0e10cSrcweir                     all_member_names[ member_pos ] =
1250cdf0e10cSrcweir                         entry->m_member_names[ pos ];
1251cdf0e10cSrcweir                     all_param_types[ member_pos ] =
1252cdf0e10cSrcweir                         entry->m_param_types[ pos ];
1253cdf0e10cSrcweir                     ++member_pos;
1254cdf0e10cSrcweir                 }
1255cdf0e10cSrcweir             }
1256cdf0e10cSrcweir         }
1257cdf0e10cSrcweir     }
1258cdf0e10cSrcweir     OSL_ASSERT( all_members_length == member_pos );
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir     // build up entry
1261cdf0e10cSrcweir //    struct_entry * entry = new struct_entry();
1262cdf0e10cSrcweir     entry->m_member_names = new ::System::String * [ members_length ];
1263cdf0e10cSrcweir     entry->m_param_types = new ::System::Type * [ members_length ];
1264cdf0e10cSrcweir 
1265cdf0e10cSrcweir     // add members
1266cdf0e10cSrcweir     Emit::FieldBuilder * members[] = new Emit::FieldBuilder * [ members_length ];
1267cdf0e10cSrcweir     //Reference< reflection::XTypeDescription > const * pseq_members =
1268cdf0e10cSrcweir     //    seq_members.getConstArray();
1269cdf0e10cSrcweir     //OUString const * pseq_member_names =
1270cdf0e10cSrcweir     //    seq_member_names.getConstArray();
1271cdf0e10cSrcweir 
1272cdf0e10cSrcweir     int curParamIndex = 0; //count the fields which have parameterized types
1273cdf0e10cSrcweir     for ( member_pos = 0; member_pos < members_length; ++member_pos )
1274cdf0e10cSrcweir     {
1275cdf0e10cSrcweir         ::System::String * field_name =
1276cdf0e10cSrcweir             ustring_to_String( pseq_member_names[ member_pos ] );
1277cdf0e10cSrcweir         ::System::Type * field_type;
1278cdf0e10cSrcweir         //Special handling of struct parameter types
1279cdf0e10cSrcweir         bool bParameterizedType = false;
1280cdf0e10cSrcweir         if (pseq_members[ member_pos ]->getTypeClass() == TypeClass_UNKNOWN)
1281cdf0e10cSrcweir         {
1282cdf0e10cSrcweir             bParameterizedType = true;
1283cdf0e10cSrcweir             if (type_param_pos < seq_type_parameters.getLength())
1284cdf0e10cSrcweir             {
1285cdf0e10cSrcweir                 field_type = __typeof(::System::Object);
1286cdf0e10cSrcweir                 type_param_pos++;
1287cdf0e10cSrcweir             }
1288cdf0e10cSrcweir             else
1289cdf0e10cSrcweir             {
1290cdf0e10cSrcweir                 throw RuntimeException(
1291cdf0e10cSrcweir                     OUSTR("unexpected member type in ") + entry->m_xType->getName(),
1292cdf0e10cSrcweir                     Reference< XInterface >() );
1293cdf0e10cSrcweir             }
1294cdf0e10cSrcweir         }
1295cdf0e10cSrcweir         else
1296cdf0e10cSrcweir         {
1297cdf0e10cSrcweir             field_type =
1298cdf0e10cSrcweir                 get_type( pseq_members[ member_pos ] );
1299cdf0e10cSrcweir         }
1300cdf0e10cSrcweir         members[ member_pos ] =
1301cdf0e10cSrcweir             entry->m_type_builder->DefineField(
1302cdf0e10cSrcweir             field_name, field_type, FieldAttributes::Public );
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir         //parameterized type (polymorphic struct) ?
1305cdf0e10cSrcweir         if (bParameterizedType && xStructTypeDesc.is())
1306cdf0e10cSrcweir         {
1307cdf0e10cSrcweir             //get the name
1308cdf0e10cSrcweir             OSL_ASSERT(seq_type_parameters.getLength() > curParamIndex);
1309cdf0e10cSrcweir             ::System::String* sTypeName = ustring_to_String(
1310cdf0e10cSrcweir                 seq_type_parameters.getConstArray()[curParamIndex++]);
1311cdf0e10cSrcweir             ::System::Object * args[] = {sTypeName};
1312cdf0e10cSrcweir             //set ParameterizedTypeAttribute
1313cdf0e10cSrcweir             ::System::Type * arCtorTypes[] = {__typeof(::System::String)};
1314cdf0e10cSrcweir 
1315cdf0e10cSrcweir             Emit::CustomAttributeBuilder * attrBuilder =
1316cdf0e10cSrcweir                 new Emit::CustomAttributeBuilder(
1317cdf0e10cSrcweir                 __typeof(::uno::ParameterizedTypeAttribute)
1318cdf0e10cSrcweir                 ->GetConstructor(arCtorTypes),
1319cdf0e10cSrcweir                 args);
1320cdf0e10cSrcweir 
1321cdf0e10cSrcweir             members[member_pos]->SetCustomAttribute(attrBuilder);
1322cdf0e10cSrcweir         }
1323cdf0e10cSrcweir         // add to all_members
1324cdf0e10cSrcweir         all_member_names[ all_members_length + member_pos ] = field_name;
1325cdf0e10cSrcweir         all_param_types[ all_members_length + member_pos ] = field_type;
1326cdf0e10cSrcweir         // add to entry
1327cdf0e10cSrcweir         entry->m_member_names[ member_pos ] = field_name;
1328cdf0e10cSrcweir         entry->m_param_types[ member_pos ] = field_type;
1329cdf0e10cSrcweir     }
1330cdf0e10cSrcweir     all_members_length += members_length;
1331cdf0e10cSrcweir 
1332cdf0e10cSrcweir     // default .ctor
1333cdf0e10cSrcweir     Emit::ConstructorBuilder * ctor_builder =
1334cdf0e10cSrcweir         entry->m_type_builder->DefineConstructor(
1335cdf0e10cSrcweir         c_ctor_method_attr, CallingConventions::Standard,
1336cdf0e10cSrcweir         new ::System::Type * [ 0 ] );
1337cdf0e10cSrcweir     Emit::ILGenerator * code = ctor_builder->GetILGenerator();
1338cdf0e10cSrcweir     code->Emit( Emit::OpCodes::Ldarg_0 );
1339cdf0e10cSrcweir     code->Emit(
1340cdf0e10cSrcweir         Emit::OpCodes::Call,
1341cdf0e10cSrcweir         0 == base_type_entry
1342cdf0e10cSrcweir         ? entry->m_base_type->GetConstructor( new ::System::Type * [ 0 ] )
1343cdf0e10cSrcweir         : base_type_entry->m_default_ctor );
1344cdf0e10cSrcweir     // default initialize members
1345cdf0e10cSrcweir     for ( member_pos = 0; member_pos < members_length; ++member_pos )
1346cdf0e10cSrcweir     {
1347cdf0e10cSrcweir         FieldInfo * field = members[ member_pos ];
1348cdf0e10cSrcweir         ::System::Type * field_type = field->get_FieldType();
1349cdf0e10cSrcweir         //            ::System::Type * new_field_type = m_module_builder->GetType(field_type->FullName, false);
1350cdf0e10cSrcweir         // default initialize:
1351cdf0e10cSrcweir         // string, type, enum, sequence, struct, exception, any
1352cdf0e10cSrcweir         if (field_type->Equals( __typeof (::System::String) ))
1353cdf0e10cSrcweir         {
1354cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_0 );
1355cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldstr, S"" );
1356cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Stfld, field );
1357cdf0e10cSrcweir         }
1358cdf0e10cSrcweir         else if (field_type->Equals( __typeof (::System::Type) ))
1359cdf0e10cSrcweir         {
1360cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_0 );
1361cdf0e10cSrcweir             code->Emit(
1362cdf0e10cSrcweir                 Emit::OpCodes::Ldtoken, __typeof (::System::Void) );
1363cdf0e10cSrcweir             code->Emit(
1364cdf0e10cSrcweir                 Emit::OpCodes::Call, m_method_info_Type_GetTypeFromHandle );
1365cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Stfld, field );
1366cdf0e10cSrcweir         }
1367cdf0e10cSrcweir         else if (field_type->get_IsArray())
1368cdf0e10cSrcweir         {
1369cdf0e10cSrcweir             //Find the value type. In case of sequence<sequence< ... > > find the actual value type
1370cdf0e10cSrcweir             ::System::Type * value = field_type;
1371cdf0e10cSrcweir             while ((value = value->GetElementType())->get_IsArray());
1372cdf0e10cSrcweir             //If the value type is a struct then make sure it is fully created.
1373cdf0e10cSrcweir             get_complete_struct(value->get_FullName());
1374cdf0e10cSrcweir 
1375cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldarg_0 );
1376cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Ldc_I4_0 );
1377cdf0e10cSrcweir             code->Emit(
1378cdf0e10cSrcweir                 Emit::OpCodes::Newarr, field_type->GetElementType() );
1379cdf0e10cSrcweir             code->Emit( Emit::OpCodes::Stfld, field );
1380cdf0e10cSrcweir         }
1381cdf0e10cSrcweir         else if (field_type->get_IsValueType())
1382cdf0e10cSrcweir         {
1383cdf0e10cSrcweir             if (field_type->get_FullName()->Equals( S"uno.Any" ))
1384cdf0e10cSrcweir             {
1385cdf0e10cSrcweir                 code->Emit( Emit::OpCodes::Ldarg_0 );
1386cdf0e10cSrcweir                 code->Emit( Emit::OpCodes::Ldsfld, __typeof(::uno::Any)->GetField(S"VOID"));
1387cdf0e10cSrcweir                 code->Emit( Emit::OpCodes::Stfld, field );
1388cdf0e10cSrcweir             }
1389cdf0e10cSrcweir         }
1390cdf0e10cSrcweir         else if (field_type->get_IsClass())
1391cdf0e10cSrcweir         {
1392cdf0e10cSrcweir             /* may be XInterface */
1393cdf0e10cSrcweir             if (! field_type->Equals( __typeof (::System::Object) ))
1394cdf0e10cSrcweir             {
1395cdf0e10cSrcweir                 // struct, exception
1396cdf0e10cSrcweir                 //make sure the struct is already complete.
1397cdf0e10cSrcweir                 get_complete_struct(field_type->get_FullName());
1398cdf0e10cSrcweir                 code->Emit( Emit::OpCodes::Ldarg_0 );
1399cdf0e10cSrcweir                 code->Emit(
1400cdf0e10cSrcweir                     Emit::OpCodes::Newobj,
1401cdf0e10cSrcweir                     //GetConstructor requies that the member types of the object which is to be constructed are already known.
1402cdf0e10cSrcweir                     field_type->GetConstructor(
1403cdf0e10cSrcweir                     new ::System::Type * [ 0 ] ) );
1404cdf0e10cSrcweir                 code->Emit( Emit::OpCodes::Stfld, field );
1405cdf0e10cSrcweir             }
1406cdf0e10cSrcweir         }
1407cdf0e10cSrcweir     }
1408cdf0e10cSrcweir     code->Emit( Emit::OpCodes::Ret );
1409cdf0e10cSrcweir     entry->m_default_ctor = ctor_builder;
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir     // parameterized .ctor including all base members
1412cdf0e10cSrcweir     ctor_builder = entry->m_type_builder->DefineConstructor(
1413cdf0e10cSrcweir         c_ctor_method_attr, CallingConventions::Standard, all_param_types );
1414cdf0e10cSrcweir     for ( member_pos = 0; member_pos < all_members_length; ++member_pos )
1415cdf0e10cSrcweir     {
1416cdf0e10cSrcweir         ctor_builder->DefineParameter(
1417cdf0e10cSrcweir             member_pos +1 /* starts with 1 */, ParameterAttributes::In,
1418cdf0e10cSrcweir             all_member_names[ member_pos ] );
1419cdf0e10cSrcweir     }
1420cdf0e10cSrcweir     code = ctor_builder->GetILGenerator();
1421cdf0e10cSrcweir     // call base .ctor
1422cdf0e10cSrcweir     code->Emit( Emit::OpCodes::Ldarg_0 ); // push this
1423cdf0e10cSrcweir     sal_Int32 base_members_length = all_members_length - members_length;
1424cdf0e10cSrcweir     ::System::Type * param_types [] =
1425cdf0e10cSrcweir         new ::System::Type * [ base_members_length ];
1426cdf0e10cSrcweir     for ( member_pos = 0; member_pos < base_members_length; ++member_pos )
1427cdf0e10cSrcweir     {
1428cdf0e10cSrcweir         emit_ldarg( code, member_pos +1 );
1429cdf0e10cSrcweir         param_types[ member_pos ] = all_param_types[ member_pos ];
1430cdf0e10cSrcweir     }
1431cdf0e10cSrcweir     code->Emit(
1432cdf0e10cSrcweir         Emit::OpCodes::Call,
1433cdf0e10cSrcweir         0 == base_type_entry
1434cdf0e10cSrcweir         ? entry->m_base_type->GetConstructor( param_types )
1435cdf0e10cSrcweir         : base_type_entry->m_ctor );
1436cdf0e10cSrcweir     // initialize members
1437cdf0e10cSrcweir     for ( member_pos = 0; member_pos < members_length; ++member_pos )
1438cdf0e10cSrcweir     {
1439cdf0e10cSrcweir         code->Emit( Emit::OpCodes::Ldarg_0 ); // push this
1440cdf0e10cSrcweir         emit_ldarg( code, member_pos + base_members_length +1 );
1441cdf0e10cSrcweir         code->Emit( Emit::OpCodes::Stfld, members[ member_pos ] );
1442cdf0e10cSrcweir     }
1443cdf0e10cSrcweir     code->Emit( Emit::OpCodes::Ret );
1444cdf0e10cSrcweir     entry->m_ctor = ctor_builder;
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir     if (g_verbose)
1447cdf0e10cSrcweir     {
1448cdf0e10cSrcweir         ::System::Console::WriteLine(
1449cdf0e10cSrcweir             "> emitting {0} type {1}",
1450cdf0e10cSrcweir             TypeClass_STRUCT == entry->m_xType->getTypeClass()
1451cdf0e10cSrcweir             ? S"struct"
1452cdf0e10cSrcweir             : S"exception",
1453cdf0e10cSrcweir             cts_name);
1454cdf0e10cSrcweir     }
1455cdf0e10cSrcweir     // new entry
1456cdf0e10cSrcweir     m_generated_structs->Add(cts_name, entry );
1457cdf0e10cSrcweir     ::System::Type * ret_type = entry->m_type_builder->CreateType();
1458cdf0e10cSrcweir 
1459cdf0e10cSrcweir     // remove from incomplete types map
1460cdf0e10cSrcweir     m_incomplete_structs->Remove( cts_name );
1461cdf0e10cSrcweir     entry->m_xType->release();
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir     if (g_verbose)
1464cdf0e10cSrcweir     {
1465cdf0e10cSrcweir         ::System::Console::WriteLine(
1466cdf0e10cSrcweir             "> emitting struct type {0}", cts_name);
1467cdf0e10cSrcweir     }
1468cdf0e10cSrcweir     return ret_type;
1469cdf0e10cSrcweir }
1470cdf0e10cSrcweir 
1471cdf0e10cSrcweir //Examples of generated code
1472cdf0e10cSrcweir // 		public static XWeak constructor1(XComponentContext ctx)
1473cdf0e10cSrcweir // 		{
1474cdf0e10cSrcweir // 			XMultiComponentFactory factory = ctx.getServiceManager();
1475cdf0e10cSrcweir // 			if (factory == null)
1476cdf0e10cSrcweir // 				throw new com.sun.star.uno.DeploymentException("bla", null);
1477cdf0e10cSrcweir // 			return (XWeak) factory.createInstanceWithContext("service_specifier", ctx);
1478cdf0e10cSrcweir // 		}
1479cdf0e10cSrcweir // 		public static XWeak constructor2(XComponentContext ctx, int a, int b, Any c)
1480cdf0e10cSrcweir // 		{
1481cdf0e10cSrcweir // 			XMultiComponentFactory factory = ctx.getServiceManager();
1482cdf0e10cSrcweir // 			if (factory == null)
1483cdf0e10cSrcweir // 				throw new com.sun.star.uno.DeploymentException("bla", null);
1484cdf0e10cSrcweir // 			Any[] arAny = new Any[3];
1485cdf0e10cSrcweir // 			arAny[0] = new Any(typeof(int), a);
1486cdf0e10cSrcweir // 			arAny[1] = new Any(typeof(int), b);
1487cdf0e10cSrcweir //			arAny[2] = new Any(c.Type, c.Value);
1488cdf0e10cSrcweir // 			return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", arAny, ctx);
1489cdf0e10cSrcweir // 		}
1490cdf0e10cSrcweir // Notice that a any parameter is NOT wrapped by another any. Instead the new any is created with the type and value
1491cdf0e10cSrcweir // of the parameter.
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir // 		public static XWeak constructor3(XComponentContext ctx, params Any[] c)
1494cdf0e10cSrcweir // 		{
1495cdf0e10cSrcweir // 			XMultiComponentFactory factory = ctx.getServiceManager();
1496cdf0e10cSrcweir // 			if (factory == null)
1497cdf0e10cSrcweir // 				throw new com.sun.star.uno.DeploymentException("bla", null);
1498cdf0e10cSrcweir // 			return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", c, ctx);
1499cdf0e10cSrcweir //		}
complete_service_type(service_entry * entry)1500cdf0e10cSrcweir ::System::Type * TypeEmitter::complete_service_type(service_entry * entry)
1501cdf0e10cSrcweir {
1502cdf0e10cSrcweir     Emit::TypeBuilder * type_builder = entry->m_type_builder;
1503cdf0e10cSrcweir     reflection::XServiceTypeDescription2 * xServiceType = entry->m_xType;
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir     //Create the private default constructor
1506cdf0e10cSrcweir     Emit::ConstructorBuilder* ctor_builder =
1507cdf0e10cSrcweir         type_builder->DefineConstructor(
1508cdf0e10cSrcweir             (MethodAttributes) (MethodAttributes::Private |
1509cdf0e10cSrcweir                                 MethodAttributes::HideBySig |
1510cdf0e10cSrcweir                                 MethodAttributes::SpecialName |
1511cdf0e10cSrcweir                                 MethodAttributes::RTSpecialName),
1512cdf0e10cSrcweir             CallingConventions::Standard, NULL);
1513cdf0e10cSrcweir 
1514cdf0e10cSrcweir     Emit::ILGenerator* ilGen = ctor_builder->GetILGenerator();
1515cdf0e10cSrcweir     ilGen->Emit( Emit::OpCodes::Ldarg_0 ); // push this
1516cdf0e10cSrcweir     ilGen->Emit(
1517cdf0e10cSrcweir             Emit::OpCodes::Call,
1518cdf0e10cSrcweir             type_builder->BaseType->GetConstructor(new ::System::Type*[0]));
1519cdf0e10cSrcweir     ilGen->Emit( Emit::OpCodes::Ret );
1520cdf0e10cSrcweir 
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir     //Create the service constructors.
1523cdf0e10cSrcweir     //obtain the interface which makes up this service, it is the return
1524cdf0e10cSrcweir     //type of the constructor functions
1525cdf0e10cSrcweir     Reference<reflection::XInterfaceTypeDescription2> xIfaceType(
1526cdf0e10cSrcweir         xServiceType->getInterface(), UNO_QUERY);
1527cdf0e10cSrcweir     if (xIfaceType.is () == sal_False)
1528cdf0e10cSrcweir         xIfaceType = resolveInterfaceTypedef(xServiceType->getInterface());
1529cdf0e10cSrcweir     System::Type * retType = get_type(xIfaceType);
1530cdf0e10cSrcweir 
1531cdf0e10cSrcweir     //Create the ConstructorInfo for a DeploymentException
1532cdf0e10cSrcweir     ::System::Type * typeDeploymentExc =
1533cdf0e10cSrcweir           get_type(S"unoidl.com.sun.star.uno.DeploymentException", true);
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir     ::System::Type * arTypeCtor[] = {__typeof(::System::String),
1536cdf0e10cSrcweir                                          __typeof(::System::Object)};
1537cdf0e10cSrcweir     ::System::Reflection::ConstructorInfo * ctorDeploymentException  =
1538cdf0e10cSrcweir           typeDeploymentExc->GetConstructor(arTypeCtor);
1539cdf0e10cSrcweir 
1540cdf0e10cSrcweir     Sequence<Reference<reflection::XServiceConstructorDescription> >  seqCtors =
1541cdf0e10cSrcweir         xServiceType->getConstructors();
1542cdf0e10cSrcweir 
1543cdf0e10cSrcweir     ::System::Type * type_uno_exception = get_type(S"unoidl.com.sun.star.uno.Exception", true);
1544cdf0e10cSrcweir 
1545cdf0e10cSrcweir     for (int i = seqCtors.getLength() - 1; i >= 0; i--)
1546cdf0e10cSrcweir     {
1547cdf0e10cSrcweir         bool bParameterArray = false;
1548cdf0e10cSrcweir         ::System::Type * typeAny = __typeof(::uno::Any);
1549cdf0e10cSrcweir         const Reference<reflection::XServiceConstructorDescription> & ctorDes =
1550cdf0e10cSrcweir             seqCtors[i];
1551cdf0e10cSrcweir         //obtain the parameter types
1552cdf0e10cSrcweir         Sequence<Reference<reflection::XParameter> > seqParams =
1553cdf0e10cSrcweir             ctorDes->getParameters();
1554cdf0e10cSrcweir         Reference<reflection::XParameter> const * arXParams = seqParams.getConstArray();
1555cdf0e10cSrcweir         sal_Int32 cParams = seqParams.getLength();
1556cdf0e10cSrcweir         ::System::Type * arTypeParameters[] = new ::System::Type* [cParams + 1];
1557cdf0e10cSrcweir         arTypeParameters[0] = get_type(S"unoidl.com.sun.star.uno.XComponentContext", true);
1558cdf0e10cSrcweir         for (int iparam = 0; iparam != cParams; iparam++)
1559cdf0e10cSrcweir         {
1560cdf0e10cSrcweir             if (arXParams[iparam]->isRestParameter())
1561cdf0e10cSrcweir                 arTypeParameters[iparam + 1] = __typeof(::uno::Any[]);
1562cdf0e10cSrcweir             else
1563cdf0e10cSrcweir                 arTypeParameters[iparam + 1] = get_type(arXParams[iparam]->getType());
1564cdf0e10cSrcweir         }
1565cdf0e10cSrcweir         //The array arTypeParameters can contain:
1566cdf0e10cSrcweir 		//System.Type and uno.PolymorphicType.
1567cdf0e10cSrcweir 		//Passing PolymorphicType to MethodBuilder.DefineMethod will cause a problem.
1568cdf0e10cSrcweir 		//The exception will read something like no on information for parameter # d
1569cdf0e10cSrcweir 		//Maybe we need no override another Type method in PolymorphicType ...
1570cdf0e10cSrcweir 		//Until we have figured this out, we will create another array of System.Type which
1571cdf0e10cSrcweir 		//we pass on to DefineMethod.
1572cdf0e10cSrcweir 		::System::Type * arParamTypes[] = new ::System::Type * [cParams + 1];
1573cdf0e10cSrcweir //        arParamTypes[0] = get_type(S"unoidl.com.sun.star.uno.XComponentContext", true);
1574cdf0e10cSrcweir 		for (int i = 0; i < cParams + 1; i++)
1575cdf0e10cSrcweir 		{
1576cdf0e10cSrcweir 			::uno::PolymorphicType * pT = dynamic_cast< ::uno::PolymorphicType * >(arTypeParameters[i]);
1577cdf0e10cSrcweir 			if (pT)
1578cdf0e10cSrcweir 				arParamTypes[i] = pT->OriginalType;
1579cdf0e10cSrcweir 			else
1580cdf0e10cSrcweir 				arParamTypes[i] = arTypeParameters[i];
1581cdf0e10cSrcweir 		}
1582cdf0e10cSrcweir         //define method
1583cdf0e10cSrcweir 		System::String * ctorName;
1584cdf0e10cSrcweir         if (ctorDes->isDefaultConstructor())
1585cdf0e10cSrcweir             ctorName = new ::System::String(S"create");
1586cdf0e10cSrcweir         else
1587cdf0e10cSrcweir             ctorName = ustring_to_String(ctorDes->getName());
1588cdf0e10cSrcweir         Emit::MethodBuilder* method_builder = type_builder->DefineMethod(
1589cdf0e10cSrcweir             ctorName,
1590cdf0e10cSrcweir             static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::HideBySig |
1591cdf0e10cSrcweir                                           MethodAttributes::Static),
1592cdf0e10cSrcweir             retType,
1593cdf0e10cSrcweir //            arTypeParameters);
1594cdf0e10cSrcweir 			arParamTypes);
1595cdf0e10cSrcweir 
1596cdf0e10cSrcweir         //define UNO exception attribute (exceptions)--------------------------------------
1597cdf0e10cSrcweir         Emit::CustomAttributeBuilder* attrBuilder = get_service_exception_attribute(ctorDes);
1598cdf0e10cSrcweir         if (attrBuilder != NULL)
1599cdf0e10cSrcweir             method_builder->SetCustomAttribute(attrBuilder);
1600cdf0e10cSrcweir 
1601cdf0e10cSrcweir 		//-------------------------------------------------------------
1602cdf0e10cSrcweir         //define parameter attributes (paramarray), names etc.
1603cdf0e10cSrcweir         //The first parameter is the XComponentContext, which cannot be obtained
1604cdf0e10cSrcweir         //from reflection.
1605cdf0e10cSrcweir         //The context is not part of the idl description
1606cdf0e10cSrcweir         method_builder->DefineParameter(
1607cdf0e10cSrcweir             1, ParameterAttributes::In, S"the_context");
1608cdf0e10cSrcweir 
1609cdf0e10cSrcweir         Emit::ParameterBuilder * arParameterBuilder[] =
1610cdf0e10cSrcweir             new Emit::ParameterBuilder * [cParams];
1611cdf0e10cSrcweir         for (int iparam = 0; iparam != cParams; iparam++)
1612cdf0e10cSrcweir         {
1613cdf0e10cSrcweir             Reference<reflection::XParameter> const & aParam = arXParams[iparam];
1614cdf0e10cSrcweir             ::System::String * sParamName = ustring_to_String(aParam->getName());
1615cdf0e10cSrcweir 
1616cdf0e10cSrcweir             arParameterBuilder[iparam] = method_builder->DefineParameter(
1617cdf0e10cSrcweir                 iparam + 2, ParameterAttributes::In, sParamName);
1618cdf0e10cSrcweir 
1619cdf0e10cSrcweir             if (aParam->isRestParameter())
1620cdf0e10cSrcweir             {
1621cdf0e10cSrcweir                 bParameterArray = true;
1622cdf0e10cSrcweir                 //set the ParameterArrayAttribute
1623cdf0e10cSrcweir                 ::System::Reflection::ConstructorInfo* ctor_info =
1624cdf0e10cSrcweir                     __typeof(System::ParamArrayAttribute)->GetConstructor(
1625cdf0e10cSrcweir                         new ::System::Type*[0]);
1626cdf0e10cSrcweir                 Emit::CustomAttributeBuilder * attr_builder =
1627cdf0e10cSrcweir                     new Emit::CustomAttributeBuilder(ctor_info, new ::System::Object*[0]);
1628cdf0e10cSrcweir 				arParameterBuilder[iparam]->SetCustomAttribute(attr_builder);
1629cdf0e10cSrcweir                 break;
1630cdf0e10cSrcweir             }
1631cdf0e10cSrcweir         }
1632cdf0e10cSrcweir 
1633cdf0e10cSrcweir         Emit::ILGenerator * ilGen = method_builder->GetILGenerator();
1634cdf0e10cSrcweir 
1635cdf0e10cSrcweir         //Define locals ---------------------------------
1636cdf0e10cSrcweir         //XMultiComponentFactory
1637cdf0e10cSrcweir         Emit::LocalBuilder* local_factory =
1638cdf0e10cSrcweir             ilGen->DeclareLocal(
1639cdf0e10cSrcweir                 get_type(S"unoidl.com.sun.star.lang.XMultiComponentFactory", true));
1640cdf0e10cSrcweir 
1641cdf0e10cSrcweir         //The return type
1642cdf0e10cSrcweir         Emit::LocalBuilder* local_return_val =
1643cdf0e10cSrcweir             ilGen->DeclareLocal(retType);
1644cdf0e10cSrcweir 
1645cdf0e10cSrcweir         //Obtain the XMultiComponentFactory and throw an exception if we do not get one
1646cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ldarg_0);
1647cdf0e10cSrcweir 
1648cdf0e10cSrcweir         ::System::Reflection::MethodInfo * methodGetServiceManager = get_type(
1649cdf0e10cSrcweir             S"unoidl.com.sun.star.uno.XComponentContext", true)
1650cdf0e10cSrcweir                 ->GetMethod(S"getServiceManager");
1651cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Callvirt, methodGetServiceManager);
1652cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Stloc, local_factory);
1653cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ldloc, local_factory);
1654cdf0e10cSrcweir         Emit::Label label1 = ilGen->DefineLabel();
1655cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Brtrue, label1);
1656cdf0e10cSrcweir         //The string for the exception
1657cdf0e10cSrcweir         ::System::Text::StringBuilder * strbuilder = new ::System::Text::StringBuilder(256);
1658cdf0e10cSrcweir         strbuilder->Append(S"The service ");
1659cdf0e10cSrcweir         strbuilder->Append(to_cts_name(xServiceType->getName()));
1660cdf0e10cSrcweir         strbuilder->Append(S" could not be created. The context failed to supply the service manager.");
1661cdf0e10cSrcweir 
1662cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString());
1663cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ldarg_0);
1664cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException);
1665cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Throw);
1666cdf0e10cSrcweir         ilGen->MarkLabel(label1);
1667cdf0e10cSrcweir 
1668cdf0e10cSrcweir         //We create a try/ catch around the createInstanceWithContext, etc. functions
1669cdf0e10cSrcweir         //There are 3 cases
1670cdf0e10cSrcweir         //1. function do not specify exceptions. Then RuntimeExceptions are retrhown and other
1671cdf0e10cSrcweir         //   exceptions produce a DeploymentException.
1672cdf0e10cSrcweir         //2. function specify  Exception. Then all exceptions fly through
1673cdf0e10cSrcweir         //3. function specifies exceptions but no Exception. Then these are rethrown
1674cdf0e10cSrcweir         //   and other exceptions, except RuntimeException, produce a deployment exception.
1675cdf0e10cSrcweir         //In case there are no parameters we call
1676cdf0e10cSrcweir         //XMultiComponentFactory.createInstanceWithContext
1677cdf0e10cSrcweir 
1678cdf0e10cSrcweir         ::System::Collections::ArrayList * arExceptionTypes =
1679cdf0e10cSrcweir               get_service_ctor_method_exceptions_reduced(ctorDes->getExceptions());
1680cdf0e10cSrcweir         if (arExceptionTypes->Contains(
1681cdf0e10cSrcweir                 type_uno_exception) == false)
1682cdf0e10cSrcweir         {
1683cdf0e10cSrcweir             ilGen->BeginExceptionBlock();
1684cdf0e10cSrcweir         }
1685cdf0e10cSrcweir         if (cParams == 0)
1686cdf0e10cSrcweir         {
1687cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldloc, local_factory);
1688cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName()));
1689cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldarg_0);
1690cdf0e10cSrcweir 
1691cdf0e10cSrcweir             ::System::Reflection::MethodInfo * methodCreate =
1692cdf0e10cSrcweir                     local_factory->get_LocalType()->GetMethod(S"createInstanceWithContext");
1693cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate);
1694cdf0e10cSrcweir         }
1695cdf0e10cSrcweir         else if(bParameterArray)
1696cdf0e10cSrcweir         {
1697cdf0e10cSrcweir             //Service constructor with parameter array
1698cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldloc, local_factory);
1699cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName()));
1700cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldarg_1);
1701cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldarg_0);
1702cdf0e10cSrcweir             ::System::Reflection::MethodInfo * methodCreate =
1703cdf0e10cSrcweir                     local_factory->get_LocalType()->GetMethod(S"createInstanceWithArgumentsAndContext");
1704cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate);
1705cdf0e10cSrcweir         }
1706cdf0e10cSrcweir         else
1707cdf0e10cSrcweir         {
1708cdf0e10cSrcweir             // Any param1, Any param2, etc.
1709cdf0e10cSrcweir             // For each parameter,except the component context, and parameter array
1710cdf0e10cSrcweir             // and Any is created.
1711cdf0e10cSrcweir             Emit::LocalBuilder * arLocalAny[] = new Emit::LocalBuilder* [cParams];
1712cdf0e10cSrcweir 
1713cdf0e10cSrcweir             for (int iParam = 0; iParam < cParams; iParam ++)
1714cdf0e10cSrcweir             {
1715cdf0e10cSrcweir                 arLocalAny[iParam] = ilGen->DeclareLocal(typeAny);
1716cdf0e10cSrcweir             }
1717cdf0e10cSrcweir 
1718cdf0e10cSrcweir             //Any[]. This array is filled with the created Anys which contain the parameters
1719cdf0e10cSrcweir             //and the values contained in the parameter array
1720cdf0e10cSrcweir             Emit::LocalBuilder * local_anyParams =
1721cdf0e10cSrcweir                 ilGen->DeclareLocal(__typeof(::uno::Any[]));
1722cdf0e10cSrcweir 
1723cdf0e10cSrcweir             //Create the Any for every argument, except for the parameter array
1724cdf0e10cSrcweir             //arLocalAny contains the LocalBuilder for all these parameters.
1725cdf0e10cSrcweir             //we call the ctor Any(Type, Object)
1726cdf0e10cSrcweir 			//If the parameter is an Any then the Any is created with Any(param.Type, param.Value);
1727cdf0e10cSrcweir             ::System::Type * arTypesCtorAny[] = {__typeof(::System::Type),
1728cdf0e10cSrcweir                                                     __typeof(::System::Object)};
1729cdf0e10cSrcweir             ::System::Reflection::ConstructorInfo * ctorAny =
1730cdf0e10cSrcweir                 typeAny->GetConstructor( arTypesCtorAny);
1731cdf0e10cSrcweir 			::System::Reflection::MethodInfo * methodAnyGetType =
1732cdf0e10cSrcweir 				typeAny->GetProperty(S"Type")->GetGetMethod();
1733cdf0e10cSrcweir 			::System::Reflection::MethodInfo * methodAnyGetValue =
1734cdf0e10cSrcweir 				typeAny->GetProperty(S"Value")->GetGetMethod();
1735cdf0e10cSrcweir             for (int i = 0; i < arLocalAny->Length; i ++)
1736cdf0e10cSrcweir             {
1737cdf0e10cSrcweir 				//check if the parameter is a polymorphic struct
1738cdf0e10cSrcweir 				::uno::PolymorphicType *polyType = dynamic_cast< ::uno::PolymorphicType* >(arTypeParameters[i+1]);
1739cdf0e10cSrcweir 				//arTypeParameters[i+1] = polyType->OriginalType;
1740cdf0e10cSrcweir 				if (polyType)
1741cdf0e10cSrcweir 				{
1742cdf0e10cSrcweir 					//It is a polymorphic struct
1743cdf0e10cSrcweir 					//Load the uninitialized local Any on which we will call the ctor
1744cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]);
1745cdf0e10cSrcweir 					// Call PolymorphicType PolymorphicType::GetType(Type t, String polyName)
1746cdf0e10cSrcweir 					// Prepare the first parameter
1747cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldtoken, polyType->get_OriginalType());
1748cdf0e10cSrcweir 					::System::Type * arTypeParams[] = {__typeof(::System::RuntimeTypeHandle)};
1749cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Call,
1750cdf0e10cSrcweir 								__typeof(::System::Type)->GetMethod(
1751cdf0e10cSrcweir 									S"GetTypeFromHandle", arTypeParams));
1752cdf0e10cSrcweir 					// Prepare the second parameter
1753cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldstr, polyType->get_PolymorphicName());
1754cdf0e10cSrcweir 					// Make the actual call
1755cdf0e10cSrcweir 					::System::Type * arTypeParam_GetType[] = {
1756cdf0e10cSrcweir 						__typeof(::System::Type), __typeof(::System::String) };
1757cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Call,
1758cdf0e10cSrcweir 					__typeof(::uno::PolymorphicType)->GetMethod(new System::String(S"GetType"),
1759cdf0e10cSrcweir 						arTypeParam_GetType));
1760cdf0e10cSrcweir 
1761cdf0e10cSrcweir 					//Stack is: localAny, PolymorphicType
1762cdf0e10cSrcweir 					//Call Any::Any(Type, Object)
1763cdf0e10cSrcweir 					//Prepare the second parameter for the any ctor
1764cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldarg, i + 1);
1765cdf0e10cSrcweir 					// if the parameter is a value type then we need to box it, because
1766cdf0e10cSrcweir 					// the Any ctor takes an Object
1767cdf0e10cSrcweir 					if (arTypeParameters[i+1]->IsValueType)
1768cdf0e10cSrcweir 						ilGen->Emit(Emit::OpCodes::Box, arTypeParameters[i+1]);
1769cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Call, ctorAny);
1770cdf0e10cSrcweir 				}
1771cdf0e10cSrcweir 				else if (arTypeParameters[i+1] == typeAny)
1772cdf0e10cSrcweir 				{
1773cdf0e10cSrcweir 					//Create the call new Any(param.Type,param,Value)
1774cdf0e10cSrcweir 					//Stack must be Any,Type,Value
1775cdf0e10cSrcweir 					//First load the Any which is to be constructed
1776cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]);
1777cdf0e10cSrcweir 					//Load the Type, which is obtained by calling param.Type
1778cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldarga, i + 1);
1779cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Call, methodAnyGetType);
1780cdf0e10cSrcweir 					//Load the Value, which is obtained by calling param.Value
1781cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldarga, i + 1);
1782cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Call, methodAnyGetValue);
1783cdf0e10cSrcweir 					//Call the Any ctor.
1784cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Call, ctorAny);
1785cdf0e10cSrcweir 				}
1786cdf0e10cSrcweir 				else
1787cdf0e10cSrcweir 				{
1788cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]);
1789cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldtoken, arTypeParameters[i+1]);
1790cdf0e10cSrcweir 
1791cdf0e10cSrcweir 					::System::Type * arTypeParams[] = {__typeof(::System::RuntimeTypeHandle)};
1792cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Call,
1793cdf0e10cSrcweir 								__typeof(::System::Type)->GetMethod(
1794cdf0e10cSrcweir 									S"GetTypeFromHandle", arTypeParams));
1795cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Ldarg, i + 1);
1796cdf0e10cSrcweir 					// if the parameter is a value type then we need to box it, because
1797cdf0e10cSrcweir 					// the Any ctor takes an Object
1798cdf0e10cSrcweir 					if (arTypeParameters[i+1]->IsValueType)
1799cdf0e10cSrcweir 						ilGen->Emit(Emit::OpCodes::Box, arTypeParameters[i+1]);
1800cdf0e10cSrcweir 					ilGen->Emit(Emit::OpCodes::Call, ctorAny);
1801cdf0e10cSrcweir 				}
1802cdf0e10cSrcweir             }
1803cdf0e10cSrcweir 
1804cdf0e10cSrcweir             //Create the Any[] that is passed to the
1805cdf0e10cSrcweir             //createInstanceWithContext[AndArguments] function
1806cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldc_I4, arLocalAny->Length);
1807cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Newarr, typeAny);
1808cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Stloc, local_anyParams);
1809cdf0e10cSrcweir 
1810cdf0e10cSrcweir             //Assign all anys created from the parameters
1811cdf0e10cSrcweir             //array to the Any[]
1812cdf0e10cSrcweir             for (int i = 0; i < arLocalAny->Length; i++)
1813cdf0e10cSrcweir             {
1814cdf0e10cSrcweir                 ilGen->Emit(Emit::OpCodes::Ldloc, local_anyParams);
1815cdf0e10cSrcweir                 ilGen->Emit(Emit::OpCodes::Ldc_I4, i);
1816cdf0e10cSrcweir                 ilGen->Emit(Emit::OpCodes::Ldelema, typeAny);
1817cdf0e10cSrcweir                 ilGen->Emit(Emit::OpCodes::Ldloc, arLocalAny[i]);
1818cdf0e10cSrcweir                 ilGen->Emit(Emit::OpCodes::Stobj, typeAny);
1819cdf0e10cSrcweir             }
1820cdf0e10cSrcweir             // call createInstanceWithContextAndArguments
1821cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldloc, local_factory);
1822cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName()));
1823cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldloc, local_anyParams);
1824cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldarg_0);
1825cdf0e10cSrcweir             ::System::Reflection::MethodInfo * methodCreate =
1826cdf0e10cSrcweir                     local_factory->get_LocalType()->GetMethod(S"createInstanceWithArgumentsAndContext");
1827cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate);
1828cdf0e10cSrcweir         }
1829cdf0e10cSrcweir         //cast the object returned by the functions createInstanceWithContext or
1830cdf0e10cSrcweir         //createInstanceWithArgumentsAndContext to the interface type
1831cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Castclass, retType);
1832cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Stloc, local_return_val);
1833cdf0e10cSrcweir 
1834cdf0e10cSrcweir         //catch exceptions thrown by createInstanceWithArgumentsAndContext and createInstanceWithContext
1835cdf0e10cSrcweir         if (arExceptionTypes->Contains(type_uno_exception) == false)
1836cdf0e10cSrcweir         {
1837cdf0e10cSrcweir             // catch (unoidl.com.sun.star.uno.RuntimeException) {throw;}
1838cdf0e10cSrcweir             ilGen->BeginCatchBlock(get_type(S"unoidl.com.sun.star.uno.RuntimeException", true));
1839cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Pop);
1840cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Rethrow);
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir             //catch and rethrow all other defined Exceptions
1843cdf0e10cSrcweir             for (int i = 0; i < arExceptionTypes->Count; i++)
1844cdf0e10cSrcweir             {
1845cdf0e10cSrcweir                 ::System::Type * excType = __try_cast< ::System::Type* >(
1846cdf0e10cSrcweir                     arExceptionTypes->get_Item(i));
1847cdf0e10cSrcweir                 if (excType->IsInstanceOfType(
1848cdf0e10cSrcweir                         get_type(S"unoidl.com.sun.star.uno.RuntimeException", true)))
1849cdf0e10cSrcweir                 {// we have a catch for RuntimeException already defined
1850cdf0e10cSrcweir                     continue;
1851cdf0e10cSrcweir                 }
1852cdf0e10cSrcweir 
1853cdf0e10cSrcweir                 //catch Exception and rethrow
1854cdf0e10cSrcweir                 ilGen->BeginCatchBlock(excType);
1855cdf0e10cSrcweir                 ilGen->Emit(Emit::OpCodes::Pop);
1856cdf0e10cSrcweir                 ilGen->Emit(Emit::OpCodes::Rethrow);
1857cdf0e10cSrcweir             }
1858cdf0e10cSrcweir             //catch (unoidl.com.sun.star.uno.Exception) {throw DeploymentException...}
1859cdf0e10cSrcweir             ilGen->BeginCatchBlock(type_uno_exception);
1860cdf0e10cSrcweir 
1861cdf0e10cSrcweir             //Define the local variabe that keeps the exception
1862cdf0e10cSrcweir              Emit::LocalBuilder * local_exception = ilGen->DeclareLocal(
1863cdf0e10cSrcweir                  type_uno_exception);
1864cdf0e10cSrcweir 
1865cdf0e10cSrcweir              //Store the exception
1866cdf0e10cSrcweir              ilGen->Emit(Emit::OpCodes::Stloc, local_exception);
1867cdf0e10cSrcweir 
1868cdf0e10cSrcweir             //prepare the construction of the exception
1869cdf0e10cSrcweir              strbuilder = new ::System::Text::StringBuilder(256);
1870cdf0e10cSrcweir              strbuilder->Append(S"The context (com.sun.star.uno.XComponentContext) failed to supply the service ");
1871cdf0e10cSrcweir              strbuilder->Append(to_cts_name(xServiceType->getName()));
1872cdf0e10cSrcweir              strbuilder->Append(S": ");
1873cdf0e10cSrcweir 
1874cdf0e10cSrcweir              ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString());
1875cdf0e10cSrcweir 
1876cdf0e10cSrcweir             //add to the string the Exception.Message
1877cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldloc, local_exception);
1878cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Callvirt,
1879cdf0e10cSrcweir                         type_uno_exception->GetProperty(S"Message")->GetGetMethod());
1880cdf0e10cSrcweir             ::System::Type * arConcatParams [] = {__typeof(System::String),
1881cdf0e10cSrcweir                                                   __typeof(System::String)};
1882cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Call,
1883cdf0e10cSrcweir                         __typeof(System::String)->GetMethod(S"Concat", arConcatParams));
1884cdf0e10cSrcweir             //load contex argument
1885cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Ldarg_0);
1886cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException);
1887cdf0e10cSrcweir             ilGen->Emit(Emit::OpCodes::Throw);//Exception(typeDeploymentExc);
1888cdf0e10cSrcweir 
1889cdf0e10cSrcweir             ilGen->EndExceptionBlock();
1890cdf0e10cSrcweir         }
1891cdf0e10cSrcweir 
1892cdf0e10cSrcweir 
1893cdf0e10cSrcweir         //Check if the service instance was create and throw a exception if not.
1894cdf0e10cSrcweir         Emit::Label label_service_created = ilGen->DefineLabel();
1895cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ldloc, local_return_val);
1896cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Brtrue_S, label_service_created);
1897cdf0e10cSrcweir 
1898cdf0e10cSrcweir         strbuilder = new ::System::Text::StringBuilder(256);
1899cdf0e10cSrcweir         strbuilder->Append(S"The context (com.sun.star.uno.XComponentContext) failed to supply the service ");
1900cdf0e10cSrcweir         strbuilder->Append(to_cts_name(xServiceType->getName()));
1901cdf0e10cSrcweir         strbuilder->Append(S".");
1902cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString());
1903cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ldarg_0);
1904cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException);
1905cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Throw);//Exception(typeDeploymentExc);
1906cdf0e10cSrcweir 
1907cdf0e10cSrcweir         ilGen->MarkLabel(label_service_created);
1908cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ldloc, local_return_val);
1909cdf0e10cSrcweir         ilGen->Emit(Emit::OpCodes::Ret);
1910cdf0e10cSrcweir 
1911cdf0e10cSrcweir     }
1912cdf0e10cSrcweir     // remove from incomplete types map
1913cdf0e10cSrcweir     ::System::String * cts_name = type_builder->get_FullName();
1914cdf0e10cSrcweir     m_incomplete_services->Remove( cts_name );
1915cdf0e10cSrcweir     xServiceType->release();
1916cdf0e10cSrcweir     if (g_verbose)
1917cdf0e10cSrcweir     {
1918cdf0e10cSrcweir         ::System::Console::WriteLine(
1919cdf0e10cSrcweir             "> emitting service type {0}", cts_name );
1920cdf0e10cSrcweir     }
1921cdf0e10cSrcweir     return type_builder->CreateType();
1922cdf0e10cSrcweir }
1923cdf0e10cSrcweir 
1924cdf0e10cSrcweir 
get_service_exception_attribute(const Reference<reflection::XServiceConstructorDescription> & ctorDes)1925cdf0e10cSrcweir Emit::CustomAttributeBuilder* TypeEmitter::get_service_exception_attribute(
1926cdf0e10cSrcweir     const Reference<reflection::XServiceConstructorDescription> & ctorDes  )
1927cdf0e10cSrcweir {
1928cdf0e10cSrcweir     return get_exception_attribute(ctorDes->getExceptions());
1929cdf0e10cSrcweir }
1930cdf0e10cSrcweir 
get_iface_method_exception_attribute(const Reference<reflection::XInterfaceMethodTypeDescription> & xMethod)1931cdf0e10cSrcweir Emit::CustomAttributeBuilder* TypeEmitter::get_iface_method_exception_attribute(
1932cdf0e10cSrcweir     const Reference< reflection::XInterfaceMethodTypeDescription >& xMethod )
1933cdf0e10cSrcweir {
1934cdf0e10cSrcweir 
1935cdf0e10cSrcweir     const Sequence<Reference<reflection::XTypeDescription> > seqTD = xMethod->getExceptions();
1936cdf0e10cSrcweir     int len = seqTD.getLength();
1937cdf0e10cSrcweir     Sequence<Reference<reflection::XCompoundTypeDescription> > seqCTD(len);
1938cdf0e10cSrcweir     Reference<reflection::XCompoundTypeDescription> * arCTD = seqCTD.getArray();
1939cdf0e10cSrcweir     for (int i = 0; i < len; i++)
1940cdf0e10cSrcweir         arCTD[i] = Reference<reflection::XCompoundTypeDescription>(seqTD[i], UNO_QUERY_THROW);
1941cdf0e10cSrcweir     return get_exception_attribute(seqCTD);
1942cdf0e10cSrcweir }
1943cdf0e10cSrcweir 
get_exception_attribute(const Sequence<Reference<reflection::XCompoundTypeDescription>> & seq_exceptionsTd)1944cdf0e10cSrcweir Emit::CustomAttributeBuilder* TypeEmitter::get_exception_attribute(
1945cdf0e10cSrcweir 
1946cdf0e10cSrcweir     const Sequence<Reference< reflection::XCompoundTypeDescription > >& seq_exceptionsTd )
1947cdf0e10cSrcweir {
1948cdf0e10cSrcweir     Emit::CustomAttributeBuilder * attr_builder = NULL;
1949cdf0e10cSrcweir 
1950cdf0e10cSrcweir     Reference< reflection::XCompoundTypeDescription > const * exceptions =
1951cdf0e10cSrcweir         seq_exceptionsTd.getConstArray();
1952cdf0e10cSrcweir 
1953cdf0e10cSrcweir     ::System::Type * arTypesCtor[] = {::System::Type::GetType(S"System.Type[]")};
1954cdf0e10cSrcweir     ConstructorInfo * ctor_ExceptionAttribute =
1955cdf0e10cSrcweir         __typeof(::uno::ExceptionAttribute)->GetConstructor(arTypesCtor);
1956cdf0e10cSrcweir 
1957cdf0e10cSrcweir     sal_Int32 exc_length = seq_exceptionsTd.getLength();
1958cdf0e10cSrcweir     if (exc_length != 0) // opt
1959cdf0e10cSrcweir     {
1960cdf0e10cSrcweir         ::System::Type * exception_types [] =
1961cdf0e10cSrcweir               new ::System::Type * [ exc_length ];
1962cdf0e10cSrcweir         for ( sal_Int32 exc_pos = 0; exc_pos < exc_length; ++exc_pos )
1963cdf0e10cSrcweir         {
1964cdf0e10cSrcweir             Reference< reflection::XCompoundTypeDescription > const & xExc =
1965cdf0e10cSrcweir                 exceptions[ exc_pos ];
1966cdf0e10cSrcweir             exception_types[ exc_pos ] = get_type( xExc );
1967cdf0e10cSrcweir         }
1968cdf0e10cSrcweir         ::System::Object * args [] = {exception_types};
1969cdf0e10cSrcweir         attr_builder = new Emit::CustomAttributeBuilder(
1970cdf0e10cSrcweir             ctor_ExceptionAttribute, args );
1971cdf0e10cSrcweir     }
1972cdf0e10cSrcweir     return attr_builder;
1973cdf0e10cSrcweir }
1974cdf0e10cSrcweir 
1975cdf0e10cSrcweir 
complete_singleton_type(singleton_entry * entry)1976cdf0e10cSrcweir ::System::Type * TypeEmitter::complete_singleton_type(singleton_entry * entry)
1977cdf0e10cSrcweir {
1978cdf0e10cSrcweir     Emit::TypeBuilder * type_builder = entry->m_type_builder;
1979cdf0e10cSrcweir     reflection::XSingletonTypeDescription2 * xSingletonType = entry->m_xType;
1980cdf0e10cSrcweir     ::System::String* sSingletonName = to_cts_name(xSingletonType->getName());
1981cdf0e10cSrcweir 
1982cdf0e10cSrcweir     //Create the private default constructor
1983cdf0e10cSrcweir     Emit::ConstructorBuilder* ctor_builder =
1984cdf0e10cSrcweir         type_builder->DefineConstructor(
1985cdf0e10cSrcweir             static_cast<MethodAttributes>(MethodAttributes::Private |
1986cdf0e10cSrcweir                                           MethodAttributes::HideBySig |
1987cdf0e10cSrcweir                                           MethodAttributes::SpecialName |
1988cdf0e10cSrcweir                                           MethodAttributes::RTSpecialName),
1989cdf0e10cSrcweir             CallingConventions::Standard, NULL);
1990cdf0e10cSrcweir 
1991cdf0e10cSrcweir     Emit::ILGenerator* ilGen = ctor_builder->GetILGenerator();
1992cdf0e10cSrcweir     ilGen->Emit( Emit::OpCodes::Ldarg_0 ); // push this
1993cdf0e10cSrcweir     ilGen->Emit(
1994cdf0e10cSrcweir             Emit::OpCodes::Call,
1995cdf0e10cSrcweir             type_builder->BaseType->GetConstructor(new ::System::Type*[0]));
1996cdf0e10cSrcweir     ilGen->Emit( Emit::OpCodes::Ret );
1997cdf0e10cSrcweir 
1998cdf0e10cSrcweir 
1999cdf0e10cSrcweir     //obtain the interface which makes up this service, it is the return
2000cdf0e10cSrcweir     //type of the constructor functions
2001cdf0e10cSrcweir     Reference<reflection::XInterfaceTypeDescription2> xIfaceType(
2002cdf0e10cSrcweir         xSingletonType->getInterface(), UNO_QUERY);
2003cdf0e10cSrcweir     if (xIfaceType.is () == sal_False)
2004cdf0e10cSrcweir         xIfaceType = resolveInterfaceTypedef(xSingletonType->getInterface());
2005cdf0e10cSrcweir     System::Type * retType = get_type(xIfaceType);
2006cdf0e10cSrcweir 
2007cdf0e10cSrcweir     //define method
2008cdf0e10cSrcweir     ::System::Type * arTypeParameters[] = {get_type(S"unoidl.com.sun.star.uno.XComponentContext", true)};
2009cdf0e10cSrcweir     Emit::MethodBuilder* method_builder = type_builder->DefineMethod(
2010cdf0e10cSrcweir         new System::String(S"get"),
2011cdf0e10cSrcweir         static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::HideBySig |
2012cdf0e10cSrcweir                                       MethodAttributes::Static),
2013cdf0e10cSrcweir         retType,
2014cdf0e10cSrcweir         arTypeParameters);
2015cdf0e10cSrcweir 
2016cdf0e10cSrcweir 
2017cdf0e10cSrcweir //         method_builder->SetCustomAttribute(get_service_ctor_method_attribute(ctorDes));
2018cdf0e10cSrcweir 
2019cdf0e10cSrcweir     //The first parameter is the XComponentContext, which cannot be obtained
2020cdf0e10cSrcweir     //from reflection.
2021cdf0e10cSrcweir     //The context is not part of the idl description
2022cdf0e10cSrcweir     method_builder->DefineParameter(1, ParameterAttributes::In, S"the_context");
2023cdf0e10cSrcweir 
2024cdf0e10cSrcweir 
2025cdf0e10cSrcweir     ilGen = method_builder->GetILGenerator();
2026cdf0e10cSrcweir     //Define locals ---------------------------------
2027cdf0e10cSrcweir 	// Any, returned by XComponentContext.getValueByName
2028cdf0e10cSrcweir 	Emit::LocalBuilder* local_any =
2029cdf0e10cSrcweir 		ilGen->DeclareLocal(__typeof(::uno::Any));
2030cdf0e10cSrcweir 
2031cdf0e10cSrcweir     //Call XContext::getValueByName
2032cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Ldarg_0);
2033cdf0e10cSrcweir     // build the singleton name : /singleton/unoidl.com.sun.star.XXX
2034cdf0e10cSrcweir     ::System::Text::StringBuilder* sBuilder =
2035cdf0e10cSrcweir           new ::System::Text::StringBuilder(S"/singletons/");
2036cdf0e10cSrcweir     sBuilder->Append(sSingletonName);
2037cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Ldstr, sBuilder->ToString());
2038cdf0e10cSrcweir 
2039cdf0e10cSrcweir     ::System::Reflection::MethodInfo * methodGetValueByName =
2040cdf0e10cSrcweir           get_type(S"unoidl.com.sun.star.uno.XComponentContext", true)->GetMethod(S"getValueByName");
2041cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Callvirt, methodGetValueByName);
2042cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Stloc_0);
2043cdf0e10cSrcweir 
2044cdf0e10cSrcweir     //Contains the returned Any a value?
2045cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Ldloca_S, local_any);
2046cdf0e10cSrcweir     ::System::Reflection::MethodInfo * methodHasValue =
2047cdf0e10cSrcweir           __typeof(::uno::Any)->GetMethod(S"hasValue");
2048cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Call, methodHasValue);
2049cdf0e10cSrcweir 
2050cdf0e10cSrcweir     //If not, then throw an DeploymentException
2051cdf0e10cSrcweir     Emit::Label label_singleton_exists = ilGen->DefineLabel();
2052cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Brtrue_S, label_singleton_exists);
2053cdf0e10cSrcweir     sBuilder = new ::System::Text::StringBuilder(
2054cdf0e10cSrcweir         S"Component context fails to supply singleton ");
2055cdf0e10cSrcweir     sBuilder->Append(sSingletonName);
2056cdf0e10cSrcweir     sBuilder->Append(S" of type ");
2057cdf0e10cSrcweir     sBuilder->Append(retType->FullName);
2058cdf0e10cSrcweir     sBuilder->Append(S".");
2059cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Ldstr, sBuilder->ToString());
2060cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Ldarg_0);
2061cdf0e10cSrcweir     ::System::Type * arTypesCtorDeploymentException[] = {
2062cdf0e10cSrcweir         __typeof(::System::String), __typeof(::System::Object)};
2063cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Newobj,
2064cdf0e10cSrcweir                 get_type(S"unoidl.com.sun.star.uno.DeploymentException",true)
2065cdf0e10cSrcweir                 ->GetConstructor(arTypesCtorDeploymentException));
2066cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Throw);
2067cdf0e10cSrcweir     ilGen->MarkLabel(label_singleton_exists);
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir     //Cast the singleton contained in the Any to the expected interface and return it.
2070cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Ldloca_S, local_any);
2071cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Call,  __typeof(::uno::Any)->GetProperty(S"Value")->GetGetMethod());
2072cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Castclass, retType);
2073cdf0e10cSrcweir     ilGen->Emit(Emit::OpCodes::Ret);
2074cdf0e10cSrcweir 
2075cdf0e10cSrcweir     // remove from incomplete types map
2076cdf0e10cSrcweir     ::System::String * cts_name = type_builder->get_FullName();
2077cdf0e10cSrcweir     m_incomplete_singletons->Remove( cts_name );
2078cdf0e10cSrcweir     xSingletonType->release();
2079cdf0e10cSrcweir     if (g_verbose)
2080cdf0e10cSrcweir     {
2081cdf0e10cSrcweir         ::System::Console::WriteLine(
2082cdf0e10cSrcweir             "> emitting singleton type {0}", cts_name );
2083cdf0e10cSrcweir     }
2084cdf0e10cSrcweir     return type_builder->CreateType();
2085cdf0e10cSrcweir }
2086cdf0e10cSrcweir 
2087cdf0e10cSrcweir 
2088cdf0e10cSrcweir //______________________________________________________________________________
get_type(Reference<reflection::XTypeDescription> const & xType)2089cdf0e10cSrcweir ::System::Type * TypeEmitter::get_type(
2090cdf0e10cSrcweir     Reference< reflection::XTypeDescription > const & xType )
2091cdf0e10cSrcweir {
2092cdf0e10cSrcweir     switch (xType->getTypeClass())
2093cdf0e10cSrcweir     {
2094cdf0e10cSrcweir     case TypeClass_VOID:
2095cdf0e10cSrcweir         return __typeof (::System::Void);
2096cdf0e10cSrcweir     case TypeClass_CHAR:
2097cdf0e10cSrcweir         return __typeof (::System::Char);
2098cdf0e10cSrcweir     case TypeClass_BOOLEAN:
2099cdf0e10cSrcweir         return __typeof (::System::Boolean);
2100cdf0e10cSrcweir     case TypeClass_BYTE:
2101cdf0e10cSrcweir         return __typeof (::System::Byte);
2102cdf0e10cSrcweir     case TypeClass_SHORT:
2103cdf0e10cSrcweir         return __typeof (::System::Int16);
2104cdf0e10cSrcweir     case TypeClass_UNSIGNED_SHORT:
2105cdf0e10cSrcweir         return __typeof (::System::UInt16);
2106cdf0e10cSrcweir     case TypeClass_LONG:
2107cdf0e10cSrcweir         return __typeof (::System::Int32);
2108cdf0e10cSrcweir     case TypeClass_UNSIGNED_LONG:
2109cdf0e10cSrcweir         return __typeof (::System::UInt32);
2110cdf0e10cSrcweir     case TypeClass_HYPER:
2111cdf0e10cSrcweir         return __typeof (::System::Int64);
2112cdf0e10cSrcweir     case TypeClass_UNSIGNED_HYPER:
2113cdf0e10cSrcweir         return __typeof (::System::UInt64);
2114cdf0e10cSrcweir     case TypeClass_FLOAT:
2115cdf0e10cSrcweir         return __typeof (::System::Single);
2116cdf0e10cSrcweir     case TypeClass_DOUBLE:
2117cdf0e10cSrcweir         return __typeof (::System::Double);
2118cdf0e10cSrcweir     case TypeClass_STRING:
2119cdf0e10cSrcweir         return __typeof (::System::String);
2120cdf0e10cSrcweir     case TypeClass_TYPE:
2121cdf0e10cSrcweir         return __typeof (::System::Type);
2122cdf0e10cSrcweir     case TypeClass_ANY:
2123cdf0e10cSrcweir         return __typeof(::uno::Any);
2124cdf0e10cSrcweir     case TypeClass_ENUM:
2125cdf0e10cSrcweir         return get_type( Reference< reflection::XEnumTypeDescription >(
2126cdf0e10cSrcweir                              xType, UNO_QUERY_THROW ) );
2127cdf0e10cSrcweir     case TypeClass_TYPEDEF:
2128cdf0e10cSrcweir         // unwind typedefs
2129cdf0e10cSrcweir         return get_type(
2130cdf0e10cSrcweir             Reference< reflection::XIndirectTypeDescription >(
2131cdf0e10cSrcweir                 xType, UNO_QUERY_THROW )->getReferencedType() );
2132cdf0e10cSrcweir     case TypeClass_STRUCT:
2133cdf0e10cSrcweir     case TypeClass_EXCEPTION:
2134cdf0e10cSrcweir         return get_type(
2135cdf0e10cSrcweir             Reference< reflection::XCompoundTypeDescription >(
2136cdf0e10cSrcweir                 xType, UNO_QUERY_THROW ) );
2137cdf0e10cSrcweir     case TypeClass_SEQUENCE:
2138cdf0e10cSrcweir     {
2139cdf0e10cSrcweir         ::System::Type * element_type = get_type(
2140cdf0e10cSrcweir             Reference< reflection::XIndirectTypeDescription >(
2141cdf0e10cSrcweir                 xType, UNO_QUERY_THROW )->getReferencedType() );
2142cdf0e10cSrcweir 		::System::Type * retType = get_type(
2143cdf0e10cSrcweir             ::System::String::Concat(
2144cdf0e10cSrcweir                 element_type->get_FullName(), S"[]" ), true );
2145cdf0e10cSrcweir 
2146cdf0e10cSrcweir 		::uno::PolymorphicType * pt = dynamic_cast< ::uno::PolymorphicType * >(element_type);
2147cdf0e10cSrcweir 		if (pt)
2148cdf0e10cSrcweir 		{
2149cdf0e10cSrcweir 			::System::String * sName = ::System::String::Concat(pt->PolymorphicName, S"[]");
2150cdf0e10cSrcweir 			retType = ::uno::PolymorphicType::GetType(retType, sName);
2151cdf0e10cSrcweir 		}
2152cdf0e10cSrcweir         return retType;
2153cdf0e10cSrcweir     }
2154cdf0e10cSrcweir     case TypeClass_INTERFACE:
2155cdf0e10cSrcweir         return get_type(
2156cdf0e10cSrcweir             Reference< reflection::XInterfaceTypeDescription2 >(
2157cdf0e10cSrcweir                 xType, UNO_QUERY_THROW ) );
2158cdf0e10cSrcweir     case TypeClass_CONSTANT:
2159cdf0e10cSrcweir         return get_type(
2160cdf0e10cSrcweir             Reference< reflection::XConstantTypeDescription >(
2161cdf0e10cSrcweir                 xType, UNO_QUERY_THROW ) );
2162cdf0e10cSrcweir     case TypeClass_CONSTANTS:
2163cdf0e10cSrcweir         return get_type(
2164cdf0e10cSrcweir             Reference< reflection::XConstantsTypeDescription >(
2165cdf0e10cSrcweir                 xType, UNO_QUERY_THROW ) );
2166cdf0e10cSrcweir     case TypeClass_SERVICE:
2167cdf0e10cSrcweir 		return get_type(
2168cdf0e10cSrcweir 			Reference< reflection::XServiceTypeDescription2 >(
2169cdf0e10cSrcweir 				xType, UNO_QUERY_THROW) );
2170cdf0e10cSrcweir     case TypeClass_SINGLETON:
2171cdf0e10cSrcweir 		return get_type(
2172cdf0e10cSrcweir 			Reference< reflection::XSingletonTypeDescription2 >(
2173cdf0e10cSrcweir 				xType, UNO_QUERY_THROW) );
2174cdf0e10cSrcweir     case TypeClass_MODULE:
2175cdf0e10cSrcweir         // ignore these
2176cdf0e10cSrcweir         return 0;
2177cdf0e10cSrcweir     default:
2178cdf0e10cSrcweir         throw RuntimeException(
2179cdf0e10cSrcweir             OUSTR("unexpected type ") + xType->getName(),
2180cdf0e10cSrcweir             Reference< XInterface >() );
2181cdf0e10cSrcweir     }
2182cdf0e10cSrcweir }
2183cdf0e10cSrcweir 
2184cdf0e10cSrcweir //______________________________________________________________________________
get_complete_struct(::System::String * sName)2185cdf0e10cSrcweir ::System::Type * TypeEmitter::get_complete_struct( ::System::String * sName)
2186cdf0e10cSrcweir {
2187cdf0e10cSrcweir     struct_entry * pStruct = __try_cast< struct_entry *>(
2188cdf0e10cSrcweir         m_incomplete_structs->get_Item(sName));
2189cdf0e10cSrcweir     if (pStruct)
2190cdf0e10cSrcweir     {
2191cdf0e10cSrcweir         complete_struct_type(pStruct);
2192cdf0e10cSrcweir     }
2193cdf0e10cSrcweir     //get_type will asked the module builder for the type or otherwise all known assemblies.
2194cdf0e10cSrcweir     return get_type(sName, true);
2195cdf0e10cSrcweir }
Dispose()2196cdf0e10cSrcweir void TypeEmitter::Dispose()
2197cdf0e10cSrcweir {
2198cdf0e10cSrcweir     while (true)
2199cdf0e10cSrcweir     {
2200cdf0e10cSrcweir         ::System::Collections::IDictionaryEnumerator * enumerator =
2201cdf0e10cSrcweir               m_incomplete_ifaces->GetEnumerator();
2202cdf0e10cSrcweir         if (! enumerator->MoveNext())
2203cdf0e10cSrcweir             break;
2204cdf0e10cSrcweir         complete_iface_type(
2205cdf0e10cSrcweir             __try_cast< iface_entry * >( enumerator->get_Value() ) );
2206cdf0e10cSrcweir     }
2207cdf0e10cSrcweir 
2208cdf0e10cSrcweir     while (true)
2209cdf0e10cSrcweir     {
2210cdf0e10cSrcweir         ::System::Collections::IDictionaryEnumerator * enumerator =
2211cdf0e10cSrcweir               m_incomplete_structs->GetEnumerator();
2212cdf0e10cSrcweir         if (! enumerator->MoveNext())
2213cdf0e10cSrcweir             break;
2214cdf0e10cSrcweir         complete_struct_type(
2215cdf0e10cSrcweir             __try_cast< struct_entry * >( enumerator->get_Value() ) );
2216cdf0e10cSrcweir     }
2217cdf0e10cSrcweir 
2218cdf0e10cSrcweir 
2219cdf0e10cSrcweir     while (true)
2220cdf0e10cSrcweir     {
2221cdf0e10cSrcweir         ::System::Collections::IDictionaryEnumerator * enumerator =
2222cdf0e10cSrcweir               m_incomplete_services->GetEnumerator();
2223cdf0e10cSrcweir         if (! enumerator->MoveNext())
2224cdf0e10cSrcweir             break;
2225cdf0e10cSrcweir         complete_service_type(
2226cdf0e10cSrcweir             __try_cast< service_entry * >( enumerator->get_Value() ) );
2227cdf0e10cSrcweir     }
2228cdf0e10cSrcweir 
2229cdf0e10cSrcweir     while (true)
2230cdf0e10cSrcweir     {
2231cdf0e10cSrcweir         ::System::Collections::IDictionaryEnumerator * enumerator =
2232cdf0e10cSrcweir               m_incomplete_singletons->GetEnumerator();
2233cdf0e10cSrcweir         if (! enumerator->MoveNext())
2234cdf0e10cSrcweir             break;
2235cdf0e10cSrcweir         complete_singleton_type(
2236cdf0e10cSrcweir             __try_cast< singleton_entry * >( enumerator->get_Value() ) );
2237cdf0e10cSrcweir     }
2238cdf0e10cSrcweir }
2239cdf0e10cSrcweir //______________________________________________________________________________
TypeEmitter(::System::Reflection::Emit::ModuleBuilder * module_builder,::System::Reflection::Assembly * extra_assemblies[])2240cdf0e10cSrcweir TypeEmitter::TypeEmitter(
2241cdf0e10cSrcweir     ::System::Reflection::Emit::ModuleBuilder * module_builder,
2242cdf0e10cSrcweir     ::System::Reflection::Assembly * extra_assemblies [] )
2243cdf0e10cSrcweir     : m_module_builder( module_builder ),
2244cdf0e10cSrcweir       m_extra_assemblies( extra_assemblies ),
2245cdf0e10cSrcweir       m_method_info_Type_GetTypeFromHandle( 0 ),
2246cdf0e10cSrcweir       m_type_Exception( 0 ),
2247cdf0e10cSrcweir       m_type_RuntimeException( 0 ),
2248cdf0e10cSrcweir       m_incomplete_ifaces( new ::System::Collections::Hashtable() ),
2249cdf0e10cSrcweir       m_incomplete_structs( new ::System::Collections::Hashtable() ),
2250cdf0e10cSrcweir       m_incomplete_services(new ::System::Collections::Hashtable() ),
2251cdf0e10cSrcweir       m_incomplete_singletons(new ::System::Collections::Hashtable() ),
2252cdf0e10cSrcweir       m_generated_structs( new ::System::Collections::Hashtable() )
2253cdf0e10cSrcweir {
2254cdf0e10cSrcweir     ::System::Type * param_types[] = new ::System::Type * [ 1 ];
2255cdf0e10cSrcweir     param_types[ 0 ] = __typeof (::System::RuntimeTypeHandle);
2256cdf0e10cSrcweir     m_method_info_Type_GetTypeFromHandle =
2257cdf0e10cSrcweir         __typeof (::System::Type)
2258cdf0e10cSrcweir           ->GetMethod( "GetTypeFromHandle", param_types );
2259cdf0e10cSrcweir }
2260cdf0e10cSrcweir 
get_service_ctor_method_exceptions_reduced(const Sequence<Reference<reflection::XCompoundTypeDescription>> & seqExceptionsTd)2261cdf0e10cSrcweir ::System::Collections::ArrayList * TypeEmitter::get_service_ctor_method_exceptions_reduced(
2262cdf0e10cSrcweir     const Sequence<Reference<reflection::XCompoundTypeDescription> > & seqExceptionsTd)
2263cdf0e10cSrcweir {
2264cdf0e10cSrcweir     if (seqExceptionsTd.getLength() == 0)
2265cdf0e10cSrcweir         return new ::System::Collections::ArrayList();
2266cdf0e10cSrcweir 
2267cdf0e10cSrcweir     ::System::Collections::ArrayList * arTypes = new ::System::Collections::ArrayList();
2268cdf0e10cSrcweir     for (int i = 0; i < seqExceptionsTd.getLength(); i++)
2269cdf0e10cSrcweir         arTypes->Add(get_type(to_cts_name(seqExceptionsTd[i]->getName()), true));
2270cdf0e10cSrcweir 
2271cdf0e10cSrcweir     int start = 0;
2272cdf0e10cSrcweir     while (true)
2273cdf0e10cSrcweir     {
2274cdf0e10cSrcweir         bool bRemove = false;
2275cdf0e10cSrcweir         for (int i = start; i < arTypes->Count; i++)
2276cdf0e10cSrcweir         {
2277cdf0e10cSrcweir             ::System::Type * t = __try_cast< ::System::Type* >(arTypes->get_Item(i));
2278cdf0e10cSrcweir             for (int j = 0; j < arTypes->Count; j++)
2279cdf0e10cSrcweir             {
2280cdf0e10cSrcweir                 if (t->IsSubclassOf(__try_cast< ::System::Type* >(arTypes->get_Item(j))))
2281cdf0e10cSrcweir                 {
2282cdf0e10cSrcweir                     arTypes->RemoveAt(i);
2283cdf0e10cSrcweir                     bRemove = true;
2284cdf0e10cSrcweir                     break;
2285cdf0e10cSrcweir                 }
2286cdf0e10cSrcweir             }
2287cdf0e10cSrcweir             if (bRemove)
2288cdf0e10cSrcweir                 break;
2289cdf0e10cSrcweir             start++;
2290cdf0e10cSrcweir         }
2291cdf0e10cSrcweir 
2292cdf0e10cSrcweir         if (bRemove == false)
2293cdf0e10cSrcweir             break;
2294cdf0e10cSrcweir     }
2295cdf0e10cSrcweir     return arTypes;
2296cdf0e10cSrcweir }
2297cdf0e10cSrcweir 
2298cdf0e10cSrcweir 
2299cdf0e10cSrcweir css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >
resolveInterfaceTypedef(const css::uno::Reference<css::reflection::XTypeDescription> & type)2300cdf0e10cSrcweir resolveInterfaceTypedef(
2301cdf0e10cSrcweir     const css::uno::Reference<css::reflection::XTypeDescription>& type)
2302cdf0e10cSrcweir {
2303cdf0e10cSrcweir     Reference<reflection::XInterfaceTypeDescription2>
2304cdf0e10cSrcweir         xIfaceTd(type, UNO_QUERY);
2305cdf0e10cSrcweir 
2306cdf0e10cSrcweir     if (xIfaceTd.is())
2307cdf0e10cSrcweir         return xIfaceTd;
2308cdf0e10cSrcweir 
2309cdf0e10cSrcweir     Reference<reflection::XIndirectTypeDescription> xIndTd(
2310cdf0e10cSrcweir         type, UNO_QUERY);
2311cdf0e10cSrcweir     if (xIndTd.is() == sal_False)
2312cdf0e10cSrcweir         throw css::uno::Exception(
2313cdf0e10cSrcweir             OUSTR("resolveInterfaceTypedef was called with an invalid argument"), 0);
2314cdf0e10cSrcweir 
2315cdf0e10cSrcweir     return resolveInterfaceTypedef(xIndTd->getReferencedType());
2316cdf0e10cSrcweir }
2317cdf0e10cSrcweir 
2318cdf0e10cSrcweir 
2319cdf0e10cSrcweir }
2320