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 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); }
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; }
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); } } } }