CodeTypeReference.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / CompMod / System / CodeDOM / CodeTypeReference.cs / 1 / CodeTypeReference.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.CodeDom { 
 
    using System.Diagnostics;
    using System; 
    using Microsoft.Win32;
    using System.Collections;
    using System.Runtime.InteropServices;
    using System.Runtime.Serialization; 
    using System.Globalization;
 
    [ 
        ComVisible(true),
        Serializable, 
        FlagsAttribute
    ]
    public enum CodeTypeReferenceOptions {
        GlobalReference =  0x00000001, 
        GenericTypeParameter = 0x00000002
    } 
 
    /// 
    ///     
    ///       Represents a Type
    ///    
    /// 
    [ 
        ClassInterface(ClassInterfaceType.AutoDispatch),
        ComVisible(true), 
        Serializable, 
    ]
    public class CodeTypeReference : CodeObject { 
        private string baseType;
        [OptionalField]
        private bool isInterface;
        private int arrayRank; 
        private CodeTypeReference arrayElementType;
        [OptionalField] 
        private CodeTypeReferenceCollection typeArguments; 
        [OptionalField]
        private CodeTypeReferenceOptions referenceOptions; 
        [OptionalField]
        private bool needsFixup = false;

        public CodeTypeReference() { 
            baseType = string.Empty;
            this.arrayRank = 0; 
            this.arrayElementType = null; 
        }
 
        public CodeTypeReference(Type type) {
            if (type == null)
                throw new ArgumentNullException("type");
 
            if (type.IsArray) {
                this.arrayRank = type.GetArrayRank(); 
                this.arrayElementType = new CodeTypeReference(type.GetElementType()); 
                this.baseType = null;
            } else { 
                Initialize(type.FullName);
                this.arrayRank = 0;
                this.arrayElementType = null;
            } 

            this.isInterface = type.IsInterface; 
        } 

        public CodeTypeReference (Type type, CodeTypeReferenceOptions codeTypeReferenceOption) : this(type) { 
            referenceOptions = codeTypeReferenceOption;
        }

        public CodeTypeReference (String typeName, CodeTypeReferenceOptions codeTypeReferenceOption): this(typeName) { 
            referenceOptions = codeTypeReferenceOption;
        } 
 
        /// 
        ///    [To be supplied.] 
        /// 

        // We support the reflection format for generice type name.
        // The format is like: 
        //
        public CodeTypeReference(string typeName) { 
            Initialize(typeName); 
        }
 
        private void Initialize(string typeName) {
            if (typeName == null || typeName.Length == 0) {
                typeName = typeof(void).FullName;
                this.baseType = typeName; 
                this.arrayRank = 0;
                this.arrayElementType = null; 
                return; 
            }
 
            typeName = RipOffAssemblyInformationFromTypeName(typeName);

            int end = typeName.Length -1;
            int current = end; 
            needsFixup = true;      // default to true, and if we find arity or generic type args, we'll clear the flag.
 
            // Scan the entire string for valid array tails and store ranks for array tails 
            // we found in a queue.
            Queue q = new Queue(); 
            while(current >= 0) {
                int rank = 1;
                if( typeName[current--] == ']') {
                    while(current >=0 && typeName[current] == ',') { 
                        rank++;
                        current--; 
                    } 

                    if( current>=0 && typeName[current] == '[') { // found a valid array tail 
                        q.Enqueue(rank);
                        current--;
                        end = current;
                        continue; 
                    }
                } 
                break; 
            }
 
            // Try find generic type arguments
            current = end;
            ArrayList typeArgumentList = new ArrayList();
            Stack subTypeNames = new Stack(); 
            if( current > 0 && typeName[current--] == ']') {
                needsFixup = false; 
                int unmatchedRightBrackets = 1; 
                int subTypeNameEndIndex = end;
 
                // Try find the matching '[', if we can't find it, we will not try to parse the string
                while(current >= 0) {
                    if( typeName[current] == '[' ) {
                        // break if we found matched brackets 
                        if( --unmatchedRightBrackets == 0) break;
                    } 
                    else if( typeName[current] == ']' ) { 
                        ++unmatchedRightBrackets;
                    } 
                    else if( typeName[current] == ',' && unmatchedRightBrackets == 1) {
                        //
                        // Type name can contain nested generic types. Following is an example:
                        // System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], 
                        //          [System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],
                        //           mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] 
                        // 
                        // Spliltting by ',' won't work. We need to do first-level split by ','.
                        // 
                        if( current + 1 < subTypeNameEndIndex) {
                            subTypeNames.Push(typeName.Substring(current+1 , subTypeNameEndIndex - current - 1));
                        }
 
                        subTypeNameEndIndex = current;
 
                    } 
                    --current;
                } 

                if( current > 0 && (end - current - 1) > 0) {
                    // push the last generic type argument name if there is any
                    if( current + 1 < subTypeNameEndIndex) { 
                        subTypeNames.Push(typeName.Substring(current+1 , subTypeNameEndIndex - current - 1));
                    } 
 
                    // we found matched brackets and the brackets contains some characters.
                    while( subTypeNames.Count > 0) { 
                        String name = RipOffAssemblyInformationFromTypeName((string)subTypeNames.Pop());
                        typeArgumentList.Add(new CodeTypeReference(name));
                    }
                    end = current - 1; 
                }
            } 
 
            if( end < 0) {  // this can happen if we have some string like "[...]"
                this.baseType = typeName; 
                return;
            }

            if (q.Count > 0 ) { 

                CodeTypeReference type = new CodeTypeReference(typeName.Substring(0, end + 1)); 
 
                for(int i = 0; i < typeArgumentList.Count; i++) {
                    type.TypeArguments.Add((CodeTypeReference)typeArgumentList[i]); 
                }

                while( q.Count > 1) {
                    type = new CodeTypeReference( type, (int)q.Dequeue()); 
                }
 
                // we don't need to create a new CodeTypeReference for the last one. 
                Debug.Assert(q.Count == 1 , "We should have one and only one in the rank queue.");
                this.baseType = null; 
                this.arrayRank = (int)q.Dequeue();
                this.arrayElementType = type;
            }
            else if( typeArgumentList.Count > 0 ) { 
                for( int i = 0; i < typeArgumentList.Count; i++) {
                    TypeArguments.Add((CodeTypeReference)typeArgumentList[i]); 
                } 

                this.baseType = typeName.Substring(0, end + 1); 
            }
            else{
                this.baseType = typeName;
            } 

            // Now see if we have some arity.  baseType could be null if this is an array type. 
            if (baseType != null && baseType.IndexOf('`') != -1) 
                needsFixup = false;
 
        }

        public CodeTypeReference(string typeName, params CodeTypeReference[] typeArguments) : this(typeName){
            if( typeArguments != null && typeArguments.Length > 0) { 
                TypeArguments.AddRange(typeArguments);
            } 
        } 

        public CodeTypeReference(CodeTypeParameter typeParameter): 
                this( (typeParameter == null) ? (string)null : typeParameter.Name) {
            referenceOptions = CodeTypeReferenceOptions.GenericTypeParameter;
        }
 
        /// 
        ///    [To be supplied.] 
        ///  
        public CodeTypeReference(string baseType, int rank) {
            this.baseType = null; 
            this.arrayRank = rank;
            this.arrayElementType = new CodeTypeReference(baseType);
        }
 
        /// 
        ///    [To be supplied.] 
        ///  
        public CodeTypeReference(CodeTypeReference arrayType, int rank) {
            this.baseType = null; 
            this.arrayRank = rank;
            this.arrayElementType = arrayType;
        }
 
        /// 
        ///    [To be supplied.] 
        ///  
        public CodeTypeReference ArrayElementType {
            get { 
                return arrayElementType;
            }
            set {
                arrayElementType = value; 
            }
        } 
 
        /// 
        ///    [To be supplied.] 
        /// 
        public int ArrayRank {
            get {
                return arrayRank; 
            }
            set { 
                arrayRank = value; 
            }
        } 

        /// 
        ///    [To be supplied.]
        ///  
        public string BaseType {
            get { 
                if (arrayRank > 0 && arrayElementType != null) { 
                    return arrayElementType.BaseType;
                } 
                if (String.IsNullOrEmpty(baseType))
                    return string.Empty;

                string returnType = baseType; 
                if (needsFixup && TypeArguments.Count > 0)
                    returnType = returnType + '`' + TypeArguments.Count.ToString(CultureInfo.InvariantCulture); 
 
                return returnType;
 
            }
            set {
                baseType = value;
                Initialize(baseType); 
            }
        } 
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public CodeTypeReferenceOptions Options { 
            get { return referenceOptions;}
            set { referenceOptions = value;}
        }
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public CodeTypeReferenceCollection TypeArguments{ 
            get { 
                if (arrayRank > 0 && arrayElementType != null) {
                    return arrayElementType.TypeArguments; 
                }

                if( typeArguments == null) {
                    typeArguments = new CodeTypeReferenceCollection(); 
                }
                return typeArguments; 
            } 
        }
 
        internal bool IsInterface {
            get {
                // Note that this only works correctly if the Type ctor was used. Otherwise, it's always false.
                return this.isInterface; 
            }
        } 
 
        //
        // The string for generic type argument might contain assembly information and square bracket pair. 
        // There might be leading spaces in front the type name.
        // Following function will rip off assembly information and brackets
        // Following is an example:
        // " [System.Collections.Generic.List[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, 
        //   PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]"
        // 
        private string RipOffAssemblyInformationFromTypeName(string typeName) { 
            int start = 0;
            int end = typeName.Length - 1; 
            string result = typeName;

            // skip white space in the beginning
            while( start < typeName.Length && Char.IsWhiteSpace(typeName[start])) start++; 
            while( end >= 0 && Char.IsWhiteSpace(typeName[end])) end--;
 
            if(start < end) { 
                if (typeName[start] =='[' && typeName[end] == ']') {
                    start++; 
                    end--;
                }

                // if we still have a ] at the end, there's no assembly info. 
                if (typeName[end] != ']') {
                    int commaCount = 0; 
                    for(int index = end; index >= start; index--) { 
                        if( typeName[index] == ',') {
                            commaCount++; 
                            if( commaCount == 4) {
                                result = typeName.Substring( start, index - start);
                                break;
                            } 
                        }
                    } 
                } 
            }
 
            return result;
        }
    }
} 


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

