public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			if (!context.IsSomethingSelected) {
				yield break;
			}
			var selected = new List<AstNode>(context.GetSelectedNodes());

			if (selected.Count != 1 || !(selected [0] is Expression)) {
				yield break;
			}

			var expr = selected [0] as Expression;
			if (expr is ArrayInitializerExpression) {
				var arr = (ArrayInitializerExpression)expr;
				if (arr.IsSingleElement) {
					expr = arr.Elements.First();
				} else {
					yield break;
				}
			}

			var visitor = new SearchNodeVisitior(expr);
			
			var node = context.GetNode <BlockStatement>();
			if (node != null) {
				node.AcceptVisitor(visitor);
			}

			yield return new CodeAction(context.TranslateString("Declare local variable"), script => {
				var resolveResult = context.Resolve(expr);
				var guessedType = resolveResult.Type;
				if (resolveResult is MethodGroupResolveResult) {
					guessedType = GetDelegateType(context, ((MethodGroupResolveResult)resolveResult).Methods.First(), expr);
				}
				var name = CreateMethodDeclarationAction.CreateBaseName(expr, guessedType);
				name = context.GetLocalNameProposal(name, expr.StartLocation);
				var type = context.UseExplicitTypes ? context.CreateShortType(guessedType) : new SimpleType("var");
				var varDecl = new VariableDeclarationStatement(type, name, expr.Clone());
				var replaceNode = visitor.Matches.First () as Expression;
				if (replaceNode.Parent is ExpressionStatement) {
					script.Replace(replaceNode.Parent, varDecl);
					script.Select(varDecl.Variables.First().NameToken);
				} else {
					var containing = replaceNode.Parent;
					while (!(containing.Parent is BlockStatement)) {
						containing = containing.Parent;
					}

					script.InsertBefore(containing, varDecl);
					var identifierExpression = new IdentifierExpression(name);
					script.Replace(replaceNode, identifierExpression);
					script.Link(varDecl.Variables.First().NameToken, identifierExpression);
				}
			}, expr);

			if (visitor.Matches.Count > 1) {
				yield return new CodeAction(string.Format(context.TranslateString("Declare local variable (replace '{0}' occurrences)"), visitor.Matches.Count), script => {
					var resolveResult = context.Resolve(expr);
					var guessedType = resolveResult.Type;
					if (resolveResult is MethodGroupResolveResult) {
						guessedType = GetDelegateType(context, ((MethodGroupResolveResult)resolveResult).Methods.First(), expr);
					}
					var linkedNodes = new List<AstNode>();
					var name = CreateMethodDeclarationAction.CreateBaseName(expr, guessedType);
					name = context.GetLocalNameProposal(name, expr.StartLocation);
					var type = context.UseExplicitTypes ? context.CreateShortType(guessedType) : new SimpleType("var");
					var varDecl = new VariableDeclarationStatement(type, name, expr.Clone());
					linkedNodes.Add(varDecl.Variables.First().NameToken);
					var first = visitor.Matches [0];
					if (first.Parent is ExpressionStatement) {
						script.Replace(first.Parent, varDecl);
					} else {
						var containing = first.Parent;
						while (!(containing.Parent is BlockStatement)) {
							containing = containing.Parent;
						}

						script.InsertBefore(containing, varDecl);
						var identifierExpression = new IdentifierExpression(name);
						linkedNodes.Add(identifierExpression);
						script.Replace(first, identifierExpression);
					}
					for (int i = 1; i < visitor.Matches.Count; i++) {
						var identifierExpression = new IdentifierExpression(name);
						linkedNodes.Add(identifierExpression);
						script.Replace(visitor.Matches [i], identifierExpression);
					}
					script.Link(linkedNodes.ToArray ());
				}, expr);
			}
		}
