public void ModelOperation(IModellingContext context, IMethodSymbol method, IEnumerable <ITypeModel> arguments) { Contract.Requires(context != null); Contract.Requires(method != null); Contract.Requires(arguments != null); Contract.Requires(arguments.Count() == method.Parameters.Length); if (method.MethodKind != MethodKind.BuiltinOperator || method.Parameters.Length == 0 || !this.IsTypeSupported(method.ReturnType)) { // This might be the case of static methods etc. context.SetUnsupported(); return; } BoolHandle boolResult = GetOperationResult(method, arguments); if (boolResult.Expression != null) { Contract.Assert(this.IsTypeSupported(method.ReturnType)); var resultModel = new BooleanModel(this, method.ReturnType, boolResult); context.SetResultValue(resultModel); } else { context.SetUnsupported(); } }
// TODO: Somehow handle the different sizes and signed/unsigned variants using modulo etc. public void ModelOperation(IModellingContext context, IMethodSymbol method, IEnumerable <ITypeModel> arguments) { Contract.Requires(context != null); Contract.Requires(method != null); Contract.Requires(arguments != null); Contract.Requires(arguments.Count() == method.Parameters.Length); if (method.MethodKind != MethodKind.BuiltinOperator || method.Parameters.Length == 0 || (!BooleanModelFactory.Instance.IsTypeSupported(method.ReturnType) && !this.IsTypeSupported(method.ReturnType))) { // This might be the case of conversions to other types, static methods etc. context.SetUnsupported(); return; } IntHandle intResult; BoolHandle boolResult; this.GetOperationResult(context, method, arguments, out intResult, out boolResult); ITypeModel resultModel = null; if (intResult.Expression != null) { Contract.Assert(this.IsTypeSupported(method.ReturnType)); resultModel = new IntegerModel(this, method.ReturnType, intResult); } else if (boolResult.Expression != null) { Contract.Assert(BooleanModelFactory.Instance.IsTypeSupported(method.ReturnType)); // TODO: Properly manage the references to the other factories instead of using singletons for all types resultModel = BooleanModelFactory.Instance.GetExpressionModel( method.ReturnType, boolResult.Expression.ToSingular()); } if (resultModel != null) { context.SetResultValue(resultModel); } else { context.SetUnsupported(); } }
private BoolHandle GetOperationResult( IModellingContext context, IMethodSymbol method, IEnumerable <ITypeModel> arguments) { if (method.Name == "op_Equality") { return((BoolHandle)ExpressionFactory.Equal( arguments.First().AssignmentRight[0], arguments.ElementAt(1).AssignmentRight[0])); } else if (method.Name == "op_Inequality") { return((BoolHandle)ExpressionFactory.Distinct( arguments.First().AssignmentRight[0], arguments.ElementAt(1).AssignmentRight[0])); } else { return(default(BoolHandle)); } }
public void ModelOperation(IModellingContext context, IMethodSymbol method, IEnumerable <ITypeModel> arguments) { if (method.MethodKind != MethodKind.BuiltinOperator || method.Parameters.Length != 2) { context.SetUnsupported(); return; } var boolResult = this.GetOperationResult(context, method, arguments); if (boolResult.Expression != null) { var resultModel = BooleanModelFactory.Instance.GetExpressionModel( method.ReturnType, boolResult.Expression.ToSingular()); context.SetResultValue(resultModel); } else { context.SetUnsupported(); } }
private void GetOperationResult( IModellingContext context, IMethodSymbol method, IEnumerable <ITypeModel> arguments, out IntHandle intResult, out BoolHandle boolResult) { var first = ((IntegerModel)arguments.First()).Value; if (method.Parameters.Length == 1) { if (method.Name == "op_UnaryNegation") { intResult = -first; } else if (method.Name == "op_UnaryPlus") { intResult = first; } } else { Contract.Assert(method.Parameters.Length == 2); var second = ((IntegerModel)arguments.ElementAt(1)).Value; if (BooleanModelFactory.Instance.IsTypeSupported(method.ReturnType)) { switch (method.Name) { case "op_Equality": boolResult = (first == second); break; case "op_Inequality": boolResult = (first != second); break; case "op_GreaterThan": boolResult = (first > second); break; case "op_LessThan": boolResult = (first < second); break; case "op_GreaterThanOrEqual": boolResult = (first >= second); break; case "op_LessThanOrEqual": boolResult = (first <= second); break; default: break; } } else { Contract.Assert(this.IsTypeSupported(method.ReturnType)); switch (method.Name) { case "op_Addition": intResult = first + second; break; case "op_Subtraction": intResult = first - second; break; case "op_Division": // TODO: Set the exception if the right is zero intResult = first / second; break; case "op_Modulus": intResult = first % second; break; case "op_Multiply": intResult = first * second; break; default: break; } } } }