private UnaryNode(
            UnaryExpression unaryExpression,
            ConstantExpression[] constExpressions,
            ParameterExpression[] parameterExpressions,
            string unaryOperationMethodName)
        {
            this.unaryExpression = unaryExpression;
            if (unaryExpression == null)
            {
                throw new ArgumentNullException("unaryExpression");
            }
            if (constExpressions == null)
            {
                throw new ArgumentNullException("constExpressions");
            }
            if (parameterExpressions == null)
            {
                throw new ArgumentNullException("parameterExpressions");
            }

            this.operandNode = AotCompiler.Compile(unaryExpression.Operand, constExpressions, parameterExpressions);
            this.isNullable  = IsNullable(unaryExpression.Operand);
            this.operation   = Intrinsic.WrapUnaryOperation(unaryExpression.Method) ??
                               (unaryOperationMethodName == null ? null : Intrinsic.WrapUnaryOperation(unaryExpression.Operand.Type, unaryOperationMethodName));
        }
        public ConvertNode(UnaryExpression convertExpression, ConstantExpression[] constExpressions, ParameterExpression[] parameterExpressions)
        {
            this.convertExpression = convertExpression;
            this.operandNode       = AotCompiler.Compile(convertExpression.Operand, constExpressions, parameterExpressions);
            this.sourceType        = TypeDescription.GetTypeDescription(convertExpression.Operand.Type);
            this.targetType        = TypeDescription.GetTypeDescription(convertExpression.Type);
            if (this.sourceType.IsNullable)
            {
                this.sourceType           = this.sourceType.UnderlyingType;
                this.isSourceTypeNullable = true;
            }
            if (this.targetType.IsNullable)
            {
                this.targetType           = this.targetType.UnderlyingType;
                this.isTargetTypeNullable = true;
            }

            this.operation = Intrinsic.WrapUnaryOperation(convertExpression.Method) ??
                             Intrinsic.WrapUnaryOperation
                             (
                this.targetType.ExplicitConvertFrom.FindConversion(this.sourceType, this.targetType) ??
                this.targetType.ImplicitConvertFrom.FindConversion(this.sourceType, this.targetType) ??
                this.sourceType.ExplicitConvertTo.FindConversion(this.sourceType, this.targetType) ??
                this.sourceType.ImplicitConvertTo.FindConversion(this.sourceType, this.targetType)
                             );
        }
 public ConvertNode(UnaryExpression convertExpression, ConstantExpression[] constExpressions, ParameterExpression[] parameterExpressions)
 {
     this.convertExpression = convertExpression;
     this.operandNode       = AotCompiler.Compile(convertExpression.Operand, constExpressions, parameterExpressions);
     this.operation         = Intrinsic.WrapUnaryOperation(convertExpression.Method) ?? Intrinsic.WrapUnaryOperation(
         convertExpression.Type
         .GetMethods(BindingFlags.Public | BindingFlags.Static)
         .FirstOrDefault(m =>
                         (string.Equals(m.Name, "op_Explicit", StringComparison.Ordinal) || string.Equals(m.Name, "op_Implicit", StringComparison.Ordinal)) &&
                         m.ReturnType == convertExpression.Type &&
                         m.GetParameters().Length == 1 &&
                         m.GetParameters()[0].ParameterType == convertExpression.Operand.Type)
         );
     this.targetType           = Nullable.GetUnderlyingType(convertExpression.Type) ?? convertExpression.Type;
     this.isTargetTypeNullable = IsNullable(convertExpression.Type);
     this.sourceType           = Nullable.GetUnderlyingType(convertExpression.Operand.Type) ?? convertExpression.Operand.Type;
     this.isSourceTypeNullable = IsNullable(convertExpression.Operand);
 }