Exemplo n.º 1
0
            private SyntaxNode GetNewRoot(CancellationToken cancellationToken)
            {
                SyntaxNode newRoot;

                if (_service.TryConvertToLocalDeclaration(_state.LocalType, _state.IdentifierToken, _document.Project.Solution.Workspace.Options, out newRoot))
                {
                    return(newRoot);
                }

                var syntaxFactory = _document.GetLanguageService <SyntaxGenerator>();
                var initializer   = _state.IsOnlyWrittenTo
                                        ? null
                                        : syntaxFactory.DefaultExpression(_state.LocalType);

                var type           = _state.LocalType;
                var localStatement = syntaxFactory.LocalDeclarationStatement(type, _state.IdentifierToken.ValueText, initializer);

                localStatement = localStatement.WithAdditionalAnnotations(Microsoft.CodeAnalysis.Formatting.Formatter.Annotation);

                var codeGenService = new CSharpCodeGenerationService(_document.Project.Solution.Workspace);
                var root           = _state.IdentifierToken.GetAncestors <SyntaxNode>().Last();

                return(codeGenService.AddStatements(
                           root,
                           SpecializedCollections.SingletonEnumerable(localStatement),
                           options: new CodeGenerationOptions(beforeThisLocation: _state.IdentifierToken.GetLocation()),
                           cancellationToken: cancellationToken));
            }
            private async Task <Document> GenerateFieldDelegatingConstructorAsync()
            {
                var arguments      = _state.Arguments.ToList();
                var parameterTypes = _state.ParameterTypes;

                var typeParametersNames = _state.TypeToGenerateIn.GetAllTypeParameters().Select(t => t.Name).ToList();
                var parameterNames      = _state.AttributeArguments != null
                                        ? _service.GenerateParameterNames(_document.SemanticModel, _state.AttributeArguments, typeParametersNames)
                                        : _service.GenerateParameterNames(_document.SemanticModel, arguments, typeParametersNames);

                Dictionary <string, ISymbol> parameterToExistingFieldMap;
                Dictionary <string, string>  parameterToNewFieldMap;
                List <IParameterSymbol>      parameters;

                GetParameters(arguments, _state.AttributeArguments, parameterTypes, parameterNames, out parameterToExistingFieldMap, out parameterToNewFieldMap, out parameters);

                var provider              = _document.Project.Solution.Workspace.Services.GetLanguageServices(_state.TypeToGenerateIn.Language);
                var syntaxFactory         = provider.GetService <SyntaxGenerator>();
                var codeGenerationService = new CSharpCodeGenerationService(_document.Project.Solution.Workspace);

                var syntaxTree = _document.SyntaxTree;
                var members    = syntaxFactory.CreateFieldDelegatingConstructor(
                    _state.TypeToGenerateIn.Name, _state.TypeToGenerateIn, parameters,
                    parameterToExistingFieldMap, parameterToNewFieldMap, _cancellationToken);

                var result = await codeGenerationService.AddMembersAsync(
                    _document.Project.Solution,
                    _state.TypeToGenerateIn,
                    members,
                    new CodeGenerationOptions(_state.Token.GetLocation(), generateDefaultAccessibility : false),
                    _cancellationToken)
                             .ConfigureAwait(false);

                return(result);
            }