Example #2
0
        public override IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            if (!context.IsSomethingSelected)
            {
                yield break;
            }
            var selected = new List <AstNode>(context.GetSelectedNodes());

            if (selected.Count != 1 || !(selected [0] is Expression))
            {
                yield break;
            }

            var expr = selected [0] as Expression;

            if (expr is ArrayInitializerExpression)
            {
                var arr = (ArrayInitializerExpression)expr;
                if (arr.IsSingleElement)
                {
                    expr = arr.Elements.First();
                }
                else
                {
                    yield break;
                }
            }

            var visitor = new SearchNodeVisitior(expr);

            var node = context.GetNode <BlockStatement>();

            if (node != null)
            {
                node.AcceptVisitor(visitor);
            }

            yield return(new CodeAction(context.TranslateString("Declare local variable"), script => {
                var resolveResult = context.Resolve(expr);
                var guessedType = resolveResult.Type;
                if (resolveResult is MethodGroupResolveResult)
                {
                    guessedType = GetDelegateType(context, ((MethodGroupResolveResult)resolveResult).Methods.First(), expr);
                }
                var name = CreateMethodDeclarationAction.CreateBaseName(expr, guessedType);
                name = context.GetLocalNameProposal(name, expr.StartLocation);
                var type = context.UseExplicitTypes ? context.CreateShortType(guessedType) : new SimpleType("var");
                var varDecl = new VariableDeclarationStatement(type, name, expr.Clone());
                var replaceNode = visitor.Matches.First() as Expression;
                if (replaceNode.Parent is ExpressionStatement)
                {
                    script.Replace(replaceNode.Parent, varDecl);
                    script.Select(varDecl.Variables.First().NameToken);
                }
                else
                {
                    var containing = replaceNode.Parent;
                    while (!(containing.Parent is BlockStatement))
                    {
                        containing = containing.Parent;
                    }

                    script.InsertBefore(containing, varDecl);
                    var identifierExpression = new IdentifierExpression(name);
                    script.Replace(replaceNode, identifierExpression);
                    script.Link(varDecl.Variables.First().NameToken, identifierExpression);
                }
            }, expr));

            if (visitor.Matches.Count > 1)
            {
                yield return(new CodeAction(string.Format(context.TranslateString("Declare local variable (replace '{0}' occurrences)"), visitor.Matches.Count), script => {
                    var resolveResult = context.Resolve(expr);
                    var guessedType = resolveResult.Type;
                    if (resolveResult is MethodGroupResolveResult)
                    {
                        guessedType = GetDelegateType(context, ((MethodGroupResolveResult)resolveResult).Methods.First(), expr);
                    }
                    var linkedNodes = new List <AstNode>();
                    var name = CreateMethodDeclarationAction.CreateBaseName(expr, guessedType);
                    name = context.GetLocalNameProposal(name, expr.StartLocation);
                    var type = context.UseExplicitTypes ? context.CreateShortType(guessedType) : new SimpleType("var");
                    var varDecl = new VariableDeclarationStatement(type, name, expr.Clone());
                    linkedNodes.Add(varDecl.Variables.First().NameToken);
                    var first = visitor.Matches [0];
                    if (first.Parent is ExpressionStatement)
                    {
                        script.Replace(first.Parent, varDecl);
                    }
                    else
                    {
                        var containing = first.Parent;
                        while (!(containing.Parent is BlockStatement))
                        {
                            containing = containing.Parent;
                        }

                        script.InsertBefore(containing, varDecl);
                        var identifierExpression = new IdentifierExpression(name);
                        linkedNodes.Add(identifierExpression);
                        script.Replace(first, identifierExpression);
                    }
                    for (int i = 1; i < visitor.Matches.Count; i++)
                    {
                        var identifierExpression = new IdentifierExpression(name);
                        linkedNodes.Add(identifierExpression);
                        script.Replace(visitor.Matches [i], identifierExpression);
                    }
                    script.Link(linkedNodes.ToArray());
                }, expr));
            }
        }