in ClrMemDiag/Desktop/types.cs [1600:1748]
internal static int FixGenericsWorker(string name, int start, int end, StringBuilder sb)
{
int parenCount = 0;
while (start < end)
{
char c = name[start];
if (c == '`')
break;
if (c == '[')
parenCount++;
if (c == ']')
parenCount--;
if (parenCount < 0)
return start + 1;
if (c == ',' && parenCount == 0)
return start;
sb.Append(c);
start++;
}
if (start >= end)
return start;
start++;
bool hasSubtypeAirity = false;
int paramCount = 0;
do
{
int currParamCount = 0;
hasSubtypeAirity = false;
// Skip airity.
while (start < end)
{
char c = name[start];
if (c < '0' || c > '9')
break;
currParamCount = (currParamCount * 10) + c - '0';
start++;
}
paramCount += currParamCount;
if (start >= end)
return start;
if (name[start] == '+')
{
while (start < end && name[start] != '[')
{
if (name[start] == '`')
{
start++;
hasSubtypeAirity = true;
break;
}
sb.Append(name[start]);
start++;
}
if (start >= end)
return start;
}
} while (hasSubtypeAirity);
if (name[start] == '[')
{
sb.Append('<');
start++;
while (paramCount-- > 0)
{
if (start >= end)
return start;
bool withModule = false;
if (name[start] == '[')
{
withModule = true;
start++;
}
start = FixGenericsWorker(name, start, end, sb);
if (start < end && name[start] == '[')
{
start++;
if (start >= end)
return start;
sb.Append('[');
while (start < end && name[start] == ',')
{
sb.Append(',');
start++;
}
if (start >= end)
return start;
if (name[start] == ']')
{
sb.Append(']');
start++;
}
}
if (withModule)
{
while (start < end && name[start] != ']')
start++;
start++;
}
if (paramCount > 0)
{
if (start >= end)
return start;
//Debug.Assert(name[start] == ',');
sb.Append(',');
start++;
if (start >= end)
return start;
if (name[start] == ' ')
start++;
}
}
sb.Append('>');
start++;
}
if (start + 1 >= end)
return start;
if (name[start] == '[' && name[start + 1] == ']')
sb.Append("[]");
return start;
}