public void ErrAppendType(CType pType, SubstContext pctx, bool fArgs)
{
if (pctx != null)
{
if (!pctx.FNop())
{
pType = GetTypeManager().SubstType(pType, pctx);
}
// We shouldn't use the SubstContext again so set it to NULL.
pctx = null;
}
switch (pType.GetTypeKind())
{
case TypeKind.TK_AggregateType:
{
AggregateType pAggType = pType.AsAggregateType();
// Check for a predefined class with a special "nice" name for
// error reported.
string text = PredefinedTypes.GetNiceName(pAggType.getAggregate());
if (text != null)
{
// Found a nice name.
ErrAppendString(text);
}
else if (pAggType.getAggregate().IsAnonymousType())
{
ErrAppendPrintf("AnonymousType#{0}", GetTypeID(pAggType));
break;
}
else
{
if (pAggType.outerType != null)
{
ErrAppendType(pAggType.outerType, pctx);
ErrAppendChar('.');
}
else
{
// In a namespace.
ErrAppendParentSym(pAggType.getAggregate(), pctx);
}
ErrAppendName(pAggType.getAggregate().name);
}
ErrAppendTypeParameters(pAggType.GetTypeArgsThis(), pctx, true);
break;
}
case TypeKind.TK_TypeParameterType:
if (null == pType.GetName())
{
// It's a standard type variable.
if (pType.AsTypeParameterType().IsMethodTypeParameter())
{
ErrAppendChar('!');
}
ErrAppendChar('!');
ErrAppendPrintf("{0}", pType.AsTypeParameterType().GetIndexInTotalParameters());
}
else
{
ErrAppendName(pType.GetName());
}
break;
case TypeKind.TK_ErrorType:
if (pType.AsErrorType().HasParent())
{
Debug.Assert(pType.AsErrorType().nameText != null && pType.AsErrorType().typeArgs != null);
ErrAppendParentType(pType, pctx);
ErrAppendName(pType.AsErrorType().nameText);
ErrAppendTypeParameters(pType.AsErrorType().typeArgs, pctx, true);
}
else
{
// Load the string "<error>".
Debug.Assert(null == pType.AsErrorType().typeArgs);
ErrAppendId(MessageID.ERRORSYM);
}
break;
case TypeKind.TK_NullType:
// Load the string "<null>".
ErrAppendId(MessageID.NULL);
break;
case TypeKind.TK_OpenTypePlaceholderType:
// Leave blank.
break;
case TypeKind.TK_BoundLambdaType:
ErrAppendId(MessageID.AnonMethod);
break;
case TypeKind.TK_UnboundLambdaType:
ErrAppendId(MessageID.Lambda);
break;
case TypeKind.TK_MethodGroupType:
ErrAppendId(MessageID.MethodGroup);
break;
case TypeKind.TK_ArgumentListType:
ErrAppendString(TokenFacts.GetText(TokenKind.ArgList));
break;
case TypeKind.TK_ArrayType:
{
CType elementType = pType.AsArrayType().GetBaseElementType();
int rank;
if (null == elementType)
{
Debug.Assert(false, "No element type");
break;
}
ErrAppendType(elementType, pctx);
for (elementType = pType;
elementType != null && elementType.IsArrayType();
elementType = elementType.AsArrayType().GetElementType())
{
rank = elementType.AsArrayType().rank;
// Add [] with (rank-1) commas inside
ErrAppendChar('[');
#if ! CSEE
// known rank.
if (rank > 1)
{
ErrAppendChar('*');
}
#endif
for (int i = rank; i > 1; --i)
{
ErrAppendChar(',');
#if ! CSEE
ErrAppendChar('*');
#endif
}
ErrAppendChar(']');
}
break;
}
case TypeKind.TK_VoidType:
ErrAppendName(GetNameManager().Lookup(TokenFacts.GetText(TokenKind.Void)));
break;
case TypeKind.TK_ParameterModifierType:
// add ref or out
ErrAppendString(pType.AsParameterModifierType().isOut ? "out " : "ref ");
// add base type name
ErrAppendType(pType.AsParameterModifierType().GetParameterType(), pctx);
break;
case TypeKind.TK_PointerType:
// Generate the base type.
ErrAppendType(pType.AsPointerType().GetReferentType(), pctx);
{
// add the trailing *
ErrAppendChar('*');
}
break;
case TypeKind.TK_NullableType:
ErrAppendType(pType.AsNullableType().GetUnderlyingType(), pctx);
ErrAppendChar('?');
break;
case TypeKind.TK_NaturalIntegerType:
default:
// Shouldn't happen.
Debug.Assert(false, "Bad type kind");
break;
}
}