protected virtual MethodDefinitionExpression CreateCreateClientMethod() { var client = Expression.Variable(FickleType.Define("PKWebServiceClient"), "client"); var self = FickleExpression.Variable(currentType, "self"); var options = FickleExpression.Parameter(FickleType.Define("NSDictionary"), "options"); var url = Expression.Parameter(typeof(string), "urlIn"); var parameters = new Expression[] { url, options }; var operationQueue = FickleExpression.Call(options, "objectForKey", "OperationQueue"); var variables = new [] { client }; var body = FickleExpression.Block ( variables, Expression.Assign(client, FickleExpression.StaticCall("PKWebServiceClient", "PKWebServiceClient", "clientWithURL", new { url = FickleExpression.New("NSURL", "initWithString", url), options = options, operationQueue })), Expression.Return(Expression.Label(), client) ); return new MethodDefinitionExpression("createClientWithURL", parameters.ToReadOnlyCollection(), FickleType.Define("PKWebServiceClient"), body, false, null); }
protected virtual Expression CreateTryParseMethod() { var value = Expression.Parameter(typeof(string), "value"); var methodName = currentTypeDefinition.Type.Name.Capitalize() + "TryParse"; var result = Expression.Parameter(currentTypeDefinition.Type.MakeByRefType(), "result"); var parameters = new Expression[] { value, result }; var defaultBody = Expression.Return(Expression.Label(), Expression.Constant(false)).ToStatement(); var cases = new List<SwitchCase>(); foreach (var enumValue in ((FickleType)currentTypeDefinition.Type).ServiceEnum.Values) { cases.Add(Expression.SwitchCase(Expression.Assign(result, Expression.Convert(Expression.Constant((int)enumValue.Value), currentTypeDefinition.Type)).ToStatement(), Expression.Constant(enumValue.Name))); } var switchStatement = Expression.Switch(value, defaultBody, cases.ToArray()); var body = FickleExpression.Block(switchStatement, Expression.Return(Expression.Label(), Expression.Constant(true))); return new MethodDefinitionExpression(methodName, parameters.ToReadOnlyCollection(), AccessModifiers.Static | AccessModifiers.ClasseslessFunction, typeof(bool), body, false, "__unused", null); }
protected virtual Expression CreateToStringMethod() { var value = Expression.Parameter(currentTypeDefinition.Type, "value"); var methodName = currentTypeDefinition.Type.Name.Capitalize() + "ToString"; var parameters = new Expression[] { value }; var array = FickleExpression.Variable("NSMutableArray", "array"); var temp = FickleExpression.Variable(currentTypeDefinition.Type, "temp"); var expressions = new List<Expression> { Expression.Assign(array, Expression.New(array.Type)) }; foreach (var enumValue in ((FickleType)currentTypeDefinition.Type).ServiceEnum.Values) { var currentEnumValue = Expression.Constant((int)enumValue.Value); expressions.Add ( Expression.IfThen ( Expression.Equal(Expression.And(currentEnumValue, Expression.Convert(value, typeof(int))), Expression.Convert(currentEnumValue, typeof(int))), FickleExpression.StatementisedGroupedExpression ( GroupedExpressionsExpressionStyle.Wide, FickleExpression.Call(array, typeof(void), "addObject", Expression.Constant(enumValue.Name)), Expression.Assign(temp, Expression.Convert(Expression.Or(Expression.Convert(temp, typeof(int)), currentEnumValue), currentTypeDefinition.Type)) ).ToBlock() ) ); } expressions.Add(Expression.IfThen(Expression.NotEqual(value, temp), FickleExpression.Return(FickleExpression.Call(Expression.Convert(value, typeof(object)), typeof(string), "stringValue", null)).ToStatementBlock())); expressions.Add(FickleExpression.Return(FickleExpression.Call(array, "componentsJoinedByString", Expression.Constant(",")))); var defaultBody = FickleExpression.StatementisedGroupedExpression ( GroupedExpressionsExpressionStyle.Wide, expressions.ToArray() ); var cases = new List<SwitchCase>(); foreach (var enumValue in ((FickleType)currentTypeDefinition.Type).ServiceEnum.Values) { cases.Add(Expression.SwitchCase(Expression.Return(Expression.Label(), Expression.Constant(enumValue.Name)).ToStatement(), Expression.Constant((int)enumValue.Value, currentTypeDefinition.Type))); } var switchStatement = Expression.Switch(value, defaultBody, cases.ToArray()); var body = FickleExpression.Block(new [] { array, temp }, switchStatement); return new MethodDefinitionExpression(methodName, parameters.ToReadOnlyCollection(), AccessModifiers.Static | AccessModifiers.ClasseslessFunction, typeof(string), body, false, "__unused", null); }
protected virtual Expression CreateConstructor() { var valParam = Expression.Parameter(typeof(int), "value"); var parameters = new Expression[] { valParam }; var valueMember = Expression.Variable(enumValueField.PropertyType, "this." + enumValueField.PropertyName); var body = FickleExpression.Block(Expression.Assign(valueMember, valParam).ToStatement()); return new MethodDefinitionExpression(currentTypeDefinition.Type.Name, parameters.ToReadOnlyCollection(), null, body, false, null); }
private Expression CreateParameterisedConstructor() { var valParam = Expression.Parameter(webServiceClientType, "client"); var parameters = new Expression[] { valParam }; var client = Expression.Variable(webServiceClientType, "webServiceClient"); var body = FickleExpression.Block(Expression.Assign(client, valParam).ToStatement()); return new MethodDefinitionExpression(currentTypeDefinitionExpression.Type.Name, parameters.ToReadOnlyCollection(), AccessModifiers.Public, null, body, false, null, null); }
protected virtual MethodDefinitionExpression CreateCreateErrorResponseMethod() { var errorCode = Expression.Parameter(typeof(string), "errorCode"); var message = Expression.Parameter(typeof(string), "errorMessage"); var stackTrace = Expression.Parameter(typeof(string), "stackTrace"); var parameters = new Expression[] { errorCode, message, stackTrace }; var responseStatusType = FickleType.Define("ResponseStatus"); var result = FickleExpression.Variable(currentType, "result"); var responseStatus = FickleExpression.Variable(responseStatusType, "responseStatus"); var newResult = Expression.Assign(result, Expression.New(currentType)); var newResponseStatus = Expression.Assign(responseStatus, Expression.New(responseStatusType)); var methodVariables = new List<ParameterExpression> { result, responseStatus }; var methodStatements = new List<Expression> { newResponseStatus, FickleExpression.Call(responseStatus, "setErrorCode", errorCode), FickleExpression.Call(responseStatus, "setMessage", message), FickleExpression.Call(responseStatus, "setStackTrace", stackTrace), newResult, FickleExpression.Call(result, "setResponseStatus", responseStatus), Expression.Return(Expression.Label(), result) }; var body = FickleExpression.Block(methodVariables.ToArray(), methodStatements.ToArray()); return new MethodDefinitionExpression("createErrorResponse", parameters.ToReadOnlyCollection(), AccessModifiers.Public | AccessModifiers.Static, currentType, body, false, null); }
MethodCallExpression ReplaceQueryableMethod (MethodCallExpression old) { Expression target = null; if (old.Object != null) target = Visit (old.Object); var method = ReplaceQueryableMethod (old.Method); var parameters = method.GetParameters (); var arguments = new Expression [old.Arguments.Count]; for (int i = 0; i < arguments.Length; i++) { arguments [i] = UnquoteIfNeeded ( Visit (old.Arguments [i]), parameters [i].ParameterType); } return new MethodCallExpression (target, method, arguments.ToReadOnlyCollection ()); }
private Expression CreateParameterisedConstructor() { var httpClientParam = Expression.Parameter(this.httpClientType, HttpClientFieldName); var httpStreamSerializerParam = Expression.Parameter(this.httpStreamSerializerType, HttpStreamSerializerFieldName); var parameters = new Expression[] { httpClientParam, httpStreamSerializerParam }; var clientField = Expression.Variable(this.httpClientType, "this." + HttpClientFieldName); var serailizerField = Expression.Variable(this.httpStreamSerializerType, "this." + HttpStreamSerializerFieldName); var body = FickleExpression.Block(new Expression[] { Expression.Assign(clientField, httpClientParam).ToStatement(), Expression.Assign(serailizerField, httpStreamSerializerParam).ToStatement() } ); return new MethodDefinitionExpression(this.currentTypeDefinitionExpression.Type.Name, parameters.ToReadOnlyCollection(), AccessModifiers.Public, null, body, false, null, null); }
protected virtual MethodDefinitionExpression CreateCreateErrorResponseWithErrorCodeMethod() { var client = Expression.Parameter(FickleType.Define("PKWebServiceClient"), "client"); var errorCode = Expression.Parameter(typeof(string), "createErrorResponseWithErrorCode"); var message = Expression.Parameter(typeof(string), "andMessage"); var parameters = new Expression[] { client, errorCode, message }; var clientOptions = FickleExpression.Property(client, FickleType.Define("NSDictionary"), "options"); var response = FickleExpression.Variable(FickleType.Define("id"), "response"); var responseClass = FickleExpression.Call(clientOptions, "Class", "objectForKey", "$ResponseClass"); var responseStatus = FickleExpression.Call(response, "ResponseStatus", "responseStatus", null); var newResponseStatus = FickleExpression.New("ResponseStatus", "init", null); var body = FickleExpression.Block ( new [] { response }, Expression.Assign(response, FickleExpression.Call(FickleExpression.Call(responseClass, response.Type, "alloc", null), response.Type, "init", null)), Expression.IfThen(Expression.IsTrue(Expression.Equal(responseStatus, Expression.Constant(null, responseStatus.Type))), FickleExpression.Block(FickleExpression.Call(response, "setResponseStatus", newResponseStatus))), FickleExpression.StatementisedGroupedExpression ( FickleExpression.Call(responseStatus, typeof(string), "setErrorCode", errorCode), FickleExpression.Call(responseStatus, typeof(string), "setMessage", message) ), Expression.Return(Expression.Label(), response) ); return new MethodDefinitionExpression("webServiceClient", parameters.ToReadOnlyCollection(), FickleType.Define("id"), body, false, null); }
protected virtual MethodDefinitionExpression CreateParseResultMethod() { var client = Expression.Parameter(FickleType.Define("PKWebServiceClient"), "client"); var data = Expression.Parameter(FickleType.Define("NSData"), "parseResult"); var contentType = Expression.Parameter(typeof(string), "withContentType"); var statusCode = Expression.Parameter(typeof(int), "andStatusCode"); var response = FickleExpression.Variable("id", "response"); var options = FickleExpression.Property(client, "NSDictionary", "options"); var parameters = new Expression[] { client, data, contentType, statusCode }; var bodyExpressions = new List<Expression>(); var delegateType = new FickleDelegateType(FickleType.Define("id"), new FickleParameterInfo(client.Type, "client"), new FickleParameterInfo(FickleType.Define("NSData"), "data")); var block = Expression.Variable(delegateType, "block"); bodyExpressions.Add(Expression.Assign(block, FickleExpression.Call(options, FickleType.Define("id"), "objectForKey", Expression.Constant("$ParseResultBlock")))); bodyExpressions.Add(Expression.Assign(response, FickleExpression.Call(block, "id", "Invoke", new { client, data })).ToStatement()); var setResponseStatus = Expression.IfThen ( Expression.Equal(FickleExpression.Call(response, "id", "responseStatus", null), Expression.Constant(null, FickleType.Define("id"))), FickleExpression.Call(response, "setResponseStatus", FickleExpression.New("ResponseStatus", "init", null)).ToStatementBlock() ); var populateResponseStatus = FickleExpression.Call(FickleExpression.Call(response, "id", "responseStatus", null), "setHttpStatus", statusCode); bodyExpressions.Add(setResponseStatus); bodyExpressions.Add(populateResponseStatus); bodyExpressions.Add(FickleExpression.Return(response)); var body = FickleExpression.Block ( new[] { response, block }, bodyExpressions.ToArray() ); return new MethodDefinitionExpression ( "webServiceClient", parameters.ToReadOnlyCollection(), FickleType.Define("id"), body, false, null ); }
protected virtual Expression CreateTryParseMethod() { var value = Expression.Parameter(typeof(string), "value"); var methodName = currentTypeDefinition.Type.Name.Capitalize() + "TryParse"; var result = Expression.Parameter(currentTypeDefinition.Type.MakeByRefType(), "result"); var retval = Expression.Variable(currentTypeDefinition.Type, "retval"); var parameters = new Expression[] { value, result }; var parts = Expression.Variable(FickleType.Define("NSArray"), "parts"); var splitCall = FickleExpression.Call(value, FickleType.Define("NSArray"), "componentsSeparatedByString", new { value = Expression.Constant(",") }); var part = Expression.Variable(typeof(string), "part"); var flagCases = new List<SwitchCase>(); var number = Expression.Variable(FickleType.Define("NSNumber"), "number"); foreach (var enumValue in ((FickleType)currentTypeDefinition.Type).ServiceEnum.Values) { flagCases.Add(Expression.SwitchCase(Expression.Assign(retval, Expression.Convert(Expression.Or(Expression.Convert(retval, typeof(int)), Expression.Constant((int)enumValue.Value)), currentTypeDefinition.Type)).ToStatement(), Expression.Constant(enumValue.Name))); } var foreachBody = FickleExpression.StatementisedGroupedExpression ( Expression.Switch(part, FickleExpression.Return(Expression.Constant(false)).ToStatement(), flagCases.ToArray()) ).ToBlock(); var defaultBody = FickleExpression.StatementisedGroupedExpression ( GroupedExpressionsExpressionStyle.Wide, Expression.Assign(number, FickleExpression.Call(Expression.New(FickleType.Define("NSNumberFormatter")), number.Type, "numberFromString", value)), Expression.IfThen ( Expression.NotEqual(number, Expression.Constant(null, number.Type)), FickleExpression.StatementisedGroupedExpression ( GroupedExpressionsExpressionStyle.Wide, Expression.Assign(result, Expression.Convert(FickleExpression.Call(number, typeof(int), "intValue", null), currentTypeDefinition.Type)), Expression.Return(Expression.Label(), Expression.Constant(true)) ).ToBlock() ), Expression.Assign(parts, splitCall), Expression.Assign(retval, Expression.Convert(Expression.Constant(0), currentTypeDefinition.Type)), FickleExpression.ForEach(part, parts, foreachBody), Expression.Assign(result, retval), Expression.Return(Expression.Label(), Expression.Constant(true)) ); var cases = new List<SwitchCase>(); foreach (var enumValue in ((FickleType)currentTypeDefinition.Type).ServiceEnum.Values) { cases.Add(Expression.SwitchCase(Expression.Assign(result, Expression.Convert(Expression.Constant((int)enumValue.Value), currentTypeDefinition.Type)).ToStatement(), Expression.Constant(enumValue.Name))); } var switchStatement = Expression.Switch(value, defaultBody, cases.ToArray()); var body = FickleExpression.Block(new[] { parts, number, retval }, switchStatement, Expression.Return(Expression.Label(), Expression.Constant(true))); return new MethodDefinitionExpression(methodName, parameters.ToReadOnlyCollection(), AccessModifiers.Static | AccessModifiers.ClasseslessFunction, typeof(bool), body, false, "__unused", null); }
protected virtual FunctionResolveResult ResolveSqlFunction(SqlFunctionCallExpression functionExpression) { var function = functionExpression.Function; var arguments = functionExpression.Arguments; switch (function) { case SqlFunction.IsNull: return new FunctionResolveResult("", true, arguments) { functionSuffix = " IS NULL" }; case SqlFunction.IsNotNull: return new FunctionResolveResult("", true, arguments) { functionSuffix = " IS NOT NULL" }; case SqlFunction.In: return new FunctionResolveResult("IN", true, arguments); case SqlFunction.Exists: return new FunctionResolveResult("EXISTSOPERATOR", true, arguments) { functionPrefix = " EXISTS " }; case SqlFunction.UserDefined: return new FunctionResolveResult(functionExpression.UserDefinedFunctionName, false, arguments); case SqlFunction.Coalesce: return new FunctionResolveResult("COALESCE", false, arguments); case SqlFunction.Like: return new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, arguments); case SqlFunction.CompareObject: var expressionType = (ExpressionType)((ConstantExpression)arguments[0].StripConstantWrappers()).Value; var args = new Expression[2]; args[0] = arguments[1]; args[1] = arguments[2]; switch (expressionType) { case ExpressionType.LessThan: return new FunctionResolveResult("<", true, args.ToReadOnlyCollection()); case ExpressionType.LessThanOrEqual: return new FunctionResolveResult("<=", true, args.ToReadOnlyCollection()); case ExpressionType.GreaterThan: return new FunctionResolveResult(">", true, args.ToReadOnlyCollection()); case ExpressionType.GreaterThanOrEqual: return new FunctionResolveResult(">=", true, args.ToReadOnlyCollection()); } throw new InvalidOperationException(); case SqlFunction.NotLike: return new FunctionResolveResult("NOT " + this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, arguments); case SqlFunction.ServerNow: return new FunctionResolveResult("NOW", false, arguments); case SqlFunction.ServerUtcNow: return new FunctionResolveResult("UTCNOW", false, arguments); case SqlFunction.StartsWith: { var newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[1], Expression.Constant("%")); var optimisedNewArgument = SqlRedundantFunctionCallRemover.Remove(newArgument); if (optimisedNewArgument != newArgument) { if (SqlExpressionFinder.FindExists(arguments[1], c => c.NodeType == (ExpressionType)SqlExpressionType.ConstantPlaceholder)) { canReuse = false; this.parameterIndexToPlaceholderIndexes = null; } } var list = new List<Expression> { arguments[0], optimisedNewArgument }; return new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyCollection()); } case SqlFunction.ContainsString: { var newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[1], Expression.Constant("%")); newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Constant("%"), newArgument); var optimisedNewArgument = SqlRedundantFunctionCallRemover.Remove(newArgument); if (optimisedNewArgument != newArgument) { if (SqlExpressionFinder.FindExists(arguments[1], c => c.NodeType == (ExpressionType)SqlExpressionType.ConstantPlaceholder)) { canReuse = false; this.parameterIndexToPlaceholderIndexes = null; } } var list = new List<Expression> { arguments[0], optimisedNewArgument }; return new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyCollection()); } case SqlFunction.EndsWith: { var newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Constant("%"), arguments[1]); var optimisedNewArgument = SqlRedundantFunctionCallRemover.Remove(newArgument); if (optimisedNewArgument != newArgument) { if (SqlExpressionFinder.FindExists(arguments[1], c => c.NodeType == (ExpressionType)SqlExpressionType.ConstantPlaceholder)) { canReuse = false; this.parameterIndexToPlaceholderIndexes = null; } } var list = new List<Expression> { arguments[0], optimisedNewArgument }; return new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyCollection()); } case SqlFunction.StringLength: return new FunctionResolveResult("LENGTH", false, arguments); default: return new FunctionResolveResult(function.ToString().ToUpper(), false, arguments); } }