Esempio n. 1
0
        internal int Unregister(IVsDropdownBarManager manager)
        {
            _textView.Caret.PositionChanged -= CaretPositionChanged;

            // A buffer may have multiple DropDownBarClients, given one may open multiple CodeWindows
            // over a single buffer using Window/New Window
            List <DropDownBarClient> clients;

            if (_textView.Properties.TryGetProperty(typeof(DropDownBarClient), out clients))
            {
                clients.Remove(this);
                if (clients.Count == 0)
                {
                    _textView.Properties.RemoveProperty(typeof(DropDownBarClient));
                }
            }
            _services.GetBufferInfo(_textView.TextBuffer).OnNewParseTree -= ParserOnNewParseTree;
#if DEBUG
            IVsDropdownBar       existing;
            IVsDropdownBarClient existingClient;
            if (ErrorHandler.Succeeded(manager.GetDropdownBar(out existing)) &&
                ErrorHandler.Succeeded(existing.GetClient(out existingClient)))
            {
                Debug.Assert(existingClient == this, "Unregistering the wrong dropdown client");
            }
#endif

            return(manager.RemoveDropdownBar());
        }
Esempio n. 2
0
        internal AnalysisEntry GetAnalysisEntry()
        {
            var bi = _services.GetBufferInfo(TextBuffer);

            Debug.Assert(bi?.AnalysisEntry != null, "Failed to get project entry for buffer " + TextBuffer.ToString());
            return(bi?.AnalysisEntry);
        }
Esempio n. 3
0
        public async void VsTextViewCreated(VisualStudio.TextManager.Interop.IVsTextView textViewAdapter)
        {
            // TODO: We should probably only track text views in Python projects or loose files.
            var textView = _services.EditorAdaptersFactoryService.GetWpfTextView(textViewAdapter);

            if (textView != null)
            {
                var analyzer = _services.AnalysisEntryService.GetVsAnalyzer(textView, null);
                var bi       = _services.GetBufferInfo(textView.TextBuffer);
                if (analyzer != null && bi != null && bi.AnalysisEntry == null)
                {
                    var entry = await analyzer.AnalyzeFileAsync(bi.Filename);

                    if (bi.TrySetAnalysisEntry(entry, null) != entry)
                    {
                        // Failed to start analyzing
                        Debug.Fail("Failed to analyze xaml file");
                        return;
                    }
                    await entry.EnsureCodeSyncedAsync(bi.Buffer);

                    textView.Closed += TextView_Closed;
                }
            }
        }
Esempio n. 4
0
        public Task WaitForAnalyzerAsync(ITextBuffer textBuffer, CancellationToken cancellationToken)
        {
            if (textBuffer == null)
            {
                throw new ArgumentNullException(nameof(textBuffer));
            }

            return(_services.GetBufferInfo(textBuffer).WaitForAnalysisEntryAsync(cancellationToken));
        }
Esempio n. 5
0
        internal static ClassificationTypeDefinition BuiltinClassificationDefinition = null; // Set via MEF

        #endregion

        #region IDlrClassifierProvider

        public IClassifier GetClassifier(ITextBuffer buffer)
        {
            if (_categoryMap == null)
            {
                _categoryMap = FillCategoryMap(_services.ClassificationTypeRegistryService);
            }

            return(_services.GetBufferInfo(buffer).GetOrCreateClassifier(b => new PythonClassifier(this, b)));
        }
        public async void VsTextViewCreated(VisualStudio.TextManager.Interop.IVsTextView textViewAdapter)
        {
            var textView = _editorAdaptersFactory.GetWpfTextView(textViewAdapter);

            if (textView == null)
            {
                return;
            }

            // Only track text views in Python projects (we don't get called for loose files)
            // For example, we may get called for xaml files in UWP projects, in which case we do nothing
            if (!IsInPythonProject(textView))
            {
                return;
            }

            // Load Python services now that we know we'll need them
            if (_services == null)
            {
                _services = _site.GetComponentModel().GetService <PythonEditorServices>();
                if (_services == null)
                {
                    return;
                }
            }

            var bi = _services.GetBufferInfo(textView.TextBuffer);

            if (bi == null)
            {
                return;
            }

            var entry = bi.AnalysisEntry ?? await AnalyzeXamlFileAsync(textView, bi);

            for (int retries = 3; retries > 0 && entry == null; --retries)
            {
                // Likely in the process of changing analyzer, so we'll delay slightly and retry.
                await Task.Delay(100);

                entry = bi.AnalysisEntry ?? await AnalyzeXamlFileAsync(textView, bi);
            }

            if (entry == null)
            {
                Debug.Fail($"Failed to analyze XAML file {bi.Filename}");
                return;
            }

            if (bi.TrySetAnalysisEntry(entry, null) != entry)
            {
                // Failed to start analyzing
                Debug.Fail("Failed to analyze xaml file");
                return;
            }
            await entry.EnsureCodeSyncedAsync(bi.Buffer);
        }
