コード例 #1
0
        void Init(IMember member)
        {
            FillDocumentation(GetBaseDocumentation(member));
            if (provider != null && !member.Location.IsEmpty && member.BodyRegion.End.Line > 0)
            {
                LineSegment start = data.Document.GetLine(member.Location.Line - 1);
                LineSegment end   = data.Document.GetLine(member.BodyRegion.End.Line - 1);
                if (start != null && end != null)
                {
                    var result = provider.ParseFile("class A {" + data.Document.GetTextAt(start.Offset, end.EndOffset - start.Offset) + "}");
                    result.AcceptVisitor(visitor, null);
                }
            }
            foreach (var macro in DocConfig.Instance.Macros)
            {
                tags.Add(macro.Key, macro.Value);
            }

            tags["DeclaringType"] = "<see cref=\"" + member.DeclaringType.DecoratedFullName + "\"/>";
            tags["ReturnType"]    = member.ReturnType != null ? "<see cref=\"" + member.ReturnType.ToInvariantString() + "\"/>" : "";
            tags["Member"]        = "<see cref=\"" + member.Name + "\"/>";

            switch (member.DeclaringType.ClassType)
            {
            case ClassType.Class:
                tags["DeclaringTypeKind"] = "class";
                break;

            case ClassType.Delegate:
                tags["DeclaringTypeKind"] = "delegate";
                break;

            case ClassType.Enum:
                tags["DeclaringTypeKind"] = "enum";
                break;

            case ClassType.Interface:
                tags["DeclaringTypeKind"] = "interface";
                break;

            case ClassType.Struct:
                tags["DeclaringTypeKind"] = "struct";
                break;
            }

            if (member.CanHaveParameters)
            {
                List <string> parameterNames = new List <string> (from p in member.Parameters select p.Name);
                tags["ParameterSentence"] = string.Join(" ", parameterNames.ToArray());
                StringBuilder paramList = new StringBuilder();
                for (int i = 0; i < parameterNames.Count; i++)
                {
                    if (i > 0)
                    {
                        if (i == parameterNames.Count - 1)
                        {
                            paramList.Append(" and ");
                        }
                        else
                        {
                            paramList.Append(", ");
                        }
                    }
                    paramList.Append(parameterNames[i]);
                }
                tags["ParameterList"] = paramList.ToString();
                for (int i = 0; i < member.Parameters.Count; i++)
                {
                    tags["Parameter" + i + ".Type"] = member.Parameters[i].ReturnType != null ? "<see cref=\"" + member.Parameters[i].ReturnType.ToInvariantString() + "\"/>" : "";
                    tags["Parameter" + i + ".Name"] = "<c>" + member.Parameters[i].Name + "</c>";
                }

                IProperty property = member as IProperty;
                if (property != null)
                {
                    if (property.HasGet && property.HasSet)
                    {
                        tags["AccessText"] = "Gets or sets";
                    }
                    else if (property.HasGet)
                    {
                        tags["AccessText"] = "Gets";
                    }
                    else
                    {
                        tags["AccessText"] = "Sets";
                    }
                }
            }

            SplitWords(member, member.Name);
        }
