public override IVsSimpleObjectList2 DoSearch(VSOBSEARCHCRITERIA2 criteria) { var node = _hierarchy as PythonFileNode; if (node != null) { var analysis = node.GetAnalysisEntry(); if (analysis != null) { string expr = criteria.szName.Substring(criteria.szName.LastIndexOf(':') + 1); var exprAnalysis = VsProjectAnalyzer.AnalyzeExpressionAsync( analysis, criteria.szName.Substring(criteria.szName.LastIndexOf(':') + 1), new Parsing.SourceLocation(0, 1, 1) ).WaitOrDefault(1000); if (exprAnalysis != null) { return(EditFilter.GetFindRefLocations(analysis.Analyzer, _hierarchy.ProjectMgr.Site, expr, exprAnalysis.Variables)); } } } return(null); }
public override IVsSimpleObjectList2 FindReferences() { var analyzer = this.Hierarchy.GetPythonProject().GetAnalyzer(); List <AnalysisVariable> vars = new List <AnalysisVariable>(); if (analyzer != null) { foreach (var value in _value.Values) { foreach (var reference in value.locations) { var entry = analyzer.GetAnalysisEntryFromPath(reference.file); var analysis = VsProjectAnalyzer.AnalyzeExpressionAsync( entry, Name, new SourceLocation(0, reference.line, reference.column) ).WaitOrDefault(1000); vars.AddRange(analysis.Variables); } } } return(EditFilter.GetFindRefLocations( analyzer, Site, Name, vars.ToArray() )); }
/// <summary> /// Implements Find All References. Called when the user selects Find All References from /// the context menu or hits the hotkey associated with find all references. /// /// Always opens the Find Symbol Results box to display the results. /// </summary> private async void FindAllReferences() { UpdateStatusForIncompleteAnalysis(); var caret = _textView.GetPythonCaret(); if (caret != null) { var references = await VsProjectAnalyzer.AnalyzeExpressionAsync(_serviceProvider, _textView, caret.Value); if (references == null) { return; } var locations = GetFindRefLocations(_textView.GetAnalyzerAtCaret(_serviceProvider), _serviceProvider, references.Expression, references.Variables); ShowFindSymbolsDialog(references.Expression, locations); } }
/// <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(); if (caret != null) { var defs = await VsProjectAnalyzer.AnalyzeExpressionAsync(_serviceProvider, _textView, caret.Value); if (defs == null) { return; } Dictionary<AnalysisLocation, SimpleLocationInfo> references, definitions, values; GetDefsRefsAndValues(_textView.GetAnalyzerAtCaret(_serviceProvider), _serviceProvider, 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(String.Format("Cannot go to definition. The cursor is not on a symbol."), "Python Tools for Visual Studio"); } else { MessageBox.Show(String.Format("Cannot go to definition \"{0}\"", defs.Expression), "Python Tools for Visual Studio"); } } else if (definitions.Count == 0) { ShowFindSymbolsDialog(defs.Expression, new SymbolList("Values", StandardGlyphGroup.GlyphForwardType, values.Values)); } else if (values.Count == 0) { ShowFindSymbolsDialog(defs.Expression, new SymbolList("Definitions", StandardGlyphGroup.GlyphLibrary, definitions.Values)); } else { ShowFindSymbolsDialog(defs.Expression, new LocationCategory("Goto Definition", new SymbolList("Definitions", StandardGlyphGroup.GlyphLibrary, definitions.Values), new SymbolList("Values", StandardGlyphGroup.GlyphForwardType, values.Values) ) ); } } }
public ExpressionAnalysis AnalyzeExpression(ITextView view, ITextSnapshot snapshot, ITrackingSpan span, bool forCompletion = true) { return(VsProjectAnalyzer.AnalyzeExpressionAsync(_container, view, span.GetStartPoint(snapshot)).WaitOrDefault(1000)); }
public async Task RenameVariable(IRenameVariableInput input, IVsPreviewChangesService previewChanges) { if (IsModuleName(input)) { input.CannotRename("Cannot rename a module name"); return; } var caret = _view.GetPythonCaret(); var analysis = await VsProjectAnalyzer.AnalyzeExpressionAsync(_serviceProvider, _view, caret.Value); if (analysis == null) { input.CannotRename("Unable to get analysis for current text view."); 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("Please select a symbol to be renamed."); 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(string.Format("No information is available for the variable '{0}'.", 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()); } } }
/// <summary> /// Gets a ExpressionAnalysis for the expression at the provided span. If the span is in /// part of an identifier then the expression is extended to complete the identifier. /// </summary> public static Task <ExpressionAnalysis> AnalyzeExpressionAsync(this ITextSnapshot snapshot, IServiceProvider serviceProvider, ITrackingSpan span, bool forCompletion = true) { return(VsProjectAnalyzer.AnalyzeExpressionAsync(span.GetStartPoint(snapshot))); }