namespace System.CodeDom { 
 
    using System.Diagnostics;
    using System; 
    using Microsoft.Win32;
    using System.Collections;
    using System.Runtime.InteropServices;
    using System.Runtime.Serialization; 
    using System.Globalization;
 
    [ 
        ComVisible(true),
        Serializable, 
        FlagsAttribute
    ]
    public enum CodeTypeReferenceOptions {
        GlobalReference =  0x00000001, 
        GenericTypeParameter = 0x00000002
    } 
 
    /// 
    ///     
    ///       Represents a Type
    ///    
    /// 
    [ 
        ClassInterface(ClassInterfaceType.AutoDispatch),
        ComVisible(true), 
        Serializable, 
    ]
    public class CodeTypeReference : CodeObject { 
        private string baseType;
        [OptionalField]
        private bool isInterface;
        private int arrayRank; 
        private CodeTypeReference arrayElementType;
        [OptionalField] 
        private CodeTypeReferenceCollection typeArguments; 
        [OptionalField]
        private CodeTypeReferenceOptions referenceOptions; 
        [OptionalField]
        private bool needsFixup = false;

        public CodeTypeReference() { 
            baseType = string.Empty;
            this.arrayRank = 0; 
            this.arrayElementType = null; 
        }
 
        public CodeTypeReference(Type type) {
            if (type == null)
                throw new ArgumentNullException("type");
 
            if (type.IsArray) {
                this.arrayRank = type.GetArrayRank(); 
                this.arrayElementType = new CodeTypeReference(type.GetElementType()); 
                this.baseType = null;
            } else { 
                Initialize(type.FullName);
                this.arrayRank = 0;
                this.arrayElementType = null;
            } 

            this.isInterface = type.IsInterface; 
        } 