コード例 #2
0
        public override List <Change> PerformChanges(RefactoringOptions options, object properties)
        {
            List <Change> result = new List <Change> ();
            IType         type   = options.SelectedItem as IType;

            if (type == null)
            {
                return(result);
            }
            string newName = GetCorrectFileName(type);

            if (type.CompilationUnit.Types.Count == 1)
            {
                result.Add(new RenameFileChange(type.CompilationUnit.FileName, newName));
            }
            else
            {
                StringBuilder content = new StringBuilder();

                if (options.Dom.Project is DotNetProject)
                {
                    content.Append(StandardHeaderService.GetHeader(options.Dom.Project, newName, true) + Environment.NewLine);
                }

                INRefactoryASTProvider                     provider = options.GetASTProvider();
                Mono.TextEditor.TextEditorData             data     = options.GetTextEditorData();
                ICSharpCode.NRefactory.Ast.CompilationUnit unit     = provider.ParseFile(options.Document.Editor.Text);

                TypeFilterTransformer typeFilterTransformer = new TypeFilterTransformer((type is InstantiatedType) ? ((InstantiatedType)type).UninstantiatedType.DecoratedFullName : type.DecoratedFullName);
                unit.AcceptVisitor(typeFilterTransformer, null);
                if (typeFilterTransformer.TypeDeclaration == null)
                {
                    return(result);
                }
                Mono.TextEditor.Document generatedDocument = new Mono.TextEditor.Document();
                generatedDocument.Text = provider.OutputNode(options.Dom, unit);

                int startLine = 0;
                int minLine   = typeFilterTransformer.TypeDeclaration.StartLocation.Line;
                foreach (var attr in typeFilterTransformer.TypeDeclaration.Attributes)
                {
                    minLine = Math.Min(minLine, attr.StartLocation.Line);
                }
                for (int i = minLine - 1; i >= 1; i--)
                {
                    string lineText = data.Document.GetTextAt(data.Document.GetLine(i)).Trim();
                    if (string.IsNullOrEmpty(lineText))
                    {
                        continue;
                    }
                    if (lineText.StartsWith("///"))
                    {
                        startLine = i;
                    }
                    else
                    {
                        break;
                    }
                }

                int start;
                if (startLine >= 1)
                {
                    start = data.Document.GetLine(startLine).Offset;
                }
                else
                {
                    var startLocation = typeFilterTransformer.TypeDeclaration.StartLocation;
                    startLocation.Column = 1;
                    foreach (var attr in typeFilterTransformer.TypeDeclaration.Attributes)
                    {
                        if (attr.StartLocation < startLocation)
                        {
                            startLocation = attr.StartLocation;
                        }
                    }

                    start = data.Document.LocationToOffset(startLocation.Line, 1);
                }
                int length = data.Document.LocationToOffset(typeFilterTransformer.TypeDeclaration.EndLocation.Line, typeFilterTransformer.TypeDeclaration.EndLocation.Column) - start;

                ICSharpCode.NRefactory.Ast.CompilationUnit generatedCompilationUnit = provider.ParseFile(generatedDocument.Text);
                TypeSearchVisitor typeSearchVisitor = new TypeSearchVisitor();
                generatedCompilationUnit.AcceptVisitor(typeSearchVisitor, null);

                int genStart = generatedDocument.LocationToOffset(typeSearchVisitor.Types[0].StartLocation.Line, 0);
                foreach (var attr in typeSearchVisitor.Types[0].Attributes)
                {
                    genStart = Math.Min(genStart, generatedDocument.LocationToOffset(attr.StartLocation.Line, 0));
                }

                int genEnd = generatedDocument.LocationToOffset(typeSearchVisitor.Types[0].EndLocation.Line, typeSearchVisitor.Types[0].EndLocation.Column);
                ((Mono.TextEditor.IBuffer)generatedDocument).Replace(genStart, genEnd - genStart, data.Document.GetTextAt(start, length));
                content.Append(generatedDocument.Text);

                result.Add(new CreateFileChange(newName, content.ToString()));

                TextReplaceChange removeDeclaration = new TextReplaceChange();
                removeDeclaration.Description  = "Remove type declaration";
                removeDeclaration.FileName     = type.CompilationUnit.FileName;
                removeDeclaration.Offset       = start;
                removeDeclaration.RemovedChars = length;
                result.Add(removeDeclaration);
            }
            result.Add(new SaveProjectChange(options.Document.Project));

            return(result);
        }
