FixUpCollection.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 / Orcas / QFE / ndp / fx / src / DataWeb / Design / system / Data / EntityModel / Emitters / FixUpCollection.cs / 1 / FixUpCollection.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Collections; 
using System.Collections.Generic;
using System.Data.Services.Design;
using System.Diagnostics;
 
namespace System.Data.EntityModel.Emitters
{ 
    internal sealed class FixUpCollection : List 
    {
        #region Private Types 
        private enum CSDeclType
        {
            Method,
            Property, 
            Other,
        } 
        public enum VBStatementType 
        {
            BeginClass, 
            EndClass,
            BeginProperty,
            EndProperty,
            BeginMethod, 
            EndMethod,
            BeginPropertyGetter, 
            EndPropertyGetter, 
            BeginPropertySetter,
            EndPropertySetter, 
            Other,
        }
        #endregion
 
        #region Instance Fields
        private Dictionary> _classFixUps; 
        private LanguageOption _language; 
        #endregion
 
        #region Static Fields
        static readonly char[] _CSEndOfClassDelimiters = new char[] { ' ',':' };
        const string _CSClassKeyWord = " class ";
        static readonly char[] _CSFieldMarkers = new char[] { '=',';' }; 
        static readonly char[] _VBEndOfClassDelimiters = new char[] { ' ', '(' };
        static readonly char[] _VBNonDeclMarkers = new char[] { '=', '"', '\'' }; 
        #endregion 

        #region Public Methods 
        /// 
        ///
        /// 
        public FixUpCollection() 
        {
        } 
 
        public static bool IsLanguageSupported(LanguageOption language)
        { 
            switch ( language )
            {
                case LanguageOption.GenerateVBCode:
                case LanguageOption.GenerateCSharpCode: 
                    return true;
            } 
            return false; 
        }
 
