Example #1
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs)
        {
            SequenceInfo seq = null;
            VariableDef  idx = null;
            var          res = AnalysisSet.Empty;

            switch (operation)
            {
            case PythonOperator.Add:
                foreach (var type in rhs.Where(t => !t.IsOfType(ClassInfo)))
                {
                    res = res.Union(CallReverseBinaryOp(node, unit, operation, rhs));
                }

                foreach (var type in rhs.Where(t => t.IsOfType(ClassInfo)))
                {
                    if (seq == null)
                    {
                        seq = (SequenceInfo)unit.Scope.GetOrMakeNodeValue(node,
                                                                          NodeValueKind.Sequence,
                                                                          _ => new SequenceInfo(new[] { new VariableDef() }, ClassInfo, node, unit.ProjectEntry)
                                                                          );
                        idx = seq.IndexTypes[0];
                        idx.AddTypes(unit, GetEnumeratorTypes(node, unit), true, DeclaringModule);
                    }
                    idx.AddTypes(unit, type.GetEnumeratorTypes(node, unit), true, DeclaringModule);
                    idx.MakeUnionStrongerIfMoreThan(ProjectState.Limits.IndexTypes);
                }

                if (seq != null)
                {
                    res = res.Union(seq);
                }
                break;

            case PythonOperator.Multiply:
                foreach (var type in rhs)
                {
                    var typeId = type.TypeId;

                    if (typeId == BuiltinTypeId.Int || typeId == BuiltinTypeId.Long)
                    {
                        res = res.Union(this);
                    }
                    else
                    {
                        res = res.Union(CallReverseBinaryOp(node, unit, operation, type));
                    }
                }
                break;

            default:
                res = CallReverseBinaryOp(node, unit, operation, rhs);
                break;
            }
            return(res);
        }
Example #2
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs)
        {
            IAnalysisSet res;

            switch (operation)
            {
            case PythonOperator.BitwiseOr:
                var seq = (SetInfo)unit.Scope.GetOrMakeNodeValue(
                    node,
                    _ => new SetInfo(ProjectState, node, unit.ProjectEntry)
                    );
                seq.AddTypes(unit, GetEnumeratorTypes(node, unit));
                foreach (var type in rhs.Where(t => t.IsOfType(ClassInfo)))
                {
                    seq.AddTypes(unit, type.GetEnumeratorTypes(node, unit));
                }
                res = seq;
                break;

            case PythonOperator.BitwiseAnd:
            case PythonOperator.ExclusiveOr:
            case PythonOperator.Subtract:
                res = this;
                break;

            default:
                res = CallReverseBinaryOp(node, unit, operation, rhs);
                break;
            }

            return(res);
        }
Example #3
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
            IAnalysisSet res;

            switch (operation) {
                case PythonOperator.BitwiseOr:
                    var seq = (SetInfo)unit.Scope.GetOrMakeNodeValue(
                        node,
                        _ => new SetInfo(ProjectState, node, unit.ProjectEntry)
                    );
                    seq.AddTypes(unit, GetEnumeratorTypes(node, unit));
                    foreach (var type in rhs.Where(t => t.IsOfType(ClassInfo))) {
                        seq.AddTypes(unit, type.GetEnumeratorTypes(node, unit));
                    }
                    res = seq;
                    break;
                case PythonOperator.BitwiseAnd:
                case PythonOperator.ExclusiveOr:
                case PythonOperator.Subtract:
                    res = this;
                    break;
                default:
                    res = CallReverseBinaryOp(node, unit, operation, rhs);
                    break;
            }

            return res;
        }
Example #4
0
        public override IAnalysisSet BinaryOperation(Node node, AnalysisUnit unit, PythonOperator operation, IAnalysisSet rhs) {
            SequenceInfo seq = null;
            VariableDef idx = null;
            var res = AnalysisSet.Empty;
            switch (operation) {
                case PythonOperator.Add:
                    foreach (var type in rhs.Where(t => !t.IsOfType(ClassInfo))) {
                        res = res.Union(CallReverseBinaryOp(node, unit, operation, rhs));
                    }
                    
                    foreach (var type in rhs.Where(t => t.IsOfType(ClassInfo))) {
                        if (seq == null) {
                            seq = (SequenceInfo)unit.Scope.GetOrMakeNodeValue(node,
                                NodeValueKind.Sequence,
                                _ => new SequenceInfo(new[] { new VariableDef() }, ClassInfo, node, unit.ProjectEntry)
                            );
                            idx = seq.IndexTypes[0];
                            idx.AddTypes(unit, GetEnumeratorTypes(node, unit), true, DeclaringModule);
                        }
                        idx.AddTypes(unit, type.GetEnumeratorTypes(node, unit), true, DeclaringModule);
                    }

                    if (seq != null) {
                        res = res.Union(seq);
                    }
                    break;
                case PythonOperator.Multiply:
                    foreach (var type in rhs) {
                        var typeId = type.TypeId;

                        if (typeId == BuiltinTypeId.Int || typeId == BuiltinTypeId.Long) {
                            res = res.Union(this);
                        } else {
                            res = res.Union(CallReverseBinaryOp(node, unit, operation, type));
                        }

                    }
                    break;
                default:
                    res = CallReverseBinaryOp(node, unit, operation, rhs);
                    break;
            }
            return res;
        }
        internal void AssignTo(Node assignStmt, Expression left, IAnalysisSet values)
        {
            if (left is ExpressionWithAnnotation)
            {
                left = ((ExpressionWithAnnotation)left).Expression;
                // "x:t=..." is a recommended pattern - we do not want to
                // actually assign the ellipsis in this case.
                if (values.Any(v => v.TypeId == BuiltinTypeId.Ellipsis))
                {
                    values = AnalysisSet.Create(values.Where(v => v.TypeId != BuiltinTypeId.Ellipsis), values.Comparer);
                }
            }

            if (left is NameExpression)
            {
                var l = (NameExpression)left;
                if (!string.IsNullOrEmpty(l.Name))
                {
                    Scope.AssignVariable(
                        l.Name,
                        l,
                        _unit,
                        values
                        );
                }
            }
            else if (left is MemberExpression)
            {
                var l = (MemberExpression)left;
                if (!string.IsNullOrEmpty(l.Name))
                {
                    foreach (var obj in Evaluate(l.Target).Resolve(_unit))
                    {
                        obj.SetMember(l, _unit, l.Name, values.Resolve(_unit));
                    }
                }
            }
            else if (left is IndexExpression)
            {
                var l        = (IndexExpression)left;
                var indexObj = Evaluate(l.Index);
                foreach (var obj in Evaluate(l.Target).Resolve(_unit))
                {
                    obj.SetIndex(assignStmt, _unit, indexObj, values.Resolve(_unit));
                }
            }
            else if (left is SequenceExpression)
            {
                // list/tuple
                var l         = (SequenceExpression)left;
                var valuesArr = values.ToArray();
                for (var i = 0; i < l.Items.Count; i++)
                {
                    if (valuesArr.Length > 0)
                    {
                        foreach (var value in valuesArr)
                        {
                            AssignTo(assignStmt, l.Items[i], value.GetIndex(assignStmt, _unit, ProjectState.GetConstant(i)));
                        }
                    }
                    else
                    {
                        AssignTo(assignStmt, l.Items[i], AnalysisSet.Empty);
                    }
                }
            }
        }