예제 #1
0
        public override IAnalysisSet GetIndex(Node node, AnalysisUnit unit, IAnalysisSet index)
        {
            if (ClassInfo is SequenceBuiltinClassInfo seq && seq.IndexTypes?.Count > 0)
            {
                int?constIndex = SequenceInfo.GetConstantIndex(index);

                if (constIndex != null)
                {
                    if (constIndex.Value < 0)
                    {
                        constIndex += seq.IndexTypes.Count;
                    }
                    if (0 <= constIndex.Value && constIndex.Value < seq.IndexTypes.Count)
                    {
                        return(seq.IndexTypes[constIndex.Value]);
                    }
                }

                if (index.Split(out IReadOnlyList <SliceInfo> sliceInfo, out _))
                {
                    return(this.SelfSet);
                }
            }

            return(UnionType);
        }
예제 #2
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);
        }
예제 #3
0
        public override bool UnionEquals(Namespace ns)
        {
            SequenceInfo si = ns as SequenceInfo;

            if (si == null)
            {
                return(false);
            }

            return(si._indexTypes.Length == _indexTypes.Length);
        }
예제 #4
0
        public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames)
        {
            if (args.Length == 1)
            {
                var res = unit.Scope.GetOrMakeNodeValue(
                    node,
                    NodeValueKind.Sequence,
                    (node_) => MakeFromIndexes(node_, unit.ProjectEntry)
                    ) as SequenceInfo;

                List <IAnalysisSet> seqTypes = new List <IAnalysisSet>();
                foreach (var type in args[0])
                {
                    SequenceInfo seqInfo = type as SequenceInfo;
                    if (seqInfo != null)
                    {
                        for (int i = 0; i < seqInfo.IndexTypes.Length; i++)
                        {
                            if (seqTypes.Count == i)
                            {
                                seqTypes.Add(seqInfo.IndexTypes[i].Types);
                            }
                            else
                            {
                                seqTypes[i] = seqTypes[i].Union(seqInfo.IndexTypes[i].Types);
                            }
                        }
                    }
                    else
                    {
                        var defaultIndexType = type.GetIndex(node, unit, ProjectState.GetConstant(0));
                        if (seqTypes.Count == 0)
                        {
                            seqTypes.Add(defaultIndexType);
                        }
                        else
                        {
                            seqTypes[0] = seqTypes[0].Union(defaultIndexType);
                        }
                    }
                }

                res.AddTypes(unit, seqTypes.ToArray());

                return(res);
            }

            return(base.Call(node, unit, args, keywordArgNames));
        }
        private static List <IPythonType>[] GetSequenceTypes(SequenceInfo seq)
        {
            List <IPythonType>[] types = new List <IPythonType> [seq.IndexTypes.Length];
            for (int i = 0; i < types.Length; i++)
            {
                foreach (var seqIndexType in seq.IndexTypes[i].Types)
                {
                    if (seqIndexType is BuiltinClassInfo)
                    {
                        if (types[i] == null)
                        {
                            types[i] = new List <IPythonType>();
                        }

                        types[i].Add(seqIndexType.PythonType);
                    }
                }
            }
            return(types);
        }
예제 #6
0
 private static void AssertTupleContains(SequenceInfo tuple, params BuiltinTypeId[] id) {
     var expected = string.Join(", ", id);
     var actual = string.Join(", ", tuple.IndexTypes.Select(t => {
         var t2 = t.TypesNoCopy;
         if (t2.Count == 1) {
             return t2.Single().TypeId.ToString();
         } else {
             return "{" + string.Join(", ", t2.Select(t3 => t3.TypeId).OrderBy(t3 => t3)) + "}";
         }
     }));
     if (tuple.IndexTypes
         .Zip(id, (t1, id2) => t1.TypesNoCopy.Count == 1 && t1.TypesNoCopy.Single().TypeId == id2)
         .Any(b => !b)) {
         Assert.Fail(string.Format("Expected <{0}>. Actual <{1}>.", expected, actual));
     }
 }