/// <inheritdoc /> public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node) { if (node is null) { throw new System.ArgumentNullException(nameof(node)); } if (!node.Modifiers.Any(SyntaxKind.StaticKeyword) && node.TryGetBackingField(out var field) && node.Parent is TypeDeclarationSyntax containingType) { if (containingType.Members.IndexOf(node) is int pi && containingType.Members.IndexOf(field) is int fi && fi == pi - 1) { if (fi == 0 || containingType.Members[fi - 1].IsKind(SyntaxKind.FieldDeclaration)) { return; } this.newLineBetween = node.HasLeadingTrivia && node.GetLeadingTrivia().Any(SyntaxKind.EndOfLineTrivia); this.Update(CodeStyleResult.Yes); }
public static MethodDeclarationSyntax ReplacePropertyWithMethod(PropertyDeclarationSyntax property, string methodName) { AccessorDeclarationSyntax getter = property.Getter(); BlockSyntax getterBody = getter.Body; BlockSyntax methodBody = null; if (getterBody != null) { methodBody = Block(getterBody.Statements) .WithTrailingTrivia(property.GetTrailingTrivia()); } else { methodBody = Block( ReturnStatement(property.Initializer.Value) .WithTrailingTrivia(property.GetTrailingTrivia())); } MethodDeclarationSyntax method = MethodDeclaration( property.AttributeLists, property.Modifiers, property.Type, property.ExplicitInterfaceSpecifier, Identifier(methodName).WithLeadingTrivia(property.Identifier.LeadingTrivia), default(TypeParameterListSyntax), ParameterList().WithTrailingTrivia(property.Identifier.TrailingTrivia), default(SyntaxList <TypeParameterConstraintClauseSyntax>), methodBody, default(ArrowExpressionClauseSyntax)); return(method .WithLeadingTrivia(property.GetLeadingTrivia()) .WithFormatterAnnotation()); }
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) => node.NormalizeWhitespace(indentation: "", eol: " ") .WithLeadingTrivia(node.GetLeadingTrivia()) .WithTrailingTrivia(node.GetTrailingTrivia());
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) { node = (PropertyDeclarationSyntax)base.VisitPropertyDeclaration(node); var newNode = node; if (node.ExpressionBody != null) { newNode = SyntaxHelper.ToStatementBody(node); } if (node.IsAutoProperty() && node.AccessorList != null) { var setter = node.AccessorList.Accessors.SingleOrDefault(a => a.Keyword.Kind() == SyntaxKind.SetKeyword); if (setter == null) { var getter = node.AccessorList.Accessors.Single(a => a.Keyword.Kind() == SyntaxKind.GetKeyword); setter = SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithModifiers(SyntaxTokenList.Create(SyntaxFactory.Token(SyntaxKind.PrivateKeyword).WithTrailingTrivia(SyntaxFactory.Space))) .WithBody(null) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)) .WithLeadingTrivia(getter.GetLeadingTrivia()) .WithTrailingTrivia(getter.GetTrailingTrivia()); newNode = newNode.AddAccessorListAccessors(setter); } if (newNode.Initializer != null) { var modifiers = SyntaxTokenList.Create(SyntaxFactory.Token(SyntaxKind.PrivateKeyword).WithTrailingTrivia(SyntaxFactory.Space)); if (node.Modifiers.Any(m => m.Kind() == SyntaxKind.StaticKeyword)) { modifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.StaticKeyword).WithTrailingTrivia(SyntaxFactory.Space)); } var field = SyntaxFactory.FieldDeclaration(SyntaxFactory.List <AttributeListSyntax>(), modifiers, SyntaxFactory.VariableDeclaration( node.Type, SyntaxFactory.SeparatedList(new[] { SyntaxFactory.VariableDeclarator( SyntaxFactory.Identifier(AutoInitFieldPrefix + node.Identifier.Text), null, newNode.Initializer ) }) ), SyntaxFactory.Token(SyntaxKind.SemicolonToken) ); field = field.WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia()); fields.Add(field); newNode = newNode.ReplaceNode(newNode.Initializer, (SyntaxNode)null); newNode = SyntaxHelper.RemoveSemicolon(newNode, newNode.SemicolonToken, t => newNode.WithSemicolonToken(t)); } return(newNode); } return(newNode.Equals(node) ? node : newNode); }
PropertyDeclarationSyntax ConvertProperty(PropertyDeclarationSyntax propertyDeclaration, FieldDeclarationSyntax relatedField) { var leadingList = new SyntaxTriviaList(); if (relatedField.Declaration.Variables.Count == 1) { leadingList = leadingList.AddRange(relatedField.GetLeadingTrivia()); } var propertyDeclaration_GetLeadingTrivia = propertyDeclaration.GetLeadingTrivia(); if (leadingList.Any() && propertyDeclaration_GetLeadingTrivia.First().IsKind(SyntaxKind.EndOfLineTrivia) == false) { var endOfLine = relatedField.GetLeadingTrivia().FirstOrDefault(x => x.IsKind(SyntaxKind.EndOfLineTrivia)); if (endOfLine != null) { leadingList = leadingList.Add(endOfLine); } } leadingList = leadingList.AddRange(propertyDeclaration.GetLeadingTrivia()); var getNode = propertyDeclaration.AccessorList.Accessors.FirstOrDefault(x => x.Keyword.IsKind(SyntaxKind.GetKeyword)); var setNode = propertyDeclaration.AccessorList.Accessors.FirstOrDefault(x => x.Keyword.IsKind(SyntaxKind.SetKeyword)); propertyDeclaration = propertyDeclaration .WithAccessorList ( propertyDeclaration.AccessorList.WithAccessors( new SyntaxList <AccessorDeclarationSyntax>() .Add( getNode .WithBody(null) .WithTrailingTrivia() .WithSemicolonToken( SyntaxFactory.ParseToken(";") .WithTrailingTrivia(SyntaxFactory.Space) ) .WithLeadingTrivia(SyntaxFactory.Space) ) .Add( setNode .WithBody(null) .WithTrailingTrivia() .WithSemicolonToken( SyntaxFactory.ParseToken(";") .WithTrailingTrivia(SyntaxFactory.Space) ) .WithLeadingTrivia(SyntaxFactory.Space) ) ) .WithOpenBraceToken(propertyDeclaration.AccessorList.OpenBraceToken.WithLeadingTrivia().WithTrailingTrivia()) .WithCloseBraceToken(propertyDeclaration.AccessorList.CloseBraceToken.WithLeadingTrivia()) ) .WithIdentifier(propertyDeclaration.Identifier.WithTrailingTrivia(SyntaxFactory.Space)) .WithLeadingTrivia(leadingList); return(propertyDeclaration); }
public static SyntaxNode Do(Compilation compilation, Compilation interfacesCompilation, SyntaxNode root, SyntaxNode targetTypeDeclaration) { // Couldn't get SymbolFinder.FindImplementedInterfaceMembersAsync or .FindImplementations working, so doing it the hard hacky way. if (targetTypeDeclaration is StructDeclarationSyntax) { return(root); // not propagating documentation into the structs (used for enumeration entry definitions) } // collect all interfaces and the methods/properties they declare Dictionary <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaces = new Dictionary <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> >(); foreach (Compilation compilation1 in new Compilation[] { interfacesCompilation, compilation }) { foreach (SyntaxTree interfaceTree in compilation1.SyntaxTrees) { foreach (SyntaxNode node in interfaceTree.GetRoot().DescendantNodesAndSelf().Where( delegate(SyntaxNode candidate) { return(candidate.IsKind(SyntaxKind.InterfaceDeclaration)); })) { if (AttributeMatchUtil.HasAttributeSimple(((InterfaceDeclarationSyntax)node).AttributeLists, DocSourceAttributeName)) { List <MemberDeclarationSyntax> members = new List <MemberDeclarationSyntax>(); foreach (SyntaxNode decl in node.DescendantNodesAndSelf().Where(delegate(SyntaxNode candidate) { return(candidate.IsKind(SyntaxKind.MethodDeclaration) || candidate.IsKind(SyntaxKind.PropertyDeclaration)); })) { members.Add((MemberDeclarationSyntax)decl); } InterfaceDeclarationSyntax ifaceDecl = (InterfaceDeclarationSyntax)node; interfaces.Add(ifaceDecl, members); } } } } // enumrate base types of generated class List <BaseTypeSyntax> baseTypes = new List <BaseTypeSyntax>(); { IEnumerable <BaseTypeSyntax> baseTypeList = ((ClassDeclarationSyntax)targetTypeDeclaration).BaseList.Types; foreach (BaseTypeSyntax baseType in baseTypeList) { baseTypes.Add(baseType); } } Dictionary <SyntaxNode, SyntaxNode> replacements = new Dictionary <SyntaxNode, SyntaxNode>(); foreach (BaseTypeSyntax baseType in baseTypes) { // can we find an interface that matches this? foreach (KeyValuePair <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaceItem in interfaces) { InterfaceDeclarationSyntax interfaceDeclaration = interfaceItem.Key; // hack string baseTypeString = GetStringForBaseTypeComparison(baseType); string patternString = GetStringForInterfaceComparison(interfaceDeclaration); //Console.WriteLine("{2} {0} ? {1}", baseTypeString, patternString, String.Equals(baseTypeString, patternString) ? "*" : " "); if (String.Equals(baseTypeString, patternString)) { // can we find any members we implemented that are in the interface? foreach (SyntaxNode node in targetTypeDeclaration.DescendantNodes(delegate(SyntaxNode descendInto) { return((descendInto == targetTypeDeclaration) || descendInto.IsKind(SyntaxKind.MethodDeclaration) || descendInto.IsKind(SyntaxKind.PropertyDeclaration)); }) .Where(delegate(SyntaxNode candidate) { return(candidate.IsKind(SyntaxKind.MethodDeclaration) || candidate.IsKind(SyntaxKind.PropertyDeclaration)); })) { if (node.IsKind(SyntaxKind.MethodDeclaration)) { MethodDeclarationSyntax implementation = (MethodDeclarationSyntax)node; if (default(SyntaxToken) == implementation.Modifiers.FirstOrDefault(delegate(SyntaxToken candidate) { return(candidate.IsKind(SyntaxKind.PublicKeyword)); })) { continue; // non-public can't be from an interface } foreach (MemberDeclarationSyntax prototype1 in interfaceItem.Value) { if (prototype1.IsKind(SyntaxKind.MethodDeclaration)) { MethodDeclarationSyntax prototype = (MethodDeclarationSyntax)prototype1; // HACK: should check argument and return types if (SyntaxFactory.AreEquivalent(implementation.Identifier, prototype.Identifier) && (implementation.ParameterList.Parameters.Count == prototype.ParameterList.Parameters.Count)) { // copy documentation SyntaxNode replacement = node.WithLeadingTrivia( node.GetLeadingTrivia() .Add(SyntaxFactory.EndOfLine(Environment.NewLine)) .AddRange(CookDocumentationTrivia(prototype.GetLeadingTrivia()))); if (!replacements.ContainsKey(node)) // in case exposed by multiple interfaces { replacements.Add(node, replacement); } break; } } } } else if (node.IsKind(SyntaxKind.PropertyDeclaration)) { PropertyDeclarationSyntax implementation = (PropertyDeclarationSyntax)node; if (default(SyntaxToken) == implementation.Modifiers.FirstOrDefault(delegate(SyntaxToken candidate) { return(candidate.IsKind(SyntaxKind.PublicKeyword)); })) { continue; // non-public can't be from an interface } foreach (MemberDeclarationSyntax prototype1 in interfaceItem.Value) { if (prototype1.IsKind(SyntaxKind.PropertyDeclaration)) { PropertyDeclarationSyntax prototype = (PropertyDeclarationSyntax)prototype1; // HACK if (SyntaxFactory.AreEquivalent(implementation.Identifier, prototype.Identifier)) { // copy documentation SyntaxNode replacement = node.WithLeadingTrivia( node.GetLeadingTrivia() .Add(SyntaxFactory.EndOfLine(Environment.NewLine)) .AddRange(CookDocumentationTrivia(prototype.GetLeadingTrivia()))); if (!replacements.ContainsKey(node)) // in case exposed by multiple interfaces { replacements.Add(node, replacement); } break; } } } } else { throw new ArgumentException(); } } break; } } } SyntaxNodeReplacementRewriter syntaxNodeReplacementRewriter = new SyntaxNodeReplacementRewriter(replacements); root = syntaxNodeReplacementRewriter.Visit(root); // This is probably really slow - but we can use AreEquivalent() since we've only changed trivia targetTypeDeclaration = root.DescendantNodes().First(delegate(SyntaxNode candidate) { return(SyntaxFactory.AreEquivalent(targetTypeDeclaration, candidate)); }); replacements.Clear(); foreach (BaseTypeSyntax baseType in baseTypes) { // can we find an interface that matches this? foreach (KeyValuePair <InterfaceDeclarationSyntax, List <MemberDeclarationSyntax> > interfaceItem in interfaces) { InterfaceDeclarationSyntax interfaceDeclaration = interfaceItem.Key; // hack if (String.Equals(baseType.Type.ToString(), String.Concat(interfaceDeclaration.Identifier.Text, interfaceDeclaration.TypeParameterList != null ? interfaceDeclaration.TypeParameterList.ToString() : null))) { // propagate interface comment to class if (!replacements.ContainsKey(targetTypeDeclaration)) { replacements.Add( targetTypeDeclaration, targetTypeDeclaration.WithLeadingTrivia( targetTypeDeclaration.GetLeadingTrivia() .Add(SyntaxFactory.EndOfLine(Environment.NewLine)) .AddRange(CookDocumentationTrivia(interfaceDeclaration.GetLeadingTrivia())))); } break; } } } syntaxNodeReplacementRewriter = new SyntaxNodeReplacementRewriter(replacements); root = syntaxNodeReplacementRewriter.Visit(root); return(root); }
public static SyntaxNode RemoveModifierFromNode(SyntaxNode node, SyntaxKind modifier) { //there seem to be no base classes to support WithModifiers. //dynamic modifiersNode = node; //return modifiersNode.WithModifiers(SyntaxFactory.TokenList(modifiersNode.Modifiers.Where(m => !m.IsKind(SyntaxKind.PrivateKeyword)))); MethodDeclarationSyntax methodNode = node as MethodDeclarationSyntax; if (methodNode != null) { return(methodNode.WithModifiers(SyntaxFactory.TokenList(methodNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(methodNode.GetLeadingTrivia())); } FieldDeclarationSyntax fieldNode = node as FieldDeclarationSyntax; if (fieldNode != null) { return(fieldNode.WithModifiers(SyntaxFactory.TokenList(fieldNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(fieldNode.GetLeadingTrivia())); } PropertyDeclarationSyntax propertyNode = node as PropertyDeclarationSyntax; if (propertyNode != null) { return(propertyNode.WithModifiers(SyntaxFactory.TokenList(propertyNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(propertyNode.GetLeadingTrivia())); } IndexerDeclarationSyntax indexerNode = node as IndexerDeclarationSyntax; if (indexerNode != null) { return(indexerNode.WithModifiers(SyntaxFactory.TokenList(indexerNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(indexerNode.GetLeadingTrivia())); } EventDeclarationSyntax eventNode = node as EventDeclarationSyntax; if (eventNode != null) { return(eventNode.WithModifiers(SyntaxFactory.TokenList(eventNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(eventNode.GetLeadingTrivia())); } ConstructorDeclarationSyntax ctrNode = node as ConstructorDeclarationSyntax; if (ctrNode != null) { return(ctrNode.WithModifiers(SyntaxFactory.TokenList(ctrNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(ctrNode.GetLeadingTrivia())); } OperatorDeclarationSyntax opNode = node as OperatorDeclarationSyntax; if (opNode != null) { return(opNode.WithModifiers(SyntaxFactory.TokenList(opNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(opNode.GetLeadingTrivia())); } ClassDeclarationSyntax classNode = node as ClassDeclarationSyntax; if (classNode != null) { return(classNode.WithModifiers(SyntaxFactory.TokenList(classNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(classNode.GetLeadingTrivia())); } InterfaceDeclarationSyntax interfaceNode = node as InterfaceDeclarationSyntax; if (interfaceNode != null) { return(interfaceNode.WithModifiers(SyntaxFactory.TokenList(interfaceNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(interfaceNode.GetLeadingTrivia())); } StructDeclarationSyntax structNode = node as StructDeclarationSyntax; if (structNode != null) { return(structNode.WithModifiers(SyntaxFactory.TokenList(structNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(structNode.GetLeadingTrivia())); } var enumNode = node as EnumDeclarationSyntax; if (enumNode != null) { return(enumNode.WithModifiers(SyntaxFactory.TokenList(enumNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(enumNode.GetLeadingTrivia())); } var delegateNode = node as DelegateDeclarationSyntax; if (delegateNode != null) { return(delegateNode.WithModifiers(SyntaxFactory.TokenList(delegateNode.Modifiers.Where(m => !m.IsKind(modifier)))) .WithLeadingTrivia(delegateNode.GetLeadingTrivia())); } return(node); }
private async Task <Document> CreatePrismProperty(Document document, PropertyDeclarationSyntax propertyDeclaration, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var classDeclaration = propertyDeclaration.FirstAncestorOrSelf <ClassDeclarationSyntax>(); var fields = classDeclaration?.DescendantNodes().OfType <FieldDeclarationSyntax>(); var backingFieldName = propertyDeclaration.Identifier.ValueText; if (char.IsUpper(backingFieldName, 0)) { backingFieldName = char.ToLower(backingFieldName[0]) + backingFieldName.Substring(1); } else { backingFieldName = "_" + backingFieldName; } if (fields != null) { int i = 1; while (fields.Any(f => f.Declaration.Variables.Any(v => v.Identifier.ValueText == backingFieldName))) { i++; backingFieldName = backingFieldName + i.ToString("D"); } } var indentation = propertyDeclaration.GetLeadingTrivia().LastOrDefault(t => t.Kind() == SyntaxKind.WhitespaceTrivia); var newFieldDeclaration = SyntaxFactory.FieldDeclaration( SyntaxFactory.VariableDeclaration( propertyDeclaration.Type.WithTrailingTrivia(SyntaxFactory.Space), SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(backingFieldName))))) .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxFactory.TriviaList(indentation), SyntaxKind.PrivateKeyword, SyntaxFactory.TriviaList(SyntaxFactory.Space)))); var newPropertyDeclaration = propertyDeclaration .WithAccessorList(SyntaxFactory.AccessorList(SyntaxFactory.List(new[] { CreateGetter(backingFieldName), CreateSetter(backingFieldName) }))); var newRoot = root.ReplaceNode(propertyDeclaration, newPropertyDeclaration); classDeclaration = classDeclaration != null?newRoot.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault(c => c.Identifier.ValueText == classDeclaration.Identifier.ValueText) : null; if (classDeclaration != null) { var ctor = classDeclaration.DescendantNodes().OfType <ConstructorDeclarationSyntax>().FirstOrDefault(); if (ctor != null) { newRoot = newRoot.InsertNodesBefore(ctor, new[] { newFieldDeclaration }); } else { var lastFieldDeclaration = classDeclaration.DescendantNodes().OfType <FieldDeclarationSyntax>().LastOrDefault(); if (lastFieldDeclaration != null) { newRoot = newRoot.InsertNodesAfter(lastFieldDeclaration, new[] { newFieldDeclaration }); } else { var newMembers = classDeclaration.Members.Insert(0, newFieldDeclaration); newRoot = newRoot.ReplaceNode(classDeclaration, classDeclaration.WithMembers(newMembers)); } } } else { newRoot = newRoot.InsertNodesBefore(newRoot.DescendantNodes().OfType <PropertyDeclarationSyntax>().FirstOrDefault(), new[] { newFieldDeclaration }); } return(document.WithSyntaxRoot(newRoot)); }
public static PropertyDeclarationSyntax ConvertToExpressionBodiedHelper(PropertyDeclarationSyntax propertyDeclaration) { if (propertyDeclaration.AccessorList == null) { return(propertyDeclaration); } var getNode = propertyDeclaration.AccessorList.Accessors.FirstOrDefault( x => x.Keyword.IsKind(SyntaxKind.GetKeyword)); var setNode = propertyDeclaration.AccessorList.Accessors.FirstOrDefault( x => x.Keyword.IsKind(SyntaxKind.SetKeyword)); if (setNode != null || getNode.Body == null) { return(propertyDeclaration); } if (getNode.Body == null) { return(propertyDeclaration); } if (getNode.Body.Statements.Count > 1) { return(propertyDeclaration); } if (getNode.Body.ContainsDirectives) { return(propertyDeclaration); } var returnStatements = getNode.Body.Statements.OfType <ReturnStatementSyntax>().ToList(); if (returnStatements.Count() != 1) { return(propertyDeclaration); } var expression = returnStatements.FirstOrDefault().Expression.WithoutTrivia(); var length = expression.Span.Length + propertyDeclaration.Span.Length - propertyDeclaration.AccessorList.FullSpan.Length; if (length >= 100) { return(propertyDeclaration); } propertyDeclaration = propertyDeclaration .WithIdentifier(propertyDeclaration.Identifier.WithTrailingTrivia(_spaceTrivia)) .WithLeadingTrivia(propertyDeclaration.GetLeadingTrivia()) .WithExpressionBody( SyntaxFactory.ArrowExpressionClause(expression.WithLeadingTrivia(_spaceTrivia))) .WithAccessorList(null) .WithSemicolonToken(GetSemicolon(propertyDeclaration.AccessorList)) .WithAdditionalAnnotations(Formatter.Annotation); return(propertyDeclaration); }
private PropertyInfo GetPropertyInfo(PropertyDeclarationSyntax node, SemanticModel semanticModel) { // 得到备注 var singleLineComment = node.GetLeadingTrivia().Where(x => x.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia); var isEnumerable = false; var isGeneric = false; var typeInfo = semanticModel.GetTypeInfo(node.Type); var propertyName = node.Identifier.ValueText; var hasSetter = node.AccessorList?.Accessors.FirstOrDefault( a => a.IsKind(SyntaxKind.SetAccessorDeclaration) && !a.Modifiers.Any(m => m.IsKind(SyntaxKind.PrivateKeyword))) != null; var typeName = ""; PropertyMapper mapper = new UnknownTypePropertyMapper(propertyName, hasSetter); if (typeInfo.ConvertedType is INamedTypeSymbol namedType) { var namedTypeFullName = namedType.ToString().Replace(" ", string.Empty); isEnumerable = namedType.ConstructedFrom.MemberNames.Contains("GetEnumerator"); var simpleTypeKinds = new[] { TypeKind.Enum, TypeKind.Struct, TypeKind.Interface }; var isSimple = namedType.IsValueType || simpleTypeKinds.Any(t => namedType.TypeKind == t) || namedType.Name.Equals("object", StringComparison.CurrentCultureIgnoreCase) || namedType.Name.Equals("string", StringComparison.CurrentCultureIgnoreCase); if (isSimple) { mapper = new SimplePropertyMapper(propertyName, hasSetter); } else { isGeneric = namedType.ConstructedFrom.IsGenericType; if (isEnumerable) { if (namedType.Name.Equals("List", StringComparison.InvariantCultureIgnoreCase)) { typeName = namedTypeFullName.Substring(namedTypeFullName.LastIndexOf(".List", StringComparison.InvariantCultureIgnoreCase) + 1); var fullGenericPart = $"{typeName.Replace("List<", string.Empty).Replace(">", string.Empty)}"; var genericPart = fullGenericPart.Substring(fullGenericPart.LastIndexOf('.') + 1); if (Constants.SimpleTypeNames.Any(t => genericPart.Equals(t))) { mapper = new SimpleGenericListPropertyMapper(propertyName, hasSetter); } else { genericPart = $"{genericPart}{Constants.DtoSuffix}"; mapper = new ListPropertyMapper(genericPart, propertyName, hasSetter); } typeName = $"List<{genericPart}>"; } } else { typeName = $"{namedType.Name}{Constants.DtoSuffix}"; mapper = new ClassPropertyMapper(typeName, propertyName, hasSetter); } } } else { if (typeInfo.ConvertedType.Kind == SymbolKind.ArrayType && typeInfo.ConvertedType is IArrayTypeSymbol arrayType) { if (arrayType.ElementType.IsValueType || arrayType.ElementType.Name.ToLowerInvariant().Contains("string")) { mapper = new SimpleArrayPropertyMapper(propertyName, hasSetter); } else { typeName = $"{arrayType.ElementType.Name}{Constants.DtoSuffix}[]"; mapper = new ArrayPropertyMapper($"{arrayType.ElementType.Name}{Constants.DtoSuffix}", propertyName, hasSetter); } isEnumerable = true; } } return(new PropertyInfo { Name = propertyName, Type = node.Type, TypeName = typeName, IsEnumerableType = isEnumerable, IsGenericType = isGeneric, Mapper = mapper, HasSetter = hasSetter, CommentTrivias = singleLineComment }); }
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) { var hasMatch = NodeHelper.HasMatch(node.AttributeLists, Constants.Data.PROPERTY_ATTRIBUTE_NAME, Constants.Data.PROPERTY_IGNORE_ATTRIBUTE_NAME); if (!hasMatch) { var name = SyntaxFactory.ParseName(Constants.Data.PROPERTY_ATTRIBUTE_NAME); var arguments = SyntaxFactory.ParseAttributeArgumentList($"(Order = {_startIndex})"); var attribute = SyntaxFactory.Attribute(name, arguments); //DataMember(Order = 1) node = TriviaMaintainer.Apply(node, (innerNode, wp) => { var newAttributes = BuildAttribute(attribute, innerNode.AttributeLists, wp); return(innerNode.WithAttributeLists(newAttributes).WithAdditionalAnnotations(Formatter.Annotation)); }); _startIndex++; } else { //renumber if (node.AttributeLists.Count > 0) { var newAttributeLists = new SyntaxList <AttributeListSyntax>(); foreach (var attributeList in node.AttributeLists) { var attributeSyntaxes = attributeList.Attributes.Where(attribute => NodeHelper.AttributeNameMatches(attribute, Constants.Data.PROPERTY_ATTRIBUTE_NAME)).ToArray(); var modifiedAttributeList = attributeList.Attributes; foreach (var attributeSyntax in attributeSyntaxes) { var attributeArguementSyntax = attributeSyntax.ArgumentList?.Arguments.FirstOrDefault(f => f.NameEquals.Name.Identifier.ValueText.Equals("Order")); var newToken = SyntaxFactory.Literal(_startIndex); var spaceTrivia = SyntaxFactory.TriviaList(SyntaxFactory.Space); var newExpression = SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, newToken); var equalsToken = SyntaxFactory.Token(SyntaxFactory.TriviaList(), SyntaxKind.EqualsToken, spaceTrivia); SeparatedSyntaxList <AttributeArgumentSyntax> newSeparatedArgList; if (attributeArguementSyntax?.Expression?.Kind() == SyntaxKind.NumericLiteralExpression) { var oldToken = attributeArguementSyntax.Expression.ChildTokens().FirstOrDefault(f => f.Kind() == SyntaxKind.NumericLiteralToken); if (oldToken == default) { continue; } var newIdentifier = attributeArguementSyntax.NameEquals.Name.Identifier.WithLeadingTrivia().WithTrailingTrivia(spaceTrivia); var newIdentifierNameSyntax = attributeArguementSyntax.NameEquals.Name.Update(newIdentifier); var newName = attributeArguementSyntax.NameEquals.Update(newIdentifierNameSyntax, equalsToken); var newAttributeArguementSyntax = attributeArguementSyntax.Update(newName, null, newExpression); newSeparatedArgList = attributeSyntax.ArgumentList.Arguments.Replace(attributeArguementSyntax, newAttributeArguementSyntax); } else { //No order attribute add it var newIdentifierNameSyntax = SyntaxFactory.IdentifierName("Order").WithTrailingTrivia(spaceTrivia); var newName = SyntaxFactory.NameEquals(newIdentifierNameSyntax, equalsToken); var newAttributeArguementSyntax = SyntaxFactory.AttributeArgument(newName, null, newExpression); if (attributeSyntax.ArgumentList == null) { var arguments = SyntaxFactory.AttributeArgumentList(); newSeparatedArgList = arguments.Arguments.Add(newAttributeArguementSyntax); } else { newSeparatedArgList = attributeSyntax.ArgumentList.Arguments.Add(newAttributeArguementSyntax); } } var newAttributeArgumentListSyntax = attributeSyntax.ArgumentList?.WithArguments(newSeparatedArgList); if (newAttributeArgumentListSyntax == null) { newAttributeArgumentListSyntax = attributeSyntax.WithArgumentList(SyntaxFactory.AttributeArgumentList(newSeparatedArgList)).ArgumentList; } var newAttributeSyntax = attributeSyntax.Update(attributeSyntax.Name, newAttributeArgumentListSyntax); modifiedAttributeList = modifiedAttributeList.Replace(attributeSyntax, newAttributeSyntax); _startIndex++; } newAttributeLists = newAttributeLists.Add(attributeList.WithAttributes(modifiedAttributeList)); } var leadTriv = node.GetLeadingTrivia(); node = node.WithAttributeLists(newAttributeLists); node = node.WithLeadingTrivia(leadTriv); } } return(base.VisitPropertyDeclaration(node)); }
private void AddProperty(PropertyDeclarationSyntax modelProperty, string propertyName, string propertyDescriptorName, TypeSyntax sourcePropertyType, TypeSyntax destinationPropertyType, List <MemberDeclarationSyntax> destinationMembers) { IdentifierNameSyntax propertyDescriptorIdentifier = IdentifierName(propertyDescriptorName); bool classPropertyTypeDiffersFromInterface = sourcePropertyType.ToString() != destinationPropertyType.ToString(); SyntaxTrivia xmlCommentTrivia = modelProperty.GetLeadingTrivia().FirstOrDefault(t => t.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia || t.Kind() == SyntaxKind.MultiLineDocumentationCommentTrivia); bool includeXmlComment = classPropertyTypeDiffersFromInterface && xmlCommentTrivia.Kind() != SyntaxKind.None; SyntaxTokenList modifiers; if (includeXmlComment) { modifiers = TokenList( Token( TriviaList(xmlCommentTrivia), SyntaxKind.PublicKeyword, TriviaList())); } else { modifiers = TokenList(Token(SyntaxKind.PublicKeyword)); } PropertyDeclarationSyntax propertyDeclaration; if (_outputType is XamlOutputType) { propertyDeclaration = PropertyDeclaration(destinationPropertyType, propertyName) .WithModifiers(modifiers) .WithAccessorList( AccessorList( List(new[] { AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithExpressionBody( ArrowExpressionClause( CastExpression( destinationPropertyType, InvocationExpression(IdentifierName("GetValue")) .WithArgumentList(ArgumentList( SingletonSeparatedList( Argument(propertyDescriptorIdentifier))))))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)), AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithExpressionBody( ArrowExpressionClause(InvocationExpression(IdentifierName("SetValue")) .WithArgumentList(ArgumentList( SeparatedList <ArgumentSyntax>( new SyntaxNodeOrToken[] { Argument(propertyDescriptorIdentifier), Token(SyntaxKind.CommaToken), Argument(IdentifierName("value")) }))))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)) }))) .NormalizeWhitespace(); } else { ExpressionSyntax defaultValue = GetDefaultValue(modelProperty, destinationPropertyType); propertyDeclaration = PropertyDeclaration(destinationPropertyType, propertyName) .WithModifiers(modifiers) .WithAccessorList( AccessorList( List(new[] { AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)), AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)) }))) .WithInitializer( EqualsValueClause(defaultValue)) .WithSemicolonToken( Token(SyntaxKind.SemicolonToken)); } //if (!includeXmlComment) propertyDeclaration = propertyDeclaration.WithLeadingTrivia( TriviaList(propertyDeclaration.GetLeadingTrivia() .Insert(0, CarriageReturnLineFeed) .Insert(0, CarriageReturnLineFeed))); destinationMembers.Add(propertyDeclaration); // If the interface property has a different type, add another property that explicitly implements it if (classPropertyTypeDiffersFromInterface) { ExpressionSyntax arrowRightHandSide; if (sourcePropertyType is IdentifierNameSyntax identifierName && IsWrappedType(identifierName.Identifier.Text)) { string wrapperTypeName = identifierName.Identifier.Text; arrowRightHandSide = MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(propertyName), IdentifierName($"Wrapped{wrapperTypeName}")); } else { arrowRightHandSide = IdentifierName(propertyName); } PropertyDeclarationSyntax explicitInterfaceProperty = PropertyDeclaration(sourcePropertyType, propertyName) .WithExplicitInterfaceSpecifier( ExplicitInterfaceSpecifier(IdentifierName(_sourceInterfaceDeclaration.Identifier))) .WithExpressionBody( ArrowExpressionClause(arrowRightHandSide)) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); destinationMembers.Add(explicitInterfaceProperty); }
internal static DocumentedElement LoadFromSyntaxNode(PropertyDeclarationSyntax node) { SyntaxToken syntaxToken = node.ChildTokens().First(token => token.IsKind(SyntaxKind.IdentifierToken)); return(DocumentedElement.LoadFromSyntaxTokenAndTrivia(syntaxToken, node.GetLeadingTrivia())); }