Exemplo n.º 3
0
            protected override async Task <Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
            {
                // First, see if there are any constructors that would take the first 'n' arguments
                // we've provided.  If so, delegate to those, and then create a field for any
                // remaining arguments.  Try to match from largest to smallest.
                //
                // Otherwise, just generate a normal constructor that assigns any provided
                // parameters into fields.
                var provider = _document.Project.Solution.Workspace.Services.GetLanguageServices(_state.ContainingType.Language);
                var factory  = provider.GetService <SyntaxGenerator>();

                var thisConstructorArguments = _state.DelegatedConstructor.Parameters.Select(par => factory.Argument(par.RefKind, SyntaxFactory.IdentifierName(par.Name))).ToList();
                var statements = new List <SyntaxNode>();

                for (var i = _state.DelegatedConstructor.Parameters.Length; i < _state.Parameters.Count; i++)
                {
                    var symbolName       = _state.SelectedMembers[i].Name;
                    var parameterName    = _state.Parameters[i].Name;
                    var assignExpression = factory.AssignmentStatement(
                        factory.MemberAccessExpression(
                            factory.ThisExpression(),
                            factory.IdentifierName(symbolName)),
                        factory.IdentifierName(parameterName));

                    var expressionStatement = factory.ExpressionStatement(assignExpression);
                    statements.Add(expressionStatement);
                }

                var syntaxTree = await _document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                var codeGenerationService = new CSharpCodeGenerationService(_document.Project.Solution.Workspace.Services.GetLanguageServices(LanguageNames.CSharp));
                var result = await codeGenerationService.AddMethodAsync(
                    _document.Project.Solution,
                    _state.ContainingType,
                    CodeGenerationSymbolFactory.CreateConstructorSymbol(
                        attributes: null,
                        accessibility: Accessibility.Public,
                        modifiers: new DeclarationModifiers(),
                        typeName: _state.ContainingType.Name,
                        parameters: _state.Parameters,
                        statements: statements,
                        thisConstructorArguments: thisConstructorArguments),
                    new CodeGenerationOptions(contextLocation : syntaxTree.GetLocation(_state.TextSpan), generateDefaultAccessibility : false),
                    cancellationToken : cancellationToken)
                             .ConfigureAwait(false);

                return(result);
            }
            public async Task <GeneratedCode> GenerateAsync(CancellationToken cancellationToken)
            {
                var root = this.SemanticDocument.Root;

                // should I check venus hidden position check here as well?
                root = root.ReplaceNode(this.GetOutermostCallSiteContainerToProcess(cancellationToken), await this.GenerateBodyForCallSiteContainerAsync(cancellationToken).ConfigureAwait(false));
                var callSiteDocument = await this.SemanticDocument.WithSyntaxRootAsync(root, cancellationToken).ConfigureAwait(false);

                var newCallSiteRoot    = callSiteDocument.Root;
                var previousMemberNode = GetPreviousMember(callSiteDocument);

                // it is possible in a script file case where there is no previous member. in that case, insert new text into top level script
                var destination = (previousMemberNode.Parent == null) ? previousMemberNode : previousMemberNode.Parent;

                var codeGenerationService = new CSharpCodeGenerationService(this.SemanticDocument.Document.Project.Solution.Workspace.Services.GetLanguageServices(LanguageNames.CSharp));
                var result       = this.GenerateMethodDefinition(cancellationToken);
                var newContainer = codeGenerationService.AddMethod(
                    destination, result.Data,
                    new CodeGenerationOptions(afterThisLocation: previousMemberNode.GetLocation(), generateDefaultAccessibility: false, generateMethodBodies: true),
                    cancellationToken);

                var newDocument = callSiteDocument.Document.WithSyntaxRoot(newCallSiteRoot.ReplaceNode(destination, newContainer));

                newDocument = await Simplifier.ReduceAsync(newDocument, Simplifier.Annotation, null, cancellationToken).ConfigureAwait(false);

                var finalDocument = await SemanticDocument.CreateAsync(newDocument, cancellationToken).ConfigureAwait(false);

                var finalRoot = finalDocument.Root;

                var methodDefinition = finalRoot.GetAnnotatedNodesAndTokens(this.MethodDefinitionAnnotation).FirstOrDefault();

                if (!methodDefinition.IsNode || methodDefinition.AsNode() == null)
                {
                    return(await CreateGeneratedCodeAsync(
                               result.Status.With(OperationStatus.FailedWithUnknownReason), finalDocument, cancellationToken).ConfigureAwait(false));
                }

                if (methodDefinition.SyntaxTree.IsHiddenPosition(methodDefinition.AsNode().SpanStart, cancellationToken) ||
                    methodDefinition.SyntaxTree.IsHiddenPosition(methodDefinition.AsNode().Span.End, cancellationToken))
                {
                    return(await CreateGeneratedCodeAsync(
                               result.Status.With(OperationStatus.OverlapsHiddenPosition), finalDocument, cancellationToken).ConfigureAwait(false));
                }

                return(await CreateGeneratedCodeAsync(result.Status, finalDocument, cancellationToken).ConfigureAwait(false));
            }
        protected async Task <Solution> AddPropertyAsync(Document document, Solution destinationSolution, IFieldSymbol field, IPropertySymbol property, CancellationToken cancellationToken)
        {
            var codeGenerationService = new CSharpCodeGenerationService(document.Project.Solution.Workspace);

            var fieldDeclaration = field.DeclaringSyntaxReferences.First();
            var options          = new CodeGenerationOptions(contextLocation: fieldDeclaration.SyntaxTree.GetLocation(fieldDeclaration.Span));

            var destination     = field.ContainingType;
            var updatedDocument = await codeGenerationService.AddPropertyAsync(destinationSolution, destination, property, options, cancellationToken)
                                  .ConfigureAwait(false);

            updatedDocument = await Formatter.FormatAsync(updatedDocument, Formatter.Annotation, cancellationToken : cancellationToken).ConfigureAwait(false);

            updatedDocument = await Simplifier.ReduceAsync(updatedDocument, cancellationToken : cancellationToken).ConfigureAwait(false);

            return(updatedDocument.Project.Solution);
        }
