private ILocatedMember GetRootDefinition(ILocatedMember lm)
 {
     for (; lm.Parent != null; lm = lm.Parent)
     {
     }
     return(lm);
 }
        private async Task <Reference[]> FindAllReferencesAsync(string name, ILocatedMember rootDefinition, CancellationToken cancellationToken)
        {
            var candidateFiles = ScanClosedFiles(name, cancellationToken);

            await AnalyzeFiles(candidateFiles, cancellationToken);

            return(rootDefinition.References
                   .Select(r => new Reference {
                uri = new Uri(r.FilePath), range = r.Span
            })
                   .ToArray());
        }
Esempio n. 3
0
        public static ILocatedMember GetRootDefinition(this ILocatedMember lm)
        {
            if (!(lm is IImportedMember im) || im.Parent == null)
            {
                return(lm);
            }

            var parent = im.Parent;

            for (; parent != null;)
            {
                if (!(parent is IImportedMember im1) || im1.Parent == null)
                {
                    break;
                }
                parent = im1.Parent;
            }
            return(parent);
        }
        public IEnumerable <IReferenceable> GetDefinitions(string name, IMemberContainer innerContainer, IModuleContext context)
        {
            IEnumerable <IReferenceable> refs = null;
            ReferenceDict references;

            if (_references != null && _references.TryGetValue(name, out references))
            {
                refs = references.Values;
            }

            var member = innerContainer.GetMember(context, name);

            if (member != null)
            {
                List <IReferenceable> res;
                if (refs == null)
                {
                    res = new List <IReferenceable>();
                }
                else
                {
                    res = new List <IReferenceable>(refs);
                }

                ILocatedMember locatedMember = member as ILocatedMember;
                if (locatedMember != null)
                {
                    foreach (var location in locatedMember.Locations)
                    {
                        res.Add(new DefinitionList(location));
                    }
                }
                return(res);
            }

            return(new IReferenceable[0]);
        }
        /// <summary>
        /// Locates definition or declaration of a symbol at the provided location.
        /// </summary>
        /// <param name="analysis">Document analysis.</param>
        /// <param name="location">Location in the document.</param>
        /// <param name="definingMember">Member location or null of not found.</param>
        /// <returns>Definition location (module URI and the text range).</returns>
        public Reference FindDefinition(IDocumentAnalysis analysis, SourceLocation location, out ILocatedMember definingMember)
        {
            definingMember = null;
            if (analysis?.Ast == null)
            {
                return(null);
            }

            ExpressionLocator.FindExpression(analysis.Ast, location,
                                             FindExpressionOptions.Hover, out var exprNode, out var statement, out var exprScope);

            if (exprNode is ConstantExpression || !(exprNode is Expression expr))
            {
                return(null); // No goto definition for literals.
            }

            Reference reference = null;

            switch (statement)
            {
            // Check if this is a relative import
            case FromImportStatement fromImport:
                reference = HandleFromImport(analysis, location, fromImport, exprNode, out definingMember);
                break;

            case ImportStatement import:
                reference = HandleImport(analysis, import, exprNode, out definingMember);
                break;
            }

            if (reference != null)
            {
                return(reference.uri == null ? null : reference);
            }

            var eval = analysis.ExpressionEvaluator;

            using (eval.OpenScope(analysis.Document, exprScope)) {
                if (expr is MemberExpression mex)
                {
                    return(FromMemberExpression(mex, analysis, out definingMember));
                }

                // Try variables
                var name = (expr as NameExpression)?.Name;
                if (!string.IsNullOrEmpty(name))
                {
                    reference = TryFromVariable(name, analysis, location, statement, out definingMember);
                }
            }

            return(reference);
        }
        private Reference HandleFromImport(IDocumentAnalysis analysis, SourceLocation location, FromImportStatement statement, Node expr, out ILocatedMember definingMember)
        {
            definingMember = null;

            var           mres    = analysis.Document.Interpreter.ModuleResolution;
            var           imports = mres.CurrentPathResolver.FindImports(analysis.Document.FilePath, statement);
            IPythonModule module  = null;

            switch (imports)
            {
            case ModuleImport moduleImport:
                module = mres.GetImportedModule(moduleImport.FullName);
                break;

            case ImplicitPackageImport packageImport:
                module = mres.GetImportedModule(packageImport.FullName);
                break;

            case ImportNotFound _:
                return(null);
            }

            // Are we in the module name (i.e. A in 'from A import B')?
            var locationIndex = location.ToIndex(analysis.Ast);

            if (statement.Root.StartIndex <= locationIndex && locationIndex <= statement.Root.EndIndex)
            {
                definingMember = module;
                return(module != null
                    ? new Reference {
                    range = default, uri = CanNavigateToModule(module) ? module.Uri : null
        private async Task <Reference[]> FindAllReferencesAsync(string name, IPythonModule declaringModule, ILocatedMember rootDefinition, SourceLocation location, DefinitionSource definitionSource,
                                                                CancellationToken cancellationToken)
        {
            var candidateFiles       = ScanClosedFiles(name, cancellationToken);
            var reloadRootDefinition = false;

            if (candidateFiles.Count > 0)
            {
                reloadRootDefinition = await AnalyzeFiles(declaringModule.Interpreter.ModuleResolution, candidateFiles, cancellationToken);
            }

            if (reloadRootDefinition)
            {
                var analysis = await Document.GetAnalysisAsync(declaringModule.Uri, _services, FindReferencesAnalysisTimeout, cancellationToken);

                var definition = definitionSource.FindDefinition(analysis, location, out var definingMember);
                if (definition == null)
                {
                    return(Array.Empty <Reference>());
                }

                rootDefinition = definingMember.GetRootDefinition();
            }

            return(rootDefinition.References
                   .Select(r => new Reference {
                uri = r.DocumentUri, range = r.Span
            })
                   .ToArray());
        }
        private Reference TryFromVariable(string name, IDocumentAnalysis analysis, SourceLocation location, Node statement, out ILocatedMember member)
        {
            member = null;

            var m = analysis.ExpressionEvaluator.LookupNameInScopes(name, out var scope);

            if (m != null && scope.Variables[name] is IVariable v)
            {
                member = v;
                var definition = v.Definition;
                if (statement is ImportStatement || statement is FromImportStatement)
                {
                    // If we are on the variable definition in this module,
                    // then goto definition should go to the parent, if any.
                    var indexSpan = v.Definition.Span.ToIndexSpan(analysis.Ast);
                    var index     = location.ToIndex(analysis.Ast);
                    if (indexSpan.Start <= index && index < indexSpan.End)
                    {
                        if (v.Parent == null)
                        {
                            return(null);
                        }
                        definition = v.Parent.Definition;
                    }
                }

                if (CanNavigateToModule(definition.DocumentUri))
                {
                    return(new Reference {
                        range = definition.Span, uri = definition.DocumentUri
                    });
                }
            }
            return(null);
        }
        public Reference FindDefinition(IDocumentAnalysis analysis, SourceLocation location, out ILocatedMember member)
        {
            member = null;
            if (analysis?.Ast == null)
            {
                return(null);
            }

            ExpressionLocator.FindExpression(analysis.Ast, location,
                                             FindExpressionOptions.Hover, out var exprNode, out var statement, out var exprScope);

            if (exprNode is ConstantExpression || !(exprNode is Expression expr))
            {
                return(null); // No hover for literals.
            }

            var eval = analysis.ExpressionEvaluator;

            using (eval.OpenScope(analysis.Document, exprScope)) {
                if (expr is MemberExpression mex)
                {
                    return(FromMemberExpression(mex, analysis, out member));
                }

                // Try variables
                var     name  = (expr as NameExpression)?.Name;
                IMember value = null;
                if (!string.IsNullOrEmpty(name))
                {
                    var reference = TryFromVariable(name, analysis, location, statement, out member);
                    if (reference != null)
                    {
                        return(reference);
                    }

                    if (statement is ImportStatement || statement is FromImportStatement)
                    {
                        reference = TryFromImport(statement, name, analysis, out value);
                        if (reference != null)
                        {
                            member = value as ILocatedMember;
                            return(reference);
                        }
                    }
                }

                value = value ?? eval.GetValueFromExpression(expr);
                if (value.IsUnknown())
                {
                    return(null);
                }
                member = value as ILocatedMember;
                return(FromMember(value));
            }
        }
        private Reference FromMemberExpression(MemberExpression mex, IDocumentAnalysis analysis, out ILocatedMember member)
        {
            member = null;

            var eval   = analysis.ExpressionEvaluator;
            var target = eval.GetValueFromExpression(mex.Target);
            var type   = target?.GetPythonType();

            if (type?.GetMember(mex.Name) is ILocatedMember lm)
            {
                member = lm;
                return(FromMember(lm));
            }

            if (type is IPythonClassType cls)
            {
                // Data members may be instances that are not tracking locations.
                // In this case we'll try look up the respective variable instead.
                using (eval.OpenScope(analysis.Document, cls.ClassDefinition)) {
                    eval.LookupNameInScopes(mex.Name, out _, out var v, LookupOptions.Local);
                    if (v != null)
                    {
                        member = v;
                        return(FromMember(v));
                    }
                }
            }
            return(null);
        }
Esempio n. 11
0
        private Reference FromMemberExpression(MemberExpression mex, IDocumentAnalysis analysis, out ILocatedMember member)
        {
            member = null;

            var eval   = analysis.ExpressionEvaluator;
            var target = eval.GetValueFromExpression(mex.Target);
            var type   = target?.GetPythonType();

            switch (type)
            {
            case IPythonModule m when m.Analysis.GlobalScope != null:
                // Module GetMember returns module variable value while we
                // want the variable itself since we want to know its location.
                var v1 = m.Analysis.GlobalScope.Variables[mex.Name];
                if (v1 != null)
                {
                    member = v1;
                    return(FromMember(v1));
                }
                break;

            case IPythonClassType cls:
                // Data members may be instances that are not tracking locations.
                // In this case we'll try look up the respective variable instead.
                using (eval.OpenScope(analysis.Document, cls.ClassDefinition)) {
                    eval.LookupNameInScopes(mex.Name, out _, out var v2, LookupOptions.Local);
                    if (v2 != null)
                    {
                        member = v2;
                        return(FromMember(v2));
                    }
                }
                break;

            default:
                if (type?.GetMember(mex.Name) is ILocatedMember lm)
                {
                    member = lm;
                    return(FromMember(lm));
                }

                break;
            }
            return(null);
        }