public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var node      = root.FindNode(context.Span);
            var parameter = node as ParameterSyntax;

            if (parameter == null)
            {
                return;
            }

            var parameterName    = RoslynHelpers.GetParameterName(parameter);
            var underscorePrefix = "_" + parameterName;
            var uppercase        = parameterName.Substring(0, 1).ToUpper() + parameterName.Substring(1);

            if (RoslynHelpers.VariableExists(root, parameterName, underscorePrefix, uppercase))
            {
                return;
            }

            var action = CodeAction.Create(
                "Introduce and initialize field '" + underscorePrefix + "'",
                ct => CreateFieldAsync(context, parameter, parameterName, underscorePrefix, ct));

            context.RegisterRefactoring(action);
        }
示例#2
0
        private async Task <Document> CreateFieldAsync(CodeRefactoringContext context, SyntaxNode root, string interfaceName, string paramName, string fieldName, CancellationToken cancellationToken)
        {
            var @namespace = (NamespaceDeclarationSyntax)
                             root.ChildNodes().First(n => n.Kind() == SyntaxKind.NamespaceDeclaration);

            var @class = (ClassDeclarationSyntax)
                         @namespace.ChildNodes().First(n => n.Kind() == SyntaxKind.ClassDeclaration);

            var constructor = (ConstructorDeclarationSyntax)
                              @class.ChildNodes().First(n => n.Kind() == SyntaxKind.ConstructorDeclaration);

            var existingDependencies = RoslynHelpers.InjectedInterfacesForConstuctor(constructor);

            var oldConstructor = constructor;
            var newConstructor = oldConstructor.WithBody(oldConstructor.Body.AddStatements(
                                                             SyntaxFactory.ExpressionStatement(
                                                                 SyntaxFactory.AssignmentExpression(
                                                                     SyntaxKind.SimpleAssignmentExpression,
                                                                     SyntaxFactory.IdentifierName(fieldName),
                                                                     SyntaxFactory.IdentifierName(paramName)))));

            newConstructor = newConstructor.WithParameterList(newConstructor.ParameterList.AddParameters(
                                                                  SyntaxFactory.Parameter(
                                                                      SyntaxFactory.Identifier(paramName))
                                                                  .WithType(SyntaxFactory.ParseTypeName(interfaceName))
                                                                  ));

            var oldClass            = @class;
            var oldClassWithNewCtor = oldClass.ReplaceNode(oldConstructor, newConstructor);

            var fieldDeclaration = RoslynHelpers.CreateFieldDeclaration(interfaceName, fieldName);
            var newClass         = oldClassWithNewCtor
                                   .WithMembers(oldClassWithNewCtor.Members.Insert(RoslynHelpers.CorrectIndexToAddNewField(oldClassWithNewCtor), fieldDeclaration))
                                   .WithAdditionalAnnotations(Formatter.Annotation);

            var oldRoot = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var newRoot = oldRoot.ReplaceNode(oldClass, newClass);

            return(context.Document.WithSyntaxRoot(newRoot));
        }
示例#3
0
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var node          = root.FindNode(context.Span);
            var interfaceType = node as IdentifierNameSyntax;

            if (interfaceType == null)
            {
                return;
            }
            if (!interfaceType.Identifier.ToString().StartsWith("I"))
            {
                return;
            }



            var interfaceName    = interfaceType.Identifier.ToString();
            var plainName        = interfaceName.Substring(1);
            var lowerPlainName   = plainName.Substring(0, 1).ToLower() + plainName.Substring(1);
            var upperPlainName   = plainName.Substring(0, 1).ToUpper() + plainName.Substring(1);
            var underscorePrefix = "_" + lowerPlainName;

            var namespaceNode        = (NamespaceDeclarationSyntax)root.ChildNodes().First(n => n.Kind() == SyntaxKind.NamespaceDeclaration);
            var classNode            = (ClassDeclarationSyntax)namespaceNode.ChildNodes().First(n => n.Kind() == SyntaxKind.ClassDeclaration);
            var constructorNode      = (ConstructorDeclarationSyntax)classNode.ChildNodes().First(n => n.Kind() == SyntaxKind.ConstructorDeclaration);
            var existingDependencies = RoslynHelpers.InjectedInterfacesForConstuctor(constructorNode);

            if (existingDependencies.Contains(interfaceName))
            {
                return;
            }

            var action = CodeAction.Create(
                "Inject this as an interface '" + underscorePrefix + "'",
                ct => CreateFieldAsync(context, root, interfaceName, lowerPlainName, underscorePrefix, ct));

            context.RegisterRefactoring(action);
        }
        private async Task <Document> CreateFieldAsync(CodeRefactoringContext context, ParameterSyntax parameter, string paramName, string fieldName, CancellationToken cancellationToken)
        {
            var oldConstructor = parameter.Ancestors().OfType <ConstructorDeclarationSyntax>().First();
            var newConstructor = oldConstructor.WithBody(oldConstructor.Body.AddStatements(
                                                             SyntaxFactory.ExpressionStatement(
                                                                 SyntaxFactory.AssignmentExpression(
                                                                     SyntaxKind.SimpleAssignmentExpression,
                                                                     SyntaxFactory.IdentifierName(fieldName),
                                                                     SyntaxFactory.IdentifierName(paramName)))));

            var oldClass            = parameter.FirstAncestorOrSelf <ClassDeclarationSyntax>();
            var oldClassWithNewCtor = oldClass.ReplaceNode(oldConstructor, newConstructor);

            var fieldDeclaration = RoslynHelpers.CreateFieldDeclaration(RoslynHelpers.GetParameterType(parameter), fieldName);
            var newClass         = oldClassWithNewCtor
                                   .WithMembers(oldClassWithNewCtor.Members.Insert(0, fieldDeclaration))
                                   .WithAdditionalAnnotations(Formatter.Annotation);

            var oldRoot = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var newRoot = oldRoot.ReplaceNode(oldClass, newClass);

            return(context.Document.WithSyntaxRoot(newRoot));
        }