private IEnumerable <Reference> GetModuleReferences(IPythonProjectEntry entry, PythonAst tree, BufferVersion version, ReferencesParams @params)
        {
            if ([email protected]?.includeDeclaration == true)
            {
                return(Enumerable.Empty <Reference>());
            }

            var index = tree.LocationToIndex(@params.position);
            var w     = new ImportedModuleNameWalker(entry, index, tree);

            tree.Walk(w);

            if (w.ImportedType != null)
            {
                @params._expr = w.ImportedType.Name;
                return(Enumerable.Empty <Reference>());
            }

            var modulesNamesInRange = w.ImportedModules.Where(m => {
                var start = tree.LocationToIndex(m.SourceSpan.Start);
                var end   = tree.LocationToIndex(m.SourceSpan.End);
                return(start <= index && index < end);
            }).ToArray();

            if (modulesNamesInRange.Length == 0)
            {
                return(Enumerable.Empty <Reference>());
            }

            var refs = new List <Reference>();

            foreach (var n in modulesNamesInRange)
            {
                if (Analyzer.Modules.TryGetImportedModule(n.Name, out var modRef) && modRef.AnalysisModule != null)
                {
                    // Return a module reference
                    refs.AddRange(modRef.AnalysisModule.Locations
                                  .Select(l => new Reference {
                        uri      = l.DocumentUri,
                        range    = l.Span,
                        _version = version?.Version,
                        _kind    = ReferenceKind.Definition
                    })
                                  .ToArray());
                }
            }
            return(refs);
        }
        private IEnumerable <AnalysisValue> GetImportHover(IPythonProjectEntry entry, IModuleAnalysis analysis, PythonAst tree, Position position, out Hover hover)
        {
            hover = null;

            var index = tree.LocationToIndex(position);
            var w     = new ImportedModuleNameWalker(entry, index, tree);

            tree.Walk(w);

            if (w.ImportedType != null)
            {
                return(analysis.GetValues(w.ImportedType.Name, position));
            }

            var sb   = new StringBuilder();
            var span = SourceSpan.Invalid;

            foreach (var n in w.ImportedModules)
            {
                if (Analyzer.Modules.TryGetImportedModule(n.Name, out var modRef) && modRef.AnalysisModule != null)
                {
                    if (sb.Length > 0)
                    {
                        sb.AppendLine();
                        sb.AppendLine();
                    }
                    sb.Append(_displayTextBuilder.GetModuleDocumentation(modRef));
                    span = span.IsValid ? span.Union(n.SourceSpan) : n.SourceSpan;
                }
            }
            if (sb.Length > 0)
            {
                hover = new Hover {
                    contents = sb.ToString(),
                    range    = span
                };
            }
            return(Enumerable.Empty <AnalysisValue>());
        }
示例#3
0
        public override async Task <Hover> Hover(TextDocumentPositionParams @params)
        {
            await _analyzerCreationTask;

            await IfTestWaitForAnalysisCompleteAsync();

            var uri = @params.textDocument.uri;

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

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

            var analysis = entry?.Analysis;

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

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

            var index = tree.LocationToIndex(@params.position);
            var w     = new ImportedModuleNameWalker(entry.ModuleName, index);

            tree.Walk(w);
            if (!string.IsNullOrEmpty(w.ImportedName) &&
                _analyzer.Modules.TryImport(w.ImportedName, out var modRef))
            {
                var doc = _displayTextBuilder.GetModuleDocumentation(modRef);
                return(new Hover {
                    contents = doc
                });
            }

            Expression expr;
            SourceSpan?exprSpan;

            Analyzer.InterpreterScope scope = null;

            var finder = new ExpressionFinder(tree, GetExpressionOptions.Hover);

            expr     = finder.GetExpression(@params.position) as Expression;
            exprSpan = expr?.GetSpan(tree);

            if (expr == null)
            {
                TraceMessage($"No hover info found in {uri} at {@params.position}");
                return(EmptyHover);
            }

            TraceMessage($"Getting hover for {expr.ToCodeString(tree, CodeFormattingOptions.Traditional)}");
            var values = analysis.GetValues(expr, @params.position, scope).ToList();

            string originalExpr;

            if (expr is ConstantExpression || expr is ErrorExpression)
            {
                originalExpr = null;
            }
            else
            {
                originalExpr = @params._expr?.Trim();
                if (string.IsNullOrEmpty(originalExpr))
                {
                    originalExpr = expr.ToCodeString(tree, CodeFormattingOptions.Traditional);
                }
            }

            var names = values.Select(GetFullTypeName).Where(n => !string.IsNullOrEmpty(n)).Distinct().ToArray();

            var res = new Hover {
                contents = GetMarkupContent(
                    _displayTextBuilder.GetDocumentation(values, originalExpr),
                    _clientCaps.textDocument?.hover?.contentFormat),
                range      = exprSpan,
                _version   = version,
                _typeNames = names
            };

            return(res);
        }
