private IReadOnlyList RenameMarshallableCore()

in SharpGen/Transform/NamingRulesManager.MultipleMarshallable.cs [49:164]


        private IReadOnlyList<string> RenameMarshallableCore<T>(IReadOnlyList<T> cppItems,
                                                                PostprocessName<T> postprocessName)
            where T : CppMarshallable
        {
            if (cppItems == null) throw new ArgumentNullException(nameof(cppItems));
            if (postprocessName == null) throw new ArgumentNullException(nameof(postprocessName));

            var count = cppItems.Count;
            var names = new string[count][];
            var result = new string[count];
            HashSet<string> nameSet = new();

            for (var index = 0; index < count; index++)
            {
                var cppItem = cppItems[index];

                var originalName = cppItem.Name;
                var tag = cppItem.Rule;
                var name = RenameCore(originalName, tag, null, out var isFinal, out var isPreempted);

                if (isFinal)
                {
                    Debug.Assert(!isPreempted);

                    var finalName = postprocessName(cppItem, name, true);
                    nameSet.Add(finalName);
                    result[index] = finalName;
                }
                else
                {
                    List<string> variantList = new(2);

                    var namingFlags = tag.NamingFlags is { } flags ? flags : NamingFlags.Default;
                    var noPrematureBreak = (namingFlags & NamingFlags.NoPrematureBreak) != 0;

                    string PascalCaseIfNeeded(string name)
                    {
                        if (isPreempted && !noPrematureBreak)
                            return name;

                        return ConvertToPascalCase(name, namingFlags);
                    }

                    if (!isPreempted || noPrematureBreak)
                    {
                        if ((namingFlags & NamingFlags.NoHungarianNotationHandler) == 0)
                        {
                            var originalNameLower = originalName.ToLowerInvariant();
                            foreach (var prefix in _hungarianNotation)
                                if (prefix.Apply(cppItem, name, originalName, originalNameLower, out var variants))
                                {
                                    variantList.AddRange(variants);
                                    break;
                                }
                        }
                    }

                    if (variantList.Count == 0)
                        variantList.Add(name);

                    names[index] = variantList.Select(x => postprocessName(cppItem, PascalCaseIfNeeded(x), false))
                                              .ToArray();
                }
            }

            Dictionary<string, uint> duplicateCount = new();

            string DeduplicateName(string name)
            {
                if (nameSet.Add(name))
                    return name;

                string newName;
                do
                {
                    if (!duplicateCount.TryGetValue(name, out var nameCount))
                        nameCount = 0;

                    duplicateCount[name] = ++nameCount;
                    newName = name + nameCount;
                } while (!nameSet.Add(newName));

                return newName;
            }

            for (var index = 0; index < count; index++)
            {
                if (result[index] != null)
                    continue;

                var nameList = names[index];

                switch (nameList.Length)
                {
                    case < 1:
                        Debug.Fail($"Expected to have non-empty {nameof(nameList)}");
                        result[index] = "SHARPGEN_FAILURE";
                        continue;
                    case 1:
                        result[index] = DeduplicateName(nameList[0]);
                        continue;
                }

                var withoutDuplicates = nameList.Except(nameSet).ToArray();

                result[index] = DeduplicateName(
                    withoutDuplicates.Length switch
                    {
                        >= 1 => withoutDuplicates[0],
                        < 1 => nameList[0]
                    }
                );
            }

            return result;
        }