public static void AddUsing(DocumentEditor editor, string namespaceName, int position) { var compUnit = editor.OriginalRoot as Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax; if (compUnit == null) { return; } if (compUnit.Usings.Any(u => u.Name.GetText().ToString() == namespaceName)) { return; } if (position >= 0) { var enclosingSymbol = editor.SemanticModel.GetEnclosingSymbol(position); if (enclosingSymbol != null) { var nsEnclName = enclosingSymbol.ContainingNamespace.ToString(); if (nsEnclName.StartsWith(namespaceName + ".") || nsEnclName == namespaceName) { return; } } } var usingDirective = editor.Generator.NamespaceImportDeclaration(namespaceName); editor.InsertAfter(compUnit.Usings.Last(), usingDirective); }
private void ReplaceImportStatements() { HashSet <string> alreadyAddedImportsStatements = new HashSet <string>(); IEnumerable <ImportsStatementSyntax> importsStatementNodes = tree.GetRoot().DescendantNodes().OfType <ImportsStatementSyntax>(); foreach (ImportsStatementSyntax oldImportsStatementNode in importsStatementNodes) // iterate over all qualified names in the file { // could be problems if this import statement isn't simple, however even if an alias is used in the import it's still simple SimpleImportsClauseSyntax oldSimpleImportsNode = oldImportsStatementNode.DescendantNodes().OfType <SimpleImportsClauseSyntax>().First(); var oldNamespace = oldSimpleImportsNode.WithoutTrivia().Name.GetText().ToString(); List <namespace_map> namespaces = NSMappingSQLConnector.GetInstance().GetNamespaceMapsFromOldNamespace(TransformProject.sdkId, oldNamespace); if (namespaces != null) { foreach (namespace_map nsMap in namespaces) { var newNamespace = nsMap.new_namespace; if (!alreadyAddedImportsStatements.Contains(newNamespace)) { alreadyAddedImportsStatements.Add(newNamespace); NameSyntax newIdentifierNode = IdentifierName(newNamespace); var newSimpleImportsNode = oldSimpleImportsNode.WithName(newIdentifierNode); SeparatedSyntaxList <ImportsClauseSyntax> simpleImportsList = new SeparatedSyntaxList <ImportsClauseSyntax>().Add(newSimpleImportsNode); ImportsStatementSyntax newImportsStatementNode = ImportsStatement(simpleImportsList).WithTriviaFrom(oldImportsStatementNode); newImportsStatementNode = newImportsStatementNode.WithImportsKeyword(oldImportsStatementNode.ImportsKeyword); documentEditor.InsertAfter(oldImportsStatementNode, newImportsStatementNode); } } documentEditor.RemoveNode(oldImportsStatementNode); } } }
internal static void AddField(this DocumentEditor editor, TypeDeclarationSyntax containingType, FieldDeclarationSyntax field) { FieldDeclarationSyntax existing = null; foreach (var member in containingType.Members) { if (member is FieldDeclarationSyntax fieldDeclaration) { if (IsInsertBefore(fieldDeclaration)) { editor.InsertBefore(fieldDeclaration, field); return; } existing = fieldDeclaration; continue; } editor.InsertBefore(member, field); return; } if (existing != null) { editor.InsertAfter(existing, field); } else { editor.AddMember(containingType, field); } }
private void ReplaceUsingStatements() { HashSet <string> alreadyAddedUsingStatements = new HashSet <string>(); IEnumerable <UsingDirectiveSyntax> usingDirectiveNodes = tree.GetRoot().DescendantNodes().OfType <UsingDirectiveSyntax>(); foreach (UsingDirectiveSyntax oldUsingDirectiveNode in usingDirectiveNodes) // iterate over all qualified names in the file { var oldNamespace = oldUsingDirectiveNode.Name.GetText().ToString(); List <namespace_map> namespaces = NSMappingSQLConnector.GetInstance().GetNamespaceMapsFromOldNamespace(TransformProject.sdkId, oldNamespace); if (namespaces != null) { foreach (namespace_map nsMap in namespaces) { var newNamespace = nsMap.new_namespace; if (!alreadyAddedUsingStatements.Contains(newNamespace)) { alreadyAddedUsingStatements.Add(newNamespace); NameSyntax newIdentifierNode = IdentifierName(newNamespace); var newUsingDirectiveNode = oldUsingDirectiveNode.WithName(newIdentifierNode); documentEditor.InsertAfter(oldUsingDirectiveNode, newUsingDirectiveNode); } } documentEditor.RemoveNode(oldUsingDirectiveNode); } } }
/// <summary> /// Move <paramref name="toMove"></paramref> before <paramref name="statement">.</paramref>. /// </summary> /// <param name="editor">The <see cref="DocumentEditor"/>.</param> /// <param name="toMove">The <see cref="StatementSyntax"/> to move.</param> /// <param name="statement">The <see cref="StatementSyntax"/>.</param> /// <returns>The <see cref="DocumentEditor"/> that was passed in.</returns> public static DocumentEditor MoveAfter(this DocumentEditor editor, StatementSyntax toMove, StatementSyntax statement) { if (editor is null) { throw new ArgumentNullException(nameof(editor)); } if (toMove is null) { throw new ArgumentNullException(nameof(toMove)); } if (statement is null) { throw new ArgumentNullException(nameof(statement)); } editor.RemoveNode(toMove); editor.InsertAfter(statement, ToMove()); return(editor); StatementSyntax ToMove() { if (statement.GetLastToken().IsKind(SyntaxKind.CloseBraceToken)) { return(toMove.WithLeadingLineFeed()); } return(toMove); } }
public static void AddImportIfNeeded(this DocumentEditor editor, string importedNamespace) { if (importedNamespace.Contains(".")) { throw new NotSupportedException("Only adding of toplevel namespace is supported"); } var root = editor.OriginalRoot; var usings = root.DescendantNodes <UsingDirectiveSyntax>() .ToArray(); var existingImport = usings .SelectMany(u => u.DescendantNodes <IdentifierNameSyntax>()) .Where(ins => ins.Parent is UsingDirectiveSyntax) .FirstOrDefault(ins => ins.Identifier.Text == importedNamespace); if (existingImport != null) { return; } var newSystemImport = SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(Constants.System)); editor.InsertAfter(usings.Last(), new[] { newSystemImport }); }
private static void Append(DocumentEditor editor, SyntaxNode lastNode, INamespaceSymbol[] namespaces, int startIndex) { var g = editor.Generator; for (int i = namespaces.Length - 1; i >= startIndex; i--) { var namespaceSymbol = namespaces[i]; var newNode = g.GenerateNamespaceImportDeclaration(namespaceSymbol); editor.InsertAfter(lastNode, newNode); } }
private static void MakeNotify(DocumentEditor editor, ExpressionSyntax assignment, string propertyName, IMethodSymbol invoker, bool usesUnderscoreNames) { var snippet = assignment.FirstAncestor <PropertyDeclarationSyntax>() is PropertyDeclarationSyntax propertyDeclaration && propertyDeclaration.Identifier.ValueText == propertyName ? Snippet.OnPropertyChanged(invoker, propertyName, usesUnderscoreNames) : Snippet.OnOtherPropertyChanged(invoker, propertyName, usesUnderscoreNames); var onPropertyChanged = SyntaxFactory.ParseStatement(snippet) .WithSimplifiedNames() .WithLeadingElasticLineFeed() .WithTrailingElasticLineFeed() .WithAdditionalAnnotations(Formatter.Annotation); if (assignment.Parent is AnonymousFunctionExpressionSyntax anonymousFunction) { if (anonymousFunction.Body is BlockSyntax block) { if (block.Statements.Count > 1) { var previousStatement = InsertAfter(block, block.Statements.Last(), invoker); editor.InsertAfter(previousStatement, new[] { onPropertyChanged }); } return; } var expressionStatement = (ExpressionStatementSyntax)editor.Generator.ExpressionStatement(anonymousFunction.Body); var withStatements = editor.Generator.WithStatements(anonymousFunction, new[] { expressionStatement, onPropertyChanged }); editor.ReplaceNode(anonymousFunction, withStatements); } else if (assignment.Parent is ExpressionStatementSyntax assignStatement && assignStatement.Parent is BlockSyntax assignBlock) { var previousStatement = InsertAfter(assignBlock, assignStatement, invoker); editor.InsertAfter(previousStatement, new[] { onPropertyChanged }); }
public override void VisitClassDeclaration(ClassDeclarationSyntax node) { var modifiers = GetModifiers(Command.Modifiers, Command.Abstract, Command.Static, Command.Partial); var baseTypes = GetBaseTypes(Command.ImplementedInterfaces, Command.InheritsType); var classNode = node.WithIdentifier(SyntaxFactory.Identifier(Command.Name)) .WithTypeParameterList(Command.GenericParameters) .WithConstraintClauses(Command.GenericParametersConstraints) .WithAttributeLists(Command.Attributes) .WithModifiers(modifiers) .WithBaseList(baseTypes) .WithAdditionalAnnotations(new SyntaxAnnotation($"{Id}")); DocumentEditor.InsertAfter(node, classNode); }
private static void ChangeEventToPublicAndNonStatic( ICodeGenerationService codeGenerationService, DocumentEditor editor, IEventSymbol eventSymbol, SyntaxNode eventDeclaration, DeclarationModifiers modifiers ) { var declaration = editor.Generator.GetDeclaration(eventDeclaration); var isEventHasExplicitAddOrRemoveMethod = (eventSymbol.AddMethod != null && !eventSymbol.AddMethod.IsImplicitlyDeclared) || ( eventSymbol.RemoveMethod != null && !eventSymbol.RemoveMethod.IsImplicitlyDeclared ); // There are three situations here: // 1. Single Event. // 2. Several events exist in one declaration. // 3. Event has add or remove method(user declared). // For situation 1, declaration is EventFieldDeclaration, eventDeclaration is variableDeclaration. // For situation 2, declaration and eventDeclaration are both EventDeclaration, which are same. // For situation 3, it is same as situation 2, but has add or remove method. if (declaration.Equals(eventDeclaration) && !isEventHasExplicitAddOrRemoveMethod) { // Several events are declared in same line var publicAndNonStaticSymbol = CodeGenerationSymbolFactory.CreateEventSymbol( eventSymbol, accessibility: Accessibility.Public, modifiers: modifiers ); var options = new CodeGenerationOptions(generateMethodBodies: false); var publicAndNonStaticSyntax = codeGenerationService.CreateEventDeclaration( publicAndNonStaticSymbol, destination: CodeGenerationDestination.ClassType, options: options ); // Insert a new declaration and remove the original declaration editor.InsertAfter(declaration, publicAndNonStaticSyntax); editor.RemoveNode(eventDeclaration); } else { // Handle both single event and event has add or remove method editor.SetAccessibility(declaration, Accessibility.Public); editor.SetModifiers(declaration, modifiers); } }
public static void AddUsingIfDoesntExists(this DocumentEditor documentEditor, string usingname) { var root = documentEditor.GetChangedDocument().GetSyntaxTreeAsync().Result.GetRoot(); var usingStatements = root.DescendantNodes().OfType <UsingDirectiveSyntax>().ToArray(); if (usingStatements.Length == 0) { return; } if (usingStatements.All(x => x.Name.ToString() != usingname)) { var usingFluientStatment = SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(usingname)).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\r\n")); documentEditor.InsertAfter(usingStatements.Last(), usingFluientStatment); } }
private static void CreateTearDownMethod(DocumentEditor editor, ISymbol fieldOrProperty, MethodDeclarationSyntax setupMethod, QualifiedType tearDownType, CancellationToken cancellationToken) { var code = StringBuilderPool.Borrow() .AppendLine($"[{tearDownType.FullName}]") .AppendLine($"public void {tearDownType.Type.Replace("Attribute", string.Empty)}()") .AppendLine("{") .AppendLine($" {Snippet.DisposeStatement(fieldOrProperty, editor.SemanticModel, cancellationToken)}") .AppendLine("}") .Return(); var tearDownMethod = Parse.MethodDeclaration(code) .WithSimplifiedNames() .WithLeadingTrivia(SyntaxFactory.ElasticMarker) .WithTrailingTrivia(SyntaxFactory.ElasticMarker) .WithAdditionalAnnotations(Formatter.Annotation); editor.InsertAfter(setupMethod, tearDownMethod); }
private static void GenerateRegistrationStatement(DocumentEditor editor, ClassBlockSyntax classDeclaration, ConstructorBlockSyntax staticConstructor, string registerPropertyMethodName, IPropertySymbol propertySymbol, bool returnsMounter, CancellationToken ct) { var semanticModel = editor.SemanticModel; var classSymbol = semanticModel.GetDeclaredSymbol(classDeclaration, ct); var statements = staticConstructor.Statements; if (statements.Count > 0) { var statement = editor.Generator.GeneratePropertyRegistration(LanguageNames.VisualBasic, classSymbol, propertySymbol, registerPropertyMethodName, returnsMounter, true); editor.InsertAfter(statements.Last(), new SyntaxNode[] { statement }); } else { var newStaticConstructor = editor.Generator.GeneratePropertyRegistration(LanguageNames.VisualBasic, classSymbol, propertySymbol, registerPropertyMethodName, returnsMounter, false); editor.ReplaceNode(staticConstructor, newStaticConstructor); } }
private static void AddToIf(DocumentEditor editor, IfStatementSyntax ifSetAndRaise, ExpressionStatementSyntax invocation) { if (ifSetAndRaise.Statement is BlockSyntax body) { editor.RemoveNode(invocation); if (body.Statements.Count == 0) { editor.ReplaceNode( body, body.AddStatements(invocation.WithLeadingElasticLineFeed())); } else { editor.InsertAfter(body.Statements.Last(), invocation.WithLeadingElasticLineFeed()); } } else { if (ifSetAndRaise.Statement == null) { editor.RemoveNode(invocation); editor.ReplaceNode( ifSetAndRaise, (x, _) => ((IfStatementSyntax)x) .WithStatement(SyntaxFactory.Block(ifSetAndRaise.Statement, invocation)) .WithSimplifiedNames() .WithTrailingElasticLineFeed() .WithAdditionalAnnotations(Formatter.Annotation)); } else { editor.RemoveNode(invocation); editor.ReplaceNode( ifSetAndRaise.Statement, (x, _) => SyntaxFactory.Block(ifSetAndRaise.Statement, invocation) .WithSimplifiedNames() .WithTrailingElasticLineFeed() .WithAdditionalAnnotations(Formatter.Annotation)); } } editor.FormatNode(ifSetAndRaise); }
/// <summary> /// Move <paramref name="toMove"></paramref> before <paramref name="member">.</paramref>. /// </summary> /// <param name="editor">The <see cref="DocumentEditor"/>.</param> /// <param name="toMove">The <see cref="MemberDeclarationSyntax"/> to move.</param> /// <param name="member">The <see cref="MemberDeclarationSyntax"/>.</param> /// <returns>The <see cref="DocumentEditor"/> that was passed in.</returns> public static DocumentEditor MoveAfter(this DocumentEditor editor, MemberDeclarationSyntax toMove, MemberDeclarationSyntax member) { if (editor is null) { throw new ArgumentNullException(nameof(editor)); } if (toMove is null) { throw new ArgumentNullException(nameof(toMove)); } if (member is null) { throw new ArgumentNullException(nameof(member)); } editor.RemoveNode(toMove); editor.InsertAfter(member, ToMove()); editor.ReplaceNode(member, Member()); return(editor); MemberDeclarationSyntax ToMove() { return(toMove.AdjustLeadingNewLine(member)); } MemberDeclarationSyntax Member() { if (member.Parent is TypeDeclarationSyntax typeDeclaration) { var index = typeDeclaration.Members.IndexOf(member) - 1; if (typeDeclaration.Members.IndexOf(toMove) == index) { index--; } return(member.AdjustLeadingNewLine(typeDeclaration.Members.ElementAtOrDefault(index))); } return(toMove); } }
public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node) { var modifiers = GetModifiers(Command.Modifiers, Command.Abstract, Command.Static); var newNode = node.WithIdentifier(SyntaxFactory.ParseToken(Command.Name)) .WithAttributeLists(Command.Attributes) .WithModifiers(modifiers) .WithAdditionalAnnotations(new SyntaxAnnotation($"{Id}")) .WithType(Command.ReturnType ?? node.Type); if (Command.InitializerExpression != null) { newNode = newNode.WithInitializer(SyntaxFactory.EqualsValueClause(Command.InitializerExpression)) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); } var getAccessor = node.AccessorList.Accessors.FirstOrDefault(x => x.IsKind(SyntaxKind.GetAccessorDeclaration)); var setAccessor = node.AccessorList.Accessors.FirstOrDefault(x => x.IsKind(SyntaxKind.SetKeyword)); var newGetAccessor = getAccessor?.WithModifiers(Command.GetModifier) .WithExpressionBody(Command.GetExpression ?? getAccessor?.ExpressionBody) .WithBody(Command.GetStatements ?? getAccessor?.Body); var newSetAccessor = setAccessor?.WithModifiers(Command.SetModifier) .WithExpressionBody(Command.SetExpression ?? setAccessor?.ExpressionBody) .WithBody(Command.SetStatements ?? setAccessor?.Body); var Accesors = new SyntaxList <AccessorDeclarationSyntax>(); if (newGetAccessor != null) { Accesors = Accesors.Add(newGetAccessor); } if (newSetAccessor != null) { Accesors = Accesors.Add(newSetAccessor); } newNode = newNode.WithAccessorList(SyntaxFactory.AccessorList(Accesors)); DocumentEditor.InsertAfter(node, newNode); }
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); } } }
public override void VisitConstructorDeclaration(ConstructorDeclarationSyntax node) { var modifiers = GetModifiers(Command.Modifiers, Command.Static); var ConstructorNode = node.WithIdentifier((Command.OnNode as TypeDeclarationSyntax)?.Identifier ?? node.Identifier) .WithAttributeLists(Command.Attributes.Count > 0 ? Command.Attributes : node.AttributeLists) .WithParameterList(Command.Parameters ?? node.ParameterList) .WithBody(Command.BlockBody ?? node.Body) .WithModifiers(modifiers.Count > 0 ? modifiers : node.Modifiers) .WithAdditionalAnnotations(new SyntaxAnnotation($"{Id}")); if (Command.OnNode is null) { DocumentEditor.InsertAfter(node, ConstructorNode); } else { DocumentEditor.InsertMembers(Command.OnNode, 0, new[] { ConstructorNode }); } }
public override void VisitMethodDeclaration(MethodDeclarationSyntax node) { var modifiers = GetModifiers(Command.Modifiers, Command.Abstract, Command.Static, Command.Partial); var methodNode = node.WithIdentifier(SyntaxFactory.ParseToken(Command.Name ?? node.Identifier.ToString())) .WithAttributeLists(Command.Attributes.Count > 0 ? Command.Attributes : node.AttributeLists) .WithParameterList(Command.Parameters ?? node.ParameterList) .WithTypeParameterList(Command.GenericParameters ?? node.TypeParameterList) .WithConstraintClauses(Command.GenericParametersConstraints.Count > 0 ? Command.GenericParametersConstraints : node.ConstraintClauses) .WithModifiers(modifiers.Count > 0 ? modifiers : node.Modifiers) .WithReturnType(Command.ReturnType ?? node.ReturnType) .WithBody(Command.BlockBody ?? (Command.ExpressionBody is null ? node.Body: null)) .WithExpressionBody(Command.ExpressionBody ?? (Command.BlockBody is null ? node.ExpressionBody : null)) .WithAdditionalAnnotations(new SyntaxAnnotation($"{Id}")); if (Command.ExpressionBody != null) { methodNode = methodNode.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); } DocumentEditor.InsertAfter(node, methodNode); }
private static void GenerateRegisterChildModel(DocumentEditor editor, ConstructorBlockSyntax staticConstructor, ClassBlockSyntax classDeclaration, SemanticModel semanticModel, IPropertySymbol childProperty, IPropertySymbol foreignKey) { if (staticConstructor == null) { var newStaticConstructor = editor.Generator.GenerateChildModelRegistrationStaticConstructor(LanguageNames.VisualBasic, childProperty, foreignKey); var index = GetMounterDeclarationInsertIndex(classDeclaration, semanticModel); editor.InsertMembers(classDeclaration, index, new SyntaxNode[] { newStaticConstructor }); } else { var statements = staticConstructor.Statements; if (statements.Count > 0) { var statement = editor.Generator.GenerateChildModelRegistration(LanguageNames.VisualBasic, childProperty, foreignKey); editor.InsertAfter(statements.Last(), new SyntaxNode[] { statement }); } else { var newStaticConstructor = editor.Generator.GenerateChildModelRegistrationStaticConstructor(LanguageNames.VisualBasic, childProperty, foreignKey); editor.ReplaceNode(staticConstructor, newStaticConstructor); } } }
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); } } }