/// <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; }
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."); }
/// <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); }
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."); }
/// <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; }
/// <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."); }
/// <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); } }
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."); }
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."); }
/// <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); } }
/// <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; }
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); } }
/// <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; }
/// <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; }