Esempio n. 7
0
        public static Task <AnalysisEntry> GetAnalysisEntryAsync(this ITextBuffer buffer, PythonEditorServices services = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            var bi = services == null?PythonTextBufferInfo.TryGetForBuffer(buffer) : services.GetBufferInfo(buffer);

            if (bi != null)
            {
                return(bi.GetAnalysisEntryAsync(cancellationToken));
            }
            return(Task.FromResult <AnalysisEntry>(null));
        }
        internal static ClassificationTypeDefinition RegularExpressionClassificationDefinition = null; // Set via MEF

        #endregion

        #region IDlrClassifierProvider

        public IClassifier GetClassifier(ITextBuffer buffer)
        {
            if (_categoryMap == null)
            {
                _categoryMap = FillCategoryMap(_classificationRegistry);
            }

            return(_services.GetBufferInfo(buffer)
                   .GetOrCreateSink(typeof(PythonAnalysisClassifier), _ => new PythonAnalysisClassifier(this)));
        }
Esempio n. 9
0
 private void BufferGraph_GraphBuffersChanged(object sender, VisualStudio.Text.Projection.GraphBuffersChangedEventArgs e)
 {
     foreach (var b in e.RemovedBuffers)
     {
         PythonTextBufferInfo.TryGetForBuffer(b)?.RemoveSink(typeof(DropDownBarClient));
     }
     foreach (var b in e.AddedBuffers)
     {
         _services.GetBufferInfo(b).AddSink(typeof(DropDownBarClient), this);
     }
 }
 public PythonSuggestedActionsSource(
     PythonEditorServices services,
     ITextView textView,
     ITextBuffer textBuffer
     )
 {
     _services   = services;
     _view       = textView;
     _textBuffer = _services.GetBufferInfo(textBuffer);
     _textBuffer.OnNewAnalysisEntry += OnNewAnalysisEntry;
     _uiThread = _services.Site.GetUIThread();
 }
Esempio n. 11
0
        private static AP.FileUpdate GetUpdateForSnapshot(PythonEditorServices services, ITextSnapshot snapshot)
        {
            var buffer = services.GetBufferInfo(snapshot.TextBuffer);

            if (buffer.DoNotParse || snapshot.IsReplBufferWithCommand() || buffer.AnalysisBufferId < 0)
            {
                return(null);
            }

            var lastSent = buffer.LastSentSnapshot;

            if (lastSent?.Version == snapshot.Version)
            {
                // this snapshot is up to date...
                return(null);
            }

            // Update last sent snapshot and the analysis cookie to our
            // current snapshot.
            buffer.LastSentSnapshot = snapshot;
            var entry = buffer.AnalysisEntry;

            if (entry != null)
            {
                entry.AnalysisCookie = new SnapshotCookie(snapshot);
            }

            if (lastSent == null || lastSent.TextBuffer != buffer.Buffer)
            {
                // First time parsing from a live buffer, send the entire
                // file and set our initial snapshot.  We'll roll forward
                // to new snapshots when we receive the errors event.  This
                // just makes sure that the content is in sync.
                return(new AP.FileUpdate {
                    content = snapshot.GetText(),
                    version = snapshot.Version.VersionNumber,
                    bufferId = buffer.AnalysisBufferId,
                    kind = AP.FileUpdateKind.reset
                });
            }

            var versions = GetVersions(lastSent.Version, snapshot.Version).Select(v => new AP.VersionChanges {
                changes = GetChanges(v)
            }).ToArray();

            return(new AP.FileUpdate()
            {
                versions = versions,
                version = snapshot.Version.VersionNumber,
                bufferId = buffer.AnalysisBufferId,
                kind = AP.FileUpdateKind.changes
            });
        }
 public bool TryCreateContext(ITextView textView, SnapshotPoint openingPoint, char openingBrace, char closingBrace, out IBraceCompletionContext context)
 {
     if (IsValidBraceCompletionContext(EditorServices.GetBufferInfo(openingPoint.Snapshot.TextBuffer), openingPoint))
     {
         context = new BraceCompletionContext();
         return(true);
     }
     else
     {
         context = null;
         return(false);
     }
 }
        internal static ClassificationTypeDefinition ModuleClassificationDefinition = null; // Set via MEF

        #endregion

        #region IDlrClassifierProvider

        public IClassifier GetClassifier(ITextBuffer buffer)
        {
            if (buffer.Properties.ContainsProperty(typeof(IInteractiveEvaluator)))
            {
                return(null);
            }

            if (_categoryMap == null)
            {
                _categoryMap = FillCategoryMap(_classificationRegistry);
            }

            return(_services.GetBufferInfo(buffer).GetOrCreateAnalysisClassifier(b => new PythonAnalysisClassifier(this, b)));
        }