        public CodeTypeReference (Type type, CodeTypeReferenceOptions codeTypeReferenceOption) : this(type) { 
            referenceOptions = codeTypeReferenceOption;
        }

        public CodeTypeReference (String typeName, CodeTypeReferenceOptions codeTypeReferenceOption): this(typeName) { 
            referenceOptions = codeTypeReferenceOption;
        } 
 
        /// 
        ///    [To be supplied.] 
        /// 

        // We support the reflection format for generice type name.
        // The format is like: 
        //
        public CodeTypeReference(string typeName) { 
            Initialize(typeName); 
        }
 
        private void Initialize(string typeName) {
            if (typeName == null || typeName.Length == 0) {
                typeName = typeof(void).FullName;
                this.baseType = typeName; 
                this.arrayRank = 0;
                this.arrayElementType = null; 
                return; 
            }
 
            typeName = RipOffAssemblyInformationFromTypeName(typeName);

            int end = typeName.Length -1;
            int current = end; 
            needsFixup = true;      // default to true, and if we find arity or generic type args, we'll clear the flag.
 
            // Scan the entire string for valid array tails and store ranks for array tails 
            // we found in a queue.
            Queue q = new Queue(); 
            while(current >= 0) {
                int rank = 1;
                if( typeName[current--] == ']') {
                    while(current >=0 && typeName[current] == ',') { 
                        rank++;
                        current--; 
                    } 

                    if( current>=0 && typeName[current] == '[') { // found a valid array tail 
                        q.Enqueue(rank);
                        current--;
                        end = current;
                        continue; 
                    }
                } 
                break; 
            }
 
            // Try find generic type arguments
            current = end;
            ArrayList typeArgumentList = new ArrayList();
            Stack subTypeNames = new Stack(); 
            if( current > 0 && typeName[current--] == ']') {
                needsFixup = false; 
                int unmatchedRightBrackets = 1; 
                int subTypeNameEndIndex = end;
 
                // Try find the matching '[', if we can't find it, we will not try to parse the string
                while(current >= 0) {
                    if( typeName[current] == '[' ) {
                        // break if we found matched brackets 
                        if( --unmatchedRightBrackets == 0) break;
                    } 
                    else if( typeName[current] == ']' ) { 
                        ++unmatchedRightBrackets;
                    } 
                    else if( typeName[current] == ',' && unmatchedRightBrackets == 1) {
                        //
                        // Type name can contain nested generic types. Following is an example:
                        // System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], 
                        //          [System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],
                        //           mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] 
                        // 
                        // Spliltting by ',' won't work. We need to do first-level split by ','.
                        // 
                        if( current + 1 < subTypeNameEndIndex) {
                            subTypeNames.Push(typeName.Substring(current+1 , subTypeNameEndIndex - current - 1));
                        }
 
                        subTypeNameEndIndex = current;
 
                    } 
                    --current;
                } 

                if( current > 0 && (end - current - 1) > 0) {
                    // push the last generic type argument name if there is any
                    if( current + 1 < subTypeNameEndIndex) { 
                        subTypeNames.Push(typeName.Substring(current+1 , subTypeNameEndIndex - current - 1));
                    } 
 
                    // we found matched brackets and the brackets contains some characters.
                    while( subTypeNames.Count > 0) { 
                        String name = RipOffAssemblyInformationFromTypeName((string)subTypeNames.Pop());
                        typeArgumentList.Add(new CodeTypeReference(name));
                    }
                    end = current - 1; 
                }
            } 
 
            if( end < 0) {  // this can happen if we have some string like "[...]"
                this.baseType = typeName; 
                return;
            }

            if (q.Count > 0 ) { 

                CodeTypeReference type = new CodeTypeReference(typeName.Substring(0, end + 1)); 
 
                for(int i = 0; i < typeArgumentList.Count; i++) {
                    type.TypeArguments.Add((CodeTypeReference)typeArgumentList[i]); 
                }

                while( q.Count > 1) {
                    type = new CodeTypeReference( type, (int)q.Dequeue()); 
                }
 
                // we don't need to create a new CodeTypeReference for the last one. 
                Debug.Assert(q.Count == 1 , "We should have one and only one in the rank queue.");
                this.baseType = null; 
                this.arrayRank = (int)q.Dequeue();
                this.arrayElementType = type;
            }
            else if( typeArgumentList.Count > 0 ) { 
                for( int i = 0; i < typeArgumentList.Count; i++) {
                    TypeArguments.Add((CodeTypeReference)typeArgumentList[i]); 
                } 

                this.baseType = typeName.Substring(0, end + 1); 
            }
            else{
                this.baseType = typeName;
            } 

            // Now see if we have some arity.  baseType could be null if this is an array type. 
            if (baseType != null && baseType.IndexOf('`') != -1) 
                needsFixup = false;
 
        }

