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); }
/// <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) ) ); } } }
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()); } } }
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()); } } }