ConstantCheck.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Compiler / ConstantCheck.cs / 1305376 / ConstantCheck.cs

                            /* **************************************************************************** 
 *
 * Copyright (c) Microsoft Corporation.
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/ 

using System.Diagnostics; 
using System.Dynamic.Utils; 

namespace System.Linq.Expressions { 
    internal enum AnalyzeTypeIsResult {
        KnownFalse,
        KnownTrue,
        KnownAssignable, // need null check only 
        Unknown,         // need full runtime check
    } 
 
    internal static class ConstantCheck {
 
        internal static bool IsNull(Expression e) {
            if (e.NodeType == ExpressionType.Constant) {
                return ((ConstantExpression)e).Value == null;
            } 
            return false;
        } 
 

        ///  
        /// If the result of a TypeBinaryExpression is known statically, this
        /// returns the result, otherwise it returns null, meaning we'll need
        /// to perform the IsInst instruction at runtime.
        /// 
        /// The result of this function must be equivalent to IsInst, or
        /// null. 
        ///  
        internal static AnalyzeTypeIsResult AnalyzeTypeIs(TypeBinaryExpression typeIs) {
            return AnalyzeTypeIs(typeIs.Expression, typeIs.TypeOperand); 
        }

        /// 
        /// If the result of a unary TypeAs expression is known statically, this 
        /// returns the result, otherwise it returns null, meaning we'll need
        /// to perform the IsInst instruction at runtime. 
        /// 
        /// The result of this function must be equivalent to IsInst, or
        /// null. 
        /// 
        internal static AnalyzeTypeIsResult AnalyzeTypeIs(UnaryExpression typeAs) {
            Debug.Assert(typeAs.NodeType == ExpressionType.TypeAs);
            return AnalyzeTypeIs(typeAs.Operand, typeAs.Type); 
        }
 
        ///  
        /// If the result of an isinst opcode is known statically, this
        /// returns the result, otherwise it returns null, meaning we'll need 
        /// to perform the IsInst instruction at runtime.
        ///
        /// The result of this function must be equivalent to IsInst, or
        /// null. 
        /// 
        private static AnalyzeTypeIsResult AnalyzeTypeIs(Expression operand, Type testType) { 
            Type operandType = operand.Type; 

            // Oddly, we allow void operands 
            // This is LinqV1 behavior of TypeIs
            if (operandType == typeof(void)) {
                return AnalyzeTypeIsResult.KnownFalse;
            } 

            // 
            // Type comparisons treat nullable types as if they were the 
            // underlying type. The reason is when you box a nullable it
            // becomes a boxed value of the underlying type, or null. 
            //
            Type nnOperandType = operandType.GetNonNullableType();
            Type nnTestType = testType.GetNonNullableType();
 
            //
            // See if we can determine the answer based on the static types 
            // 
            // Extensive testing showed that Type.IsAssignableFrom,
            // Type.IsInstanceOfType, and the isinst instruction were all 
            // equivalent when used against a live object
            //
            if (nnTestType.IsAssignableFrom(nnOperandType)) {
                // If the operand is a value type (other than nullable), we 
                // know the result is always true.
                if (operandType.IsValueType && !operandType.IsNullableType()) { 
                    return AnalyzeTypeIsResult.KnownTrue; 
                }
 
                // For reference/nullable types, we need to compare to null at runtime
                return AnalyzeTypeIsResult.KnownAssignable;
            }
 
            // We used to have an if IsSealed, return KnownFalse check here.
            // but that doesn't handle generic types & co/contravariance correctly. 
            // So just use IsInst, which we know always gives us the right answer. 

            // Otherwise we need a full runtime check 
            return AnalyzeTypeIsResult.Unknown;
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/* **************************************************************************** 
 *
 * Copyright (c) Microsoft Corporation.
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/ 

using System.Diagnostics; 
using System.Dynamic.Utils; 

namespace System.Linq.Expressions { 
    internal enum AnalyzeTypeIsResult {
        KnownFalse,
        KnownTrue,
        KnownAssignable, // need null check only 
        Unknown,         // need full runtime check
    } 
 
    internal static class ConstantCheck {
 
        internal static bool IsNull(Expression e) {
            if (e.NodeType == ExpressionType.Constant) {
                return ((ConstantExpression)e).Value == null;
            } 
            return false;
        } 
 

        ///  
        /// If the result of a TypeBinaryExpression is known statically, this
        /// returns the result, otherwise it returns null, meaning we'll need
        /// to perform the IsInst instruction at runtime.
        /// 
        /// The result of this function must be equivalent to IsInst, or
        /// null. 
        ///  
        internal static AnalyzeTypeIsResult AnalyzeTypeIs(TypeBinaryExpression typeIs) {
            return AnalyzeTypeIs(typeIs.Expression, typeIs.TypeOperand); 
        }

        /// 
        /// If the result of a unary TypeAs expression is known statically, this 
        /// returns the result, otherwise it returns null, meaning we'll need
        /// to perform the IsInst instruction at runtime. 
        /// 
        /// The result of this function must be equivalent to IsInst, or
        /// null. 
        /// 
        internal static AnalyzeTypeIsResult AnalyzeTypeIs(UnaryExpression typeAs) {
            Debug.Assert(typeAs.NodeType == ExpressionType.TypeAs);
            return AnalyzeTypeIs(typeAs.Operand, typeAs.Type); 
        }
 
        ///  
        /// If the result of an isinst opcode is known statically, this
        /// returns the result, otherwise it returns null, meaning we'll need 
        /// to perform the IsInst instruction at runtime.
        ///
        /// The result of this function must be equivalent to IsInst, or
        /// null. 
        /// 
        private static AnalyzeTypeIsResult AnalyzeTypeIs(Expression operand, Type testType) { 
            Type operandType = operand.Type; 

            // Oddly, we allow void operands 
            // This is LinqV1 behavior of TypeIs
            if (operandType == typeof(void)) {
                return AnalyzeTypeIsResult.KnownFalse;
            } 

            // 
            // Type comparisons treat nullable types as if they were the 
            // underlying type. The reason is when you box a nullable it
            // becomes a boxed value of the underlying type, or null. 
            //
            Type nnOperandType = operandType.GetNonNullableType();
            Type nnTestType = testType.GetNonNullableType();
 
            //
            // See if we can determine the answer based on the static types 
            // 
            // Extensive testing showed that Type.IsAssignableFrom,
            // Type.IsInstanceOfType, and the isinst instruction were all 
            // equivalent when used against a live object
            //
            if (nnTestType.IsAssignableFrom(nnOperandType)) {
                // If the operand is a value type (other than nullable), we 
                // know the result is always true.
                if (operandType.IsValueType && !operandType.IsNullableType()) { 
                    return AnalyzeTypeIsResult.KnownTrue; 
                }
 
                // For reference/nullable types, we need to compare to null at runtime
                return AnalyzeTypeIsResult.KnownAssignable;
            }
 
            // We used to have an if IsSealed, return KnownFalse check here.
            // but that doesn't handle generic types & co/contravariance correctly. 
            // So just use IsInst, which we know always gives us the right answer. 

            // Otherwise we need a full runtime check 
            return AnalyzeTypeIsResult.Unknown;
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK