public override bool Walk(AssignmentStatement node)
        {
            var value = Eval.GetValueFromExpression(node.Right) ?? Eval.UnknownType;

            foreach (var lhs in node.Left)
            {
                switch (lhs)
                {
                case MemberExpression memberExp when memberExp.Target is NameExpression nameExp1:
                    if (_function.DeclaringType.GetPythonType() is PythonClassType t && nameExp1.Name == "self")
                    {
                        t.AddMembers(new[] { new KeyValuePair <string, IMember>(memberExp.Name, value) }, false);
                    }
                    continue;

                case NameExpression nameExp2 when nameExp2.Name == "self":
                    // Only assign to 'self' if it is not declared yet.
                    if (Eval.LookupNameInScopes(nameExp2.Name, out _) == null)
                    {
                        Eval.DeclareVariable(nameExp2.Name, value, VariableSource.Declaration);
                    }
                    return(true);
                }
            }
            return(base.Walk(node));
        }
示例#2
0
        private void HandleNameExpression(NameExpression ne, IMember value)
        {
            IScope scope;

            if (Eval.CurrentScope.NonLocals[ne.Name] != null)
            {
                Eval.LookupNameInScopes(ne.Name, out scope, LookupOptions.Nonlocal);
                scope?.Variables[ne.Name].Assign(value, Eval.GetLocationOfName(ne));
                return;
            }

            if (Eval.CurrentScope.Globals[ne.Name] != null)
            {
                Eval.LookupNameInScopes(ne.Name, out scope, LookupOptions.Global);
                scope?.Variables[ne.Name].Assign(value, Eval.GetLocationOfName(ne));
                return;
            }

            var source   = value.IsGeneric() ? VariableSource.Generic : VariableSource.Declaration;
            var location = Eval.GetLocationOfName(ne);

            if (IsValidAssignment(ne.Name, location))
            {
                Eval.DeclareVariable(ne.Name, value ?? Module.Interpreter.UnknownType, source, location);
            }
        }
 public override bool Walk(NonlocalStatement node)
 {
     foreach (var nex in node.Names)
     {
         var m = Eval.LookupNameInScopes(nex.Name, out _, LookupOptions.Nonlocal);
         if (m == null)
         {
             ReportUndefinedVariable(nex);
         }
     }
     return(false);
 }
 private void HandleGlobal(GlobalStatement node)
 {
     foreach (var nex in node.Names)
     {
         var m = Eval.LookupNameInScopes(nex.Name, out _, LookupOptions.Global);
         if (m == null)
         {
             _diagnostics.Add(new DiagnosticsEntry(
                                  Resources.ErrorVariableNotDefinedGlobally.FormatInvariant(nex.Name),
                                  Eval.GetLocation(nex).Span, ErrorCodes.VariableNotDefinedGlobally, Severity.Warning, DiagnosticSource.Linter));
         }
     }
 }
示例#5
0
        private void ExtendAll(Node location, IPythonCollection values)
        {
            Eval.LookupNameInScopes(AllVariableName, out var scope, LookupOptions.Global);
            if (scope == null)
            {
                return;
            }

            var all    = scope.Variables[AllVariableName]?.Value as IPythonCollection;
            var list   = PythonCollectionType.CreateConcatenatedList(Module.Interpreter, all, values);
            var source = list.IsGeneric() ? VariableSource.Generic : VariableSource.Declaration;

            Eval.DeclareVariable(AllVariableName, list, source, location);
        }
