public UserOperatorCall (MethodGroupExpr mg, Arguments args, ExpressionTreeExpression expr_tree, Location loc) { this.mg = mg; this.arguments = args; this.expr_tree = expr_tree; type = TypeManager.TypeToCoreType (((MethodInfo) mg).ReturnType); eclass = ExprClass.Value; this.loc = loc; }
protected override Expression DoResolve(ResolveContext ec) { if (Arguments == null || Arguments.Count != 1) { ec.Report.Error(149, loc, "Method name expected"); return(null); } Argument a = Arguments [0]; if (!a.ResolveMethodGroup(ec)) { return(null); } Expression e = a.Expr; AnonymousMethodExpression ame = e as AnonymousMethodExpression; if (ame != null && ec.Module.Compiler.Settings.Version != LanguageVersion.ISO_1) { e = ame.Compatible(ec, type); if (e == null) { return(null); } return(e.Resolve(ec)); } method_group = e as MethodGroupExpr; if (method_group == null) { if (e.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { e = Convert.ImplicitConversionRequired(ec, e, type, loc); } else if (!e.Type.IsDelegate) { e.Error_UnexpectedKind(ec, ResolveFlags.MethodGroup | ResolveFlags.Type, loc); return(null); } // // An argument is not a method but another delegate // method_group = new MethodGroupExpr(Delegate.GetInvokeMethod(e.Type), e.Type, loc); method_group.InstanceExpression = e; } return(base.DoResolve(ec)); }
public static bool ImplicitStandardConversionExists(ResolveContext ec, MethodGroupExpr mg, TypeSpec target_type) { if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type) { return(false); } var invoke = Delegate.GetInvokeMethod(ec.Compiler, target_type); Arguments arguments = CreateDelegateMethodArguments(invoke.Parameters, invoke.Parameters.Types, mg.Location); return(mg.OverloadResolve(ec, ref arguments, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly) != null); }
private static MemberInfo [] FilterOverridenMembersOut( MemberInfo [] ml) { if (ml == null) { return(empty_member_infos); } ArrayList al = new ArrayList(ml.Length); for (int i = 0; i < ml.Length; i++) { MethodBase mx = ml [i] as MethodBase; PropertyInfo px = ml [i] as PropertyInfo; if (mx != null || px != null) { bool overriden = false; for (int j = 0; j < ml.Length; j++) { if (j == i) { continue; } MethodBase my = ml [j] as MethodBase; if (mx != null && my != null && MethodGroupExpr.IsOverride(my, mx)) { overriden = true; break; } else if (mx != null) { continue; } PropertyInfo py = ml [j] as PropertyInfo; if (px != null && py != null && IsOverride(py, px)) { overriden = true; break; } } if (overriden) { continue; } } al.Add(ml [i]); } return(al.ToArray(typeof(MemberInfo)) as MemberInfo []); }
public static bool ImplicitStandardConversionExists(ResolveContext ec, MethodGroupExpr mg, Type target_type) { if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type) { return(false); } mg.DelegateType = target_type; MethodInfo invoke = Delegate.GetInvokeMethod(ec.Compiler, null, target_type); Arguments arguments = CreateDelegateMethodArguments(TypeManager.GetParameterData(invoke), mg.Location); return(mg.OverloadResolve(ec, ref arguments, true, mg.Location) != null); }
public override Expression DoResolve(ResolveContext ec) { if (Arguments == null || Arguments.Count != 1) { ec.Report.Error(149, loc, "Method name expected"); return(null); } Argument a = Arguments [0]; if (!a.ResolveMethodGroup(ec)) { return(null); } Expression e = a.Expr; AnonymousMethodExpression ame = e as AnonymousMethodExpression; if (ame != null && RootContext.Version != LanguageVersion.ISO_1) { e = ame.Compatible(ec, type); if (e == null) { return(null); } return(e.Resolve(ec)); } method_group = e as MethodGroupExpr; if (method_group == null) { if (!TypeManager.IsDelegateType(e.Type)) { e.Error_UnexpectedKind(ec, ResolveFlags.MethodGroup | ResolveFlags.Type, loc); return(null); } // // An argument is not a method but another delegate // delegate_instance_expression = e; method_group = new MethodGroupExpr(new MemberInfo [] { Delegate.GetInvokeMethod(ec.Compiler, ec.CurrentType, e.Type) }, e.Type, loc); } return(base.DoResolve(ec)); }
private void EmitOnCompleted(EmitContext ec, Expression awaiter, bool unsafeVersion) { var pm = Module.PredefinedMembers; PredefinedMember <MethodSpec> predefined; bool has_task_return_type = false; if (return_type.Kind == MemberKind.Void) { predefined = unsafeVersion ? pm.AsyncVoidMethodBuilderOnCompletedUnsafe : pm.AsyncVoidMethodBuilderOnCompleted; } else if (return_type == Module.PredefinedTypes.Task.TypeSpec) { predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderOnCompletedUnsafe : pm.AsyncTaskMethodBuilderOnCompleted; } else { predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderGenericOnCompletedUnsafe : pm.AsyncTaskMethodBuilderGenericOnCompleted; has_task_return_type = true; } var on_completed = predefined.Resolve(Location); if (on_completed == null) { return; } if (has_task_return_type) { on_completed = MemberCache.GetMember <MethodSpec>(set_result.DeclaringType, on_completed); } on_completed = on_completed.MakeGenericMethod(this, awaiter.Type, ec.CurrentType); var mg = MethodGroupExpr.CreatePredefined(on_completed, on_completed.DeclaringType, Location); mg.InstanceExpression = new FieldExpr(builder, Location) { InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, Location) }; var args = new Arguments(2); args.Add(new Argument(awaiter, Argument.AType.Ref)); args.Add(new Argument(new CompilerGeneratedThis(CurrentType, Location), Argument.AType.Ref)); using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) { mg.EmitCall(ec, args, true); } }
public override Expression CreateExpressionTree(ResolveContext ec) { Arguments args = new Arguments(2); args.Add(new Argument(new TypeOf(type, loc))); if (method_group.InstanceExpression == null) { args.Add(new Argument(new NullLiteral(loc))); } else { args.Add(new Argument(method_group.InstanceExpression)); } Expression ma; var create_v45 = ec.Module.PredefinedMembers.MethodInfoCreateDelegate.Get(); if (create_v45 != null) { // // .NET 4.5 has better API but it produces different instance than Delegate::CreateDelegate // and because csc uses this enhancement we have to as well to be fully compatible // var mg = MethodGroupExpr.CreatePredefined(create_v45, create_v45.DeclaringType, loc); mg.InstanceExpression = method_group.CreateExpressionTree(ec); ma = mg; } else { ma = new MemberAccess(new MemberAccess(new QualifiedAliasMember("global", "System", loc), "Delegate", loc), "CreateDelegate", loc); args.Add(new Argument(method_group.CreateExpressionTree(ec))); } Expression e = new Invocation(ma, args).Resolve(ec); if (e == null) { return(null); } e = Convert.ExplicitConversion(ec, e, type, loc); if (e == null) { return(null); } return(e.CreateExpressionTree(ec)); }
protected override void DoEmit(EmitContext ec) { var fe_awaiter = new FieldExpr(awaiter, loc); fe_awaiter.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); // // result = awaiter.GetResult (); // var mg_result = MethodGroupExpr.CreatePredefined(get_result, fe_awaiter.Type, loc); mg_result.InstanceExpression = fe_awaiter; mg_result.EmitCall(ec, new Arguments(0)); }
static public Expression MakeSimpleCall (EmitContext ec, MethodGroupExpr mg, Expression e, Location loc) { ArrayList args; MethodBase method; args = new ArrayList (1); args.Add (new Argument (e, Argument.AType.Expression)); method = Invocation.OverloadResolve (ec, (MethodGroupExpr) mg, args, loc); if (method == null) return null; return new StaticCallExpr ((MethodInfo) method, args, loc); }
// <summary> // Verifies whether the invocation arguments are compatible with the // delegate's target method // </summary> public static bool VerifyApplicability(EmitContext ec, Type delegate_type, ArrayList args, Location loc) { int arg_count; if (args == null) { arg_count = 0; } else { arg_count = args.Count; } Expression ml = Expression.MemberLookup( ec.ContainerType, delegate_type, "Invoke", loc); MethodGroupExpr me = ml as MethodGroupExpr; if (me == null) { Report.Error(-100, loc, "Internal error: could not find Invoke method!" + delegate_type); return(false); } MethodBase mb = GetInvokeMethod(ec.ContainerType, delegate_type); AParametersCollection pd = TypeManager.GetParameterData(mb); int pd_count = pd.Count; bool params_method = pd.HasParams; bool is_params_applicable = false; bool is_applicable = me.IsApplicable(ec, args, arg_count, ref mb, ref is_params_applicable) == 0; if (!is_applicable && !params_method && arg_count != pd_count) { Report.Error(1593, loc, "Delegate `{0}' does not take `{1}' arguments", TypeManager.CSharpName(delegate_type), arg_count.ToString()); return(false); } return(me.VerifyArgumentsCompat( ec, ref args, arg_count, mb, is_params_applicable || (!is_applicable && params_method), false, loc)); }
public static MethodBase ImplicitStandardConversionExists(MethodGroupExpr mg, Type target_type) { if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type) { return(null); } foreach (MethodInfo mi in mg.Methods) { MethodBase mb = Delegate.VerifyMethod(mg.DeclaringType, target_type, mg, mi); if (mb != null) { return(mb); } } return(null); }
public void EmitSetException(EmitContext ec, LocalVariableReference exceptionVariable) { // // $builder.SetException (Exception) // var mg = MethodGroupExpr.CreatePredefined(set_exception, set_exception.DeclaringType, Location); mg.InstanceExpression = new FieldExpr(builder, Location) { InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, Location) }; Arguments args = new Arguments(1); args.Add(new Argument(exceptionVariable)); mg.EmitCall(ec, args); }
// <summary> // Verifies whether the invocation arguments are compatible with the // delegate's target method // </summary> public static bool VerifyApplicability(ResolveContext ec, Type delegate_type, ref Arguments args, Location loc) { int arg_count; if (args == null) { arg_count = 0; } else { arg_count = args.Count; } MethodBase mb = GetInvokeMethod(ec.Compiler, ec.CurrentType, delegate_type); MethodGroupExpr me = new MethodGroupExpr(new MemberInfo [] { mb }, delegate_type, loc); AParametersCollection pd = TypeManager.GetParameterData(mb); int pd_count = pd.Count; bool params_method = pd.HasParams; bool is_params_applicable = false; bool is_applicable = me.IsApplicable(ec, ref args, arg_count, ref mb, ref is_params_applicable) == 0; if (args != null) { arg_count = args.Count; } if (!is_applicable && !params_method && arg_count != pd_count) { ec.Report.Error(1593, loc, "Delegate `{0}' does not take `{1}' arguments", TypeManager.CSharpName(delegate_type), arg_count.ToString()); return(false); } return(me.VerifyArgumentsCompat( ec, ref args, arg_count, mb, is_params_applicable || (!is_applicable && params_method), false, loc)); }
public Expression GetResultExpression(EmitContext ec) { var fe_awaiter = new FieldExpr(awaiter, loc); fe_awaiter.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); // // result = awaiter.GetResult (); // if (IsDynamic) { var rc = new ResolveContext(ec.MemberContext); return(new Invocation(new MemberAccess(fe_awaiter, "GetResult"), new Arguments(0)).Resolve(rc)); } var mg_result = MethodGroupExpr.CreatePredefined(awaiter_definition.GetResult, fe_awaiter.Type, loc); mg_result.InstanceExpression = fe_awaiter; return(new GetResultInvocation(mg_result, new Arguments(0))); }
public static ConstructorInfo GetConstructor(Type container_type, Type delegate_type) { Type dt = delegate_type; #if GMCS_SOURCE Type[] g_args = null; if (delegate_type.IsGenericType) { g_args = delegate_type.GetGenericArguments(); delegate_type = delegate_type.GetGenericTypeDefinition(); } #endif Delegate d = TypeManager.LookupDelegate(delegate_type); if (d != null) { #if GMCS_SOURCE if (g_args != null) { return(TypeBuilder.GetConstructor(dt, d.ConstructorBuilder)); } #endif return(d.ConstructorBuilder); } Expression ml = Expression.MemberLookup(container_type, null, dt, ConstructorInfo.ConstructorName, MemberTypes.Constructor, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, Location.Null); MethodGroupExpr mg = ml as MethodGroupExpr; if (mg == null) { Report.Error(-100, Location.Null, "Internal error: could not find delegate constructor!"); // FIXME: null will cause a crash later return(null); } return((ConstructorInfo)mg.Methods[0]); }
public override bool Resolve (EmitContext ec) { enumerator_type = TypeManager.ienumerator_type; if (!ProbeCollectionType (ec, expr.Type)) { Error_Enumerator (); return false; } bool is_disposable = !enumerator_type.IsSealed || TypeManager.ImplementsInterface (enumerator_type, TypeManager.idisposable_type); VarExpr ve = var_type as VarExpr; if (ve != null) { // Infer implicitly typed local variable from foreach enumerable type var_type = new TypeExpression (get_current.PropertyInfo.PropertyType, var_type.Location); } var_type = var_type.ResolveAsTypeTerminal (ec, false); if (var_type == null) return false; enumerator = new TemporaryVariable (enumerator_type, loc); enumerator.Resolve (ec); init = new Invocation (get_enumerator, null); init = init.Resolve (ec); if (init == null) return false; Expression move_next_expr; { MemberInfo[] mi = new MemberInfo[] { move_next }; MethodGroupExpr mg = new MethodGroupExpr (mi, var_type.Type, loc); mg.InstanceExpression = enumerator; move_next_expr = new Invocation (mg, null); } get_current.InstanceExpression = enumerator; Statement block = new CollectionForeachStatement ( var_type.Type, variable, get_current, statement, loc); loop = new While (move_next_expr, block, loc); wrapper = is_disposable ? (Statement) new DisposableWrapper (this) : (Statement) new NonDisposableWrapper (this); return wrapper.Resolve (ec); }
/// <summary> /// Find the Applicable Function Members (7.4.2.1) /// /// me: Method Group expression with the members to select. /// it might contain constructors or methods (or anything /// that maps to a method). /// /// Arguments: ArrayList containing resolved Argument objects. /// /// loc: The location if we want an error to be reported, or a Null /// location for "probing" purposes. /// /// Returns: The MethodBase (either a ConstructorInfo or a MethodInfo) /// that is the best match of me on Arguments. /// /// </summary> public static MethodBase OverloadResolve (EmitContext ec, MethodGroupExpr me, ArrayList Arguments, Location loc) { MethodBase method = null; Type current_type = null; int argument_count; ArrayList candidates = new ArrayList (); foreach (MethodBase candidate in me.Methods){ int x; // If we're going one level higher in the class hierarchy, abort if // we already found an applicable method. if (candidate.DeclaringType != current_type) { current_type = candidate.DeclaringType; if (method != null) break; } // Check if candidate is applicable (section 14.4.2.1) if (!IsApplicable (ec, Arguments, candidate)) continue; candidates.Add (candidate); x = BetterFunction (ec, Arguments, candidate, method, false, loc); if (x == 0) continue; method = candidate; } if (Arguments == null) argument_count = 0; else argument_count = Arguments.Count; // // Now we see if we can find params functions, applicable in their expanded form // since if they were applicable in their normal form, they would have been selected // above anyways // bool chose_params_expanded = false; if (method == null) { candidates = new ArrayList (); foreach (MethodBase candidate in me.Methods){ if (!IsParamsMethodApplicable (ec, Arguments, candidate)) continue; candidates.Add (candidate); int x = BetterFunction (ec, Arguments, candidate, method, true, loc); if (x == 0) continue; method = candidate; chose_params_expanded = true; } } if (method == null) { // // Okay so we have failed to find anything so we // return by providing info about the closest match // for (int i = 0; i < me.Methods.Length; ++i) { MethodBase c = (MethodBase) me.Methods [i]; ParameterData pd = GetParameterData (c); if (pd.Count != argument_count) continue; VerifyArgumentsCompat (ec, Arguments, argument_count, c, false, null, loc); } return null; } // // Now check that there are no ambiguities i.e the selected method // should be better than all the others // foreach (MethodBase candidate in candidates){ if (candidate == method) continue; // // If a normal method is applicable in the sense that it has the same // number of arguments, then the expanded params method is never applicable // so we debar the params method. // if (IsParamsMethodApplicable (ec, Arguments, candidate) && IsApplicable (ec, Arguments, method)) continue; int x = BetterFunction (ec, Arguments, method, candidate, chose_params_expanded, loc); if (x != 1) { Report.Error ( 121, loc, "Ambiguous call when selecting function due to implicit casts"); return null; } } // // And now check if the arguments are all compatible, perform conversions // if necessary etc. and return if everything is all right // if (!VerifyArgumentsCompat (ec, Arguments, argument_count, method, chose_params_expanded, null, loc)) return null; return method; }
public override Expression DoResolve (ResolveContext ec) { eclass = ExprClass.Value; // TODO: ec.GetSignatureForError () ConstructorBuilder caller_builder = ((Constructor) ec.MemberContext).ConstructorBuilder; if (argument_list != null) { bool dynamic; // // Spec mandates that constructor initializer will not have `this' access // using (ec.Set (ResolveContext.Options.BaseInitializer)) { argument_list.Resolve (ec, out dynamic); } if (dynamic) { SimpleName ctor = new SimpleName (ConstructorBuilder.ConstructorName, loc); return new DynamicInvocation (ctor, argument_list, loc).Resolve (ec) as ExpressionStatement; } } type = ec.CurrentType; if (this is ConstructorBaseInitializer) { if (ec.CurrentType.BaseType == null) return this; type = ec.CurrentType.BaseType; if (TypeManager.IsStruct (ec.CurrentType)) { ec.Report.Error (522, loc, "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder)); return this; } } else { // // It is legal to have "this" initializers that take no arguments // in structs, they are just no-ops. // // struct D { public D (int a) : this () {} // if (TypeManager.IsStruct (ec.CurrentType) && argument_list == null) return this; } base_constructor_group = MemberLookupFinal ( ec, null, type, ConstructorBuilder.ConstructorName, MemberTypes.Constructor, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, loc) as MethodGroupExpr; if (base_constructor_group == null) return this; base_constructor_group = base_constructor_group.OverloadResolve ( ec, ref argument_list, false, loc); if (base_constructor_group == null) return this; if (!ec.IsStatic) base_constructor_group.InstanceExpression = ec.GetThis (loc); ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group; if (base_ctor == caller_builder){ ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder)); } return this; }
public void EmitPrologue(EmitContext ec) { var fe_awaiter = new FieldExpr(awaiter, loc); fe_awaiter.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); // // awaiter = expr.GetAwaiter (); // fe_awaiter.EmitAssign(ec, expr, false, false); Label skip_continuation = ec.DefineLabel(); is_completed.InstanceExpression = fe_awaiter; is_completed.EmitBranchable(ec, skip_continuation, true); base.DoEmit(ec); FieldSpec[] stack_fields = null; TypeSpec[] stack = null; // // Here is the clever bit. We know that await statement has to yield the control // back but it can appear inside almost any expression. This means the stack can // contain any depth of values and same values have to be present when the continuation // handles control back. // // For example: await a + await b // // In this case we fabricate a static stack forwarding method which moves the values // from the stack to async storey fields. On re-entry point we restore exactly same // stack using these fields. // // We fabricate a static method because we don't want to touch original stack and // the instance method would require `this' as the first stack value on the stack // if (ec.StackHeight > 0) { var async_storey = (AsyncTaskStorey)machine_initializer.Storey; stack = ec.GetStackTypes(); var method = async_storey.GetStackForwarder(stack, out stack_fields); ec.EmitThis(); ec.Emit(OpCodes.Call, method); } var mg_completed = MethodGroupExpr.CreatePredefined(on_completed, fe_awaiter.Type, loc); mg_completed.InstanceExpression = fe_awaiter; var args = new Arguments(1); var storey = (AsyncTaskStorey)machine_initializer.Storey; var fe_cont = new FieldExpr(storey.Continuation, loc); fe_cont.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); args.Add(new Argument(fe_cont)); // // awaiter.OnCompleted (continuation); // mg_completed.EmitCall(ec, args); // Return ok machine_initializer.EmitLeave(ec, unwind_protect); ec.MarkLabel(resume_point); if (stack_fields != null) { for (int i = 0; i < stack_fields.Length; ++i) { ec.EmitThis(); var field = stack_fields[i]; // // We don't store `this' because it can be easily re-created // if (field == null) { continue; } if (stack[i] is ReferenceContainer) { ec.Emit(OpCodes.Ldflda, field); } else { ec.Emit(OpCodes.Ldfld, field); } } } ec.MarkLabel(skip_continuation); }
// <summary> // Verifies whether the invocation arguments are compatible with the // delegate's target method // </summary> public static bool VerifyApplicability (ResolveContext ec, Type delegate_type, ref Arguments args, Location loc) { int arg_count; if (args == null) arg_count = 0; else arg_count = args.Count; MethodBase mb = GetInvokeMethod (ec.Compiler, ec.CurrentType, delegate_type); MethodGroupExpr me = new MethodGroupExpr (new MemberInfo [] { mb }, delegate_type, loc); AParametersCollection pd = TypeManager.GetParameterData (mb); int pd_count = pd.Count; bool params_method = pd.HasParams; bool is_params_applicable = false; bool is_applicable = me.IsApplicable (ec, ref args, arg_count, ref mb, ref is_params_applicable) == 0; if (args != null) arg_count = args.Count; if (!is_applicable && !params_method && arg_count != pd_count) { ec.Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments", TypeManager.CSharpName (delegate_type), arg_count.ToString ()); return false; } return me.VerifyArgumentsCompat ( ec, ref args, arg_count, mb, is_params_applicable || (!is_applicable && params_method), false, loc); }
public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, Type target_type) { if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type) return false; mg.DelegateType = target_type; MethodInfo invoke = Delegate.GetInvokeMethod (ec.Compiler, null, target_type); Arguments arguments = CreateDelegateMethodArguments (TypeManager.GetParameterData (invoke), mg.Location); return mg.OverloadResolve (ec, ref arguments, true, mg.Location) != null; }
ImplicitDelegateCreation (TypeSpec t, MethodGroupExpr mg, Location l) { type = t; this.method_group = mg; loc = l; }
Expression CreateExpressionTree (ResolveContext ec, MethodGroupExpr user_op) { string method_name; switch (Oper) { case Operator.AddressOf: Error_PointerInsideExpressionTree (ec); return null; case Operator.UnaryNegation: if (ec.HasSet (ResolveContext.Options.CheckedScope) && user_op == null && !IsFloat (type)) method_name = "NegateChecked"; else method_name = "Negate"; break; case Operator.OnesComplement: case Operator.LogicalNot: method_name = "Not"; break; case Operator.UnaryPlus: method_name = "UnaryPlus"; break; default: throw new InternalErrorException ("Unknown unary operator " + Oper.ToString ()); } Arguments args = new Arguments (2); args.Add (new Argument (Expr.CreateExpressionTree (ec))); if (user_op != null) args.Add (new Argument (user_op.CreateExpressionTree (ec))); return CreateExpressionFactoryCall (ec, method_name, args); }
Expression CreateExpressionTree (ResolveContext ec, MethodGroupExpr method) { string method_name; bool lift_arg = false; switch (oper) { case Operator.Addition: if (method == null && ec.HasSet (ResolveContext.Options.CheckedScope) && !IsFloat (type)) method_name = "AddChecked"; else method_name = "Add"; break; case Operator.BitwiseAnd: method_name = "And"; break; case Operator.BitwiseOr: method_name = "Or"; break; case Operator.Division: method_name = "Divide"; break; case Operator.Equality: method_name = "Equal"; lift_arg = true; break; case Operator.ExclusiveOr: method_name = "ExclusiveOr"; break; case Operator.GreaterThan: method_name = "GreaterThan"; lift_arg = true; break; case Operator.GreaterThanOrEqual: method_name = "GreaterThanOrEqual"; lift_arg = true; break; case Operator.Inequality: method_name = "NotEqual"; lift_arg = true; break; case Operator.LeftShift: method_name = "LeftShift"; break; case Operator.LessThan: method_name = "LessThan"; lift_arg = true; break; case Operator.LessThanOrEqual: method_name = "LessThanOrEqual"; lift_arg = true; break; case Operator.LogicalAnd: method_name = "AndAlso"; break; case Operator.LogicalOr: method_name = "OrElse"; break; case Operator.Modulus: method_name = "Modulo"; break; case Operator.Multiply: if (method == null && ec.HasSet (ResolveContext.Options.CheckedScope) && !IsFloat (type)) method_name = "MultiplyChecked"; else method_name = "Multiply"; break; case Operator.RightShift: method_name = "RightShift"; break; case Operator.Subtraction: if (method == null && ec.HasSet (ResolveContext.Options.CheckedScope) && !IsFloat (type)) method_name = "SubtractChecked"; else method_name = "Subtract"; break; default: throw new InternalErrorException ("Unknown expression tree binary operator " + oper); } Arguments args = new Arguments (2); args.Add (new Argument (left.CreateExpressionTree (ec))); args.Add (new Argument (right.CreateExpressionTree (ec))); if (method != null) { if (lift_arg) args.Add (new Argument (new BoolConstant (false, loc))); args.Add (new Argument (method.CreateExpressionTree (ec))); } return CreateExpressionFactoryCall (ec, method_name, args); }
bool TryType (EmitContext ec, Type t) { MethodGroupExpr mg = Expression.MemberLookup ( ec.ContainerType, t, "GetEnumerator", MemberTypes.Method, Expression.AllBindingFlags, loc) as MethodGroupExpr; if (mg == null) return false; MethodInfo result = null; MethodInfo tmp_move_next = null; PropertyExpr tmp_get_cur = null; Type tmp_enumerator_type = enumerator_type; foreach (MethodInfo mi in mg.Methods) { if (TypeManager.GetParameterData (mi).Count != 0) continue; // Check whether GetEnumerator is public if ((mi.Attributes & MethodAttributes.Public) != MethodAttributes.Public) continue; if (IsOverride (mi)) continue; enumerator_found = true; if (!GetEnumeratorFilter (ec, mi)) continue; if (result != null) { if (TypeManager.IsGenericType (result.ReturnType)) { if (!TypeManager.IsGenericType (mi.ReturnType)) continue; MethodBase mb = TypeManager.DropGenericMethodArguments (mi); Report.SymbolRelatedToPreviousError (t); Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " + "because it contains multiple implementation of `{1}'. Try casting to a specific implementation", TypeManager.CSharpName (t), TypeManager.CSharpSignature (mb)); return false; } // Always prefer generics enumerators if (!TypeManager.IsGenericType (mi.ReturnType)) { if (TypeManager.ImplementsInterface (mi.DeclaringType, result.DeclaringType) || TypeManager.ImplementsInterface (result.DeclaringType, mi.DeclaringType)) continue; Report.SymbolRelatedToPreviousError (result); Report.SymbolRelatedToPreviousError (mi); Report.Warning (278, 2, loc, "`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'", TypeManager.CSharpName (t), "enumerable", TypeManager.CSharpSignature (result), TypeManager.CSharpSignature (mi)); return false; } } result = mi; tmp_move_next = move_next; tmp_get_cur = get_current; tmp_enumerator_type = enumerator_type; if (mi.DeclaringType == t) break; } if (result != null) { move_next = tmp_move_next; get_current = tmp_get_cur; enumerator_type = tmp_enumerator_type; MethodInfo[] mi = new MethodInfo[] { (MethodInfo) result }; get_enumerator = new MethodGroupExpr (mi, enumerator_type, loc); if (t != expr.Type) { expr = Convert.ExplicitConversion ( ec, expr, t, loc); if (expr == null) throw new InternalErrorException (); } get_enumerator.InstanceExpression = expr; get_enumerator.IsBase = t != expr.Type; return true; } return false; }
// // D operator + (D x, D y) // D operator - (D x, D y) // bool operator == (D x, D y) // bool operator != (D x, D y) // Expression ResolveOperatorDelegate (ResolveContext ec, Type l, Type r) { bool is_equality = (oper & Operator.EqualityMask) != 0; if (!TypeManager.IsEqual (l, r) && !TypeManager.IsVariantOf (r, l)) { Expression tmp; if (right.eclass == ExprClass.MethodGroup || (r == InternalType.AnonymousMethod && !is_equality)) { tmp = Convert.ImplicitConversionRequired (ec, right, l, loc); if (tmp == null) return null; right = tmp; r = right.Type; } else if (left.eclass == ExprClass.MethodGroup || (l == InternalType.AnonymousMethod && !is_equality)) { tmp = Convert.ImplicitConversionRequired (ec, left, r, loc); if (tmp == null) return null; left = tmp; l = left.Type; } else { return null; } } // // Resolve delegate equality as a user operator // if (is_equality) return ResolveUserOperator (ec, l, r); MethodInfo method; Arguments args = new Arguments (2); args.Add (new Argument (left)); args.Add (new Argument (right)); if (oper == Operator.Addition) { if (TypeManager.delegate_combine_delegate_delegate == null) { TypeManager.delegate_combine_delegate_delegate = TypeManager.GetPredefinedMethod ( TypeManager.delegate_type, "Combine", loc, TypeManager.delegate_type, TypeManager.delegate_type); } method = TypeManager.delegate_combine_delegate_delegate; } else { if (TypeManager.delegate_remove_delegate_delegate == null) { TypeManager.delegate_remove_delegate_delegate = TypeManager.GetPredefinedMethod ( TypeManager.delegate_type, "Remove", loc, TypeManager.delegate_type, TypeManager.delegate_type); } method = TypeManager.delegate_remove_delegate_delegate; } MethodGroupExpr mg = new MethodGroupExpr (new MemberInfo [] { method }, TypeManager.delegate_type, loc); mg = mg.OverloadResolve (ec, ref args, false, loc); return new ClassCast (new UserOperatorCall (mg, args, CreateExpressionTree, loc), l); }
public override Expression DoResolve (EmitContext ec) { // Don't resolve already resolved expression if (eclass != ExprClass.Invalid) return this; Expression expr_resolved = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup); if (expr_resolved == null) return null; mg = expr_resolved as MethodGroupExpr; if (mg == null) { Type expr_type = expr_resolved.Type; if (expr_type != null && TypeManager.IsDelegateType (expr_type)){ return (new DelegateInvocation ( expr_resolved, Arguments, loc)).Resolve (ec); } MemberExpr me = expr_resolved as MemberExpr; if (me == null) { expr_resolved.Error_UnexpectedKind (ResolveFlags.MethodGroup, loc); return null; } mg = ec.TypeContainer.LookupExtensionMethod (me.Type, me.Name, loc); if (mg == null) { Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate", expr_resolved.GetSignatureForError ()); return null; } ((ExtensionMethodGroupExpr)mg).ExtensionExpression = me.InstanceExpression; } // // Next, evaluate all the expressions in the argument list // if (Arguments != null && !arguments_resolved) { for (int i = 0; i < Arguments.Count; ++i) { if (!((Argument)Arguments[i]).Resolve(ec, loc)) return null; } } mg = DoResolveOverload (ec); if (mg == null) return null; MethodInfo method = (MethodInfo)mg; if (method != null) { type = TypeManager.TypeToCoreType (method.ReturnType); // TODO: this is a copy of mg.ResolveMemberAccess method Expression iexpr = mg.InstanceExpression; if (method.IsStatic) { if (iexpr == null || iexpr is This || iexpr is EmptyExpression || mg.IdenticalTypeName) { mg.InstanceExpression = null; } else { MemberExpr.error176 (loc, mg.GetSignatureForError ()); return null; } } else { if (iexpr == null) { SimpleName.Error_ObjectRefRequired (ec, loc, mg.GetSignatureForError ()); } } } if (type.IsPointer){ if (!ec.InUnsafe){ UnsafeError (loc); return null; } } // // Only base will allow this invocation to happen. // if (mg.IsBase && method.IsAbstract){ Error_CannotCallAbstractBase (TypeManager.CSharpSignature (method)); return null; } if (Arguments == null && method.DeclaringType == TypeManager.object_type && method.Name == Destructor.MetadataName) { if (mg.IsBase) Report.Error (250, loc, "Do not directly call your base class Finalize method. It is called automatically from your destructor"); else Report.Error (245, loc, "Destructors and object.Finalize cannot be called directly. Consider calling IDisposable.Dispose if available"); return null; } IsSpecialMethodInvocation (method, loc); if (mg.InstanceExpression != null) mg.InstanceExpression.CheckMarshalByRefAccess (ec); eclass = ExprClass.Value; return this; }
public void EmitPrologue(EmitContext ec) { var fe_awaiter = new FieldExpr(awaiter, loc); fe_awaiter.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); // // awaiter = expr.GetAwaiter (); // fe_awaiter.EmitAssign(ec, expr, false, false); Label skip_continuation = ec.DefineLabel(); Expression completed_expr; if (IsDynamic) { var rc = new ResolveContext(ec.MemberContext); Arguments dargs = new Arguments(1); dargs.Add(new Argument(fe_awaiter)); completed_expr = new DynamicMemberBinder("IsCompleted", dargs, loc).Resolve(rc); } else { var pe = PropertyExpr.CreatePredefined(is_completed, loc); pe.InstanceExpression = fe_awaiter; completed_expr = pe; } completed_expr.EmitBranchable(ec, skip_continuation, true); base.DoEmit(ec); // // The stack has to be empty before calling await continuation. We handle this // by lifting values which would be left on stack into class fields. The process // is quite complicated and quite hard to test because any expression can possibly // leave a value on the stack. // // Following assert fails when some of expression called before is missing EmitToField // or parent expression fails to find await in children expressions // ec.AssertEmptyStack(); var args = new Arguments(1); var storey = (AsyncTaskStorey)machine_initializer.Storey; var fe_cont = new FieldExpr(storey.Continuation, loc); fe_cont.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); args.Add(new Argument(fe_cont)); if (IsDynamic) { var rc = new ResolveContext(ec.MemberContext); var mg_expr = new Invocation(new MemberAccess(fe_awaiter, "OnCompleted"), args).Resolve(rc); ExpressionStatement es = (ExpressionStatement)mg_expr; es.EmitStatement(ec); } else { var mg_completed = MethodGroupExpr.CreatePredefined(on_completed, fe_awaiter.Type, loc); mg_completed.InstanceExpression = fe_awaiter; // // awaiter.OnCompleted (continuation); // mg_completed.EmitCall(ec, args); } // Return ok machine_initializer.EmitLeave(ec, unwind_protect); ec.MarkLabel(resume_point); ec.MarkLabel(skip_continuation); }
public override Expression DoResolve (ResolveContext ec) { if (Arguments == null || Arguments.Count != 1) { ec.Report.Error (149, loc, "Method name expected"); return null; } Argument a = Arguments [0]; if (!a.ResolveMethodGroup (ec)) return null; Expression e = a.Expr; AnonymousMethodExpression ame = e as AnonymousMethodExpression; if (ame != null && RootContext.Version != LanguageVersion.ISO_1) { e = ame.Compatible (ec, type); if (e == null) return null; return e.Resolve (ec); } method_group = e as MethodGroupExpr; if (method_group == null) { if (!TypeManager.IsDelegateType (e.Type)) { e.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup | ResolveFlags.Type, loc); return null; } // // An argument is not a method but another delegate // delegate_instance_expression = e; method_group = new MethodGroupExpr (new MemberInfo [] { Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, e.Type) }, e.Type, loc); } return base.DoResolve (ec); }
protected override bool DoDefineMembers() { var action = Module.PredefinedTypes.Action.Resolve(); if (action != null) { continuation = AddCompilerGeneratedField("$continuation", new TypeExpression(action, Location), true); continuation.ModFlags |= Modifiers.READONLY; } PredefinedType builder_type; PredefinedMember <MethodSpec> bf; PredefinedMember <MethodSpec> sr; PredefinedMember <MethodSpec> se; bool has_task_return_type = false; var pred_members = Module.PredefinedMembers; if (return_type.Kind == MemberKind.Void) { builder_type = Module.PredefinedTypes.AsyncVoidMethodBuilder; bf = pred_members.AsyncVoidMethodBuilderCreate; sr = pred_members.AsyncVoidMethodBuilderSetResult; se = pred_members.AsyncVoidMethodBuilderSetException; } else if (return_type == Module.PredefinedTypes.Task.TypeSpec) { builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilder; bf = pred_members.AsyncTaskMethodBuilderCreate; sr = pred_members.AsyncTaskMethodBuilderSetResult; se = pred_members.AsyncTaskMethodBuilderSetException; task = pred_members.AsyncTaskMethodBuilderTask.Get(); } else { builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilderGeneric; bf = pred_members.AsyncTaskMethodBuilderGenericCreate; sr = pred_members.AsyncTaskMethodBuilderGenericSetResult; se = pred_members.AsyncTaskMethodBuilderGenericSetException; task = pred_members.AsyncTaskMethodBuilderGenericTask.Get(); has_task_return_type = true; } set_result = sr.Get(); set_exception = se.Get(); var builder_factory = bf.Get(); if (!builder_type.Define() || set_result == null || builder_factory == null || set_exception == null) { Report.Error(1993, Location, "Cannot find compiler required types for asynchronous functions support. Are you targeting the wrong framework version?"); return(base.DoDefineMembers()); } var bt = builder_type.TypeSpec; // // Inflate generic Task types // if (has_task_return_type) { var task_return_type = return_type.TypeArguments; if (mutator != null) { task_return_type = mutator.Mutate(task_return_type); } bt = bt.MakeGenericType(Module, task_return_type); builder_factory = MemberCache.GetMember <MethodSpec> (bt, builder_factory); set_result = MemberCache.GetMember <MethodSpec> (bt, set_result); set_exception = MemberCache.GetMember <MethodSpec> (bt, set_exception); if (task != null) { task = MemberCache.GetMember <PropertySpec> (bt, task); } } builder = AddCompilerGeneratedField("$builder", new TypeExpression(bt, Location)); if (!base.DoDefineMembers()) { return(false); } MethodGroupExpr mg; var block = instance_constructors[0].Block; // // Initialize continuation with state machine method // if (continuation != null) { var args = new Arguments(1); mg = MethodGroupExpr.CreatePredefined(StateMachineMethod.Spec, spec, Location); args.Add(new Argument(mg)); block.AddStatement( new StatementExpression(new SimpleAssign( new FieldExpr(continuation, Location), new NewDelegate(action, args, Location), Location ))); } mg = MethodGroupExpr.CreatePredefined(builder_factory, bt, Location); block.AddStatement( new StatementExpression(new SimpleAssign( new FieldExpr(builder, Location), new Invocation(mg, new Arguments(0)), Location))); if (has_task_return_type) { hoisted_return = LocalVariable.CreateCompilerGenerated(bt.TypeArguments[0], block, Location); } return(true); }
public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, TypeSpec target_type) { // if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type) // return false; var invoke = Delegate.GetInvokeMethod (target_type); Arguments arguments = CreateDelegateMethodArguments (ec, invoke.Parameters, invoke.Parameters.Types, mg.Location); mg = mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly); return mg != null && Delegate.IsTypeCovariant (ec, mg.BestCandidateReturnType, invoke.ReturnType); }
/// <summary> /// Verifies whether the method in question is compatible with the delegate /// Returns the method itself if okay and null if not. /// </summary> public static MethodBase VerifyMethod(Type container_type, Type delegate_type, MethodGroupExpr old_mg, MethodBase mb) { bool is_method_definition = TypeManager.IsGenericMethodDefinition(mb); MethodInfo invoke_mb = GetInvokeMethod(container_type, delegate_type); if (invoke_mb == null) { return(null); } if (is_method_definition) { invoke_mb = (MethodInfo)TypeManager.DropGenericMethodArguments(invoke_mb); } AParametersCollection invoke_pd = TypeManager.GetParameterData(invoke_mb); #if GMCS_SOURCE if (!is_method_definition && old_mg.type_arguments == null && !TypeManager.InferTypeArguments(invoke_pd, ref mb)) { return(null); } #endif AParametersCollection pd = TypeManager.GetParameterData(mb); if (invoke_pd.Count != pd.Count) { return(null); } for (int i = pd.Count; i > 0;) { i--; Type invoke_pd_type = invoke_pd.Types [i]; Type pd_type = pd.Types [i]; Parameter.Modifier invoke_pd_type_mod = invoke_pd.FixedParameters [i].ModFlags; Parameter.Modifier pd_type_mod = pd.FixedParameters [i].ModFlags; invoke_pd_type_mod &= ~Parameter.Modifier.PARAMS; pd_type_mod &= ~Parameter.Modifier.PARAMS; if (invoke_pd_type_mod != pd_type_mod) { return(null); } if (TypeManager.IsEqual(invoke_pd_type, pd_type)) { continue; } if (IsTypeCovariant(new EmptyExpression(invoke_pd_type), pd_type)) { continue; } return(null); } Type invoke_mb_retval = ((MethodInfo)invoke_mb).ReturnType; Type mb_retval = ((MethodInfo)mb).ReturnType; if (TypeManager.TypeToCoreType(invoke_mb_retval) == TypeManager.TypeToCoreType(mb_retval)) { return(mb); } //if (!IsTypeCovariant (mb_retval, invoke_mb_retval)) // return null; if (RootContext.Version == LanguageVersion.ISO_1) { return(null); } return(mb); }
protected override Expression DoResolve (ResolveContext ec) { if (Arguments == null || Arguments.Count != 1) { ec.Report.Error (149, loc, "Method name expected"); return null; } Argument a = Arguments [0]; if (!a.ResolveMethodGroup (ec)) return null; Expression e = a.Expr; AnonymousMethodExpression ame = e as AnonymousMethodExpression; if (ame != null && ec.Module.Compiler.Settings.Version != LanguageVersion.ISO_1) { e = ame.Compatible (ec, type); if (e == null) return null; return e.Resolve (ec); } method_group = e as MethodGroupExpr; if (method_group == null) { if (e.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { e = Convert.ImplicitConversionRequired (ec, e, type, loc); } else if (!e.Type.IsDelegate) { e.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup | ResolveFlags.Type, loc); return null; } // // An argument is not a method but another delegate // method_group = new MethodGroupExpr (Delegate.GetInvokeMethod (e.Type), e.Type, loc); method_group.InstanceExpression = e; } return base.DoResolve (ec); }
public override Expression DoResolve (ResolveContext ec) { constructor_method = Delegate.GetConstructor (ec.Compiler, ec.CurrentType, type); MethodInfo invoke_method = Delegate.GetInvokeMethod (ec.Compiler, ec.CurrentType, type); method_group.DelegateType = type; method_group.CustomErrorHandler = this; Arguments arguments = CreateDelegateMethodArguments (TypeManager.GetParameterData (invoke_method), loc); method_group = method_group.OverloadResolve (ec, ref arguments, false, loc); if (method_group == null) return null; delegate_method = (MethodInfo) method_group; if (TypeManager.IsNullableType (delegate_method.DeclaringType)) { ec.Report.Error (1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type", TypeManager.GetFullNameSignature (delegate_method)); return null; } Invocation.IsSpecialMethodInvocation (ec, delegate_method, loc); ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { delegate_instance_expression = emg.ExtensionExpression; Type e_type = delegate_instance_expression.Type; if (TypeManager.IsValueType (e_type)) { ec.Report.Error (1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", TypeManager.CSharpSignature (delegate_method), TypeManager.CSharpName (e_type)); } } Type rt = TypeManager.TypeToCoreType (delegate_method.ReturnType); Expression ret_expr = new TypeExpression (rt, loc); if (!Delegate.IsTypeCovariant (ret_expr, (TypeManager.TypeToCoreType (invoke_method.ReturnType)))) { Error_ConversionFailed (ec, delegate_method, ret_expr); } if (Invocation.IsMethodExcluded (delegate_method, loc)) { ec.Report.SymbolRelatedToPreviousError (delegate_method); MethodOrOperator m = TypeManager.GetMethod (delegate_method) as MethodOrOperator; if (m != null && m.IsPartialDefinition) { ec.Report.Error (762, loc, "Cannot create delegate from partial method declaration `{0}'", TypeManager.CSharpSignature (delegate_method)); } else { ec.Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method)); } } DoResolveInstanceExpression (ec); eclass = ExprClass.Value; return this; }
protected override Expression DoResolve(ResolveContext ec) { constructor_method = Delegate.GetConstructor(type); var invoke_method = Delegate.GetInvokeMethod(type); ResolveConditionalAccessReceiver(ec); Arguments arguments = CreateDelegateMethodArguments(ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve(ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); if (method_group == null) { return(null); } var delegate_method = method_group.BestCandidate; if (delegate_method.DeclaringType.IsNullableType) { ec.Report.Error(1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type", delegate_method.GetSignatureForError()); return(null); } if (!AllowSpecialMethodsInvocation) { Invocation.IsSpecialMethodInvocation(ec, delegate_method, loc); } ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { method_group.InstanceExpression = emg.ExtensionExpression; TypeSpec e_type = emg.ExtensionExpression.Type; if (TypeSpec.IsValueType(e_type)) { ec.Report.Error(1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", delegate_method.GetSignatureForError(), e_type.GetSignatureForError()); } } TypeSpec rt = method_group.BestCandidateReturnType; if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { rt = ec.BuiltinTypes.Object; } if (!Delegate.IsTypeCovariant(ec, rt, invoke_method.ReturnType)) { Expression ret_expr = new TypeExpression(delegate_method.ReturnType, loc); Error_ConversionFailed(ec, delegate_method, ret_expr); } if (method_group.IsConditionallyExcluded) { ec.Report.SymbolRelatedToPreviousError(delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { ec.Report.Error(762, loc, "Cannot create delegate from partial method declaration `{0}'", delegate_method.GetSignatureForError()); } else { ec.Report.Error(1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature(delegate_method)); } } var expr = method_group.InstanceExpression; if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType(expr.Type))) { method_group.InstanceExpression = new BoxedCast(expr, ec.BuiltinTypes.Object); } eclass = ExprClass.Value; return(this); }
public override Expression DoResolve(ResolveContext ec) { constructor_method = Delegate.GetConstructor(ec.Compiler, ec.CurrentType, type); MethodInfo invoke_method = Delegate.GetInvokeMethod(ec.Compiler, ec.CurrentType, type); method_group.DelegateType = type; method_group.CustomErrorHandler = this; Arguments arguments = CreateDelegateMethodArguments(TypeManager.GetParameterData(invoke_method), loc); method_group = method_group.OverloadResolve(ec, ref arguments, false, loc); if (method_group == null) { return(null); } delegate_method = (MethodInfo)method_group; if (TypeManager.IsNullableType(delegate_method.DeclaringType)) { ec.Report.Error(1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type", TypeManager.GetFullNameSignature(delegate_method)); return(null); } Invocation.IsSpecialMethodInvocation(ec, delegate_method, loc); ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { delegate_instance_expression = emg.ExtensionExpression; Type e_type = delegate_instance_expression.Type; if (TypeManager.IsValueType(e_type)) { ec.Report.Error(1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", TypeManager.CSharpSignature(delegate_method), TypeManager.CSharpName(e_type)); } } Type rt = TypeManager.TypeToCoreType(delegate_method.ReturnType); Expression ret_expr = new TypeExpression(rt, loc); if (!Delegate.IsTypeCovariant(ret_expr, (TypeManager.TypeToCoreType(invoke_method.ReturnType)))) { Error_ConversionFailed(ec, delegate_method, ret_expr); } if (Invocation.IsMethodExcluded(delegate_method, loc)) { ec.Report.SymbolRelatedToPreviousError(delegate_method); MethodOrOperator m = TypeManager.GetMethod(delegate_method) as MethodOrOperator; if (m != null && m.IsPartialDefinition) { ec.Report.Error(762, loc, "Cannot create delegate from partial method declaration `{0}'", TypeManager.CSharpSignature(delegate_method)); } else { ec.Report.Error(1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature(delegate_method)); } } DoResolveInstanceExpression(ec); eclass = ExprClass.Value; return(this); }
public GetResultInvocation(MethodGroupExpr mge, Arguments arguments) : base(null, arguments) { mg = mge; type = mg.BestCandidateReturnType; }
protected override Expression DoResolve(ResolveContext ec) { if (InstanceExpr is EventExpr) { ((EventExpr) InstanceExpr).Error_CannotAssign (ec); return null; } TypeSpec del_type = InstanceExpr.Type; if (del_type == null) return null; method = Delegate.GetInvokeMethod (ec.Compiler, del_type); var mb = method; var me = new MethodGroupExpr (mb, del_type, loc); me.InstanceExpression = InstanceExpr; AParametersCollection pd = mb.Parameters; int pd_count = pd.Count; int arg_count = arguments == null ? 0 : arguments.Count; bool params_method = pd.HasParams; bool is_params_applicable = false; bool is_applicable = me.IsApplicable (ec, ref arguments, arg_count, ref mb, ref is_params_applicable) == 0; if (arguments != null) arg_count = arguments.Count; if (!is_applicable && !params_method && arg_count != pd_count) { ec.Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments", TypeManager.CSharpName (del_type), arg_count.ToString ()); } else if (arguments == null || !arguments.HasDynamic) { me.VerifyArgumentsCompat (ec, ref arguments, arg_count, mb, is_params_applicable || (!is_applicable && params_method), false, loc); } type = method.ReturnType; eclass = ExprClass.Value; return this; }
protected override bool DoDefineMembers() { PredefinedType builder_type; PredefinedMember <MethodSpec> bf; PredefinedMember <MethodSpec> bs; PredefinedMember <MethodSpec> sr; PredefinedMember <MethodSpec> se; PredefinedMember <MethodSpec> sm; bool has_task_return_type = false; var pred_members = Module.PredefinedMembers; if (return_type.Kind == MemberKind.Void) { builder_type = Module.PredefinedTypes.AsyncVoidMethodBuilder; bf = pred_members.AsyncVoidMethodBuilderCreate; bs = pred_members.AsyncVoidMethodBuilderStart; sr = pred_members.AsyncVoidMethodBuilderSetResult; se = pred_members.AsyncVoidMethodBuilderSetException; sm = pred_members.AsyncVoidMethodBuilderSetStateMachine; } else if (return_type == Module.PredefinedTypes.Task.TypeSpec) { builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilder; bf = pred_members.AsyncTaskMethodBuilderCreate; bs = pred_members.AsyncTaskMethodBuilderStart; sr = pred_members.AsyncTaskMethodBuilderSetResult; se = pred_members.AsyncTaskMethodBuilderSetException; sm = pred_members.AsyncTaskMethodBuilderSetStateMachine; task = pred_members.AsyncTaskMethodBuilderTask.Get(); } else { builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilderGeneric; bf = pred_members.AsyncTaskMethodBuilderGenericCreate; bs = pred_members.AsyncTaskMethodBuilderGenericStart; sr = pred_members.AsyncTaskMethodBuilderGenericSetResult; se = pred_members.AsyncTaskMethodBuilderGenericSetException; sm = pred_members.AsyncTaskMethodBuilderGenericSetStateMachine; task = pred_members.AsyncTaskMethodBuilderGenericTask.Get(); has_task_return_type = true; } set_result = sr.Get(); set_exception = se.Get(); builder_factory = bf.Get(); builder_start = bs.Get(); var istate_machine = Module.PredefinedTypes.IAsyncStateMachine; var set_statemachine = sm.Get(); if (!builder_type.Define() || !istate_machine.Define() || set_result == null || builder_factory == null || set_exception == null || set_statemachine == null || builder_start == null || !Module.PredefinedTypes.INotifyCompletion.Define()) { Report.Error(1993, Location, "Cannot find compiler required types for asynchronous functions support. Are you targeting the wrong framework version?"); return(base.DoDefineMembers()); } var bt = builder_type.TypeSpec; // // Inflate generic Task types // if (has_task_return_type) { var task_return_type = return_type.TypeArguments; if (mutator != null) { task_return_type = mutator.Mutate(task_return_type); } bt = bt.MakeGenericType(Module, task_return_type); set_result = MemberCache.GetMember(bt, set_result); set_exception = MemberCache.GetMember(bt, set_exception); set_statemachine = MemberCache.GetMember(bt, set_statemachine); if (task != null) { task = MemberCache.GetMember(bt, task); } } builder = AddCompilerGeneratedField("$builder", new TypeExpression(bt, Location)); var set_state_machine = new Method(this, new TypeExpression(Compiler.BuiltinTypes.Void, Location), Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN | Modifiers.PUBLIC, new MemberName("SetStateMachine"), ParametersCompiled.CreateFullyResolved( new Parameter(new TypeExpression(istate_machine.TypeSpec, Location), "stateMachine", Parameter.Modifier.NONE, null, Location), istate_machine.TypeSpec), null); ToplevelBlock block = new ToplevelBlock(Compiler, set_state_machine.ParameterInfo, Location); block.IsCompilerGenerated = true; set_state_machine.Block = block; Members.Add(set_state_machine); if (!base.DoDefineMembers()) { return(false); } // // Fabricates SetStateMachine method // // public void SetStateMachine (IAsyncStateMachine stateMachine) // { // $builder.SetStateMachine (stateMachine); // } // var mg = MethodGroupExpr.CreatePredefined(set_statemachine, bt, Location); mg.InstanceExpression = new FieldExpr(builder, Location); var param_reference = block.GetParameterReference(0, Location); param_reference.Type = istate_machine.TypeSpec; param_reference.eclass = ExprClass.Variable; var args = new Arguments(1); args.Add(new Argument(param_reference)); set_state_machine.Block.AddStatement(new StatementExpression(new Invocation(mg, args))); if (has_task_return_type) { HoistedReturnValue = TemporaryVariableReference.Create(bt.TypeArguments [0], StateMachineMethod.Block, Location); } return(true); }
protected override Expression DoResolve(ResolveContext ec) { eclass = ExprClass.Value; // FIXME: Hack var caller_builder = (Constructor) ec.MemberContext; if (argument_list != null) { bool dynamic; // // Spec mandates that constructor initializer will not have `this' access // using (ec.Set (ResolveContext.Options.BaseInitializer)) { argument_list.Resolve (ec, out dynamic); } if (dynamic) { ec.Report.Error (1975, loc, "The constructor call cannot be dynamically dispatched within constructor initializer"); return null; } } type = ec.CurrentType; if (this is ConstructorBaseInitializer) { if (ec.CurrentType.BaseType == null) return this; type = ec.CurrentType.BaseType; if (ec.CurrentType.IsStruct) { ec.Report.Error (522, loc, "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ()); return this; } } else { // // It is legal to have "this" initializers that take no arguments // in structs, they are just no-ops. // // struct D { public D (int a) : this () {} // if (TypeManager.IsStruct (ec.CurrentType) && argument_list == null) return this; } base_constructor_group = MemberLookupFinal ( ec, null, type, ConstructorBuilder.ConstructorName, 0, MemberKind.Constructor, BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly, loc) as MethodGroupExpr; if (base_constructor_group == null) return this; base_constructor_group = base_constructor_group.OverloadResolve ( ec, ref argument_list, false, loc); if (base_constructor_group == null) return this; if (!ec.IsStatic) base_constructor_group.InstanceExpression = ec.GetThis (loc); var base_ctor = base_constructor_group.BestCandidate; // TODO MemberCache: Does it work for inflated types ? if (base_ctor == caller_builder.Spec){ ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself", caller_builder.GetSignatureForError ()); } return this; }
public static MethodGroupExpr MakeUnionSet (Expression mg1, Expression mg2, Location loc) { MemberInfo [] miset; MethodGroupExpr union; if (mg1 == null){ if (mg2 == null) return null; return (MethodGroupExpr) mg2; } else { if (mg2 == null) return (MethodGroupExpr) mg1; } MethodGroupExpr left_set = null, right_set = null; int length1 = 0, length2 = 0; left_set = (MethodGroupExpr) mg1; length1 = left_set.Methods.Length; right_set = (MethodGroupExpr) mg2; length2 = right_set.Methods.Length; ArrayList common = new ArrayList (); foreach (MethodBase l in left_set.Methods){ foreach (MethodBase r in right_set.Methods){ if (l != r) continue; common.Add (r); break; } } miset = new MemberInfo [length1 + length2 - common.Count]; left_set.Methods.CopyTo (miset, 0); int k = length1; foreach (MemberInfo mi in right_set.Methods){ if (!common.Contains (mi)) miset [k++] = mi; } union = new MethodGroupExpr (miset, loc); return union; }
public ConditionalLogicalOperator (MethodGroupExpr oper_method, Arguments arguments, ExpressionTreeExpression expr_tree, bool is_and, Location loc) : base (oper_method, arguments, expr_tree, loc) { this.is_and = is_and; }
public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, TypeSpec target_type) { if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type) return false; var invoke = Delegate.GetInvokeMethod (ec.Compiler, target_type); Arguments arguments = CreateDelegateMethodArguments (invoke.Parameters, invoke.Parameters.Types, mg.Location); return mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.Covariant | OverloadResolver.Restrictions.ProbingOnly) != null; }
static public Expression Create (ResolveContext ec, MethodGroupExpr mge, TypeSpec target_type, Location loc) { ImplicitDelegateCreation d = new ImplicitDelegateCreation (target_type, mge, loc); return d.DoResolve (ec); }
public override Expression DoResolve (ResolveContext ec) { // Don't resolve already resolved expression if (eclass != ExprClass.Invalid) return this; Expression expr_resolved = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup); if (expr_resolved == null) return null; // // Next, evaluate all the expressions in the argument list // bool dynamic_arg = false; if (arguments != null && !arguments_resolved) arguments.Resolve (ec, out dynamic_arg); Type expr_type = expr_resolved.Type; mg = expr_resolved as MethodGroupExpr; if (dynamic_arg || TypeManager.IsDynamicType (expr_type)) { Arguments args; DynamicMemberBinder dmb = expr_resolved as DynamicMemberBinder; if (dmb != null) { args = dmb.Arguments; if (arguments != null) args.AddRange (arguments); } else if (mg == null) { if (arguments == null) args = new Arguments (1); else args = arguments; args.Insert (0, new Argument (expr_resolved)); expr = null; } else { if (mg.IsBase) { ec.Report.Error (1971, loc, "The base call to method `{0}' cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access", mg.Name); return null; } args = arguments; if (mg.IsStatic != mg.IsInstance) { if (args == null) args = new Arguments (1); if (mg.IsStatic) { args.Insert (0, new Argument (new TypeOf (new TypeExpression (mg.DeclaringType, loc), loc).Resolve (ec), Argument.AType.DynamicStatic)); } else { MemberAccess ma = expr as MemberAccess; if (ma != null) args.Insert (0, new Argument (ma.Left.Resolve (ec))); else args.Insert (0, new Argument (new This (loc).Resolve (ec))); } } } return new DynamicInvocation (expr as ATypeNameExpression, args, loc).Resolve (ec); } if (mg == null) { if (expr_type != null && TypeManager.IsDelegateType (expr_type)){ return (new DelegateInvocation ( expr_resolved, arguments, loc)).Resolve (ec); } MemberExpr me = expr_resolved as MemberExpr; if (me == null) { expr_resolved.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup, loc); return null; } mg = ec.LookupExtensionMethod (me.Type, me.Name, loc); if (mg == null) { ec.Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate", expr_resolved.GetSignatureForError ()); return null; } ((ExtensionMethodGroupExpr)mg).ExtensionExpression = me.InstanceExpression; } mg = DoResolveOverload (ec); if (mg == null) return null; MethodInfo method = (MethodInfo)mg; if (method != null) { type = TypeManager.TypeToCoreType (method.ReturnType); // TODO: this is a copy of mg.ResolveMemberAccess method Expression iexpr = mg.InstanceExpression; if (method.IsStatic) { if (iexpr == null || iexpr is This || iexpr is EmptyExpression || mg.IdenticalTypeName) { mg.InstanceExpression = null; } else { MemberExpr.error176 (ec, loc, mg.GetSignatureForError ()); return null; } } else { if (iexpr == null || iexpr == EmptyExpression.Null) { SimpleName.Error_ObjectRefRequired (ec, loc, mg.GetSignatureForError ()); } } } if (type.IsPointer){ if (!ec.IsUnsafe){ UnsafeError (ec, loc); return null; } } // // Only base will allow this invocation to happen. // if (mg.IsBase && method.IsAbstract){ Error_CannotCallAbstractBase (ec, TypeManager.CSharpSignature (method)); return null; } if (arguments == null && method.DeclaringType == TypeManager.object_type && method.Name == Destructor.MetadataName) { if (mg.IsBase) ec.Report.Error (250, loc, "Do not directly call your base class Finalize method. It is called automatically from your destructor"); else ec.Report.Error (245, loc, "Destructors and object.Finalize cannot be called directly. Consider calling IDisposable.Dispose if available"); return null; } IsSpecialMethodInvocation (ec, method, loc); if (mg.InstanceExpression != null) mg.InstanceExpression.CheckMarshalByRefAccess (ec); eclass = ExprClass.Value; return this; }
protected override Expression DoResolve (ResolveContext ec) { constructor_method = Delegate.GetConstructor (type); var invoke_method = Delegate.GetInvokeMethod (type); if (!ec.HasSet (ResolveContext.Options.ConditionalAccessReceiver)) { if (method_group.HasConditionalAccess ()) { conditional_access_receiver = true; ec.Set (ResolveContext.Options.ConditionalAccessReceiver); } } Arguments arguments = CreateDelegateMethodArguments (ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); if (conditional_access_receiver) ec.With (ResolveContext.Options.ConditionalAccessReceiver, false); if (method_group == null) return null; var delegate_method = method_group.BestCandidate; if (delegate_method.DeclaringType.IsNullableType) { ec.Report.Error (1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type", delegate_method.GetSignatureForError ()); return null; } if (!AllowSpecialMethodsInvocation) Invocation.IsSpecialMethodInvocation (ec, delegate_method, loc); ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { method_group.InstanceExpression = emg.ExtensionExpression; TypeSpec e_type = emg.ExtensionExpression.Type; if (TypeSpec.IsValueType (e_type)) { ec.Report.Error (1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", delegate_method.GetSignatureForError (), e_type.GetSignatureForError ()); } } TypeSpec rt = method_group.BestCandidateReturnType; if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) rt = ec.BuiltinTypes.Object; if (!Delegate.IsTypeCovariant (ec, rt, invoke_method.ReturnType)) { Expression ret_expr = new TypeExpression (delegate_method.ReturnType, loc); Error_ConversionFailed (ec, delegate_method, ret_expr); } if (method_group.IsConditionallyExcluded) { ec.Report.SymbolRelatedToPreviousError (delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { ec.Report.Error (762, loc, "Cannot create delegate from partial method declaration `{0}'", delegate_method.GetSignatureForError ()); } else { ec.Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method)); } } var expr = method_group.InstanceExpression; if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType (expr.Type))) method_group.InstanceExpression = new BoxedCast (expr, ec.BuiltinTypes.Object); eclass = ExprClass.Value; return this; }
public override Expression DoResolve (ResolveContext ec) { // // The New DoResolve might be called twice when initializing field // expressions (see EmitFieldInitializers, the call to // GetInitializerExpression will perform a resolve on the expression, // and later the assign will trigger another resolution // // This leads to bugs (#37014) // if (type != null){ if (RequestedType is NewDelegate) return RequestedType; return this; } TypeExpr texpr = RequestedType.ResolveAsTypeTerminal (ec, false); if (texpr == null) return null; type = texpr.Type; if (type.IsPointer) { ec.Report.Error (1919, loc, "Unsafe type `{0}' cannot be used in an object creation expression", TypeManager.CSharpName (type)); return null; } if (Arguments == null) { Constant c = Constantify (type); if (c != null) return ReducedExpression.Create (c, this); } if (TypeManager.IsDelegateType (type)) { return (new NewDelegate (type, Arguments, loc)).Resolve (ec); } if (TypeManager.IsGenericParameter (type)) { GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type); if ((gc == null) || (!gc.HasConstructorConstraint && !gc.IsValueType)) { ec.Report.Error (304, loc, "Cannot create an instance of the variable type '{0}' because it doesn't have the new() constraint", TypeManager.CSharpName (type)); return null; } if ((Arguments != null) && (Arguments.Count != 0)) { ec.Report.Error (417, loc, "`{0}': cannot provide arguments when creating an instance of a variable type", TypeManager.CSharpName (type)); return null; } if (TypeManager.activator_create_instance == null) { Type activator_type = TypeManager.CoreLookupType (ec.Compiler, "System", "Activator", Kind.Class, true); if (activator_type != null) { TypeManager.activator_create_instance = TypeManager.GetPredefinedMethod ( activator_type, "CreateInstance", loc, Type.EmptyTypes); } } is_type_parameter = true; eclass = ExprClass.Value; return this; } if (type.IsAbstract && type.IsSealed) { ec.Report.SymbolRelatedToPreviousError (type); ec.Report.Error (712, loc, "Cannot create an instance of the static class `{0}'", TypeManager.CSharpName (type)); return null; } if (type.IsInterface || type.IsAbstract){ if (!TypeManager.IsGenericType (type)) { RequestedType = CheckComImport (ec); if (RequestedType != null) return RequestedType; } ec.Report.SymbolRelatedToPreviousError (type); ec.Report.Error (144, loc, "Cannot create an instance of the abstract class or interface `{0}'", TypeManager.CSharpName (type)); return null; } bool is_struct = TypeManager.IsStruct (type); eclass = ExprClass.Value; // // SRE returns a match for .ctor () on structs (the object constructor), // so we have to manually ignore it. // if (is_struct && Arguments == null) return this; // For member-lookup, treat 'new Foo (bar)' as call to 'foo.ctor (bar)', where 'foo' is of type 'Foo'. Expression ml = MemberLookupFinal (ec, type, type, ConstructorInfo.ConstructorName, MemberTypes.Constructor, AllBindingFlags | BindingFlags.DeclaredOnly, loc); if (Arguments != null) { bool dynamic; Arguments.Resolve (ec, out dynamic); if (dynamic) { Arguments.Insert (0, new Argument (new TypeOf (texpr, loc).Resolve (ec))); return new DynamicInvocation (new SimpleName (ConstructorInfo.ConstructorName, loc), Arguments, type, loc).Resolve (ec); } } if (ml == null) return null; method = ml as MethodGroupExpr; if (method == null) { ml.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup, loc); return null; } method = method.OverloadResolve (ec, ref Arguments, false, loc); if (method == null) return null; return this; }
public ImplicitDelegateCreation (TypeSpec delegateType, MethodGroupExpr mg, Location loc) { type = delegateType; this.method_group = mg; this.loc = loc; }
protected override bool DoDefineMembers() { TypeSpec bt; bool has_task_return_type = false; var istate_machine = Module.PredefinedTypes.IAsyncStateMachine; MethodSpec set_statemachine; if (return_type.IsCustomTaskType()) { // // TODO: Would be nice to cache all this on per-type basis // var btypes = Compiler.BuiltinTypes; bt = return_type.MemberDefinition.GetAsyncMethodBuilder(); TypeSpec bt_inflated; if (return_type.IsGeneric) { bt_inflated = bt.MakeGenericType(Module, bt.MemberDefinition.TypeParameters); } else { bt_inflated = bt; } var set_result_sign = MemberFilter.Method("SetResult", 0, ParametersCompiled.CreateFullyResolved(bt.MemberDefinition.TypeParameters), btypes.Void); set_result = new PredefinedMember <MethodSpec> (Module, bt, set_result_sign).Resolve(Location); var set_exception_sign = MemberFilter.Method("SetException", 0, ParametersCompiled.CreateFullyResolved(btypes.Exception), btypes.Void); set_exception = new PredefinedMember <MethodSpec> (Module, bt, set_exception_sign).Resolve(Location); var builder_factory_sign = MemberFilter.Method("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, bt_inflated); builder_factory = new PredefinedMember <MethodSpec> (Module, bt, builder_factory_sign).Resolve(Location); if (builder_factory?.IsStatic == false) { throw new NotImplementedException("report better error message"); } var builder_start_sign = MemberFilter.Method("Start", 1, new ParametersImported( new [] { new ParameterData(null, Parameter.Modifier.REF), }, new [] { new TypeParameterSpec(0, null, SpecialConstraint.None, Variance.None, null), }, false), btypes.Void); builder_start = new PredefinedMember <MethodSpec> (Module, bt, builder_start_sign).Resolve(Location); if (!istate_machine.Define()) { return(false); } var set_statemachine_sign = MemberFilter.Method("SetStateMachine", 0, ParametersCompiled.CreateFullyResolved(istate_machine.TypeSpec), btypes.Void); set_statemachine = new PredefinedMember <MethodSpec> (Module, bt, set_statemachine_sign).Resolve(Location);; var task_sign = MemberFilter.Property("Task", return_type.MemberDefinition as TypeSpec); task = new PredefinedMember <PropertySpec> (Module, bt, task_sign).Resolve(Location); if (set_result == null || set_exception == null || builder_factory == null || builder_start == null || set_statemachine == null || task == null || !Module.PredefinedTypes.INotifyCompletion.Define()) { return(false); } has_task_return_type = return_type.IsGeneric; } else { PredefinedType builder_type; PredefinedMember <MethodSpec> bf; PredefinedMember <MethodSpec> bs; PredefinedMember <MethodSpec> sr; PredefinedMember <MethodSpec> se; PredefinedMember <MethodSpec> sm; var pred_members = Module.PredefinedMembers; if (return_type.Kind == MemberKind.Void) { builder_type = Module.PredefinedTypes.AsyncVoidMethodBuilder; bf = pred_members.AsyncVoidMethodBuilderCreate; bs = pred_members.AsyncVoidMethodBuilderStart; sr = pred_members.AsyncVoidMethodBuilderSetResult; se = pred_members.AsyncVoidMethodBuilderSetException; sm = pred_members.AsyncVoidMethodBuilderSetStateMachine; } else if (return_type == Module.PredefinedTypes.Task.TypeSpec) { builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilder; bf = pred_members.AsyncTaskMethodBuilderCreate; bs = pred_members.AsyncTaskMethodBuilderStart; sr = pred_members.AsyncTaskMethodBuilderSetResult; se = pred_members.AsyncTaskMethodBuilderSetException; sm = pred_members.AsyncTaskMethodBuilderSetStateMachine; task = pred_members.AsyncTaskMethodBuilderTask.Get(); } else { builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilderGeneric; bf = pred_members.AsyncTaskMethodBuilderGenericCreate; bs = pred_members.AsyncTaskMethodBuilderGenericStart; sr = pred_members.AsyncTaskMethodBuilderGenericSetResult; se = pred_members.AsyncTaskMethodBuilderGenericSetException; sm = pred_members.AsyncTaskMethodBuilderGenericSetStateMachine; task = pred_members.AsyncTaskMethodBuilderGenericTask.Get(); has_task_return_type = true; } set_result = sr.Get(); set_exception = se.Get(); builder_factory = bf.Get(); builder_start = bs.Get(); set_statemachine = sm.Get(); if (!builder_type.Define() || !istate_machine.Define() || set_result == null || builder_factory == null || set_exception == null || set_statemachine == null || builder_start == null || !Module.PredefinedTypes.INotifyCompletion.Define()) { Report.Error(1993, Location, "Cannot find compiler required types for asynchronous functions support. Are you targeting the wrong framework version?"); return(base.DoDefineMembers()); } bt = builder_type.TypeSpec; } // // Inflate generic Task types // if (has_task_return_type) { var task_return_type = return_type.TypeArguments; if (mutator != null) { task_return_type = mutator.Mutate(task_return_type); } bt = bt.MakeGenericType(Module, task_return_type); set_result = MemberCache.GetMember(bt, set_result); set_exception = MemberCache.GetMember(bt, set_exception); set_statemachine = MemberCache.GetMember(bt, set_statemachine); if (task != null) { task = MemberCache.GetMember(bt, task); } } builder = AddCompilerGeneratedField("$builder", new TypeExpression(bt, Location)); Field rfield; if (has_task_return_type && HasAwaitInsideFinally) { // // Special case async block with return value from finally clause. In such case // we rewrite all return expresison stores to stfld to $return. Instead of treating // returns outside of finally and inside of finally differently. // rfield = AddCompilerGeneratedField("$return", new TypeExpression(bt.TypeArguments [0], Location)); } else { rfield = null; } var set_state_machine = new Method(this, new TypeExpression(Compiler.BuiltinTypes.Void, Location), Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN | Modifiers.PUBLIC, new MemberName("SetStateMachine"), ParametersCompiled.CreateFullyResolved( new Parameter(new TypeExpression(istate_machine.TypeSpec, Location), "stateMachine", Parameter.Modifier.NONE, null, Location), istate_machine.TypeSpec), null); ToplevelBlock block = new ToplevelBlock(Compiler, set_state_machine.ParameterInfo, Location); block.IsCompilerGenerated = true; set_state_machine.Block = block; Members.Add(set_state_machine); if (!base.DoDefineMembers()) { return(false); } // // Fabricates SetStateMachine method // // public void SetStateMachine (IAsyncStateMachine stateMachine) // { // $builder.SetStateMachine (stateMachine); // } // var mg = MethodGroupExpr.CreatePredefined(set_statemachine, bt, Location); mg.InstanceExpression = new FieldExpr(builder, Location); var param_reference = block.GetParameterReference(0, Location); param_reference.Type = istate_machine.TypeSpec; param_reference.eclass = ExprClass.Variable; var args = new Arguments(1); args.Add(new Argument(param_reference)); set_state_machine.Block.AddStatement(new StatementExpression(new Invocation(mg, args))); if (has_task_return_type) { if (rfield != null) { HoistedReturnValue = new FieldExpr(rfield, Location) { InstanceExpression = new CompilerGeneratedThis(CurrentType, Location.Null) }; } else { HoistedReturnValue = TemporaryVariableReference.Create(bt.TypeArguments [0], StateMachineMethod.Block, Location); } } return(true); }
ImplicitDelegateCreation(TypeSpec t, MethodGroupExpr mg, Location l) { type = t; this.method_group = mg; loc = l; }
void EmitOnCompleted(EmitContext ec, Expression awaiter, bool unsafeVersion) { var pm = Module.PredefinedMembers; PredefinedMember <MethodSpec> predefined; bool has_task_return_type = false; if (return_type.Kind == MemberKind.Void) { predefined = unsafeVersion ? pm.AsyncVoidMethodBuilderOnCompletedUnsafe : pm.AsyncVoidMethodBuilderOnCompleted; } else if (return_type == Module.PredefinedTypes.Task.TypeSpec) { predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderOnCompletedUnsafe : pm.AsyncTaskMethodBuilderOnCompleted; } else if (return_type.IsGenericTask) { predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderGenericOnCompletedUnsafe : pm.AsyncTaskMethodBuilderGenericOnCompleted; has_task_return_type = true; } else { var parameters = new ParametersImported( new [] { new ParameterData(null, Parameter.Modifier.REF), new ParameterData(null, Parameter.Modifier.REF) }, new [] { new TypeParameterSpec(0, null, SpecialConstraint.None, Variance.None, null), new TypeParameterSpec(1, null, SpecialConstraint.None, Variance.None, null) }, false); var on_completed_sign = unsafeVersion ? MemberFilter.Method("AwaitUnsafeOnCompleted", 2, parameters, Compiler.BuiltinTypes.Void) : MemberFilter.Method("AwaitOnCompleted", 2, parameters, Compiler.BuiltinTypes.Void); predefined = new PredefinedMember <MethodSpec> (Module, return_type.MemberDefinition.GetAsyncMethodBuilder(), on_completed_sign); has_task_return_type = return_type.IsGeneric; } var on_completed = predefined.Resolve(Location); if (on_completed == null) { return; } if (has_task_return_type) { on_completed = MemberCache.GetMember <MethodSpec> (set_result.DeclaringType, on_completed); } on_completed = on_completed.MakeGenericMethod(this, awaiter.Type, ec.CurrentType); var mg = MethodGroupExpr.CreatePredefined(on_completed, on_completed.DeclaringType, Location); mg.InstanceExpression = new FieldExpr(builder, Location) { InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, Location) }; var args = new Arguments(2); args.Add(new Argument(awaiter, Argument.AType.Ref)); args.Add(new Argument(new CompilerGeneratedThis(CurrentType, Location), Argument.AType.Ref)); using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) { mg.EmitCall(ec, args, true); } }
public ImplicitDelegateCreation(TypeSpec delegateType, MethodGroupExpr mg, Location loc) { type = delegateType; this.method_group = mg; this.loc = loc; }
static void AddConversionOperators(List<MethodSpec> list, Expression source, TypeSpec target_type, bool look_for_explicit, MethodGroupExpr mg) { if (mg == null) return; TypeSpec source_type = source.Type; EmptyExpression expr = EmptyExpression.Grab (); // // LAMESPEC: Undocumented IntPtr/UIntPtr conversions // IntPtr -> uint uses int // UIntPtr -> long uses ulong // if (source_type == TypeManager.intptr_type) { if (target_type == TypeManager.uint32_type) target_type = TypeManager.int32_type; } else if (source_type == TypeManager.uintptr_type) { if (target_type == TypeManager.int64_type) target_type = TypeManager.uint64_type; } foreach (MethodSpec m in mg.Methods) { AParametersCollection pd = m.Parameters; TypeSpec return_type = m.ReturnType; TypeSpec arg_type = pd.Types [0]; if (source_type != arg_type) { if (!ImplicitStandardConversionExists (source, arg_type)) { if (!look_for_explicit) continue; expr.SetType (arg_type); if (!ImplicitStandardConversionExists (expr, source_type)) continue; } } if (target_type != return_type) { expr.SetType (return_type); if (!ImplicitStandardConversionExists (expr, target_type)) { if (!look_for_explicit) continue; expr.SetType (target_type); if (!ImplicitStandardConversionExists (expr, return_type)) continue; } } // See LAMESPEC: Exclude IntPtr -> int conversion if (source_type == TypeManager.uintptr_type && return_type == TypeManager.uint32_type) continue; list.Add (m); } EmptyExpression.Release (expr); }
public ArrayInitializer CreateDynamicBinderArguments(ResolveContext rc) { Location loc = Location.Null; var all = new ArrayInitializer(args.Count, loc); MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace(rc, loc); foreach (Argument a in args) { Arguments dargs = new Arguments(2); // CSharpArgumentInfoFlags.None = 0 const string info_flags_enum = "CSharpArgumentInfoFlags"; Expression info_flags = new IntLiteral(rc.BuiltinTypes, 0, loc); if (a.Expr is Constant) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "Constant", loc)); } else if (a.ArgType == Argument.AType.Ref) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsRef", loc)); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } else if (a.ArgType == Argument.AType.Out) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsOut", loc)); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } else if (a.ArgType == Argument.AType.DynamicTypeName) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsStaticType", loc)); } TypeSpec arg_type; if (rc.FileType == SourceFileType.PlayScript && a.Expr is ArrayInitializer || a.Expr is AsObjectInitializer) { if (a.Expr is ArrayInitializer) { arg_type = rc.Module.PredefinedTypes.AsArray.Resolve(); } else { arg_type = rc.Module.PredefinedTypes.AsExpandoObject.Resolve(); } } else { arg_type = a.Expr.Type; } if (arg_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic && arg_type != InternalType.NullLiteral) { MethodGroupExpr mg = a.Expr as MethodGroupExpr; bool wasConverted = false; // In PlayScript, we try to implicity convert to dynamic, which handles conversions of method groups to delegates, and // anon methods to delegates. if (rc.FileType == SourceFileType.PlayScript && (mg != null || arg_type == InternalType.AnonymousMethod)) { var expr = Convert.ImplicitConversion(rc, a.Expr, rc.BuiltinTypes.Dynamic, loc); if (expr != null) { a.Expr = expr; arg_type = rc.BuiltinTypes.Dynamic; wasConverted = true; } } // Failed.. check the C# error if (!wasConverted) { if (mg != null) { rc.Report.Error(1976, a.Expr.Location, "The method group `{0}' cannot be used as an argument of dynamic operation. Consider using parentheses to invoke the method", mg.Name); } else if (arg_type == InternalType.AnonymousMethod) { rc.Report.Error(1977, a.Expr.Location, "An anonymous method or lambda expression cannot be used as an argument of dynamic operation. Consider using a cast"); } else if (arg_type.Kind == MemberKind.Void || arg_type == InternalType.Arglist || arg_type.IsPointer) { rc.Report.Error(1978, a.Expr.Location, "An expression of type `{0}' cannot be used as an argument of dynamic operation", arg_type.GetSignatureForError()); } } info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } string named_value; NamedArgument na = a as NamedArgument; if (na != null) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "NamedArgument", loc)); named_value = na.Name; } else { named_value = null; } dargs.Add(new Argument(info_flags)); dargs.Add(new Argument(new StringLiteral(rc.BuiltinTypes, named_value, loc))); all.Add(new Invocation(new MemberAccess(new MemberAccess(binder, "CSharpArgumentInfo", loc), "Create", loc), dargs)); } return(all); }
public static MethodGroupExpr MakeUnionSet(MethodGroupExpr mg1, MethodGroupExpr mg2, Location loc) { if (mg1 == null) { if (mg2 == null) return null; return mg2; } if (mg2 == null) return mg1; var all = new List<MemberSpec> (mg1.Methods); foreach (MethodSpec m in mg2.Methods){ if (!TypeManager.ArrayContainsMethod (all, m, false)) all.Add (m); } return new MethodGroupExpr (all, null, loc); }
public ArrayInitializer CreateDynamicBinderArguments(ResolveContext rc) { Location loc = Location.Null; var all = new ArrayInitializer(args.Count, loc); MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace(loc); foreach (Argument a in args) { Arguments dargs = new Arguments(2); // CSharpArgumentInfoFlags.None = 0 const string info_flags_enum = "CSharpArgumentInfoFlags"; Expression info_flags = new IntLiteral(rc.BuiltinTypes, 0, loc); if (a.Expr is Constant) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "Constant", loc)); } else if (a.ArgType == Argument.AType.Ref) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsRef", loc)); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } else if (a.ArgType == Argument.AType.Out) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsOut", loc)); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } else if (a.ArgType == Argument.AType.DynamicTypeName) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsStaticType", loc)); } var arg_type = a.Expr.Type; if (arg_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic && arg_type != InternalType.NullLiteral) { MethodGroupExpr mg = a.Expr as MethodGroupExpr; if (mg != null) { rc.Report.Error(1976, a.Expr.Location, "The method group `{0}' cannot be used as an argument of dynamic operation. Consider using parentheses to invoke the method", mg.Name); } else if (arg_type == InternalType.AnonymousMethod) { rc.Report.Error(1977, a.Expr.Location, "An anonymous method or lambda expression cannot be used as an argument of dynamic operation. Consider using a cast"); } else if (arg_type.Kind == MemberKind.Void || arg_type == InternalType.Arglist || arg_type.IsPointer) { rc.Report.Error(1978, a.Expr.Location, "An expression of type `{0}' cannot be used as an argument of dynamic operation", arg_type.GetSignatureForError()); } info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } string named_value; NamedArgument na = a as NamedArgument; if (na != null) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "NamedArgument", loc)); named_value = na.Name; } else { named_value = null; } dargs.Add(new Argument(info_flags)); dargs.Add(new Argument(new StringLiteral(rc.BuiltinTypes, named_value, loc))); all.Add(new Invocation(new MemberAccess(new MemberAccess(binder, "CSharpArgumentInfo", loc), "Create", loc), dargs)); } return(all); }
bool TryType(ResolveContext ec, TypeSpec t) { var mg = Expression.MemberLookup (ec.Compiler, ec.CurrentType, null, t, "GetEnumerator", 0, MemberKind.Method, BindingRestriction.NoOverrides | BindingRestriction.InstanceOnly, loc) as MethodGroupExpr; if (mg == null) return false; MethodSpec result = null; MethodSpec tmp_move_next = null; PropertyExpr tmp_get_cur = null; TypeSpec tmp_enumerator_type = enumerator_type; foreach (MethodSpec mi in mg.Methods) { if (!mi.Parameters.IsEmpty) continue; // Check whether GetEnumerator is public if ((mi.Modifiers & Modifiers.AccessibilityMask) != Modifiers.PUBLIC) continue; enumerator_found = true; if (!GetEnumeratorFilter (ec, mi)) continue; if (result != null) { if (TypeManager.IsGenericType (result.ReturnType)) { if (!TypeManager.IsGenericType (mi.ReturnType)) continue; ec.Report.SymbolRelatedToPreviousError (t); ec.Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " + "because it contains multiple implementation of `{1}'. Try casting to a specific implementation", TypeManager.CSharpName (t), TypeManager.generic_ienumerable_type.GetSignatureForError ()); return false; } // Always prefer generics enumerators if (!TypeManager.IsGenericType (mi.ReturnType)) { if (mi.DeclaringType.ImplementsInterface (result.DeclaringType) || result.DeclaringType.ImplementsInterface (mi.DeclaringType)) continue; ec.Report.SymbolRelatedToPreviousError (result); ec.Report.SymbolRelatedToPreviousError (mi); ec.Report.Warning (278, 2, loc, "`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'", TypeManager.CSharpName (t), "enumerable", result.GetSignatureForError (), mi.GetSignatureForError ()); return false; } } result = mi; tmp_move_next = move_next; tmp_get_cur = get_current; tmp_enumerator_type = enumerator_type; if (mi.DeclaringType == t) break; } if (result != null) { move_next = tmp_move_next; get_current = tmp_get_cur; enumerator_type = tmp_enumerator_type; get_enumerator = new MethodGroupExpr (result, enumerator_type, loc); if (t != expr.Type) { expr = Convert.ExplicitConversion ( ec, expr, t, loc); if (expr == null) throw new InternalErrorException (); } get_enumerator.InstanceExpression = expr; get_enumerator.IsBase = t != expr.Type; return true; } return false; }