コード例 #3
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            varCount       = 0;
            selectionStart = selectionEnd = -1;
            List <Change>          result   = new List <Change> ();
            IResolver              resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();

            if (resolver == null || provider == null)
            {
                return(result);
            }
            TextEditorData data = options.GetTextEditorData();

            if (data == null)
            {
                return(result);
            }
            ResolveResult resolveResult;
            LineSegment   lineSegment;

            ICSharpCode.NRefactory.Ast.CompilationUnit unit = provider.ParseFile(data.Document.Text);
            MonoDevelop.Refactoring.ExtractMethod.VariableLookupVisitor visitor = new MonoDevelop.Refactoring.ExtractMethod.VariableLookupVisitor(resolver, new DomLocation(data.Caret.Line, data.Caret.Column));
            if (options.ResolveResult == null)
            {
                LoggingService.LogError("resolve result == null:" + options.ResolveResult);
                return(result);
            }
            IMember callingMember = options.ResolveResult.CallingMember;

            if (callingMember != null)
            {
                visitor.MemberLocation = new Location(callingMember.Location.Column, callingMember.Location.Line);
            }
            unit.AcceptVisitor(visitor, null);

            if (data.IsSomethingSelected)
            {
                ExpressionResult expressionResult = new ExpressionResult(data.SelectedText.Trim());
                if (expressionResult.Expression.Contains(" ") || expressionResult.Expression.Contains("\t"))
                {
                    expressionResult.Expression = "(" + expressionResult.Expression + ")";
                }
                resolveResult = resolver.Resolve(expressionResult, new DomLocation(data.Caret.Line, data.Caret.Column));
                if (resolveResult == null)
                {
                    return(result);
                }
                IReturnType resolvedType = resolveResult.ResolvedType;
                if (resolvedType == null || string.IsNullOrEmpty(resolvedType.Name))
                {
                    resolvedType = DomReturnType.Object;
                }
                varName = CreateVariableName(resolvedType, visitor);
                TypeReference returnType;
                if (resolveResult.ResolvedType == null || string.IsNullOrEmpty(resolveResult.ResolvedType.Name))
                {
                    returnType           = new TypeReference("var");
                    returnType.IsKeyword = true;
                }
                else
                {
                    returnType = options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference();
                }
                options.ParseMember(resolveResult.CallingMember);

                TextReplaceChange insert = new TextReplaceChange();
                insert.FileName    = options.Document.FileName;
                insert.Description = GettextCatalog.GetString("Insert variable declaration");

                LocalVariableDeclaration varDecl = new LocalVariableDeclaration(returnType);
                varDecl.Variables.Add(new VariableDeclaration(varName, provider.ParseExpression(data.SelectedText)));

                GetContainingEmbeddedStatementVisitor blockVisitor = new GetContainingEmbeddedStatementVisitor();
                blockVisitor.LookupLocation = new Location(data.Caret.Column + 1, data.Caret.Line + 1);

                unit.AcceptVisitor(blockVisitor, null);

                StatementWithEmbeddedStatement containing = blockVisitor.ContainingStatement as StatementWithEmbeddedStatement;

                if (containing != null && !(containing.EmbeddedStatement is BlockStatement))
                {
                    insert.Offset       = data.Document.LocationToOffset(containing.StartLocation.Line - 1, containing.StartLocation.Column - 1);
                    lineSegment         = data.Document.GetLineByOffset(insert.Offset);
                    insert.RemovedChars = data.Document.LocationToOffset(containing.EndLocation.Line - 1, containing.EndLocation.Column - 1) - insert.Offset;
                    BlockStatement insertedBlock = new BlockStatement();
                    insertedBlock.AddChild(varDecl);
                    insertedBlock.AddChild(containing.EmbeddedStatement);

                    containing.EmbeddedStatement = insertedBlock;
                    insert.InsertedText          = provider.OutputNode(options.Dom, containing, options.GetWhitespaces(lineSegment.Offset)).TrimStart();
                    int offset, length;
                    if (SearchSubExpression(insert.InsertedText, data.SelectedText, 0, out offset, out length))
                    {
                        if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                        {
                            insert.InsertedText = insert.InsertedText.Substring(0, offset) + varName + insert.InsertedText.Substring(offset + length);
                            insertOffset        = insert.Offset + offset;
                        }
                    }
                }
                else if (blockVisitor.ContainingStatement is IfElseStatement)
                {
                    IfElseStatement ifElse = blockVisitor.ContainingStatement as IfElseStatement;

                    insert.Offset       = data.Document.LocationToOffset(blockVisitor.ContainingStatement.StartLocation.Line - 1, blockVisitor.ContainingStatement.StartLocation.Column - 1);
                    lineSegment         = data.Document.GetLineByOffset(insert.Offset);
                    insert.RemovedChars = data.Document.LocationToOffset(blockVisitor.ContainingStatement.EndLocation.Line - 1, blockVisitor.ContainingStatement.EndLocation.Column - 1) - insert.Offset;
                    BlockStatement insertedBlock = new BlockStatement();
                    insertedBlock.AddChild(varDecl);
                    if (blockVisitor.ContainsLocation(ifElse.TrueStatement[0]))
                    {
                        insertedBlock.AddChild(ifElse.TrueStatement[0]);
                        ifElse.TrueStatement[0] = insertedBlock;
                    }
                    else
                    {
                        insertedBlock.AddChild(ifElse.FalseStatement[0]);
                        ifElse.FalseStatement[0] = insertedBlock;
                    }

                    insert.InsertedText = provider.OutputNode(options.Dom, blockVisitor.ContainingStatement, options.GetWhitespaces(lineSegment.Offset));
                    int offset, length;

                    if (SearchSubExpression(insert.InsertedText, provider.OutputNode(options.Dom, insertedBlock), 0, out offset, out length))
                    {
                        if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                        {
                            if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                            {
                                insert.InsertedText = insert.InsertedText.Substring(0, offset) + varName + insert.InsertedText.Substring(offset + length);
                                insertOffset        = insert.Offset + offset;
                            }
                        }
                    }
                }
                else
                {
                    lineSegment         = data.Document.GetLine(data.Caret.Line);
                    insert.Offset       = lineSegment.Offset;
                    insert.InsertedText = options.GetWhitespaces(lineSegment.Offset) + provider.OutputNode(options.Dom, varDecl) + Environment.NewLine;
                    insertOffset        = insert.Offset + options.GetWhitespaces(lineSegment.Offset).Length + provider.OutputNode(options.Dom, varDecl.TypeReference).Length + " ".Length;

                    TextReplaceChange replace = new TextReplaceChange();
                    replace.FileName     = options.Document.FileName;
                    replace.Offset       = data.SelectionRange.Offset;
                    replace.RemovedChars = data.SelectionRange.Length;
                    replace.InsertedText = varName;
                    result.Add(replace);
                    replaceOffset = replace.Offset;
                    if (insert.Offset < replaceOffset)
                    {
                        replaceOffset += insert.InsertedText.Length - insert.RemovedChars;
                    }
                    varCount++;
                }
                result.Add(insert);
                varCount++;
                selectionStart = insert.Offset;
                return(result);
            }

            lineSegment = data.Document.GetLine(data.Caret.Line);
            string line = data.Document.GetTextAt(lineSegment);

            Expression expression = provider.ParseExpression(line);

            if (expression == null)
            {
                return(result);
            }

            resolveResult = resolver.Resolve(new ExpressionResult(line), new DomLocation(options.Document.TextEditor.CursorLine, options.Document.TextEditor.CursorColumn));

            if (resolveResult.ResolvedType != null && !string.IsNullOrEmpty(resolveResult.ResolvedType.FullName))
            {
                TextReplaceChange insert = new TextReplaceChange();
                insert.FileName    = options.Document.FileName;
                insert.Description = GettextCatalog.GetString("Insert variable declaration");
                insert.Offset      = lineSegment.Offset + options.GetWhitespaces(lineSegment.Offset).Length;
                varName            = CreateVariableName(resolveResult.ResolvedType, visitor);
                LocalVariableDeclaration varDecl = new LocalVariableDeclaration(options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference());
                varDecl.Variables.Add(new VariableDeclaration(varName, expression));
                insert.RemovedChars = expression.EndLocation.Column - 1;
                insert.InsertedText = provider.OutputNode(options.Dom, varDecl);
                insertOffset        = insert.Offset + provider.OutputNode(options.Dom, varDecl.TypeReference).Length + " ".Length;

                result.Add(insert);
                varCount++;

                int idx = 0;
                while (idx < insert.InsertedText.Length - varName.Length)
                {
                    if (insert.InsertedText.Substring(idx, varName.Length) == varName && (idx == 0 || insert.InsertedText[idx - 1] == ' ') && (idx == insert.InsertedText.Length - varName.Length - 1 || insert.InsertedText[idx + varName.Length] == ' '))
                    {
                        selectionStart = insert.Offset + idx;
                        selectionEnd   = selectionStart + varName.Length;
                        break;
                    }
                    idx++;
                }
            }

            return(result);
        }
