| File: Symbols\WellKnownGeneratedNameParser.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using Microsoft.CodeAnalysis.CodeGen; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Symbols; internal static partial class WellKnownGeneratedNames { /// <summary> /// Parses one or two debug ids that the specified <paramref name="metadataNameSuffix"/> ends with. /// /// Returns true if <paramref name="metadataNameSuffix"/> ends with one or two well-formed debug ids. /// If two ids are present in the name then the first is <paramref name="methodId"/> and the second is <paramref name="entityId"/>. /// Otherwise, if <paramref name="isMethodIdOptional"/> is true then the single parsed id is returned in <paramref name="entityId"/>, /// otherwise in <paramref name="methodId"/>. /// </summary> /// <param name="metadataNameSuffix">Suffix of the metadata name following the suffix separator.</param> public static bool TryParseDebugIds(ReadOnlySpan<char> metadataNameSuffix, char idSeparator, bool isMethodIdOptional, out DebugId methodId, out DebugId entityId) { methodId = entityId = default; int generation = -1; long power = 1; long value = 0; DebugId? seenId = null; for (int i = metadataNameSuffix.Length - 1; i >= -1; i--) { var c = (i >= 0) ? metadataNameSuffix[i] : '\0'; switch (c) { case >= '0' and <= '9': value += (c - '0') * power; if (value > int.MaxValue) { return false; } power *= 10; break; case GenerationSeparator: if (generation >= 0 || power == 1) { // bad format: return false; } generation = (int)value; value = 0; power = 1; break; default: if (power == 1) { // no digits parsed return false; } var id = new DebugId((int)value, (generation >= 0) ? generation : 0); generation = -1; value = 0; power = 1; if (seenId == null) { if (c == idSeparator) { // continue parsing, we have another id seenId = id; break; } // only a single id is present if (isMethodIdOptional) { entityId = id; } else { methodId = id; } return true; } if (c == idSeparator) { // bad format - only two ids allowed return false; } // two ids are present: methodId = id; entityId = seenId.Value; return true; } } throw ExceptionUtilities.Unreachable(); } }