示例#4
0
        internal async Task <Reference[]> FindReferences(ReferencesParams @params, CancellationToken cancellationToken)
        {
            var uri = @params.textDocument.uri;

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

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

            var analysis = entry != null ? await entry.GetAnalysisAsync(50, cancellationToken) : null;

            if (analysis == null)
            {
                TraceMessage($"No analysis found for {uri}");
                return(Array.Empty <Reference>());
            }

            tree = GetParseTree(entry, uri, cancellationToken, out var version);
            var extras = new List <Reference>();

            if (@params.context?.includeDeclaration ?? false)
            {
                var index = tree.LocationToIndex(@params.position);
                var w     = new ImportedModuleNameWalker(entry, index, tree);
                tree.Walk(w);

                if (w.ImportedType != null)
                {
                    @params._expr = w.ImportedType.Name;
                }
                else
                {
                    foreach (var n in w.ImportedModules)
                    {
                        if (Analyzer.Modules.TryGetImportedModule(n.Name, out var modRef) && modRef.AnalysisModule != null)
                        {
                            // Return a module reference
                            extras.AddRange(modRef.AnalysisModule.Locations
                                            .Select(l => new Reference {
                                uri      = l.DocumentUri,
                                range    = l.Span,
                                _version = version?.Version,
                                _kind    = ReferenceKind.Definition
                            })
                                            .ToArray());
                        }
                    }
                }
            }

            IEnumerable <IAnalysisVariable> result;

            if (!string.IsNullOrEmpty(@params._expr))
            {
                TraceMessage($"Getting references for {@params._expr}");
                result = analysis.GetVariables(@params._expr, @params.position);
            }
            else
            {
                var finder = new ExpressionFinder(tree, GetExpressionOptions.FindDefinition);
                if (finder.GetExpression(@params.position) is Expression expr)
                {
                    TraceMessage($"Getting references for {expr.ToCodeString(tree, CodeFormattingOptions.Traditional)}");
                    result = analysis.GetVariables(expr, @params.position);
                }
                else
                {
                    TraceMessage($"No references found in {uri} at {@params.position}");
                    result = Enumerable.Empty <IAnalysisVariable>();
                }
            }

            var filtered = result.Where(v => v.Type != VariableType.None);

            if (!(@params.context?.includeDeclaration ?? false))
            {
                filtered = filtered.Where(v => v.Type != VariableType.Definition);
            }
            if (!(@params.context?._includeValues ?? false))
            {
                filtered = filtered.Where(v => v.Type != VariableType.Value);
            }

            var res = filtered.Select(v => new Reference {
                uri      = v.Location.DocumentUri,
                range    = v.Location.Span,
                _kind    = ToReferenceKind(v.Type),
                _version = version?.Version
            })
                      .Concat(extras)
                      .GroupBy(r => r, ReferenceComparer.Instance)
                      .Select(g => g.OrderByDescending(r => (SourceLocation)r.range.end).ThenBy(r => (int?)r._kind ?? int.MaxValue).First())
                      .ToArray();

            return(res);
        }
示例#5
0
        internal Task <Hover> Hover(TextDocumentPositionParams @params, CancellationToken cancellationToken)
        {
            var uri = @params.textDocument.uri;

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

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

            var analysis = entry?.Analysis;

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

            tree = GetParseTree(entry, uri, cancellationToken, out var version) ?? tree;

            Expression expr;
            SourceSpan?exprSpan;

            Analyzer.InterpreterScope scope = null;

            var finder = new ExpressionFinder(tree, GetExpressionOptions.Hover);

            expr     = finder.GetExpression(@params.position) as Expression;
            exprSpan = expr?.GetSpan(tree);

            if (expr == null)
            {
                TraceMessage($"No hover info found in {uri} at {@params.position}");
                return(Task.FromResult(EmptyHover));
            }

            TraceMessage($"Getting hover for {expr.ToCodeString(tree, CodeFormattingOptions.Traditional)}");

            // First try values from expression. This works for the import statement most of the time.
            var values = analysis.GetValues(expr, @params.position, scope).ToList();

            if (values.Count == 0)
            {
                // See if this is hover over import statement
                var index = tree.LocationToIndex(@params.position);
                var w     = new ImportedModuleNameWalker(entry, index, tree);
                tree.Walk(w);

                if (w.ImportedType != null)
                {
                    values = analysis.GetValues(w.ImportedType.Name, @params.position).ToList();
                }
                else
                {
                    var sb   = new StringBuilder();
                    var span = SourceSpan.Invalid;
                    foreach (var n in w.ImportedModules)
                    {
                        if (Analyzer.Modules.TryGetImportedModule(n.Name, out var modRef) && modRef.AnalysisModule != null)
                        {
                            if (sb.Length > 0)
                            {
                                sb.AppendLine();
                                sb.AppendLine();
                            }
                            sb.Append(_displayTextBuilder.GetModuleDocumentation(modRef));
                            span = span.IsValid ? span.Union(n.SourceSpan) : n.SourceSpan;
                        }
                    }
                    if (sb.Length > 0)
                    {
                        return(Task.FromResult(new Hover {
                            contents = sb.ToString(),
                            range = span
                        }));
                    }
                }
            }

            if (values.Count > 0)
            {
                string originalExpr;
                if (expr is ConstantExpression || expr is ErrorExpression)
                {
                    originalExpr = null;
                }
                else
                {
                    originalExpr = @params._expr?.Trim();
                    if (string.IsNullOrEmpty(originalExpr))
                    {
                        originalExpr = expr.ToCodeString(tree, CodeFormattingOptions.Traditional);
                    }
                }

                var names = values.Select(GetFullTypeName).Where(n => !string.IsNullOrEmpty(n)).Distinct().ToArray();
                var res   = new Hover {
                    contents = GetMarkupContent(
                        _displayTextBuilder.GetDocumentation(values, originalExpr),
                        _clientCaps.textDocument?.hover?.contentFormat),
                    range      = exprSpan,
                    _version   = version?.Version,
                    _typeNames = names
                };
                return(Task.FromResult(res));
            }

            return(Task.FromResult(EmptyHover));
        }