        public CodeTypeReference(string typeName, params CodeTypeReference[] typeArguments) : this(typeName){
            if( typeArguments != null && typeArguments.Length > 0) { 
                TypeArguments.AddRange(typeArguments);
            } 
        } 

        public CodeTypeReference(CodeTypeParameter typeParameter): 
                this( (typeParameter == null) ? (string)null : typeParameter.Name) {
            referenceOptions = CodeTypeReferenceOptions.GenericTypeParameter;
        }
 
        /// 
        ///    [To be supplied.] 
        ///  
        public CodeTypeReference(string baseType, int rank) {
            this.baseType = null; 
            this.arrayRank = rank;
            this.arrayElementType = new CodeTypeReference(baseType);
        }
 
        /// 
        ///    [To be supplied.] 
        ///  
        public CodeTypeReference(CodeTypeReference arrayType, int rank) {
            this.baseType = null; 
            this.arrayRank = rank;
            this.arrayElementType = arrayType;
        }
 
        /// 
        ///    [To be supplied.] 
        ///  
        public CodeTypeReference ArrayElementType {
            get { 
                return arrayElementType;
            }
            set {
                arrayElementType = value; 
            }
        } 
 
        /// 
        ///    [To be supplied.] 
        /// 
        public int ArrayRank {
            get {
                return arrayRank; 
            }
            set { 
                arrayRank = value; 
            }
        } 

