Esempio n. 1
0
		//
		// Implements method type arguments inference
		//
		bool InferInPhases (EmitContext ec, TypeInferenceContext tic, AParametersCollection methodParameters)
		{
			int params_arguments_start;
			if (methodParameters.HasParams) {
				params_arguments_start = methodParameters.Count - 1;
			} else {
				params_arguments_start = arg_count;
			}

			Type [] ptypes = methodParameters.Types;
			
			//
			// The first inference phase
			//
			Type method_parameter = null;
			for (int i = 0; i < arg_count; i++) {
				Argument a = (Argument) arguments [i];
				
				if (i < params_arguments_start) {
					method_parameter = methodParameters.Types [i];
				} else if (i == params_arguments_start) {
					if (arg_count == params_arguments_start + 1 && TypeManager.HasElementType (a.Type))
						method_parameter = methodParameters.Types [params_arguments_start];
					else
						method_parameter = TypeManager.GetElementType (methodParameters.Types [params_arguments_start]);

					ptypes = (Type[]) ptypes.Clone ();
					ptypes [i] = method_parameter;
				}

				//
				// When a lambda expression, an anonymous method
				// is used an explicit argument type inference takes a place
				//
				AnonymousMethodExpression am = a.Expr as AnonymousMethodExpression;
				if (am != null) {
					if (am.ExplicitTypeInference (tic, method_parameter))
						--score; 
					continue;
				}

				if (a.Expr is NullLiteral)
					continue;

				//
				// Otherwise an output type inference is made
				//
				score -= tic.OutputTypeInference (ec, a.Expr, method_parameter);
			}

			//
			// Part of the second phase but because it happens only once
			// we don't need to call it in cycle
			//
			bool fixed_any = false;
			if (!tic.FixIndependentTypeArguments (ptypes, ref fixed_any))
				return false;

			return DoSecondPhase (ec, tic, ptypes, !fixed_any);
		}
Esempio n. 2
0
		bool DoSecondPhase (EmitContext ec, TypeInferenceContext tic, Type[] methodParameters, bool fixDependent)
		{
			bool fixed_any = false;
			if (fixDependent && !tic.FixDependentTypes (ref fixed_any))
				return false;

			// If no further unfixed type variables exist, type inference succeeds
			if (!tic.UnfixedVariableExists)
				return true;

			if (!fixed_any && fixDependent)
				return false;
			
			// For all arguments where the corresponding argument output types
			// contain unfixed type variables but the input types do not,
			// an output type inference is made
			for (int i = 0; i < arg_count; i++) {
				
				// Align params arguments
				Type t_i = methodParameters [i >= methodParameters.Length ? methodParameters.Length - 1: i];
				
				if (!TypeManager.IsDelegateType (t_i)) {
					if (TypeManager.DropGenericTypeArguments (t_i) != TypeManager.expression_type)
						continue;

					t_i = t_i.GetGenericArguments () [0];
				}

				MethodInfo mi = Delegate.GetInvokeMethod (t_i, t_i);
				Type rtype = mi.ReturnType;

#if MS_COMPATIBLE
				// Blablabla, because reflection does not work with dynamic types
				Type[] g_args = t_i.GetGenericArguments ();
				rtype = g_args[rtype.GenericParameterPosition];
#endif

				if (tic.IsReturnTypeNonDependent (mi, rtype))
					score -= tic.OutputTypeInference (ec, ((Argument) arguments [i]).Expr, t_i);
			}


			return DoSecondPhase (ec, tic, methodParameters, true);
		}
Esempio n. 3
0
File: generic.cs Progetto: ikvm/mono
		bool DoSecondPhase (ResolveContext ec, TypeInferenceContext tic, TypeSpec[] methodParameters, bool fixDependent)
		{
			bool fixed_any = false;
			if (fixDependent && !tic.FixDependentTypes (ec, ref fixed_any))
				return false;

			// If no further unfixed type variables exist, type inference succeeds
			if (!tic.UnfixedVariableExists)
				return true;

			if (!fixed_any && fixDependent)
				return false;
			
			// For all arguments where the corresponding argument output types
			// contain unfixed type variables but the input types do not,
			// an output type inference is made
			for (int i = 0; i < arg_count; i++) {
				
				// Align params arguments
				TypeSpec t_i = methodParameters [i >= methodParameters.Length ? methodParameters.Length - 1: i];
				
				if (!TypeManager.IsDelegateType (t_i)) {
					if (t_i.GetDefinition () != TypeManager.expression_type)
						continue;

					t_i = TypeManager.GetTypeArguments (t_i) [0];
				}

				var mi = Delegate.GetInvokeMethod (ec.Compiler, t_i);
				TypeSpec rtype = mi.ReturnType;

				if (tic.IsReturnTypeNonDependent (ec, mi, rtype))
					score -= tic.OutputTypeInference (ec, arguments [i].Expr, t_i);
			}


			return DoSecondPhase (ec, tic, methodParameters, true);
		}