Exemple #1
0
        public static ITypeConverter GetTypeConverter(Type type)
        {
            if (type == typeof(object))
            {
                return ObjectTypeConverter.Default;
            }

            if (type == typeof(string))
            {
                return StringTypeConverter.Default;
            }

            if (type == typeof(bool))
            {
                return BooleanTypeConverter.Default;
            }

            if (type == typeof(int))
            {
                return Int32TypeConverter.Default;
            }

            if (type == typeof(double))
            {
                return DoubleTypeConverter.Default;
            }

            if (type == typeof(TimeSpan))
            {
                return TimeSpanTypeConverter.Default;
            }

            if (type.IsEnum)
            {
                return new EnumTypeConverter(type);
            }

            if (type == typeof(Type))
            {
                return TypeTypeConverter.Default;
            }

            if (type.GetIsGenericType() && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                return GetTypeConverter(type.GetGenericArguments().First());
            }

            TypeConverterAttribute typeConverterAttribute = type.GetCustomAttributes(typeof(TypeConverterAttribute), false).FirstOrDefault() as TypeConverterAttribute;
            if (typeConverterAttribute != null)
            {
                return Activator.CreateInstance(typeConverterAttribute.ConverterType) as ITypeConverter;
            }

            if (ParseTypeConverter.ContainsParseMethod(type))
            {
                return new ParseTypeConverter(type);
            }

            return null;
        }
		public object Get( SerializationContext context, Type keyType )
		{
			object matched;
			object genericDefinitionMatched;
			if ( !this.Get( keyType, out matched, out genericDefinitionMatched ) )
			{
				return null;
			}

			if ( matched != null )
			{
				return matched;
			}
			// ReSharper disable once RedundantIfElseBlock
			else
			{
#if !UNITY_ANDROID && !UNITY_IPHONE
				Contract.Assert( keyType.GetIsGenericType() );
				Contract.Assert( !keyType.GetIsGenericTypeDefinition() );
#endif // !UNITY_ANDROID && !UNITY_IPHONE
				var type = genericDefinitionMatched as Type;
#if !UNITY_ANDROID && !UNITY_IPHONE
				Contract.Assert( type != null );
				Contract.Assert( type.GetIsGenericTypeDefinition() );
#endif // !UNITY_ANDROID && !UNITY_IPHONE
				var result = Activator.CreateInstance( type.MakeGenericType( keyType.GetGenericArguments() ), context );
#if !UNITY_ANDROID && !UNITY_IPHONE
				Contract.Assert( result != null );
#endif // !UNITY_ANDROID && !UNITY_IPHONE
				return result;
			}
		}