        /// 
        ///    [To be supplied.]
        ///  
        public string BaseType {
            get { 
                if (arrayRank > 0 && arrayElementType != null) { 
                    return arrayElementType.BaseType;
                } 
                if (String.IsNullOrEmpty(baseType))
                    return string.Empty;

                string returnType = baseType; 
                if (needsFixup && TypeArguments.Count > 0)
                    returnType = returnType + '`' + TypeArguments.Count.ToString(CultureInfo.InvariantCulture); 
 
                return returnType;
 
            }
            set {
                baseType = value;
                Initialize(baseType); 
            }
        } 
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public CodeTypeReferenceOptions Options { 
            get { return referenceOptions;}
            set { referenceOptions = value;}
        }
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public CodeTypeReferenceCollection TypeArguments{ 
            get { 
                if (arrayRank > 0 && arrayElementType != null) {
                    return arrayElementType.TypeArguments; 
                }

                if( typeArguments == null) {
                    typeArguments = new CodeTypeReferenceCollection(); 
                }
                return typeArguments; 
            } 
        }
 
        internal bool IsInterface {
            get {
                // Note that this only works correctly if the Type ctor was used. Otherwise, it's always false.
                return this.isInterface; 
            }
        } 
 
        //
        // The string for generic type argument might contain assembly information and square bracket pair. 
        // There might be leading spaces in front the type name.
        // Following function will rip off assembly information and brackets
        // Following is an example:
        // " [System.Collections.Generic.List[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, 
        //   PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]"
        // 
        private string RipOffAssemblyInformationFromTypeName(string typeName) { 
            int start = 0;
            int end = typeName.Length - 1; 
            string result = typeName;

            // skip white space in the beginning
            while( start < typeName.Length && Char.IsWhiteSpace(typeName[start])) start++; 
            while( end >= 0 && Char.IsWhiteSpace(typeName[end])) end--;
 
            if(start < end) { 
                if (typeName[start] =='[' && typeName[end] == ']') {
                    start++; 
                    end--;
                }

                // if we still have a ] at the end, there's no assembly info. 
                if (typeName[end] != ']') {
                    int commaCount = 0; 
                    for(int index = end; index >= start; index--) { 
                        if( typeName[index] == ',') {
                            commaCount++; 
                            if( commaCount == 4) {
                                result = typeName.Substring( start, index - start);
                                break;
                            } 
                        }
                    } 
                } 
            }
 
            return result;
        }
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

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