public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node) { var containingTypeSyntax = node.FirstAncestorOrSelf <TypeDeclarationSyntax>(); if (node.ExpressionBody != null) { var propertySymbol = this.SemanticModel.GetDeclaredSymbol(node); var methodSymbol = propertySymbol.GetMethod; this.ProcessArrowExpressionDecl(node.ExpressionBody, containingTypeSyntax, methodSymbol); } else if (node.AccessorList != null) { foreach (var accessor in node.AccessorList.Accessors) { var methodSymbol = this.SemanticModel.GetDeclaredSymbol(accessor); this.ProcessPropertyAccessorDecl(accessor, containingTypeSyntax, methodSymbol); } } else { throw new NotImplementedException("Unknown PropertyDeclaration syntax."); } base.VisitPropertyDeclaration(node); }
public override async Task RegisterCodeFixesAsync(CodeFixContext context) { foreach (var diagnostic in context.Diagnostics) { if (!string.Equals(diagnostic.Id, ImplementBuilderPatternAnalyzer.DiagnosticId, StringComparison.Ordinal)) { continue; } var documentRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); SyntaxNode syntax = documentRoot.FindNode(diagnostic.Location.SourceSpan); if (syntax == null) { continue; } PropertyDeclarationSyntax propertyDeclaration = syntax.FirstAncestorOrSelf <PropertyDeclarationSyntax>(); if (propertyDeclaration == null) { continue; } ClassDeclarationSyntax classDeclarationSyntax = propertyDeclaration.FirstAncestorOrSelf <ClassDeclarationSyntax>(); if (classDeclarationSyntax == null) { continue; } string description = string.Format("Implement builder method 'With{0}'", propertyDeclaration.Identifier.ValueText); context.RegisterCodeFix(CodeAction.Create(description, cancellationToken => CreateChangedSolution(context, classDeclarationSyntax, propertyDeclaration, cancellationToken)), diagnostic); } }
public static int GetMaxOrderNumber(this PropertyDeclarationSyntax property) { var orderNumber = 0; var type = property.FirstAncestorOrSelf <TypeDeclarationSyntax>(); var properties = type.Members.OfType <PropertyDeclarationSyntax>(); foreach (var item in properties) { foreach (var attribute in item.AttributeLists.SelectMany(p => p.Attributes)) { if (_dataMemberNames.Contains(attribute.Name.GetIdentifierName()) && attribute.ArgumentList != null) { foreach (var argument in attribute.ArgumentList.Arguments) { if (argument.NameEquals.Name.Identifier.Text == Constants.OrderPropertyName) { var currentNumber = (int)((LiteralExpressionSyntax)argument.Expression).Token.Value; if (currentNumber > orderNumber) { orderNumber = currentNumber; } } } } } } return(orderNumber); }
internal static bool TryGetBackingField(PropertyDeclarationSyntax property, out IdentifierNameSyntax field, out FieldDeclarationSyntax fieldDeclaration) { field = null; fieldDeclaration = null; if (property == null) { return(false); } AccessorDeclarationSyntax setter; if (property.TryGetSetAccessorDeclaration(out setter) && setter.Body != null) { using (var pooled = AssignmentWalker.Create(setter)) { if (pooled.Item.Assignments.Count != 1) { return(false); } var left = pooled.Item.Assignments[0].Left; field = left as IdentifierNameSyntax; if (field == null) { var memberAccess = left as MemberAccessExpressionSyntax; if (!(memberAccess?.Expression is ThisExpressionSyntax)) { return(false); } field = memberAccess.Name as IdentifierNameSyntax; } if (field == null) { return(false); } foreach (var member in property.FirstAncestorOrSelf <TypeDeclarationSyntax>().Members) { fieldDeclaration = member as FieldDeclarationSyntax; if (fieldDeclaration != null) { foreach (var variable in fieldDeclaration.Declaration.Variables) { if (variable.Identifier.ValueText == field.Identifier.ValueText) { return(true); } } } } } } return(false); }
public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node) { if (!node.FirstAncestorOrSelf <ClassDeclarationSyntax>().Identifier.Text.Contains("Mapper")) { // check if node is automatically generated (not wrapped inside custom comments) if (!this._finder.IsNodeWithinCustomCode(node)) { this.GeneratedProperties.Add(node.Identifier.Text); } } }
private static void MakeAutoPropertySet(DocumentEditor editor, PropertyDeclarationSyntax propertyDeclaration, IMethodSymbol setAndRaise, SemanticModel semanticModel, CancellationToken cancellationToken) { var classDeclaration = propertyDeclaration.FirstAncestorOrSelf <ClassDeclarationSyntax>(); if (classDeclaration == null) { return; } if (Property.IsMutableAutoProperty(propertyDeclaration, out var getter, out var setter)) { if (getter.Body != null || getter.ContainsSkippedText || setter.Body != null || setter.ContainsSkippedText) { return; } var underscoreFields = CodeStyle.UnderscoreFields(semanticModel); var backingField = editor.AddBackingField(propertyDeclaration, underscoreFields, cancellationToken); var fieldAccess = underscoreFields ? backingField.Name() : $"this.{backingField.Name()}"; var code = StringBuilderPool.Borrow() .AppendLine($"public Type PropertyName") .AppendLine("{") .AppendLine($" get => {fieldAccess};") .AppendLine($" set => {(underscoreFields ? string.Empty : "this.")}{setAndRaise.Name}(ref {fieldAccess}, value);") .AppendLine("}") .Return(); var template = ParseProperty(code); editor.ReplaceNode( getter, x => x.WithExpressionBody(template.Getter().ExpressionBody) .WithLeadingLineFeed()); editor.ReplaceNode( setter, x => x.WithExpressionBody(template.Setter().ExpressionBody) .WithLeadingLineFeed() .WithTrailingLineFeed()); if (propertyDeclaration.Initializer != null) { editor.ReplaceNode( propertyDeclaration, (node, g) => ((PropertyDeclarationSyntax)node).WithoutInitializer()); } editor.ReplaceNode(propertyDeclaration, x => x.WithAdditionalAnnotations(Formatter.Annotation)); } }
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) { if (!node.FirstAncestorOrSelf <ClassDeclarationSyntax>().Identifier.Text.Contains("Mapper")) { // check if node is automatically generated (not wrapped inside custom comments) if (!this._finder.IsNodeWithinCustomCode(node)) { return(null); } } return(base.VisitPropertyDeclaration(node)); }
private static bool IsValidConstructorArgumentName(AttributeData attribute, PropertyDeclarationSyntax propertyDeclaration) { var allConstructorArguments = propertyDeclaration .FirstAncestorOrSelf <ClassDeclarationSyntax>() .Members .OfType <ConstructorDeclarationSyntax>() .SelectMany(x => x.ParameterList.Parameters) .Select(x => x.Identifier.ValueText) .ToHashSet(); return(allConstructorArguments.Contains(attribute.ConstructorArguments[0].Value)); }
internal static string BackingFieldNameForAutoProperty(PropertyDeclarationSyntax property) { var typeDeclaration = property.FirstAncestorOrSelf <TypeDeclarationSyntax>(); var usesUnderscoreNames = typeDeclaration.UsesUnderscoreNames(); var fieldName = usesUnderscoreNames ? $"_{property.Identifier.ValueText.ToFirstCharLower()}" : property.Identifier.ValueText.ToFirstCharLower(); while (typeDeclaration.HasMember(fieldName)) { fieldName += "_"; } return(fieldName); }
internal static CompilationUnitSyntax ImplementFullProperty(CompilationUnitSyntax root, SemanticModel model, PropertyDeclarationSyntax propertyDecl, Workspace workspace) { TypeDeclarationSyntax typeDecl = propertyDecl.FirstAncestorOrSelf <TypeDeclarationSyntax>(); string propertyName = propertyDecl.Identifier.ValueText; string backingFieldName = $"_{char.ToLower(propertyName[0])}{propertyName.Substring(1)}"; ITypeSymbol propertyTypeSymbol = model.GetDeclaredSymbol(propertyDecl).Type; root = root.ReplaceNodes(new SyntaxNode[] { propertyDecl, typeDecl }, (original, updated) => original.IsKind(SyntaxKind.PropertyDeclaration) ? ExpandProperty((PropertyDeclarationSyntax)original, (PropertyDeclarationSyntax)updated, backingFieldName) as SyntaxNode : ExpandType((TypeDeclarationSyntax)original, (TypeDeclarationSyntax)updated, propertyTypeSymbol, backingFieldName, model, workspace) as SyntaxNode ); return(root); }
private static void MakeWithBackingFieldSet(DocumentEditor editor, PropertyDeclarationSyntax propertyDeclaration, IMethodSymbol setAndRaise, SemanticModel semanticModel) { var classDeclaration = propertyDeclaration.FirstAncestorOrSelf <ClassDeclarationSyntax>(); if (classDeclaration == null) { return; } if (IsSimpleAssignmentOnly(propertyDeclaration, out _, out _, out var assignment, out var fieldAccess)) { var underscoreFields = CodeStyle.UnderscoreFields(semanticModel); var setExpression = SyntaxFactory.ParseExpression($"{(underscoreFields ? string.Empty : "this.")}{setAndRaise.Name}(ref {fieldAccess}, value);") .WithTrailingTrivia(SyntaxFactory.ElasticMarker) .WithSimplifiedNames() .WithAdditionalAnnotations(Formatter.Annotation); editor.ReplaceNode(assignment, setExpression); } }
private static (SyntaxNode newRoot, PropertyDeclarationSyntax newNode) ConvertToFullProperty(SyntaxNode root, PropertyDeclarationSyntax node) { string nodeType = (node.Type as TypeSyntax).GetText().ToString(); string fieldName = node.Identifier.Text; fieldName = fieldName.First().ToString().ToLower() + new String(fieldName.Skip(1).ToArray()); if (fieldName == node.Identifier.Text) { fieldName = "_" + fieldName; } var getArrow = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.IdentifierName(fieldName)); var newGetter = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration); newGetter = newGetter.WithExpressionBody(getArrow); newGetter = newGetter.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); var assignment = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SyntaxFactory.IdentifierName(fieldName), SyntaxFactory.IdentifierName("value")); var newSetter = SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration, SyntaxFactory.Block(SyntaxFactory.ExpressionStatement(assignment))); var annotation = new SyntaxAnnotation("prop_with_new_setter", ""); var accessorList = SyntaxFactory.AccessorList(); var newaccessorList = accessorList.AddAccessors(newGetter, newSetter); var newNode = node.WithAccessorList(newaccessorList) .WithAdditionalAnnotations(annotation); var cls = node.FirstAncestorOrSelf <ClassDeclarationSyntax>(); var newCls = cls.ReplaceNode(node, newNode); newCls = newCls.AddField(nodeType, fieldName); var newRoot = root.ReplaceNode(cls, newCls); newNode = newRoot.GetAnnotatedNodes(annotation).First() as PropertyDeclarationSyntax; return(newRoot, newNode); }
private static Task <Document> ApplyConvertAutoPropertyFixAsync( CodeFixContext context, SyntaxNode syntaxRoot, PropertyDeclarationSyntax propertyDeclaration, IPropertySymbol property, ExpressionStatementSyntax assignStatement, string fieldName, IMethodSymbol invoker) { var syntaxGenerator = SyntaxGenerator.GetGenerator(context.Document); var typeDeclaration = propertyDeclaration.FirstAncestorOrSelf <TypeDeclarationSyntax>(); var newPropertyDeclaration = propertyDeclaration.WithGetterReturningBackingField(syntaxGenerator, fieldName) .WithNotifyingSetter(syntaxGenerator, property, assignStatement, fieldName, invoker); var newTypeDeclaration = typeDeclaration.ReplaceNode(propertyDeclaration, newPropertyDeclaration); return(Task.FromResult(context.Document.WithSyntaxRoot(syntaxRoot.ReplaceNode(typeDeclaration, newTypeDeclaration)))); }
private static void MakeWithBackingFieldNotify(DocumentEditor editor, PropertyDeclarationSyntax propertyDeclaration, IMethodSymbol invoker, SemanticModel semanticModel, CancellationToken cancellationToken) { var classDeclaration = propertyDeclaration.FirstAncestorOrSelf <ClassDeclarationSyntax>(); if (classDeclaration == null) { return; } if (IsSimpleAssignmentOnly(propertyDeclaration, out var setter, out var statement, out var assignment, out _)) { var underscoreFields = CodeStyle.UnderscoreFields(semanticModel); var property = semanticModel.GetDeclaredSymbolSafe(propertyDeclaration, cancellationToken); var notifyStatement = SyntaxFactory .ParseStatement(Snippet.OnPropertyChanged(invoker, property.Name, underscoreFields)) .WithLeadingTrivia(SyntaxFactory.ElasticMarker) .WithTrailingTrivia(SyntaxFactory.ElasticMarker) .WithSimplifiedNames() .WithAdditionalAnnotations(Formatter.Annotation); if (setter.ExpressionBody != null) { editor.ReplaceNode( setter, (x, _) => { var old = (AccessorDeclarationSyntax)x; return(old.WithBody( SyntaxFactory.Block( SyntaxFactory.ExpressionStatement(assignment), notifyStatement)) .WithExpressionBody(null) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))); }); editor.FormatNode(propertyDeclaration); } else if (setter.Body != null) { editor.InsertAfter(statement, notifyStatement); editor.FormatNode(propertyDeclaration); } } }
private static void MakeWithBackingFieldNotifyWhenValueChanges(DocumentEditor editor, PropertyDeclarationSyntax propertyDeclaration, IMethodSymbol invoker, SemanticModel semanticModel, CancellationToken cancellationToken) { var classDeclaration = propertyDeclaration.FirstAncestorOrSelf <ClassDeclarationSyntax>(); if (classDeclaration == null) { return; } if (propertyDeclaration.TryGetSetter(out var setter)) { if (setter.ExpressionBody != null && IsSimpleAssignmentOnly(propertyDeclaration, out _, out _, out var assignment, out _)) { var property = semanticModel.GetDeclaredSymbolSafe(propertyDeclaration, cancellationToken); var underscoreFields = CodeStyle.UnderscoreFields(semanticModel); var code = StringBuilderPool.Borrow() .AppendLine($"public Type PropertyName") .AppendLine("{") .AppendLine($" get => {assignment.Left};") .AppendLine() .AppendLine(" set") .AppendLine(" {") .AppendLine($" if ({Snippet.EqualityCheck(property.Type, "value", assignment.Left.ToString(), semanticModel)})") .AppendLine(" {") .AppendLine($" return;") .AppendLine(" }") .AppendLine() .AppendLine($" {assignment};") .AppendLine($" {Snippet.OnPropertyChanged(invoker, property.Name, underscoreFields)}") .AppendLine(" }") .AppendLine("}") .Return(); var template = ParseProperty(code); editor.ReplaceNode( setter, (x, _) => { var old = (AccessorDeclarationSyntax)x; return(old.WithBody(template.Setter().Body) .WithExpressionBody(null) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))); }); editor.FormatNode(propertyDeclaration); } if (setter.Body?.Statements.Count == 1 && IsSimpleAssignmentOnly(propertyDeclaration, out _, out var statement, out assignment, out _)) { var property = semanticModel.GetDeclaredSymbolSafe(propertyDeclaration, cancellationToken); var code = StringBuilderPool.Borrow() .AppendLine($" if ({Snippet.EqualityCheck(property.Type, "value", assignment.Left.ToString(), semanticModel)})") .AppendLine(" {") .AppendLine($" return;") .AppendLine(" }") .AppendLine() .Return(); var ifStatement = SyntaxFactory.ParseStatement(code) .WithSimplifiedNames() .WithLeadingElasticLineFeed() .WithTrailingElasticLineFeed() .WithAdditionalAnnotations(Formatter.Annotation); editor.InsertBefore( statement, ifStatement); var underscoreFields = CodeStyle.UnderscoreFields(semanticModel); var notifyStatement = SyntaxFactory .ParseStatement( Snippet.OnPropertyChanged(invoker, property.Name, underscoreFields)) .WithSimplifiedNames() .WithLeadingElasticLineFeed() .WithTrailingElasticLineFeed() .WithAdditionalAnnotations(Formatter.Annotation); editor.InsertAfter(statement, notifyStatement); editor.FormatNode(propertyDeclaration); } } }
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)); }
protected override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) { Boolean isDependencyProperty = node .Attributes .SelectMany(a => a.ChildNodes().OfType<AttributeSyntax>()) .Any(a => a.Name.PlainName == "Dependency"); if (!isDependencyProperty) { return base.VisitPropertyDeclaration(node); } AccessorDeclarationSyntax changeCallback = node .AccessorList .Accessors .FirstOrDefault(a => a.Kind == SyntaxKind.UnknownAccessorDeclaration && a.Keyword.ValueText == "change"); Boolean hasChangeCallback = changeCallback != null; TypeSyntax dpType = Syntax.ParseTypeName("System.Windows.DependencyProperty"); // add a DP field: // DependencyProperty XxxProperty = DependencyProperty.Register("Xxx", typeof(PropType), typeof(OwnerType), // new FrameworkPropertyMetadata(OnXxxChanged); TypeSyntax ownerType = Syntax.ParseTypeName(node .FirstAncestorOrSelf<ClassDeclarationSyntax>() .Identifier .ValueText); String propertyName = node.Identifier.ValueText; ExpressionSyntax propertyNameExpression = Syntax.LiteralExpression(SyntaxKind.StringLiteralExpression, Syntax.Literal(text: '"' + propertyName + '"', value: propertyName)); ExpressionSyntax typeofPropertyType = Syntax.TypeOfExpression(argumentList: Syntax.ArgumentList(arguments: Syntax.SeparatedList(Syntax.Argument(expression: node.Type)))); ExpressionSyntax typeofOwnerType = Syntax.TypeOfExpression(argumentList: Syntax.ArgumentList(arguments: Syntax.SeparatedList(Syntax.Argument(expression: ownerType)))); var registerArgs = new List<ArgumentSyntax> { Syntax.Argument(expression: propertyNameExpression), Syntax.Argument(expression: typeofPropertyType), Syntax.Argument(expression: typeofOwnerType) }; if (hasChangeCallback) { ExpressionSyntax changeMethod = Syntax.ParseName("On" + propertyName + "Changed"); ExpressionSyntax frameworkPropertyMetadata = Syntax.ObjectCreationExpression( type: Syntax.ParseTypeName("System.Windows.FrameworkPropertyMetadata"), argumentListOpt: Syntax.ArgumentList(arguments: Syntax.SeparatedList(Syntax.Argument(expression: changeMethod)))); registerArgs.Add(Syntax.Argument(expression: frameworkPropertyMetadata) ); } IEnumerable<SyntaxToken> argSeparators = Enumerable.Repeat( Syntax.Token(SyntaxKind.CommaToken), registerArgs.Count - 1) .ToList(); ExpressionSyntax dpexpr = Syntax.InvocationExpression( expression: Syntax.ParseName("System.Windows.DependencyProperty.Register"), argumentList: Syntax.ArgumentList(arguments: Syntax.SeparatedList(registerArgs, argSeparators))); String fieldName = propertyName + "Property"; VariableDeclaratorSyntax declarator = Syntax.VariableDeclarator( identifier: Syntax.Identifier(fieldName), initializerOpt: Syntax.EqualsValueClause(value: dpexpr)); FieldDeclarationSyntax newField = Syntax.FieldDeclaration( modifiers: Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword), Syntax.Token(SyntaxKind.StaticKeyword)), declaration: Syntax.VariableDeclaration( type: dpType, variables: Syntax.SeparatedList(declarator))); _fields.Add(newField); // add a DP CLR wrapper: // public PropType Xxx // { // get { return (PropType)GetValue(XxxProperty); } // set { SetValue(XxxPropety, value); } // } ExpressionSyntax getval = Syntax.ParseExpression("GetValue(" + fieldName + ")"); ExpressionSyntax cast = Syntax.CastExpression(type: node.Type, expression: getval); StatementSyntax getter = Syntax.ReturnStatement(expressionOpt: cast); StatementSyntax setter = Syntax.ParseStatement("SetValue(" + fieldName + ");"); PropertyDeclarationSyntax newProperty = Syntax.PropertyDeclaration( modifiers: Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword)), type: node.Type, identifier: node.Identifier, accessorList: Syntax.AccessorList( accessors: Syntax.List( Syntax.AccessorDeclaration( kind: SyntaxKind.GetAccessorDeclaration, bodyOpt: Syntax.Block( statements: Syntax.List( getter ) ) ), Syntax.AccessorDeclaration( kind: SyntaxKind.SetAccessorDeclaration, bodyOpt: Syntax.Block( statements: Syntax.List( setter ) ) ) ) )); // add change callback if required // private static void OnXxxChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) // { // /* body */ // } if (hasChangeCallback) { List<ParameterSyntax> parameterList = new List<ParameterSyntax> { Syntax.Parameter(identifier: Syntax.Identifier("d"), typeOpt: Syntax.ParseTypeName("System.Windows.DependencyObject")), Syntax.Parameter(identifier: Syntax.Identifier("e"), typeOpt: Syntax.ParseTypeName("System.Windows.DependencyPropertyChangedEventArgs")), }; var paramSeparators = Enumerable.Repeat(Syntax.Token(SyntaxKind.CommaToken), parameterList.Count - 1).ToList(); ParameterListSyntax parameters = Syntax.ParameterList( parameters: Syntax.SeparatedList(parameterList, paramSeparators) ); MethodDeclarationSyntax changeMethod = Syntax.MethodDeclaration( modifiers: Syntax.TokenList(Syntax.Token(SyntaxKind.PrivateKeyword), Syntax.Token(SyntaxKind.StaticKeyword)), identifier: Syntax.Identifier("On" + propertyName + "Changed"), returnType: Syntax.PredefinedType(Syntax.Token(SyntaxKind.VoidKeyword)), parameterList: parameters, bodyOpt: changeCallback.BodyOpt ); _methods.Add(changeMethod); } return newProperty; }