public ClassComposer AddProperty(PropertyOptions options) { if (!IsAtRoot()) { throw new Exception("A class must be selected (which is also a root to the composer) to add a field to it."); } PropertyDeclarationSyntax @property = SyntaxFactory .PropertyDeclaration(SyntaxFactory.ParseTypeName(options.PropertyType), options.PropertyName) .WithModifiers(options.ModifiersToTokenList()); @property = @property.AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken) )); @property = @property.AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken) )); var newNode = (CurrentNode as ClassDeclarationSyntax).AddMembers(@property); Replace(CurrentNode, newNode, null); return(this); }
private async Task <Document> AddBackingFieldAsync(Document document, SyntaxNode equalsSyntax, CancellationToken cancellationToken) { var pds = equalsSyntax as PropertyDeclarationSyntax; var propName = pds.Identifier.ToString(); var fieldName = "_" + char.ToLowerInvariant(propName[0]) + propName.Substring(1); var fieldType = pds.GetTypeName(); var backingField = SyntaxFactory.FieldDeclaration( SyntaxFactory.VariableDeclaration( SyntaxFactory.ParseTypeName(fieldType), SyntaxFactory.SeparatedList( new[] { SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(fieldName)), }))) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)); PropertyDeclarationSyntax newProperty = SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(fieldType), propName) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); newProperty = newProperty.AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration( SyntaxKind.GetAccessorDeclaration, SyntaxFactory.Block( SyntaxFactory.List(new[] { SyntaxFactory.ReturnStatement(SyntaxFactory.IdentifierName(fieldName)), })))); var setCall = SyntaxFactory.ExpressionStatement( SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("SetProperty")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(fieldName)) .WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.RefKeyword)), SyntaxFactory.Argument(SyntaxFactory.IdentifierName("value")))); newProperty = newProperty.AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration( SyntaxKind.SetAccessorDeclaration, SyntaxFactory.Block(SyntaxFactory.List(new[] { setCall })))); var oldRoot = await document.GetSyntaxRootAsync(cancellationToken); var newNodes = new List <SyntaxNode> { backingField, newProperty, }; var newRoot = oldRoot.ReplaceNode(pds, newNodes); return(document.WithSyntaxRoot(newRoot)); }
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) { if (node.ExplicitInterfaceSpecifier?.Name?.ToString() == nameof(IProxy)) { node = node.WithExpressionBody(ArrowExpressionClause( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("pipeline"), IdentifierName("Behaviors")))); } else { (var canRead, var canWrite) = generator.InspectProperty(node); canRead = canRead || node.ExpressionBody != null; if (node.ExpressionBody != null) { node = node.RemoveNode(node.ExpressionBody, SyntaxRemoveOptions.KeepNoTrivia); } if (node.AccessorList?.Accessors.Any() == true) { node = node.RemoveNodes(node.AccessorList.Accessors, SyntaxRemoveOptions.KeepNoTrivia); } if (canRead && !canWrite) { node = node.WithExpressionBody( ArrowExpressionClause(ExecutePipeline(node.Type, Enumerable.Empty <ParameterSyntax>()))); } else { if (canRead) { node = node.AddAccessorListAccessors(AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithExpressionBody(ArrowExpressionClause(ExecutePipeline(node.Type, Enumerable.Empty <ParameterSyntax>()))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); } if (canWrite) { node = node.AddAccessorListAccessors(AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithExpressionBody(ArrowExpressionClause( // NOTE: we always append the implicit "value" parameter for setters. ExecutePipeline(null, new[] { Parameter(Identifier("value")).WithType(node.Type) }))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); } } } return(base.VisitPropertyDeclaration(node)); }
public static PropertyDeclarationSyntax WithGetterAndInit( this PropertyDeclarationSyntax property) => property.AddAccessorListAccessors( AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)), AccessorDeclaration(SyntaxKind.InitAccessorDeclaration) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
private static PropertyDeclarationSyntax PropertyBody(PropertyDeclarationSyntax prop, SyntaxKind accessorKind, object[] code) { var statements = ToStatements(code).ToList(); if (accessorKind == SyntaxKind.GetAccessorDeclaration && !(prop.AccessorList?.Accessors.Any() ?? false) && statements.Count == 1 && statements[0] is ExpressionStatementSyntax expr) { // If this is a getter with no setter, containing a single expression, then use an expression-bodied property. return(prop.WithExpressionBody(ArrowExpressionClause(expr.Expression)).WithSemicolonToken(s_semicolonToken)); } if (accessorKind == SyntaxKind.SetAccessorDeclaration && prop.ExpressionBody != null) { prop = prop.AddAccessorListAccessors(AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithExpressionBody(prop.ExpressionBody).WithSemicolonToken(s_semicolonToken)) .WithExpressionBody(null); } return(WithBody(code, x => prop.AddAccessorListAccessors(AccessorDeclaration(accessorKind).WithExpressionBody(x).WithSemicolonToken(s_semicolonToken)), x => prop.AddAccessorListAccessors(AccessorDeclaration(accessorKind, x)))); }
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) { if (generator.GetAttributes(node).Any(attr => generator.GetName(attr) == "CompilerGenerated")) { return(base.VisitPropertyDeclaration(node)); } (var canRead, var canWrite) = generator.InspectProperty(node); canRead = canRead || node.ExpressionBody != null; if (node.ExpressionBody != null) { node = node.RemoveNode(node.ExpressionBody, SyntaxRemoveOptions.KeepNoTrivia); } node = node.WithAccessorList(null); if (canRead && !canWrite) { node = node .WithExpressionBody(ArrowExpressionClause(ExecutePipeline(node.Type, Enumerable.Empty <ParameterSyntax>()))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); } else { if (canRead) { node = node.AddAccessorListAccessors(AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithExpressionBody(ArrowExpressionClause(ExecutePipeline(node.Type, Enumerable.Empty <ParameterSyntax>()))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); } if (canWrite) { node = node.AddAccessorListAccessors(AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithExpressionBody(ArrowExpressionClause( // NOTE: we always append the implicit "value" parameter for setters. ExecutePipeline(null, new[] { Parameter(Identifier("value")).WithType(node.Type) }))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); } } return(base.VisitPropertyDeclaration(node)); }
private CSharpSyntaxNode ToGetSet(PropertyDeclaration node) { List <Node> modifiers = node.Modifiers.FindAll(n => n.Kind != NodeKind.ReadonlyKeyword); PropertyDeclarationSyntax csProperty = SyntaxFactory .PropertyDeclaration(node.Type.ToCsNode <TypeSyntax>(), node.Name.Text) .AddModifiers(modifiers.ToCsNodes <SyntaxToken>()); if (node.JsDoc.Count > 0) { csProperty = csProperty.WithLeadingTrivia(SyntaxFactory.Trivia(node.JsDoc[0].ToCsNode <DocumentationCommentTriviaSyntax>())); } //GetAccess AccessorDeclarationSyntax csGetAccess = SyntaxFactory .AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); // if (node.Initializer != null) // { // csGetAccess = csGetAccess.WithBody(SyntaxFactory.Block(SyntaxFactory.ReturnStatement(node.Initializer.ToCsNode<ExpressionSyntax>()))); // } csProperty = csProperty.AddAccessorListAccessors(csGetAccess); //SetsAccess if ((node.IsReadonly && !node.IsAbstract) || (!node.IsReadonly)) { AccessorDeclarationSyntax csSetAccess = SyntaxFactory .AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); if (node.IsReadonly) { csSetAccess = csSetAccess.AddModifiers(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)); } csProperty = csProperty.AddAccessorListAccessors(csSetAccess); } return(csProperty); }
public CSharpSyntaxNode Convert(PropertySignature node) { PropertyDeclarationSyntax csProperty = SyntaxFactory.PropertyDeclaration(node.Type.ToCsNode <TypeSyntax>(), node.Name.Text); if (node.Parent != null && node.Parent.Kind == NodeKind.InterfaceDeclaration) { csProperty = csProperty.AddAccessorListAccessors(SyntaxFactory .AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))); if (!node.HasModify(NodeKind.ReadonlyKeyword)) { csProperty = csProperty.AddAccessorListAccessors(SyntaxFactory .AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))); } } if (node.JsDoc.Count > 0) { csProperty = csProperty.WithLeadingTrivia(SyntaxFactory.Trivia(node.JsDoc[0].ToCsNode <DocumentationCommentTriviaSyntax>())); } return(csProperty); }
public CSharpSyntaxNode Convert(SetAccessor node) { PropertyDeclarationSyntax csProperty = SyntaxFactory .PropertyDeclaration(node.Parameters[0].Type.ToCsNode <TypeSyntax>(), node.Name.Text) .AddModifiers(node.Modifiers.ToCsNodes <SyntaxToken>()); if (node.JsDoc.Count > 0) { csProperty = csProperty.WithLeadingTrivia(SyntaxFactory.Trivia(node.JsDoc[0].ToCsNode <DocumentationCommentTriviaSyntax>())); } AccessorDeclarationSyntax csSetAccess = SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration); if (node.Body != null) { csSetAccess = csSetAccess.WithBody(node.Body.ToCsNode <BlockSyntax>()); } return(csProperty.AddAccessorListAccessors(csSetAccess)); }
private async Task <Document> ToBindablePropertyAsync(Document document, SyntaxNode equalsSyntax, CancellationToken cancellationToken) { var pds = equalsSyntax as PropertyDeclarationSyntax; var propName = pds.Identifier.ToString(); var propType = pds.GetTypeName(); var className = ((ClassDeclarationSyntax)pds.Parent).Identifier.Text; var bindPropName = $"{propName}Property"; var callbackName = $"On{propName}Changed"; var validationName = $"IsValid{propName}Value"; PropertyDeclarationSyntax backingProperty = SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(propType), propName) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); var getCall = SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("GetValue")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(bindPropName))); var getCast = SyntaxFactory.CastExpression( SyntaxFactory.ParseTypeName(propType), SyntaxFactory.ParenthesizedExpression(getCall)); var returnStatement = SyntaxFactory.ReturnStatement(getCast); backingProperty = backingProperty.AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration( SyntaxKind.GetAccessorDeclaration, SyntaxFactory.Block(SyntaxFactory.List(new[] { returnStatement })))); var setCall = SyntaxFactory.ExpressionStatement( SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("SetValue")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(bindPropName)), SyntaxFactory.Argument(SyntaxFactory.IdentifierName("value")))); backingProperty = backingProperty.AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration( SyntaxKind.SetAccessorDeclaration, SyntaxFactory.Block(SyntaxFactory.List(new[] { setCall })))); var bindProperty = SyntaxFactory.FieldDeclaration( SyntaxFactory.VariableDeclaration( SyntaxFactory.ParseTypeName("BindableProperty"), SyntaxFactory.SeparatedList( new[] { SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(bindPropName)) .WithInitializer(SyntaxFactory.EqualsValueClause( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("BindableProperty"), SyntaxFactory.IdentifierName("Create")), SyntaxFactory.ArgumentList( default(SeparatedSyntaxList <ArgumentSyntax>) .Add( SyntaxFactory.Argument( SyntaxFactory.InvocationExpression( SyntaxFactory.IdentifierName("nameof")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(propName))))) .Add( SyntaxFactory.Argument( SyntaxFactory.InvocationExpression( SyntaxFactory.IdentifierName("typeof")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(propType))))) .Add( SyntaxFactory.Argument( SyntaxFactory.InvocationExpression( SyntaxFactory.IdentifierName("typeof")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(className))))) .Add( SyntaxFactory.Argument( SyntaxFactory.DefaultExpression(SyntaxFactory.ParseTypeName(propType))) .WithNameColon(SyntaxFactory.NameColon(SyntaxFactory.IdentifierName("defaultValue")))) .Add( SyntaxFactory.Argument( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("BindingMode"), SyntaxFactory.IdentifierName("Default"))) .WithNameColon(SyntaxFactory.NameColon(SyntaxFactory.IdentifierName("defaultBindingMode")))) .Add( SyntaxFactory.Argument( SyntaxFactory.IdentifierName(validationName)) .WithNameColon(SyntaxFactory.NameColon(SyntaxFactory.IdentifierName("validateValue")))) .Add( SyntaxFactory.Argument( SyntaxFactory.IdentifierName(callbackName)) .WithNameColon(SyntaxFactory.NameColon(SyntaxFactory.IdentifierName("propertyChanged")))))))), }))) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword), SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)); var callbackMethod = SyntaxFactory.MethodDeclaration( SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)), SyntaxFactory.Identifier(callbackName)) .AddParameterListParameters( SyntaxFactory.Parameter( SyntaxFactory.Identifier("bindable")) .WithType(SyntaxFactory.IdentifierName("BindableObject")), SyntaxFactory.Parameter( SyntaxFactory.Identifier("oldValue")) .WithType(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword))), SyntaxFactory.Parameter( SyntaxFactory.Identifier("newValue")) .WithType(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)))) .WithBody( SyntaxFactory.Block().WithCloseBraceToken( SyntaxFactory.Token( SyntaxFactory.TriviaList( SyntaxFactory.Comment($"// TODO: Property changed implementation goes here{System.Environment.NewLine}")), SyntaxKind.CloseBraceToken, SyntaxFactory.TriviaList()))) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PrivateKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)); var validationMethod = SyntaxFactory.MethodDeclaration( SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.BoolKeyword)), SyntaxFactory.Identifier(validationName)) .AddParameterListParameters( SyntaxFactory.Parameter( SyntaxFactory.Identifier("view")) .WithType(SyntaxFactory.IdentifierName("BindableObject")), SyntaxFactory.Parameter( SyntaxFactory.Identifier("value")) .WithType(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)))) .AddBodyStatements( SyntaxFactory.ReturnStatement(SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression)) .WithLeadingTrivia(SyntaxFactory.Comment($"// Add logic for validating value as necessary{System.Environment.NewLine}"))) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PrivateKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)); var newNodes = new List <SyntaxNode> { backingProperty, bindProperty, callbackMethod, validationMethod, }; var oldRoot = await document.GetSyntaxRootAsync(cancellationToken); var newRoot = oldRoot.ReplaceNode(pds, newNodes); return(document.WithSyntaxRoot(newRoot)); }
private async Task <Document> ToDependencyPropertyAsync(Document document, SyntaxNode equalsSyntax, CancellationToken cancellationToken) { var pds = equalsSyntax as PropertyDeclarationSyntax; var propName = pds.Identifier.ToString(); var propType = pds.GetTypeName(); var className = ((ClassDeclarationSyntax)pds.Parent).Identifier.Text; var depPropName = $"{propName}Property"; var callbackName = $"On{propName}Changed"; PropertyDeclarationSyntax backingProperty = SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(propType), propName) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); var getCall = SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("GetValue")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(depPropName))); var getCast = SyntaxFactory.CastExpression( SyntaxFactory.ParseTypeName(propType), SyntaxFactory.ParenthesizedExpression(getCall)); var returnStatement = SyntaxFactory.ReturnStatement(getCast); backingProperty = backingProperty.AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration( SyntaxKind.GetAccessorDeclaration, SyntaxFactory.Block(SyntaxFactory.List(new[] { returnStatement })))); var setCall = SyntaxFactory.ExpressionStatement( SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("SetValue")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(depPropName)), SyntaxFactory.Argument(SyntaxFactory.IdentifierName("value")))); backingProperty = backingProperty.AddAccessorListAccessors( SyntaxFactory.AccessorDeclaration( SyntaxKind.SetAccessorDeclaration, SyntaxFactory.Block(SyntaxFactory.List(new[] { setCall })))); var depProperty = SyntaxFactory.FieldDeclaration( SyntaxFactory.VariableDeclaration( SyntaxFactory.ParseTypeName("DependencyProperty"), SyntaxFactory.SeparatedList( new[] { SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(depPropName)) .WithInitializer(SyntaxFactory.EqualsValueClause( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("DependencyProperty"), SyntaxFactory.IdentifierName("Register")), SyntaxFactory.ArgumentList( default(SeparatedSyntaxList <ArgumentSyntax>) .Add( SyntaxFactory.Argument( SyntaxFactory.LiteralExpression( SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(propName)))) .Add( SyntaxFactory.Argument( SyntaxFactory.InvocationExpression( SyntaxFactory.IdentifierName("typeof")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(propType))))) .Add( SyntaxFactory.Argument( SyntaxFactory.InvocationExpression( SyntaxFactory.IdentifierName("typeof")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(className))))) .Add( SyntaxFactory.Argument( SyntaxFactory.ObjectCreationExpression( SyntaxFactory.IdentifierName("PropertyMetadata")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.DefaultExpression(SyntaxFactory.ParseTypeName(propType))), SyntaxFactory.Argument( SyntaxFactory.ObjectCreationExpression( SyntaxFactory.IdentifierName("PropertyChangedCallback")) .AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.IdentifierName(callbackName))))))))))), }))) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword), SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)); var callbackMethod = SyntaxFactory.MethodDeclaration( SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)), SyntaxFactory.Identifier(callbackName)) .AddParameterListParameters( SyntaxFactory.Parameter( SyntaxFactory.Identifier("d")) .WithType(SyntaxFactory.IdentifierName("DependencyObject")), SyntaxFactory.Parameter( SyntaxFactory.Identifier("e")) .WithType(SyntaxFactory.IdentifierName("DependencyPropertyChangedEventArgs"))) .AddBodyStatements( SyntaxFactory.ThrowStatement( SyntaxFactory.ObjectCreationExpression( SyntaxFactory.IdentifierName("NotImplementedException")) .AddArgumentListArguments())) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PrivateKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)); var newNodes = new List <SyntaxNode> { backingProperty, depProperty, callbackMethod, }; var oldRoot = await document.GetSyntaxRootAsync(cancellationToken); var newRoot = oldRoot.ReplaceNode(pds, newNodes); return(document.WithSyntaxRoot(newRoot)); }