public override bool TryGetDocumentTracker(ITextBuffer textBuffer, out VisualStudioDocumentTracker documentTracker)
        {
            if (textBuffer == null)
            {
                throw new ArgumentNullException(nameof(textBuffer));
            }

            if (!textBuffer.IsRazorBuffer())
            {
                documentTracker = null;
                return(false);
            }

            var textBufferInitialized = TryInitializeTextBuffer(textBuffer);

            if (!textBufferInitialized)
            {
                documentTracker = null;
                return(false);
            }

            if (!textBuffer.Properties.TryGetProperty(typeof(VisualStudioDocumentTracker), out documentTracker))
            {
                Debug.Fail("Document tracker should have been stored on the text buffer during initialization.");
                return(false);
            }

            return(true);
        }
Exemple #2
0
        public override void OnSubscribed(VisualStudioDocumentTracker tracker)
        {
            if (tracker == null)
            {
                throw new ArgumentNullException(nameof(tracker));
            }

            _foregroundDispatcher.AssertForegroundThread();

            var imports = GetImportItems(tracker);

            foreach (var import in imports)
            {
                var importFilePath = import.PhysicalPath;
                Debug.Assert(importFilePath != null);

                if (!_importTrackerCache.TryGetValue(importFilePath, out var importTracker))
                {
                    // First time seeing this import. Start tracking it.
                    var fileChangeTracker = _fileChangeTrackerFactory.Create(importFilePath);
                    importTracker = new ImportTracker(fileChangeTracker);
                    _importTrackerCache[importFilePath] = importTracker;

                    fileChangeTracker.Changed += FileChangeTracker_Changed;
                    fileChangeTracker.StartListening();
                }

                importTracker.AssociatedDocuments.Add(tracker.FilePath);
            }
        }
