public sealed override async Task ComputeRefactoringsAsync(
			CodeRefactoringContext context)
		{
			var document = context.Document;
			var documentFileNameWithoutExtension =
				Path.GetFileNameWithoutExtension(document.FilePath);

			var root = await document.GetSyntaxRootAsync(context.CancellationToken)
				.ConfigureAwait(false);
			var model = await document.GetSemanticModelAsync(context.CancellationToken)
				.ConfigureAwait(false);

			var typesToRemove = root.GetTypesToRemove(
				model, documentFileNameWithoutExtension);

			if (typesToRemove.Length > 1)
			{
				context.RegisterRefactoring(CodeAction.Create(
					"Move types to files in folders",
					async token => await ExtractTypesToFilesCodeRefactoringProvider.CreateFiles(
						document, root, model, typesToRemove,
						_ => _.Replace(".", "\\"), token)));
				context.RegisterRefactoring(CodeAction.Create(
					"Move types to files in current folder",
					async token => await ExtractTypesToFilesCodeRefactoringProvider.CreateFiles(
						document, root, model, typesToRemove,
						_ => string.Empty, token)));
			}
		}
		public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
		{
			var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
			var node = root.FindNode(context.Span);

			if (node.IsKind(SyntaxKind.Argument))
			{
				var argSyntax = (ArgumentSyntax)node;
				if (argSyntax == null) return;

				//Exit if not valid XML
				if (!IsXml(argSyntax.Expression.GetFirstToken().ValueText)) return;

				var action = CodeAction.Create("Format XML", c => FormatXmlAsync(context.Document, argSyntax, c));
				context.RegisterRefactoring(action);
			}

			if (node.IsKind(SyntaxKind.StringLiteralExpression))
			{
				var sleSyntax = (LiteralExpressionSyntax)node;
				if (sleSyntax == null) return;

				//Exit if not valid XML
				var text = sleSyntax.GetFirstToken().ValueText;
				if (!IsXml(text)) return;

				var action = CodeAction.Create("Format XML", c => FormatXmlAsync(context.Document, sleSyntax, c));
				context.RegisterRefactoring(action);
			}
		}
コード例 #3
0
        //*** This is the entry point when user hits Ctrl + . ***
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
            
            // Find the Property at the selection
            var node = root.FindNode(context.Span);
            var property = node.FirstAncestorOrSelf<PropertyDeclarationSyntax>();

            if (property == null)
            {
                return; // No property here... move along!
            }

            // Check if user is on an Auto property
            if (property.IsAutoProperty() || property.IsExpressionProperty())
            {
                // Auto Property is selected (Get ready for EXPLOSION)
                var explodeAction = CodeAction.Create("Explode Property...", c => ExplodePropertyAsync(root, context.Document, property, c));
                context.RegisterRefactoring(explodeAction); // Register Explode Code Action (This will show Explode Property... in the context menu)
            }
            else if (property.HasGetter())
            {
                // Full Property is selected (Get ready to CRUNCH)
                var implodeAction = CodeAction.Create("Crunch Property...", c => CrunchPropertyAsync(root, context.Document, property, c));
                context.RegisterRefactoring(implodeAction); // Register Crunch Code Action (This will show Crunch Property... in the context menu)
            }
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxToken token = root.FindToken(span.Start);
            if (!token.IsKind(SyntaxKind.IdentifierToken))
                return;
            var property = token.Parent as PropertyDeclarationSyntax;
            if (property == null || !property.Identifier.Span.Contains(span))
                return;
            if (IsEmptyComputedProperty(property))
            {
                context.RegisterRefactoring(
                    CodeActionFactory.Create(
                        token.Span,
                        DiagnosticSeverity.Info,
                        GettextCatalog.GetString("Convert to auto-property"),
                        t2 =>
                        {
                            var newRoot = root.ReplaceNode(property, CreateNewProperty(property).WithAdditionalAnnotations(Formatter.Annotation).WithLeadingTrivia(property.GetLeadingTrivia()));
                            return Task.FromResult(document.WithSyntaxRoot(newRoot));
                        }
                    )
                );
                return;
            }
            var field = GetBackingField(model, property);
            if (!IsValidField(field, property.Parent as TypeDeclarationSyntax))
                return;

            //variable declarator->declaration->field declaration
            var backingFieldNode = root.FindNode(field.Locations.First().SourceSpan).Ancestors().OfType<FieldDeclarationSyntax>().First();


            var propertyAnnotation = new SyntaxAnnotation();
            var fieldAnnotation = new SyntaxAnnotation();

            //annotate our property node and our field node
            root = root.ReplaceNode((SyntaxNode)property, property.WithAdditionalAnnotations(propertyAnnotation));
            root = root.ReplaceNode((SyntaxNode)root.FindNode(backingFieldNode.Span), backingFieldNode.WithAdditionalAnnotations(fieldAnnotation));

            context.RegisterRefactoring(
                CodeActionFactory.Create(token.Span, DiagnosticSeverity.Info, GettextCatalog.GetString("Convert to auto-property"),
                    PerformAction(document, model, root, field.Name, CreateNewProperty(property), propertyAnnotation, fieldAnnotation))
            );
        }
