public static ILChainIfCondition IfEqual(this ILGenerator il, ILPointer left, ILPointer right)
 {
     return(new ILChainIfCondition(il, () => il.AreEqual(left, right)));
 }
        private void GeneratePropertyCode(ILArgPointer graphArg, SerializableProperty target)
        {
            var extPropertyType   = target.Ext;
            var argsField         = _context.GetArgsField(target);
            var argsFieldVariable = ILPointer.Field(ILPointer.This(), argsField);

            if (extPropertyType.IsValueOrNullableOfValue())
            {
                var isNullable  = extPropertyType.Classification == TypeClassification.Nullable;
                var isEnum      = extPropertyType.IsEnum();
                var isValueType = extPropertyType.Info.IsValueType;

                var mediatorPropertyType = isEnum ? extPropertyType.GetUnderlyingEnumType() : extPropertyType.Ref;
                var valueType            = !isNullable && isValueType ? Members.Nullable[mediatorPropertyType].NullableType : mediatorPropertyType;

                var valueLocal = _il.NewLocal(valueType);

                _il.InvokeMethod(_visitorVariable, Members.VisitorTryVisitValue[valueType], argsFieldVariable, valueLocal);

                if (isValueType && !isNullable)
                {
                    var labelValueNotFound = _il.NewLabel();
                    labelValueNotFound.TransferLongIfFalse();

                    _il.Load(valueLocal
                             .Call(Members.Nullable[mediatorPropertyType].GetHasValue)
                             .Negate());

                    var nullableHasValueLabel = _il.NewLabel();
                    nullableHasValueLabel.TransferLong();

                    labelValueNotFound.Mark();
                    _il.Load(true);
                    nullableHasValueLabel.Mark();
                }
                else
                {
                    _il.Negate();
                }

                var skipSetValueLabel = _il.NewLabel();
                skipSetValueLabel.TransferLongIfTrue();

                var valueToAdd = isValueType && !isNullable
                    ? valueLocal.Call(Members.Nullable[mediatorPropertyType].GetValue)
                    : valueLocal;

                _il.Set(graphArg, target.Ref, valueToAdd);

                skipSetValueLabel.Mark();
            }
            else if (extPropertyType.Classification == TypeClassification.Dictionary)
            {
                var stateLocal = _il.NewLocal(typeof(ValueState));
                _il.Set(stateLocal, _visitorVariable.Call(Members.VisitorTryVisit, argsFieldVariable));

                var endLabel = _il.NewLabel();
                endLabel.TransferLongIfTrue(stateLocal.Equal((int)ValueState.NotFound));

                _il.AreEqual(stateLocal, (int)ValueState.Found);

                var nullLabel = _il.NewLabel();
                nullLabel.TransferLongIfFalse();

                var dictionaryLocal = GenerateDictionaryEnumerateCode(target.Ref.PropertyType, target.Ref.Name);

                _il.Set(graphArg, target.Ref, dictionaryLocal.Cast(target.Ref.PropertyType));

                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, argsFieldVariable);

                endLabel.TransferLong();

                nullLabel.Mark();
                _il.Set(graphArg, target.Ref, null);

                endLabel.Mark();
            }
            else if (extPropertyType.Classification == TypeClassification.Collection)
            {
                _il.InvokeMethod(_visitorVariable, Members.VisitorTryVisit, argsFieldVariable);
                var stateLocal = _il.NewLocal(typeof(ValueState));
                _il.Set(stateLocal);

                _il.AreEqual(stateLocal, (int)ValueState.NotFound);

                var endLabel = _il.NewLabel();
                endLabel.TransferLongIfTrue();

                _il.AreEqual(stateLocal, (int)ValueState.Found);

                var nullLabel = _il.NewLabel();
                nullLabel.TransferLongIfFalse();

                var collectionParam = GenerateCollectionContent(extPropertyType, target.Ref.Name);

                _il.Set(graphArg, target.Ref, collectionParam);
                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, argsFieldVariable);
                endLabel.TransferLong();

                nullLabel.Mark();
                _il.Set(graphArg, target.Ref, null);

                endLabel.Mark();
            }
            else
            {
                _il.InvokeMethod(_visitorVariable, Members.VisitorTryVisit, argsFieldVariable);
                var stateLocal = _il.NewLocal(typeof(ValueState));
                _il.Set(stateLocal);

                _il.IfNotEqual(stateLocal, (int)ValueState.NotFound)
                .Then(() => {
                    _il.IfEqual(stateLocal, (int)ValueState.Found)
                    .Then(() => {
                        var singleLocal = _il.NewLocal(extPropertyType.Ref);
                        GenerateCreateAndChildCallCode(singleLocal);

                        _il.Set(graphArg, target.Ref, singleLocal);
                        _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, argsFieldVariable);
                    }).Else(() => {
                        _il.Set(graphArg, target.Ref, null);
                    }).End();
                }).End();
            }
        }
Exemple #3
0
 public void TransferIfNull(ILPointer value)
 {
     _il.AreEqual(value, null);
     TransferLongIfTrue();
 }