public override bool Walk(NameExpression node)
        {
            if (_localNames?.Contains(node.Name) == true)
            {
                return(false);
            }
            if (_localNameExpressions?.Contains(node) == true)
            {
                return(false);
            }

            var analysis = _walker.Analysis;
            var m        = analysis.ExpressionEvaluator.LookupNameInScopes(node.Name, out var variableDefinitionScope, out var v, LookupOptions.All);

            if (m == null)
            {
                _walker.ReportUndefinedVariable(node);
            }
            v?.AddReference(new Location(analysis.Document, node.IndexSpan));

            // Make sure we have definition and the document matches
            if (v?.Definition == null || v.Definition.DocumentUri != analysis.Document.Uri)
            {
                return(false);
            }
            // Do not complain about functions and classes that appear later in the file
            if (v.Value is IPythonFunctionType || v.Value is IPythonClassType)
            {
                return(false);
            }

            // Take into account where variable is defined so we do detect
            // undefined x in
            //    y = x
            //    x = 1
            var variableDefinitionSpan = v.Definition.Span;
            var nameUseLocation        = node.GetLocation(analysis);

            // Make sure we are in the same scope in order to avoid
            //    def func():
            //      y = x
            //
            //    x = 1
            var nameUseScope = analysis.ExpressionEvaluator.GlobalScope.FindScope(analysis.Document, nameUseLocation.Span.Start);

            if (nameUseScope.IsNestedInScope(variableDefinitionScope))
            {
                return(false);
            }

            // Exclude same-name variables declared within the same statement
            // like 'e' that appears before its declaration in '[e in for e in {}]'
            if (variableDefinitionSpan.IsAfter(nameUseLocation.Span) && !IsSpanInComprehension(nameUseLocation.Span))
            {
                _walker.ReportUndefinedVariable(node);
            }
            return(false);
        }
Beispiel #2
0
        public override bool Walk(NameExpression node)
        {
            if (_localNames?.Contains(node.Name) == true)
            {
                return(false);
            }
            if (_localNameExpressions?.Contains(node) == true)
            {
                return(false);
            }

            var analysis = _walker.Analysis;
            var m        = analysis.ExpressionEvaluator.LookupNameInScopes(node.Name, out _, out var v);

            if (m == null)
            {
                _walker.ReportUndefinedVariable(node);
            }
            v?.AddReference(new Location(analysis.Document, node.IndexSpan));

            // Take into account where variable is defined so we do detect
            // undefined x in
            //    y = x
            //    x = 1
            if (v?.Definition != null && v.Definition.DocumentUri == analysis.Document.Uri)
            {
                // Do not complain about functions and classes that appear later in the file
                if (!(v.Value is IPythonFunctionType || v.Value is IPythonClassType))
                {
                    var span    = v.Definition.Span;
                    var nodeLoc = node.GetLocation(analysis.Document);
                    // Exclude same-name variables declared within the same statement
                    // like 'e' that appears before its declaration in '[e in for e in {}]'
                    if (span.IsAfter(nodeLoc.Span) && !IsSpanInComprehension(nodeLoc.Span))
                    {
                        _walker.ReportUndefinedVariable(node);
                    }
                }
            }
            return(false);
        }