Method element.
Inheritance: InterfaceMemberElement, IGenericElement
Ejemplo n.º 1
0
        /// <summary>
        /// Creates a constructor from a method element.
        /// </summary>
        /// <param name="methodElement">The method element.</param>
        /// <returns>A constructor element.</returns>
        private static ConstructorElement CreateConstructor(MethodElement methodElement)
        {
            ConstructorElement constructor = new ConstructorElement();
            constructor.Name = methodElement.Name;
            constructor.Access = methodElement.Access;
            constructor.MemberModifiers = methodElement.MemberModifiers;
            constructor.Parameters = methodElement.Parameters;
            constructor.BodyText = methodElement.BodyText;

            return constructor;
        }
Ejemplo n.º 2
0
        public void FormatTest()
        {
            MethodElement methodElement = new MethodElement();
            methodElement.Name = "Test";

            string formatted = ElementUtilities.Format(
                "End $(ElementType) $(Name)",
                methodElement);

            Assert.AreEqual("End Method Test", formatted, "Unexpected formatted result.");
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a clone of this instance.
        /// </summary>
        /// <returns>
        /// Clone of the instance with the interface member element state copied.
        /// </returns>
        protected override InterfaceMemberElement DoInterfaceMemberClone()
        {
            MethodElement clone = new MethodElement();

            //
            // Copy state
            //
            clone._params       = _params;
            clone._isOperator   = _isOperator;
            clone._operatorType = _operatorType;
            clone._isAsync      = _isAsync;

            foreach (TypeParameter typeParam in TypeParameters)
            {
                TypeParameter typeParamClone = typeParam.Clone() as TypeParameter;
                clone.TypeParametersBase.Add(typeParamClone);
            }

            return(clone);
        }
Ejemplo n.º 4
0
        public void CanArrangeTest()
        {
            RegionConfiguration methodRegionConfiguration = new RegionConfiguration();
            methodRegionConfiguration.Name = "Methods";
            ElementConfiguration methodConfiguration = new ElementConfiguration();
            methodConfiguration.ElementType = ElementType.Method;
            methodRegionConfiguration.Elements.Add(methodConfiguration);

            RegionConfiguration propertyRegionConfiguration = new RegionConfiguration();
            propertyRegionConfiguration.Name = "Properties";
            ElementConfiguration propertyConfiguration = new ElementConfiguration();
            propertyConfiguration.ElementType = ElementType.Property;
            propertyRegionConfiguration.Elements.Add(propertyConfiguration);

            ElementConfiguration parentConfiguration = new ElementConfiguration();
            parentConfiguration.ElementType = ElementType.Type;

            RegionArranger methodRegionArranger = new RegionArranger(
                methodRegionConfiguration, parentConfiguration);

            RegionArranger propertyRegionArranger = new RegionArranger(
                propertyRegionConfiguration, parentConfiguration);

            MethodElement method = new MethodElement();
            method.Name = "DoSomething";

            Assert.IsTrue(
                methodRegionArranger.CanArrange(method),
                "Expected region arranger to be able to arrange the element.");

            Assert.IsFalse(
                propertyRegionArranger.CanArrange(method),
                "Expected region arranger to not be able to arrange the element.");

            Assert.IsFalse(
                methodRegionArranger.CanArrange(null),
                "Expected region arranger to not be able to arrange a null element.");
        }
Ejemplo n.º 5
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;
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Processes a method element.
 /// </summary>
 /// <param name="element">Method code element.</param>
 public abstract void VisitMethodElement(MethodElement element);
        public void EvaluateElementNameMatchesTest()
        {
            IConditionExpression expression = new BinaryOperatorExpression(
                BinaryExpressionOperator.Matches,
                new ElementAttributeExpression(ElementAttributeType.Name),
                new StringExpression("IDisposable\\..*"));

            MethodElement element = new MethodElement();
            element.Name = "IDisposable.Dispose";

            bool result = ConditionExpressionEvaluator.Instance.Evaluate(
                expression, element);
            Assert.IsTrue(result, "Unexpected expression evaluation result.");

            element.Name = "IDisposable.Test";
            result = ConditionExpressionEvaluator.Instance.Evaluate(
                expression, element);
            Assert.IsTrue(result, "Unexpected expression evaluation result.");

            element.Name = "IDisposable";
            result = ConditionExpressionEvaluator.Instance.Evaluate(
                expression, element);
            Assert.IsFalse(result, "Unexpected expression evaluation result.");
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Processes a method element.
        /// </summary>
        /// <param name="element">Method code element.</param>
        public override void VisitMethodElement(MethodElement element)
        {
            this.WriteComments(element.HeaderComments);
            this.WriteAttributes(element);

            if (element.IsPartial)
            {
                Writer.Write(VBKeyword.Partial);
                Writer.Write(' ');
            }

            WriteAccess(element.Access);

            if (element.IsExternal)
            {
                Writer.Write(VBKeyword.Declare);
                Writer.Write(' ');
            }

            if (element[VBExtendedProperties.ExternalModifier] != null)
            {
                Writer.Write(element[VBExtendedProperties.ExternalModifier].ToString());
                Writer.Write(' ');
            }

            WriteMemberAttributes(
                element.MemberModifiers,
                element[VBExtendedProperties.Overloads] is bool && (bool)element[VBExtendedProperties.Overloads]);

            if (element.IsOperator)
            {
                if (element.OperatorType == OperatorType.Explicit)
                {
                    Writer.Write(VBKeyword.Narrowing);
                    Writer.Write(' ');
                }
                else if (element.OperatorType == OperatorType.Implicit)
                {
                    Writer.Write(VBKeyword.Widening);
                    Writer.Write(' ');
                }

                Writer.Write(VBKeyword.Operator);
                Writer.Write(' ');
            }
            else
            {
                WriteMethodType(element.Type);
            }

            Writer.Write(element.Name);

            WriteTypeParameters(element);

            if (element[VBExtendedProperties.ExternalLibrary] != null)
            {
                Writer.Write(' ');
                Writer.Write(VBKeyword.Lib);
                Writer.Write(' ');

                Writer.Write(VBSymbol.BeginString);
                Writer.Write(element[VBExtendedProperties.ExternalLibrary].ToString());
                Writer.Write(VBSymbol.BeginString);
                Writer.Write(' ');
            }

            if (element[VBExtendedProperties.ExternalAlias] != null)
            {
                Writer.Write(VBKeyword.Alias);
                Writer.Write(' ');

                Writer.Write(VBSymbol.BeginString);
                Writer.Write(element[VBExtendedProperties.ExternalAlias].ToString());
                Writer.Write(VBSymbol.BeginString);
                Writer.Write(' ');
            }

            WriteParameterList(element.Parameters);

            WriteReturnType(element.Type);
            WriteImplements(element.Implements);

            string[] handles = element[VBExtendedProperties.Handles] as string[];
            if (handles != null && handles.Length > 0)
            {
                Writer.Write(' ');
                Writer.Write(VBKeyword.Handles);
                for (int handleIndex = 0; handleIndex < handles.Length; handleIndex++)
                {
                    string handleReference = handles[handleIndex];
                    Writer.Write(' ');
                    Writer.Write(handleReference);
                    if (handleIndex < handles.Length - 1)
                    {
                        Writer.Write(VBSymbol.AliasSeparator);
                    }
                }
            }

            if (!element.IsExternal)
            {
                WriteBody(element);
            }
        }
Ejemplo n.º 9
0
        public void InsertByTypeTest()
        {
            SortBy sortBy = new SortBy();
            sortBy.By = ElementAttributeType.Type;
            sortBy.Direction = SortDirection.Ascending;

            SortedInserter sortedInserter = new SortedInserter(ElementType.Method, sortBy);

            //
            // Create a parent element
            //
            RegionElement regionElement = new RegionElement();
            Assert.AreEqual(0, regionElement.Children.Count, "Parent element should not have any children.");

            //
            // Insert an element with a mid alphabet return type.
            //
            MethodElement method1 = new MethodElement();
            method1.Name = "DoSomething";
            method1.Type = "Nullable<DateTime>";
            sortedInserter.InsertElement(regionElement, method1);
            Assert.AreEqual(1, regionElement.Children.Count, "Element was not inserted into the parent.");
            Assert.AreEqual(0, regionElement.Children.IndexOf(method1), "Element was not inserted at the correct index.");

            //
            // Insert an element that should be sorted toward the end
            //
            MethodElement method2 = new MethodElement();
            method2.Name = "DoSomething";
            method2.Type = "Type";
            sortedInserter.InsertElement(regionElement, method2);
            Assert.AreEqual(2, regionElement.Children.Count, "Element was not inserted into the parent.");
            Assert.AreEqual(0, regionElement.Children.IndexOf(method1), "Element is not at the correct index.");
            Assert.AreEqual(1, regionElement.Children.IndexOf(method2), "Element is not at the correct index.");

            //
            // Insert an element that should be sorted toward the beginning
            //
            MethodElement method3 = new MethodElement();
            method3.Name = "DoSomething";
            method3.Type = "IEnumerable";
            sortedInserter.InsertElement(regionElement, method3);
            Assert.AreEqual(3, regionElement.Children.Count, "Element was not inserted into the parent.");
            Assert.AreEqual(0, regionElement.Children.IndexOf(method3), "Element is not at the correct index.");
            Assert.AreEqual(1, regionElement.Children.IndexOf(method1), "Element is not at the correct index.");
            Assert.AreEqual(2, regionElement.Children.IndexOf(method2), "Element is not at the correct index.");
        }
Ejemplo n.º 10
0
        public void InsertByElementTypeTest()
        {
            SortBy sortBy = new SortBy();
            sortBy.By = ElementAttributeType.ElementType;
            sortBy.Direction = SortDirection.Ascending;

            SortedInserter sortedInserter = new SortedInserter(ElementType.NotSpecified, sortBy);

            //
            // Create a parent element
            //
            RegionElement regionElement = new RegionElement();
            Assert.AreEqual(0, regionElement.Children.Count, "Parent element should not have any children.");

            //
            // Insert an element with a middle access.
            //
            ConstructorElement constructor = new ConstructorElement();
            constructor.Name = "SomeClass";
            constructor.Access = CodeAccess.Public;
            sortedInserter.InsertElement(regionElement, constructor);
            Assert.AreEqual(1, regionElement.Children.Count, "Element was not inserted into the parent.");
            Assert.AreEqual(0, regionElement.Children.IndexOf(constructor), "Element was not inserted at the correct index.");

            //
            // Insert an element that should be sorted toward the end
            //
            MethodElement methodElement = new MethodElement();
            methodElement.Name = "SomeMethod";
            methodElement.Access = CodeAccess.Public;
            sortedInserter.InsertElement(regionElement, methodElement);
            Assert.AreEqual(2, regionElement.Children.Count, "Element was not inserted into the parent.");
            Assert.AreEqual(0, regionElement.Children.IndexOf(constructor), "Element is not at the correct index.");
            Assert.AreEqual(1, regionElement.Children.IndexOf(methodElement), "Element is not at the correct index.");

            //
            // Insert an element that should be sorted toward the beginning
            //
            FieldElement fieldElement = new FieldElement();
            fieldElement.Name = "someField";
            fieldElement.Access = CodeAccess.Private;
            sortedInserter.InsertElement(regionElement, fieldElement);
            Assert.AreEqual(3, regionElement.Children.Count, "Element was not inserted into the parent.");
            Assert.AreEqual(0, regionElement.Children.IndexOf(fieldElement), "Element is not at the correct index.");
            Assert.AreEqual(1, regionElement.Children.IndexOf(constructor), "Element is not at the correct index.");
            Assert.AreEqual(2, regionElement.Children.IndexOf(methodElement), "Element is not at the correct index.");
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Processes a method element.
        /// </summary>
        /// <param name="element">Method code element.</param>
        public override void VisitMethodElement(MethodElement element)
        {
            this.WriteComments(element.HeaderComments);
            this.WriteAttributes(element);

            if (element.IsPartial)
            {
                Writer.Write(CSharpKeyword.Partial);
                Writer.Write(' ');
            }

            WriteAccess(element.Access);

            WriteMemberAttributes(element.MemberModifiers);

            if (element.OperatorType == OperatorType.None)
            {
                Writer.Write(element.Type);
                Writer.Write(' ');

                if (element.IsOperator)
                {
                    Writer.Write(CSharpKeyword.Operator);
                    Writer.Write(' ');
                }

                Writer.Write(element.Name);
            }
            else if (element.IsOperator)
            {
                if (element.OperatorType == OperatorType.Explicit)
                {
                    Writer.Write(CSharpKeyword.Explicit);
                }
                else if (element.OperatorType == OperatorType.Implicit)
                {
                    Writer.Write(CSharpKeyword.Implicit);
                }
                Writer.Write(' ');

                Writer.Write(CSharpKeyword.Operator);
                Writer.Write(' ');
                Writer.Write(element.Type);
            }

            WriteTypeParameters(element);
            WriteParameterList(element.Parameters);
            WriteTypeParameterConstraints(element);

            if (element.BodyText == null)
            {
                Writer.Write(CSharpSymbol.EndOfStatement);
            }
            else
            {
                Writer.WriteLine();
                WriteBody(element);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Parses a method.
        /// </summary>
        /// <param name="memberName">Member name.</param>
        /// <param name="access">Code access.</param>
        /// <param name="memberAttributes">Member attributes.</param>
        /// <param name="returnType">Return type.</param>
        /// <param name="isOperator">Whether or not the method is an operator.</param>
        /// <param name="operatorType">Type of the operator.</param>
        /// <returns>Method code element.</returns>
        private MethodElement ParseMethod(
            string memberName,
            CodeAccess access,
            MemberModifiers memberAttributes,
            string returnType,
            bool isOperator,
            OperatorType operatorType)
        {
            MethodElement method = new MethodElement();
            method.Name = memberName;
            method.Access = access;
            method.Type = returnType;
            method.MemberModifiers = memberAttributes;
            method.IsOperator = isOperator;
            method.OperatorType = operatorType;
            if (isOperator &&
                (operatorType == OperatorType.Implicit || operatorType == OperatorType.Explicit))
            {
                method.Type = memberName;
                method.Name = null;
            }

            int genericIndex = memberName.LastIndexOf(CSharpSymbol.BeginGeneric);
            int lastQualifierIndex = memberName.LastIndexOf(CSharpSymbol.AliasQualifier);
            bool isGeneric = !isOperator &&
                (genericIndex >= 0 && genericIndex < memberName.Length - 1 &&
                (lastQualifierIndex < 0 || lastQualifierIndex < genericIndex));
            if (isGeneric)
            {
                method.Name = memberName.Substring(0, genericIndex);
                string typeParameterString = memberName.TrimEnd(CSharpSymbol.EndGeneric).Substring(
                    genericIndex + 1);

                string[] typeParameterNames = typeParameterString.Split(
                    new char[] { CSharpSymbol.AliasSeparator, ' ' },
                    StringSplitOptions.RemoveEmptyEntries);
                foreach (string typeParameterName in typeParameterNames)
                {
                    TypeParameter typeParameter = new TypeParameter();
                    typeParameter.Name = typeParameterName;
                    method.AddTypeParameter(typeParameter);
                }
            }

            method.Parameters = this.ParseParameters();

            if (isGeneric)
            {
                ParseTypeParameterConstraints(method);
            }

            EatWhiteSpace();
            bool endOfStatement = NextChar == CSharpSymbol.EndOfStatement;
            if (endOfStatement)
            {
                TryReadChar();
                method.BodyText = null;
            }
            else
            {
                method.BodyText = this.ParseBlock(true, method);
            }

            return method;
        }
Ejemplo n.º 13
0
        public void DefaultArrangeSimpleClassTest()
        {
            List<ICodeElement> codeElements = new List<ICodeElement>();

            TypeElement classElement = new TypeElement();
            classElement.Type = TypeElementType.Class;
            classElement.Access = CodeAccess.Public;
            classElement.Name = "TestClass";

            NamespaceElement namespaceElement = new NamespaceElement();
            namespaceElement.Name = "TestNamespace";
            namespaceElement.AddChild(classElement);

            MethodElement methodElement = new MethodElement();
            methodElement.Type = "void";
            methodElement.Access = CodeAccess.Public;
            methodElement.Name = "DoSomething";
            classElement.AddChild(methodElement);

            FieldElement fieldElement = new FieldElement();
            fieldElement.Type = "bool";
            fieldElement.Access = CodeAccess.Private;
            fieldElement.Name = "_val";
            classElement.AddChild(fieldElement);

            PropertyElement propertyElement = new PropertyElement();
            propertyElement.Type = "bool";
            propertyElement.Access = CodeAccess.Public;
            propertyElement.Name = "Value";
            propertyElement.BodyText = "return _val";
            classElement.AddChild(propertyElement);

            codeElements.Add(namespaceElement);

            CodeArranger arranger = new CodeArranger(CodeConfiguration.Default);

            ReadOnlyCollection<ICodeElement> arranged =
                arranger.Arrange(codeElements.AsReadOnly());

            Assert.AreEqual(1, arranged.Count, "After arranging, an unexpected number of elements were returned.");
            NamespaceElement namespaceElementTest = arranged[0] as NamespaceElement;
            Assert.IsNotNull(namespaceElementTest, "Expected a namespace element.");

            Assert.AreEqual(1, namespaceElementTest.Children.Count,
                "After arranging, an unexpected number of namespace elements were returned.");
            RegionElement typeRegionElement = namespaceElementTest.Children[0] as RegionElement;
            Assert.IsNotNull(typeRegionElement, "Expected a region element.");
            Assert.AreEqual("Types", typeRegionElement.Name);

            Assert.AreEqual(1, typeRegionElement.Children.Count,
                "After arranging, an unexpected number of namespace elements were returned.");
            TypeElement typeElement = typeRegionElement.Children[0] as TypeElement;
            Assert.IsNotNull(typeElement, "Expected a type element.");

            Assert.AreEqual(TypeElementType.Class, typeElement.Type, "Unexpected type element type.");
            Assert.AreEqual(classElement.Name, typeElement.Name, "Unexpected type element name.");

            Assert.AreEqual(3, typeElement.Children.Count, "An unexpected number of class child elements were returned.");
            List<RegionElement> regionElements = new List<RegionElement>();
            foreach (ICodeElement classChildElement in typeElement.Children)
            {
                RegionElement regionElement = classChildElement as RegionElement;
                Assert.IsNotNull(
                    regionElement, "Expected a region element but was {0}.", classChildElement.ElementType);
                regionElements.Add(regionElement);
            }

            Assert.AreEqual("Fields", regionElements[0].Name, "Unexpected region element name.");
            Assert.AreEqual("Properties", regionElements[1].Name, "Unexpected region element name.");
            Assert.AreEqual("Methods", regionElements[2].Name, "Unexpected region element name.");

            GroupElement fieldGroupElement = regionElements[0].Children[0].Children[0] as GroupElement;
            Assert.IsNotNull(fieldGroupElement, "Expected a group element for fields.");

            foreach (ICodeElement codeElement in fieldGroupElement.Children)
            {
                FieldElement fieldElementTest = codeElement as FieldElement;
                Assert.IsNotNull(
                    fieldElementTest,
                    "Expected a field element but was type {0}: {1}",
                    codeElement.ElementType,
                    codeElement);
            }

            Assert.AreEqual(1, regionElements[1].Children.Count);
            foreach (ICodeElement codeElement in regionElements[1].Children[0].Children)
            {
                PropertyElement propertyElementTest = codeElement as PropertyElement;
                Assert.IsNotNull(
                    propertyElementTest,
                    "Expected a property element but was type {0}: {1}",
                    codeElement.ElementType,
                    codeElement);
            }

            Assert.AreEqual(1, regionElements[2].Children.Count);
            foreach (ICodeElement codeElement in regionElements[2].Children[0].Children)
            {
                MethodElement methodElementTest = codeElement as MethodElement;
                Assert.IsNotNull(
                    methodElementTest,
                    "Expected a method element but was type {0}: {1}",
                    codeElement.ElementType,
                    codeElement);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Creates a clone of this instance.
        /// </summary>
        /// <returns>
        /// Clone of the instance with the interface member element state copied.
        /// </returns>
        protected override InterfaceMemberElement DoInterfaceMemberClone()
        {
            MethodElement clone = new MethodElement();

            //
            // Copy state
            //
            clone._params = _params;
            clone._isOperator = _isOperator;
            clone._operatorType = _operatorType;

            foreach (TypeParameter typeParam in TypeParameters)
            {
                TypeParameter typeParamClone = typeParam.Clone() as TypeParameter;
                clone.TypeParametersBase.Add(typeParamClone);
            }

            return clone;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Parses a method.
        /// </summary>
        /// <param name="memberName">Member name.</param>
        /// <param name="access">Code access.</param>
        /// <param name="memberAttributes">Member attributes.</param>
        /// <param name="returnType">Return type.</param>
        /// <param name="isOperator">Whether or not the method is an operator.</param>
        /// <param name="operatorType">Type of the operator.</param>
        /// <returns>Method code element.</returns>
        private MethodElement ParseMethod(
			string memberName,
			CodeAccess access,
			MemberModifiers memberAttributes,
			string returnType,
			bool isOperator,
			OperatorType operatorType)
        {
            MethodElement method = new MethodElement();
            method.Name = memberName;
            method.Access = access;
            method.Type = returnType;
            method.MemberModifiers = memberAttributes;
            method.IsOperator = isOperator;
            method.OperatorType = operatorType;
            if (isOperator &&
                (operatorType == OperatorType.Implicit || operatorType == OperatorType.Explicit))
            {
                method.Type = memberName;
                method.Name = null;
            }

            int genericIndex = memberName.LastIndexOf(CSharpSymbol.BeginGeneric);
            int lastQualifierIndex = memberName.LastIndexOf(CSharpSymbol.AliasQualifier);
            bool isGeneric = !isOperator &&
                             (genericIndex >= 0 && genericIndex < memberName.Length - 1 &&
                              (lastQualifierIndex < 0 || lastQualifierIndex < genericIndex));
            if (isGeneric)
            {
                method.Name = memberName.Substring(0, genericIndex);
                string typeParameterString = memberName.TrimEnd(CSharpSymbol.EndGeneric).Substring(
                    genericIndex + 1);

                string[] typeParameterNames = typeParameterString.Split(
                    new char[] { CSharpSymbol.AliasSeparator, ' ' },
                    StringSplitOptions.RemoveEmptyEntries);
                foreach (string typeParameterName in typeParameterNames)
                {
                    TypeParameter typeParameter = new TypeParameter();
                    typeParameter.Name = typeParameterName;
                    method.AddTypeParameter(typeParameter);
                }
            }

            method.Parameters = this.ParseParameters();

            if (isGeneric)
            {
                ParseTypeParameterConstraints(method);
            }

            EatWhiteSpace();
            bool endOfStatement = NextChar == CSharpSymbol.EndOfStatement;
            if (endOfStatement)
            {
                TryReadChar();
                method.BodyText = null;
            }
            else
            {
                bool expression = NextChar == CSharpSymbol.Assignment;
                if (expression)
                {
                    var expressionHead = new[] { CSharpSymbol.ExpressionBodyArrow1, CSharpSymbol.ExpressionBodyArrow2 };
                    // lucky for us, expressions can only have one statement (unlike expression lambdas),
                    // therefore we must have text like this "=> followed.by.a.statement;" which ParseOptionalAssignment will automatically trim to "followed.by.a.statement"
                    method.BodyText = this.ParseOptionalExpression(expressionHead);
                    method.HasExpressionBody = true;
                    if (string.IsNullOrEmpty(method.BodyText))
                    {
                        // is expression, but no suitable body found
                        this.OnParseError("Unexpected end of method. Expected " + new string(expressionHead) + " or a method body.");
                    }
                }
                else
                {
                    method.BodyText = this.ParseBlock(true, method);
                }
            }

            return method;
        }