Exemplo n.º 1
0
        internal override void SetDocumentContext(DocumentId documentId)
        {
            var hostDocument = GetHostDocument(documentId);
            var hierarchy    = hostDocument.Project.Hierarchy;
            var itemId       = hostDocument.GetItemId();

            if (itemId == (uint)VSConstants.VSITEMID.Nil)
            {
                // the document has been removed from the solution
                return;
            }

            var sharedHierarchy = LinkedFileUtilities.GetSharedHierarchyForItem(hierarchy, itemId);

            if (sharedHierarchy != null)
            {
                // Universal Project shared files
                //     Change the SharedItemContextHierarchy of the project's parent hierarchy, then
                //     hierarchy events will trigger the workspace to update.
                var hr = sharedHierarchy.SetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID7.VSHPROPID_SharedItemContextHierarchy, hierarchy);
            }
            else
            {
                // Regular linked files
                //     Transfer the item (open buffer) to the new hierarchy, and then hierarchy events
                //     will trigger the workspace to update.
                var vsproj = hierarchy as IVsProject3;
                var hr     = vsproj.TransferItem(hostDocument.FilePath, hostDocument.FilePath, punkWindowFrame: null);
            }
        }
Exemplo n.º 2
0
            private void UnsubscribeFromSharedHierarchyEvents(DocumentId documentId)
            {
                var hostDocument = _workspace.GetHostDocument(documentId);
                var hierarchy    = hostDocument.Project.Hierarchy;

                var itemId = hostDocument.GetItemId();

                if (itemId == (uint)VSConstants.VSITEMID.Nil)
                {
                    // the document has been removed from the solution
                    return;
                }

                var sharedHierarchy = LinkedFileUtilities.GetSharedHierarchyForItem(hierarchy, itemId);

                if (sharedHierarchy != null)
                {
                    uint cookie;
                    if (_documentIdToHierarchyEventsCookieMap.TryGetValue(documentId, out cookie))
                    {
                        var hr = sharedHierarchy.UnadviseHierarchyEvents(cookie);
                        _documentIdToHierarchyEventsCookieMap.Remove(documentId);
                    }
                }
            }
Exemplo n.º 3
0
            private void SubscribeToSharedHierarchyEvents(DocumentId documentId)
            {
                // Todo: maybe avoid double alerts.
                var hostDocument = _workspace.GetHostDocument(documentId);

                if (hostDocument == null)
                {
                    return;
                }

                var hierarchy = hostDocument.Project.Hierarchy;

                var itemId = hostDocument.GetItemId();

                if (itemId == (uint)VSConstants.VSITEMID.Nil)
                {
                    // the document has been removed from the solution
                    return;
                }

                var sharedHierarchy = LinkedFileUtilities.GetSharedHierarchyForItem(hierarchy, itemId);

                if (sharedHierarchy != null)
                {
                    uint cookie;
                    var  eventSink = new HierarchyEventsSink(_workspace, sharedHierarchy, documentId);
                    var  hr        = sharedHierarchy.AdviseHierarchyEvents(eventSink, out cookie);

                    if (hr == VSConstants.S_OK && !_documentIdToHierarchyEventsCookieMap.ContainsKey(documentId))
                    {
                        _documentIdToHierarchyEventsCookieMap.Add(documentId, cookie);
                    }
                }
            }
Exemplo n.º 4
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));
        }
Exemplo n.º 5
0
            public StandardTextDocument(
                DocumentProvider documentProvider,
                IVisualStudioHostProject project,
                DocumentKey documentKey,
                uint itemId,
                SourceCodeKind sourceCodeKind,
                ITextBufferFactoryService textBufferFactoryService,
                ITextUndoHistoryRegistry textUndoHistoryRegistry,
                IVsFileChangeEx fileChangeService,
                ITextBuffer openTextBuffer,
                DocumentId id)
            {
                Contract.ThrowIfNull(documentProvider);
                Contract.ThrowIfNull(textBufferFactoryService);

                this.Project = project;
                this.Id      = id ?? DocumentId.CreateNewId(project.Id, documentKey.Moniker);
                this.Folders = project.GetFolderNames(itemId);

                // TODO:
                // this one doesn't work for asynchronous project load situation where shared projects is loaded after one uses shared file.
                // we need to figure out what to do on those case. but this works for project k case.
                // opened an issue to track this issue - https://github.com/dotnet/roslyn/issues/1859
                this.SharedHierarchy = project.Hierarchy == null ? null : LinkedFileUtilities.GetSharedHierarchyForItem(project.Hierarchy, itemId);
                _documentProvider    = documentProvider;

                this.Key                          = documentKey;
                this.SourceCodeKind               = sourceCodeKind;
                _itemMoniker                      = documentKey.Moniker;
                _textBufferFactoryService         = textBufferFactoryService;
                _textUndoHistoryRegistry          = textUndoHistoryRegistry;
                _fileChangeTracker                = new FileChangeTracker(fileChangeService, this.FilePath);
                _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;

                _openTextBuffer  = openTextBuffer;
                _snapshotTracker = new ReiteratedVersionSnapshotTracker(openTextBuffer);

                // The project system does not tell us the CodePage specified in the proj file, so
                // we use null to auto-detect.
                _doNotAccessDirectlyLoader = new FileTextLoader(documentKey.Moniker, defaultEncoding: null);

                // If we aren't already open in the editor, then we should create a file change notification
                if (openTextBuffer == null)
                {
                    _fileChangeTracker.StartFileChangeListeningAsync();
                }
            }
Exemplo n.º 6
0
            public StandardTextDocument(
                DocumentProvider documentProvider,
                IVisualStudioHostProject project,
                DocumentKey documentKey,
                uint itemId,
                SourceCodeKind sourceCodeKind,
                ITextBufferFactoryService textBufferFactoryService,
                ITextUndoHistoryRegistry textUndoHistoryRegistry,
                IVsFileChangeEx fileChangeService,
                ITextBuffer openTextBuffer,
                DocumentId id)
            {
                Contract.ThrowIfNull(documentProvider);
                Contract.ThrowIfNull(textBufferFactoryService);

                this.Project = project;
                this.Id      = id ?? DocumentId.CreateNewId(project.Id, documentKey.Moniker);
                this.Folders = project.GetFolderNames(itemId);

                this.SharedHierarchy = project.Hierarchy == null ? null : LinkedFileUtilities.GetSharedHierarchyForItem(project.Hierarchy, itemId);
                _documentProvider    = documentProvider;

                this.Key                          = documentKey;
                this.SourceCodeKind               = sourceCodeKind;
                _itemMoniker                      = documentKey.Moniker;
                _textBufferFactoryService         = textBufferFactoryService;
                _textUndoHistoryRegistry          = textUndoHistoryRegistry;
                _fileChangeTracker                = new FileChangeTracker(fileChangeService, this.FilePath);
                _fileChangeTracker.UpdatedOnDisk += OnUpdatedOnDisk;

                _openTextBuffer  = openTextBuffer;
                _snapshotTracker = new ReiteratedVersionSnapshotTracker(openTextBuffer);

                // The project system does not tell us the CodePage specified in the proj file, so
                // we use null to auto-detect.
                _doNotAccessDirectlyLoader = new FileTextLoader(documentKey.Moniker, defaultEncoding: null);

                // If we aren't already open in the editor, then we should create a file change notification
                if (openTextBuffer == null)
                {
                    _fileChangeTracker.StartFileChangeListeningAsync();
                }
            }