Пример #1
0
        internal void UpdateDocumentContextIfContainsDocument(IVsHierarchy sharedHierarchy, DocumentId documentId)
        {
            // TODO: This is a very roundabout way to update the context

            // The sharedHierarchy passed in has a new context, but we don't know what it is.
            // The documentId passed in is associated with this sharedHierarchy, and this method
            // will be called once for each such documentId. During this process, one of these
            // documentIds will actually belong to the new SharedItemContextHierarchy. Once we
            // find that one, we can map back to the open buffer and set its active context to
            // the appropriate project.

            // Note that if there is a single head project and it's in the process of being unloaded
            // there might not be a host project.
            var hostProject = LinkedFileUtilities.GetContextHostProject(sharedHierarchy, DeferredState.ProjectTracker);

            if (hostProject?.Hierarchy == sharedHierarchy)
            {
                return;
            }

            if (hostProject.Id != documentId.ProjectId)
            {
                // While this documentId is associated with one of the head projects for this
                // sharedHierarchy, it is not associated with the new context hierarchy. Another
                // documentId will be passed to this method and update the context.
                return;
            }

            // This documentId belongs to the new SharedItemContextHierarchy. Update the associated
            // buffer.
            OnDocumentContextUpdated(documentId);
        }
Пример #2
0
        private bool IsCurrentContext(uint docCookie, DocumentKey documentKey)
        {
            AssertIsForeground();
            _runningDocumentTable.GetDocumentHierarchyItem(docCookie, out var hierarchy, out var itemid);

            // If it belongs to a Shared Code or ASP.NET 5 project, then find the correct host project
            var hostProject = LinkedFileUtilities.GetContextHostProject(hierarchy, _projectContainer);

            return(documentKey.HostProject == hostProject);
        }
Пример #3
0
        /// <summary>
        /// Finds the <see cref="DocumentId"/> related to the given <see cref="DocumentId"/> that
        /// is in the current context. For regular files (non-shared and non-linked) and closed
        /// linked files, this is always the provided <see cref="DocumentId"/>. For open linked
        /// files and open shared files, the active context is already tracked by the
        /// <see cref="Workspace"/> and can be looked up directly. For closed shared files, the
        /// document in the shared project's <see cref="__VSHPROPID7.VSHPROPID_SharedItemContextHierarchy"/>
        /// is preferred.
        /// </summary>
        internal override DocumentId GetDocumentIdInCurrentContext(DocumentId documentId)
        {
            // If the document is open, then the Workspace knows the current context for both
            // linked and shared files
            if (IsDocumentOpen(documentId))
            {
                return(base.GetDocumentIdInCurrentContext(documentId));
            }

            var hostDocument = GetHostDocument(documentId);

            if (hostDocument == null)
            {
                // This can happen if the document was temporary and has since been closed/deleted.
                return(base.GetDocumentIdInCurrentContext(documentId));
            }

            var itemId = hostDocument.GetItemId();

            if (itemId == (uint)VSConstants.VSITEMID.Nil)
            {
                // An itemid is required to determine whether the file belongs to a Shared Project
                return(base.GetDocumentIdInCurrentContext(documentId));
            }

            // If this is a regular document or a closed linked (non-shared) document, then use the
            // default logic for determining current context.
            var sharedHierarchy = LinkedFileUtilities.GetSharedHierarchyForItem(hostDocument.Project.Hierarchy, itemId);

            if (sharedHierarchy == null)
            {
                return(base.GetDocumentIdInCurrentContext(documentId));
            }

            // This is a closed shared document, so we must determine the correct context.
            var hostProject     = LinkedFileUtilities.GetContextHostProject(sharedHierarchy, DeferredState.ProjectTracker);
            var matchingProject = CurrentSolution.GetProject(hostProject.Id);

            if (matchingProject == null || hostProject.Hierarchy == sharedHierarchy)
            {
                return(base.GetDocumentIdInCurrentContext(documentId));
            }

            if (matchingProject.ContainsDocument(documentId))
            {
                // The provided documentId is in the current context project
                return(documentId);
            }

            // The current context document is from another project.
            var linkedDocumentIds  = CurrentSolution.GetDocument(documentId).GetLinkedDocumentIds();
            var matchingDocumentId = linkedDocumentIds.FirstOrDefault(id => id.ProjectId == matchingProject.Id);

            return(matchingDocumentId ?? base.GetDocumentIdInCurrentContext(documentId));
        }