private static void AddCheckIfDifferent(DocumentEditor editor, AssignmentExpressionSyntax assignment, CancellationToken cancellationToken) { var statementSyntax = assignment.FirstAncestorOrSelf <ExpressionStatementSyntax>(); if (statementSyntax == null) { return; } var type = editor.SemanticModel.GetTypeInfoSafe(assignment.Left, cancellationToken).Type; var code = StringBuilderPool.Borrow() .AppendLine($"if ({Snippet.EqualityCheck(type, "value", assignment.Left.ToString(), editor.SemanticModel)})") .AppendLine("{") .AppendLine(" return;") .AppendLine("}") .AppendLine() .Return(); var ifReturn = SyntaxFactory.ParseStatement(code) .WithSimplifiedNames() .WithLeadingElasticLineFeed() .WithTrailingElasticLineFeed() .WithAdditionalAnnotations(Formatter.Annotation); editor.InsertBefore(statementSyntax, ifReturn); }
private static void MakeAutoPropertyNotifyWhenValueChanges(DocumentEditor editor, PropertyDeclarationSyntax propertyDeclaration, IMethodSymbol invoker, SemanticModel semanticModel, CancellationToken cancellationToken) { 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 property = semanticModel.GetDeclaredSymbolSafe(propertyDeclaration, cancellationToken); 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() .AppendLine(" set") .AppendLine(" {") .AppendLine($" if ({Snippet.EqualityCheck(property.Type, "value", fieldAccess, semanticModel)})") .AppendLine(" {") .AppendLine($" return;") .AppendLine(" }") .AppendLine() .AppendLine($" {fieldAccess} = value;") .AppendLine($" {Snippet.OnPropertyChanged(invoker, property.Name, underscoreFields)}") .AppendLine(" }") .AppendLine("}") .Return(); var template = ParseProperty(code); editor.ReplaceNode( getter, x => x.WithExpressionBody(template.Getter().ExpressionBody) .WithTrailingElasticLineFeed() .WithAdditionalAnnotations(Formatter.Annotation)); editor.ReplaceNode( setter, x => x.WithBody(template.Setter().Body) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) .WithAdditionalAnnotations(Formatter.Annotation)); if (propertyDeclaration.Initializer != null) { editor.ReplaceNode( propertyDeclaration, x => x.WithoutInitializer()); } editor.ReplaceNode(propertyDeclaration, x => x.WithAdditionalAnnotations(Formatter.Annotation)); } }
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)); } }
private static void CreateIf(DocumentEditor editor, ExpressionStatementSyntax setAndRaise, ExpressionStatementSyntax invocation) { editor.RemoveNode(setAndRaise); editor.ReplaceNode( invocation, (node, _) => { var code = StringBuilderPool.Borrow() .AppendLine($"if ({setAndRaise.ToFullString().TrimEnd('\r', '\n', ';')})") .AppendLine("{") .AppendLine($" {invocation.ToFullString().TrimEnd('\r', '\n')}") .AppendLine("}") .Return(); return(SyntaxFactory.ParseStatement(code) .WithSimplifiedNames() .WithLeadingElasticLineFeed() .WithTrailingElasticLineFeed() .WithAdditionalAnnotations(Formatter.Annotation)); }); }
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); } } }