コード例 #5
0
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            if (!await TypeAndFileNameMismatch(context))
                return;

            context.RegisterRefactoring(await new RenameTypeRefactoring(context).GetCodeAction());
            context.RegisterRefactoring(await new RenameFileRefactoring(DTE,context).GetCodeAction());
            context.RegisterRefactoring(await new MoveTypeToFileRefactoring(context).GetCodeAction());
        }
 public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
 {
     var document = context.Document;
     if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
         return;
     var span = context.Span;
     if (!span.IsEmpty)
         return;
     var cancellationToken = context.CancellationToken;
     if (cancellationToken.IsCancellationRequested)
         return;
     var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     if (model.IsFromGeneratedCode(cancellationToken))
         return;
     var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
     var node = root.FindNode(span) as BinaryExpressionSyntax;
     if (node == null || !(node.IsKind(SyntaxKind.EqualsExpression) || node.IsKind(SyntaxKind.NotEqualsExpression)))
         return;
     context.RegisterRefactoring(
         CodeActionFactory.Create(
             span,
             DiagnosticSeverity.Info,
             GettextCatalog.GetString("To 'Equals' call"),
             t2 => Task.FromResult(document.WithSyntaxRoot(root.ReplaceNode((SyntaxNode)node, CreateEquals(model, node))))
         )
     );
 }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(span.Start);
            if (!token.IsKind(SyntaxKind.StringLiteralToken) || token.Value.ToString() != "")
                return;

            context.RegisterRefactoring(
                CodeActionFactory.Create(
                    token.Span,
                    DiagnosticSeverity.Info,
                    GettextCatalog.GetString("Use 'string.Empty'"),
                    t2 =>
                    {
                        var newRoot = root.ReplaceNode((SyntaxNode)token.Parent, SyntaxFactory.ParseExpression("string.Empty"));
                        return Task.FromResult(document.WithSyntaxRoot(newRoot));
                    }
                )
            );
        }