コード例 #4
0
        ICSharpCode.NRefactory.Ast.INode Analyze(RefactoringOptions options, ExtractMethodParameters param, bool fillParameter)
        {
            IResolver resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();

            if (resolver == null || provider == null)
            {
                return(null);
            }

            string text = options.Document.TextEditor.GetText(options.Document.TextEditor.SelectionStartPosition, options.Document.TextEditor.SelectionEndPosition);

            TextEditorData data = options.GetTextEditorData();
            var            cu   = provider.ParseFile(data.Document.GetTextAt(0, data.SelectionRange.Offset) + "MethodCall ();" + data.Document.GetTextAt(data.SelectionRange.EndOffset, data.Document.Length - data.SelectionRange.EndOffset));

            if (cu == null || provider.LastErrors.Count > 0)
            {
                cu = provider.ParseFile(data.Document.GetTextAt(0, data.SelectionRange.Offset) + "MethodCall ()" + data.Document.GetTextAt(data.SelectionRange.EndOffset, data.Document.Length - data.SelectionRange.EndOffset));
            }

            if (cu == null || provider.LastErrors.Count > 0)
            {
                return(null);
            }

            param.Text = RemoveIndent(text, GetIndent(text)).TrimEnd('\n', '\r');

            ICSharpCode.NRefactory.Ast.INode result = provider.ParseText(text);
            if (cu == null || provider.LastErrors.Count > 0)
            {
                return(null);
            }

            VariableLookupVisitor visitor = new VariableLookupVisitor(resolver, param.Location);

            visitor.MemberLocation = new Location(param.DeclaringMember.Location.Column, param.DeclaringMember.Location.Line);
            if (fillParameter)
            {
                if (result != null)
                {
                    result.AcceptVisitor(visitor, null);
                }
                if (result is Expression)
                {
                    ResolveResult resolveResult = resolver.Resolve(new ExpressionResult(text), param.Location);
                    if (resolveResult != null)
                    {
                        param.ExpressionType = resolveResult.ResolvedType;
                    }
                }

                var startLocation = data.Document.OffsetToLocation(data.SelectionRange.Offset);
                var endLocation   = data.Document.OffsetToLocation(data.SelectionRange.EndOffset);
//				Console.WriteLine ("startLocation={0}, endLocation={1}", startLocation, endLocation);

                foreach (VariableDescriptor varDescr in visitor.VariableList.Where(v => !v.IsDefined && v.InitialValueUsed))
                {
                    if (startLocation <= varDescr.Location && varDescr.Location < endLocation)
                    {
                        continue;
                    }
//					Console.WriteLine (varDescr.Location);
//					Console.WriteLine (startLocation <= varDescr.Location);
//					Console.WriteLine (varDescr.Location < endLocation);
                    param.Parameters.Add(varDescr);
                }
                param.Variables = new List <VariableDescriptor> (visitor.Variables.Values);
                foreach (VariableDescriptor varDescr in visitor.VariableList.Where(v => !v.IsDefined && param.Variables.Contains(v)))
                {
                    if (param.Parameters.Contains(varDescr))
                    {
                        continue;
                    }
                    if (startLocation <= varDescr.Location && varDescr.Location < endLocation)
                    {
                        continue;
                    }
                    param.Parameters.Add(varDescr);
                }

                param.ReferencesMember = visitor.ReferencesMember;
                param.ChangedVariables = new HashSet <string> (visitor.Variables.Values.Where(v => v.GetsChanged).Select(v => v.Name));

                // analyze the variables outside of the selected text
                IMember member = param.DeclaringMember;

                int startOffset = data.Document.LocationToOffset(member.BodyRegion.Start.Line, member.BodyRegion.Start.Column);
                int endOffset   = data.Document.LocationToOffset(member.BodyRegion.End.Line, member.BodyRegion.End.Column);
                if (data.SelectionRange.Offset < startOffset || endOffset < data.SelectionRange.EndOffset)
                {
                    return(null);
                }
                text = data.Document.GetTextBetween(startOffset, data.SelectionRange.Offset) + data.Document.GetTextBetween(data.SelectionRange.EndOffset, endOffset);
                ICSharpCode.NRefactory.Ast.INode parsedNode = provider.ParseText(text);
                visitor                = new VariableLookupVisitor(resolver, param.Location);
                visitor.CutRegion      = new DomRegion(data.MainSelection.MinLine, data.MainSelection.MaxLine);
                visitor.MemberLocation = new Location(param.DeclaringMember.Location.Column, param.DeclaringMember.Location.Line);
                if (parsedNode != null)
                {
                    parsedNode.AcceptVisitor(visitor, null);
                }


                param.VariablesOutside = new Dictionary <string, VariableDescriptor> ();
                foreach (var pair in visitor.Variables)
                {
                    if (startLocation < pair.Value.Location || endLocation >= pair.Value.Location)
                    {
                        param.VariablesOutside.Add(pair.Key, pair.Value);
                    }
                }
                param.OutsideVariableList = new List <VariableDescriptor> ();
                foreach (var v in visitor.VariableList)
                {
                    if (startLocation < v.Location || endLocation >= v.Location)
                    {
                        param.OutsideVariableList.Add(v);
                    }
                }



                param.ChangedVariablesUsedOutside = new List <VariableDescriptor> (param.Variables.Where(v => v.GetsChanged && param.VariablesOutside.ContainsKey(v.Name)));
                param.OneChangedVariable          = result is BlockStatement;
                if (param.OneChangedVariable)
                {
                    param.OneChangedVariable = param.ChangedVariablesUsedOutside.Count == 1;
                }

                param.VariablesToGenerate = new List <VariableDescriptor> (param.ChangedVariablesUsedOutside.Where(v => v.IsDefined));
                foreach (VariableDescriptor var in param.VariablesToGenerate)
                {
                    param.Parameters.Add(var);
                }
                if (param.OneChangedVariable)
                {
                    param.VariablesToDefine = new List <VariableDescriptor> (param.Parameters.Where(var => !var.InitialValueUsed));
                    param.VariablesToDefine.ForEach(var => param.Parameters.Remove(var));
                }
                else
                {
                    param.VariablesToDefine = new List <VariableDescriptor> ();
                }
            }
            return(result);
        }
