public static async Task <Document> RefactorAsync( Document document, PropertyDeclarationSyntax propertyDeclaration, bool prefixIdentifierWithUnderscore = true, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); string fieldName = TextUtility.ToCamelCase( propertyDeclaration.Identifier.ValueText, prefixWithUnderscore: prefixIdentifierWithUnderscore); FieldDeclarationSyntax fieldDeclaration = CreateBackingField(propertyDeclaration, fieldName) .WithFormatterAnnotation(); PropertyDeclarationSyntax newPropertyDeclaration = ExpandPropertyAndAddBackingField(propertyDeclaration, fieldName) .WithTriviaFrom(propertyDeclaration) .WithFormatterAnnotation(); var parentMember = (MemberDeclarationSyntax)propertyDeclaration.Parent; SyntaxList <MemberDeclarationSyntax> members = parentMember.GetMembers(); int propertyIndex = members.IndexOf(propertyDeclaration); if (propertyDeclaration.IsReadOnlyAutoProperty()) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync( semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken), document.Project.Solution, cancellationToken).ConfigureAwait(false); ImmutableArray <IdentifierNameSyntax> identifierNames = SyntaxUtility .FindNodes <IdentifierNameSyntax>(oldRoot, referencedSymbols) .ToImmutableArray(); var rewriter = new IdentifierNameSyntaxRewriter(identifierNames, Identifier(fieldName)); var newParentMember = (MemberDeclarationSyntax)rewriter.Visit(parentMember); members = newParentMember.GetMembers(); } int indexOfLastField = members.LastIndexOf(f => f.IsKind(SyntaxKind.FieldDeclaration)); SyntaxList <MemberDeclarationSyntax> newMembers = members .Replace(members[propertyIndex], newPropertyDeclaration) .Insert(indexOfLastField + 1, fieldDeclaration); SyntaxNode newRoot = oldRoot.ReplaceNode(parentMember, parentMember.SetMembers(newMembers)); return(document.WithSyntaxRoot(newRoot)); }
private static async Task <Document> ReplacePropertyWithAutoPropertyAsync( Document document, PropertyDeclarationSyntax property, CancellationToken cancellationToken) { SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var parentMember = (MemberDeclarationSyntax)property.Parent; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ISymbol fieldSymbol = GetFieldSymbol(property, semanticModel, cancellationToken); var declarator = (VariableDeclaratorSyntax)await fieldSymbol.DeclaringSyntaxReferences[0].GetSyntaxAsync(cancellationToken).ConfigureAwait(false); var variableDeclaration = (VariableDeclarationSyntax)declarator.Parent; SyntaxList <MemberDeclarationSyntax> members = parentMember.GetMembers(); int propertyIndex = members.IndexOf(property); int fieldIndex = members.IndexOf((FieldDeclarationSyntax)variableDeclaration.Parent); IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync( fieldSymbol, document.Project.Solution, cancellationToken).ConfigureAwait(false); ImmutableArray <IdentifierNameSyntax> identifierNames = SyntaxUtility .FindNodes <IdentifierNameSyntax>(oldRoot, referencedSymbols) .ToImmutableArray(); var rewriter = new IdentifierNameSyntaxRewriter(identifierNames, Identifier(property.Identifier.ValueText)); var newParentMember = (MemberDeclarationSyntax)rewriter.Visit(parentMember); members = newParentMember.GetMembers(); if (variableDeclaration.Variables.Count == 1) { newParentMember = newParentMember.RemoveNode( newParentMember.GetMemberAt(fieldIndex), SyntaxRemoveOptions.KeepUnbalancedDirectives); if (propertyIndex > fieldIndex) { propertyIndex--; } } else { var field = (FieldDeclarationSyntax)members[fieldIndex]; FieldDeclarationSyntax newField = field.RemoveNode( field.Declaration.Variables[variableDeclaration.Variables.IndexOf(declarator)], SyntaxRemoveOptions.KeepUnbalancedDirectives); members = members.Replace(field, newField.WithFormatterAnnotation()); newParentMember = newParentMember.SetMembers(members); } members = newParentMember.GetMembers(); property = (PropertyDeclarationSyntax)members[propertyIndex]; PropertyDeclarationSyntax newProperty = CreateAutoProperty(property, declarator.Initializer); members = members.Replace(property, newProperty); newParentMember = newParentMember.SetMembers(members); SyntaxNode newRoot = oldRoot.ReplaceNode(parentMember, newParentMember); return(document.WithSyntaxRoot(newRoot)); }