コード例 #8
0
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            try
            {
                var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

                // Find the node at the selection.
                var node = root.FindNode(context.Span);

                // Only offer a refactoring if the selected node is a method declaration node.
                var methodDecl = node as MethodDeclarationSyntax;
                if (methodDecl == null) return;

                // Only offer a refactoring if the method declaration node matches a signature pattern we recognize.
                var refactoringProviderList = BuildRefactoringProviderList();
                foreach (var mapper in refactoringProviderList)
                {
                    if (await mapper.CanRefactor(context.Document, methodDecl))
                    {
                        // Register mapping code action.
                        var action = CodeAction.Create(mapper.Description, c => mapper.Refactor(context.Document, methodDecl, c));
                        context.RegisterRefactoring(action);

                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                string error = ex.ToString();
            }
        }
コード例 #9
0
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            var textSpan = context.Span;
            var cancellationToken = context.CancellationToken;

            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) as CompilationUnitSyntax;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            // if length is 0 then no particular range is selected, so pick the first enclosing member
            if (textSpan.Length == 0)
            {
                var decl = root.FindToken(textSpan.Start).Parent.AncestorsAndSelf().OfType<MemberDeclarationSyntax>().FirstOrDefault();
                if (decl != null)
                {
                    textSpan = decl.FullSpan;
                }
            }

            var properties = ExpansionChecker.GetExpandableProperties(textSpan, root, model);

            if (properties.Any())
            {
#pragma warning disable RS0005
                context.RegisterRefactoring(
                   CodeAction.Create("Apply INotifyPropertyChanged pattern", (c) =>
                                     ImplementNotifyPropertyChangedAsync(document, root, model, properties, c)));
#pragma warning restore RS0005
            }
        }
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var node = root.FindNode(context.Span);

            if (node == null) return;

            //process string literal or interpolated string.
            if (!node.IsKind(SyntaxKind.StringLiteralExpression))
            {
                node = node.AncestorsAndSelf().OfType<InterpolatedStringExpressionSyntax>().FirstOrDefault();
            }

            if (node == null) return;

            if (node.IsKind(SyntaxKind.StringLiteralExpression) || node.IsKind(SyntaxKind.InterpolatedStringExpression))
            {
                var tree = root.SyntaxTree;
                var lines = tree.GetText().Lines;

                // find add-expression in the same line (left end and right start).
                var addExpression = node.Ancestors()
                    .TakeWhile(n => n.IsKind(SyntaxKind.AddExpression))
                    .Cast<BinaryExpressionSyntax>()
                    .TakeWhile(n => lines.GetLinePosition(n.Left.Span.End).Line == lines.GetLinePosition(n.Right.Span.Start).Line)
                    .LastOrDefault();

                if (addExpression != null)
                {
                    var action = CodeAction.Create("Integrate strings", c => IntegrateStringsAsync(context.Document, addExpression, c), ActionKeyStringIntegration);
                    context.RegisterRefactoring(action);
                }
            }
        }
        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 currentRoot = await context.Document.GetSyntaxTreeAsync().Result.GetRootAsync();
            var classCount = currentRoot.DescendantNodesAndSelf().Where(n => n is ClassStatementSyntax).Count();
            
            // only for a type declaration node that doesn't match the current file name
            // also omit all private classes
            var typeDecl = node as ClassStatementSyntax;
            var className = typeDecl.Identifier.GetIdentifierText() + ".vb";

            //Is the name of the file the same as the name of the class then do nothing. 
            if(typeDecl == null || context.Document.Name.ToLowerInvariant() == className.ToLowerInvariant() || typeDecl.Modifiers.Any(SyntaxKind.PrivateKeyword))
            { return; }

            //We know the name of the class is not the same as the file. If this is the only class in the file we will offer a rename file refactoring.
            if(classCount == 1)
            {
                var renameFileActino = CodeAction.Create("Rename file to \"" + className + "\" ", c => RenameDocumentAsync(context.Document, className,c));
            }else
            {
                var action = CodeAction.Create("Move class to file \"" + className + "\" ", c => MoveClassIntoNewFileAsync(context.Document, typeDecl, className, c));
                context.RegisterRefactoring(action);
            }
                            
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            var node = root.FindToken(span.Start).Parent;
            if (node.Parent == null || node.Parent.Parent == null || !node.Parent.Parent.IsKind(SyntaxKind.InvocationExpression))
                return;
            var symbol = model.GetSymbolInfo(node.Parent).Symbol;

            if (symbol == null || symbol.Kind != SymbolKind.Method || symbol.ContainingType.SpecialType != SpecialType.System_Enum || symbol.Name != "HasFlag")
                return;
            var invocationNode = (InvocationExpressionSyntax)node.Parent.Parent;
            var arg = invocationNode.ArgumentList.Arguments.Select(a => a.Expression).First();
            if (!arg.DescendantNodesAndSelf().OfType<BinaryExpressionSyntax>().All(bop => bop.IsKind(SyntaxKind.BitwiseOrExpression)))
                return;

            context.RegisterRefactoring(
                CodeActionFactory.Create(node.Span, DiagnosticSeverity.Info, GettextCatalog.GetString("To bitwise flag comparison"), t2 => Task.FromResult(PerformAction(document, root, invocationNode)))
            );
        }
 public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
 {
     var document = context.Document;
     if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
         return;
     var span = context.Span;
     if (!span.IsEmpty)
         return;
     var cancellationToken = context.CancellationToken;
     if (cancellationToken.IsCancellationRequested)
         return;
     var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     if (model.IsFromGeneratedCode(cancellationToken))
         return;
     var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
     ExpressionSyntax expr;
     SyntaxToken token;
     if (!GetRelationalExpression(root, span, out expr, out token))
         return;
     context.RegisterRefactoring(
         CodeActionFactory.Create(
             span,
             DiagnosticSeverity.Info,
             string.Format(GettextCatalog.GetString("Negate '{0}'"), expr),
             t2 =>
             {
                 var newRoot = root.ReplaceNode((SyntaxNode)
                     expr,
                     CSharpUtil.InvertCondition(expr).WithAdditionalAnnotations(Formatter.Annotation)
                 );
                 return Task.FromResult(document.WithSyntaxRoot(newRoot));
             }
         )
     );
 }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(span.Start);
            var parameter = token.Parent as ParameterSyntax;

            if (parameter != null)
            {
                var ctor = parameter.Parent.Parent as ConstructorDeclarationSyntax;
                if (ctor == null)
                    return;
                
                context.RegisterRefactoring(
                    CodeActionFactory.Create(
                        parameter.Span,
                        DiagnosticSeverity.Info,
                        GettextCatalog.GetString("Initialize field from parameter"),
                        t2 =>
                        {
                    var newFieldName = NameProposalService.GetNameProposal(parameter.Identifier.ValueText, SyntaxKind.FieldDeclaration, Accessibility.Private, false, context.Document, ctor.SpanStart);
                            var newField = SyntaxFactory.FieldDeclaration(
                                SyntaxFactory.VariableDeclaration(
                                    parameter.Type,
                                    SyntaxFactory.SingletonSeparatedList<VariableDeclaratorSyntax>(SyntaxFactory.VariableDeclarator(newFieldName)))
                            ).WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)))
                            .WithAdditionalAnnotations(Formatter.Annotation);

                            var assignmentStatement = SyntaxFactory.ExpressionStatement(
                                SyntaxFactory.AssignmentExpression(
                                    SyntaxKind.SimpleAssignmentExpression,
                                    SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName(newFieldName)),
                                    SyntaxFactory.IdentifierName(newFieldName)
                                )
                            ).WithAdditionalAnnotations(Formatter.Annotation);

                            var trackedRoot = root.TrackNodes(ctor);
                            var newRoot = trackedRoot.InsertNodesBefore(trackedRoot.GetCurrentNode(ctor), new List<SyntaxNode>() {
                                newField
                            });
                            newRoot = newRoot.ReplaceNode(newRoot.GetCurrentNode(ctor), ctor.WithBody(
                                ctor.Body.WithStatements(SyntaxFactory.List<StatementSyntax>(new[] { assignmentStatement }.Concat(ctor.Body.Statements)))
                            ));

                            return Task.FromResult(document.WithSyntaxRoot(newRoot));
                        })
                );
            }
        }
 public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
 {
     var document = context.Document;
     if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
         return;
     var span = context.Span;
     if (!span.IsEmpty)
         return;
     var cancellationToken = context.CancellationToken;
     if (cancellationToken.IsCancellationRequested)
         return;
     var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     if (model.IsFromGeneratedCode(cancellationToken))
         return;
     var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
     var token = root.FindToken(span.Start);
     if (!token.IsKind(SyntaxKind.EqualsToken))
         return;
     var node = token.Parent as AssignmentExpressionSyntax;
     if (node == null)
         return;
     var assignment = CreateAssignment(node);
     if (assignment == null)
         return;
     assignment = assignment.WithAdditionalAnnotations(Formatter.Annotation);
     context.RegisterRefactoring(
         CodeActionFactory.Create(span, DiagnosticSeverity.Info, String.Format(GettextCatalog.GetString("To '{0}='"), node.Left.ToString()), document.WithSyntaxRoot(
         root.ReplaceNode((SyntaxNode)node, assignment)))
     );
 }
