Example #1
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;
		}
		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;
		}
Example #3
0
 public override string GetSignatureForError()
 {
     return(mg.GetSignatureForError());
 }