示例#6
0
 private void TryHandleClassVariable(MemberExpression mex, IMember value)
 {
     if (mex.Target is NameExpression nex && nex.Name == "self")
     {
         var m   = Eval.LookupNameInScopes(nex.Name, out _, LookupOptions.Local);
         var cls = m.GetPythonType <IPythonClassType>();
         if (cls != null)
         {
             using (Eval.OpenScope(Eval.Module, cls.ClassDefinition, out _)) {
                 Eval.DeclareVariable(mex.Name, value, VariableSource.Declaration, Eval.GetLocationOfName(mex));
             }
         }
     }
 }
        public async Task HandleAnnotatedExpressionAsync(ExpressionWithAnnotation expr, IMember value, CancellationToken cancellationToken = default)
        {
            if (expr?.Annotation == null)
            {
                return;
            }

            var variableType = await Eval.GetTypeFromAnnotationAsync(expr.Annotation, cancellationToken);

            // If value is null, then this is a pure declaration like
            //   x: List[str]
            // without a value. If value is provided, then this is
            //   x: List[str] = [...]

            // Check value type for compatibility
            IMember instance = null;

            if (value != null)
            {
                var valueType = value.GetPythonType();
                if (!variableType.IsUnknown() && !valueType.Equals(variableType))
                {
                    // TODO: warn incompatible value type.
                    // TODO: verify values. Value may be list() while variable type is List[str].
                    // Leave it as variable type.
                }
                else
                {
                    instance = value;
                }
            }
            instance = instance ?? variableType?.CreateInstance(variableType.Name, Eval.GetLoc(expr.Expression), ArgumentSet.Empty) ?? Eval.UnknownType;

            if (expr.Expression is NameExpression ne)
            {
                Eval.DeclareVariable(ne.Name, instance, expr.Expression);
                return;
            }

            if (expr.Expression is MemberExpression m)
            {
                // self.x : int = 42
                var self    = Eval.LookupNameInScopes("self", out var scope);
                var argType = self?.GetPythonType();
                if (argType is PythonClassType cls && scope != null)
                {
                    cls.AddMember(m.Name, instance, true);
                }
            }
        }
 public bool HandleGlobal(GlobalStatement node)
 {
     foreach (var nex in node.Names)
     {
         var m = Eval.LookupNameInScopes(nex.Name, out _, out var v, LookupOptions.Global);
         if (m != null)
         {
             var location = Eval.GetLocationOfName(nex);
             Eval.CurrentScope.DeclareGlobal(nex.Name, location);
             v?.AddReference(location);
         }
     }
     return(false);
 }
        private void TryHandleClassVariable(AssignmentStatement node, IMember value)
        {
            var mex = node.Left.OfType <MemberExpression>().FirstOrDefault();

            if (!string.IsNullOrEmpty(mex?.Name) && mex.Target is NameExpression nex && nex.Name.EqualsOrdinal("self"))
            {
                var m   = Eval.LookupNameInScopes(nex.Name, out _, LookupOptions.Local);
                var cls = m.GetPythonType <IPythonClassType>();
                if (cls != null)
                {
                    using (Eval.OpenScope(Eval.Module, cls.ClassDefinition, out _)) {
                        Eval.DeclareVariable(mex.Name, value, VariableSource.Declaration, Eval.GetLocationOfName(mex));
                    }
                }
            }
        }
示例#10
0
        private void ExtendAll(Node declNode, IReadOnlyList <IMember> values)
        {
            Eval.LookupNameInScopes(AllVariableName, out var scope, LookupOptions.Normal);
            if (scope == null)
            {
                return;
            }

            var loc = Eval.GetLoc(declNode);

            var allContents = (scope.Variables[AllVariableName].Value as IPythonCollection)?.Contents;

            var list   = PythonCollectionType.CreateConcatenatedList(Module.Interpreter, loc, allContents, values);
            var source = list.IsGeneric() ? VariableSource.Generic : VariableSource.Declaration;

            Eval.DeclareVariable(AllVariableName, list, source, loc);
        }
