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