Пример #1
0
		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;
		}
Пример #2
0
        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));
        }
Пример #3
0
        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);
        }
Пример #4
0
Файл: doc.cs Проект: mdae/MonoRT
        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 []);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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));
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        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));
        }
Пример #9
0
        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));
        }
Пример #10
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);
		}
Пример #11
0
        // <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));
        }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #14
0
        // <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));
        }
Пример #15
0
        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)));
        }
Пример #16
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]);
        }
Пример #17
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);
			}
Пример #18
0
		/// <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;
		}
Пример #19
0
		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;
		}
Пример #20
0
        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);
        }
Пример #21
0
		// <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);
		}
Пример #22
0
		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;
		}
Пример #23
0
		ImplicitDelegateCreation (TypeSpec t, MethodGroupExpr mg, Location l)
		{
			type = t;
			this.method_group = mg;
			loc = l;
		}
Пример #24
0
		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);
		}
Пример #25
0
		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);
		}
Пример #26
0
			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;
			}		
Пример #27
0
		//
		// 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);
		}
Пример #28
0
		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;
		}
Пример #29
0
        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);
        }
Пример #30
0
		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);
		}
Пример #31
0
        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);
        }
Пример #32
0
		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);
		}
Пример #33
0
        /// <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);
        }
Пример #34
0
		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);
		}
Пример #35
0
		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;
		}
Пример #36
0
        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);
        }
Пример #37
0
        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);
        }
Пример #38
0
 public GetResultInvocation(MethodGroupExpr mge, Arguments arguments)
     : base(null, arguments)
 {
     mg   = mge;
     type = mg.BestCandidateReturnType;
 }
Пример #39
0
        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;
        }
Пример #40
0
        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);
        }
Пример #41
0
        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;
        }
Пример #42
0
		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;
		}
Пример #43
0
		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;
		}
Пример #44
0
		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;
		}
Пример #45
0
		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);
		}
Пример #46
0
		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;
		}
Пример #47
0
		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;
		}
Пример #48
0
		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;
		}
Пример #49
0
		public ImplicitDelegateCreation (TypeSpec delegateType, MethodGroupExpr mg, Location loc)
		{
			type = delegateType;
			this.method_group = mg;
			this.loc = loc;
		}
Пример #50
0
        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);
        }
Пример #51
0
 ImplicitDelegateCreation(TypeSpec t, MethodGroupExpr mg, Location l)
 {
     type = t;
     this.method_group = mg;
     loc = l;
 }
Пример #52
0
        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);
            }
        }
Пример #53
0
 public ImplicitDelegateCreation(TypeSpec delegateType, MethodGroupExpr mg, Location loc)
 {
     type = delegateType;
     this.method_group = mg;
     this.loc          = loc;
 }
Пример #54
0
        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);
        }
Пример #55
0
        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);
        }
Пример #56
0
        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);
        }
Пример #57
0
        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);
        }
Пример #58
0
            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;
            }