コード例 #5
0
            protected override IEnumerable <IBaseMember> GetValidMembers()
            {
                if (Options == null || Options.EnclosingType == null || Options.EnclosingMember == null || Options.Document == null)
                {
                    yield break;
                }
                var editor = Options.Document.Editor;

                if (editor == null)
                {
                    yield break;
                }
                INRefactoryASTProvider provider = Options.GetASTProvider();

                if (provider == null)
                {
                    yield break;
                }

                // add local variables
                LookupTableVisitor visitor  = new LookupTableVisitor(ICSharpCode.NRefactory.SupportedLanguage.CSharp);
                Location           location = new Location(editor.Caret.Line, editor.Caret.Column);
                var result = provider.ParseFile(editor.Text);

                result.AcceptVisitor(visitor, null);

                foreach (var pair in visitor.Variables)
                {
                    foreach (LocalLookupVariable varDescr in pair.Value)
                    {
                        if (varDescr.StartPos <= location && location <= varDescr.EndPos)
                        {
                            yield return(new LocalVariable(Options.EnclosingMember, varDescr.Name, varDescr.TypeRef.ConvertToReturnType(), DomRegion.Empty));
                        }
                    }
                }

                // add parameters
                if (Options.EnclosingMember.CanHaveParameters)
                {
                    foreach (IParameter param in Options.EnclosingMember.Parameters)
                    {
                        yield return(param);
                    }
                }

                // add type members
                foreach (IField field in Options.EnclosingType.Fields)
                {
                    if (field.IsSpecialName)
                    {
                        continue;
                    }
                    yield return(field);
                }

                foreach (IProperty property in Options.EnclosingType.Properties)
                {
                    if (property.IsSpecialName)
                    {
                        continue;
                    }
                    if (property.HasGet)
                    {
                        yield return(property);
                    }
                }
            }
