ContainedLanguage.cs 5.7 KB
Newer Older
S
Sam Harwell 已提交
1
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
2 3 4

using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
5
using Microsoft.CodeAnalysis.Diagnostics;
6 7 8 9 10 11
using Microsoft.CodeAnalysis.Formatting.Rules;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.Shell.Interop;
12
using Microsoft.VisualStudio.Text;
13 14
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.TextManager.Interop;
15
using Roslyn.Utilities;
16 17 18

namespace Microsoft.VisualStudio.LanguageServices.Implementation.Venus
{
19 20
    using Workspace = Microsoft.CodeAnalysis.Workspace;

C
CyrusNajmabadi 已提交
21 22 23
    internal partial class ContainedLanguage<TPackage, TLanguageService> : AbstractContainedLanguage
        where TPackage : AbstractPackage<TPackage, TLanguageService>
        where TLanguageService : AbstractLanguageService<TPackage, TLanguageService>
24 25
    {
        private readonly IVsEditorAdaptersFactoryService _editorAdaptersFactoryService;
26
        private readonly IDiagnosticAnalyzerService _diagnosticAnalyzerService;
27 28 29 30 31 32 33 34 35 36 37 38
        private readonly TLanguageService _languageService;

        protected readonly Workspace Workspace;
        protected readonly IComponentModel ComponentModel;
        protected readonly ContainedDocument ContainedDocument;

        // Set when a TextViewFIlter is set.  We hold onto this to keep our TagSource objects alive even if Venus
        // disconnects the subject buffer from the view temporarily (which they do frequently).  Otherwise, we have to
        // re-compute all of the tag data when they re-connect it, and this causes issues like classification
        // flickering.
        private ITagAggregator<ITag> _bufferTagAggregator;

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
        // <Previous release> BACKCOMPAT OVERLOAD -- DO NOT TOUCH
        // This is required for the Typescript Language Service
        public ContainedLanguage(
            IVsTextBufferCoordinator bufferCoordinator,
            IComponentModel componentModel,
            AbstractProject project,
            IVsHierarchy hierarchy,
            uint itemid,
            TLanguageService languageService,
            SourceCodeKind sourceCodeKind,
            IFormattingRule vbHelperFormattingRule)
            : this(bufferCoordinator,
                   componentModel,
                   project,
                   hierarchy,
                   itemid,
                   languageService,
                   sourceCodeKind,
                   vbHelperFormattingRule,
                   workspace: null)
        {
        }

62 63 64
        public ContainedLanguage(
            IVsTextBufferCoordinator bufferCoordinator,
            IComponentModel componentModel,
C
CyrusNajmabadi 已提交
65
            AbstractProject project,
66 67 68 69
            IVsHierarchy hierarchy,
            uint itemid,
            TLanguageService languageService,
            SourceCodeKind sourceCodeKind,
70 71
            IFormattingRule vbHelperFormattingRule = null,
            Workspace workspace = null)
72 73 74 75 76 77
            : base(project)
        {
            this.BufferCoordinator = bufferCoordinator;
            this.ComponentModel = componentModel;
            _languageService = languageService;

78
            this.Workspace = workspace ?? componentModel.GetService<VisualStudioWorkspace>();
79

80
            _editorAdaptersFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
81 82
            _diagnosticAnalyzerService = componentModel.GetService<IDiagnosticAnalyzerService>();

83
            // Get the ITextBuffer for the secondary buffer
C
CyrusNajmabadi 已提交
84
            Marshal.ThrowExceptionForHR(bufferCoordinator.GetSecondaryBuffer(out var secondaryTextLines));
85 86 87 88 89
            var secondaryVsTextBuffer = (IVsTextBuffer)secondaryTextLines;
            SetSubjectBuffer(_editorAdaptersFactoryService.GetDocumentBuffer(secondaryVsTextBuffer));

            var bufferTagAggregatorFactory = ComponentModel.GetService<IBufferTagAggregatorFactoryService>();
            _bufferTagAggregator = bufferTagAggregatorFactory.CreateTagAggregator<ITag>(SubjectBuffer);
C
CyrusNajmabadi 已提交
90
            Marshal.ThrowExceptionForHR(bufferCoordinator.GetPrimaryBuffer(out var primaryTextLines));
91
            var primaryVsTextBuffer = (IVsTextBuffer)primaryTextLines;
92
            var dataBuffer = _editorAdaptersFactoryService.GetDataBuffer(primaryVsTextBuffer);
93 94 95 96 97 98
            SetDataBuffer(dataBuffer);

            this.ContainedDocument = new ContainedDocument(
                this, sourceCodeKind, this.Workspace, hierarchy, itemid, componentModel, vbHelperFormattingRule);

            // TODO: Can contained documents be linked or shared?
99
            this.Project.AddDocument(this.ContainedDocument, isCurrentContext: true, hookupHandlers: true);
100
            this.DataBuffer.Changed += OnDataBufferChanged;
101 102 103 104
        }

        private void OnDisconnect()
        {
105
            this.DataBuffer.Changed -= OnDataBufferChanged;
106 107 108
            this.Project.RemoveDocument(this.ContainedDocument);
        }

109 110 111 112 113 114 115
        private void OnDataBufferChanged(object sender, TextContentChangedEventArgs e)
        {
            // we don't actually care what has changed in primary buffer. we just want to re-analyze secondary buffer
            // when primary buffer has changed to update diagnostic positions.
            _diagnosticAnalyzerService.Reanalyze(this.Workspace, documentIds: SpecializedCollections.SingletonEnumerable(this.ContainedDocument.Id));
        }

116 117 118 119 120 121 122 123 124 125
        public override void Dispose()
        {
            if (_bufferTagAggregator != null)
            {
                _bufferTagAggregator.Dispose();
                _bufferTagAggregator = null;
            }
        }
    }
}