Exemple #3
0
        public BraceSmartIndenter(
            JoinableTaskContext joinableTaskContext,
            VisualStudioDocumentTracker documentTracker,
            TextBufferCodeDocumentProvider codeDocumentProvider,
            IEditorOperationsFactoryService editorOperationsFactory)
        {
            if (joinableTaskContext is null)
            {
                throw new ArgumentNullException(nameof(joinableTaskContext));
            }

            if (documentTracker is null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            if (codeDocumentProvider is null)
            {
                throw new ArgumentNullException(nameof(codeDocumentProvider));
            }

            if (editorOperationsFactory is null)
            {
                throw new ArgumentNullException(nameof(editorOperationsFactory));
            }

            _joinableTaskContext     = joinableTaskContext;
            _documentTracker         = documentTracker;
            _codeDocumentProvider    = codeDocumentProvider;
            _editorOperationsFactory = editorOperationsFactory;
            _textBuffer              = _documentTracker.TextBuffer;
            _textBuffer.Changed     += TextBuffer_OnChanged;
            _textBuffer.PostChanged += TextBuffer_OnPostChanged;
        }
Exemple #4
0
        public override void OnUnsubscribed(VisualStudioDocumentTracker tracker)
        {
            if (tracker == null)
            {
                throw new ArgumentNullException(nameof(tracker));
            }

            _foregroundDispatcher.AssertForegroundThread();

            var imports = GetImportItems(tracker);

            foreach (var import in imports)
            {
                var importFilePath = import.PhysicalPath;
                Debug.Assert(importFilePath != null);

                if (_importTrackerCache.TryGetValue(importFilePath, out var importTracker))
                {
                    importTracker.AssociatedDocuments.Remove(tracker.FilePath);

                    if (importTracker.AssociatedDocuments.Count == 0)
                    {
                        // There are no open documents that care about this import. We no longer need to track it.
                        importTracker.FileChangeTracker.StopListening();
                        _importTrackerCache.Remove(importFilePath);
                    }
                }
            }
        }
Exemple #5
0
        private static DefaultRazorEditorFactoryService CreateFactoryService(
            VisualStudioDocumentTracker documentTracker = null,
            VisualStudioRazorParser parser   = null,
            BraceSmartIndenter smartIndenter = null)
        {
            documentTracker ??= Mock.Of <VisualStudioDocumentTracker>(MockBehavior.Strict);
            parser ??= Mock.Of <VisualStudioRazorParser>(MockBehavior.Strict);
            smartIndenter ??= Mock.Of <BraceSmartIndenter>(MockBehavior.Strict);

            var documentTrackerFactory = Mock.Of <VisualStudioDocumentTrackerFactory>(f => f.Create(It.IsAny <ITextBuffer>()) == documentTracker, MockBehavior.Strict);
            var parserFactory          = Mock.Of <VisualStudioRazorParserFactory>(f => f.Create(It.IsAny <VisualStudioDocumentTracker>()) == parser, MockBehavior.Strict);
            var smartIndenterFactory   = Mock.Of <BraceSmartIndenterFactory>(f => f.Create(It.IsAny <VisualStudioDocumentTracker>()) == smartIndenter, MockBehavior.Strict);

            var services = TestServices.Create(new ILanguageService[]
            {
                documentTrackerFactory,
                parserFactory,
                smartIndenterFactory
            });

            Workspace workspace         = TestWorkspace.Create(services);
            var       workspaceAccessor = new Mock <VisualStudioWorkspaceAccessor>(MockBehavior.Strict);

            workspaceAccessor.Setup(p => p.TryGetWorkspace(It.IsAny <ITextBuffer>(), out workspace))
            .Returns(true);

            var factoryService = new DefaultRazorEditorFactoryService(workspaceAccessor.Object);

            return(factoryService);
        }
        public BraceSmartIndenter(
            ForegroundDispatcher dispatcher,
            VisualStudioDocumentTracker documentTracker,
            TextBufferCodeDocumentProvider codeDocumentProvider,
            IEditorOperationsFactoryService editorOperationsFactory)
        {
            if (dispatcher == null)
            {
                throw new ArgumentNullException(nameof(dispatcher));
            }

            if (documentTracker == null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            if (codeDocumentProvider == null)
            {
                throw new ArgumentNullException(nameof(codeDocumentProvider));
            }

            if (editorOperationsFactory == null)
            {
                throw new ArgumentNullException(nameof(editorOperationsFactory));
            }

            _dispatcher              = dispatcher;
            _documentTracker         = documentTracker;
            _codeDocumentProvider    = codeDocumentProvider;
            _editorOperationsFactory = editorOperationsFactory;
            _textBuffer              = _documentTracker.TextBuffer;
            _textBuffer.Changed     += TextBuffer_OnChanged;
            _textBuffer.PostChanged += TextBuffer_OnPostChanged;
        }
Exemple #7
0
        private IEnumerable <RazorProjectItem> GetImportItems(VisualStudioDocumentTracker tracker)
        {
            var projectDirectory = Path.GetDirectoryName(tracker.ProjectPath);
            var templateEngine   = _templateEngineFactoryService.Create(projectDirectory, _ => { });
            var imports          = templateEngine.GetImportItems(tracker.FilePath);

            return(imports);
        }
        private IEnumerable <RazorProjectItem> GetImportItems(VisualStudioDocumentTracker tracker)
        {
            var projectEngine    = tracker.ProjectSnapshot.GetProjectEngine();
            var documentSnapshot = tracker.ProjectSnapshot.GetDocument(tracker.FilePath);
            var fileKind         = documentSnapshot?.FileKind;
            var trackerItem      = projectEngine.FileSystem.GetItem(tracker.FilePath, fileKind);
            var importFeatures   = projectEngine.ProjectFeatures.OfType <IImportProjectFeature>();
            var importItems      = importFeatures.SelectMany(f => f.GetImports(trackerItem));
            var physicalImports  = importItems.Where(import => import.FilePath != null);

            return(physicalImports);
        }
Exemple #9
0
        public override BraceSmartIndenter Create(VisualStudioDocumentTracker documentTracker)
        {
            if (documentTracker is null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            _joinableTaskContext.AssertUIThread();

            var braceSmartIndenter = new BraceSmartIndenter(_joinableTaskContext, documentTracker, _codeDocumentProvider, _editorOperationsFactory);

            return(braceSmartIndenter);
        }
        public override BraceSmartIndenter Create(VisualStudioDocumentTracker documentTracker)
        {
            if (documentTracker == null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            _dispatcher.AssertForegroundThread();

            var braceSmartIndenter = new BraceSmartIndenter(_dispatcher, documentTracker, _editorOperationsFactory);

            return(braceSmartIndenter);
        }
        private IEnumerable <RazorProjectItem> GetImportItems(VisualStudioDocumentTracker tracker)
        {
            var projectEngine = tracker.ProjectSnapshot.GetProjectEngine();

            // It's not correct to use the file system to examine items in tooling, but it's a safe assumption
            // for right now that imports are a .cshtml file.
            var trackerItem     = projectEngine.FileSystem.GetItem(tracker.FilePath);
            var importFeatures  = projectEngine.ProjectFeatures.OfType <IImportProjectFeature>();
            var importItems     = importFeatures.SelectMany(f => f.GetImports(trackerItem));
            var physicalImports = importItems.Where(import => import.FilePath != null);

            return(physicalImports);
        }
        private IEnumerable <RazorProjectItem> GetImportItems(VisualStudioDocumentTracker tracker)
        {
            var projectEngine = tracker.ProjectSnapshot.GetProjectEngine();
            var trackerItem   = projectEngine.FileSystem.GetItem(tracker.FilePath);
            var importFeature = projectEngine.ProjectFeatures.OfType <IImportProjectFeature>().FirstOrDefault();

            // There should always be an import feature unless someone has misconfigured their RazorProjectEngine.
            // In that case once we attempt to parse the Razor file we'll explode and give the a user a decent
            // error message; for now, lets just be extra protective and assume 0 imports to not give a bad error.
            var importItems     = importFeature?.GetImports(trackerItem) ?? Enumerable.Empty <RazorProjectItem>();
            var physicalImports = importItems.Where(import => import.FilePath != null);

            return(physicalImports);
        }
Exemple #13
0
        private static DefaultRazorEditorFactoryService CreateFactoryService(
            VisualStudioDocumentTracker documentTracker = null,
            VisualStudioRazorParser parser   = null,
            BraceSmartIndenter smartIndenter = null)
        {
            documentTracker = documentTracker ?? Mock.Of <VisualStudioDocumentTracker>();
            parser          = parser ?? Mock.Of <VisualStudioRazorParser>();
            smartIndenter   = smartIndenter ?? Mock.Of <BraceSmartIndenter>();

            var documentTrackerFactory = Mock.Of <VisualStudioDocumentTrackerFactory>(f => f.Create(It.IsAny <ITextBuffer>()) == documentTracker);
            var parserFactory          = Mock.Of <VisualStudioRazorParserFactory>(f => f.Create(It.IsAny <VisualStudioDocumentTracker>()) == parser);
            var smartIndenterFactory   = Mock.Of <BraceSmartIndenterFactory>(f => f.Create(It.IsAny <VisualStudioDocumentTracker>()) == smartIndenter);
            var factoryService         = new DefaultRazorEditorFactoryService(documentTrackerFactory, parserFactory, smartIndenterFactory);

            return(factoryService);
        }
Exemple #14
0
        public override VisualStudioRazorParser Create(VisualStudioDocumentTracker documentTracker)
        {
            if (documentTracker == null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            _joinableTaskContext.AssertUIThread();

            var parser = new DefaultVisualStudioRazorParser(
                _joinableTaskContext,
                documentTracker,
                _projectEngineFactory,
                _errorReporter,
                _completionBroker);

            return(parser);
        }
        public override VisualStudioRazorParser Create(VisualStudioDocumentTracker documentTracker)
        {
            if (documentTracker == null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            _dispatcher.AssertForegroundThread();

            var parser = new DefaultVisualStudioRazorParser(
                _dispatcher,
                documentTracker,
                _projectEngineFactoryService,
                _errorReporter,
                _completionBroker);

            return(parser);
        }
Exemple #16
0
        public DefaultVisualStudioRazorParser(
            JoinableTaskContext joinableTaskContext,
            VisualStudioDocumentTracker documentTracker,
            ProjectSnapshotProjectEngineFactory projectEngineFactory,
            ErrorReporter errorReporter,
            VisualStudioCompletionBroker completionBroker)
        {
            if (joinableTaskContext is null)
            {
                throw new ArgumentNullException(nameof(joinableTaskContext));
            }

            if (documentTracker is null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            if (projectEngineFactory is null)
            {
                throw new ArgumentNullException(nameof(projectEngineFactory));
            }

            if (errorReporter is null)
            {
                throw new ArgumentNullException(nameof(errorReporter));
            }

            if (completionBroker is null)
            {
                throw new ArgumentNullException(nameof(completionBroker));
            }

            _joinableTaskContext  = joinableTaskContext;
            _projectEngineFactory = projectEngineFactory;
            _errorReporter        = errorReporter;
            _completionBroker     = completionBroker;
            _documentTracker      = documentTracker;
            _codeDocumentRequests = new List <CodeDocumentRequest>();

            _documentTracker.ContextChanged += DocumentTracker_ContextChanged;

            _joinableTaskContext.AssertUIThread();
            _uiThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        }
        // Internal for testing
        internal static bool TryCreateIndentationContext(
            int changePosition,
            int changeLength,
            string finalText,
            RazorSyntaxTree syntaxTree,
            VisualStudioDocumentTracker documentTracker,
            out BraceIndentationContext context)
        {
            var focusedTextView = documentTracker.GetFocusedTextView();

            if (focusedTextView != null && ParserHelpers.IsNewLine(finalText))
            {
                if (!AtApplicableRazorBlock(changePosition, syntaxTree))
                {
                    context = null;
                    return(false);
                }

                var currentSnapshot       = documentTracker.TextBuffer.CurrentSnapshot;
                var preChangeLineSnapshot = currentSnapshot.GetLineFromPosition(changePosition);

                // Handle the case where the \n comes through separately from the \r and the position
                // on the line is beyond what the GetText call above gives back.
                var linePosition = Math.Min(preChangeLineSnapshot.Length, changePosition - preChangeLineSnapshot.Start) - 1;

                if (AfterOpeningBrace(linePosition, preChangeLineSnapshot))
                {
                    var afterChangePosition     = changePosition + changeLength;
                    var afterChangeLineSnapshot = currentSnapshot.GetLineFromPosition(afterChangePosition);
                    var afterChangeLinePosition = afterChangePosition - afterChangeLineSnapshot.Start;

                    if (BeforeClosingBrace(afterChangeLinePosition, afterChangeLineSnapshot))
                    {
                        context = new BraceIndentationContext(focusedTextView, changePosition);
                        return(true);
                    }
                }
            }

            context = null;
            return(false);
        }
Exemple #18
0
        private TestParserManager CreateParserManager(VisualStudioDocumentTracker documentTracker)
        {
            var templateEngineFactory = CreateProjectEngineFactory();
            var parser = new DefaultVisualStudioRazorParser(
                Dispatcher,
                documentTracker,
                templateEngineFactory,
                new DefaultErrorReporter(),
                new TestCompletionBroker())
            {
                // We block idle work with the below reset events. Therefore, make tests fast and have the idle timer fire as soon as possible.
                IdleDelay = TimeSpan.FromMilliseconds(1),
                NotifyForegroundIdleStart = new ManualResetEventSlim(),
                BlockBackgroundIdleWork   = new ManualResetEventSlim(),
            };

            parser.StartParser();

            return(new TestParserManager(parser));
        }
Exemple #19
0
        public DefaultVisualStudioRazorParser(
            ForegroundDispatcher dispatcher,
            VisualStudioDocumentTracker documentTracker,
            ProjectSnapshotProjectEngineFactory projectEngineFactory,
            ErrorReporter errorReporter,
            VisualStudioCompletionBroker completionBroker)
        {
            if (dispatcher == null)
            {
                throw new ArgumentNullException(nameof(dispatcher));
            }

            if (documentTracker == null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            if (projectEngineFactory == null)
            {
                throw new ArgumentNullException(nameof(projectEngineFactory));
            }

            if (errorReporter == null)
            {
                throw new ArgumentNullException(nameof(errorReporter));
            }

            if (completionBroker == null)
            {
                throw new ArgumentNullException(nameof(completionBroker));
            }

            _dispatcher           = dispatcher;
            _projectEngineFactory = projectEngineFactory;
            _errorReporter        = errorReporter;
            _completionBroker     = completionBroker;
            _documentTracker      = documentTracker;
            _codeDocumentRequests = new List <CodeDocumentRequest>();

            _documentTracker.ContextChanged += DocumentTracker_ContextChanged;
        }
Exemple #20
0
        public DefaultVisualStudioRazorParser(
            ForegroundDispatcher dispatcher,
            VisualStudioDocumentTracker documentTracker,
            RazorTemplateEngineFactoryService templateEngineFactory,
            ErrorReporter errorReporter,
            VisualStudioCompletionBroker completionBroker)
        {
            if (dispatcher == null)
            {
                throw new ArgumentNullException(nameof(dispatcher));
            }

            if (documentTracker == null)
            {
                throw new ArgumentNullException(nameof(documentTracker));
            }

            if (templateEngineFactory == null)
            {
                throw new ArgumentNullException(nameof(templateEngineFactory));
            }

            if (errorReporter == null)
            {
                throw new ArgumentNullException(nameof(errorReporter));
            }

            if (completionBroker == null)
            {
                throw new ArgumentNullException(nameof(completionBroker));
            }

            _dispatcher            = dispatcher;
            _templateEngineFactory = templateEngineFactory;
            _errorReporter         = errorReporter;
            _completionBroker      = completionBroker;
            _documentTracker       = documentTracker;

            _documentTracker.ContextChanged += DocumentTracker_ContextChanged;
        }
Exemple #21
0
 public abstract VisualStudioRazorParser Create(VisualStudioDocumentTracker documentTracker);
 public abstract void OnUnsubscribed(VisualStudioDocumentTracker tracker);
Exemple #23
0
 public abstract BraceSmartIndenter Create(VisualStudioDocumentTracker documentTracker);
Exemple #24
0
        protected static TestTextBuffer CreateTextBuffer(ITextSnapshot initialSnapshot, VisualStudioDocumentTracker documentTracker)
        {
            var textBuffer = new TestTextBuffer(initialSnapshot);

            textBuffer.Properties.AddProperty(typeof(VisualStudioDocumentTracker), documentTracker);

            return(textBuffer);
        }
 public abstract bool TryGetDocumentTracker(ITextBuffer textBuffer, out VisualStudioDocumentTracker documentTracker);