예제 #1
0
        public virtual bool IsAssignableFrom(IType other)
        {
            if (other == this || other == Null.Default)
            {
                return(true);
            }

            if (other.IsArray)
            {
                IArrayType otherArray = (IArrayType)other;

                if (otherArray.GetArrayRank() != _rank)
                {
                    return(false);
                }

                IType otherEntityType = otherArray.GetElementType();
                if (_elementType.IsValueType || otherEntityType.IsValueType)
                {
                    return(_elementType == otherEntityType);
                }
                return(_elementType.IsAssignableFrom(otherEntityType));
            }

            return(false);
        }
예제 #2
0
        /// <summary>
        /// Maps a type involving generic parameters to the corresponding type after substituting concrete
        /// arguments for generic parameters.
        /// </summary>
        /// <remarks>
        /// If the source type is a generic parameter, it is mapped to the corresponding argument.
        /// If the source type is an open generic type using any of the specified generic parameters, it
        /// is mapped to a closed constructed type based on the specified arguments.
        /// TODO: complete this
        /// </remarks>
        public IType MapType(IType sourceType)
        {
            if (sourceType == null)
            {
                return(null);
            }

            // If sourceType is a reference type, map its element type
            if (sourceType.IsByRef)
            {
                return(MapType(sourceType.GetElementType()));
            }

            // Map generic parameter to corresponding argument
            IGenericParameter gp = sourceType as IGenericParameter;

            if (null != gp && _map.ContainsKey(gp))
            {
                return(_map[gp]);
            }

            // Map open constructed type using generic parameters to closed constructed type
            // using corresponding arguments
            if (null != sourceType.GenericTypeInfo)
            {
                IType[] mappedArguments = Array.ConvertAll <IType, IType>(
                    sourceType.GenericTypeInfo.GenericArguments,
                    MapType);

                IType mapped = sourceType.GenericTypeInfo.
                               GenericDefinition.GenericTypeDefinitionInfo.
                               MakeGenericType(mappedArguments);

                return(mapped);
            }

            // Map array types
            IArrayType array = (sourceType as IArrayType);

            if (array != null)
            {
                IType elementType       = array.GetElementType();
                IType mappedElementType = MapType(elementType);
                if (mappedElementType != elementType)
                {
                    return(_tss.GetArrayType(mappedElementType, array.GetArrayRank()));
                }
            }

            // Map callable types
            ICallableType callable = sourceType as ICallableType;

            if (callable != null)
            {
                CallableSignature signature = callable.GetSignature();

                IType        returnType = MapType(signature.ReturnType);
                IParameter[] parameters = Array.ConvertAll <IParameter, IParameter>(
                    signature.Parameters,
                    delegate(IParameter p) { return(new MappedParameter(_tss, (ExternalParameter)p, this)); });

                CallableSignature mappedSignature = new CallableSignature(
                    parameters, returnType, signature.AcceptVarArgs);

                return(_tss.GetCallableType(mappedSignature));
            }

            // If source type doesn't require mapping, return it as is
            return(sourceType);
        }
예제 #3
0
 private bool InferArrayType(IArrayType formalType, IType actualType, Inference inference)
 {
     IArrayType actualArrayType = actualType as IArrayType;
     return
         (actualArrayType != null) &&
         (actualArrayType.GetArrayRank() == formalType.GetArrayRank()) &&
         (Infer(formalType.GetElementType(), actualType.GetElementType(), inference));
 }
예제 #4
0
        /// <summary>
        /// Maps a type involving generic parameters to the corresponding type after substituting concrete
        /// arguments for generic parameters.
        /// </summary>
        /// <remarks>
        /// If the source type is a generic parameter, it is mapped to the corresponding argument.
        /// If the source type is an open generic type using any of the specified generic parameters, it
        /// is mapped to a closed constructed type based on the specified arguments.
        /// </remarks>
        protected virtual IType MapType(IType sourceType)
        {
            if (sourceType == null)
            {
                return(null);
            }

            // Strip reference types
            if (sourceType.IsByRef)
            {
                return(MapType(sourceType.GetElementType()));
            }

            // Map generic parameter to corresponding argument
            IGenericParameter gp = sourceType as IGenericParameter;

            if (null != gp && _map.ContainsKey(gp))
            {
                return(_map[gp]);
            }

            // Map open constructed type using generic parameters to closed constructed type
            // using corresponding arguments
            if (null != sourceType.ConstructedInfo)
            {
                IType[] mappedArguments = Array.ConvertAll <IType, IType>(
                    sourceType.ConstructedInfo.GenericArguments,
                    MapType);

                IType mapped = sourceType.ConstructedInfo.
                               GenericDefinition.GenericInfo.
                               ConstructType(mappedArguments);

                return(mapped);
            }

            // TODO: Map nested types
            // GenericType[of T].NestedType => GenericType[of int].NestedType

            // Map array types
            IArrayType array = (sourceType as IArrayType);

            if (array != null)
            {
                IType elementType       = array.GetElementType();
                IType mappedElementType = MapType(elementType);
                if (mappedElementType != elementType)
                {
                    return(_tss.GetArrayType(mappedElementType, array.GetArrayRank()));
                }
            }

            // Map callable types
            ICallableType callable = sourceType as ICallableType;

            if (callable != null)
            {
                CallableSignature signature = callable.GetSignature();

                IType        returnType = MapType(signature.ReturnType);
                IParameter[] parameters = Map(signature.Parameters);

                CallableSignature mappedSignature = new CallableSignature(
                    parameters, returnType, signature.AcceptVarArgs);

                return(_tss.GetCallableType(mappedSignature));
            }

            // If source type doesn't require mapping, return it as is
            return(sourceType);
        }