示例#1
0
		private static object[] GetStubParameterTypes(
			int paramCount,
			int typeParamCount,
			PhpRoutineSignature/*!*/ signature,
			PHP.Core.AST.FormalTypeParam[]/*!*/ formalTypeParams)
		{
			object[] parameter_types = new object[paramCount];
			for (int i = 0; i < paramCount; i++)
			{
				DType type_hint = signature.TypeHints[i];
				if (type_hint != null && !type_hint.IsUnknown)
				{
					GenericParameter gen_type_hint = type_hint as GenericParameter;
					if (gen_type_hint != null)
					{
						// this is a generic parameter - declared by either the method or type
						if (gen_type_hint.DeclaringMember is PhpRoutine)
						{
							if (gen_type_hint.Index < typeParamCount)
							{
								// unknown at this point - fixed-up later
								parameter_types[i] = gen_type_hint.Index;
							}
							else
							{
								// default generic parameter
                                var typeparam = formalTypeParams[gen_type_hint.Index].DefaultType;
                                
                                DType default_type = typeparam as DType;
                                if (default_type == null && typeparam is GenericQualifiedName)
                                    default_type = PrimitiveType.GetByName((GenericQualifiedName)typeparam);

								parameter_types[i] = (default_type == null ? Types.Object[0] : default_type.RealType);
							}
						}
						else parameter_types[i] = gen_type_hint.RealGenericTypeParameterBuilder;
					}
					else parameter_types[i] = type_hint.RealType;
				}
				else parameter_types[i] = Types.Object[0];

				// make it byref if declared with &
				if (signature.AliasMask[i])
				{
					Type type = parameter_types[i] as Type;
					if (type != null) parameter_types[i] = type.MakeByRefType();
					else parameter_types[i] = -((int)parameter_types[i] + 1);
				}

				Debug.Assert(parameter_types[i] != null);
			}

			return parameter_types;
		}
示例#2
0
		/// <summary>
		/// Defines generic parameters according to the given template and re-maps relevant parameters.
		/// </summary>
		public static void DefineStubGenericParameters(MethodBuilder/*!*/ stub, Type[]/*!!*/ genericParameters,
			PhpRoutineSignature/*!*/ targetSignature, Type[]/*!!*/ parameters)
		{
			// determine generic parameter names
			string[] generic_param_names = new string[genericParameters.Length];
			for (int j = 0; j < generic_param_names.Length; j++)
			{
				if (j < targetSignature.GenericParamCount)
				{
					generic_param_names[j] = targetSignature.GenericParams[j].Name.ToString();
				}
				else generic_param_names[j] = genericParameters[j].Name;
			}
			GenericTypeParameterBuilder[] generic_params = stub.DefineGenericParameters(generic_param_names);

			// determine generic parameter attributes and constraints
			for (int j = 0; j < generic_params.Length; j++)
			{
				Type template_type = genericParameters[j];

				// attributes
				generic_params[j].SetGenericParameterAttributes(template_type.GenericParameterAttributes);

				// constraints
				Type[] template_constraints = template_type.GetGenericParameterConstraints();

				List<Type> interface_constraints = new List<Type>();
				for (int k = 0; k < template_constraints.Length; k++)
				{
					if (template_constraints[k].IsClass) generic_params[j].SetBaseTypeConstraint(template_constraints[k]);
					else interface_constraints.Add(template_constraints[k]);
				}
				generic_params[j].SetInterfaceConstraints(interface_constraints.ToArray());
			}

			// re-map base method generic parameters to the newly defined generic parameters
			for (int j = 0; j < parameters.Length; j++)
			{
				if (parameters[j].IsGenericParameter && parameters[j].DeclaringMethod != null)
				{
					// method generic parameter
					parameters[j] = generic_params[parameters[j].GenericParameterPosition];
				}
			}
		}
示例#3
0
		internal void WriteUp(PhpRoutineSignature/*!*/ signature)
		{
			Debug.Assert(signature != null);
			Debug.Assert(this.signature == null, "Already written up.");

			this.signature = signature;
		}
示例#4
0
		/// <summary>
		/// Used by the reflection.
		/// </summary>
		public PhpRoutine(DRoutineDesc/*!*/ functionDesc)
			: base(functionDesc)
		{
			this.signature = null; // to be written up
			this.builder = null; // unused
		}
示例#5
0
		/// <summary>
		/// Used by the compiler.
		/// </summary>
		internal PhpRoutine(DRoutineDesc/*!*/ functionDesc, Signature astSignature, TypeSignature astTypeSignature)
			: base(functionDesc)
		{
			this.signature = null; // to be written up
			this.builder = new PhpRoutineBuilder(this, astSignature, astTypeSignature);
		}