/// <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; }
/// <summary> /// Processes a property element. /// </summary> /// <param name="element">Property code element.</param> public override void VisitPropertyElement(PropertyElement element) { this.WriteComments(element.HeaderComments); this.WriteAttributes(element); WriteAccess(element.Access); WriteMemberAttributes( element.MemberModifiers, element[VBExtendedProperties.Overloads] is bool && (bool)element[VBExtendedProperties.Overloads]); if (element[VBExtendedProperties.Default] is bool && (bool)element[VBExtendedProperties.Default]) { Writer.Write(VBKeyword.Default); Writer.Write(' '); } if (element[VBExtendedProperties.AccessModifier] != null && element[VBExtendedProperties.AccessModifier].ToString() != VBKeyword.ReadOnly) { Writer.Write(element[VBExtendedProperties.AccessModifier]); Writer.Write(' '); } Writer.Write(VBKeyword.Property); Writer.Write(' '); Writer.Write(element.Name); Writer.Write(VBSymbol.BeginParameterList); if (element.IndexParameter != null) { Writer.Write(element.IndexParameter.Trim()); } Writer.Write(VBSymbol.EndParameterList); WriteReturnType(element.Type); WriteImplements(element.Implements); WriteBody(element); }
/// <summary> /// Processes a property element. /// </summary> /// <param name="element">Property code element.</param> public abstract void VisitPropertyElement(PropertyElement element);
/// <summary> /// Processes a property element. /// </summary> /// <param name="element">Property element to process.</param> public override void VisitPropertyElement(PropertyElement element) { this.WriteComments(element.HeaderComments); this.WriteAttributes(element); WriteAccess(element.Access); WriteMemberAttributes(element.MemberModifiers); Writer.Write(element.Type); Writer.Write(' '); Writer.Write(element.Name); if (element.IndexParameter != null) { Writer.Write(CSharpSymbol.BeginAttribute); Writer.Write(element.IndexParameter); Writer.Write(CSharpSymbol.EndAttribute); } Writer.WriteLine(); WriteBody(element); }
public void GroupSortByAccessTest() { GroupBy groupBy = new GroupBy(); groupBy.By = ElementAttributeType.Access; groupBy.Direction = SortDirection.Ascending; GroupedInserter groupedInserter = new GroupedInserter(groupBy); // // Create a parent element // GroupElement groupElement = new GroupElement(); Assert.AreEqual(0, groupElement.Children.Count, "Parent element should not have any children."); // Insert elements PropertyElement property1 = new PropertyElement(); property1.Access = CodeAccess.Internal; property1.Name = "Property1"; property1.Type = "string"; groupedInserter.InsertElement(groupElement, property1); PropertyElement property2 = new PropertyElement(); property2.Access = CodeAccess.Public; property2.Name = "Property2"; property2.Type = "string"; groupedInserter.InsertElement(groupElement, property2); PropertyElement property3 = new PropertyElement(); property3.Access = CodeAccess.Protected | CodeAccess.Internal; property3.Name = "Property3"; property3.Type = "string"; groupedInserter.InsertElement(groupElement, property3); PropertyElement property4 = new PropertyElement(); property4.Access = CodeAccess.Private; property4.Name = "Property4"; property4.Type = "string"; groupedInserter.InsertElement(groupElement, property4); PropertyElement property5 = new PropertyElement(); property5.Access = CodeAccess.Public; property5.Name = "Property5"; property5.Type = "string"; groupedInserter.InsertElement(groupElement, property5); Assert.AreEqual(4, groupElement.Children.Count, "Unexpected number of child groups."); GroupElement childGroup; childGroup = groupElement.Children[0] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(1, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("Property4", childGroup.Children[0].Name); childGroup = groupElement.Children[1] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(1, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("Property1", childGroup.Children[0].Name); childGroup = groupElement.Children[2] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(1, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("Property3", childGroup.Children[0].Name); childGroup = groupElement.Children[3] as GroupElement; Assert.IsNotNull(childGroup, "Expected a child group."); Assert.AreEqual(2, childGroup.Children.Count, "Unexpected number of group children."); Assert.AreEqual("Property2", childGroup.Children[0].Name); Assert.AreEqual("Property5", childGroup.Children[1].Name); }
/// <summary> /// Parses a property. /// </summary> /// <param name="memberName">Name of the member.</param> /// <param name="returnType">Type of the return.</param> /// <param name="access">The access.</param> /// <param name="memberAttributes">The member attributes.</param> /// <returns>A property code element.</returns> private PropertyElement ParseProperty(string memberName, string returnType, CodeAccess access, MemberModifiers memberAttributes) { PropertyElement property = new PropertyElement(); int indexStart = memberName.IndexOf(CSharpSymbol.BeginAttribute); if (indexStart >= 0) { string indexParameter = memberName.Substring(indexStart).Trim().Trim( CSharpSymbol.BeginAttribute, CSharpSymbol.EndAttribute).Trim(); property.IndexParameter = indexParameter; memberName = memberName.Substring(0, indexStart); } property.Name = memberName; property.Access = access; property.Type = returnType; property.MemberModifiers = memberAttributes; property.BodyText = this.ParseBlock(false, property); return property; }
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); } }
private void WriteAutoPropertyInitializer(PropertyElement element) { Writer.Write(" = "); Writer.Write(element.AutoPropertyInitializer); Writer.Write(';'); }
/// <summary> /// Processes a property element. /// </summary> /// <param name="element">Property element to process.</param> public override void VisitPropertyElement(PropertyElement element) { this.WriteComments(element.HeaderComments); this.WriteAttributes(element); WriteAccess(element.Access); WriteMemberAttributes(element.MemberModifiers); Writer.Write(element.Type); Writer.Write(' '); Writer.Write(element.Name); if (element.IndexParameter != null) { Writer.Write(CSharpSymbol.BeginAttribute); Writer.Write(element.IndexParameter); Writer.Write(CSharpSymbol.EndAttribute); } // only inline the property if it doesn't contain braces as that means // that we are definitly not using get;/set; notation // new in C# 6: expression properties that are implicit get-only properties, we handle those below var inline = !element.IsExpressionBodyProperty && !element.BodyText.Contains("{") && !element.BodyText.Contains("}"); if (inline) { // code copied from WriteBody method; but altered to // remove indenting with tabs and line feeds this.Writer.Write(" { "); if (element.BodyText == null || element.BodyText.Trim().Length <= 0) { this.Writer.Write("}"); if (!string.IsNullOrEmpty(element.AutoPropertyInitializer)) { WriteAutoPropertyInitializer(element); } return; } // check whether we actually have a valid property var noFormatting = element.BodyText.Replace("\r", "").Replace("\n", "").Replace(" ", "").Replace("\t", ""); if (noFormatting.Contains("get;") || noFormatting.Contains("set;")) { // in C# get; or set; cannpt be used in combination with get {} or set {}, therefore if one of them has a ";" we can assume auto property // it appears to be; inline by replacing all linefeeds and whitespaces var noDoubleWhiteSpaces = element.BodyText.Replace("\t", "").Replace("\r", "").Replace("\n", " "); while (noDoubleWhiteSpaces.Contains(" ")) { noDoubleWhiteSpaces = noDoubleWhiteSpaces.Replace(" ", " "); } base.Writer.Write(noDoubleWhiteSpaces); this.Writer.Write(" }"); base.WriteClosingComment(element, "// "); if (!string.IsNullOrEmpty(element.AutoPropertyInitializer)) { WriteAutoPropertyInitializer(element); } return; } } // no inline = use same methods as before if (element.IsExpressionBodyProperty) { Writer.Write(" => "); Writer.Write(element.ExpressionBodyText); Writer.Write(';'); } else { Writer.WriteLine(); WriteBody(element); if (!string.IsNullOrEmpty(element.AutoPropertyInitializer)) { WriteAutoPropertyInitializer(element); } } }
/// <summary> /// Parses a property. /// </summary> /// <param name="memberName">Name of the member.</param> /// <param name="returnType">Type of the return.</param> /// <param name="access">The access.</param> /// <param name="memberAttributes">The member attributes.</param> /// <param name="isExpressionBodyProperty">Set to true if the property uses the new C# 6 API where it does not even need braces, but instead can directly use an expression body (= implicit get only property).</param> /// <returns>A property code element.</returns> private PropertyElement ParseProperty(string memberName, string returnType, CodeAccess access, MemberModifiers memberAttributes, bool isExpressionBodyProperty) { PropertyElement property = new PropertyElement(); int indexStart = memberName.IndexOf(CSharpSymbol.BeginAttribute); if (indexStart >= 0) { string indexParameter = memberName.Substring(indexStart).Trim().Trim( CSharpSymbol.BeginAttribute, CSharpSymbol.EndAttribute).Trim(); property.IndexParameter = indexParameter; memberName = memberName.Substring(0, indexStart); } property.Name = memberName; property.Access = access; property.Type = returnType; property.MemberModifiers = memberAttributes; if (isExpressionBodyProperty) { property.IsExpressionBodyProperty = true; var expressionHead = new[] { CSharpSymbol.ExpressionBodyArrow1, CSharpSymbol.ExpressionBodyArrow2 }; // we can skip the first part as it already has been swallowed in order to identify the property var body = this.ParseOptionalExpression(expressionHead.Skip(1).ToArray()); if (string.IsNullOrEmpty(body)) { // in this case the expression is not optional and in fact required. this.OnParseError("Unexpected end of property. Expected " + new string(expressionHead) + " or property body with getter/setter."); } property.ExpressionBodyText = body; } else { property.BodyText = this.ParseBlock(false, property); property.AutoPropertyInitializer = this.ParseOptionalExpression(new[] { CSharpSymbol.Assignment }); } return property; }