private static MetadataTypeReference ReadGenericArgument(ref StringSpan remaining) { var isBracketed = TryRead(ref remaining, '['); var(typeName, genericArguments, nestedArrayRanks) = ReadTypeParts(ref remaining); var assemblyName = default(StringSpan); if (isBracketed) { var endingBracket = remaining.IndexOf(']'); if (endingBracket == -1) { throw new FormatException("Expected ']'"); } assemblyName = TryReadAssemblyName(remaining.Slice(0, endingBracket)); remaining = remaining.Slice(endingBracket + 1); } return(CreateType(typeName, assemblyName, genericArguments, nestedArrayRanks)); }
ReadTypeParts(ref StringSpan remaining) { var firstComma = remaining.IndexOf(','); var beforeComma = firstComma != -1 ? remaining.Slice(0, firstComma) : remaining; var firstBracket = beforeComma.IndexOf('['); if (firstBracket == -1) { var outerEndingBracket = beforeComma.IndexOf(']'); if (outerEndingBracket != -1) { remaining = remaining.Slice(outerEndingBracket); return(beforeComma.Slice(0, outerEndingBracket), null, null); } remaining = firstComma != -1 ? remaining.Slice(firstComma) : default; return(beforeComma, null, null); } var typeName = remaining.Slice(0, firstBracket); remaining = remaining.Slice(firstBracket + 1); var nestedArrayRanks = (List <int>)null; IReadOnlyList <MetadataTypeReference> genericArguments; var hasGenericAritySeparator = typeName.LastIndexOf('`') != -1; if (!hasGenericAritySeparator) { genericArguments = null; nestedArrayRanks = new List <int> { ReadArrayRank(ref remaining) }; } else { genericArguments = ReadGenericArgumentList(ref remaining); if (genericArguments.Count == 0) { throw new FormatException("Expected: generic argument"); } } for (;;) { while (TryRead(ref remaining, ' ')) { } if (!TryRead(ref remaining, '[')) { break; } if (nestedArrayRanks == null) { nestedArrayRanks = new List <int>(); } nestedArrayRanks.Add(ReadArrayRank(ref remaining)); } return(typeName, genericArguments, nestedArrayRanks); }