protected override BlockContext CreateBlockContext(BlockContext bc) { var ctx = base.CreateBlockContext(bc); var am = bc.CurrentAnonymousMethod as AnonymousMethodBody; if (am != null) { return_inference = am.ReturnTypeInference; } ctx.Set(ResolveContext.Options.TryScope); return(ctx); }
protected override BlockContext CreateBlockContext(BlockContext bc) { var ctx = base.CreateBlockContext(bc); var lambda = bc.CurrentAnonymousMethod as LambdaMethod; if (lambda != null) { return_inference = lambda.ReturnTypeInference; } ctx.Set(ResolveContext.Options.TryScope); return(ctx); }
protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, Type delegateType) { if (!TypeManager.IsDelegateType (delegateType)) return null; AParametersCollection d_params = TypeManager.GetDelegateParameters (ec, delegateType); if (HasExplicitParameters) { if (!VerifyExplicitParameters (ec, delegateType, d_params)) return null; return Parameters; } // // If L has an implicitly typed parameter list we make implicit parameters explicit // Set each parameter of L is given the type of the corresponding parameter in D // if (!VerifyParameterCompatibility (ec, delegateType, d_params, ec.IsInProbingMode)) return null; Type [] ptypes = new Type [Parameters.Count]; for (int i = 0; i < d_params.Count; i++) { // D has no ref or out parameters if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0) return null; Type d_param = d_params.Types [i]; #if MS_COMPATIBLE // Blablabla, because reflection does not work with dynamic types if (d_param.IsGenericParameter) d_param = delegateType.GetGenericArguments () [d_param.GenericParameterPosition]; #endif // // When type inference context exists try to apply inferred type arguments // if (tic != null) { d_param = tic.InflateGenericArgument (d_param); } ptypes [i] = d_param; ((ImplicitLambdaParameter) Parameters.FixedParameters [i]).Type = d_param; } Parameters.Types = ptypes; return Parameters; }
protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegateType) { if (!delegateType.IsDelegate) return null; AParametersCollection d_params = Delegate.GetParameters (delegateType); if (HasExplicitParameters) { if (!VerifyExplicitParameters (ec, tic, delegateType, d_params)) return null; return Parameters; } // // If L has an implicitly typed parameter list we make implicit parameters explicit // Set each parameter of L is given the type of the corresponding parameter in D // if (!VerifyParameterCompatibility (ec, tic, delegateType, d_params, ec.IsInProbingMode)) return null; TypeSpec [] ptypes = new TypeSpec [Parameters.Count]; for (int i = 0; i < d_params.Count; i++) { // D has no ref or out parameters if ((d_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != 0) return null; TypeSpec d_param = d_params.Types [i]; // // When type inference context exists try to apply inferred type arguments // if (tic != null) { d_param = tic.InflateGenericArgument (ec, d_param); } ptypes [i] = d_param; ImplicitLambdaParameter ilp = (ImplicitLambdaParameter) Parameters.FixedParameters [i]; ilp.SetParameterType (d_param); ilp.Resolve (null, i); } Parameters.Types = ptypes; return Parameters; }
public TypeSpec InferReturnType (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type) { Expression expr; AnonymousExpression am; if (compatibles.TryGetValue (delegate_type, out expr)) { am = expr as AnonymousExpression; return am == null ? null : am.ReturnType; } using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) { am = CompatibleMethodBody (ec, tic, InternalType.Arglist, delegate_type); if (am != null) am = am.Compatible (ec); } if (am == null) return null; // compatibles.Add (delegate_type, am); return am.ReturnType; }
// // Infers type arguments based on explicit arguments // public bool ExplicitTypeInference (TypeInferenceContext type_inference, Type delegate_type) { if (!HasExplicitParameters) return false; if (!TypeManager.IsDelegateType (delegate_type)) { #if GMCS_SOURCE if (TypeManager.DropGenericTypeArguments (delegate_type) != TypeManager.expression_type) return false; delegate_type = delegate_type.GetGenericArguments () [0]; if (!TypeManager.IsDelegateType (delegate_type)) return false; #else return false; #endif } AParametersCollection d_params = TypeManager.GetDelegateParameters (delegate_type); if (d_params.Count != Parameters.Count) return false; for (int i = 0; i < Parameters.Count; ++i) { Type itype = d_params.Types [i]; if (!TypeManager.IsGenericParameter (itype)) { if (!TypeManager.HasElementType (itype)) continue; if (!TypeManager.IsGenericParameter (itype.GetElementType ())) continue; } type_inference.ExactInference (Parameters.Types [i], itype); } return true; }
protected virtual ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type) { var delegate_parameters = Delegate.GetParameters (delegate_type); if (Parameters == ParametersCompiled.Undefined) { // // We provide a set of inaccessible parameters // Parameter[] fixedpars = new Parameter[delegate_parameters.Count]; for (int i = 0; i < delegate_parameters.Count; i++) { Parameter.Modifier i_mod = delegate_parameters.FixedParameters [i].ModFlags; if ((i_mod & Parameter.Modifier.OUT) != 0) { if (!ec.IsInProbingMode) { ec.Report.Error (1688, loc, "Cannot convert anonymous method block without a parameter list to delegate type `{0}' because it has one or more `out' parameters", delegate_type.GetSignatureForError ()); } return null; } fixedpars[i] = new Parameter ( new TypeExpression (delegate_parameters.Types [i], loc), null, delegate_parameters.FixedParameters [i].ModFlags, null, loc); } return ParametersCompiled.CreateFullyResolved (fixedpars, delegate_parameters.Types); } if (!VerifyExplicitParameters (ec, delegate_type, delegate_parameters)) { return null; } return Parameters; }
// // Infers type arguments based on explicit arguments // public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, TypeSpec delegate_type) { if (!HasExplicitParameters) return false; if (!delegate_type.IsDelegate) { if (!delegate_type.IsExpressionTreeType) return false; delegate_type = TypeManager.GetTypeArguments (delegate_type) [0]; if (!delegate_type.IsDelegate) return false; } AParametersCollection d_params = Delegate.GetParameters (delegate_type); if (d_params.Count != Parameters.Count) return false; var ptypes = Parameters.Types; var dtypes = d_params.Types; for (int i = 0; i < Parameters.Count; ++i) { if (type_inference.ExactInference (ptypes[i], dtypes[i]) == 0) { // // Continue when 0 (quick path) does not mean inference failure. Checking for // same type handles cases like int -> int // if (ptypes[i] == dtypes[i]) continue; return false; } } return true; }
protected bool VerifyParameterCompatibility (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors) { if (Parameters.Count != invoke_pd.Count) { if (ignore_errors) return false; ec.Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments", delegate_type.GetSignatureForError (), Parameters.Count.ToString ()); return false; } bool has_implicit_parameters = !HasExplicitParameters; bool error = false; for (int i = 0; i < Parameters.Count; ++i) { Parameter.Modifier p_mod = invoke_pd.FixedParameters [i].ModFlags; if (Parameters.FixedParameters [i].ModFlags != p_mod && p_mod != Parameter.Modifier.PARAMS) { if (ignore_errors) return false; if (p_mod == Parameter.Modifier.NONE) ec.Report.Error (1677, Parameters[i].Location, "Parameter `{0}' should not be declared with the `{1}' keyword", (i + 1).ToString (), Parameter.GetModifierSignature (Parameters [i].ModFlags)); else ec.Report.Error (1676, Parameters[i].Location, "Parameter `{0}' must be declared with the `{1}' keyword", (i+1).ToString (), Parameter.GetModifierSignature (p_mod)); error = true; } if (has_implicit_parameters) continue; TypeSpec type = invoke_pd.Types [i]; if (tic != null) type = tic.InflateGenericArgument (ec, type); if (!TypeSpecComparer.IsEqual (type, Parameters.Types [i])) { if (ignore_errors) return false; ec.Report.Error (1678, Parameters [i].Location, "Parameter `{0}' is declared as type `{1}' but should be `{2}'", (i+1).ToString (), Parameters.Types [i].GetSignatureForError (), invoke_pd.Types [i].GetSignatureForError ()); error = true; } } return !error; }
AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, TypeSpec return_type, TypeSpec delegate_type) { ParametersCompiled p = ResolveParameters (ec, tic, delegate_type); if (p == null) return null; ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone () : Block; return CompatibleMethodFactory (return_type, delegate_type, p, b); }
// // 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); }
public override Type[] InferMethodArguments (EmitContext ec, MethodBase method) { Type[] method_generic_args = method.GetGenericArguments (); TypeInferenceContext context = new TypeInferenceContext (method_generic_args); if (!context.UnfixedVariableExists) return Type.EmptyTypes; AParametersCollection pd = TypeManager.GetParameterData (method); if (!InferInPhases (ec, context, pd)) return null; return context.InferredTypeArguments; }
public override Type[] InferDelegateArguments (MethodBase method) { AParametersCollection pd = TypeManager.GetParameterData (method); if (arg_count != pd.Count) return null; Type[] d_gargs = method.GetGenericArguments (); TypeInferenceContext context = new TypeInferenceContext (d_gargs); // A lower-bound inference is made from each argument type Uj of D // to the corresponding parameter type Tj of M for (int i = 0; i < arg_count; ++i) { Type t = pd.Types [i]; if (!t.IsGenericParameter) continue; context.LowerBoundInference ((Type)arguments[i], t); } if (!context.FixAllTypes ()) return null; return context.InferredTypeArguments; }
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); }
public override TypeSpec[] InferMethodArguments (ResolveContext ec, MethodSpec method) { var method_generic_args = method.GenericDefinition.TypeParameters; TypeInferenceContext context = new TypeInferenceContext (method_generic_args); if (!context.UnfixedVariableExists) return TypeSpec.EmptyTypes; AParametersCollection pd = method.Parameters; if (!InferInPhases (ec, context, pd)) return null; return context.InferredTypeArguments; }
// // Infers type arguments based on explicit arguments // public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, TypeSpec delegate_type) { if (!HasExplicitParameters) return false; if (!delegate_type.IsDelegate) { if (!delegate_type.IsExpressionTreeType) return false; delegate_type = TypeManager.GetTypeArguments (delegate_type) [0]; if (!delegate_type.IsDelegate) return false; } AParametersCollection d_params = Delegate.GetParameters (delegate_type); if (d_params.Count != Parameters.Count) return false; for (int i = 0; i < Parameters.Count; ++i) { TypeSpec itype = d_params.Types [i]; if (!TypeManager.IsGenericParameter (itype)) { if (!TypeManager.HasElementType (itype)) continue; if (!TypeManager.IsGenericParameter (TypeManager.GetElementType (itype))) continue; } type_inference.ExactInference (Parameters.Types [i], itype); } return true; }
public TypeSpec InferReturnType (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type) { Expression expr; AnonymousExpression am; if (compatibles.TryGetValue (delegate_type, out expr)) { am = expr as AnonymousExpression; return am == null ? null : am.ReturnType; } using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) { var body = CompatibleMethodBody (ec, tic, InternalType.Arglist, delegate_type); if (body != null) { if (Block.IsAsync) { AsyncInitializer.Create (ec, body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent, null, loc); } am = body.Compatible (ec, body); } else { am = null; } } if (am == null) return null; // compatibles.Add (delegate_type, am); return am.ReturnType; }
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); }
protected bool VerifyExplicitParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type, AParametersCollection parameters) { if (VerifyParameterCompatibility (ec, tic, delegate_type, parameters, ec.IsInProbingMode)) return true; if (!ec.IsInProbingMode) ec.Report.Error (1661, loc, "Cannot convert `{0}' to delegate type `{1}' since there is a parameter mismatch", GetSignatureForError (), delegate_type.GetSignatureForError ()); return false; }
public Type InferReturnType (ResolveContext ec, TypeInferenceContext tic, Type delegate_type) { AnonymousMethodBody am; using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) { am = CompatibleMethod (ec, tic, InternalType.Arglist, delegate_type); } if (am == null) return null; return am.ReturnType; }
protected virtual ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, Type delegate_type) { AParametersCollection delegate_parameters = TypeManager.GetDelegateParameters (ec, delegate_type); if (Parameters == ParametersCompiled.Undefined) { // // We provide a set of inaccessible parameters // Parameter[] fixedpars = new Parameter[delegate_parameters.Count]; for (int i = 0; i < delegate_parameters.Count; i++) { Parameter.Modifier i_mod = delegate_parameters.FixedParameters [i].ModFlags; if (i_mod == Parameter.Modifier.OUT) { ec.Report.Error (1688, loc, "Cannot convert anonymous " + "method block without a parameter list " + "to delegate type `{0}' because it has " + "one or more `out' parameters.", TypeManager.CSharpName (delegate_type)); return null; } fixedpars[i] = new Parameter ( null, null, delegate_parameters.FixedParameters [i].ModFlags, null, loc); } return ParametersCompiled.CreateFullyResolved (fixedpars, delegate_parameters.Types); } if (!VerifyExplicitParameters (ec, delegate_type, delegate_parameters)) { return null; } return Parameters; }
protected AnonymousMethodBody CompatibleMethod (ResolveContext ec, TypeInferenceContext tic, Type return_type, Type delegate_type) { ParametersCompiled p = ResolveParameters (ec, tic, delegate_type); if (p == null) return null; ToplevelBlock b = ec.IsInProbingMode ? (ToplevelBlock) Block.PerformClone () : Block; AnonymousMethodBody anonymous = CompatibleMethodFactory (return_type, delegate_type, p, b); if (!anonymous.Compatible (ec)) return null; return anonymous; }
public TypeSpec InferReturnType (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type) { Expression expr; AnonymousExpression am; if (compatibles.TryGetValue (delegate_type, out expr)) { am = expr as AnonymousExpression; return am == null ? null : am.ReturnType; } using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) { ReportPrinter prev; if (TypeInferenceReportPrinter != null) { prev = ec.Report.SetPrinter (TypeInferenceReportPrinter); } else { prev = null; } var body = CompatibleMethodBody (ec, tic, null, delegate_type); if (body != null) { am = body.Compatible (ec, body); } else { am = null; } if (TypeInferenceReportPrinter != null) { ec.Report.SetPrinter (prev); } } if (am == null) return null; // compatibles.Add (delegate_type, am); return am.ReturnType; }
protected override Parameters ResolveParameters(EmitContext ec, TypeInferenceContext tic, Type delegateType) { if (!TypeManager.IsDelegateType(delegateType)) { return(null); } AParametersCollection d_params = TypeManager.GetDelegateParameters(delegateType); if (HasExplicitParameters) { if (!VerifyExplicitParameters(delegateType, d_params, ec.IsInProbingMode)) { return(null); } return(Parameters); } // // If L has an implicitly typed parameter list we make implicit parameters explicit // Set each parameter of L is given the type of the corresponding parameter in D // if (!VerifyParameterCompatibility(delegateType, d_params, ec.IsInProbingMode)) { return(null); } Type [] ptypes = new Type [Parameters.Count]; for (int i = 0; i < d_params.Count; i++) { // D has no ref or out parameters if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0) { return(null); } Type d_param = d_params.Types [i]; #if MS_COMPATIBLE // Blablabla, because reflection does not work with dynamic types if (d_param.IsGenericParameter) { d_param = delegateType.GetGenericArguments() [d_param.GenericParameterPosition]; } #endif // // When type inference context exists try to apply inferred type arguments // if (tic != null) { d_param = tic.InflateGenericArgument(d_param); } ptypes [i] = d_param; ((ImplicitLambdaParameter)Parameters.FixedParameters [i]).Type = d_param; } Parameters.Types = ptypes; return(Parameters); }
AnonymousMethodBody CompatibleMethodBody (ResolveContext ec, TypeInferenceContext tic, TypeSpec return_type, TypeSpec delegate_type) { ParametersCompiled p = ResolveParameters (ec, tic, delegate_type); if (p == null) return null; ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone () : Block; if (b.IsAsync) { var rt = return_type; if (rt != null && rt.Kind != MemberKind.Void && rt != ec.Module.PredefinedTypes.Task.TypeSpec && !rt.IsGenericTask) { ec.Report.Error (4010, loc, "Cannot convert async {0} to delegate type `{1}'", GetSignatureForError (), delegate_type.GetSignatureForError ()); return null; } b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, loc); } return CompatibleMethodFactory (return_type ?? InternalType.Arglist, delegate_type, p, b); }
public Type InferReturnType (EmitContext ec, TypeInferenceContext tic, Type delegate_type) { AnonymousMethodBody am; using (ec.Set (EmitContext.Flags.ProbingMode | EmitContext.Flags.InferReturnType)) { am = CompatibleMethod (ec, tic, GetType (), delegate_type); } if (am == null) return null; if (am.ReturnType == TypeManager.null_type) am.ReturnType = null; return am.ReturnType; }