Esempio n. 14
0
        private void AddMissingImports(List <string> importList, SnapshotPoint point)
        {
            if (importList.Count == 0)
            {
                return;
            }

            var bi    = _services.GetBufferInfo(_textView.TextBuffer);
            var entry = bi?.AnalysisEntry;

            if (entry == null)
            {
                return;
            }

            SourceLocation loc;

            try {
                var line = point.GetContainingLine();
                loc = new SourceLocation(
                    point.Position,
                    line.LineNumber + 1,
                    point.Position - line.Start + 1
                    );
            } catch (ArgumentException ex) {
                Debug.Fail(ex.ToUnhandledExceptionMessage(GetType()));
                return;
            }

            foreach (var import in importList)
            {
                var isMissing = entry.Analyzer.WaitForRequest(
                    entry.Analyzer.IsMissingImportAsync(entry, import, loc),
                    "ExpansionClient.IsMissingImportAsync",
                    false
                    );

                if (isMissing)
                {
                    VsProjectAnalyzer.AddImport(
                        entry,
                        null,
                        import,
                        _textView,
                        _textView.TextBuffer
                        );
                }
            }
        }
        public ISuggestedActionsSource CreateSuggestedActionsSource(
            ITextView textView,
            ITextBuffer textBuffer
            )
        {
            if (textView == null || textBuffer == null)
            {
                return(null);
            }

            return(_services.GetBufferInfo(textBuffer).GetOrCreateSink(
                       typeof(PythonSuggestedActionsSource),
                       _ => new PythonSuggestedActionsSource(_services)
                       ));
        }
Esempio n. 16
0
        internal static ClassificationTypeDefinition BuiltinClassificationDefinition = null; // Set via MEF

        #endregion

        #region IDlrClassifierProvider

        public IClassifier GetClassifier(ITextBuffer buffer)
        {
            if (_categoryMap == null)
            {
                _categoryMap = FillCategoryMap(_services.ClassificationTypeRegistryService);
            }

            if (buffer.ContentType.IsOfType(CodeRemoteContentDefinition.CodeRemoteContentTypeName))
            {
                return(null);
            }

            return(_services.GetBufferInfo(buffer)
                   .GetOrCreateSink(typeof(PythonClassifier), _ => new PythonClassifier(this)));
        }
Esempio n. 17
0
        public DropDownBarClient(IServiceProvider serviceProvider, IWpfTextView textView, AnalysisEntry analysisEntry)
        {
            Utilities.ArgumentNotNull(nameof(serviceProvider), serviceProvider);
            Utilities.ArgumentNotNull(nameof(textView), textView);
            Utilities.ArgumentNotNull(nameof(analysisEntry), analysisEntry);

            _serviceProvider = serviceProvider;
            _uiThread        = _serviceProvider.GetUIThread();
            _services        = _serviceProvider.GetComponentModel().GetService <PythonEditorServices>();
            _analysisEntry   = analysisEntry;
            _textView        = textView;
            _services.GetBufferInfo(_textView.TextBuffer).OnNewParseTree += ParserOnNewParseTree;
            _dispatcher = Dispatcher.CurrentDispatcher;
            _textView.Caret.PositionChanged += CaretPositionChanged;
            for (int i = 0; i < NavigationLevels; i++)
            {
                _curSelection[i] = -1;
            }
        }
        public async void VsTextViewCreated(VisualStudio.TextManager.Interop.IVsTextView textViewAdapter)
        {
            // TODO: We should probably only track text views in Python projects or loose files.
            var textView = _services.EditorAdaptersFactoryService.GetWpfTextView(textViewAdapter);

            if (textView == null)
            {
                return;
            }

            var bi = _services.GetBufferInfo(textView.TextBuffer);

            if (bi == null)
            {
                return;
            }

            var entry = bi.AnalysisEntry ?? await AnalyzeXamlFileAsync(textView, bi);

            for (int retries = 3; retries > 0 && entry == null; --retries)
            {
                // Likely in the process of changing analyzer, so we'll delay slightly and retry.
                await Task.Delay(100);

                entry = await AnalyzeXamlFileAsync(textView, bi);
            }

            if (entry == null)
            {
                Debug.Fail($"Failed to analyze XAML file {bi.Filename}");
                return;
            }

            if (bi.TrySetAnalysisEntry(entry, null) != entry)
            {
                // Failed to start analyzing
                Debug.Fail("Failed to analyze xaml file");
                return;
            }
            await entry.EnsureCodeSyncedAsync(bi.Buffer);
        }
