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;
}