public override CompletionSet GetCompletions(IGlyphService glyphService) { var start1 = _stopwatch.ElapsedMilliseconds; IEnumerable <CompletionResult> members = null; IEnumerable <CompletionResult> replMembers = null; var interactiveWindow = _snapshot.TextBuffer.GetInteractiveWindow(); var pyReplEval = interactiveWindow?.Evaluator as IPythonInteractiveIntellisense; var analysis = GetAnalysisEntry(); string text; SnapshotSpan statementRange; if (!GetPrecedingExpression(out text, out statementRange)) { return(null); } else if (string.IsNullOrEmpty(text)) { if (analysis != null) { Debug.Assert(analysis.Analyzer == _analyzer); lock (_analyzer) { var location = VsProjectAnalyzer.TranslateIndex( statementRange.Start.Position, statementRange.Snapshot, analysis ); var parameters = Enumerable.Empty <CompletionResult>(); var sigs = _analyzer.WaitForRequest(_analyzer.GetSignaturesAsync(analysis, View, _snapshot, Span), "GetCompletions.GetSignatures"); if (sigs != null && sigs.Signatures.Any()) { parameters = sigs.Signatures .SelectMany(s => s.Parameters) .Select(p => p.Name) .Distinct() .Select(n => new CompletionResult(n, PythonMemberType.Field)); } members = _analyzer.WaitForRequest(_analyzer.GetAllAvailableMembersAsync(analysis, location, _options.MemberOptions), "GetCompletions.GetAllAvailableMembers") .MaybeEnumerate() .Union(parameters, CompletionComparer.MemberEquality); } } if (pyReplEval == null) { var expansions = _analyzer.WaitForRequest(_serviceProvider.GetPythonToolsService().GetExpansionCompletionsAsync(), "GetCompletions.GetExpansionCompletions"); if (expansions != null) { // Expansions should come first, so that they replace our keyword // completions with the more detailed snippets. if (members != null) { members = expansions.Union(members, CompletionComparer.MemberEquality); } else { members = expansions; } } } if (pyReplEval != null) { replMembers = pyReplEval.GetMemberNames(string.Empty); } } else { if (analysis != null && (pyReplEval == null || !pyReplEval.LiveCompletionsOnly)) { Debug.Assert(analysis.Analyzer == _analyzer); lock (_analyzer) { var location = VsProjectAnalyzer.TranslateIndex( statementRange.Start.Position, statementRange.Snapshot, analysis ); members = _analyzer.WaitForRequest(_analyzer.GetMembersAsync(analysis, text, location, _options.MemberOptions), "GetCompletions.GetMembers"); } } if (pyReplEval != null && _analyzer.ShouldEvaluateForCompletion(text)) { Debug.Assert(pyReplEval.Analyzer == _analyzer); replMembers = pyReplEval.GetMemberNames(text); } } if (replMembers != null) { if (members != null) { members = members.Union(replMembers, CompletionComparer.MemberEquality); } else { members = replMembers; } } var end = _stopwatch.ElapsedMilliseconds; if (/*Logging &&*/ (end - start1) > TooMuchTime) { if (members != null) { var memberArray = members.ToArray(); members = memberArray; Trace.WriteLine(String.Format("{0} lookup time {1} for {2} members", this, end - start1, members.Count())); } else { Trace.WriteLine(String.Format("{0} lookup time {1} for zero members", this, end - start1)); } } if (members == null) { // The expression is invalid so we shouldn't provide // a completion set at all. return(null); } var start = _stopwatch.ElapsedMilliseconds; var result = new FuzzyCompletionSet( "Python", "Python", Span, members.Select(m => PythonCompletion(glyphService, m)), _options, CompletionComparer.UnderscoresLast, matchInsertionText: true ); end = _stopwatch.ElapsedMilliseconds; if (/*Logging &&*/ (end - start1) > TooMuchTime) { Trace.WriteLine(String.Format("{0} completion set time {1} total time {2}", this, end - start, end - start1)); } return(result); }