Esempio n. 19
0
 public PythonTextBufferInfo GetBuffer(ITextBuffer buffer)
 {
     return(buffer == null ? null : _services.GetBufferInfo(buffer));
 }
Esempio n. 20
0
        public async Task <bool> ExtractMethod(IExtractMethodInput input)
        {
            var buffer = _view.GetPythonBufferAtCaret();
            var bi     = _services.GetBufferInfo(buffer);
            var entry  = bi?.AnalysisEntry;

            if (entry?.Analyzer == null)
            {
                return(false);
            }

            var snapshot = buffer.CurrentSnapshot;

            // extract once to validate the selection
            var extract = await entry.Analyzer.ExtractMethodAsync(
                bi,
                _view,
                "method_name",
                null,
                null
                );

            if (extract == null)
            {
                return(false);
            }

            if (extract.cannotExtractMsg != null)
            {
                input.CannotExtract(extract.cannotExtractMsg);
                return(false);
            }

            if (extract.wasExpanded && !input.ShouldExpandSelection())
            {
                return(false);
            }

            if (extract.startLine > 0 && extract.endLine > 0)
            {
                var selectionSpan = _view.BufferGraph.MapUpToBuffer(
                    new SourceSpan(
                        new SourceLocation(extract.startLine, extract.startCol),
                        new SourceLocation(extract.endLine, extract.endCol)
                        ).ToSnapshotSpan(snapshot),
                    SpanTrackingMode.EdgeInclusive,
                    _view.TextBuffer
                    );

                foreach (var span in selectionSpan)
                {
                    _view.Selection.Select(span, false);
                    break;
                }
            }

            var info = input.GetExtractionInfo(new ExtractedMethodCreator(bi, _view, extract));

            if (info == null)
            {
                // user cancelled extract method
                return(false);
            }

            // extract again to get the final result...
            extract = await entry.Analyzer.ExtractMethodAsync(
                bi,
                _view,
                info.Name,
                info.Parameters,
                info.TargetScope?.Scope.id
                );

            if (extract == null)
            {
                return(false);
            }

            VsProjectAnalyzer.ApplyChanges(
                extract.changes,
                buffer,
                bi.LocationTracker,
                extract.version
                );

            return(true);
        }
        public async Task <bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken)
        {
            var textBuffer = range.Snapshot.TextBuffer;
            var bi         = _services.GetBufferInfo(textBuffer);
            var entry      = bi.AnalysisEntry;

            if (entry == null)
            {
                return(false);
            }

            var needSuggestion = new List <SnapshotSpan>();

            var tokens = textBuffer.GetPythonClassifier()?.GetClassificationSpans(range);

            foreach (var t in tokens.MaybeEnumerate())
            {
                if (t.ClassificationType.IsOfType(PredefinedClassificationTypeNames.Identifier))
                {
                    var isMissing = await entry.Analyzer.IsMissingImportAsync(
                        entry,
                        t.Span.GetText(),
                        t.Span.Start.ToSourceLocation()
                        );

                    if (isMissing)
                    {
                        needSuggestion.Add(t.Span);
                    }
                }
            }

            if (!needSuggestion.Any())
            {
                return(false);
            }


            var suggestions = new List <SuggestedActionSet>();

            foreach (var span in needSuggestion)
            {
                var available = await entry.Analyzer.FindNameInAllModulesAsync(span.GetText());

                var actions = available.Select(s => new PythonSuggestedImportAction(this, textBuffer, s))
                              .OrderBy(k => k)
                              .Distinct()
                              .ToArray();
                if (actions.Any())
                {
                    suggestions.Add(new SuggestedActionSet(actions));
                }
            }

            if (!suggestions.Any())
            {
                return(false);
            }

            cancellationToken.ThrowIfCancellationRequested();

            lock (_currentLock) {
                cancellationToken.ThrowIfCancellationRequested();
                _current     = suggestions;
                _currentSpan = range;
            }

            return(true);
        }