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); }
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); }
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); }
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; }