private async Task <Document> InitializeFieldAsync(Document document, SyntaxNode root, ParameterSyntax parameter, ConstructorDeclarationSyntax constructor, CancellationToken cancellationToken) { string fieldName; var typeDeclaration = constructor.GetParentTypeDeclaration(); var trackedRoot = root.TrackNodes(constructor, typeDeclaration); var model = await document.GetSemanticModelAsync(cancellationToken); var existingField = FindExistingField(model, parameter, constructor.Parent as TypeDeclarationSyntax, cancellationToken); if (existingField != null) { fieldName = existingField.Name; } else { fieldName = await nameGenerator.GetNewMemberNameAsync(constructor.Parent as TypeDeclarationSyntax, parameter.Identifier.ValueText, document, cancellationToken); var field = CreateFieldDeclaration(parameter.Type, fieldName); var insertionPoint = FindInsertionPointBelowFieldGroup(trackedRoot.GetCurrentNode(typeDeclaration)); if (insertionPoint != null) { trackedRoot = trackedRoot.InsertNodesAfter(insertionPoint, SingletonList(field)); } else { // skip parent/interface list, type parameter list, type parameter constraint list and attribute list insertionPoint = trackedRoot.GetCurrentNode(typeDeclaration).ChildNodes() .First(node => !(node is BaseListSyntax) && !(node is TypeParameterListSyntax) && !(node is TypeParameterConstraintClauseSyntax) && !(node is AttributeListSyntax)); trackedRoot = trackedRoot.InsertNodesBefore(insertionPoint, SingletonList(field)); } } var assignment = constructor.ParameterList.Parameters.Any(p => p.Identifier.ValueText == fieldName) ? CreateThisAssignmentStatement(fieldName, parameter.Identifier.ValueText) : CreateAssignmentStatement(fieldName, parameter.Identifier.ValueText); var constructorBody = trackedRoot.GetCurrentNode(constructor).Body; var newConstructorBody = constructorBody.AddStatements(assignment) .WithAdditionalAnnotations(Formatter.Annotation); trackedRoot = trackedRoot.ReplaceNode(constructorBody, newConstructorBody); return(document.WithSyntaxRoot(trackedRoot)); }