Exemplo n.º 6
0
            protected override async Task <Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
            {
                // First, see if there are any constructors that would take the first 'n' arguments
                // we've provided.  If so, delegate to those, and then create a field for any
                // remaining arguments.  Try to match from largest to smallest.
                //
                // Otherwise, just generate a normal constructor that assigns any provided
                // parameters into fields.
                var parameterToExistingFieldMap = new Dictionary <string, ISymbol>();

                for (int i = 0; i < _state.Parameters.Count; i++)
                {
                    parameterToExistingFieldMap[_state.Parameters[i].Name] = _state.SelectedMembers[i];
                }

                var factory = _document.GetLanguageService <SyntaxGenerator>();

                var syntaxTree = await _document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                var members = factory.CreateFieldDelegatingConstructor(
                    _state.ContainingType.Name,
                    _state.ContainingType,
                    _state.Parameters,
                    parameterToExistingFieldMap,
                    parameterToNewFieldMap: null,
                    cancellationToken: cancellationToken);
                var codeGenerationService = new CSharpCodeGenerationService(_document.Project.Solution.Workspace.Services.GetLanguageServices(LanguageNames.CSharp));

                var result = await codeGenerationService.AddMembersAsync(
                    _document.Project.Solution,
                    _state.ContainingType,
                    members,
                    new CodeGenerationOptions(contextLocation : syntaxTree.GetLocation(_state.TextSpan), generateDefaultAccessibility : false),
                    cancellationToken)
                             .ConfigureAwait(false);

                return(result);
            }
            private async Task <Document> GenerateDelegatingConstructorAsync(
                int argumentCount,
                INamedTypeSymbol namedType)
            {
                if (namedType == null)
                {
                    return(null);
                }

                // We can't resolve overloads across language.
                if (_document.Project.Language != namedType.Language)
                {
                    return(null);
                }

                var arguments                   = _state.Arguments.Take(argumentCount).ToList();
                var remainingArguments          = _state.Arguments.Skip(argumentCount).ToList();
                var remainingAttributeArguments = _state.AttributeArguments != null?_state.AttributeArguments.Skip(argumentCount).ToList() : null;

                var remainingParameterTypes = _state.ParameterTypes.Skip(argumentCount).ToList();

                var instanceConstructors = namedType.InstanceConstructors.Where(IsSymbolAccessible).ToSet();

                if (instanceConstructors.IsEmpty())
                {
                    return(null);
                }

                var delegatedConstructor = _service.GetDelegatingConstructor(_state, _document, argumentCount, namedType, instanceConstructors, _cancellationToken);

                if (delegatedConstructor == null)
                {
                    return(null);
                }

                // There was a best match.  Call it directly.
                var provider              = _document.Project.Solution.Workspace.Services.GetLanguageServices(_state.TypeToGenerateIn.Language);
                var syntaxFactory         = provider.GetService <SyntaxGenerator>();
                var codeGenerationService = new CSharpCodeGenerationService(_document.Project.Solution.Workspace);

                // Map the first N parameters to the other constructor in this type.  Then
                // try to map any further parameters to existing fields.  Finally, generate
                // new fields if no such parameters exist.

                // Find the names of the parameters that will follow the parameters we're
                // delegating.
                var remainingParameterNames = _service.GenerateParameterNames(
                    _document.SemanticModel, remainingArguments, delegatedConstructor.Parameters.Select(p => p.Name).ToList());

                // Can't generate the constructor if the parameter names we're copying over forcibly
                // conflict with any names we generated.
                if (delegatedConstructor.Parameters.Select(p => p.Name).Intersect(remainingParameterNames).Any())
                {
                    return(null);
                }

                // Try to map those parameters to fields.
                Dictionary <string, ISymbol> parameterToExistingFieldMap;
                Dictionary <string, string>  parameterToNewFieldMap;
                List <IParameterSymbol>      remainingParameters;

                this.GetParameters(remainingArguments, remainingAttributeArguments, remainingParameterTypes, remainingParameterNames, out parameterToExistingFieldMap, out parameterToNewFieldMap, out remainingParameters);

                var fields           = syntaxFactory.CreateFieldsForParameters(remainingParameters, parameterToNewFieldMap);
                var assignStatements = syntaxFactory.CreateAssignmentStatements(remainingParameters, parameterToExistingFieldMap, parameterToNewFieldMap);

                var allParameters = delegatedConstructor.Parameters.Concat(remainingParameters).ToList();

                var isThis = namedType.Equals(_state.TypeToGenerateIn);
                var delegatingArguments      = syntaxFactory.CreateArguments(delegatedConstructor.Parameters);
                var baseConstructorArguments = isThis ? null : delegatingArguments;
                var thisConstructorArguments = isThis ? delegatingArguments : null;

                var constructor = CodeGenerationSymbolFactory.CreateConstructorSymbol(
                    attributes: null,
                    accessibility: Accessibility.Public,
                    modifiers: default(DeclarationModifiers),
                    typeName: _state.TypeToGenerateIn.Name,
                    parameters: allParameters,
                    statements: assignStatements.ToList(),
                    baseConstructorArguments: baseConstructorArguments,
                    thisConstructorArguments: thisConstructorArguments);

                var members = new List <ISymbol>(fields)
                {
                    constructor
                };
                var result = await codeGenerationService.AddMembersAsync(
                    _document.Project.Solution,
                    _state.TypeToGenerateIn,
                    members,
                    new CodeGenerationOptions(_state.Token.GetLocation(), generateDefaultAccessibility : false),
                    _cancellationToken)
                             .ConfigureAwait(false);

                return(result);
            }
