protected override Expression ListToResult(Expression list) { var method = ExpressionReflector.GetMethodInfo(() => Enumerable.ToArray <object>(null), true) .MakeGenericMethod(ElementType); return(Expression.Call(method, list)); }
protected override Expression ParseRawValue(Expression rawValue) { return(Expression.Call( ExpressionReflector.GetMethodInfo(() => Convert.ToInt32("", null)), rawValue, Expression.Constant(CultureInfo.InvariantCulture))); }
internal override Expression GetDeserializerExpression(ParameterExpression jsonReader, ParameterExpression settings) { return(Expression.Call( ExpressionReflector.GetMethodInfo(() => Enums.Parse <StringComparison>(""), true).MakeGenericMethod(Type), Expression.Call( jsonReader, ExpressionReflector.GetMethodInfo((JsonReader r) => r.ReadUnquoted())))); }
internal override Expression GetDeserializerExpression(ParameterExpression jsonReaderParam, ParameterExpression settingsParam) { var resultVar = Expression.Variable(typeof(Dictionary <,>).MakeGenericType(KeyType, ValueType), "result"); return(Expression.Block( new[] { resultVar }, MakeSureBlockStartsWith(jsonReaderParam, '{'), Expression.Call(jsonReaderParam, ExpressionReflector.GetMethodInfo <JsonReader>(r => r.ReadNextChar())), Expression.Assign(resultVar, Expression.New(resultVar.Type)), CreateValueLoop(jsonReaderParam, settingsParam, resultVar), DictionaryToResult(resultVar))); }
protected ConditionalExpression MakeSureBlockStartsWith(ParameterExpression jsonReaderParam, char c) { return(Expression.IfThen( Expression.NotEqual( Expression.Call(jsonReaderParam, ExpressionReflector.GetMethodInfo <JsonReader>(r => r.CurrentChar())), Expression.Constant(c)), Expression.Throw( Expression.New( ExpressionReflector.GetConstructorInfo(() => new JsonReadException(null, null)), Expression.Constant($"Input is not a valid Json: '{c}' expected."), Expression.Default(typeof(Exception)))))); }
private Expression CreateParameterLessFactory() { var constructor = Type.GetConstructor(BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); return(constructor != null ? (Expression)Expression.New(constructor) : Expression.Convert( Expression.Call( ExpressionReflector.GetMethodInfo(() => FormatterServices.GetUninitializedObject(null)), Expression.Constant(Type)), Type)); }
protected Expression ManageEndOfBlockOrNextElement(ParameterExpression jsonReaderVar, LabelTarget breakTarget, LabelTarget continueTarget, char endOfBlock) { var nextCharVar = Expression.Variable(typeof(char), "nextChar"); return(Expression.Block( new[] { nextCharVar }, Expression.Assign(nextCharVar, Expression.Call(jsonReaderVar, nameof(JsonReader.CurrentChar), Type.EmptyTypes)), Expression.Call(jsonReaderVar, ExpressionReflector.GetMethodInfo <JsonReader>(r => r.ReadNextChar())), Expression.IfThen( Expression.Equal(nextCharVar, Expression.Constant(',')), Expression.Goto(continueTarget)), Expression.IfThen( Expression.Equal(nextCharVar, Expression.Constant(endOfBlock)), Expression.Goto(breakTarget)), Expression.Call( jsonReaderVar, ExpressionReflector.GetMethodInfo <JsonReader>(r => r.ThrowError("")), Expression.Constant("Input is not a valid Json: ',' or '}' expected at position {0}.")))); }
private BlockExpression GetMemberExpressionLoopBlock(ParameterExpression jsonReaderParam, ParameterExpression jsonReaderVar, ParameterExpression resultVar, ParameterExpression memberNameVar, ParameterExpression comparerVar, ParameterExpression settingsParam, LabelTarget breakTarget, LabelTarget continueTarget) { var expressions = new List <Expression>(); expressions.Add(Expression.Assign( memberNameVar, Expression.Call( jsonReaderParam, ExpressionReflector.GetMethodInfo <JsonReader>(r => r.ReadMemberName())))); expressions.Add(Expression.Call(jsonReaderVar, nameof(JsonReader.ReadAssignment), Type.EmptyTypes)); var properties = Type.GetProperties().Where(p => p.GetSetMethod(true) != null); using (var enumerator = properties.GetEnumerator()) { var updates = GenerateMemberSetters(jsonReaderParam, resultVar, memberNameVar, comparerVar, settingsParam, enumerator); expressions.Add(updates); } expressions.Add(ManageEndOfBlockOrNextElement(jsonReaderVar, breakTarget, continueTarget, '}')); return(Expression.Block(expressions)); }
internal override Expression GetDeserializerExpression(ParameterExpression jsonReader, ParameterExpression settings) { var rawValue = GetRawStringValue(jsonReader); if (!Type.IsGenericType || Type.GetGenericTypeDefinition() != typeof(Nullable <>)) { return(ParseRawValue(rawValue)); } else { var stringValue = Expression.Variable(typeof(string)); return(Expression.Block( new[] { stringValue }, Expression.Assign(stringValue, rawValue), Expression.Condition( Expression.Call( ExpressionReflector.GetMethodInfo(() => string.IsNullOrWhiteSpace("")), stringValue), Expression.Default(Type), Expression.Convert(ParseRawValue(stringValue), Type)))); } }
private static Expression GenerateMemberSetters(ParameterExpression jsonReaderParam, ParameterExpression resultVar, ParameterExpression memberNameVar, ParameterExpression comparerVar, ParameterExpression settingsParam, IEnumerator <PropertyInfo> enumerator) { if (enumerator.MoveNext()) { var p = enumerator.Current; var setter = p.GetSetMethod(true); return(Expression.IfThenElse( Expression.Call( comparerVar, ExpressionReflector.GetMethodInfo <IEqualityComparer <StringChunk> >(c => c.Equals(default(StringChunk), default(StringChunk))), memberNameVar, Expression.Constant(new StringChunk(p.Name))), Expression.Call( resultVar, setter, GetMemberFactory(jsonReaderParam, settingsParam, p)), GenerateMemberSetters(jsonReaderParam, resultVar, memberNameVar, comparerVar, settingsParam, enumerator))); } else { // TODO return(Expression.Default(typeof(void))); } }
internal virtual Expression GetDeserializerExpression(ParameterExpression jsonReaderParam, ParameterExpression settingsParam) { var resultVar = Expression.Variable(Type, "result"); var memberNameVar = Expression.Variable(typeof(StringChunk), "memberName"); var comparerVar = Expression.Variable(typeof(IEqualityComparer <StringChunk>), "comparer"); var breakLabel = Expression.Label("break"); var continueLabel = Expression.Label("continue"); return(Expression.Block( new[] { resultVar, memberNameVar, comparerVar }, MakeSureBlockStartsWith(jsonReaderParam, '{'), Expression.Call(jsonReaderParam, ExpressionReflector.GetMethodInfo <JsonReader>(r => r.ReadNextChar())), Expression.Assign(resultVar, CreateParameterLessFactory()), Expression.Assign(comparerVar, Expression.Property(settingsParam, ExpressionReflector.GetPropertyInfo((JsonSettings s) => s.Comparer))), new WhileExpression( Expression.Equal( Expression.Call(jsonReaderParam, nameof(JsonReader.CurrentChar), Type.EmptyTypes), Expression.Constant('"')), GetMemberExpressionLoopBlock(jsonReaderParam, jsonReaderParam, resultVar, memberNameVar, comparerVar, settingsParam, breakLabel, continueLabel), breakLabel, continueLabel), resultVar)); }
protected override Expression ParseRawValue(Expression rawValue) { return(Expression.Call( ExpressionReflector.GetMethodInfo(() => Guid.Parse("")), rawValue)); }
protected override Expression GetRawStringValue(ParameterExpression jsonReader) { return(Expression.Call( jsonReader, ExpressionReflector.GetMethodInfo((JsonReader r) => r.ReadString()))); }
internal override Expression GetDeserializerExpression(ParameterExpression jsonReader, ParameterExpression settings) { return(Expression.Call( jsonReader, ExpressionReflector.GetMethodInfo((JsonReader r) => r.ReadString()))); }