コード例 #16
0
		public async override Task ComputeRefactoringsAsync (CodeRefactoringContext context)
		{
			var document = context.Document;
			var span = context.Span;
			var cancellationToken = context.CancellationToken;

			var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait (false);
			if (model.IsFromGeneratedCode (cancellationToken))
				return;
			var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait (false);
			var token = root.FindToken(span.Start);

			var type = token.Parent as BaseTypeDeclarationSyntax;
			if (type == null)
				return;
			
			if (Path.GetFileNameWithoutExtension (document.FilePath) == type.Identifier.ToString ())
				return;
					
			string title;
			if (IsSingleType (root)) {
				title = String.Format (GettextCatalog.GetString ("Rename file to '{0}'"), Path.GetFileName (GetCorrectFileName (document, type)));
			} else {
				title = String.Format (GettextCatalog.GetString ("Move type to file '{0}'"), Path.GetFileName (GetCorrectFileName (document, type)));
			}
			context.RegisterRefactoring (new MyCodeAction (document, title, root, type));
		}
コード例 #17
0
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            var textSpan = context.Span;
            var cancellationToken = context.CancellationToken;

            var root = (SyntaxNode)await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(textSpan.Start);

            // Only trigger if the text span is within the 'if' keyword token of an if-else statement.

            if (token.Kind() != SyntaxKind.IfKeyword ||
                !token.Span.IntersectsWith(textSpan.Start) ||
                !token.Span.IntersectsWith(textSpan.End))
            {
                return;
            }

            var ifStatement = token.Parent as IfStatementSyntax;
            if (ifStatement == null || ifStatement.Else == null)
            {
                return;
            }

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

            ReturnStatementSyntax returnStatement;
            if (ReturnConditionalAnalyzer.TryGetNewReturnStatement(ifStatement, semanticModel, out returnStatement))
            {
                var action = new ConvertToConditionalCodeAction("Convert to conditional expression", (c) => Task.FromResult(ConvertToConditional(document, semanticModel, ifStatement, returnStatement, c)));
                context.RegisterRefactoring(action);
            }
        }
