Esempio n. 1
0
        public override async Task <CompletionList> Completion(CompletionParams @params)
        {
            var uri = @params.textDocument.uri;

            GetAnalysis(@params.textDocument, @params.position, @params._version, out var entry, out var tree);

            TraceMessage($"Completions in {uri} at {@params.position}");

            var analysis = entry?.Analysis;

            if (analysis == null)
            {
                TraceMessage($"No analysis found for {uri}");
                return(new CompletionList {
                });
            }

            var opts = (GetMemberOptions)0;

            if (@params.context.HasValue)
            {
                var c = @params.context.Value;
                if (c._intersection)
                {
                    opts |= GetMemberOptions.IntersectMultipleResults;
                }
                if (c._statementKeywords ?? true)
                {
                    opts |= GetMemberOptions.IncludeStatementKeywords;
                }
                if (c._expressionKeywords ?? true)
                {
                    opts |= GetMemberOptions.IncludeExpressionKeywords;
                }
            }
            else
            {
                opts = GetMemberOptions.IncludeStatementKeywords | GetMemberOptions.IncludeExpressionKeywords;
            }

            var parse = entry.WaitForCurrentParse(_clientCaps?.python?.completionsTimeout ?? -1);

            if (_traceLogging)
            {
                if (parse == null)
                {
                    LogMessage(MessageType.Error, $"Timed out waiting for AST for {uri}");
                }
                else if (parse.Cookie is VersionCookie vc && vc.Versions.TryGetValue(GetPart(uri), out var bv))
                {
                    LogMessage(MessageType.Log, $"Got AST for {uri} at version {bv.Version}");
                }
                else
                {
                    LogMessage(MessageType.Log, $"Got AST for {uri}");
                }
            }
Esempio n. 2
0
        public override async Task <CompletionList> Completion(CompletionParams @params)
        {
            await _analyzerCreationTask;

            await IfTestWaitForAnalysisCompleteAsync();

            var uri = @params.textDocument.uri;
            // Make sure document is enqueued for processing
            var openFile = _openFiles.GetDocument(uri);

            _projectFiles.GetAnalysis(@params.textDocument, @params.position, @params._version, out var entry, out var tree);
            TraceMessage($"Completions in {uri} at {@params.position}");

            tree = GetParseTree(entry, uri, CancellationToken, out _) ?? tree;
            var analysis = entry?.Analysis;

            if (analysis == null)
            {
                TraceMessage($"No analysis found for {uri}");
                return(new CompletionList());
            }

            var opts    = GetOptions(@params.context);
            var ctxt    = new CompletionAnalysis(analysis, tree, @params.position, opts, _displayTextBuilder, this);
            var members = ctxt.GetCompletionsFromString(@params._expr) ?? ctxt.GetCompletions();

            if (members == null)
            {
                TraceMessage($"Do not trigger at {@params.position} in {uri}");
                return(new CompletionList());
            }

            if (_settings.SuppressAdvancedMembers)
            {
                members = members.Where(m => !m.label.StartsWith("__"));
            }

            var filterKind = @params.context?._filterKind;

            if (filterKind.HasValue && filterKind != CompletionItemKind.None)
            {
                TraceMessage($"Only returning {filterKind.Value} items");
                members = members.Where(m => m.kind == filterKind.Value);
            }

            var res = new CompletionList {
                items            = members.ToArray(),
                _applicableSpan  = ctxt.Node?.GetSpan(tree),
                _expr            = ctxt.ParentExpression?.ToCodeString(tree, CodeFormattingOptions.Traditional),
                _commitByDefault = ctxt.ShouldCommitByDefault
            };

            LogMessage(MessageType.Info, $"Found {res.items.Length} completions for {uri} at {@params.position} after filtering");
            return(res);
        }
Esempio n. 3
0
 public virtual Task <CompletionList> Completion(CompletionParams @params) => throw new NotImplementedException();
Esempio n. 4
0
        public override Task <CompletionList> Completion(CompletionParams @params)
        {
            var uri = @params.textDocument.uri;
            // Make sure document is enqueued for processing
            var openFile = _openFiles.GetDocument(uri);

            _projectFiles.GetAnalysis(@params.textDocument, @params.position, @params._version, out var entry, out var tree);
            TraceMessage($"Completions in {uri} at {@params.position}");

            tree = GetParseTree(entry, uri, CancellationToken, out var version) ?? tree;
            var analysis = entry?.Analysis;

            if (analysis == null)
            {
                TraceMessage($"No analysis found for {uri}");
                return(Task.FromResult(new CompletionList()));
            }

            var opts = GetOptions(@params.context);
            var ctxt = new CompletionAnalysis(analysis, tree, @params.position, opts, _displayTextBuilder, this,
                                              () => entry.ReadDocument(_projectFiles.GetPart(uri), out _));
            var members = ctxt.GetCompletionsFromString(@params._expr) ?? ctxt.GetCompletions();

            if (members == null)
            {
                TraceMessage($"Do not trigger at {@params.position} in {uri}");
                return(Task.FromResult(new CompletionList()));
            }

            if (_settings.SuppressAdvancedMembers)
            {
                members = members.Where(m => !m.label.StartsWith("__"));
            }

            var filterKind = @params.context?._filterKind;

            if (filterKind.HasValue && filterKind != CompletionItemKind.None)
            {
                TraceMessage($"Only returning {filterKind.Value} items");
                members = members.Where(m => m.kind == filterKind.Value);
            }

            var res = new CompletionList {
                items            = members.ToArray(),
                _expr            = ctxt.ParentExpression?.ToCodeString(tree, CodeFormattingOptions.Traditional),
                _commitByDefault = ctxt.ShouldCommitByDefault
            };

            SourceLocation trigger = @params.position;

            if (ctxt.ApplicableSpan.HasValue)
            {
                res._applicableSpan = ctxt.ApplicableSpan;
            }
            else if (ctxt.Node != null)
            {
                var span = ctxt.Node.GetSpan(tree);
                if (@params.context?.triggerKind == CompletionTriggerKind.TriggerCharacter)
                {
                    if (span.End > trigger)
                    {
                        span = new SourceSpan(span.Start, trigger);
                    }
                }
                if (span.End != span.Start)
                {
                    res._applicableSpan = span;
                }
            }
            else if (@params.context?.triggerKind == CompletionTriggerKind.TriggerCharacter)
            {
                var ch = @params.context?.triggerCharacter.FirstOrDefault() ?? '\0';
                res._applicableSpan = new SourceSpan(
                    trigger.Line,
                    Tokenizer.IsIdentifierStartChar(ch) ? Math.Max(1, trigger.Column - 1) : trigger.Column,
                    trigger.Line,
                    trigger.Column
                    );
            }

            LogMessage(MessageType.Info, $"Found {res.items.Length} completions for {uri} at {@params.position} after filtering");

            var evt = PostProcessCompletion;

            if (evt != null)
            {
                var e = new Extensibility.CompletionEventArgs(analysis, tree, @params.position, res);
                try {
                    evt(this, e);
                    res       = e.CompletionList;
                    res.items = res.items ?? Array.Empty <CompletionItem>();
                    LogMessage(MessageType.Info, $"Found {res.items.Length} completions after hooks");
                } catch (Exception ex) when(!ex.IsCriticalException())
                {
                    // We do not replace res in this case.
                    LogMessage(MessageType.Error, $"Error while post-processing completions: {ex}");
                }
            }

            return(Task.FromResult(res));
        }
Esempio n. 5
0
 public override Task <CompletionList> Completion(CompletionParams @params) => Completion(@params, CancellationToken.None);