Exemple #3
0
		public static PropertyInfo FindEnumeratorCurrentProperty( Type enumeratorType, CollectionTraits traits )
		{
#if DEBUG
			Contract.Assert( traits.GetEnumeratorMethod != null );
#endif // DEBUG
			PropertyInfo currentProperty = traits.GetEnumeratorMethod.ReturnType.GetProperty( "Current" );

			if ( currentProperty == null )
			{
				if ( enumeratorType == typeof( IDictionaryEnumerator ) )
				{
					currentProperty = Metadata._IDictionaryEnumerator.Entry;
				}
				else if ( enumeratorType.GetIsInterface() )
				{
					if ( enumeratorType.GetIsGenericType() && enumeratorType.GetGenericTypeDefinition() == typeof( IEnumerator<> ) )
					{
						currentProperty = typeof( IEnumerator<> ).MakeGenericType( traits.ElementType ).GetProperty( "Current" );
					}
					else
					{
						currentProperty = Metadata._IEnumerator.Current;
					}
				}
			}
			return currentProperty;
		}
		public object Get( SerializationContext context, Type keyType )
		{
			object matched;
			object genericDefinitionMatched;
			if ( !this.Get( keyType, out matched, out genericDefinitionMatched ) )
			{
				return null;
			}

			if ( matched != null )
			{
				return matched;
			}
			else
			{
#if DEBUG
				Contract.Assert( keyType.GetIsGenericType(), "keyType.GetIsGenericType()" );
				Contract.Assert( !keyType.GetIsGenericTypeDefinition(), "!keyType.GetIsGenericTypeDefinition()" );
#endif // DEBUG
				var type = genericDefinitionMatched as Type;
#if DEBUG
				Contract.Assert( type != null, "type != null" );
				Contract.Assert( type.GetIsGenericTypeDefinition(), "type.GetIsGenericTypeDefinition()" );
#endif // DEBUG
#if !UNITY
				var result =
					ReflectionExtensions.CreateInstancePreservingExceptionType( 
						type.MakeGenericType( keyType.GetGenericArguments() ), 
						context
					);
#else
				var resultType = type.IsGenericTypeDefinition ? type.MakeGenericType( keyType.GetGenericArguments() ) : type;
				var constructor2 = resultType.GetConstructor( NonGenericSerializerConstructorParameterTypes );
				object result;
				try
				{
					result =
						constructor2 == null
						? ReflectionExtensions.CreateInstancePreservingExceptionType( resultType, context )
						: ReflectionExtensions.CreateInstancePreservingExceptionType( resultType, context, keyType );
				}
				catch ( Exception ex )
				{
					AotHelper.HandleAotError( keyType, ex );
					throw;
				}
#endif // !UNITY
				Contract.Assert( result != null, "result != null" );

				return result;
			}
		}
        public static bool GetFirstDerivedOfGenericType(Type type, Type genericType, out Type derivedType)
        {
            if (type.GetIsGenericType() && type.GetGenericTypeDefinition() == genericType)
            {
                derivedType = type;
                return true;
            }

            if (type.GetBaseType() != null)
                return GetFirstDerivedOfGenericType(type.GetBaseType(), genericType, out derivedType);

            derivedType = null;
            return false;
        }
		private static bool JudgeNullable( Type type )
		{
			if ( !type.GetIsValueType() )
			{
				// reference type.
				return true;
			}

			if ( type == typeof( MessagePackObject ) )
			{
				// can be MPO.Nil.
				return true;
			}

			if ( type.GetIsGenericType() && type.GetGenericTypeDefinition() == typeof( Nullable<> ) )
			{
				// Nullable<T>
				return true;
			}

			return false;
		}
        public static object ChangeType(object value, Type conversionType,
            CultureInfo culture = null)
        {
            if (conversionType == null)
                throw new ArgumentNullException("conversionType");

            if (conversionType is Type &&
                (value == null || value is Type))
                return value;

            if (conversionType.GetIsGenericType() &&
                conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                if (value == null)
                    return null;

                NullableConverter nullableConverter = new NullableConverter(conversionType);
                conversionType = nullableConverter.UnderlyingType;
            }

            return Convert.ChangeType(value, conversionType, culture ?? CultureInfo.CurrentCulture);
        }
		internal Type GetConcreteType( Type abstractCollectionType )
		{
			var typeOrDefinition = this.Get( abstractCollectionType );
			if ( typeOrDefinition == null || !typeOrDefinition.GetIsGenericTypeDefinition() || !abstractCollectionType.GetIsGenericType() )
			{
				return typeOrDefinition;
			}

			// Assume type repository has only concrete generic type definition which has same arity for abstract type.
			return typeOrDefinition.MakeGenericType( abstractCollectionType.GetGenericArguments() );
		}
		private bool GetCore( Type type, out object matched, out object genericDefinitionMatched )
		{
			bool holdsReadLock = false;
#if !SILVERLIGHT && !NETFX_CORE
			RuntimeHelpers.PrepareConstrainedRegions();
#endif
			try
			{
#if !SILVERLIGHT && !NETFX_CORE
				RuntimeHelpers.PrepareConstrainedRegions();
#endif
				try { }
				finally
				{
					this._lock.EnterReadLock();
					holdsReadLock = true;
				}
				object result;
				if ( this._table.TryGetValue( type.TypeHandle, out result ) )
				{
					matched = result;
					genericDefinitionMatched = null;
					return true;
				}

				if ( type.GetIsGenericType() )
				{
					if ( this._table.TryGetValue( type.GetGenericTypeDefinition().TypeHandle, out result ) )
					{
						matched = null;
						genericDefinitionMatched = result;
						return true;
					}
				}

				matched = null;
				genericDefinitionMatched = null;
				return false;
			}
			finally
			{
				if ( holdsReadLock )
				{
					this._lock.ExitReadLock();
				}
			}
		}
		private static bool IsIEnumeratorT( Type @interface )
		{
			return @interface.GetIsGenericType() && @interface.GetGenericTypeDefinition() == typeof( IEnumerator<> );
		}
        protected virtual void MakeFriendlyReference(Type type, string codeNamespace, StringBuilder sb = null)
        {
            sb = sb ?? this.sb;

            string ns;

            if (type.GetIsGenericType())
            {
                var gtd = type.GetGenericTypeDefinition();
                ns = ShortenNamespace(gtd, codeNamespace);

                if (!string.IsNullOrEmpty(ns))
                {
                    sb.Append(ns);
                    sb.Append(".");
                }

                var name = gtd.Name;
                var idx = name.IndexOf('`');
                if (idx >= 0)
                    name = name.Substring(0, idx);

                sb.Append(name);
                sb.Append("<");

                int i = 0;
                foreach (var argument in type.GetGenericArguments())
                {
                    if (i++ > 0)
                        sb.Append(", ");

                    HandleMemberType(argument, codeNamespace);
                }

                sb.Append(">");
                return;
            }

            if (codeNamespace != null)
            {
                ns = ShortenNamespace(type, codeNamespace);
                if (!string.IsNullOrEmpty(ns))
                    sb.Append(ns + "." + type.Name);
                else
                    sb.Append(type.Name);
            }
            else
                sb.Append(type.Name);
        }
        public static void HandleMemberType(StringBuilder code, Type memberType, string codeNamespace, HashSet<string> usingNamespaces, 
            Action<Type> enqueueType = null)
        {
            if (memberType == typeof(DateTime?) || memberType == typeof(DateTime) || memberType == typeof(TimeSpan) || memberType == typeof(TimeSpan?))
            {
                code.Append("String"); // şu an için string, JSON tarafında ISO string formatında tarihler gidiyor, 
                // ama bunu daha sonra JSON.parse, JSON.stringify'ı değiştirip düzelteceğiz.
                return;
            }

            if (GeneratorUtils.IsSimpleType(memberType))
            {
                code.Append(memberType.Name);
                return;
            }

            var nullableType = Nullable.GetUnderlyingType(memberType);
            if (nullableType != null &&
                GeneratorUtils.IsSimpleType(nullableType))
            {
                code.Append(nullableType.Name);
                code.Append("?");
                return;
            }

            if (nullableType != null)
            {
                HandleMemberType(code, nullableType, codeNamespace, usingNamespaces, enqueueType);
                code.Append("?");
                return;
            }

            // TODO: Bunlar özel durumlar, attribute la daha sonra halledelim!
            if (memberType == typeof(SortBy[]))
            {
                code.Append("SortBy[]");
                return;
            }

            if (memberType == typeof(Stream))
            {
                code.Append("byte[]");
                return;
            }

            if (memberType == typeof(Object))
            {
                code.Append("Object");
                return;
            }

            if (memberType.IsArray)
            {
                code.Append("List<");
                HandleMemberType(code, memberType.GetElementType(), codeNamespace, usingNamespaces, enqueueType);
                code.Append(">");
                return;
            }

            if (memberType.GetIsGenericType() &&
                (memberType.GetGenericTypeDefinition() == typeof(List<>) || memberType.GetGenericTypeDefinition() == typeof(HashSet<>)))
            {
                code.Append("List<");
                HandleMemberType(code, memberType.GenericTypeArguments[0], codeNamespace, usingNamespaces, enqueueType);
                code.Append(">");
                return;
            }

            if (memberType.GetIsGenericType() &&
                memberType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
            {
                code.Append("JsDictionary<");
                HandleMemberType(code, memberType.GenericTypeArguments[0], codeNamespace, usingNamespaces, enqueueType);
                code.Append(",");
                HandleMemberType(code, memberType.GenericTypeArguments[1], codeNamespace, usingNamespaces, enqueueType);
                code.Append(">");
                return;
            }

            if (enqueueType != null)
                enqueueType(memberType);

            code.Append(MakeFriendlyName(memberType, codeNamespace, usingNamespaces));
        }
        public static string MakeFriendlyName(Type type, string codeNamespace, HashSet<string> usingNamespaces)
        {
            if (type.GetIsGenericType())
            {
                StringBuilder sb = new StringBuilder();

                var name = type.GetGenericTypeDefinition().Name;
                var idx = name.IndexOf('`');
                if (idx >= 0)
                    name = name.Substring(0, idx);

                sb.Append(name);
                sb.Append("<");

                foreach (var argument in type.GetGenericArguments())
                {
                    var arg = MakeFriendlyName(argument, codeNamespace, usingNamespaces);
                    sb.Append(arg);
                }

                sb.Append(">");

                return sb.ToString();
            }

            // compability with older code generators that doesn't take namespaces into account
            if (usingNamespaces == null && codeNamespace == null)
                return type.Name;

            var ns = GetNamespace(type);

            if (ns == "Serenity" ||
                ns.StartsWith("Serenity.") ||
                (usingNamespaces != null && usingNamespaces.Contains(ns)) ||
                (codeNamespace != null && (ns == codeNamespace)) ||
                (codeNamespace != null && codeNamespace.StartsWith((ns + "."))))
                return type.Name;

            if (codeNamespace != null)
            {
                var idx = codeNamespace.IndexOf('.');
                if (idx >= 0 && type.FullName.StartsWith(codeNamespace.Substring(0, idx + 1)))
                    return type.FullName.Substring(idx + 1);
            }

            return type.FullName;
        }
        protected bool IsPublicServiceMethod(MethodInfo method, out Type requestType, out Type responseType,
            out string requestParam)
        {
            responseType = null;
            requestType = null;
            requestParam = null;

            if (method.GetCustomAttribute<NonActionAttribute>() != null)
                return false;

            if (typeof(Controller).IsSubclassOf(method.DeclaringType))
                return false;

            if (method.IsSpecialName && (method.Name.StartsWith("set_") || method.Name.StartsWith("get_")))
                return false;

            var parameters = method.GetParameters().Where(x => !x.ParameterType.GetIsInterface()).ToArray();
            if (parameters.Length > 1)
                return false;

            if (parameters.Length == 1)
            {
                requestType = parameters[0].ParameterType;
                if (requestType.GetIsPrimitive() || !CanHandleType(requestType))
                    return false;
            }
            else
                requestType = typeof(ServiceRequest);

            requestParam = parameters.Length == 0 ? "request" : parameters[0].Name;

            responseType = method.ReturnType;
            if (responseType != null &&
                responseType.GetIsGenericType() &&
                responseType.GetGenericTypeDefinition() == typeof(Result<>))
            {
                responseType = responseType.GenericTypeArguments[0];
            }
            else if (typeof(ActionResult).IsAssignableFrom(responseType))
                return false;
            else if (responseType == typeof(void))
                return false;

            return true;
        }
		private static bool DetermineCollectionInterfaces(
			Type type,
			ref GenericCollectionTypes genericTypes,
			ref Type idictionary,
			ref Type ilist,
			ref Type icollection,
			ref Type ienumerable
		)
		{
			if ( type.GetIsGenericType() )
			{
				var genericTypeDefinition = type.GetGenericTypeDefinition();
				if ( genericTypeDefinition == typeof( IDictionary<,> ) )
				{
					if ( genericTypes.IDictionaryT != null )
					{
						return false;
					}

					genericTypes.IDictionaryT = type;
				}
#if !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE )
				else if ( genericTypeDefinition == typeof( IReadOnlyDictionary<,> ) )
				{
					if ( genericTypes.IReadOnlyDictionaryT != null )
					{
						return false;
					}

					genericTypes.IReadOnlyDictionaryT = type;
				}
#endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE )
				else if ( genericTypeDefinition == typeof( IList<> ) )
				{
					if ( genericTypes.IListT != null )
					{
						return false;
					}

					genericTypes.IListT = type;
				}
#if !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE )
				else if ( genericTypeDefinition == typeof( IReadOnlyList<> ) )
				{
					if ( genericTypes.IReadOnlyListT != null )
					{
						return false;
					}

					genericTypes.IReadOnlyListT = type;
				}
#endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE )
#if !NETFX_35 && !UNITY
				else if ( genericTypeDefinition == typeof( ISet<> ) )
				{
					if ( genericTypes.ISetT != null )
					{
						return false;
					}

					genericTypes.ISetT = type;
				}
#endif // !NETFX_35 && !UNITY
				else if ( genericTypeDefinition == typeof( ICollection<> ) )
				{
					if ( genericTypes.ICollectionT != null )
					{
						return false;
					}

					genericTypes.ICollectionT = type;
				}
#if !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE )
				else if ( genericTypeDefinition == typeof( IReadOnlyCollection<> ) )
				{
					if ( genericTypes.IReadOnlyCollectionT != null )
					{
						return false;
					}

					genericTypes.IReadOnlyCollectionT = type;
				}
#endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE )
				else if ( genericTypeDefinition == typeof( IEnumerable<> ) )
				{
					if ( genericTypes.IEnumerableT != null )
					{
						return false;
					}

					genericTypes.IEnumerableT = type;
				}
			}
			else
			{
				if ( type == typeof( IDictionary ) )
				{
					idictionary = type;
				}
				else if ( type == typeof( IList ) )
				{
					ilist = type;
				}
				else if ( type == typeof( ICollection ) )
				{
					icollection = type;
				}
				else if ( type == typeof( IEnumerable ) )
				{
					ienumerable = type;
				}
			}

			return true;
		}
        protected virtual string MakeFriendlyName(Type type, string codeNamespace, StringBuilder sb = null)
        {
            sb = sb ?? this.sb;

            if (type.GetIsGenericType())
            {
                var gtd = type.GetGenericTypeDefinition();
                var name = gtd.Name;
                var idx = name.IndexOf('`');
                if (idx >= 0)
                    name = name.Substring(0, idx);

                sb.Append(name);
                sb.Append("<");

                int i = 0;
                foreach (var argument in type.GetGenericArguments())
                {
                    if (i++ > 0)
                        sb.Append(", ");

                    HandleMemberType(argument, codeNamespace, sb);
                }

                sb.Append(">");

                return name + "`" + type.GetGenericArguments().Length;
            }
            else
            {
                sb.Append(type.Name);
                return type.Name;
            }
        }
        protected override void HandleMemberType(Type memberType, string codeNamespace, StringBuilder sb = null)
        {
            sb = sb ?? this.sb;

            if (memberType == typeof(String))
            {
                sb.Append("String");
                return;
            }

            var nullableType = Nullable.GetUnderlyingType(memberType);
            if (nullableType != null)
                memberType = nullableType;

            if (memberType == typeof(DateTime) || 
                memberType == typeof(TimeSpan))
            {
                sb.Append("String");
                return;
            }

            if (GeneratorUtils.IsSimpleType(memberType))
            {
                sb.Append(memberType.Name);
                if (nullableType != null)
                    sb.Append("?");
                return;
            }

            if (nullableType != null)
            {
                HandleMemberType(nullableType, codeNamespace, sb);
                sb.Append("?");
                return;
            }

            if (memberType == typeof(SortBy[]))
            {
                sb.Append("SortBy[]");
                return;
            }

            if (memberType == typeof(Stream))
            {
                sb.Append("byte[]");
                return;
            }

            if (memberType == typeof(Object))
            {
                sb.Append("Object");
                return;
            }

            if (memberType.IsArray)
            {
                sb.Append("List<");
                HandleMemberType(memberType.GetElementType(), codeNamespace, sb);
                sb.Append(">");
                return;
            }

            if (memberType.GetIsGenericType() &&
                (memberType.GetGenericTypeDefinition() == typeof(List<>) ||
                memberType.GetGenericTypeDefinition() == typeof(HashSet<>)))
            {
                sb.Append("List<");
                HandleMemberType(memberType.GenericTypeArguments[0], codeNamespace, sb);
                sb.Append(">");
                return;
            }

            if (memberType.GetIsGenericType() &&
                memberType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
            {
                sb.Append("JsDictionary<");
                HandleMemberType(memberType.GenericTypeArguments[0], codeNamespace, sb);
                sb.Append(",");
                HandleMemberType(memberType.GenericTypeArguments[1], codeNamespace, sb);
                sb.Append(">");
                return;
            }

            EnqueueType(memberType);

            MakeFriendlyReference(memberType, codeNamespace);
        }
        protected override void HandleMemberType(Type memberType, string codeNamespace, 
            StringBuilder sb = null)
        {
            sb = sb ?? this.sb;

            if (memberType == typeof(String))
            {
                sb.Append("string");
                return;
            }

            var nullableType = Nullable.GetUnderlyingType(memberType);
            if (nullableType != null)
                memberType = nullableType;

            if (memberType == typeof(Int16) ||
                memberType == typeof(Int32) ||
                memberType == typeof(Int64) ||
                memberType == typeof(UInt16) ||
                memberType == typeof(UInt32) ||
                memberType == typeof(UInt64) ||
                memberType == typeof(Single) ||
                memberType == typeof(Double) ||
                memberType == typeof(Decimal))
            {
                sb.Append("number");
                return;
            }

            if (memberType == typeof(Boolean))
            {
                sb.Append("boolean");
                return;
            }

            if (memberType == typeof(DateTime) ||
                memberType == typeof(TimeSpan) ||
                memberType == typeof(Guid))
            {
                sb.Append("string");
                return;
            }

            if (memberType == typeof(SortBy[]))
            {
                sb.Append("string[]");
                return;
            }

            if (memberType == typeof(Stream))
            {
                sb.Append("number[]");
                return;
            }

            if (memberType == typeof(Object))
            {
                sb.Append("any");
                return;
            }

            if (memberType.IsArray)
            {
                HandleMemberType(memberType.GetElementType(), codeNamespace, sb);
                sb.Append("[]");
                return;
            }

            if (memberType.GetIsGenericType() &&
                (memberType.GetGenericTypeDefinition() == typeof(List<>) ||
                memberType.GetGenericTypeDefinition() == typeof(HashSet<>)))
            {
                HandleMemberType(memberType.GenericTypeArguments[0], codeNamespace, sb);
                sb.Append("[]");
                return;
            }

            if (memberType.GetIsGenericType() &&
                memberType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
            {
                sb.Append("{ [key: ");
                HandleMemberType(memberType.GenericTypeArguments[0], codeNamespace, sb);
                sb.Append("]: ");
                HandleMemberType(memberType.GenericTypeArguments[1], codeNamespace, sb);
                sb.Append(" }");
                return;
            }

            EnqueueType(memberType);
            MakeFriendlyReference(memberType, codeNamespace);
        }