コード例 #18
0
        public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            var textSpan = context.Span;
            var cancellationToken = context.CancellationToken;

            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(textSpan.Start);
            if (token.Parent == null)
            {
                return;
            }

            var propertyDeclaration = token.Parent.FirstAncestorOrSelf<PropertyDeclarationSyntax>();

            // Refactor only properties with both a getter and a setter.
            if (propertyDeclaration == null ||
                !HasBothAccessors(propertyDeclaration) ||
                !propertyDeclaration.Identifier.Span.IntersectsWith(textSpan.Start))
            {
                return;
            }

            context.RegisterRefactoring(
                new ConvertToAutoPropertyCodeAction("Convert to auto property",
                                                    (c) => ConvertToAutoPropertyAsync(document, propertyDeclaration, c)));
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(span.Start);
            var boP = token.Parent as BinaryExpressionSyntax;
            if (boP == null || !boP.OperatorToken.Span.Contains(span))
                return;

            ExpressionSyntax flagsExpression, targetExpression;
            bool testFlagset;
            if (!AnalyzeComparisonWithNull(boP, out flagsExpression, out targetExpression, out testFlagset) && !AnalyzeComparisonWithFlags(boP, out flagsExpression, out targetExpression, out testFlagset))
                return;

            if (!testFlagset && !flagsExpression.DescendantNodesAndSelf().OfType<BinaryExpressionSyntax>().All(bop => bop.IsKind(SyntaxKind.BitwiseOrExpression)))
                return;
            if (testFlagset && !flagsExpression.DescendantNodesAndSelf().OfType<BinaryExpressionSyntax>().All(bop => bop.IsKind(SyntaxKind.BitwiseAndExpression)))
                return;

            context.RegisterRefactoring(
                CodeActionFactory.Create(token.Span, DiagnosticSeverity.Info, GettextCatalog.GetString("To 'Enum.HasFlag'"), t2 => Task.FromResult(PerformAction(document, root, boP, flagsExpression, targetExpression, testFlagset)))
            );
        }
 public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
 {
     var document = context.Document;
     if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
         return;
     var span = context.Span;
     if (!span.IsEmpty)
         return;
     var cancellationToken = context.CancellationToken;
     if (cancellationToken.IsCancellationRequested)
         return;
     var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     if (model.IsFromGeneratedCode(cancellationToken))
         return;
     var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
     var token = root.FindToken(span.Start);
     if (!token.IsKind(SyntaxKind.IntegerLiteralToken))
         return;
     var value = token.Value;
     if (!((value is int) || (value is long) || (value is short) || (value is sbyte) ||
         (value is uint) || (value is ulong) || (value is ushort) || (value is byte)))
     {
         return;
     }
     var literalValue = token.ToString();
     if (literalValue.StartsWith("&H", System.StringComparison.OrdinalIgnoreCase))
         return;
     context.RegisterRefactoring(CodeActionFactory.Create(token.Span, DiagnosticSeverity.Info, GettextCatalog.GetString("To hex"), t2 => Task.FromResult(PerformAction(document, root, token))));
 }
 public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
 {
     var document = context.Document;
     if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
         return;
     var span = context.Span;
     if (!span.IsEmpty)
         return;
     var cancellationToken = context.CancellationToken;
     if (cancellationToken.IsCancellationRequested)
         return;
     var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     if (model.IsFromGeneratedCode(cancellationToken))
         return;
     var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
     var node = root.FindToken(span.Start).Parent as InterpolatedStringTextSyntax;
     if (node == null)
         return;
     context.RegisterRefactoring(
         CodeActionFactory.Create(
             node.Span,
             DiagnosticSeverity.Info,
             GettextCatalog.GetString("To format string"),
             t =>
             {
                 var newRoot = root.ReplaceNode(node.Parent, CreateFormatString(node));
                 return Task.FromResult(document.WithSyntaxRoot(newRoot));
             }
         )
     );
 }
