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