Exemplo n.º 8
0
        private async Task <Result> EncapsulateFieldAsync(IFieldSymbol field, Document document, bool updateReferences, CancellationToken cancellationToken)
        {
            var originalField         = field;
            var finalNames            = GeneratePropertyAndFieldNames(field);
            var finalFieldName        = finalNames.Item1;
            var generatedPropertyName = finalNames.Item2;

            // Annotate the field declarations so we can find it after rename.
            var fieldDeclaration      = field.DeclaringSyntaxReferences.First();
            var declarationAnnotation = new SyntaxAnnotation();

            document = document.WithSyntaxRoot(fieldDeclaration.SyntaxTree.GetRoot(cancellationToken).ReplaceNode(fieldDeclaration.GetSyntax(cancellationToken),
                                                                                                                  fieldDeclaration.GetSyntax(cancellationToken).WithAdditionalAnnotations(declarationAnnotation)));

            var solution = document.Project.Solution;

            foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
            {
                var linkedDocument = solution.GetDocument(linkedDocumentId);
                var linkedRoot     = await linkedDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var linkedFieldNode = linkedRoot.FindNode(fieldDeclaration.Span);
                if (linkedFieldNode.Span != fieldDeclaration.Span)
                {
                    continue;
                }

                var updatedRoot = linkedRoot.ReplaceNode(linkedFieldNode, linkedFieldNode.WithAdditionalAnnotations(declarationAnnotation));
                solution = solution.WithDocumentSyntaxRoot(linkedDocumentId, updatedRoot);
            }

            document = solution.GetDocument(document.Id);

            // Resolve the annotated symbol and prepare for rename.

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var compilation = semanticModel.Compilation;

            field = field.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IFieldSymbol;

            var solutionNeedingProperty = solution;

            // We couldn't resolve field after annotating its declaration. Bail
            if (field == null)
            {
                return(null);
            }

            solutionNeedingProperty = await UpdateReferencesAsync(
                updateReferences, solution, document, field, finalFieldName, generatedPropertyName, cancellationToken).ConfigureAwait(false);

            document = solutionNeedingProperty.GetDocument(document.Id);

            var markFieldPrivate          = field.DeclaredAccessibility != Accessibility.Private;
            var rewrittenFieldDeclaration = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, document, declarationAnnotation, cancellationToken).ConfigureAwait(false);

            document = await Formatter.FormatAsync(document.WithSyntaxRoot(rewrittenFieldDeclaration), Formatter.Annotation, cancellationToken : cancellationToken).ConfigureAwait(false);

            solution = document.Project.Solution;
            foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
            {
                var linkedDocument    = solution.GetDocument(linkedDocumentId);
                var updatedLinkedRoot = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, linkedDocument, declarationAnnotation, cancellationToken).ConfigureAwait(false);

                var updatedLinkedDocument = await Formatter.FormatAsync(linkedDocument.WithSyntaxRoot(updatedLinkedRoot), Formatter.Annotation, cancellationToken : cancellationToken).ConfigureAwait(false);

                solution = updatedLinkedDocument.Project.Solution;
            }

            document = solution.GetDocument(document.Id);

            semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            compilation = semanticModel.Compilation;

            var newRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var newDeclaration = newRoot.GetAnnotatedNodes <SyntaxNode>(declarationAnnotation).First();

            field = semanticModel.GetDeclaredSymbol(newDeclaration, cancellationToken) as IFieldSymbol;

            var generatedProperty = GenerateProperty(generatedPropertyName, finalFieldName, originalField.DeclaredAccessibility, originalField, field.ContainingType, new SyntaxAnnotation(), document, cancellationToken);

            var codeGenerationService = new CSharpCodeGenerationService(document.Project.Solution.Workspace);
            var solutionWithProperty  = await AddPropertyAsync(document, document.Project.Solution, field, generatedProperty, cancellationToken).ConfigureAwait(false);

            return(new Result(solutionWithProperty, originalField.ToDisplayString(), Glyph.FieldPublic));
        }
		protected async Task<Solution> AddPropertyAsync(Document document, Solution destinationSolution, IFieldSymbol field, IPropertySymbol property, CancellationToken cancellationToken)
		{
			var codeGenerationService = new CSharpCodeGenerationService (document.Project.Solution.Workspace);

			var fieldDeclaration = field.DeclaringSyntaxReferences.First();
			var options = new CodeGenerationOptions(contextLocation: fieldDeclaration.SyntaxTree.GetLocation(fieldDeclaration.Span));

			var destination = field.ContainingType;
			var updatedDocument = await codeGenerationService.AddPropertyAsync(destinationSolution, destination, property, options, cancellationToken)
			                                                 .ConfigureAwait(false);

			updatedDocument = await Formatter.FormatAsync(updatedDocument, Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);
			updatedDocument = await Simplifier.ReduceAsync(updatedDocument, cancellationToken: cancellationToken).ConfigureAwait(false);

			return updatedDocument.Project.Solution;
		}
        protected async override Task <SyntaxNode> RewriteFieldNameAndAccessibility(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var declarator = root.GetAnnotatedNodes <VariableDeclaratorSyntax>(declarationAnnotation).FirstOrDefault();

            // There may be no field to rewrite if this document is part of a set of linked files
            // and the declaration is not conditionally compiled in this document's project.
            if (declarator == null)
            {
                return(root);
            }

            var tempAnnotation = new SyntaxAnnotation();
            var newIdentifier  = SyntaxFactory.Identifier(originalFieldName)
                                 .WithTrailingTrivia(declarator.Identifier.TrailingTrivia)
                                 .WithLeadingTrivia(declarator.Identifier.LeadingTrivia);

            var updatedDeclarator = declarator.WithIdentifier(newIdentifier).WithAdditionalAnnotations(tempAnnotation);

            root     = root.ReplaceNode(declarator, updatedDeclarator);
            document = document.WithSyntaxRoot(root);

            var declaration = root.GetAnnotatedNodes <SyntaxNode>(tempAnnotation).First().Parent as VariableDeclarationSyntax;

            if (declaration.Variables.Count == 1)
            {
                var fieldSyntax = declaration.Parent as FieldDeclarationSyntax;

                var modifierKinds = new[] { SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.InternalKeyword, SyntaxKind.PublicKeyword };

                if (makePrivate)
                {
                    var modifiers = SpecializedCollections.SingletonEnumerable(SyntaxFactory.Token(SyntaxKind.PrivateKeyword))
                                    .Concat(fieldSyntax.Modifiers.Where(m => !modifierKinds.Contains(m.Kind())));

                    root = root.ReplaceNode(fieldSyntax, fieldSyntax.WithModifiers(
                                                SyntaxFactory.TokenList(modifiers))
                                            .WithAdditionalAnnotations(Formatter.Annotation)
                                            .WithLeadingTrivia(fieldSyntax.GetLeadingTrivia())
                                            .WithTrailingTrivia(fieldSyntax.GetTrailingTrivia()));
                }
            }
            else if (declaration.Variables.Count > 1 && makePrivate)
            {
                document = document.WithSyntaxRoot(root);
                var codeGenService = new CSharpCodeGenerationService(document.Project.Solution.Workspace.Services.GetLanguageServices(LanguageNames.CSharp));
                var semanticModel  = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                declarator  = root.GetAnnotatedNodes <VariableDeclaratorSyntax>(tempAnnotation).First();
                declaration = declarator.Parent as VariableDeclarationSyntax;

                var field = semanticModel.GetDeclaredSymbol(declarator, cancellationToken) as IFieldSymbol;

                var fieldToAdd = declarationAnnotation.AddAnnotationToSymbol(CodeGenerationSymbolFactory.CreateFieldSymbol(
                                                                                 field.GetAttributes(),
                                                                                 Accessibility.Private,
                                                                                 new DeclarationModifiers().WithIsStatic(field.IsStatic).WithIsReadOnly(field.IsReadOnly).WithIsConst(field.IsConst),
                                                                                 field.Type,
                                                                                 field.Name,
                                                                                 field.HasConstantValue,
                                                                                 field.ConstantValue,
                                                                                 declarator.Initializer));

                var withField = await codeGenService.AddFieldAsync(document.Project.Solution, field.ContainingType, fieldToAdd, new CodeGenerationOptions(), cancellationToken).ConfigureAwait(false);

                root = await withField.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                declarator  = root.GetAnnotatedNodes <VariableDeclaratorSyntax>(tempAnnotation).First();
                declaration = declarator.Parent as VariableDeclarationSyntax;

                return(root.RemoveNode(declarator, SyntaxRemoveOptions.KeepNoTrivia));
            }

            return(root);
        }
		private async Task<Result> EncapsulateFieldAsync(IFieldSymbol field, Document document, bool updateReferences, CancellationToken cancellationToken)
		{
			var originalField = field;
			var finalNames = GeneratePropertyAndFieldNames(field);
			var finalFieldName = finalNames.Item1;
			var generatedPropertyName = finalNames.Item2;

			// Annotate the field declarations so we can find it after rename.
			var fieldDeclaration = field.DeclaringSyntaxReferences.First();
			var declarationAnnotation = new SyntaxAnnotation();
			document = document.WithSyntaxRoot(fieldDeclaration.SyntaxTree.GetRoot(cancellationToken).ReplaceNode(fieldDeclaration.GetSyntax(cancellationToken),
			                                                                                                      fieldDeclaration.GetSyntax(cancellationToken).WithAdditionalAnnotations(declarationAnnotation)));

			var solution = document.Project.Solution;

			foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
			{
				var linkedDocument = solution.GetDocument(linkedDocumentId);
				var linkedRoot = await linkedDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
				var linkedFieldNode = linkedRoot.FindNode(fieldDeclaration.Span);
				if (linkedFieldNode.Span != fieldDeclaration.Span)
				{
					continue;
				}

				var updatedRoot = linkedRoot.ReplaceNode(linkedFieldNode, linkedFieldNode.WithAdditionalAnnotations(declarationAnnotation));
				solution = solution.WithDocumentSyntaxRoot(linkedDocumentId, updatedRoot);
			}

			document = solution.GetDocument(document.Id);

			// Resolve the annotated symbol and prepare for rename.

			var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
			var compilation = semanticModel.Compilation;
			field = field.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IFieldSymbol;

			var solutionNeedingProperty = solution;

			// We couldn't resolve field after annotating its declaration. Bail
			if (field == null)
			{
				return null;
			}

			solutionNeedingProperty = await UpdateReferencesAsync(
				updateReferences, solution, document, field, finalFieldName, generatedPropertyName, cancellationToken).ConfigureAwait(false);
			document = solutionNeedingProperty.GetDocument(document.Id);

			var markFieldPrivate = field.DeclaredAccessibility != Accessibility.Private;
			var rewrittenFieldDeclaration = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, document, declarationAnnotation, cancellationToken).ConfigureAwait(false);

			document = await Formatter.FormatAsync(document.WithSyntaxRoot(rewrittenFieldDeclaration), Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);

			solution = document.Project.Solution;
			foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
			{
				var linkedDocument = solution.GetDocument(linkedDocumentId);
				var updatedLinkedRoot = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, linkedDocument, declarationAnnotation, cancellationToken).ConfigureAwait(false);
				var updatedLinkedDocument = await Formatter.FormatAsync(linkedDocument.WithSyntaxRoot(updatedLinkedRoot), Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);
				solution = updatedLinkedDocument.Project.Solution;
			}

			document = solution.GetDocument(document.Id);

			semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
			compilation = semanticModel.Compilation;

			var newRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
			var newDeclaration = newRoot.GetAnnotatedNodes<SyntaxNode>(declarationAnnotation).First();
			field = semanticModel.GetDeclaredSymbol(newDeclaration, cancellationToken) as IFieldSymbol;

			var generatedProperty = GenerateProperty(generatedPropertyName, finalFieldName, originalField.DeclaredAccessibility, originalField, field.ContainingType, new SyntaxAnnotation(), document, cancellationToken);

			var codeGenerationService = new CSharpCodeGenerationService (document.Project.Solution.Workspace);
			var solutionWithProperty = await AddPropertyAsync(document, document.Project.Solution, field, generatedProperty, cancellationToken).ConfigureAwait(false);

			return new Result(solutionWithProperty, originalField.ToDisplayString(), Glyph.FieldPublic);
		}
		protected async override Task<SyntaxNode> RewriteFieldNameAndAccessibility(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken)
		{
			var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

			var declarator = root.GetAnnotatedNodes<VariableDeclaratorSyntax>(declarationAnnotation).FirstOrDefault();

			// There may be no field to rewrite if this document is part of a set of linked files
			// and the declaration is not conditionally compiled in this document's project.
			if (declarator == null)
			{
				return root;
			}

			var tempAnnotation = new SyntaxAnnotation();
			var newIdentifier = SyntaxFactory.Identifier(originalFieldName)
			                                 .WithTrailingTrivia(declarator.Identifier.TrailingTrivia)
			                                 .WithLeadingTrivia(declarator.Identifier.LeadingTrivia);

			var updatedDeclarator = declarator.WithIdentifier(newIdentifier).WithAdditionalAnnotations(tempAnnotation);

			root = root.ReplaceNode(declarator, updatedDeclarator);
			document = document.WithSyntaxRoot(root);

			var declaration = root.GetAnnotatedNodes<SyntaxNode>(tempAnnotation).First().Parent as VariableDeclarationSyntax;

			if (declaration.Variables.Count == 1)
			{
				var fieldSyntax = declaration.Parent as FieldDeclarationSyntax;

				var modifierKinds = new[] { SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.InternalKeyword, SyntaxKind.PublicKeyword };

				if (makePrivate)
				{
					var modifiers = SpecializedCollections.SingletonEnumerable(SyntaxFactory.Token(SyntaxKind.PrivateKeyword))
					                                      .Concat(fieldSyntax.Modifiers.Where(m => !modifierKinds.Contains(m.Kind())));

					root = root.ReplaceNode(fieldSyntax, fieldSyntax.WithModifiers(
						SyntaxFactory.TokenList(modifiers))
					                        .WithAdditionalAnnotations(Formatter.Annotation)
					                        .WithLeadingTrivia(fieldSyntax.GetLeadingTrivia())
					                        .WithTrailingTrivia(fieldSyntax.GetTrailingTrivia()));
				}
			}
			else if (declaration.Variables.Count > 1 && makePrivate)
			{
				document = document.WithSyntaxRoot(root);
				var codeGenService = new CSharpCodeGenerationService (document.Project.Solution.Workspace.Services.GetLanguageServices (LanguageNames.CSharp));
				var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

				root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

				declarator = root.GetAnnotatedNodes<VariableDeclaratorSyntax>(tempAnnotation).First();
				declaration = declarator.Parent as VariableDeclarationSyntax;

				var field = semanticModel.GetDeclaredSymbol(declarator, cancellationToken) as IFieldSymbol;

				var fieldToAdd = declarationAnnotation.AddAnnotationToSymbol(CodeGenerationSymbolFactory.CreateFieldSymbol(
					field.GetAttributes(),
					Accessibility.Private,
					new DeclarationModifiers().WithIsStatic (field.IsStatic).WithIsReadOnly(field.IsReadOnly).WithIsConst(field.IsConst),
					field.Type,
					field.Name,
					field.HasConstantValue,
					field.ConstantValue,
					declarator.Initializer));

				var withField = await codeGenService.AddFieldAsync(document.Project.Solution, field.ContainingType, fieldToAdd, new CodeGenerationOptions(), cancellationToken).ConfigureAwait(false);
				root = await withField.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

				declarator = root.GetAnnotatedNodes<VariableDeclaratorSyntax>(tempAnnotation).First();
				declaration = declarator.Parent as VariableDeclarationSyntax;

				return root.RemoveNode(declarator, SyntaxRemoveOptions.KeepNoTrivia);
			}

			return root;
		}