コード例 #22
0
		public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
		{
			var document = context.Document;
			var textSpan = context.Span;
			var cancellationToken = context.CancellationToken;
			if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
			{
				return;
			}
			var model = await document.GetSemanticModelAsync (cancellationToken).ConfigureAwait (false);
			if (model.IsFromGeneratedCode (cancellationToken))
				return;
			var root = await document.GetCSharpSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
			if (textSpan.Start >= root.FullSpan.Length)
				return;
			var token = root.FindToken(textSpan.Start);

			if (!token.Span.Contains(textSpan))
			{
				return;
			}

			var node = token.Parent.AncestorsAndSelf ().FirstOrDefault (n => n.IsKind(SyntaxKind.UsingDirective)  || n.IsParentKind(SyntaxKind.ExternAliasDirective));
			if (node == null)
			{
				return;
			}

			context.RegisterRefactoring(
				new DocumentChangeAction(node.Span, DiagnosticSeverity.Info,
				                         GettextCatalog.GetString ("Sort usings"),
				                         (t) => OrganizeImportsCommandHandler.SortUsingsAsync(document, t)));
		}
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(span.Start);

            if (!token.IsKind(SyntaxKind.AsKeyword))
                return;
            var node = token.Parent as BinaryExpressionSyntax;

            context.RegisterRefactoring(
                CodeActionFactory.Create(token.Span, DiagnosticSeverity.Info, GettextCatalog.GetString("Convert 'as' to cast"), t2 => Task.FromResult(PerformAction(document, root, node)))
            );
        }
 public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
 {
     var document = context.Document;
     if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
         return;
     var span = context.Span;
     if (!span.IsEmpty)
         return;
     var cancellationToken = context.CancellationToken;
     if (cancellationToken.IsCancellationRequested)
         return;
     var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     if (model.IsFromGeneratedCode(cancellationToken))
         return;
     var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
     var token = root.FindToken(span.Start);
     var castExpression = token.Parent.AncestorsAndSelf().OfType<CastExpressionSyntax>().FirstOrDefault();
     if (castExpression == null || castExpression.IsKind(SyntaxKind.TryCastExpression) || castExpression.Expression.Span.Contains(span))
         return;
     var type = model.GetTypeInfo(castExpression.Type).Type;
     if (type == null || type.IsValueType && !type.IsNullableType())
         return;
     context.RegisterRefactoring(
         CodeActionFactory.Create(
             token.Span,
             DiagnosticSeverity.Info,
             GettextCatalog.GetString("Convert cast to 'TryCast'"),
             t2 => Task.FromResult(PerformAction(document, root, castExpression))
         )
     );
 }