示例#11
0
        private void HandleTypedVariable(IPythonType variableType, IMember value, Expression expr)
        {
            // Check value type for compatibility
            IMember instance = null;

            if (value != null)
            {
                var valueType = value.GetPythonType();
                if (!variableType.IsUnknown() && !valueType.Equals(variableType))
                {
                    // TODO: warn incompatible value type.
                    // TODO: verify values. Value may be list() while variable type is List[str].
                    // Leave it as variable type.
                }
                else
                {
                    instance = value;
                }
            }
            var args = ArgumentSet.Empty(expr, Eval);

            instance = instance ?? variableType?.CreateInstance(args) ?? Eval.UnknownType.CreateInstance(ArgumentSet.WithoutContext);

            if (expr is NameExpression ne)
            {
                Eval.DeclareVariable(ne.Name, instance, VariableSource.Declaration, ne);
                return;
            }

            if (expr is MemberExpression m)
            {
                // self.x : int = 42
                var self    = Eval.LookupNameInScopes("self", out var scope);
                var argType = self?.GetPythonType();
                if (argType is PythonClassType cls && scope != null)
                {
                    cls.AddMember(m.Name, instance, true);
                }
            }
        }
        public void HandleAssignment(AssignmentStatement node)
        {
            if (node.Right is ErrorExpression)
            {
                return;
            }

            var value = Eval.GetValueFromExpression(node.Right) ?? Eval.UnknownType;
            // Check PEP hint first
            var valueType = Eval.GetTypeFromPepHint(node.Right);

            if (valueType != null)
            {
                HandleTypedVariable(valueType, value, node.Left.FirstOrDefault());
                return;
            }

            if (value.IsUnknown())
            {
                Log?.Log(TraceEventType.Verbose, $"Undefined value: {node.Right.ToCodeString(Ast).Trim()}");
            }
            if (value?.GetPythonType().TypeId == BuiltinTypeId.Ellipsis)
            {
                value = Eval.UnknownType;
            }

            if (node.Left.FirstOrDefault() is SequenceExpression seq)
            {
                // Tuple = Tuple. Transfer values.
                var seqHandler = new SequenceExpressionHandler(Walker);
                seqHandler.HandleAssignment(seq.Items, node.Right, value);
                return;
            }

            // Process annotations, if any.
            foreach (var expr in node.Left.OfType <ExpressionWithAnnotation>())
            {
                // x: List[str] = [...]
                HandleAnnotatedExpression(expr, value);
            }

            foreach (var ne in node.Left.OfType <NameExpression>())
            {
                if (Eval.CurrentScope.NonLocals[ne.Name] != null)
                {
                    Eval.LookupNameInScopes(ne.Name, out var scope, LookupOptions.Nonlocal);
                    scope?.Variables[ne.Name].Assign(value, Eval.GetLocationOfName(ne));
                    continue;
                }

                if (Eval.CurrentScope.Globals[ne.Name] != null)
                {
                    Eval.LookupNameInScopes(ne.Name, out var scope, LookupOptions.Global);
                    scope?.Variables[ne.Name].Assign(value, Eval.GetLocationOfName(ne));
                    continue;
                }

                var source   = value.IsGeneric() ? VariableSource.Generic : VariableSource.Declaration;
                var location = Eval.GetLocationOfName(ne);
                if (IsValidAssignment(ne.Name, location))
                {
                    Eval.DeclareVariable(ne.Name, value ?? Module.Interpreter.UnknownType, source, location);
                }
            }

            TryHandleClassVariable(node, value);
        }
        public async Task HandleAssignmentAsync(AssignmentStatement node, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var value = await Eval.GetValueFromExpressionAsync(node.Right, cancellationToken);

            if (value.IsUnknown())
            {
                Log?.Log(TraceEventType.Verbose, $"Undefined value: {node.Right.ToCodeString(Ast).Trim()}");
            }

            if (value?.GetPythonType().TypeId == BuiltinTypeId.Ellipsis)
            {
                value = Eval.UnknownType;
            }

            if (node.Left.FirstOrDefault() is TupleExpression lhs)
            {
                // Tuple = Tuple. Transfer values.
                var texHandler = new TupleExpressionHandler(Walker);
                await texHandler.HandleTupleAssignmentAsync(lhs, node.Right, value, cancellationToken);

                return;
            }
            foreach (var expr in node.Left.OfType <ExpressionWithAnnotation>())
            {
                // x: List[str] = [...]
                await HandleAnnotatedExpressionAsync(expr, value, cancellationToken);
            }

            foreach (var ne in node.Left.OfType <NameExpression>())
            {
                if (Eval.CurrentScope.NonLocals[ne.Name] != null)
                {
                    Eval.LookupNameInScopes(ne.Name, out var scope, LookupOptions.Nonlocal);
                    if (scope != null)
                    {
                        scope.Variables[ne.Name].Value = value;
                    }
                    else
                    {
                        // TODO: report variable is not declared in outer scopes.
                    }
                    continue;
                }

                if (Eval.CurrentScope.Globals[ne.Name] != null)
                {
                    Eval.LookupNameInScopes(ne.Name, out var scope, LookupOptions.Global);
                    if (scope != null)
                    {
                        scope.Variables[ne.Name].Value = value;
                    }
                    else
                    {
                        // TODO: report variable is not declared in global scope.
                    }
                    continue;
                }

                Eval.DeclareVariable(ne.Name, value, Eval.GetLoc(ne));
            }
        }