示例#1
0
        public async Task <bool> ExtractMethod(IExtractMethodInput input)
        {
            var analyzer = _view.GetAnalyzerAtCaret(_serviceProvider);

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

            var buffer      = _view.GetPythonBufferAtCaret();
            var snapshot    = buffer.CurrentSnapshot;
            var projectFile = _view.GetAnalysisAtCaret(_serviceProvider);

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

            // extract once to validate the selection
            var extractInfo = await analyzer.ExtractMethodAsync(
                projectFile,
                buffer,
                _view,
                "method_name",
                null,
                null
                );

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

            var extract = extractInfo.Data;

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

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

            if (extract.startIndex != null && extract.endIndex != null)
            {
                var selectionSpan = _view.BufferGraph.MapUpToBuffer(
                    new SnapshotSpan(
                        snapshot,
                        Span.FromBounds(extract.startIndex.Value, extract.endIndex.Value)
                        ),
                    SpanTrackingMode.EdgeInclusive,
                    _view.TextBuffer
                    );

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

            var info = input.GetExtractionInfo(new ExtractedMethodCreator(analyzer, projectFile, _view, buffer, extract));

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

            // extract again to get the final result...
            extractInfo = await analyzer.ExtractMethodAsync(
                projectFile,
                buffer,
                _view,
                info.Name,
                info.Parameters,
                info.TargetScope?.Scope.id
                );

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

            VsProjectAnalyzer.ApplyChanges(
                extractInfo.Data.changes,
                buffer,
                extractInfo.GetTracker(extractInfo.Data.version)
                );

            return(true);
        }
示例#2
0
        /// <summary>
        /// Implements Goto Definition.  Called when the user selects Goto Definition from the
        /// context menu or hits the hotkey associated with Goto Definition.
        ///
        /// If there is 1 and only one definition immediately navigates to it.  If there are
        /// no references displays a dialog box to the user.  Otherwise it opens the find
        /// symbols dialog with the list of results.
        /// </summary>
        private async void GotoDefinition()
        {
            UpdateStatusForIncompleteAnalysis();

            var caret    = _textView.GetPythonCaret();
            var analysis = _textView.GetAnalysisAtCaret(_editorServices.Site);

            if (analysis != null && caret != null)
            {
                var defs = await analysis.Analyzer.AnalyzeExpressionAsync(analysis, caret.Value, ExpressionAtPointPurpose.FindDefinition);

                if (defs == null)
                {
                    return;
                }
                Dictionary <LocationInfo, SimpleLocationInfo> references, definitions, values;
                GetDefsRefsAndValues(analysis.Analyzer, _editorServices.Site, defs.Expression, defs.Variables, out definitions, out references, out values);

                if ((values.Count + definitions.Count) == 1)
                {
                    if (values.Count != 0)
                    {
                        foreach (var location in values.Keys)
                        {
                            GotoLocation(location);
                            break;
                        }
                    }
                    else
                    {
                        foreach (var location in definitions.Keys)
                        {
                            GotoLocation(location);
                            break;
                        }
                    }
                }
                else if (values.Count + definitions.Count == 0)
                {
                    if (String.IsNullOrWhiteSpace(defs.Expression))
                    {
                        MessageBox.Show(Strings.CannotGoToDefn, Strings.ProductTitle);
                    }
                    else
                    {
                        MessageBox.Show(Strings.CannotGoToDefn_Name.FormatUI(defs.Expression), Strings.ProductTitle);
                    }
                }
                else if (definitions.Count == 0)
                {
                    ShowFindSymbolsDialog(defs.Expression, new SymbolList(Strings.SymbolListValues, StandardGlyphGroup.GlyphForwardType, values.Values));
                }
                else if (values.Count == 0)
                {
                    ShowFindSymbolsDialog(defs.Expression, new SymbolList(Strings.SymbolListDefinitions, StandardGlyphGroup.GlyphLibrary, definitions.Values));
                }
                else
                {
                    ShowFindSymbolsDialog(defs.Expression,
                                          new LocationCategory(
                                              new SymbolList(Strings.SymbolListDefinitions, StandardGlyphGroup.GlyphLibrary, definitions.Values),
                                              new SymbolList(Strings.SymbolListValues, StandardGlyphGroup.GlyphForwardType, values.Values)
                                              )
                                          );
                }
            }
        }
示例#3
0
        public async Task RenameVariable(IRenameVariableInput input, IVsPreviewChangesService previewChanges)
        {
            if (IsModuleName(input))
            {
                input.CannotRename(Strings.RenameVariable_CannotRenameModuleName);
                return;
            }

            var caret  = _view.GetPythonCaret();
            var entry  = _view.GetAnalysisAtCaret(_serviceProvider);
            var buffer = entry?.TryGetBufferParser()?.DefaultBufferInfo ?? PythonTextBufferInfo.TryGetForBuffer(_view.TextBuffer);

            if (caret == null || entry == null || buffer == null)
            {
                input.CannotRename(Strings.RenameVariable_UnableGetAnalysisCurrentTextView);
                return;
            }
            var analysis = await entry.Analyzer.AnalyzeExpressionAsync(entry, caret.Value, ExpressionAtPointPurpose.Rename);

            if (analysis == null || string.IsNullOrEmpty(analysis.Expression) || !(analysis.Variables?.Any() ?? false))
            {
                input.CannotRename(Strings.RenameVariable_UnableGetExpressionAnalysis);
                return;
            }

            string privatePrefix = analysis.PrivatePrefix;
            var    originalName  = analysis.Variables
                                   .Where(r => r.Type == VariableType.Definition)
                                   .Where(r => r.Location.DocumentUri == buffer.DocumentUri && buffer.LocationTracker.CanTranslateFrom(r.Version ?? -1))
                                   .Select(r => {
                var snapshot = buffer.CurrentSnapshot;
                try {
                    return(buffer.LocationTracker.Translate(r.Location.Span, r.Version ?? -1, snapshot).GetText());
                } catch (ArgumentException) {
                    return(null);
                }
            })
                                   .Where(n => !string.IsNullOrEmpty(n))
                                   .FirstOrDefault() ?? analysis.Expression;

            if (analysis.PrivatePrefix != null && originalName != null && originalName.StartsWithOrdinal("_" + analysis.PrivatePrefix))
            {
                originalName  = originalName.Substring(analysis.PrivatePrefix.Length + 1);
                privatePrefix = analysis.PrivatePrefix;
            }

            if (originalName != null && _view.Selection.IsActive && !_view.Selection.IsEmpty)
            {
                if (_view.Selection.Start.Position < analysis.Span.GetStartPoint(_view.TextBuffer.CurrentSnapshot) ||
                    _view.Selection.End.Position > analysis.Span.GetEndPoint(_view.TextBuffer.CurrentSnapshot))
                {
                    originalName = null;
                }
            }

            if (originalName == null)
            {
                input.CannotRename(Strings.RenameVariable_SelectSymbol);
                return;
            }

            if (!analysis.Variables.Any(v => v.Type == VariableType.Definition || v.Type == VariableType.Reference))
            {
                input.CannotRename(Strings.RenameVariable_NoInformationAvailableForVariable.FormatUI(originalName));
                return;
            }

            PythonLanguageVersion languageVersion = PythonLanguageVersion.None;
            var analyzer = _view.GetAnalyzerAtCaret(_serviceProvider);
            var factory  = analyzer != null ? analyzer.InterpreterFactory : null;

            if (factory != null)
            {
                languageVersion = factory.Configuration.Version.ToLanguageVersion();
            }

            var info = input.GetRenameInfo(originalName, languageVersion);

            if (info != null)
            {
                var engine = new PreviewChangesEngine(_serviceProvider, input, analysis.Expression, info, originalName, privatePrefix, _view.GetAnalyzerAtCaret(_serviceProvider), analysis.Variables);
                if (info.Preview)
                {
                    previewChanges.PreviewChanges(engine);
                }
                else
                {
                    ErrorHandler.ThrowOnFailure(engine.ApplyChanges());
                }
            }
        }
示例#4
0
        public async Task RenameVariable(IRenameVariableInput input, IVsPreviewChangesService previewChanges)
        {
            if (IsModuleName(input))
            {
                input.CannotRename(Strings.RenameVariable_CannotRenameModuleName);
                return;
            }

            var caret = _view.GetPythonCaret();
            var entry = _view.GetAnalysisAtCaret(_serviceProvider);

            if (caret == null || entry == null)
            {
                input.CannotRename(Strings.RenameVariable_UnableGetAnalysisCurrentTextView);
                return;
            }
            var analysis = await entry.Analyzer.AnalyzeExpressionAsync(entry, _view, caret.Value);

            if (analysis == null)
            {
                input.CannotRename(Strings.RenameVariable_UnableGetAnalysisCurrentTextView);
                return;
            }

            string originalName  = null;
            string privatePrefix = null;

            if (!String.IsNullOrWhiteSpace(analysis.Expression))
            {
                originalName = analysis.MemberName;

                if (analysis.PrivatePrefix != null && originalName != null && originalName.StartsWith("_" + analysis.PrivatePrefix))
                {
                    originalName  = originalName.Substring(analysis.PrivatePrefix.Length + 1);
                    privatePrefix = analysis.PrivatePrefix;
                }

                if (originalName != null && _view.Selection.IsActive && !_view.Selection.IsEmpty)
                {
                    if (_view.Selection.Start.Position < analysis.Span.GetStartPoint(_view.TextBuffer.CurrentSnapshot) ||
                        _view.Selection.End.Position > analysis.Span.GetEndPoint(_view.TextBuffer.CurrentSnapshot))
                    {
                        originalName = null;
                    }
                }
            }

            if (originalName == null)
            {
                input.CannotRename(Strings.RenameVariable_SelectSymbol);
                return;
            }

            bool hasVariables = false;

            foreach (var variable in analysis.Variables)
            {
                if (variable.Type == VariableType.Definition || variable.Type == VariableType.Reference)
                {
                    hasVariables = true;
                    break;
                }
            }

            IEnumerable <AnalysisVariable> variables;

            if (!hasVariables)
            {
                List <AnalysisVariable> paramVars = await GetKeywordParameters(analysis.Expression, originalName);

                if (paramVars.Count == 0)
                {
                    input.CannotRename(Strings.RenameVariable_NoInformationAvailableForVariable.FormatUI(originalName));
                    return;
                }

                variables = paramVars;
            }
            else
            {
                variables = analysis.Variables;
            }

            PythonLanguageVersion languageVersion = PythonLanguageVersion.None;
            var analyzer = _view.GetAnalyzerAtCaret(_serviceProvider);
            var factory  = analyzer != null ? analyzer.InterpreterFactory : null;

            if (factory != null)
            {
                languageVersion = factory.Configuration.Version.ToLanguageVersion();
            }

            var info = input.GetRenameInfo(originalName, languageVersion);

            if (info != null)
            {
                var engine = new PreviewChangesEngine(_serviceProvider, input, analysis.Expression, info, originalName, privatePrefix, _view.GetAnalyzerAtCaret(_serviceProvider), variables);
                if (info.Preview)
                {
                    previewChanges.PreviewChanges(engine);
                }
                else
                {
                    ErrorHandler.ThrowOnFailure(engine.ApplyChanges());
                }
            }
        }