private bool AddUniqueMembers()

in Elfie/Elfie/Model/MergedMembersDatabase.cs [55:187]


        private bool AddUniqueMembers(
            PackageDatabase source,
            int sourceMemberIndex,
            int targetMemberIndex,
            DatabaseAddResult result,
            ArdbVersion version)
        {
            int pathLength = result.CurrentPath.Length;
            SymbolDetails memberDetails = source.DeclaredMemberDetails[sourceMemberIndex];
            bool hasUniqueDescendants = false;
            int indexToAddChildrenUnder = targetMemberIndex;

            // Add public types and namespaces which contain either
            bool addMember = false;
            if (memberDetails.Type == SymbolType.FrameworkTarget)
            {
                String8 encodedFrameworkNames = source.StringStore[source.DeclaredMembers.GetNameIdentifier(sourceMemberIndex)];
                result.CurrentFrameworkNames = new HashSet<string>(encodedFrameworkNames.ToString().ToFrameworkNames());
            }
            else if (memberDetails.Type == SymbolType.Namespace)
            {
                addMember = ContainsPublics(source, sourceMemberIndex);
            }
            else if (memberDetails.Type == SymbolType.Assembly)
            {
                if (result.CurrentFrameworkNames != null)
                {
                    result.CurrentFrameworkNames.Clear();
                }
            }
            else if (memberDetails.Type.IsType())
            {
                addMember = memberDetails.Modifiers.HasFlag(SymbolModifier.Public);
            }

            // Add the member if it is a public type or contains them [and set 'indexInTarget' to the added member]
            if (addMember)
            {
                result.PublicTypeCount++;

                // Remap name for target StringStore [all unique names will be added anyway]
                int memberName = source.DeclaredMembers.GetNameIdentifier(sourceMemberIndex);
                String8 memberNameText = source.StringStore[memberName];
                result.CurrentPath.Append((result.CurrentPath.Length > 0 ? "." : "") + memberNameText.ToString());
                memberName = this.StringStore.FindOrAddString(memberNameText);

                string fullTypeName;
                HashSet<string> frameworkTargets;

                // See if this name is already found in the merged namespace tree
                if (!this.MergedMembers.TryFindChildByName(targetMemberIndex, memberName, out indexToAddChildrenUnder))
                {
                    // If not, add it, and the tree is unique because this name is
                    indexToAddChildrenUnder = this.MergedMembers.Add(targetMemberIndex, memberName);

                    // Identify the package which added it
                    int packageNameIdentifier = this.StringStore.FindOrAddString(source.Identity.PackageName);
                    this.MergedMemberSourcePackageIdentifier.Add(packageNameIdentifier);
                    this.MergedMemberDuplicateCount.Add(1);

                    hasUniqueDescendants = true;
                    result.MergedTypeCount++;

                    if (version != ArdbVersion.V1 && memberDetails.Type.IsType())
                    {
                        // We have encountered a fully-qualified type name for the 
                        // very first time. We will associate this name with the
                        // current framework target. We will also remember this
                        // sourceMemberIndex, in order to use it as the item
                        // to add when populating the ARDB.
                        fullTypeName = result.CurrentPath.ToString();
                        result.TypeToFrameworkTargetsMap.Add(fullTypeName, new HashSet<string>());

                        if (result.CurrentFrameworkNames != null)
                        {
                            result.TypeToFrameworkTargetsMap[fullTypeName].UnionWith(result.CurrentFrameworkNames);
                        }

                        result.TypeNameToTypeIndexMap.Add(fullTypeName, sourceMemberIndex);
                    }
                }
                else
                {
                    // Otherwise, if this is a duplicate with another entry in the same package, still include it (different framework targets)
                    String8 sourcePackage = this.StringStore[this.MergedMemberSourcePackageIdentifier[indexToAddChildrenUnder]];
                    if (version != ArdbVersion.V1 &&
                        result.CurrentFrameworkNames != null &&
                        sourcePackage.Equals(source.Identity.PackageName))
                    {
                        hasUniqueDescendants = true;
                        result.MergedTypeCount++;

                        if (version != ArdbVersion.V1 && memberDetails.Type.IsType())
                        {
                            // We have encountered a fully-qualified type name that we've seen
                            // before. We will record the current framework target but 
                            // will already have a source member index to use to add
                            // to the ARDB later.
                            fullTypeName = result.CurrentPath.ToString();
                            frameworkTargets = result.TypeToFrameworkTargetsMap[fullTypeName];
                            frameworkTargets.UnionWith(result.CurrentFrameworkNames);
                            Debug.Assert(result.TypeNameToTypeIndexMap.ContainsKey(fullTypeName));
                        }
                    }
                    else
                    {
                        // If this isn't unique, increment the count of copies
                        this.MergedMemberDuplicateCount[indexToAddChildrenUnder] += 1;
                    }
                }
            }

            if (!memberDetails.Type.IsType())
            {
                int childIndex = source.DeclaredMembers.GetFirstChild(sourceMemberIndex);
                while (childIndex > 0)
                {
                    hasUniqueDescendants |= AddUniqueMembers(source, childIndex, indexToAddChildrenUnder, result, version);
                    childIndex = source.DeclaredMembers.GetNextSibling(childIndex);
                }
            }

            // Add the package which had this member to results if it wasn't unique
            if (hasUniqueDescendants == false)
            {
                result.SourcePackageNames[sourceMemberIndex] = this.StringStore[this.MergedMemberSourcePackageIdentifier[indexToAddChildrenUnder]];
            }

            // Record whether this member was unique (and added)
            result.WasMemberAdded[sourceMemberIndex] = hasUniqueDescendants;
            result.CurrentPath.Length = pathLength;
            return hasUniqueDescendants;
        }