        /// 
        ///
        /// 
        ///  
        /// 
        ///  
        public void Do(System.IO.TextReader reader, System.IO.TextWriter writer, LanguageOption language, bool hasNamespace) 
        {
            Language = language; 

            // set up the fix ups for each class.
            foreach ( FixUp fixUp in this )
            { 
                List fixUps = null;
                if ( ClassFixUps.ContainsKey(fixUp.Class) ) 
                { 
                    fixUps = ClassFixUps[fixUp.Class];
                } 
                else
                {
                    fixUps = new List();
                    ClassFixUps.Add(fixUp.Class,fixUps); 
                }
                fixUps.Add(fixUp); 
            } 

            switch ( Language ) 
            {
                case LanguageOption.GenerateVBCode:
                    DoFixUpsForVB(reader,writer);
                    break; 
                case LanguageOption.GenerateCSharpCode:
                    DoFixUpsForCS(reader, writer, hasNamespace); 
                    break; 
                default:
                    Debug.Assert(false,"Unexpected language value: "+Language.ToString()); 
                    CopyFile(reader,writer);
                    break;
            }
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        private static void CopyFile(System.IO.TextReader reader, System.IO.TextWriter writer)
        {
            string line; 
            while ( (line=reader.ReadLine()) != null )
                writer.WriteLine(line); 
        } 

        ///  
        ///
        /// 
        /// 
        ///  
        private void DoFixUpsForCS(System.IO.TextReader reader, System.IO.TextWriter writer, bool hasNamespace)
        { 
            int braceCount = 0; 
            string line;
            string nakedLine; 
            string currentOuterClass = null;
            string className;
            bool classWanted = false;
            FixUp getterFixUp = null; 
            FixUp setterFixUp = null;
            int nameSpaceLevel = hasNamespace ? 1 : 0; 
            while ((line = reader.ReadLine()) != null) 
            {
                nakedLine = line.Trim(); 
                if ( nakedLine == "{" )
                    ++braceCount;
                else if ( nakedLine == "}" )
                { 
                    --braceCount;
                    if (braceCount < nameSpaceLevel + 2) 
                    { 
                        setterFixUp = null;
                        if (braceCount < nameSpaceLevel + 1) 
                        {
                            currentOuterClass = null;
                            classWanted = false;
                        } 
                    }
                } 
                else if ( string.IsNullOrEmpty(nakedLine) || nakedLine.StartsWith("//",StringComparison.Ordinal) ) 
                {
                    // comment, just emit as is.... 
                }
                else if ( IsCSClassDefinition(line,out className) )
                {
                    if (braceCount == nameSpaceLevel) 
                    {
                        currentOuterClass = className; 
                        className = null; 
                        classWanted = IsClassWanted(currentOuterClass);
                        if ( classWanted ) 
                            line = FixUpClassDecl(currentOuterClass,line);
                    }
                }
                else if ( classWanted ) 
                {
                    //we only care about methods/properties in top level classes 
                    if (braceCount == nameSpaceLevel + 1) 
                    {
                        string name; 
                        switch ( GetCSDeclType(nakedLine,out name) )
                        {
                            case CSDeclType.Method:
                                line = FixUpMethodDecl(currentOuterClass,name,line); 
                                break;
                            case CSDeclType.Property: 
                                setterFixUp = FixUpSetter(currentOuterClass, name); 
                                getterFixUp = FixUpGetter(currentOuterClass, name);
                                break; 
                        }
                    }
                    else if (braceCount == nameSpaceLevel + 2)
                    { 
                        if (nakedLine == "set" && setterFixUp != null)
                        { 
                            line = setterFixUp.Fix(LanguageOption.GenerateCSharpCode, line); 
                            setterFixUp = null;
                        } 
                        else if (nakedLine == "get" && getterFixUp != null)
                        {
                            line = getterFixUp.Fix(LanguageOption.GenerateCSharpCode, line);
                            getterFixUp = null; 
                        }
                    } 
                } 
                writer.WriteLine(line);
            } 
        }

        /// 
        /// 
        /// 
        ///  
        ///  
        public void DoFixUpsForVB(System.IO.TextReader reader, System.IO.TextWriter writer)
        { 
            Language = LanguageOption.GenerateVBCode;

            string line;
            Stack context = new Stack(); 
            int classDepth = 0;
            string currentOuterClass = null; 
            bool classWanted = false; 
            FixUp getterFixUp = null;
            FixUp setterFixUp = null; 
            while ( (line=reader.ReadLine()) != null )
            {
                if ( line == null || line.Length == 0 || line[0] == '\'' )
                { 
                    // empty line or comment, ouput as is
                } 
                else 
                {
                    string name; 
                    switch ( GetVBStatementType(context, line, out name) )
                    {
                        case VBStatementType.BeginClass:
                            ++classDepth; 
                            setterFixUp = null;
                            if ( classDepth == 1 ) 
                            { 
                                currentOuterClass = name;
                                classWanted = IsClassWanted(name); 
                                if ( classWanted )
                                    line = FixUpClassDecl(currentOuterClass, line);
                            }
                            break; 

                        case VBStatementType.EndClass: 
                            --classDepth; 
                            if (classDepth == 0)
                            { 
                                currentOuterClass = null;
                            }
                            break;
 
                        case VBStatementType.BeginProperty:
                            if (classWanted) 
                            { 
                                getterFixUp = FixUpGetter(currentOuterClass, name);
                                setterFixUp = FixUpSetter(currentOuterClass, name); 
                            }
                            else
                            {
                                getterFixUp = null; 
                                setterFixUp = null;
                            } 
                            break; 

                        case VBStatementType.EndProperty: 
                            getterFixUp = null;
                            setterFixUp = null;
                            break;
 
                        case VBStatementType.BeginMethod:
                            if (classWanted) 
                            { 
                                line = FixUpMethodDecl(currentOuterClass, name, line);
                            } 
                            break;

                        case VBStatementType.BeginPropertySetter:
                            if (setterFixUp != null) 
                            {
                                line = setterFixUp.Fix(Language, line); 
                            } 
                            setterFixUp = null;
                            break; 

                        case VBStatementType.BeginPropertyGetter:
                            if (getterFixUp != null)
                            { 
                                line = getterFixUp.Fix(Language, line);
                            } 
                            getterFixUp = null; 
                            break;
                    } 
                }
                writer.WriteLine(line);
            }
        } 

        #endregion 
 
        #region Private Methods
        ///  
        ///
        /// 
        /// 
        ///  
        private bool IsClassWanted(string className)
        { 
            return ClassFixUps.ContainsKey(className); 
        }
 
        /// 
        ///
        /// 
        ///  
        /// 
        ///  
        private static bool IsCSClassDefinition(string line,out string className) 
        {
            int index = line.IndexOf(_CSClassKeyWord,StringComparison.Ordinal); 
            if ( index < 0 )
            {
                className = null;
                return false; 
            }
            index += _CSClassKeyWord.Length; 
            int end = line.IndexOfAny(_CSEndOfClassDelimiters, index); 
            if ( end < 0 )
                className = line.Substring(index); 
            else
                className = line.Substring(index,end-index);

 
            if (className.StartsWith("@", StringComparison.Ordinal))
            { 
                // remove the escaping mechanisim for C# keywords 
                className = className.Substring(1);
            } 

            return true;
        }
 
        /// 
        /// 
        ///  
        /// 
        ///  
        /// 
        private string FixUpClassDecl(string className,string line)
        {
            IList fixUps = ClassFixUps[className]; 
            foreach ( FixUp fixUp in fixUps )
            { 
                if ( fixUp.Type == FixUpType.MarkClassAsStatic ) 
                {
                    return fixUp.Fix(Language,line); 
                }
            }
            return line;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        /// 
        private static CSDeclType GetCSDeclType(string line, out string name)
        { 
            // we know we're at the class member level.
            // things we could encounter are (limited to things we actually emit): 
            //    nested classes (already identified) 
            //    attributes
            //    fields 
            //    methods
            //    properties

            name = null; 

            //Attributes 
            if (line[0] == '[') 
                return CSDeclType.Other;
 
            // Methods have ( and ) without a =
            int parIdx1 = line.IndexOf('(');
            int parIdx2 = line.IndexOf(')');
            int equIdx = line.IndexOf('='); //return -1 for absent equal sign. 

            if (equIdx == -1 && parIdx1 >= 0 && parIdx2 > parIdx1) 
            { 
                line = line.Substring(0, parIdx1).TrimEnd(null);
                name = line.Substring(line.LastIndexOf(' ') + 1); 
                return CSDeclType.Method;
            }

            //we assume fields have = or ; 
            if (line.IndexOfAny(_CSFieldMarkers, 0) >= 0)
                return CSDeclType.Other; 
 
            //Properties
            CSDeclType declType = CSDeclType.Property; 
            name = line.Substring(line.LastIndexOf(' ') + 1);
            return declType;
        }
 
        /// 
        /// 
        ///  
        /// 
        ///  
        /// 
        /// 
        private string FixUpMethodDecl(string className,string methodName,string line)
        { 
            IList fixUps = ClassFixUps[className];
            foreach ( FixUp fixUp in fixUps ) 
            { 
                if ( fixUp.Method == methodName &&
                    (fixUp.Type == FixUpType.MarkOverrideMethodAsSealed || fixUp.Type == FixUpType.MarkAbstractMethodAsPartial) ) 
                {
                    return fixUp.Fix(Language,line);
                }
            } 
            return line;
        } 
 
        /// 
        /// 
        /// 
        /// 
        /// 
        ///  
        private FixUp FixUpSetter(string className,string propertyName)
        { 
            IList fixUps = ClassFixUps[className]; 
            foreach ( FixUp fixUp in fixUps )
            { 
                if (fixUp.Property == propertyName &&
                    (fixUp.Type == FixUpType.MarkPropertySetAsPrivate ||
                     fixUp.Type == FixUpType.MarkPropertySetAsInternal ||
                     fixUp.Type == FixUpType.MarkPropertySetAsPublic || 
                     fixUp.Type == FixUpType.MarkPropertySetAsProtected))
                { 
                    return fixUp; 
                }
            } 
            return null;
        }

        private FixUp FixUpGetter(string className, string propertyName) 
        {
            IList fixUps = ClassFixUps[className]; 
            foreach (FixUp fixUp in fixUps) 
            {
                if (fixUp.Property == propertyName && 
                    (fixUp.Type == FixUpType.MarkPropertyGetAsPrivate ||
                     fixUp.Type == FixUpType.MarkPropertyGetAsInternal ||
                     fixUp.Type == FixUpType.MarkPropertyGetAsPublic ||
                     fixUp.Type == FixUpType.MarkPropertyGetAsProtected)) 
                {
                    return fixUp; 
                } 
            }
            return null; 
        }
        /// 
        ///
        ///  
        /// 
        ///  
        ///  
        /// 
        private static VBStatementType GetVBStatementType(Stack context, string line, out string name) 
        {
            name = null;
            VBStatementType current = VBStatementType.Other;
 
            // if the statement constains ", =, or... then it's not a statement type we care about
            if ( line.IndexOfAny(_VBNonDeclMarkers) >= 0 ) 
                return current; 

 
            string normalizedLine = NormalizeForVB(line);

            if ( context.Count <= 0 )
            { 
                // without context we only accept BeginClass
                if ( LineIsVBBeginClassMethodProperty(normalizedLine, "Class", ref name) ) 
                { 
                    current = VBStatementType.BeginClass;
                    context.Push(current); 
                }
            }
            else
            { 
                // we only look for things based on context:
                switch ( context.Peek() ) 
                { 
                    // at BeginClass we only accept
                    //    BeginClass 
                    //    EndClass
                    //    BeginProperty
                    //    BeginMethod
                    case VBStatementType.BeginClass: 
                        if ( normalizedLine == "End Class" )
                        { 
                            current = VBStatementType.EndClass; 
                            context.Pop();
                        } 
                        else
                        {
                            if ( LineIsVBBeginClassMethodProperty(normalizedLine, "Class", ref name) )
                            { 
                                current = VBStatementType.BeginClass;
                                context.Push(current); 
                            } 
                            else if ( LineIsVBBeginClassMethodProperty(normalizedLine, "MustOverride Sub", ref name) )
                            { 
                                // Abstract methods do not have an "End Sub", this don't push the context.
                                current = VBStatementType.BeginMethod;
                            }
                            else if ( LineIsVBBeginClassMethodProperty(normalizedLine, "Function", ref name) 
                                || LineIsVBBeginClassMethodProperty(normalizedLine, "Sub", ref name) )
                            { 
                                current = VBStatementType.BeginMethod; 
                                context.Push(current);
                            } 
                            else if ( LineIsVBBeginClassMethodProperty(normalizedLine, "Property", ref name) )
                            {
                                current = VBStatementType.BeginProperty;
                                context.Push(current); 
                            }
                        } 
                        break; 

                    // at BeginProperty we only accept 
                    //    EndProperty
                    //    BeginPropertyGetter
                    //    BeginPropertySetter
                    case VBStatementType.BeginProperty: 
                        if ( normalizedLine == "End Property" )
                        { 
                            current = VBStatementType.EndProperty; 
                            context.Pop();
                        } 
                        else
                        {
                            if ( LineIsVBBeginSetterGetter(normalizedLine, "Get") )
                            { 
                                current = VBStatementType.BeginPropertyGetter;
                                context.Push(current); 
                            } 
                            else if ( LineIsVBBeginSetterGetter(normalizedLine, "Set") )
                            { 
                                current = VBStatementType.BeginPropertySetter;
                                context.Push(current);
                            }
                        } 
                        break;
 
                    // at BeginMethod we only accept 
                    //    EndMethod
                    case VBStatementType.BeginMethod: 
                        if ( normalizedLine == "End Sub" || normalizedLine == "End Function" )
                        {
                            current = VBStatementType.EndMethod;
                            context.Pop(); 
                        }
                        break; 
 
                    // at BeginPropertyGetter we only accept
                    //    EndPropertyGetter 
                    case VBStatementType.BeginPropertyGetter:
                        if ( normalizedLine == "End Get" )
                        {
                            current = VBStatementType.EndPropertyGetter; 
                            context.Pop();
                        } 
                        break; 

                    // at BeginPropertySetter we only accept 
                    //    EndPropertySetter
                    case VBStatementType.BeginPropertySetter:
                        if ( normalizedLine == "End Set" )
                        { 
                            current = VBStatementType.EndPropertySetter;
                            context.Pop(); 
                        } 
                        break;
                } 
            }

            return current;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        private static string NormalizeForVB(string line)
        {
            // no leading or trailing spaces and tabs are replaced with spaces 
            line = line.Replace('\t', ' ').Trim();
 
            // consecutuve spaces are replaced with single spaces... 
            // (we don't care about hammering strings; we just use the normalized line for statment identification...
            while ( line.IndexOf("  ", 0,StringComparison.Ordinal) >= 0 ) 
                line = line.Replace("  ", " ");

            return line;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        /// 
        private static bool LineIsVBBeginSetterGetter(string line, string keyword)
        { 
            return IndexOfKeyword(line, keyword) >= 0;
        } 
 
        /// 
        /// 
        /// 
        /// 
        /// 
        ///  
        private static int IndexOfKeyword(string line, string keyword)
        { 
            int index = line.IndexOf(keyword,StringComparison.Ordinal); 
            if ( index < 0 )
                return index; 

            char ch;
            int indexAfter = index+keyword.Length;
            if ( (index == 0 || char.IsWhiteSpace(line, index-1)) && (indexAfter == line.Length || (ch=line[indexAfter]) == '(' || char.IsWhiteSpace(ch)) ) 
                return index;
 
            return -1; 
        }
 
        /// 
        ///
        /// 
        ///  
        /// 
        ///  
        ///  
        private static bool LineIsVBBeginClassMethodProperty(string line, string keyword, ref string name)
        { 
            // line must contain the keyword
            int index = IndexOfKeyword(line, keyword);
            if ( index < 0 )
                return false; 

            // after the keyword we expact a space and the name 
            index += keyword.Length; 
            if ( index >= line.Length || !char.IsWhiteSpace(line, index) )
                return false; 
            ++index;
            if ( index >= line.Length )
                return false;
 
            // after the name we expect a EOL or a delimiter...
            int end = line.IndexOfAny(_VBEndOfClassDelimiters, index); 
            if ( end < 0 ) 
                end = line.Length;
 
            name = line.Substring(index, end-index).Trim();

            if (name.StartsWith("[", StringComparison.Ordinal) && name.EndsWith("]", StringComparison.Ordinal))
            { 
                // remove the vb keyword escaping mechanisim
                name = name.Substring(1, name.Length - 2); 
            } 

            return true; 
        }
        #endregion

        #region Private Properties 
        /// 
        /// 
        ///  
        private LanguageOption Language
        { 
            get
            {
                return _language;
            } 
            set
            { 
                _language = value; 
            }
        } 

        /// 
        ///
        ///  
        /// 
        private Dictionary> ClassFixUps 
        { 
            get
            { 
                if ( _classFixUps == null )
                {
                    _classFixUps = new Dictionary>();
                } 

                return _classFixUps; 
            } 
        }
        #endregion 
    }
}

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

using System.Collections; 
using System.Collections.Generic;
using System.Data.Services.Design;
using System.Diagnostics;
 
namespace System.Data.EntityModel.Emitters
{ 
    internal sealed class FixUpCollection : List 
    {
        #region Private Types 
        private enum CSDeclType
        {
            Method,
            Property, 
            Other,
        } 
        public enum VBStatementType 
        {
            BeginClass, 
            EndClass,
            BeginProperty,
            EndProperty,
            BeginMethod, 
            EndMethod,
            BeginPropertyGetter, 
            EndPropertyGetter, 
            BeginPropertySetter,
            EndPropertySetter, 
            Other,
        }
        #endregion
 
        #region Instance Fields
        private Dictionary> _classFixUps; 
        private LanguageOption _language; 
        #endregion
 
        #region Static Fields
        static readonly char[] _CSEndOfClassDelimiters = new char[] { ' ',':' };
        const string _CSClassKeyWord = " class ";
        static readonly char[] _CSFieldMarkers = new char[] { '=',';' }; 
        static readonly char[] _VBEndOfClassDelimiters = new char[] { ' ', '(' };
        static readonly char[] _VBNonDeclMarkers = new char[] { '=', '"', '\'' }; 
        #endregion 

        #region Public Methods 
        /// 
        ///
        /// 
        public FixUpCollection() 
        {
        } 
 
        public static bool IsLanguageSupported(LanguageOption language)
        { 
            switch ( language )
            {
                case LanguageOption.GenerateVBCode:
                case LanguageOption.GenerateCSharpCode: 
                    return true;
            } 
            return false; 
        }
 
        /// 
        ///
        /// 
        ///  
        /// 
        ///  
        public void Do(System.IO.TextReader reader, System.IO.TextWriter writer, LanguageOption language, bool hasNamespace) 
        {
            Language = language; 

            // set up the fix ups for each class.
            foreach ( FixUp fixUp in this )
            { 
                List fixUps = null;
                if ( ClassFixUps.ContainsKey(fixUp.Class) ) 
                { 
                    fixUps = ClassFixUps[fixUp.Class];
                } 
                else
                {
                    fixUps = new List();
                    ClassFixUps.Add(fixUp.Class,fixUps); 
                }
                fixUps.Add(fixUp); 
            } 

            switch ( Language ) 
            {
                case LanguageOption.GenerateVBCode:
                    DoFixUpsForVB(reader,writer);
                    break; 
                case LanguageOption.GenerateCSharpCode:
                    DoFixUpsForCS(reader, writer, hasNamespace); 
                    break; 
                default:
                    Debug.Assert(false,"Unexpected language value: "+Language.ToString()); 
                    CopyFile(reader,writer);
                    break;
            }
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        private static void CopyFile(System.IO.TextReader reader, System.IO.TextWriter writer)
        {
            string line; 
            while ( (line=reader.ReadLine()) != null )
                writer.WriteLine(line); 
        } 

        ///  
        ///
        /// 
        /// 
        ///  
        private void DoFixUpsForCS(System.IO.TextReader reader, System.IO.TextWriter writer, bool hasNamespace)
        { 
            int braceCount = 0; 
            string line;
            string nakedLine; 
            string currentOuterClass = null;
            string className;
            bool classWanted = false;
            FixUp getterFixUp = null; 
            FixUp setterFixUp = null;
            int nameSpaceLevel = hasNamespace ? 1 : 0; 
            while ((line = reader.ReadLine()) != null) 
            {
                nakedLine = line.Trim(); 
                if ( nakedLine == "{" )
                    ++braceCount;
                else if ( nakedLine == "}" )
                { 
                    --braceCount;
                    if (braceCount < nameSpaceLevel + 2) 
                    { 
                        setterFixUp = null;
                        if (braceCount < nameSpaceLevel + 1) 
                        {
                            currentOuterClass = null;
                            classWanted = false;
                        } 
                    }
                } 
                else if ( string.IsNullOrEmpty(nakedLine) || nakedLine.StartsWith("//",StringComparison.Ordinal) ) 
                {
                    // comment, just emit as is.... 
                }
                else if ( IsCSClassDefinition(line,out className) )
                {
                    if (braceCount == nameSpaceLevel) 
                    {
                        currentOuterClass = className; 
                        className = null; 
                        classWanted = IsClassWanted(currentOuterClass);
                        if ( classWanted ) 
                            line = FixUpClassDecl(currentOuterClass,line);
                    }
                }
                else if ( classWanted ) 
                {
                    //we only care about methods/properties in top level classes 
                    if (braceCount == nameSpaceLevel + 1) 
                    {
                        string name; 
                        switch ( GetCSDeclType(nakedLine,out name) )
                        {
                            case CSDeclType.Method:
                                line = FixUpMethodDecl(currentOuterClass,name,line); 
                                break;
                            case CSDeclType.Property: 
                                setterFixUp = FixUpSetter(currentOuterClass, name); 
                                getterFixUp = FixUpGetter(currentOuterClass, name);
                                break; 
                        }
                    }
                    else if (braceCount == nameSpaceLevel + 2)
                    { 
                        if (nakedLine == "set" && setterFixUp != null)
                        { 
                            line = setterFixUp.Fix(LanguageOption.GenerateCSharpCode, line); 
                            setterFixUp = null;
                        } 
                        else if (nakedLine == "get" && getterFixUp != null)
                        {
                            line = getterFixUp.Fix(LanguageOption.GenerateCSharpCode, line);
                            getterFixUp = null; 
                        }
                    } 
                } 
                writer.WriteLine(line);
            } 
        }

        /// 
        /// 
        /// 
        ///  
        ///  
        public void DoFixUpsForVB(System.IO.TextReader reader, System.IO.TextWriter writer)
        { 
            Language = LanguageOption.GenerateVBCode;

            string line;
            Stack context = new Stack(); 
            int classDepth = 0;
            string currentOuterClass = null; 
            bool classWanted = false; 
            FixUp getterFixUp = null;
            FixUp setterFixUp = null; 
            while ( (line=reader.ReadLine()) != null )
            {
                if ( line == null || line.Length == 0 || line[0] == '\'' )
                { 
                    // empty line or comment, ouput as is
                } 
                else 
                {
                    string name; 
                    switch ( GetVBStatementType(context, line, out name) )
                    {
                        case VBStatementType.BeginClass:
                            ++classDepth; 
                            setterFixUp = null;
                            if ( classDepth == 1 ) 
                            { 
                                currentOuterClass = name;
                                classWanted = IsClassWanted(name); 
                                if ( classWanted )
                                    line = FixUpClassDecl(currentOuterClass, line);
                            }
                            break; 

                        case VBStatementType.EndClass: 
                            --classDepth; 
                            if (classDepth == 0)
                            { 
                                currentOuterClass = null;
                            }
                            break;
 
                        case VBStatementType.BeginProperty:
                            if (classWanted) 
                            { 
                                getterFixUp = FixUpGetter(currentOuterClass, name);
                                setterFixUp = FixUpSetter(currentOuterClass, name); 
                            }
                            else
                            {
                                getterFixUp = null; 
                                setterFixUp = null;
                            } 
                            break; 

                        case VBStatementType.EndProperty: 
                            getterFixUp = null;
                            setterFixUp = null;
                            break;
 
                        case VBStatementType.BeginMethod:
                            if (classWanted) 
                            { 
                                line = FixUpMethodDecl(currentOuterClass, name, line);
                            } 
                            break;

                        case VBStatementType.BeginPropertySetter:
                            if (setterFixUp != null) 
                            {
                                line = setterFixUp.Fix(Language, line); 
                            } 
                            setterFixUp = null;
                            break; 

                        case VBStatementType.BeginPropertyGetter:
                            if (getterFixUp != null)
                            { 
                                line = getterFixUp.Fix(Language, line);
                            } 
                            getterFixUp = null; 
                            break;
                    } 
                }
                writer.WriteLine(line);
            }
        } 

        #endregion 
 
        #region Private Methods
        ///  
        ///
        /// 
        /// 
        ///  
        private bool IsClassWanted(string className)
        { 
            return ClassFixUps.ContainsKey(className); 
        }
 
        /// 
        ///
        /// 
        ///  
        /// 
        ///  
        private static bool IsCSClassDefinition(string line,out string className) 
        {
            int index = line.IndexOf(_CSClassKeyWord,StringComparison.Ordinal); 
            if ( index < 0 )
            {
                className = null;
                return false; 
            }
            index += _CSClassKeyWord.Length; 
            int end = line.IndexOfAny(_CSEndOfClassDelimiters, index); 
            if ( end < 0 )
                className = line.Substring(index); 
            else
                className = line.Substring(index,end-index);

 
            if (className.StartsWith("@", StringComparison.Ordinal))
            { 
                // remove the escaping mechanisim for C# keywords 
                className = className.Substring(1);
            } 

            return true;
        }
 
        /// 
        /// 
        ///  
        /// 
        ///  
        /// 
        private string FixUpClassDecl(string className,string line)
        {
            IList fixUps = ClassFixUps[className]; 
            foreach ( FixUp fixUp in fixUps )
            { 
                if ( fixUp.Type == FixUpType.MarkClassAsStatic ) 
                {
                    return fixUp.Fix(Language,line); 
                }
            }
            return line;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        /// 
        private static CSDeclType GetCSDeclType(string line, out string name)
        { 
            // we know we're at the class member level.
            // things we could encounter are (limited to things we actually emit): 
            //    nested classes (already identified) 
            //    attributes
            //    fields 
            //    methods
            //    properties

            name = null; 

            //Attributes 
            if (line[0] == '[') 
                return CSDeclType.Other;
 
            // Methods have ( and ) without a =
            int parIdx1 = line.IndexOf('(');
            int parIdx2 = line.IndexOf(')');
            int equIdx = line.IndexOf('='); //return -1 for absent equal sign. 

            if (equIdx == -1 && parIdx1 >= 0 && parIdx2 > parIdx1) 
            { 
                line = line.Substring(0, parIdx1).TrimEnd(null);
                name = line.Substring(line.LastIndexOf(' ') + 1); 
                return CSDeclType.Method;
            }

            //we assume fields have = or ; 
            if (line.IndexOfAny(_CSFieldMarkers, 0) >= 0)
                return CSDeclType.Other; 
 
            //Properties
            CSDeclType declType = CSDeclType.Property; 
            name = line.Substring(line.LastIndexOf(' ') + 1);
            return declType;
        }
 
        /// 
        /// 
        ///  
        /// 
        ///  
        /// 
        /// 
        private string FixUpMethodDecl(string className,string methodName,string line)
        { 
            IList fixUps = ClassFixUps[className];
            foreach ( FixUp fixUp in fixUps ) 
            { 
                if ( fixUp.Method == methodName &&
                    (fixUp.Type == FixUpType.MarkOverrideMethodAsSealed || fixUp.Type == FixUpType.MarkAbstractMethodAsPartial) ) 
                {
                    return fixUp.Fix(Language,line);
                }
            } 
            return line;
        } 
 
        /// 
        /// 
        /// 
        /// 
        /// 
        ///  
        private FixUp FixUpSetter(string className,string propertyName)
        { 
            IList fixUps = ClassFixUps[className]; 
            foreach ( FixUp fixUp in fixUps )
            { 
                if (fixUp.Property == propertyName &&
                    (fixUp.Type == FixUpType.MarkPropertySetAsPrivate ||
                     fixUp.Type == FixUpType.MarkPropertySetAsInternal ||
                     fixUp.Type == FixUpType.MarkPropertySetAsPublic || 
                     fixUp.Type == FixUpType.MarkPropertySetAsProtected))
                { 
                    return fixUp; 
                }
            } 
            return null;
        }

        private FixUp FixUpGetter(string className, string propertyName) 
        {
            IList fixUps = ClassFixUps[className]; 
            foreach (FixUp fixUp in fixUps) 
            {
                if (fixUp.Property == propertyName && 
                    (fixUp.Type == FixUpType.MarkPropertyGetAsPrivate ||
                     fixUp.Type == FixUpType.MarkPropertyGetAsInternal ||
                     fixUp.Type == FixUpType.MarkPropertyGetAsPublic ||
                     fixUp.Type == FixUpType.MarkPropertyGetAsProtected)) 
                {
                    return fixUp; 
                } 
            }
            return null; 
        }
        /// 
        ///
        ///  
        /// 
        ///  
        ///  
        /// 
        private static VBStatementType GetVBStatementType(Stack context, string line, out string name) 
        {
            name = null;
            VBStatementType current = VBStatementType.Other;
 
            // if the statement constains ", =, or... then it's not a statement type we care about
            if ( line.IndexOfAny(_VBNonDeclMarkers) >= 0 ) 
                return current; 

 
            string normalizedLine = NormalizeForVB(line);

            if ( context.Count <= 0 )
            { 
                // without context we only accept BeginClass
                if ( LineIsVBBeginClassMethodProperty(normalizedLine, "Class", ref name) ) 
                { 
                    current = VBStatementType.BeginClass;
                    context.Push(current); 
                }
            }
            else
            { 
                // we only look for things based on context:
                switch ( context.Peek() ) 
                { 
                    // at BeginClass we only accept
                    //    BeginClass 
                    //    EndClass
                    //    BeginProperty
                    //    BeginMethod
                    case VBStatementType.BeginClass: 
                        if ( normalizedLine == "End Class" )
                        { 
                            current = VBStatementType.EndClass; 
                            context.Pop();
                        } 
                        else
                        {
                            if ( LineIsVBBeginClassMethodProperty(normalizedLine, "Class", ref name) )
                            { 
                                current = VBStatementType.BeginClass;
                                context.Push(current); 
                            } 
                            else if ( LineIsVBBeginClassMethodProperty(normalizedLine, "MustOverride Sub", ref name) )
                            { 
                                // Abstract methods do not have an "End Sub", this don't push the context.
                                current = VBStatementType.BeginMethod;
                            }
                            else if ( LineIsVBBeginClassMethodProperty(normalizedLine, "Function", ref name) 
                                || LineIsVBBeginClassMethodProperty(normalizedLine, "Sub", ref name) )
                            { 
                                current = VBStatementType.BeginMethod; 
                                context.Push(current);
                            } 
                            else if ( LineIsVBBeginClassMethodProperty(normalizedLine, "Property", ref name) )
                            {
                                current = VBStatementType.BeginProperty;
                                context.Push(current); 
                            }
                        } 
                        break; 

                    // at BeginProperty we only accept 
                    //    EndProperty
                    //    BeginPropertyGetter
                    //    BeginPropertySetter
                    case VBStatementType.BeginProperty: 
                        if ( normalizedLine == "End Property" )
                        { 
                            current = VBStatementType.EndProperty; 
                            context.Pop();
                        } 
                        else
                        {
                            if ( LineIsVBBeginSetterGetter(normalizedLine, "Get") )
                            { 
                                current = VBStatementType.BeginPropertyGetter;
                                context.Push(current); 
                            } 
                            else if ( LineIsVBBeginSetterGetter(normalizedLine, "Set") )
                            { 
                                current = VBStatementType.BeginPropertySetter;
                                context.Push(current);
                            }
                        } 
                        break;
 
                    // at BeginMethod we only accept 
                    //    EndMethod
                    case VBStatementType.BeginMethod: 
                        if ( normalizedLine == "End Sub" || normalizedLine == "End Function" )
                        {
                            current = VBStatementType.EndMethod;
                            context.Pop(); 
                        }
                        break; 
 
                    // at BeginPropertyGetter we only accept
                    //    EndPropertyGetter 
                    case VBStatementType.BeginPropertyGetter:
                        if ( normalizedLine == "End Get" )
                        {
                            current = VBStatementType.EndPropertyGetter; 
                            context.Pop();
                        } 
                        break; 

                    // at BeginPropertySetter we only accept 
                    //    EndPropertySetter
                    case VBStatementType.BeginPropertySetter:
                        if ( normalizedLine == "End Set" )
                        { 
                            current = VBStatementType.EndPropertySetter;
                            context.Pop(); 
                        } 
                        break;
                } 
            }

            return current;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        private static string NormalizeForVB(string line)
        {
            // no leading or trailing spaces and tabs are replaced with spaces 
            line = line.Replace('\t', ' ').Trim();
 
            // consecutuve spaces are replaced with single spaces... 
            // (we don't care about hammering strings; we just use the normalized line for statment identification...
            while ( line.IndexOf("  ", 0,StringComparison.Ordinal) >= 0 ) 
                line = line.Replace("  ", " ");

            return line;
        } 

        ///  
        /// 
        /// 
        ///  
        /// 
        /// 
        private static bool LineIsVBBeginSetterGetter(string line, string keyword)
        { 
            return IndexOfKeyword(line, keyword) >= 0;
        } 
 
        /// 
        /// 
        /// 
        /// 
        /// 
        ///  
        private static int IndexOfKeyword(string line, string keyword)
        { 
            int index = line.IndexOf(keyword,StringComparison.Ordinal); 
            if ( index < 0 )
                return index; 

            char ch;
            int indexAfter = index+keyword.Length;
            if ( (index == 0 || char.IsWhiteSpace(line, index-1)) && (indexAfter == line.Length || (ch=line[indexAfter]) == '(' || char.IsWhiteSpace(ch)) ) 
                return index;
 
            return -1; 
        }
 
        /// 
        ///
        /// 
        ///  
        /// 
        ///  
        ///  
        private static bool LineIsVBBeginClassMethodProperty(string line, string keyword, ref string name)
        { 
            // line must contain the keyword
            int index = IndexOfKeyword(line, keyword);
            if ( index < 0 )
                return false; 

            // after the keyword we expact a space and the name 
            index += keyword.Length; 
            if ( index >= line.Length || !char.IsWhiteSpace(line, index) )
                return false; 
            ++index;
            if ( index >= line.Length )
                return false;
 
            // after the name we expect a EOL or a delimiter...
            int end = line.IndexOfAny(_VBEndOfClassDelimiters, index); 
            if ( end < 0 ) 
                end = line.Length;
 
            name = line.Substring(index, end-index).Trim();

            if (name.StartsWith("[", StringComparison.Ordinal) && name.EndsWith("]", StringComparison.Ordinal))
            { 
                // remove the vb keyword escaping mechanisim
                name = name.Substring(1, name.Length - 2); 
            } 

            return true; 
        }
        #endregion

        #region Private Properties 
        /// 
        /// 
        ///  
        private LanguageOption Language
        { 
            get
            {
                return _language;
            } 
            set
            { 
                _language = value; 
            }
        } 

        /// 
        ///
        ///  
        /// 
        private Dictionary> ClassFixUps 
        { 
            get
            { 
                if ( _classFixUps == null )
                {
                    _classFixUps = new Dictionary>();
                } 

                return _classFixUps; 
            } 
        }
        #endregion 
    }
}

// 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