コード例 #25
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 parameter = node as ParameterSyntax;
			if ((parameter == null)
				|| !(node?.Parent?.Parent is ConstructorDeclarationSyntax)) // constructor parameters only
			{
				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 '" + parameterName + "'",
				ct => CreateFieldAsync(context, parameter, parameterName, parameterName, ct));

			context.RegisterRefactoring(action);
		}
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            var token = root.FindToken(span.Start);
            var parameter = token.Parent as ParameterSyntax;

            if (parameter != null)
            {
                var ctor = parameter.Parent.Parent as ConstructorDeclarationSyntax;
                if (ctor == null)
                    return;

                context.RegisterRefactoring(
                    CodeActionFactory.Create(
                        parameter.Span,
                        DiagnosticSeverity.Info,
                        GettextCatalog.GetString("Initialize auto-property from parameter"),
                        t2 =>
                        {
                            var propertyName = GetPropertyName(parameter.Identifier.ToString());
                            var accessorDeclList = new SyntaxList<AccessorDeclarationSyntax>().Add(SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))).Add(SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)));
                            var newProperty = SyntaxFactory.PropertyDeclaration(parameter.Type, propertyName)
                                .WithAccessorList(SyntaxFactory.AccessorList(accessorDeclList))
                                .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)))
                                .WithAdditionalAnnotations(Formatter.Annotation);

                            var assignmentStatement = SyntaxFactory.ExpressionStatement(
                                SyntaxFactory.AssignmentExpression(
                                    SyntaxKind.SimpleAssignmentExpression,
                                    propertyName != parameter.Identifier.ToString() ? (ExpressionSyntax)SyntaxFactory.IdentifierName(propertyName) : SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName(parameter.Identifier)),
                                    SyntaxFactory.IdentifierName(parameter.Identifier)
                                )
                            ).WithAdditionalAnnotations(Formatter.Annotation);

                            root = root.TrackNodes(ctor);
                            var newRoot = root.InsertNodesBefore(root.GetCurrentNode(ctor), new List<SyntaxNode>() {
                                newProperty
                            });
                            newRoot = newRoot.ReplaceNode(newRoot.GetCurrentNode(ctor), ctor.WithBody(
                                ctor.Body.WithStatements(SyntaxFactory.List<StatementSyntax>(new[] { assignmentStatement }.Concat(ctor.Body.Statements)))
                            ));

                            return Task.FromResult(document.WithSyntaxRoot(newRoot));
                        })
                );
            }
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var node = root.FindNode(span);
            if (!node.IsKind(SyntaxKind.IdentifierName))
                return;

            var nodeGrandparent = node.Parent?.Parent;
            if ((nodeGrandparent is EventDeclarationSyntax) || (nodeGrandparent is EventFieldDeclarationSyntax))
                return;

            if (node.Parent.IsKind(SyntaxKind.SimpleMemberAccessExpression))
                node = node.Parent;

            var info = model.GetTypeInfo(node, cancellationToken);
            var type = info.ConvertedType ?? info.Type;
            if (type == null)
                return;

            var invocationMethod = type.GetDelegateInvokeMethod();
            if (invocationMethod == null)
                return;

            context.RegisterRefactoring(
                CodeActionFactory.Create(
                    node.Span,
                    DiagnosticSeverity.Info,
                    GettextCatalog.GetString("To anonymous method"),
                    t2 =>
                    {
                        var expr = SyntaxFactory.InvocationExpression(
                            (ExpressionSyntax)node,
                            SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(invocationMethod.Parameters.Select(p => SyntaxFactory.Argument(SyntaxFactory.IdentifierName(p.Name)))))
                        );
                        var parameters = invocationMethod.Parameters.Select(p => CreateParameterSyntax(model, node, p)).ToList();
                        var stmt = invocationMethod.ReturnType.SpecialType == SpecialType.System_Void ? (StatementSyntax)SyntaxFactory.ExpressionStatement(expr) : SyntaxFactory.ReturnStatement(expr);
                        var ame = SyntaxFactory.AnonymousMethodExpression(
                            parameters.Count == 0 ? null : SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters)),
                            SyntaxFactory.Block(stmt)
                        );
                        var newRoot = root.ReplaceNode((SyntaxNode)node, ame.WithAdditionalAnnotations(Formatter.Annotation));
                        return Task.FromResult(document.WithSyntaxRoot(newRoot));
                    }
                )
            );
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var property = root.FindNode(span) as PropertyDeclarationSyntax;
            if (property == null || !property.Identifier.Span.Contains(span))
                return;

            if (property.AccessorList.Accessors.Any(b => b.Body != null)) //ignore properties with >=1 accessor body
                return;
            context.RegisterRefactoring(
                CodeActionFactory.Create(
                    property.Identifier.Span,
                    DiagnosticSeverity.Info,
                    GettextCatalog.GetString("To computed property"),
                    t2 =>
                    {
                        //string name = GetNameProposal(property.Identifier.ValueText, model, root);

                        //create our new property
                        //var fieldExpression = name == "value" ? 
                        //	(ExpressionSyntax)SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName("value")) : 
                        //	SyntaxFactory.IdentifierName(name);

                        var getBody = SyntaxFactory.Block(
                            SyntaxFactory.ThrowStatement(
                                SyntaxFactory.ObjectCreationExpression(
                                    SyntaxFactory.QualifiedName(
                                        SyntaxFactory.IdentifierName(@"System"),
                                        SyntaxFactory.IdentifierName(@"NotImplementedException")
                                    ).WithoutAnnotations(Simplifier.Annotation)
                                ).WithArgumentList(SyntaxFactory.ArgumentList())
                            )
                        );

                        var getter = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, getBody);
                        var setter = SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration, getBody);

                        //var newPropAnno = new SyntaxAnnotation();
                        var newProperty = property.WithAccessorList(SyntaxFactory.AccessorList(new SyntaxList<AccessorDeclarationSyntax>().Add(getter).Add(setter)));
                        newProperty = newProperty.WithAdditionalAnnotations(Formatter.Annotation);
                        var newRoot = root.ReplaceNode((SyntaxNode)property, newProperty);
                        return Task.FromResult(document.WithSyntaxRoot(newRoot));
                    })
            );
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var node = root.FindNode(span) as BinaryExpressionSyntax;
            //ignore nodes except string concat.
            if (node == null || !node.OperatorToken.IsKind(SyntaxKind.PlusToken))
                return;

            LiteralExpressionSyntax left;
            var leftBinaryExpr = node.Left as BinaryExpressionSyntax;
            //if there is something other than a string literal on the left, then just take the right node (e.g. a+b+c => a+(b+c))
            if (leftBinaryExpr != null && leftBinaryExpr.OperatorToken.IsKind(SyntaxKind.PlusToken))
                left = leftBinaryExpr.Right as LiteralExpressionSyntax;
            else
                left = node.Left as LiteralExpressionSyntax;

            var right = node.Right as LiteralExpressionSyntax;

            //ignore non-string literals
            if (left == null || right == null || !left.IsKind(SyntaxKind.StringLiteralExpression) || !right.IsKind(SyntaxKind.StringLiteralExpression))
                return;

            bool isLeftVerbatim = left.Token.IsVerbatimStringLiteral();
            bool isRightVerbatim = right.Token.IsVerbatimStringLiteral();
            if (isLeftVerbatim != isRightVerbatim)
                return;

            String newString = left.Token.ValueText + right.Token.ValueText;
            LiteralExpressionSyntax stringLit;

            if (isLeftVerbatim)
                stringLit = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("@\"" + newString + "\"", newString));
            else
                stringLit = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(newString));

            ExpressionSyntax exprNode;

            if (leftBinaryExpr == null)
                exprNode = stringLit;
            else
                exprNode = leftBinaryExpr.WithRight(stringLit);
            context.RegisterRefactoring(
                CodeActionFactory.Create(span, DiagnosticSeverity.Info, GettextCatalog.GetString("Join strings"), document.WithSyntaxRoot(root.ReplaceNode((SyntaxNode)node, exprNode as ExpressionSyntax)))
            );
        }
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var token = root.FindToken(span.Start);
            if (token.Parent == null)
                return;

            var bracketedList = token.Parent.AncestorsAndSelf().OfType<BracketedArgumentListSyntax>().FirstOrDefault();
            if (bracketedList == null)
                return;
            var elementAccess = bracketedList.AncestorsAndSelf().OfType<ElementAccessExpressionSyntax>().FirstOrDefault();
            if (elementAccess == null)
                return;
            var elementType = model.GetTypeInfo(elementAccess.Expression);
            var type = elementType.Type;
            if (type == null)
                return;
            if (!IsCollection(type as INamedTypeSymbol) && !type.AllInterfaces.Any(IsCollection))
                return;
            var argument = elementAccess.ArgumentList?.Arguments.FirstOrDefault();
            if (argument == null)
                return;
            context.RegisterRefactoring(
                CodeActionFactory.Create(
                    span,
                    DiagnosticSeverity.Info,
                    string.Format(GettextCatalog.GetString("Check 'if ({0}.Count > {1})'"), elementAccess.Expression, argument),
                    t2 =>
                    {
                        var parentStatement = elementAccess.Parent.AncestorsAndSelf().OfType<StatementSyntax>().FirstOrDefault();

                        var newParent = SyntaxFactory.IfStatement(
                            SyntaxFactory.BinaryExpression(
                                SyntaxKind.GreaterThanExpression,
                                SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, elementAccess.Expression, SyntaxFactory.IdentifierName("Count")),
                                argument.Expression
                            ),
                            parentStatement
                        );

                        return Task.FromResult(document.WithSyntaxRoot(root.ReplaceNode((SyntaxNode)parentStatement, newParent.WithAdditionalAnnotations(Formatter.Annotation))));
                    }
                )
            );
        }