| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| using System; |
| using System.Collections; |
| using System.Reflection; |
| using System.Globalization; |
| |
| namespace uno { |
| |
| |
| |
| /** represents a polymorphic type. |
| |
| This class is used to carry type information for polymorphic struct types |
| and arrays of polymorphic struct types. These types would be easiest represented |
| with type templates, which are not available in .NET 1.1. Therefore |
| the System.Type cannot contain information about template parameters. To |
| retain this information we use PolymorphicType which directly inherits from |
| System.Type. The additional information about type parameters are passed |
| as simple string when creating an instance of PolymorphicType. Usually one |
| only needs a PolymorphicType when a polymporphic type is put into an |
| uno.Any. For example, let's assume there is a idl type PolyStruct: |
| |
| module test { |
| struct PolyStruct< T > |
| { |
| T member; |
| }; |
| }; |
| |
| Then one would use it in C# in this way: |
| |
| uno.Any myAny = new uno.Any( PolymorphicType.GetType( |
| typeof(PolyStruct), "unoidl.test.PolyStruct<System.Boolean>"), |
| new PolyStruct(true)); |
| |
| or if one has a sequence of polymorphic structs: |
| |
| uno.Any myAny = new uno.Any( PolymorphicType.GetType( |
| typeof(PolyStruct), "unoidl.test.PolyStruct<System.Boolean>[]"), |
| new PolyStruct[] {new PolyStruct(true)} ); |
| |
| |
| To get a new instance of PolymorphicType one uses the static method |
| PolymorphicType.GetType. The method ensures that there is only one instance |
| for each distinct name. For example, if GetType is called multiple times with |
| the name "unoidl.test.PolyStruct<System.Boolean>" then the same instance of |
| PolymorphicType is returned. This makes it possible to compare the instances |
| by reference, thas is using the operator "==". |
| |
| The polymorphic name, which is passed as second argument to PolymorphicType.GetType, |
| contains a list of type names. Only type names common |
| to all CLI languages can be used. That is, instead of using names, such as |
| char, int, float, the names System.Char, System.Int32 and |
| System.Single are to be used. Spaces are not allowed. |
| The name will always start with "unoidl", when the type was generated by climaker. |
| Here are a couple of possible strings: |
| |
| unoidl.test.PolyStruct<System.Int32> |
| unoidl.test.PolyStruct<System.Char[]> |
| unoidl.test.PolyStruct<System.Int64>[] |
| unoidl.test.PolyStruct<unoidl.test.PolyStruct<System.Int64>> |
| unoidl.test.PolyStruct<unoidl.test.PolyStruct<System.Int64[]>[]>[] |
| |
| In the future, when the CLI supports templates, we will probably adapt the cli-uno |
| bridge accordingly to use real template types. Then this class will become obsolete. |
| */ |
| public class PolymorphicType: Type |
| { |
| private Type m_base; |
| private string m_type_name; |
| |
| private static Hashtable m_ht_types = Hashtable.Synchronized(new Hashtable(256)); |
| |
| /** provides a unique instance of this class. |
| |
| This function returns null if the specified type is no polymorphic struct. |
| |
| @param type |
| the type of the polymorphic struct. For example, created by |
| <code>typeof(unoidl.com.sun.star.beans.Defaulted)</code> |
| @param name |
| the full name of the struct (including the type list). |
| @return |
| null - the argument type is no valid polymorphic struct or <br> |
| an instance of this class. |
| @exception System.ArgumentNullException |
| The argument was null. |
| */ |
| public static PolymorphicType GetType(Type type, string name) |
| { |
| if (name == null || type == null) |
| throw new ArgumentNullException( |
| "cli-uno: uno.PolymorphicType.GetType was called with a null argument"); |
| //check if the type is either a array of structs or a polymorphic struct. |
| if (type.IsArray) |
| { |
| Type elementType = type; |
| while ((elementType = elementType.GetElementType()).IsArray); |
| //unfortunately we cannot check if it is a real polymorphic struct here. |
| if ( ! elementType.IsClass) |
| return null; |
| |
| |
| } |
| else if (Attribute.GetCustomAttribute(type, typeof(uno.TypeParametersAttribute)) |
| == null) |
| { |
| return null; |
| } |
| |
| lock (m_ht_types.SyncRoot) |
| { |
| PolymorphicType t = (PolymorphicType) m_ht_types[name]; |
| if (t == null) |
| { |
| t = new PolymorphicType(type, name); |
| m_ht_types.Add(name, t); |
| } |
| return t; |
| } |
| } |
| |
| private PolymorphicType(Type type, string name) |
| { |
| m_type_name = name; |
| m_base = type; |
| } |
| |
| public string PolymorphicName |
| { |
| get |
| { |
| return m_type_name; |
| } |
| } |
| |
| public Type OriginalType |
| { |
| get |
| { |
| return m_base; |
| } |
| } |
| |
| |
| //implementations of abstract methods and properties from base class |
| public override string Name |
| { |
| get |
| { |
| return m_base.Name; |
| } |
| } |
| |
| public override Assembly Assembly |
| { |
| get |
| { |
| return m_base.Assembly; |
| } |
| } |
| |
| public override string AssemblyQualifiedName |
| { |
| get |
| { |
| return m_base.AssemblyQualifiedName; |
| } |
| } |
| |
| public override Type BaseType |
| { |
| get |
| { |
| return m_base.BaseType; |
| } |
| } |
| |
| public override string FullName |
| { |
| get |
| { |
| return m_base.FullName; |
| } |
| } |
| |
| public override Guid GUID |
| { |
| get |
| { |
| return m_base.GUID; |
| } |
| } |
| |
| public override Module Module |
| { |
| get |
| { |
| return m_base.Module; |
| } |
| } |
| |
| public override string Namespace |
| { |
| get |
| { |
| return m_base.Namespace; |
| } |
| } |
| |
| public override RuntimeTypeHandle TypeHandle |
| { |
| get |
| { |
| return m_base.TypeHandle; |
| } |
| } |
| |
| public override Type UnderlyingSystemType |
| { |
| get |
| { |
| return m_base.UnderlyingSystemType; |
| } |
| } |
| |
| public override Type DeclaringType |
| { |
| get |
| { |
| return m_base.DeclaringType; |
| } |
| } |
| |
| public override object[] GetCustomAttributes( |
| bool inherit) |
| { |
| return m_base.GetCustomAttributes(inherit); |
| } |
| |
| public override object[] GetCustomAttributes( |
| Type attributeType, |
| bool inherit) |
| { |
| return m_base.GetCustomAttributes(attributeType, inherit); |
| } |
| |
| public override bool IsDefined( |
| Type attributeType, |
| bool inherit) |
| { |
| return IsDefined(attributeType, inherit); |
| } |
| |
| protected override TypeAttributes GetAttributeFlagsImpl() |
| { |
| return m_base.Attributes; |
| } |
| |
| protected override ConstructorInfo GetConstructorImpl( |
| BindingFlags bindingAttr, |
| Binder binder, |
| CallingConventions callConvention, |
| Type[] types, |
| ParameterModifier[] modifiers) |
| { |
| return m_base.GetConstructor( |
| bindingAttr, binder, callConvention, types, modifiers); |
| } |
| |
| public override ConstructorInfo[] GetConstructors( |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetConstructors(bindingAttr); |
| } |
| |
| public override Type GetElementType() |
| { |
| return m_base.GetElementType(); |
| } |
| |
| public override EventInfo GetEvent( |
| string name, |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetEvent(name, bindingAttr); |
| } |
| |
| public override EventInfo[] GetEvents( |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetEvents(bindingAttr); |
| } |
| |
| public override FieldInfo GetField( |
| string name, |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetField(name, bindingAttr); |
| } |
| |
| public override FieldInfo[] GetFields( |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetFields(bindingAttr); |
| } |
| |
| public override Type GetInterface( |
| string name, bool ignoreCase) |
| { |
| return m_base.GetInterface(name, ignoreCase); |
| } |
| |
| public override Type[] GetInterfaces() |
| { |
| return m_base.GetInterfaces(); |
| } |
| |
| public override MemberInfo[] GetMembers( |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetMembers(bindingAttr); |
| } |
| |
| protected override MethodInfo GetMethodImpl( |
| string name, |
| BindingFlags bindingAttr, |
| Binder binder, |
| CallingConventions callConvention, |
| Type[] types, |
| ParameterModifier[] modifiers) |
| { |
| return m_base.GetMethod( |
| name, bindingAttr, binder, callConvention, types, modifiers); |
| } |
| |
| public override MethodInfo[] GetMethods( |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetMethods(bindingAttr); |
| } |
| |
| public override Type GetNestedType( |
| string name, BindingFlags bindingAttr) |
| { |
| return m_base.GetNestedType(name, bindingAttr); |
| } |
| |
| public override Type[] GetNestedTypes( |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetNestedTypes(bindingAttr); |
| } |
| |
| public override PropertyInfo[] GetProperties( |
| BindingFlags bindingAttr) |
| { |
| return m_base.GetProperties(bindingAttr); |
| } |
| |
| protected override PropertyInfo GetPropertyImpl( |
| string name, |
| BindingFlags bindingAttr, |
| Binder binder, |
| Type returnType, |
| Type[] types, |
| ParameterModifier[] modifiers) |
| { |
| return m_base.GetProperty( |
| name, bindingAttr, binder, returnType, types, modifiers); |
| } |
| |
| protected override bool HasElementTypeImpl() |
| { |
| return m_base.HasElementType; |
| } |
| |
| public override object InvokeMember( |
| string name, |
| BindingFlags invokeAttr, |
| Binder binder, |
| object target, |
| object[] args, |
| ParameterModifier[] modifiers, |
| CultureInfo culture, |
| string[] namedParameters) |
| { |
| return m_base.InvokeMember( |
| name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); |
| } |
| |
| protected override bool IsArrayImpl() |
| { |
| return m_base.IsArray; |
| } |
| |
| protected override bool IsByRefImpl() |
| { |
| return m_base.IsByRef; |
| } |
| |
| protected override bool IsCOMObjectImpl() |
| { |
| return m_base.IsCOMObject; |
| } |
| |
| protected override bool IsPointerImpl() |
| { |
| return m_base.IsPointer; |
| } |
| |
| protected override bool IsPrimitiveImpl() |
| { |
| return m_base.IsPrimitive; |
| } |
| } |
| } |