Interface implementation definition for type and member references to interfaces and interface members.
Inheritance: ICloneable
Esempio n. 1
0
 /// <summary>
 /// Adds an item to the Implements collection.
 /// </summary>
 /// <param name="implementation">The implementation.</param>
 public void AddImplementation(InterfaceReference implementation)
 {
     if (implementation != null)
     {
         ImplementsBase.Add(implementation);
     }
 }
Esempio n. 2
0
 /// <summary>
 /// Adds an interface implementation to the type definition.
 /// </summary>
 /// <param name="interfaceReference">The interface reference.</param>
 public void AddInterface(InterfaceReference interfaceReference)
 {
     if (interfaceReference != null)
     {
         BaseInterfaces.Add(interfaceReference);
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Creates a clone of this instance.
        /// </summary>
        /// <returns>
        /// Clone of the instance with the member element state copied.
        /// </returns>
        protected override sealed MemberElement DoMemberClone()
        {
            InterfaceMemberElement clone = DoInterfaceMemberClone();

            foreach (InterfaceReference implementation in Implements)
            {
                InterfaceReference implementationClone = implementation.Clone() as InterfaceReference;
                clone.ImplementsBase.Add(implementation);
            }

            return(clone);
        }
Esempio n. 4
0
        /// <summary>
        /// Creates a clone of this instance
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone()
        {
            InterfaceReference clone = new InterfaceReference();

            //
            // Copy state
            //
            clone._name = _name;
            clone._referenceType = _referenceType;

            return clone;
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a clone of this instance
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone()
        {
            InterfaceReference clone = new InterfaceReference();

            //
            // Copy state
            //
            clone._name          = _name;
            clone._referenceType = _referenceType;

            return(clone);
        }
Esempio n. 6
0
        /// <summary>
        /// Clones an attributed element.
        /// </summary>
        /// <returns>Cloned attribute element state.</returns>
        protected override AttributedElement DoAttributedClone()
        {
            TypeElement clone = new TypeElement();

            //
            // Copy state
            //
            clone._typeModifiers = _typeModifiers;
            clone._type          = _type;
            foreach (InterfaceReference interfaceReference in Interfaces)
            {
                InterfaceReference referenceClone = interfaceReference.Clone() as InterfaceReference;
                clone.AddInterface(referenceClone);
            }
            foreach (TypeParameter typeParam in TypeParameters)
            {
                TypeParameter typeParamClone = typeParam.Clone() as TypeParameter;
                clone.TypeParametersBase.Add(typeParamClone);
            }

            return(clone);
        }
Esempio n. 7
0
        /// <summary>
        /// Parses a property.
        /// </summary>
        /// <param name="access">The access.</param>
        /// <param name="memberAttributes">The member attributes.</param>
        /// <param name="isDefault">Whether or not the property is a default property</param>
        /// <param name="modifyAccess">The modify access.</param>
        /// <param name="inInterface">Whether or not the property is part of an interface.</param>
        /// <returns>A property code element.</returns>
        private PropertyElement ParseProperty(
            CodeAccess access,
            MemberModifiers memberAttributes,
            bool isDefault,
            string modifyAccess,
            bool inInterface)
        {
            PropertyElement property = new PropertyElement();
            property.Name = CaptureWord();
            property.Access = access;
            property.MemberModifiers = memberAttributes;
            property[VBExtendedProperties.Default] = isDefault;
            property[VBExtendedProperties.AccessModifier] = modifyAccess;

            EatLineContinuation();

            if (NextChar == VBSymbol.BeginParameterList)
            {
                string indexParam = this.ParseParams();
                if (indexParam.Length > 0)
                {
                    property.IndexParameter = indexParam;
                }
            }

            EatWord(VBKeyword.As, "Expected As");

            string type = CaptureTypeName();
            if (string.IsNullOrEmpty(type))
            {
                this.OnParseError("Expected return type");
            }

            property.Type = type;

            string[] implements;
            string blockTemp = TryParseImplements(out implements);
            foreach (string implementation in implements)
            {
                InterfaceReference interfaceReference =
                    new InterfaceReference(implementation, InterfaceReferenceType.Interface);
                property.AddImplementation(interfaceReference);
            }

            if ((memberAttributes & MemberModifiers.Abstract) != MemberModifiers.Abstract &&
                !inInterface)
            {
                property.BodyText = (blockTemp + this.ParseBlock(VBKeyword.Property)).Trim();
            }

            return property;
        }
Esempio n. 8
0
        /// <summary>
        /// Parses a method.
        /// </summary>
        /// <param name="access">The member access.</param>
        /// <param name="memberAttributes">The member attributes.</param>
        /// <param name="isFunction">Whether or not the method is a function.</param>
        /// <param name="isDelegate">Whether or not the method is a delegate.</param>
        /// <param name="isOperator">Whether or not the method is an operator.</param>
        /// <param name="operatorType">Type of the operator.</param>
        /// <param name="inInterface">Whether or not the method is in an interface.</param>
        /// <param name="isExternal">Whether or not the method is external.</param>
        /// <param name="externalModifier">The external modifier.</param>
        /// <returns>A method element.</returns>
        private MethodElement ParseMethod(
            CodeAccess access,
            MemberModifiers memberAttributes,
            bool isFunction,
            bool isDelegate,
            bool isOperator,
            OperatorType operatorType,
            bool inInterface,
            bool isExternal,
            string externalModifier)
        {
            MethodElement method = new MethodElement();

            method.Name = CaptureWord();
            if (isOperator)
            {
                // Handle greater than/less than for the method name since these will get
                // excluded with < and > being alias breaks (needed by attributes).
                while (NextChar == VBSymbol.BeginAttribute || NextChar == VBSymbol.EndAttribute)
                {
                    TryReadChar();
                    method.Name += CurrentChar + CaptureWord();
                }
            }

            method.Access = access;
            method.MemberModifiers = memberAttributes;

            method.IsOperator = isOperator;
            method.OperatorType = operatorType;
            method[VBExtendedProperties.ExternalModifier] = externalModifier;

            if (isExternal)
            {
                method.MemberModifiers = method.MemberModifiers | MemberModifiers.External;

                EatLineContinuation();

                EatWord(VBKeyword.Lib);

                EatLineContinuation();

                EatChar(VBSymbol.BeginString);
                string library = CaptureWord().TrimEnd(VBSymbol.BeginString);

                method[VBExtendedProperties.ExternalLibrary] = library;

                EatLineContinuation();

                if (NextChar != VBSymbol.BeginParameterList)
                {
                    EatLineContinuation();

                    EatWord(VBKeyword.Alias);

                    EatLineContinuation();

                    EatChar(VBSymbol.BeginString);
                    string alias = CaptureWord().TrimEnd(VBSymbol.BeginString);

                    method[VBExtendedProperties.ExternalAlias] = alias;
                }
            }

            EatLineContinuation();

            EatChar(VBSymbol.BeginParameterList);
            EatWhiteSpace();
            string paramsTemp = string.Empty;

            if (char.ToLower(NextChar) == char.ToLower(VBKeyword.Of[0]))
            {
                TryReadChar();
                paramsTemp += CurrentChar;

                if (char.ToLower(NextChar) == char.ToLower(VBKeyword.Of[1]))
                {
                    TryReadChar();
                    paramsTemp = string.Empty;

                    this.ParseTypeParameters(method);

                    EatChar(VBSymbol.BeginParameterList);
                    EatWhiteSpace();
                }
            }

            method.Parameters = paramsTemp + ParseNestedText(
                VBSymbol.BeginParameterList, VBSymbol.EndParameterList, false, false);

            if (isFunction || isOperator)
            {
                EatLineContinuation();
                if (char.ToUpper(NextChar) == VBKeyword.As[0])
                {
                    EatWord(VBKeyword.As);
                    method.Type = CaptureTypeName();
                }
                else
                {
                    method.Type = string.Empty;
                }
            }

            EatWhiteSpace();

            string[] implements;
            string[] handles;
            bool parseHandles = !(isFunction || isOperator || isDelegate);
            string blockTemp = TryParseImplementsOrHandles(out implements, out handles, parseHandles);
            if (parseHandles)
            {
                method[VBExtendedProperties.Handles] = handles;
            }

            foreach (string implementation in implements)
            {
                InterfaceReference interfaceReference =
                     new InterfaceReference(implementation, InterfaceReferenceType.Interface);
                method.AddImplementation(interfaceReference);
            }

            if ((memberAttributes & MemberModifiers.Abstract) != MemberModifiers.Abstract &&
                !inInterface && !isExternal)
            {
                if (isFunction || isOperator)
                {
                    if (isOperator)
                    {
                        method.BodyText = (blockTemp + this.ParseBlock(VBKeyword.Operator)).Trim();
                    }
                    else if (!isDelegate)
                    {
                        method.BodyText = (blockTemp + this.ParseBlock(VBKeyword.Function)).Trim();
                    }
                }
                else if (!isDelegate)
                {
                    method.BodyText = (blockTemp + this.ParseBlock(VBKeyword.Sub)).Trim();
                }
            }

            return method;
        }
Esempio n. 9
0
        /// <summary>
        /// Parses an event.
        /// </summary>
        /// <param name="access">The event access.</param>
        /// <param name="memberAttributes">The member attributes.</param>
        /// <param name="isCustom">Whether or not the event is custom.</param>
        /// <returns>An event code element.</returns>
        private EventElement ParseEvent(
            CodeAccess access, MemberModifiers memberAttributes, bool isCustom)
        {
            EventElement eventElement = new EventElement();
            string name = CaptureWord();
            eventElement.Name = name;
            eventElement.Access = access;
            eventElement.MemberModifiers = memberAttributes;

            EatWhiteSpace(WhiteSpaceTypes.SpaceAndTab);
            if (NextChar == VBSymbol.BeginParameterList)
            {
                eventElement.Parameters = ParseNestedText(
                    VBSymbol.BeginParameterList, VBSymbol.EndParameterList, true, true);
            }
            else
            {
                EatWord(VBKeyword.As);

                string eventType = CaptureTypeName();
                if (string.IsNullOrEmpty(eventType))
                {
                    this.OnParseError("Expected type identifier");
                }
                eventElement.Type = eventType;
            }

            string[] implements;
            string blockTemp = TryParseImplements(out implements);
            foreach (string implementation in implements)
            {
                InterfaceReference interfaceReference =
                    new InterfaceReference(implementation, InterfaceReferenceType.Interface);
                eventElement.AddImplementation(interfaceReference);
            }

            if (isCustom)
            {
                eventElement.BodyText = (blockTemp + this.ParseBlock(VBKeyword.Event)).Trim();
            }

            return eventElement;
        }
Esempio n. 10
0
 /// <summary>
 /// Adds an interface implementation to the type definition.
 /// </summary>
 /// <param name="interfaceReference">The interface reference.</param>
 public void AddInterface(InterfaceReference interfaceReference)
 {
     if (interfaceReference != null)
     {
         BaseInterfaces.Add(interfaceReference);
     }
 }
Esempio n. 11
0
 public void CreateDefaultTest()
 {
     InterfaceReference reference1 = new InterfaceReference();
     Assert.IsNull(reference1.Name, "Unexpected default value for Name.");
     Assert.AreEqual(InterfaceReferenceType.None, reference1.ReferenceType, "Unexpected default value for ReferenceType.");
 }
Esempio n. 12
0
        /// <summary>
        /// Parses a type definition.
        /// </summary>
        /// <param name="access">Type accessibility.</param>
        /// <param name="typeAttributes">Type modifiers.</param>
        /// <param name="elementType">Type element type.</param>
        /// <returns>Type code element.</returns>
        private TypeElement ParseType(
            CodeAccess access,
            TypeModifiers typeAttributes,
            TypeElementType elementType)
        {
            TypeElement typeElement = new TypeElement();

            EatWhiteSpace();
            string className = CaptureWord();
            typeElement.Name = className;
            typeElement.Access = access;
            typeElement.Type = elementType;
            typeElement.TypeModifiers = typeAttributes;

            EatWhiteSpace();

            if (elementType == TypeElementType.Enum)
            {
                EatWhiteSpace();

                if (NextChar == CSharpSymbol.TypeImplements)
                {
                    TryReadChar();
                    string interfaceName = CaptureTypeName();
                    InterfaceReference interfaceReference =
                        new InterfaceReference(interfaceName, InterfaceReferenceType.None);
                    typeElement.AddInterface(interfaceReference);
                }

                string enumText = ParseBlock(true, typeElement);

                // TODO: Parse enum values as fields
                typeElement.BodyText = enumText;
            }
            else
            {
                bool isGeneric = TryReadChar(CSharpSymbol.BeginGeneric);
                if (isGeneric)
                {
                    string[] typeParameterNames = ParseAliasList();
                    foreach (string typeParameterName in typeParameterNames)
                    {
                        TypeParameter typeParameter = new TypeParameter();
                        typeParameter.Name = typeParameterName;
                        typeElement.AddTypeParameter(typeParameter);
                    }

                    EatWhiteSpace();

                    if (!TryReadChar(CSharpSymbol.EndGeneric))
                    {
                        this.OnParseError("Expected " + CSharpSymbol.EndGeneric);
                    }
                }

                EatWhiteSpace();

                bool implements = TryReadChar(CSharpSymbol.TypeImplements);

                if (implements)
                {
                    string[] typeList = ParseAliasList();
                    foreach (string type in typeList)
                    {
                        InterfaceReference interfaceReference =
                            new InterfaceReference(type, InterfaceReferenceType.None);
                        typeElement.AddInterface(interfaceReference);
                    }
                }

                EatWhiteSpace();

                ParseTypeParameterConstraints(typeElement);

                // Associate any additional comments in the type definition with the type.
                ReadOnlyCollection<ICommentElement> extraComments = ParseComments();
                foreach (ICommentElement comment in extraComments)
                {
                    typeElement.AddHeaderComment(comment);
                }

                EatChar(CSharpSymbol.BeginBlock);

                EatWhiteSpace();

                if (NextChar != CSharpSymbol.EndBlock)
                {
                    //
                    // Parse child elements
                    //
                    List<ICodeElement> childElements = ParseElements(typeElement);
                    foreach (ICodeElement childElement in childElements)
                    {
                        typeElement.AddChild(childElement);
                    }
                }

                EatChar(CSharpSymbol.EndBlock);
            }

            //
            // Types allow a trailing semi-colon
            //
            EatTrailingEndOfStatement();

            return typeElement;
        }
Esempio n. 13
0
 public void ReferenceTypeTest()
 {
     InterfaceReference reference = new InterfaceReference();
     reference.ReferenceType = InterfaceReferenceType.Class;
     Assert.AreEqual(InterfaceReferenceType.Class, reference.ReferenceType, "Unexpected value for ReferenceType.");
 }
Esempio n. 14
0
 public void NameTest()
 {
     InterfaceReference reference = new InterfaceReference();
     reference.Name = "Test";
     Assert.AreEqual("Test", reference.Name, "Unexpected value for Name.");
 }
Esempio n. 15
0
 public void CreateTest()
 {
     InterfaceReference reference1 = new InterfaceReference("IDisposable", InterfaceReferenceType.Interface);
     Assert.AreEqual("IDisposable", reference1.Name, "Unexpected value for Name.");
     Assert.AreEqual(InterfaceReferenceType.Interface, reference1.ReferenceType, "Unexpected value for ReferenceType.");
 }
Esempio n. 16
0
        /// <summary>
        /// Parses a type definition.
        /// </summary>
        /// <param name="access">The access.</param>
        /// <param name="typeAttributes">The type attributes.</param>
        /// <param name="elementType">Type of the element.</param>
        /// <returns>A type code element.</returns>
        private TypeElement ParseType(
            CodeAccess access, TypeModifiers typeAttributes, TypeElementType elementType)
        {
            TypeElement typeElement = new TypeElement();

            EatWhiteSpace();
            string className = CaptureWord();
            typeElement.Name = className;
            typeElement.Access = access;
            typeElement.Type = elementType;
            typeElement.TypeModifiers = typeAttributes;

            if (elementType == TypeElementType.Enum)
            {
                EatLineContinuation();

                if (NextChar == VBKeyword.As[0])
                {
                    EatWord(VBKeyword.As);
                    string interfaceName = CaptureTypeName();
                    InterfaceReference interfaceReference =
                        new InterfaceReference(interfaceName, InterfaceReferenceType.None);
                    typeElement.AddInterface(interfaceReference);
                }

                string enumText = ParseBlock(VBKeyword.Enumeration);

                // TODO: Parse enum values as fields
                typeElement.BodyText = enumText;
            }
            else
            {
                EatWhiteSpace();
                bool isGeneric = TryReadChar(VBSymbol.BeginParameterList);
                if (isGeneric)
                {
                    EatWord(VBKeyword.Of, "Expected Of");

                    this.ParseTypeParameters(typeElement);
                }

                EatWhiteSpace();

                //
                // Parse child elements
                //
                List<ICodeElement> childElements = ParseElements(typeElement);
                foreach (ICodeElement childElement in childElements)
                {
                    typeElement.AddChild(childElement);
                }

                EatWhiteSpace();
                string elementTypeString = EnumUtilities.ToString(elementType);
                EatWord(elementTypeString, "Expected End " + elementTypeString);
            }

            return typeElement;
        }
Esempio n. 17
0
        /// <summary>
        /// Parses elements from the current point in the stream.
        /// </summary>
        /// <param name="parentElement">Parent element</param>
        /// <returns>A list of parsed code elements.</returns>
        private List<ICodeElement> ParseElements(ICodeElement parentElement)
        {
            List<ICodeElement> codeElements = new List<ICodeElement>();
            List<ICommentElement> comments = new List<ICommentElement>();
            List<AttributeElement> attributes = new List<AttributeElement>();
            Stack<ICodeElement> enclosingElementStack = new Stack<ICodeElement>();

            StringBuilder elementBuilder = new StringBuilder(DefaultBlockLength);

            char nextChar;
            bool end = false;
            bool lineContinuation = false;

            while (TryReadChar() && !end)
            {
                switch (CurrentChar)
                {
                    //
                    // Comments
                    //
                    case VBSymbol.BeginComment:
                        CommentElement commentLine = ParseCommentLine();
                        string commentDirectiveRegionName =
                                GetCommentDirectiveText(commentLine, Configuration.Formatting.Regions.CommentDirectiveBeginPattern, "Name");

                        if (commentDirectiveRegionName != null)
                        {
                            PushComments(codeElements, comments);

                            RegionElement regionElement = new RegionElement();
                            regionElement.Name = commentDirectiveRegionName;
                            enclosingElementStack.Push(regionElement);
                        }
                        else
                        {
                            commentDirectiveRegionName = GetCommentDirectiveText(commentLine, Configuration.Formatting.Regions.CommentDirectiveEndPattern, "Name");
                            if (commentDirectiveRegionName != null)
                            {
                                if (enclosingElementStack.Count == 0 ||
                                enclosingElementStack.Peek().ElementType != ElementType.Region)
                                {
                                    this.OnParseError("Unmatched end region directive");
                                }

                                ICodeElement enclosingElement = enclosingElementStack.Pop();

                                //
                                // Add any processed comments to the region or condition directive.
                                //
                                if (comments.Count > 0)
                                {
                                    foreach (ICommentElement commentElement in comments)
                                    {
                                        enclosingElement.AddChild(commentElement);
                                    }
                                    comments.Clear();
                                }

                                //
                                // Are we processing a nested region or condition directive?
                                //
                                if (enclosingElementStack.Count > 0)
                                {
                                    enclosingElementStack.Peek().AddChild(enclosingElement);
                                }
                                else
                                {
                                    codeElements.Add(enclosingElement);
                                }
                            }
                            else
                            {
                                comments.Add(commentLine);
                            }
                        }
                        break;

                    //
                    // Preprocessor
                    //
                    case VBSymbol.Preprocessor:
                        //
                        // TODO: Parse additional preprocessor directives.
                        //
                        string line = ReadLine().Trim();
                        string[] words = line.Split(WhiteSpaceCharacters, StringSplitOptions.RemoveEmptyEntries);
                        if (words.Length > 0 && VBKeyword.Normalize(words[0]) == VBKeyword.Region)
                        {
                            PushComments(codeElements, comments);

                            RegionElement regionElement = ParseRegion(line);
                            enclosingElementStack.Push(regionElement);
                        }
                        else if (words.Length > 0 &&
                            (VBKeyword.Normalize(words[0]) == VBKeyword.If ||
                            VBKeyword.Normalize(words[0]) == VBKeyword.Else ||
                            VBKeyword.Normalize(words[0]) == VBKeyword.ElseIf))
                        {
                            bool isIf;
                            ConditionDirectiveElement conditionDirective = ParseConditionDirective(line.Trim(), out isIf);

                            if (isIf)
                            {
                                enclosingElementStack.Push(conditionDirective);
                            }
                            else
                            {
                                if (enclosingElementStack.Count == 0 ||
                                    enclosingElementStack.Peek().ElementType != ElementType.ConditionDirective)
                                {
                                    this.OnParseError("Expected 'If' preprocessor directive.");
                                }
                                else
                                {
                                    ConditionDirectiveElement previousCondition =
                                        enclosingElementStack.Peek() as ConditionDirectiveElement;
                                    while (previousCondition.ElseCondition != null)
                                    {
                                        previousCondition = previousCondition.ElseCondition;
                                    }

                                    // Add the condition to the end of the condition linked list
                                    previousCondition.ElseCondition = conditionDirective;
                                }
                            }
                        }
                        else if (words.Length > 1 &&
                            VBKeyword.Normalize(words[0]) == VBKeyword.End &&
                            (VBKeyword.Normalize(words[1]) == VBKeyword.Region ||
                            VBKeyword.Normalize(words[1]) == VBKeyword.If))
                        {
                            ICodeElement enclosingElement = null;

                            if (VBKeyword.Normalize(words[1]) == VBKeyword.Region)
                            {
                                if (enclosingElementStack.Count == 0 ||
                                    enclosingElementStack.Peek().ElementType != ElementType.Region)
                                {
                                    this.OnParseError("Unmatched end region directive");
                                }
                            }
                            else if (enclosingElementStack.Count == 0 ||
                                enclosingElementStack.Peek().ElementType != ElementType.ConditionDirective)
                            {
                                this.OnParseError("Unmatched #End If");
                            }

                            enclosingElement = enclosingElementStack.Pop();

                            //
                            // If there are any attributes not associated with an element (e.g.
                            // a condition directive containing only an attribute, then
                            // throw an error as this is currently not supported.
                            //
                            if (enclosingElement.ElementType == ElementType.ConditionDirective &&
                                attributes.Count > 0)
                            {
                                this.OnParseError("Cannot arrange files with preprocessor directives containing attributes unassociated to an element");
                            }

                            if (comments.Count > 0)
                            {
                                foreach (ICommentElement commentElement in comments)
                                {
                                    enclosingElement.AddChild(commentElement);
                                }
                                comments.Clear();
                            }

                            if (enclosingElementStack.Count > 0)
                            {
                                enclosingElementStack.Peek().AddChild(enclosingElement);
                            }
                            else
                            {
                                codeElements.Add(enclosingElement);
                            }
                        }
                        else
                        {
                            this.OnParseError(
                                "Cannot arrange files with preprocessor directives " +
                                "other than #Region, #End Region and conditional compilation directives");
                        }
                        break;

                    //
                    // Attribute
                    //
                    case VBSymbol.BeginAttribute:
                        nextChar = NextChar;

                        //
                        // Parse attribute
                        //
                        AttributeElement attributeElement = ParseAttribute(comments.AsReadOnly());

                        attributes.Add(attributeElement);
                        codeElements.Add(attributeElement);
                        comments.Clear();
                        break;

                    case VBSymbol.LineContinuation:
                        if (IsWhiteSpace(PreviousChar) && IsWhiteSpace(NextChar))
                        {
                            lineContinuation = true;
                        }
                        else
                        {
                            elementBuilder.Append(CurrentChar);
                        }
                        break;

                    // Eat any unneeded whitespace
                    case ' ':
                    case '\n':
                    case '\r':
                    case '\t':
                    case ':':
                        if (elementBuilder.Length > 0)
                        {
                            string processedText = elementBuilder.ToString().Trim();
                            if (CurrentChar == '\n')
                            {
                                if (!lineContinuation)
                                {
                                    this.OnParseError(
                                        string.Format(
                                        Thread.CurrentThread.CurrentCulture,
                                        "Unhandled element text '{0}'",
                                        processedText));
                                }
                                else
                                {
                                    lineContinuation = false;
                                }
                            }

                            if (elementBuilder[elementBuilder.Length - 1] != ' ')
                            {
                                elementBuilder.Append(' ');
                            }
                        }
                        break;

                    default:
                        elementBuilder.Append(CurrentChar);

                        string upperElementText = elementBuilder.ToString().ToUpperInvariant();
                        nextChar = NextChar;

                        if (upperElementText == VBKeyword.End.ToUpperInvariant())
                        {
                            end = true;
                            elementBuilder = new StringBuilder(DefaultBlockLength);
                        }
                        else if (upperElementText == VBKeyword.Rem.ToUpperInvariant() &&
                            nextChar == ' ')
                        {
                            CommentElement remCommentLine = ParseCommentLine();
                            comments.Add(remCommentLine);
                            elementBuilder = new StringBuilder(DefaultBlockLength);
                        }
                        else if (upperElementText == VBKeyword.Option.ToUpperInvariant() &&
                            IsWhiteSpace(nextChar))
                        {
                            ICodeElement optionElement = ParseOption(comments.AsReadOnly());
                            comments.Clear();
                            codeElements.Add(optionElement);
                            elementBuilder = new StringBuilder(DefaultBlockLength);
                        }
                        else
                        {
                            if (char.IsWhiteSpace(nextChar) || VBSymbol.IsVBSymbol(CurrentChar))
                            {
                                string elementText = VBKeyword.Normalize(elementBuilder.ToString());
                                bool isImplements = elementText.StartsWith(
                                    VBKeyword.Implements, StringComparison.OrdinalIgnoreCase);
                                bool isInherits = !isImplements && elementText.StartsWith(
                                    VBKeyword.Inherits, StringComparison.OrdinalIgnoreCase);
                                TypeElement typeElement = parentElement as TypeElement;
                                if ((isImplements || isInherits) && typeElement != null)
                                {
                                    InterfaceReferenceType referenceType = InterfaceReferenceType.None;
                                    if (isInherits)
                                    {
                                        referenceType = InterfaceReferenceType.Class;
                                    }
                                    else if (isImplements)
                                    {
                                        referenceType = InterfaceReferenceType.Interface;
                                    }

                                    do
                                    {
                                        EatWhiteSpace(WhiteSpaceTypes.SpaceAndTab);
                                        if (NextChar == VBSymbol.AliasSeparator)
                                        {
                                            EatChar(VBSymbol.AliasSeparator);
                                        }

                                        string typeName = CaptureTypeName();
                                        InterfaceReference interfaceReference =
                                            new InterfaceReference(typeName, referenceType);
                                        typeElement.AddInterface(interfaceReference);
                                        EatWhiteSpace(WhiteSpaceTypes.SpaceAndTab);
                                    }
                                    while (NextChar == VBSymbol.AliasSeparator);

                                    elementBuilder = new StringBuilder(DefaultBlockLength);
                                }
                                else
                                {
                                    //
                                    // Try to parse a code element
                                    //
                                    ICodeElement element = TryParseElement(parentElement,
                                        elementBuilder, comments.AsReadOnly(), attributes.AsReadOnly());
                                    if (element != null)
                                    {
                                        if (element is CommentedElement)
                                        {
                                            UsingElement usingElement = element as UsingElement;

                                            //
                                            // If this is the first using statement, then don't attach
                                            // header comments to the element.
                                            //
                                            if (usingElement != null && parentElement == null && codeElements.Count == 0)
                                            {
                                                foreach (ICommentElement commentElement in usingElement.HeaderComments)
                                                {
                                                    if (enclosingElementStack.Count > 0)
                                                    {
                                                        enclosingElementStack.Peek().AddChild(commentElement);
                                                    }
                                                    else
                                                    {
                                                        codeElements.Add(commentElement);
                                                    }
                                                }
                                                usingElement.ClearHeaderCommentLines();
                                            }
                                            comments.Clear();
                                        }

                                        if (enclosingElementStack.Count > 0)
                                        {
                                            ICodeElement enclosingElement = enclosingElementStack.Peek();

                                            if (enclosingElement.ElementType == ElementType.ConditionDirective)
                                            {
                                                ConditionDirectiveElement conditionDirective = enclosingElement as ConditionDirectiveElement;
                                                while (conditionDirective.ElseCondition != null)
                                                {
                                                    conditionDirective = conditionDirective.ElseCondition;
                                                }

                                                enclosingElement = conditionDirective;
                                            }

                                            enclosingElement.AddChild(element);
                                        }
                                        else
                                        {
                                            codeElements.Add(element);
                                        }

                                        elementBuilder = new StringBuilder(DefaultBlockLength);

                                        if (element is IAttributedElement)
                                        {
                                            foreach (AttributeElement attribute in attributes)
                                            {
                                                codeElements.Remove(attribute);
                                            }

                                            attributes = new List<AttributeElement>();
                                        }
                                    }
                                }
                            }
                        }

                        break;
                }

                char nextCh = NextChar;
            }

            if (comments.Count > 0)
            {
                for (int commentIndex = 0; commentIndex < comments.Count; commentIndex++)
                {
                    ICommentElement comment = comments[commentIndex];
                    codeElements.Insert(commentIndex, comment);
                }
            }

            //
            // Make sure that all region elements have been closed
            //
            if (enclosingElementStack.Count > 0)
            {
                if (enclosingElementStack.Peek().ElementType == ElementType.Region)
                {
                    this.OnParseError(
                        string.Format(
                        CultureInfo.InvariantCulture,
                        "Missing end region directive for '{0}'",
                        enclosingElementStack.Peek().Name));
                }
                else
                {
                    this.OnParseError("Expected #End If");
                }
            }

            if (elementBuilder.Length > 0)
            {
                this.OnParseError(
                    string.Format(
                    Thread.CurrentThread.CurrentCulture,
                    "Unhandled element text '{0}'",
                    elementBuilder));
            }

            return codeElements;
        }
Esempio n. 18
0
 /// <summary>
 /// Adds an item to the Implements collection.
 /// </summary>
 /// <param name="implementation">The implementation.</param>
 public void AddImplementation(InterfaceReference implementation)
 {
     if (implementation != null)
     {
         ImplementsBase.Add(implementation);
     }
 }