protected void ErrAppendMethod(MethodSymbol meth, SubstContext pctx, bool fArgs)
{
if (meth.IsExpImpl() && meth.swtSlot)
{
ErrAppendParentSym(meth, pctx);
// Get the type args from the explicit impl type and substitute using pctx (if there is one).
SubstContext ctx = new SubstContext(GetTypeManager().SubstType(meth.swtSlot.GetType(), pctx).AsAggregateType());
ErrAppendSym(meth.swtSlot.Sym, ctx, fArgs);
// args already added
return;
}
if (meth.isPropertyAccessor())
{
PropertySymbol prop = meth.getProperty();
// this includes the parent class
ErrAppendSym(prop, pctx);
// add accessor name
if (prop.methGet == meth)
{
ErrAppendString(".get");
}
else
{
Debug.Assert(meth == prop.methSet);
ErrAppendString(".set");
}
// args already added
return;
}
if (meth.isEventAccessor())
{
EventSymbol @event = meth.getEvent();
// this includes the parent class
ErrAppendSym(@event, pctx);
// add accessor name
if (@event.methAdd == meth)
{
ErrAppendString(".add");
}
else
{
Debug.Assert(meth == @event.methRemove);
ErrAppendString(".remove");
}
// args already added
return;
}
TypeArray replacementTypeArray = null;
ErrAppendMethodParentSym(meth, pctx, out replacementTypeArray);
if (meth.IsConstructor())
{
// Use the name of the parent class instead of the name "<ctor>".
ErrAppendName(meth.getClass().name);
}
else if (meth.IsDestructor())
{
// Use the name of the parent class instead of the name "Finalize".
ErrAppendChar('~');
ErrAppendName(meth.getClass().name);
}
else if (meth.isConversionOperator())
{
// implicit/explicit
ErrAppendString(meth.isImplicit() ? "implicit" : "explicit");
ErrAppendString(" operator ");
// destination type name
ErrAppendType(meth.RetType, pctx);
}
else if (meth.isOperator)
{
// handle user defined operators
// map from CLS predefined names to "operator <X>"
ErrAppendString("operator ");
//
// This is kinda slow, but the alternative is to add bits to methsym.
//
string operatorName;
OperatorKind op = Operators.OperatorOfMethodName(GetNameManager(), meth.name);
if (Operators.HasDisplayName(op))
{
operatorName = Operators.GetDisplayName(op);
}
else
{
//
// either equals or compare
//
if (meth.name == GetNameManager().GetPredefName(PredefinedName.PN_OPEQUALS))
{
operatorName = "equals";
}
else
{
Debug.Assert(meth.name == GetNameManager().GetPredefName(PredefinedName.PN_OPCOMPARE));
operatorName = "compare";
}
}
ErrAppendString(operatorName);
}
else if (meth.IsExpImpl())
{
if (meth.errExpImpl != null)
ErrAppendType(meth.errExpImpl, pctx, fArgs);
}
else
{
// regular method
ErrAppendName(meth.name);
}
if (null == replacementTypeArray)
{
ErrAppendTypeParameters(meth.typeVars, pctx, false);
}
if (fArgs)
{
// append argument types
ErrAppendChar('(');
if (!meth.computeCurrentBogusState())
{
ErrAppendParamList(GetTypeManager().SubstTypeArray(meth.Params, pctx), meth.isVarargs, meth.isParamArray);
}
ErrAppendChar(')');
}
}