private int ImportPackageNodes(PackageDatabase source) { int packageNodeIndex, sourceMemberIndex, targetMemberIndex; sourceMemberIndex = targetMemberIndex = 0; // 0 == sentinel root sourceMemberIndex = source.DeclaredMembers.GetFirstChild(sourceMemberIndex); SymbolDetails memberDetails = source.DeclaredMemberDetails[sourceMemberIndex]; int memberName = source.DeclaredMembers.GetNameIdentifier(sourceMemberIndex); memberName = this.StringStore.FindOrAddString(source.StringStore[memberName]); targetMemberIndex = this.DeclaredMembers.Add(targetMemberIndex, memberName); this.DeclaredMemberTypes.Add(memberDetails.Type); packageNodeIndex = targetMemberIndex; Debug.Assert(memberDetails.Type == SymbolType.Package); Debug.Assert(source.DeclaredMembers.GetNextSibling(sourceMemberIndex) < 0); // Add optional pre-release node if (source.Identity.ReleaseName.IsPrereleaseVersion()) { int packageReleaseId = this.StringStore.FindOrAddString(source.Identity.ReleaseName); this.DeclaredMembers.Add(targetMemberIndex, packageReleaseId); this.DeclaredMemberTypes.Add(SymbolType.Version); } // Inject popularity rank as an sibling node of package contents int popularityRank = source.GetPopularityRank(sourceMemberIndex); int popularityRankId = this.StringStore.FindOrAddString(popularityRank.ToString()); this.DeclaredMembers.Add(targetMemberIndex, popularityRankId); this.DeclaredMemberTypes.Add(SymbolType.PopularityRank); return(packageNodeIndex); }
private void ImportPublics( PackageDatabase source, int sourceMemberIndex, int targetMemberIndex, bool?[] uniqueMembers, ArdbVersion ardbVersion) { SymbolDetails memberDetails = source.DeclaredMemberDetails[sourceMemberIndex]; // Skip adding any subtrees which are not unique if (uniqueMembers != null) { bool?wasUnique = uniqueMembers[sourceMemberIndex]; if (wasUnique == null) { // Not added because not a public type (or ancestor wasn't) return; } else if (wasUnique == false) { // Not added because a non-unique item was detected for a package db // that is not permitted to add duplicates (only MS frameworks pkgs should). return; } } int indexInTarget = targetMemberIndex; // Index everything except the sentinel root. Also skip assembly nodes, // as matches will occur at the package node (which will actually // represent either a package or a reference assembly). if (sourceMemberIndex > 0 && (ardbVersion != ArdbVersion.V1 || memberDetails.Type != SymbolType.FrameworkTarget)) { // Remap name for target StringStore int memberName = source.DeclaredMembers.GetNameIdentifier(sourceMemberIndex); memberName = this.StringStore.FindOrAddString(source.StringStore[memberName]); // Add this member if it doesn't already exist [ex: same namespaces in multiple binaries in Package] if (!this.DeclaredMembers.TryFindChildByName(targetMemberIndex, memberName, out indexInTarget)) { // Add member to target tree indexInTarget = this.DeclaredMembers.Add(targetMemberIndex, memberName); this.DeclaredMemberTypes.Add(memberDetails.Type); // Validate DeclaredMembers and DeclaredMemberTypes are in sync if (this.DeclaredMemberTypes.Count != this.DeclaredMembers.Count) { throw new InvalidOperationException(String.Format(Resources.DatabaseArraysOutOfSync, "DeclaredMemberTypes")); } // Add member to index [types and namespaces so 'find second-to-last value' search works] this.Index.AddItem(memberName, indexInTarget); if (memberDetails.Type == SymbolType.Package) { int addedNode; // If this package is a pre-release version, we will introduce // a new node that holds the specific release details. This is // a short-term fix required to allow a fixer to request installation // of a pre-release only package. Nuget will add a new API in the future // that prevents the need for this node (which we can then remove). if (source.Identity.ReleaseName.IsPrereleaseVersion()) { int packageReleaseId = this.StringStore.FindOrAddString(source.Identity.ReleaseName); addedNode = this.DeclaredMembers.Add(indexInTarget, packageReleaseId); if (ardbVersion == ArdbVersion.V1) { // For V1, we injected the prerelease node as a parent to all // following nodes. For post-V1, this node is a sibling with // popularity rank. indexInTarget = addedNode; } this.DeclaredMemberTypes.Add(SymbolType.Version); } // Inject popularity rank as an sibling node of package contents int popularityRank = source.GetPopularityRank(sourceMemberIndex); int popularityRankId = this.StringStore.FindOrAddString(popularityRank.ToString()); addedNode = this.DeclaredMembers.Add(indexInTarget, popularityRankId); if (ardbVersion == ArdbVersion.V1) { // For V1, we injected the popularity rank directly underneath the // package or pre-release node. Post-V1, this node is a sibling of // the target frameworks node. // popularity rank. indexInTarget = addedNode; } this.DeclaredMemberTypes.Add(SymbolType.PopularityRank); } } else if (ardbVersion == ArdbVersion.V1) { if (memberDetails.Type == SymbolType.Package) { // For V1, we need to skip injected popularity node and prerelease nodes // when looking for duplicate children. This isn't required for post-V1, as // these nodes are introduced as siblings of the TFM and/or assembly-level data. indexInTarget = this.DeclaredMembers.GetFirstChild(indexInTarget); SymbolType symbolType = this.GetMemberType(indexInTarget); if (symbolType == SymbolType.Version) { indexInTarget = this.DeclaredMembers.GetFirstChild(indexInTarget); } // At this point, we should always have the popularity rank in hand Debug.Assert(this.GetMemberType(indexInTarget) == SymbolType.PopularityRank); } else if (memberDetails.Type == SymbolType.FrameworkTarget) { // If we find a TFM node, we will skip past it; indexInTarget = this.DeclaredMembers.GetFirstChild(indexInTarget); } } } // Recurse on children down to type level. We do not walk type members. // This means that we will exclude public nested types from the database. if (!memberDetails.Type.IsType()) { int childIndex = source.DeclaredMembers.GetFirstChild(sourceMemberIndex); while (childIndex > 0) { ImportPublics(source, childIndex, indexInTarget, uniqueMembers, ardbVersion); childIndex = source.DeclaredMembers.GetNextSibling(childIndex); } } }