1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #using <mscorlib.dll>
25 #using <cli_basetypes.dll>
26 
27 #include <vcclr.h>
28 
29 #include "osl/diagnose.h"
30 #include "com/sun/star/reflection/XConstantTypeDescription.hpp"
31 #include "com/sun/star/reflection/XConstantsTypeDescription.hpp"
32 #include "com/sun/star/reflection/XEnumTypeDescription.hpp"
33 #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
34 #include "com/sun/star/reflection/XCompoundTypeDescription.hpp"
35 #include "com/sun/star/reflection/XServiceTypeDescription2.hpp"
36 #include "com/sun/star/reflection/XSingletonTypeDescription2.hpp"
37 #include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
38 
39 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
40 
41 
42 namespace css = ::com::sun::star;
43 
44 namespace climaker
45 {
46 
47 //------------------------------------------------------------------------------
48 extern bool g_verbose;
49 
50 __gc struct Constants
51 {
52 	static const ::System::String * sUnoVoid = S"void";
53 	static const ::System::String * sUnoType = S"type";
54 	static const ::System::String * sUnoAny =  S"any";
55 	static const ::System::String * sUnoBool = S"boolean";
56 	static const ::System::String * sUnoByte = S"byte";
57 	static const ::System::String * sUnoChar = S"char";
58 	static const ::System::String * sUnoShort = S"short";
59 	static const ::System::String * sUnoUShort = S"unsigned short";
60 	static const ::System::String * sUnoLong = S"long";
61 	static const ::System::String * sUnoULong = S"unsigned long";
62 	static const ::System::String * sUnoHyper = S"hyper";
63 	static const ::System::String * sUnoUHyper = S"unsigned hyper";
64 	static const ::System::String * sUnoString = S"string";
65 	static const ::System::String * sUnoFloat = S"float";
66 	static const ::System::String * sUnoDouble = S"double";
67 	static const ::System::String * sUnoXInterface = S"com.sun.star.uno.XInterface";
68 	static const ::System::String * sBrackets = S"[]";
69 
70     static const System::String* sObject = S"System.Object";
71     static const System::String* sType = S"System.Type";
72     static const System::String* sUnoidl = S"unoidl.";
73     static const System::String* sVoid = S"System.Void";
74     static const System::String* sAny = S"uno.Any";
75     static const System::String* sBoolean = S"System.Boolean";
76     static const System::String* sChar = S"System.Char";
77     static const System::String* sByte = S"System.Byte";
78     static const System::String* sInt16 = S"System.Int16";
79     static const System::String* sUInt16 = S"System.UInt16";
80     static const System::String* sInt32 = S"System.Int32";
81     static const System::String* sUInt32 = S"System.UInt32";
82     static const System::String* sInt64 = S"System.Int64";
83     static const System::String* sUInt64 = S"System.UInt64";
84     static const System::String* sString = S"System.String";
85     static const System::String* sSingle = S"System.Single";
86     static const System::String* sDouble = S"System.Double";
87 	static const System::String* sComma = new System::String(S",");
88 
89 };
90 
91 //------------------------------------------------------------------------------
ustring_to_String(::rtl::OUString const & ustr)92 inline ::System::String * ustring_to_String( ::rtl::OUString const & ustr )
93 {
94     return new ::System::String( ustr.getStr(), 0, ustr.getLength() );
95 }
96 
97 //------------------------------------------------------------------------------
String_to_ustring(::System::String * str)98 inline ::rtl::OUString String_to_ustring( ::System::String * str )
99 {
100     OSL_ASSERT( sizeof (wchar_t) == sizeof (sal_Unicode) );
101     wchar_t const __pin * chars = PtrToStringChars( str );
102     return ::rtl::OUString( chars, str->get_Length() );
103 }
104 
105 /* If the argument type is a typedef for an interface then the interface
106    type description is returned, otherwise an exeption is thrown.
107 */
108 css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >
109 resolveInterfaceTypedef(const css::uno::Reference<css::reflection::XTypeDescription>& type);
110 
111 const ::System::Reflection::MethodAttributes c_ctor_method_attr =
112 (::System::Reflection::MethodAttributes)
113     (::System::Reflection::MethodAttributes::Public |
114      ::System::Reflection::MethodAttributes::HideBySig |
115      ::System::Reflection::MethodAttributes::SpecialName |
116      ::System::Reflection::MethodAttributes::RTSpecialName
117      /* | xxx todo: ??? compiler does not know Instance ???
118         ::System::Reflection::MethodAttributes::Instance*/);
119 
120 //==============================================================================
121 __gc class TypeEmitter : public ::System::IDisposable
122 {
123     ::System::Reflection::Emit::ModuleBuilder * m_module_builder;
124     ::System::Reflection::Assembly * m_extra_assemblies __gc [];
125 
126     ::System::Reflection::MethodInfo * m_method_info_Type_GetTypeFromHandle;
127 
128     ::System::Type * m_type_Exception;
129     ::System::Type * get_type_Exception();
130     ::System::Type * m_type_RuntimeException;
131     ::System::Type * get_type_RuntimeException();
132 
133     ::System::Reflection::Emit::CustomAttributeBuilder* get_service_exception_attribute(
134         const css::uno::Reference<css::reflection::XServiceConstructorDescription> & ctorDesc);
135     ::System::Reflection::Emit::CustomAttributeBuilder* get_iface_method_exception_attribute(
136         const css::uno::Reference< css::reflection::XInterfaceMethodTypeDescription >& xMethod );
137     ::System::Reflection::Emit::CustomAttributeBuilder* get_exception_attribute(
138         const css::uno::Sequence<css::uno::Reference<
139         css::reflection::XCompoundTypeDescription > >& seq_exceptionsTd );
140 /* Creates ::System::Type object for UNO exceptions. The UNO exceptions are
141        obtained by
142        com::sun::star::reflection::XServiceConstructorDescription::getExceptions
143        In a first step the respective CLI types are created. Then it is examined
144        if a Type represents a super class of another class. If so the Type of the
145        derived class is discarded. For example there are a uno RuntimeException and
146        a DeploymentException which inherits RuntimeException. Then only the cli Type
147        of the RuntimeException is returned.
148        The purpose of this function is to provide exceptions for which catch blocks
149        are generated in the service constructor code.
150 
151        It is always an instance of an ArrayList returned, even if the sequence argument
152        does not contain elements.
153     */
154     ::System::Collections::ArrayList * get_service_ctor_method_exceptions_reduced(
155         const css::uno::Sequence<
156         css::uno::Reference<css::reflection::XCompoundTypeDescription> > & seqExceptionsTd);
157 
158 
159     __gc class iface_entry
160     {
161     public:
162         css::reflection::XInterfaceTypeDescription2 * m_xType;
163         ::System::Reflection::Emit::TypeBuilder * m_type_builder;
164     };
165     ::System::Collections::Hashtable * m_incomplete_ifaces;
166     ::System::Type * complete_iface_type( iface_entry * entry );
167 
168     __gc class struct_entry
169     {
170     public:
171          css::reflection::XCompoundTypeDescription * m_xType;
172         ::System::Reflection::Emit::TypeBuilder * m_type_builder;
173         ::System::Type * m_base_type;
174 
175         ::System::String * m_member_names __gc [];
176         ::System::Type * m_param_types __gc [];
177         ::System::Reflection::ConstructorInfo * m_default_ctor;
178         ::System::Reflection::ConstructorInfo * m_ctor;
179     };
180     ::System::Collections::Hashtable * m_incomplete_structs;
181     ::System::Type * complete_struct_type( struct_entry * entry );
182 
183     /*  returns the type for the name. If it is a struct then it may
184         complete the struct if not already done. This also refers to its
185         base types.
186 
187         @param sName
188             the full name of the type.
189         @return the type object for sName. Not necessarily a struct.
190     */
191     ::System::Type * get_complete_struct( ::System::String * sName);
192 
193     __gc class service_entry
194     {
195     public:
196         ::System::Reflection::Emit::TypeBuilder * m_type_builder;
197         css::reflection::XServiceTypeDescription2 * m_xType;
198     };
199     ::System::Collections::Hashtable * m_incomplete_services;
200     ::System::Type * complete_service_type(service_entry * entry);
201 
202     __gc class singleton_entry
203     {
204     public:
205         ::System::Reflection::Emit::TypeBuilder * m_type_builder;
206         css::reflection::XSingletonTypeDescription2 * m_xType;
207     };
208 
209 
210     ::System::Collections::Hashtable * m_incomplete_singletons;
211     ::System::Type * complete_singleton_type(singleton_entry * entry);
212 
213 
214     ::System::Collections::Hashtable * m_generated_structs;
215 
216     ::System::Type * get_type(
217         ::System::String * cli_name, bool throw_exc );
218     ::System::Type * get_type(
219         css::uno::Reference<
220         css::reflection::XConstantTypeDescription > const & xType );
221     ::System::Type * get_type(
222         css::uno::Reference<
223         css::reflection::XConstantsTypeDescription > const & xType );
224     ::System::Type * get_type(
225         css::uno::Reference<
226         css::reflection::XEnumTypeDescription > const & xType );
227     /* returns the type for a struct or exception. In case of a polymorphic struct it may
228         return a ::uno::PolymorphicType (cli_basetypes.dll) only if the struct is already
229         complete.
230     */
231     ::System::Type * get_type(
232         css::uno::Reference<
233         css::reflection::XCompoundTypeDescription > const & xType );
234     ::System::Type * get_type(
235         css::uno::Reference<
236         css::reflection::XInterfaceTypeDescription2 > const & xType );
237     ::System::Type * get_type(
238         css::uno::Reference<
239         css::reflection::XSingletonTypeDescription2 > const & xType );
240 
241     /*
242       May return NULL if the service description is an obsolete. See
243       description of
244       com.sun.star.reflection.XServiceTypeDescription2.isSingleInterfaceBased
245      */
246     ::System::Type * get_type(
247         css::uno::Reference<
248         css::reflection::XServiceTypeDescription2 > const & xType );
249 public:
250     TypeEmitter(
251         ::System::Reflection::Emit::ModuleBuilder * module_builder,
252         ::System::Reflection::Assembly * assemblies __gc [] );
253     // must be called to finish up uncompleted types
254     void Dispose();
255 
256     ::System::Reflection::Assembly * type_resolve(
257         ::System::Object * sender, ::System::ResolveEventArgs * args );
258 
259     ::System::Type * get_type(
260         css::uno::Reference<
261         css::reflection::XTypeDescription > const & xType );
262 };
263 
264 }
265