protected virtual void EmitHoistedParameters (EmitContext ec, List<HoistedParameter> hoisted)
{
foreach (HoistedParameter hp in hoisted) {
+ if (hp == null)
+ continue;
+
//
// Parameters could be proxied via local fields for value type storey
//
}
}
+ public bool IsAssigned { get; set; }
+
public ParameterReference Parameter {
get {
return parameter;
return delegate_type;
ec.Report.Error (835, loc, "Cannot convert `{0}' to an expression tree of non-delegate type `{1}'",
- GetSignatureForError (), TypeManager.CSharpName (delegate_type));
+ GetSignatureForError (), delegate_type.GetSignatureForError ());
return null;
}
ec.Report.Error (1660, loc, "Cannot convert `{0}' to non-delegate type `{1}'",
- GetSignatureForError (), TypeManager.CSharpName (delegate_type));
+ GetSignatureForError (), delegate_type.GetSignatureForError ());
return null;
}
if (!ec.IsInProbingMode)
ec.Report.Error (1661, loc,
"Cannot convert `{0}' to delegate type `{1}' since there is a parameter mismatch",
- GetSignatureForError (), TypeManager.CSharpName (delegate_type));
+ GetSignatureForError (), delegate_type.GetSignatureForError ());
return false;
}
return false;
ec.Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments",
- TypeManager.CSharpName (delegate_type), Parameters.Count.ToString ());
+ delegate_type.GetSignatureForError (), Parameters.Count.ToString ());
return false;
}
ec.Report.Error (1678, loc, "Parameter `{0}' is declared as type `{1}' but should be `{2}'",
(i+1).ToString (),
- TypeManager.CSharpName (Parameters.Types [i]),
- TypeManager.CSharpName (invoke_pd.Types [i]));
+ Parameters.Types [i].GetSignatureForError (),
+ invoke_pd.Types [i].GetSignatureForError ());
error = true;
}
}
}
} else {
am = body.Compatible (ec);
+
+ if (body.DirectMethodGroupConversion != null) {
+ var errors_printer = new SessionReportPrinter ();
+ var old = ec.Report.SetPrinter (errors_printer);
+ var expr = new ImplicitDelegateCreation (delegate_type, body.DirectMethodGroupConversion, loc) {
+ AllowSpecialMethodsInvocation = true
+ }.Resolve (ec);
+ ec.Report.SetPrinter (old);
+ if (expr != null && errors_printer.ErrorsCount == 0)
+ am = expr;
+ }
}
} catch (CompletionResult) {
throw;
return null;
}
- b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, loc);
+ b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, delegate_type, loc);
}
- return CompatibleMethodFactory (return_type ?? InternalType.Arglist, delegate_type, p, b);
+ return CompatibleMethodFactory (return_type ?? InternalType.ErrorType, delegate_type, p, b);
}
protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ParametersBlock b)
get { return "anonymous method"; }
}
+ //
+ // Method-group instance for lambdas which can be replaced with
+ // simple method group call
+ //
+ public MethodGroupExpr DirectMethodGroupConversion {
+ get; set;
+ }
+
public override bool IsIterator {
get {
return false;
}
public override AnonymousMethodStorey Storey {
- get { return storey; }
+ get {
+ return storey;
+ }
}
#endregion
parent = storey = FindBestMethodStorey ();
if (storey == null) {
- var sm = src_block.ParametersBlock.TopBlock.StateMachine;
+ var top_block = src_block.ParametersBlock.TopBlock;
+ var sm = top_block.StateMachine;
- //
- // Remove hoisted this demand when simple instance method is enough (no hoisted variables only this)
- //
- if (src_block.HasCapturedThis && src_block.ParametersBlock.StateMachine == null) {
- src_block.ParametersBlock.TopBlock.RemoveThisReferenceFromChildrenBlock (src_block);
+ if (src_block.HasCapturedThis) {
+ //
+ // Remove hoisted 'this' request when simple instance method is
+ // enough (no hoisted variables only 'this')
+ //
+ if (src_block.ParametersBlock.StateMachine == null)
+ top_block.RemoveThisReferenceFromChildrenBlock (src_block);
//
// Special case where parent class is used to emit instance method
- // because currect storey is of value type (async host) and we don't
- // want to create another childer storey to host this reference only
+ // because currect storey is of value type (async host). We cannot
+ // use ldftn on non-boxed instances either to share mutated state
//
- if (sm != null && sm.Kind == MemberKind.Struct)
+ if (sm != null && sm.Kind == MemberKind.Struct) {
parent = sm.Parent.PartialContainer;
+ }
}
//
//
method = DoCreateMethodHost (ec);
method.Define ();
+ method.PrepareEmit ();
}
bool is_static = (method.ModFlags & Modifiers.STATIC) != 0;
public override string GetSignatureForError ()
{
- return TypeManager.CSharpName (type);
+ return type.GetSignatureForError ();
}
}
equals.Block = equals_block;
equals.Define ();
+ equals.PrepareEmit ();
Members.Add (equals);
//
hashcode_block.AddStatement (new Return (hash_variable, loc));
hashcode.Block = hashcode_top;
hashcode.Define ();
+ hashcode.PrepareEmit ();
Members.Add (hashcode);
//
tostring_block.AddStatement (new Return (string_concat, loc));
tostring.Block = tostring_block;
tostring.Define ();
+ tostring.PrepareEmit ();
Members.Add (tostring);
return true;