Exemplo n.º 1
0
        private void AddCompatibleOverloads(ClrMethod /*!*/ constructedMethod, ClrMethod /*!*/ genericMethod,
                                            DTypeDescs /*!*/ typeArgs, bool exactMatch)
        {
            foreach (ClrMethod.Overload overload in genericMethod.Overloads)
            {
                // add the overloads that are compatible with typeArgs
                int gen_count = overload.GenericParamCount;
                if (exactMatch ? gen_count == typeArgs.Count : gen_count > typeArgs.Count)
                {
                    bool compatible = true;

                    for (int i = 0; i < gen_count; i++)
                    {
                        DTypeDesc desc = (i < typeArgs.Count ? typeArgs[i] : PrimitiveTypeDesc.SystemObjectTypeDesc);
                        if (!desc.IsCompatibleWithGenericParameter(overload.GenericParameters[i]))
                        {
                            compatible = false;
                            break;
                        }
                    }

                    if (compatible)
                    {
                        // make generic method
                        Type[] real_type_args;
                        if (exactMatch)
                        {
                            real_type_args = typeArgs.GetRealTypes();
                        }
                        else
                        {
                            real_type_args = new Type[gen_count];

                            typeArgs.GetRealTypes(real_type_args, 0);
                            for (int i = typeArgs.Count; i < gen_count; i++)
                            {
                                real_type_args[i] = Types.Object[0];
                            }
                        }
                        MethodInfo info = ((MethodInfo)overload.Method).MakeGenericMethod(real_type_args);

                        ClrMethod.Overload constructed_overload;
                        constructedMethod.AddOverload(info, out constructed_overload);
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a constructed method desc for the given type arguments.
        /// </summary>
        private ClrMethodDesc ConstructMethodDesc(DTypeDescs /*!*/ typeArgs)
        {
            ClrMethod generic_method     = ClrMethod;
            ClrMethod constructed_method = new ClrMethod(generic_method.Name, declaringType, memberAttributes, 1, false);

            // add overloads which have an exact match
            AddCompatibleOverloads(constructed_method, generic_method, typeArgs, true);

            if (constructed_method.Overloads.Count == 0)
            {
                // now try overloads whose additional type parameters can by substituted by System.Object
                AddCompatibleOverloads(constructed_method, generic_method, typeArgs, false);

                if (constructed_method.Overloads.Count == 0)
                {
                    // sorry, bad luck
                    PhpException.NoSuitableOverload(generic_method.DeclaringType.FullName, generic_method.FullName);
                    return(null);
                }
            }

            return(constructed_method.ClrMethodDesc);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Dispatches the invocation to a constructed method according to type arguments on the stack.
        /// </summary>
        /// <remarks>
        /// Constructed methods are cached in the <see cref="instantiations"/> dictionary.
        /// </remarks>
        private object ArglessPreStub(object instance, PhpStack /*!*/ stack)
        {
            // get type arguments from the stack
            DTypeDescs type_args = new DTypeDescs(stack);

            ClrMethodDesc method_desc;

            lock (instantiations)
            {
                if (!instantiations.TryGetValue(type_args, out method_desc))
                {
                    method_desc = ConstructMethodDesc(type_args);
                    if (method_desc == null)
                    {
                        return(null);
                    }

                    instantiations.Add(type_args, method_desc);
                }
            }

            return(method_desc.ArglessStub(instance, stack));
        }
Exemplo n.º 4
0
		private void AddCompatibleOverloads(ClrMethod/*!*/ constructedMethod, ClrMethod/*!*/ genericMethod,
			DTypeDescs/*!*/ typeArgs, bool exactMatch)
		{
			foreach (ClrMethod.Overload overload in genericMethod.Overloads)
			{
				// add the overloads that are compatible with typeArgs
				int gen_count = overload.GenericParamCount;
				if (exactMatch ? gen_count == typeArgs.Count : gen_count > typeArgs.Count)
				{
					bool compatible = true;

					for (int i = 0; i < gen_count; i++)
					{
						DTypeDesc desc = (i < typeArgs.Count ? typeArgs[i] : PrimitiveTypeDesc.SystemObjectTypeDesc);
						if (!desc.IsCompatibleWithGenericParameter(overload.GenericParameters[i]))
						{
							compatible = false;
							break;
						}
					}

					if (compatible)
					{
						// make generic method
						Type[] real_type_args;
						if (exactMatch) real_type_args = typeArgs.GetRealTypes();
						else
						{
							real_type_args = new Type[gen_count];

							typeArgs.GetRealTypes(real_type_args, 0);
							for (int i = typeArgs.Count; i < gen_count; i++) real_type_args[i] = Types.Object[0];
						}
						MethodInfo info = ((MethodInfo)overload.Method).MakeGenericMethod(real_type_args);

						ClrMethod.Overload constructed_overload;
						constructedMethod.AddOverload(info, out constructed_overload);
					}
				}
			}
		}
Exemplo n.º 5
0
		/// <summary>
		/// Creates a constructed method desc for the given type arguments.
		/// </summary>
		private ClrMethodDesc ConstructMethodDesc(DTypeDescs/*!*/ typeArgs)
		{
			ClrMethod generic_method = ClrMethod;
			ClrMethod constructed_method = new ClrMethod(generic_method.Name, declaringType, memberAttributes, 1, false);

			// add overloads which have an exact match
			AddCompatibleOverloads(constructed_method, generic_method, typeArgs, true);

			if (constructed_method.Overloads.Count == 0)
			{
				// now try overloads whose additional type parameters can by substituted by System.Object
				AddCompatibleOverloads(constructed_method, generic_method, typeArgs, false);

				if (constructed_method.Overloads.Count == 0)
				{
					// sorry, bad luck
					PhpException.NoSuitableOverload(generic_method.DeclaringType.FullName, generic_method.FullName);
					return null;
				}
			}

			return constructed_method.ClrMethodDesc;
		}
Exemplo n.º 6
0
		/// <summary>
		/// Dispatches the invocation to a constructed method according to type arguments on the stack.
		/// </summary>
		/// <remarks>
		/// Constructed methods are cached in the <see cref="instantiations"/> dictionary.
		/// </remarks>
		private object ArglessPreStub(object instance, PhpStack/*!*/ stack)
		{
			// get type arguments from the stack
			DTypeDescs type_args = new DTypeDescs(stack);

			ClrMethodDesc method_desc;
			lock (instantiations)
			{
				if (!instantiations.TryGetValue(type_args, out method_desc))
				{
					method_desc = ConstructMethodDesc(type_args);
					if (method_desc == null) return null;

					instantiations.Add(type_args, method_desc);
				}
			}

			return method_desc.ArglessStub(instance, stack);
		}
Exemplo n.º 7
0
		internal ConstructedType/*!*/ CreateConstructedType(DTypeDesc/*!*/ genericType, DTypeDesc[]/*!!*/ arguments, int argCount)
		{
			ConstructedType result;

			if (genericType.IsUnknown)
			{
				Array.Resize(ref arguments, argCount);
				result = new ConstructedType(genericType, arguments);
			}
			else
			{
				DTypeDescs tuple = new DTypeDescs(genericType, arguments, argCount);

				if (!constructedTypes.TryGetValue(tuple, out result))
				{
					Array.Resize(ref arguments, argCount);
					result = new ConstructedType(genericType, arguments);
					constructedTypes.Add(tuple, result);
				}
			}

			return result;
		}