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); }
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); }
public override bool UnionEquals(Namespace ns) { SequenceInfo si = ns as SequenceInfo; if (si == null) { return(false); } return(si._indexTypes.Length == _indexTypes.Length); }
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); }
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)); } }