Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
                }
            }
        }