コード例 #6
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            varCount       = 0;
            selectionStart = selectionEnd = -1;

            List <Change>          result   = new List <Change> ();
            IResolver              resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();
            TextEditorData         data     = options.GetTextEditorData();

            if (resolver == null || provider == null || data == null)
            {
                return(result);
            }

            DocumentLocation endPoint;

            if (data.IsSomethingSelected)
            {
                endPoint = data.MainSelection.Anchor < data.MainSelection.Lead ? data.MainSelection.Lead : data.MainSelection.Anchor;
            }
            else
            {
                endPoint = data.Caret.Location;
            }
            ResolveResult resolveResult;
            LineSegment   lineSegment;
            var           unit = provider.ParseFile(data.Document.Text);

            if (unit == null)
            {
                LoggingService.LogError("Declare local error: parese file == null");
                return(result);
            }
            var visitor = new VariableLookupVisitor(resolver, new DomLocation(endPoint.Line, endPoint.Column));

            if (options.ResolveResult == null)
            {
                LoggingService.LogError("Declare local error: resolve result == null");
                return(result);
            }
            IMember callingMember = options.ResolveResult.CallingMember;

            if (callingMember != null)
            {
                visitor.MemberLocation = new AstLocation(callingMember.Location.Column, callingMember.Location.Line);
            }
            unit.AcceptVisitor(visitor, null);

            ExpressionResult expressionResult = new ExpressionResult(data.SelectedText.Trim());

            if (expressionResult.Expression.Contains(" ") || expressionResult.Expression.Contains("\t"))
            {
                expressionResult.Expression = "(" + expressionResult.Expression + ")";
            }
            resolveResult = resolver.Resolve(expressionResult, new DomLocation(endPoint.Line, endPoint.Column));
            if (resolveResult == null)
            {
                return(result);
            }
            IReturnType resolvedType = GetResolvedType(options, resolveResult);

            AstType returnType;

            if (resolveResult.ResolvedType == null || string.IsNullOrEmpty(resolveResult.ResolvedType.Name))
            {
                returnType = new SimpleType("var");
            }
            else
            {
                returnType = options.ShortenTypeName(resolvedType).ConvertToTypeReference();
            }

            varName = CreateVariableName(resolvedType, visitor);
            options.ParseMember(resolveResult.CallingMember);

            // insert local variable declaration
            TextReplaceChange insert = new TextReplaceChange();

            insert.FileName    = options.Document.FileName;
            insert.Description = GettextCatalog.GetString("Insert variable declaration");

            var varDecl = new VariableDeclarationStatement(returnType, varName, provider.ParseExpression(data.SelectedText));

            var node = unit.GetNodeAt(endPoint.Line, endPoint.Column);

            var containing = node.Parent;

            while (!(containing.Parent is BlockStatement))
            {
                containing = containing.Parent;
            }

            if (containing is BlockStatement)
            {
                lineSegment = data.Document.GetLine(data.Caret.Line);
            }
            else
            {
                lineSegment = data.Document.GetLine(containing.StartLocation.Line);
            }
            insert.Offset       = lineSegment.Offset;
            insert.InsertedText = options.GetWhitespaces(lineSegment.Offset) + provider.OutputNode(options.Dom, varDecl);
            var insertOffset = insert.Offset + options.GetWhitespaces(lineSegment.Offset).Length + provider.OutputNode(options.Dom, varDecl.Type).Length + " ".Length;

            offsets.Add(insertOffset);
            result.Add(insert);
            varCount++;

            // replace main selection
            TextReplaceChange replace = new TextReplaceChange();

            replace.FileName     = options.Document.FileName;
            replace.Offset       = data.SelectionRange.Offset;
            replace.RemovedChars = data.SelectionRange.Length;
            replace.InsertedText = varName;
            result.Add(replace);
            int delta = insert.InsertedText.Length - insert.RemovedChars;

            offsets.Add(replace.Offset + delta);
            Console.WriteLine(replace.Offset);
            delta += varName.Length - replace.RemovedChars;
            varCount++;
            selectionStart = insert.Offset;

            if (replaceAll)
            {
                matches.Sort((x, y) => x.StartLocation.CompareTo(y.StartLocation));
                foreach (var match in matches)
                {
                    replace          = new TextReplaceChange();
                    replace.FileName = options.Document.FileName;
                    int start = data.LocationToOffset(match.StartLocation.Line, match.StartLocation.Column);
                    int end   = data.LocationToOffset(match.EndLocation.Line, match.EndLocation.Column);

                    replace.Offset       = start;
                    replace.RemovedChars = end - start;
                    replace.InsertedText = varName;
                    result.Add(replace);
                    offsets.Add(start + delta);
                    delta += varName.Length - replace.RemovedChars;
                }
            }
            return(result);
        }