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 System;
25 using System.Collections;
26 using System.Reflection;
27 using System.Globalization;
28 
29 namespace uno {
30 
31 
32 
33 /** represents a polymorphic type.
34 
35     This class is used to carry type information for polymorphic struct types
36     and arrays of polymorphic struct types. These types would be easiest represented
37     with type templates, which are not available in .NET 1.1. Therefore
38     the System.Type cannot contain information about template parameters. To
39     retain this information we use PolymorphicType which directly inherits from
40     System.Type. The additional information about type parameters are passed
41     as simple string when creating an instance of PolymorphicType. Usually one
42     only needs a PolymorphicType when a polymporphic type is put into an
43     uno.Any. For example, let's assume there is a idl type PolyStruct:
44 
45     module test {
46     struct PolyStruct< T >
47     {
48         T member;
49     };
50     };
51 
52     Then one would use it in C# in this way:
53 
54     uno.Any myAny = new uno.Any( PolymorphicType.GetType(
55         typeof(PolyStruct),  "unoidl.test.PolyStruct<System.Boolean>"),
56         new PolyStruct(true));
57 
58     or if one has a sequence of polymorphic structs:
59 
60     uno.Any myAny = new uno.Any( PolymorphicType.GetType(
61         typeof(PolyStruct),  "unoidl.test.PolyStruct<System.Boolean>[]"),
62         new PolyStruct[] {new PolyStruct(true)} );
63 
64 
65     To get a new instance of PolymorphicType one uses the static method
66     PolymorphicType.GetType. The method ensures that there is only one instance
67     for each distinct name. For example, if GetType is called multiple times with
68     the name "unoidl.test.PolyStruct<System.Boolean>" then the same instance of
69     PolymorphicType is returned. This makes it possible to compare the instances
70     by reference, thas is using the operator "==".
71 
72     The polymorphic name, which is passed as second argument to PolymorphicType.GetType,
73     contains a list of type names. Only type names common
74     to all CLI languages can be used. That is, instead of using names, such as
75     char, int, float, the names System.Char, System.Int32 and
76     System.Single are to be used. Spaces are not allowed.
77     The name will always start with "unoidl", when the type was generated by climaker.
78     Here are a couple of possible strings:
79 
80     unoidl.test.PolyStruct<System.Int32>
81     unoidl.test.PolyStruct<System.Char[]>
82     unoidl.test.PolyStruct<System.Int64>[]
83     unoidl.test.PolyStruct<unoidl.test.PolyStruct<System.Int64>>
84     unoidl.test.PolyStruct<unoidl.test.PolyStruct<System.Int64[]>[]>[]
85 
86     In the future, when the CLI supports templates, we will probably adapt the cli-uno
87     bridge accordingly to use real template types. Then this class will become obsolete.
88  */
89 public class PolymorphicType: Type
90 {
91     private Type m_base;
92     private string m_type_name;
93 
94     private static Hashtable m_ht_types = Hashtable.Synchronized(new Hashtable(256));
95 
96     /** provides a unique instance of this class.
97 
98        This function returns null if the specified type is no polymorphic struct.
99 
100        @param type
101        the type of the polymorphic struct. For example, created by
102        <code>typeof(unoidl.com.sun.star.beans.Defaulted)</code>
103        @param name
104        the full name of the struct (including the type list).
105        @return
106        null - the argument type is no valid polymorphic struct or <br>
107        an instance of this class.
108        @exception System.ArgumentNullException
109        The argument was null.
110      */
GetType(Type type, string name)111     public static PolymorphicType GetType(Type type, string name)
112     {
113         if (name == null || type == null)
114             throw new ArgumentNullException(
115                 "cli-uno: uno.PolymorphicType.GetType was called with a null argument");
116         //check if the type is either a array of structs or a polymorphic struct.
117         if (type.IsArray)
118         {
119             Type elementType = type;
120             while ((elementType = elementType.GetElementType()).IsArray);
121 			//unfortunately we cannot check if it is a real polymorphic struct here.
122 			if ( ! elementType.IsClass)
123 				return null;
124 
125 
126         }
127         else if (Attribute.GetCustomAttribute(type, typeof(uno.TypeParametersAttribute))
128             == null)
129         {
130             return null;
131         }
132 
133         lock (m_ht_types.SyncRoot)
134         {
135             PolymorphicType t = (PolymorphicType) m_ht_types[name];
136             if (t == null)
137             {
138                 t = new PolymorphicType(type, name);
139                 m_ht_types.Add(name, t);
140             }
141             return t;
142         }
143     }
144 
PolymorphicType(Type type, string name)145     private PolymorphicType(Type type, string name)
146     {
147         m_type_name = name;
148         m_base = type;
149     }
150 
151     public string PolymorphicName
152     {
153         get
154         {
155             return m_type_name;
156         }
157     }
158 
159     public Type OriginalType
160     {
161         get
162         {
163             return m_base;
164         }
165     }
166 
167 
168     //implementations of abstract methods and properties from base class
169     public override string Name
170     {
171         get
172         {
173             return m_base.Name;
174         }
175     }
176 
177     public override Assembly Assembly
178     {
179         get
180         {
181             return m_base.Assembly;
182         }
183     }
184 
185     public override string AssemblyQualifiedName
186     {
187         get
188         {
189             return m_base.AssemblyQualifiedName;
190         }
191     }
192 
193     public override Type BaseType
194     {
195         get
196         {
197             return m_base.BaseType;
198         }
199     }
200 
201     public override string FullName
202     {
203         get
204         {
205             return m_base.FullName;
206         }
207     }
208 
209     public override Guid GUID
210     {
211         get
212         {
213             return m_base.GUID;
214         }
215     }
216 
217     public override Module Module
218     {
219         get
220         {
221             return m_base.Module;
222         }
223     }
224 
225     public override string Namespace
226     {
227         get
228         {
229             return m_base.Namespace;
230         }
231     }
232 
233     public override RuntimeTypeHandle TypeHandle
234     {
235         get
236         {
237             return m_base.TypeHandle;
238         }
239     }
240 
241     public override Type UnderlyingSystemType
242     {
243         get
244         {
245             return m_base.UnderlyingSystemType;
246         }
247     }
248 
249 	public override Type DeclaringType
250 	{
251 		get
252 		{
253 			return m_base.DeclaringType;
254 		}
255 	}
256 
GetCustomAttributes( bool inherit)257     public override  object[] GetCustomAttributes(
258         bool inherit)
259     {
260         return m_base.GetCustomAttributes(inherit);
261     }
262 
GetCustomAttributes( Type attributeType, bool inherit)263     public override object[] GetCustomAttributes(
264         Type attributeType,
265         bool inherit)
266     {
267         return m_base.GetCustomAttributes(attributeType, inherit);
268     }
269 
IsDefined( Type attributeType, bool inherit)270     public override bool IsDefined(
271         Type attributeType,
272         bool inherit)
273     {
274         return IsDefined(attributeType, inherit);
275     }
276 
GetAttributeFlagsImpl()277     protected override TypeAttributes GetAttributeFlagsImpl()
278     {
279         return m_base.Attributes;
280     }
281 
GetConstructorImpl( BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)282     protected override ConstructorInfo GetConstructorImpl(
283         BindingFlags bindingAttr,
284         Binder binder,
285         CallingConventions callConvention,
286         Type[] types,
287         ParameterModifier[] modifiers)
288     {
289         return m_base.GetConstructor(
290             bindingAttr, binder, callConvention, types, modifiers);
291     }
292 
GetConstructors( BindingFlags bindingAttr)293     public override ConstructorInfo[] GetConstructors(
294         BindingFlags bindingAttr)
295     {
296         return m_base.GetConstructors(bindingAttr);
297     }
298 
GetElementType()299     public override Type GetElementType()
300     {
301         return m_base.GetElementType();
302     }
303 
GetEvent( string name, BindingFlags bindingAttr)304     public override EventInfo GetEvent(
305         string name,
306         BindingFlags bindingAttr)
307     {
308         return m_base.GetEvent(name, bindingAttr);
309     }
310 
GetEvents( BindingFlags bindingAttr)311     public override EventInfo[] GetEvents(
312         BindingFlags bindingAttr)
313     {
314         return m_base.GetEvents(bindingAttr);
315     }
316 
GetField( string name, BindingFlags bindingAttr)317     public override FieldInfo GetField(
318         string name,
319         BindingFlags bindingAttr)
320     {
321         return m_base.GetField(name, bindingAttr);
322     }
323 
GetFields( BindingFlags bindingAttr)324     public override FieldInfo[] GetFields(
325         BindingFlags bindingAttr)
326     {
327         return m_base.GetFields(bindingAttr);
328     }
329 
GetInterface( string name, bool ignoreCase)330     public override Type GetInterface(
331         string name, bool ignoreCase)
332     {
333         return m_base.GetInterface(name, ignoreCase);
334     }
335 
GetInterfaces()336     public override Type[] GetInterfaces()
337     {
338         return m_base.GetInterfaces();
339     }
340 
GetMembers( BindingFlags bindingAttr)341     public override MemberInfo[] GetMembers(
342         BindingFlags bindingAttr)
343     {
344         return m_base.GetMembers(bindingAttr);
345     }
346 
GetMethodImpl( string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)347     protected override MethodInfo GetMethodImpl(
348         string name,
349         BindingFlags bindingAttr,
350         Binder binder,
351         CallingConventions callConvention,
352         Type[] types,
353         ParameterModifier[] modifiers)
354     {
355         return m_base.GetMethod(
356             name, bindingAttr, binder, callConvention, types, modifiers);
357     }
358 
GetMethods( BindingFlags bindingAttr)359     public override MethodInfo[] GetMethods(
360         BindingFlags bindingAttr)
361     {
362         return m_base.GetMethods(bindingAttr);
363     }
364 
GetNestedType( string name, BindingFlags bindingAttr)365     public override Type GetNestedType(
366         string name, BindingFlags bindingAttr)
367     {
368         return m_base.GetNestedType(name, bindingAttr);
369     }
370 
GetNestedTypes( BindingFlags bindingAttr)371     public override Type[] GetNestedTypes(
372         BindingFlags bindingAttr)
373     {
374         return m_base.GetNestedTypes(bindingAttr);
375     }
376 
GetProperties( BindingFlags bindingAttr)377     public override PropertyInfo[] GetProperties(
378         BindingFlags bindingAttr)
379     {
380         return m_base.GetProperties(bindingAttr);
381     }
382 
GetPropertyImpl( string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)383     protected override PropertyInfo GetPropertyImpl(
384         string name,
385         BindingFlags bindingAttr,
386         Binder binder,
387         Type returnType,
388         Type[] types,
389         ParameterModifier[] modifiers)
390     {
391         return m_base.GetProperty(
392             name, bindingAttr, binder, returnType, types, modifiers);
393     }
394 
HasElementTypeImpl()395     protected override  bool HasElementTypeImpl()
396     {
397         return m_base.HasElementType;
398     }
399 
InvokeMember( string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)400     public override object InvokeMember(
401         string name,
402         BindingFlags invokeAttr,
403         Binder binder,
404         object target,
405         object[] args,
406         ParameterModifier[] modifiers,
407         CultureInfo culture,
408         string[] namedParameters)
409     {
410         return m_base.InvokeMember(
411             name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
412     }
413 
IsArrayImpl()414     protected override bool IsArrayImpl()
415     {
416         return m_base.IsArray;
417     }
418 
IsByRefImpl()419     protected override bool IsByRefImpl()
420     {
421         return m_base.IsByRef;
422     }
423 
IsCOMObjectImpl()424     protected override bool IsCOMObjectImpl()
425     {
426         return m_base.IsCOMObject;
427     }
428 
IsPointerImpl()429     protected override bool IsPointerImpl()
430     {
431         return m_base.IsPointer;
432     }
433 
IsPrimitiveImpl()434     protected override bool IsPrimitiveImpl()
435     {
436         return m_base.IsPrimitive;
437     }
438 }
439 }
440