public CError RealizeError(CParameterizedError parameterizedError)
{
// Create an arg array manually using the type information in the ErrArgs.
string[] prgpsz = new string[parameterizedError.GetParameterCount()];
int[] prgiarg = new int[parameterizedError.GetParameterCount()];
int ppsz = 0;
int piarg = 0;
int cargUnique = 0;
_userStringBuilder.ResetUndisplayableStringFlag();
for (int iarg = 0; iarg < parameterizedError.GetParameterCount(); iarg++)
{
ErrArg arg = parameterizedError.GetParameter(iarg);
// If the NoStr bit is set we don't add it to prgpsz.
if (0 != (arg.eaf & ErrArgFlags.NoStr))
continue;
bool fUserStrings = false;
if (!_userStringBuilder.ErrArgToString(out prgpsz[ppsz], arg, out fUserStrings))
{
if (arg.eak == ErrArgKind.Int)
{
prgpsz[ppsz] = arg.n.ToString(CultureInfo.InvariantCulture);
}
}
ppsz++;
int iargRec;
if (!fUserStrings || 0 == (arg.eaf & ErrArgFlags.Unique))
{
iargRec = -1;
}
else
{
iargRec = iarg;
cargUnique++;
}
prgiarg[piarg] = iargRec;
piarg++;
}
// don't ever display undisplayable strings to the user
// if this happens we should track down the caller to not display the error
// this should only ever occur in a cascading error situation due to
// error tolerance
if (_userStringBuilder.HadUndisplayableString())
{
return null;
}
int cpsz = ppsz;
if (cargUnique > 1)
{
// Copy the strings over to another buffer.
string[] prgpszNew = new string[cpsz];
Array.Copy(prgpsz, 0, prgpszNew, 0, cpsz);
for (int i = 0; i < cpsz; i++)
{
if (prgiarg[i] < 0 || prgpszNew[i] != prgpsz[i])
continue;
ErrArg arg = parameterizedError.GetParameter(prgiarg[i]);
Debug.Assert(0 != (arg.eaf & ErrArgFlags.Unique) && 0 == (arg.eaf & ErrArgFlags.NoStr));
Symbol sym = null;
CType pType = null;
switch (arg.eak)
{
case ErrArgKind.Sym:
sym = arg.sym;
break;
case ErrArgKind.Type:
pType = arg.pType;
break;
case ErrArgKind.SymWithType:
sym = arg.swtMemo.sym;
break;
case ErrArgKind.MethWithInst:
sym = arg.mpwiMemo.sym;
break;
default:
Debug.Assert(false, "Shouldn't be here!");
continue;
}
bool fMunge = false;
for (int j = i + 1; j < cpsz; j++)
{
if (prgiarg[j] < 0)
continue;
Debug.Assert(0 != (parameterizedError.GetParameter(prgiarg[j]).eaf & ErrArgFlags.Unique));
if (prgpsz[i] != prgpsz[j])
continue;
// The strings are identical. If they are the same symbol, leave them alone.
// Otherwise, munge both strings. If j has already been munged, just make
// sure we munge i.
if (prgpszNew[j] != prgpsz[j])
{
fMunge = true;
continue;
}
ErrArg arg2 = parameterizedError.GetParameter(prgiarg[j]);
Debug.Assert(0 != (arg2.eaf & ErrArgFlags.Unique) && 0 == (arg2.eaf & ErrArgFlags.NoStr));
Symbol sym2 = null;
CType pType2 = null;
switch (arg2.eak)
{
case ErrArgKind.Sym:
sym2 = arg2.sym;
break;
case ErrArgKind.Type:
pType2 = arg2.pType;
break;
case ErrArgKind.SymWithType:
sym2 = arg2.swtMemo.sym;
break;
case ErrArgKind.MethWithInst:
sym2 = arg2.mpwiMemo.sym;
break;
default:
Debug.Assert(false, "Shouldn't be here!");
continue;
}
if (sym2 == sym && pType2 == pType && !fMunge)
continue;
prgpszNew[j] = prgpsz[j];
fMunge = true;
}
if (fMunge)
{
prgpszNew[i] = prgpsz[i];
}
}
prgpsz = prgpszNew;
}
CError err = CreateError(parameterizedError.GetErrorNumber(), prgpsz);
return err;
}
}