public ExtractMethodParameters CreateParameters(RefactoringOptions options) { var buffer = options.Document.Editor; if (!buffer.IsSomethingSelected) { return(null); } ParsedDocument doc = options.ParseDocument(); if (doc == null || doc.CompilationUnit == null) { return(null); } IMember member = doc.CompilationUnit.GetMemberAt(buffer.Caret.Line, buffer.Caret.Column); if (member == null) { return(null); } ExtractMethodParameters param = new ExtractMethodParameters() { DeclaringMember = member, Location = new DomLocation(buffer.Caret.Line, buffer.Caret.Column) }; Analyze(options, param, true); return(param); }
public ExtractMethodParameters CreateParameters(RefactoringOptions options) { var buffer = options.Document.TextEditor; if (buffer.SelectionStartPosition - buffer.SelectionEndPosition == 0) { return(null); } ParsedDocument doc = options.ParseDocument(); if (doc == null || doc.CompilationUnit == null) { return(null); } int line, column; buffer.GetLineColumnFromPosition(buffer.CursorPosition, out line, out column); IMember member = doc.CompilationUnit.GetMemberAt(line, column); if (member == null) { return(null); } ExtractMethodParameters param = new ExtractMethodParameters() { DeclaringMember = member, Location = new DomLocation(line, column) }; Analyze(options, param, true); return(param); }
public override void Run(RefactoringOptions options) { ExtractMethodParameters param = CreateParameters(options); if (param == null) { return; } if (!Analyze(options, param, false)) { MessageService.ShowError(GettextCatalog.GetString("Invalid selection for method extraction.")); return; } MessageService.ShowCustomDialog(new ExtractMethodDialog(options, this, param)); }
static DomMethod GenerateMethodStub(RefactoringOptions options, ExtractMethodParameters param) { DomMethod result = new DomMethod(); result.Name = param.Name; result.ReturnType = param.ExpressionType ?? DomReturnType.Void; result.Modifiers = param.Modifiers; if (!param.ReferencesMember) { result.Modifiers |= Modifiers.Static; } if (param.Parameters == null) { return(result); } foreach (var p in param.Parameters) { if (param.OneChangedVariable && p.UsedAfterCutRegion && !p.UsedInCutRegion) { continue; } var newParameter = new DomParameter(); newParameter.Name = p.Name; newParameter.ReturnType = p.ReturnType; if (!param.OneChangedVariable) { if (!p.IsDefinedInsideCutRegion && p.IsChangedInsideCutRegion) { newParameter.ParameterModifiers = p.UsedBeforeCutRegion ? ParameterModifiers.Ref : ParameterModifiers.Out; } } result.Add(newParameter); } return(result); }
public ExtractMethodParameters CreateParameters (RefactoringOptions options) { var buffer = options.Document.TextEditor; if (buffer.SelectionStartPosition - buffer.SelectionEndPosition == 0) return null; ParsedDocument doc = options.ParseDocument (); if (doc == null || doc.CompilationUnit == null) return null; int line, column; buffer.GetLineColumnFromPosition (buffer.CursorPosition, out line, out column); IMember member = doc.CompilationUnit.GetMemberAt (line, column); if (member == null) return null; ExtractMethodParameters param = new ExtractMethodParameters () { DeclaringMember = member, Location = new DomLocation (line, column) }; Analyze (options, param, true); return param; }
static string GenerateMethodDeclaration (RefactoringOptions options, ExtractMethodParameters param) { StringBuilder methodText = new StringBuilder (); string indent = options.GetIndent (param.DeclaringMember); if (param.InsertionPoint != null) { switch (param.InsertionPoint.LineBefore) { case NewLineInsertion.Eol: methodText.AppendLine (); break; case NewLineInsertion.BlankLine: methodText.Append (indent); methodText.AppendLine (); break; } } else { methodText.AppendLine (); methodText.Append (indent); methodText.AppendLine (); } var codeGenerator = new CSharpCodeGenerator () { UseSpaceIndent = options.Document.Editor.Options.TabsToSpaces, EolMarker = options.Document.Editor.EolMarker, TabSize = options.Document.Editor.Options.TabSize }; var newMethod = GenerateMethodStub (options, param); IType callingType = null; var cu = options.Document.CompilationUnit; if (cu != null) callingType = newMethod.DeclaringType = options.Document.CompilationUnit.GetTypeAt (options.Document.Editor.Caret.Line, options.Document.Editor.Caret.Column); var createdMethod = codeGenerator.CreateMemberImplementation (callingType, newMethod, false); if (param.GenerateComment && DocGenerator.Instance != null) methodText.AppendLine (DocGenerator.Instance.GenerateDocumentation (newMethod, indent + "/// ")); string code = createdMethod.Code; int idx1 = code.LastIndexOf ("throw"); int idx2 = code.LastIndexOf (";"); methodText.Append (code.Substring (0, idx1)); if (param.Nodes != null && (param.Nodes.Count == 1 && param.Nodes[0].NodeType == NodeType.Expression)) { methodText.Append ("return "); methodText.Append (param.Text.Trim ()); methodText.Append (";"); } else { StringBuilder text = new StringBuilder (); if (param.OneChangedVariable) { var par = param.Variables.First (p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion); if (!par.UsedInCutRegion) { text.Append (new CSharpAmbience ().GetString (par.ReturnType, OutputFlags.ClassBrowserEntries)); text.Append (" "); text.Append (par.Name); text.AppendLine (";"); } } text.Append (param.Text); if (param.OneChangedVariable) { text.AppendLine (); text.Append ("return "); text.Append (param.Variables.First (p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion).Name); text.Append (";"); } methodText.Append (AddIndent (text.ToString (), indent + "\t")); } methodText.Append (code.Substring (idx2 + 1)); if (param.InsertionPoint != null) { switch (param.InsertionPoint.LineAfter) { case NewLineInsertion.Eol: methodText.AppendLine (); break; case NewLineInsertion.BlankLine: methodText.AppendLine (); methodText.Append (indent); methodText.AppendLine (); break; case NewLineInsertion.None: methodText.AppendLine (); break; } } else { methodText.AppendLine (); methodText.Append (indent); methodText.AppendLine (); } return methodText.ToString (); }
static DomMethod GenerateMethodStub (RefactoringOptions options, ExtractMethodParameters param) { DomMethod result = new DomMethod (); result.Name = param.Name; result.ReturnType = param.ExpressionType ?? DomReturnType.Void; result.Modifiers = param.Modifiers; if (!param.ReferencesMember) result.Modifiers |= MonoDevelop.Projects.Dom.Modifiers.Static; if (param.Parameters == null) return result; foreach (var p in param.Parameters) { if (param.OneChangedVariable && p.UsedAfterCutRegion && !p.UsedInCutRegion) continue; var newParameter = new DomParameter (); newParameter.Name = p.Name; newParameter.ReturnType = p.ReturnType; if (!param.OneChangedVariable) { if (!p.IsDefinedInsideCutRegion && p.IsChangedInsideCutRegion) { newParameter.ParameterModifiers = p.UsedBeforeCutRegion ? ParameterModifiers.Ref : ParameterModifiers.Out; } } result.Add (newParameter); } return result; }
static string GenerateMethodCall (RefactoringOptions options, ExtractMethodParameters param) { // var data = options.GetTextEditorData (); StringBuilder sb = new StringBuilder (); /* LineSegment line = data.Document.GetLine (Math.Max (0, data.Document.OffsetToLineNumber (data.SelectionRange.Offset) - 1)); if (param.VariablesToGenerate != null && param.VariablesToGenerate.Count > 0) { string indent = options.GetWhitespaces (line.Offset); sb.Append (Environment.NewLine + indent); foreach (VariableDescriptor var in param.VariablesToGenerate) { var returnType = options.ShortenTypeName (var.ReturnType); sb.Append (returnType.ToInvariantString ()); sb.Append (" "); sb.Append (var.Name); sb.AppendLine (";"); sb.Append (indent); } }*/ if (param.OneChangedVariable) { var resultVariable = param.Variables.First (p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion); if (resultVariable.IsDefinedInsideCutRegion) { var s = resultVariable.Declaration.Type.StartLocation; var e = resultVariable.Declaration.Type.EndLocation; sb.Append (options.Document.Editor.GetTextBetween (s.Line, s.Column, e.Line, e.Column) + " "); } sb.Append (resultVariable.Name); sb.Append (" = "); } sb.Append (param.Name); sb.Append (" "); // TODO: respect formatting sb.Append ("("); bool first = true; foreach (VariableDescriptor var in param.Parameters) { if (param.OneChangedVariable && var.UsedAfterCutRegion && !var.UsedInCutRegion) continue; if (first) { first = false; } else { sb.Append (", "); // TODO: respect formatting } if (!param.OneChangedVariable) { if (!var.IsDefinedInsideCutRegion && var.IsChangedInsideCutRegion) { sb.Append (var.UsedBeforeCutRegion ? "ref " : "out "); } } sb.Append (var.Name); } sb.Append (")"); if (param.Nodes != null && (param.Nodes.Count > 1 || param.Nodes.Count == 1 && param.Nodes[0].NodeType != NodeType.Expression)) sb.Append (";"); return sb.ToString (); }
bool Analyze (RefactoringOptions options, ExtractMethodParameters param, bool fillParameter) { var data = options.GetTextEditorData (); var parser = new CSharpParser (); var unit = parser.Parse (data); var resolver = options.GetResolver (); if (unit == null) return false; var selectionRange = data.SelectionRange; var startOffset = selectionRange.Offset; while (startOffset + 1 < data.Length && char.IsWhiteSpace (data.GetCharAt (startOffset + 1))) startOffset++; var endOffset = selectionRange.EndOffset; while (startOffset < endOffset && endOffset - 1 > 0 && char.IsWhiteSpace (data.GetCharAt (endOffset - 1))) endOffset--; if (startOffset >= endOffset) return false; var endLocation = data.OffsetToLocation (endOffset); var startLocation = data.OffsetToLocation (startOffset); param.StartOffset = startOffset; param.EndOffset = endOffset; param.Nodes = new List<AstNode> (unit.GetNodesBetween (startLocation.Line, startLocation.Column, endLocation.Line, endLocation.Column)); string text = options.Document.Editor.GetTextBetween (startLocation, endLocation); param.Text = RemoveIndent (text, GetIndent (data.GetTextBetween (data.GetLine (startLocation.Line).Offset, data.GetLine (endLocation.Line).EndOffset))).TrimEnd ('\n', '\r'); VariableLookupVisitor visitor = new VariableLookupVisitor (resolver, param.Location); visitor.MemberLocation = param.DeclaringMember.Location; visitor.CutRegion = new DomRegion (startLocation.Line, startLocation.Column, endLocation.Line, endLocation.Column); if (fillParameter) { unit.AcceptVisitor (visitor, null); if (param.Nodes != null && (param.Nodes.Count == 1 && param.Nodes [0].NodeType == NodeType.Expression)) { ResolveResult resolveResult = resolver.Resolve (new ExpressionResult ("(" + text + ")"), param.Location); if (resolveResult != null && resolveResult.ResolvedType != null) param.ExpressionType = resolveResult.ResolvedType; } foreach (VariableDescriptor varDescr in visitor.VariableList.Where (v => !v.IsDefinedInsideCutRegion && (v.UsedInCutRegion || v.IsChangedInsideCutRegion || v.UsedAfterCutRegion && v.IsDefinedInsideCutRegion))) { param.Parameters.Add (varDescr); } param.Variables = new List<VariableDescriptor> (visitor.Variables.Values); param.ReferencesMember = visitor.ReferencesMember; param.OneChangedVariable = param.Variables.Count (p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion) == 1; if (param.OneChangedVariable) param.ExpressionType = param.Variables.First (p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion).ReturnType; /* 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.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 bodyStartOffset = data.Document.LocationToOffset (member.BodyRegion.Start.Line, member.BodyRegion.Start.Column); int bodyEndOffset = data.Document.LocationToOffset (member.BodyRegion.End.Line, member.BodyRegion.End.Column); if (startOffset < bodyStartOffset || bodyEndOffset < endOffset) return false; text = data.Document.GetTextBetween (bodyStartOffset, startOffset) + data.Document.GetTextBetween (endOffset, bodyEndOffset); // ICSharpCode.OldNRefactory.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 = param.Nodes.Count == 1 && param.Nodes[0] 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 true; }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { List <Change> result = new List <Change> (); ExtractMethodParameters param = (ExtractMethodParameters)prop; var data = options.GetTextEditorData(); // IResolver resolver = options.GetResolver (); TextReplaceChange replacement = new TextReplaceChange(); replacement.Description = string.Format(GettextCatalog.GetString("Substitute selected statement(s) with call to {0}"), param.Name); replacement.FileName = options.Document.FileName; replacement.Offset = param.StartOffset; replacement.RemovedChars = param.EndOffset - param.StartOffset; replacement.MoveCaretToReplace = true; replacement.InsertedText = GenerateMethodCall(options, param); result.Add(replacement); TextReplaceChange insertNewMethod = new TextReplaceChange(); insertNewMethod.FileName = options.Document.FileName; insertNewMethod.Description = string.Format(GettextCatalog.GetString("Create new method {0} from selected statement(s)"), param.Name); var insertionPoint = param.InsertionPoint; if (insertionPoint == null) { var points = CodeGenerationService.GetInsertionPoints(options.Document, param.DeclaringMember.DeclaringType); insertionPoint = points.LastOrDefault(p => p.Location.Line < param.DeclaringMember.Location.Line); if (insertionPoint == null) { insertionPoint = points.FirstOrDefault(); } } insertNewMethod.RemovedChars = 0; //insertionPoint.LineBefore == NewLineInsertion.Eol ? 0 : insertionPoint.Location.Column - 1; insertNewMethod.Offset = data.Document.LocationToOffset(insertionPoint.Location) - insertNewMethod.RemovedChars; insertNewMethod.InsertedText = GenerateMethodDeclaration(options, param); result.Add(insertNewMethod); /* * * ExtractMethodAstTransformer transformer = new ExtractMethodAstTransformer (param.VariablesToGenerate); * node.AcceptVisitor (transformer, null); * if (!param.OneChangedVariable && node is Expression) { * ResolveResult resolveResult = resolver.Resolve (new ExpressionResult ("(" + provider.OutputNode (options.Dom, node) + ")"), new DomLocation (options.Document.Editor.Caret.Line, options.Document.Editor.Caret.Column)); * if (resolveResult.ResolvedType != null) * returnType = options.ShortenTypeName (resolveResult.ResolvedType).ConvertToTypeReference (); * } * * MethodDeclaration methodDecl = new MethodDeclaration (); * methodDecl.Name = param.Name; * methodDecl.Modifier = param.Modifiers; * methodDecl.TypeReference = returnType; * * * if (node is BlockStatement) { * methodDecl.Body = new BlockStatement (); * methodDecl.Body.AddChild (new EmptyStatement ()); * if (param.OneChangedVariable) * methodDecl.Body.AddChild (new ReturnStatement (new IdentifierExpression (param.ChangedVariables.First ()))); * } else if (node is Expression) { * methodDecl.Body = new BlockStatement (); * methodDecl.Body.AddChild (new ReturnStatement (node as Expression)); * } * * foreach (VariableDescriptor var in param.VariablesToDefine) { * BlockStatement block = methodDecl.Body; * LocalVariableDeclaration varDecl = new LocalVariableDeclaration (options.ShortenTypeName (var.ReturnType).ConvertToTypeReference ()); * varDecl.Variables.Add (new VariableDeclaration (var.Name)); * block.Children.Insert (0, varDecl); * } * * * * string indent = options.GetIndent (param.DeclaringMember); * StringBuilder methodText = new StringBuilder (); * switch (param.InsertionPoint.LineBefore) { * case NewLineInsertion.Eol: * methodText.AppendLine (); * break; * case NewLineInsertion.BlankLine: * methodText.Append (indent); * methodText.AppendLine (); * break; * } * if (param.GenerateComment) { * methodText.Append (indent); * methodText.AppendLine ("/// <summary>"); * methodText.Append (indent); * methodText.AppendLine ("/// TODO: write a comment."); * methodText.Append (indent); * methodText.AppendLine ("/// </summary>"); * Ambience ambience = AmbienceService.GetAmbienceForFile (options.Document.FileName); * foreach (ParameterDeclarationExpression pde in methodDecl.Parameters) { * methodText.Append (indent); * methodText.Append ("/// <param name=\""); * methodText.Append (pde.ParameterName); * methodText.Append ("\"> A "); * methodText.Append (ambience.GetString (pde.TypeReference.ConvertToReturnType (), OutputFlags.IncludeGenerics | OutputFlags.UseFullName)); * methodText.Append (" </param>"); * methodText.AppendLine (); * } * if (methodDecl.TypeReference.Type != "System.Void") { * methodText.Append (indent); * methodText.AppendLine ("/// <returns>"); * methodText.Append (indent); * methodText.Append ("/// A "); * methodText.AppendLine (ambience.GetString (methodDecl.TypeReference.ConvertToReturnType (), OutputFlags.IncludeGenerics | OutputFlags.UseFullName)); * methodText.Append (indent); * methodText.AppendLine ("/// </returns>"); * } * } * * methodText.Append (indent); * * if (node is BlockStatement) { * string text = provider.OutputNode (options.Dom, methodDecl, indent).Trim (); * int emptyStatementMarker = text.LastIndexOf (';'); * if (param.OneChangedVariable) * emptyStatementMarker = text.LastIndexOf (';', emptyStatementMarker - 1); * StringBuilder sb = new StringBuilder (); * sb.Append (text.Substring (0, emptyStatementMarker)); * sb.Append (AddIndent (param.Text, indent + "\t")); * sb.Append (text.Substring (emptyStatementMarker + 1)); * * methodText.Append (sb.ToString ()); * } else { * methodText.Append (provider.OutputNode (options.Dom, methodDecl, options.GetIndent (param.DeclaringMember)).Trim ()); * } * */ 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); }
static string GenerateMethodCall(RefactoringOptions options, ExtractMethodParameters param) { // var data = options.GetTextEditorData (); StringBuilder sb = new StringBuilder(); /* LineSegment line = data.Document.GetLine (Math.Max (0, data.Document.OffsetToLineNumber (data.SelectionRange.Offset) - 1)); * if (param.VariablesToGenerate != null && param.VariablesToGenerate.Count > 0) { * string indent = options.GetWhitespaces (line.Offset); * sb.Append (Environment.NewLine + indent); * foreach (VariableDescriptor var in param.VariablesToGenerate) { * var returnType = options.ShortenTypeName (var.ReturnType); * sb.Append (returnType.ToInvariantString ()); * sb.Append (" "); * sb.Append (var.Name); * sb.AppendLine (";"); * sb.Append (indent); * } * }*/ if (param.OneChangedVariable) { var resultVariable = param.Variables.First(p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion); if (resultVariable.IsDefinedInsideCutRegion) { var s = resultVariable.Declaration.Type.StartLocation; var e = resultVariable.Declaration.Type.EndLocation; sb.Append(options.Document.Editor.GetTextBetween(s.Line, s.Column, e.Line, e.Column) + " "); } sb.Append(resultVariable.Name); sb.Append(" = "); } sb.Append(param.Name); sb.Append(" "); // TODO: respect formatting sb.Append("("); bool first = true; foreach (VariableDescriptor var in param.Parameters) { if (param.OneChangedVariable && var.UsedAfterCutRegion && !var.UsedInCutRegion) { continue; } if (first) { first = false; } else { sb.Append(", "); // TODO: respect formatting } if (!param.OneChangedVariable) { if (!var.IsDefinedInsideCutRegion && var.IsChangedInsideCutRegion) { sb.Append(var.UsedBeforeCutRegion ? "ref " : "out "); } } sb.Append(var.Name); } sb.Append(")"); if (param.Nodes != null && (param.Nodes.Count > 1 || param.Nodes.Count == 1 && param.Nodes[0].NodeType != NodeType.Expression)) { sb.Append(";"); } return(sb.ToString()); }
bool Analyze(RefactoringOptions options, ExtractMethodParameters param, bool fillParameter) { var data = options.GetTextEditorData(); var parser = new CSharpParser(); var unit = parser.Parse(data); var resolver = options.GetResolver(); if (unit == null) { return(false); } var selectionRange = data.SelectionRange; var startOffset = selectionRange.Offset; while (startOffset + 1 < data.Length && char.IsWhiteSpace(data.GetCharAt(startOffset + 1))) { startOffset++; } var endOffset = selectionRange.EndOffset; while (startOffset < endOffset && endOffset - 1 > 0 && char.IsWhiteSpace(data.GetCharAt(endOffset - 1))) { endOffset--; } if (startOffset >= endOffset) { return(false); } var endLocation = data.OffsetToLocation(endOffset); var startLocation = data.OffsetToLocation(startOffset); param.StartOffset = startOffset; param.EndOffset = endOffset; param.Nodes = new List <AstNode> (unit.GetNodesBetween(startLocation.Line, startLocation.Column, endLocation.Line, endLocation.Column)); string text = options.Document.Editor.GetTextBetween(startLocation, endLocation); param.Text = RemoveIndent(text, GetIndent(data.GetTextBetween(data.GetLine(startLocation.Line).Offset, data.GetLine(endLocation.Line).EndOffset))).TrimEnd('\n', '\r'); VariableLookupVisitor visitor = new VariableLookupVisitor(resolver, param.Location); visitor.MemberLocation = param.DeclaringMember.Location; visitor.CutRegion = new DomRegion(startLocation.Line, startLocation.Column, endLocation.Line, endLocation.Column); if (fillParameter) { unit.AcceptVisitor(visitor, null); if (param.Nodes != null && (param.Nodes.Count == 1 && param.Nodes [0].NodeType == NodeType.Expression)) { ResolveResult resolveResult = resolver.Resolve(new ExpressionResult("(" + text + ")"), param.Location); if (resolveResult != null && resolveResult.ResolvedType != null) { param.ExpressionType = resolveResult.ResolvedType; } } foreach (VariableDescriptor varDescr in visitor.VariableList.Where(v => !v.IsDefinedInsideCutRegion && (v.UsedInCutRegion || v.IsChangedInsideCutRegion || v.UsedAfterCutRegion && v.IsDefinedInsideCutRegion))) { param.Parameters.Add(varDescr); } param.Variables = new List <VariableDescriptor> (visitor.Variables.Values); param.ReferencesMember = visitor.ReferencesMember; param.OneChangedVariable = param.Variables.Count(p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion) == 1; if (param.OneChangedVariable) { param.ExpressionType = param.Variables.First(p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion).ReturnType; } /* * 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.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 bodyStartOffset = data.Document.LocationToOffset(member.BodyRegion.Start.Line, member.BodyRegion.Start.Column); int bodyEndOffset = data.Document.LocationToOffset(member.BodyRegion.End.Line, member.BodyRegion.End.Column); if (startOffset < bodyStartOffset || bodyEndOffset < endOffset) { return(false); } text = data.Document.GetTextBetween(bodyStartOffset, startOffset) + data.Document.GetTextBetween(endOffset, bodyEndOffset); // 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 = param.Nodes.Count == 1 && param.Nodes[0] 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(true); }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { List <Change> result = new List <Change> (); ExtractMethodParameters param = (ExtractMethodParameters)prop; TextEditorData data = options.GetTextEditorData(); INRefactoryASTProvider provider = options.GetASTProvider(); IResolver resolver = options.GetResolver(); ICSharpCode.NRefactory.Ast.INode node = Analyze(options, param, false); if (param.VariablesToGenerate.Count > 0) { TextReplaceChange varGen = new TextReplaceChange(); varGen.Description = GettextCatalog.GetString("Generate some temporary variables"); varGen.FileName = options.Document.FileName; LineSegment line = data.Document.GetLine(Math.Max(0, data.Document.OffsetToLineNumber(data.SelectionRange.Offset) - 1)); varGen.Offset = line.Offset + line.EditableLength; varGen.InsertedText = Environment.NewLine + options.GetWhitespaces(line.Offset); foreach (VariableDescriptor var in param.VariablesToGenerate) { TypeReference tr = options.ShortenTypeName(var.ReturnType).ConvertToTypeReference(); varGen.InsertedText += provider.OutputNode(options.Dom, new LocalVariableDeclaration(new VariableDeclaration(var.Name, null, tr))).Trim(); } result.Add(varGen); } InvocationExpression invocation = new InvocationExpression(new IdentifierExpression(param.Name)); foreach (VariableDescriptor var in param.Parameters) { if (!param.OneChangedVariable && param.ChangedVariables.Contains(var.Name)) { FieldDirection fieldDirection = FieldDirection.Ref; VariableDescriptor outsideVar = null; if (param.VariablesOutside.TryGetValue(var.Name, out outsideVar) && (var.GetsAssigned || param.VariablesToGenerate.Where(v => v.Name == var.Name).Any())) { if (!outsideVar.GetsAssigned) { fieldDirection = FieldDirection.Out; } } invocation.Arguments.Add(new DirectionExpression(fieldDirection, new IdentifierExpression(var.Name))); } else { invocation.Arguments.Add(new IdentifierExpression(var.Name)); } } // string mimeType = DesktopService.GetMimeTypeForUri (options.Document.FileName); TypeReference returnType = new TypeReference("System.Void", true); ICSharpCode.NRefactory.Ast.INode outputNode; if (param.OneChangedVariable) { string name = param.ChangedVariables.First(); returnType = options.ShortenTypeName(param.Variables.Find(v => v.Name == name).ReturnType).ConvertToTypeReference(); if (param.OutsideVariableList.Any(v => v.Name == name && !v.IsDefined)) { LocalVariableDeclaration varDecl = new LocalVariableDeclaration(returnType); varDecl.Variables.Add(new VariableDeclaration(name, invocation)); outputNode = varDecl; } else { outputNode = new ExpressionStatement(new AssignmentExpression(new IdentifierExpression(name), ICSharpCode.NRefactory.Ast.AssignmentOperatorType.Assign, invocation)); } } else { outputNode = node is BlockStatement ? (ICSharpCode.NRefactory.Ast.INode) new ExpressionStatement(invocation) : invocation; } TextReplaceChange replacement = new TextReplaceChange(); replacement.Description = string.Format(GettextCatalog.GetString("Substitute selected statement(s) with call to {0}"), param.Name); replacement.FileName = options.Document.FileName; replacement.Offset = options.Document.TextEditor.SelectionStartPosition; replacement.RemovedChars = options.Document.TextEditor.SelectionEndPosition - options.Document.TextEditor.SelectionStartPosition; replacement.MoveCaretToReplace = true; LineSegment line1 = data.Document.GetLineByOffset(options.Document.TextEditor.SelectionEndPosition); if (options.Document.TextEditor.SelectionEndPosition == line1.Offset) { if (line1.Offset > 0) { LineSegment line2 = data.Document.GetLineByOffset(line1.Offset - 1); replacement.RemovedChars -= line2.DelimiterLength; } } replacement.InsertedText = options.GetWhitespaces(options.Document.TextEditor.SelectionStartPosition) + provider.OutputNode(options.Dom, outputNode).Trim(); result.Add(replacement); TextReplaceChange insertNewMethod = new TextReplaceChange(); insertNewMethod.FileName = options.Document.FileName; insertNewMethod.Description = string.Format(GettextCatalog.GetString("Create new method {0} from selected statement(s)"), param.Name); insertNewMethod.RemovedChars = param.InsertionPoint.LineBefore == NewLineInsertion.Eol ? 0 : param.InsertionPoint.Location.Column; insertNewMethod.Offset = data.Document.LocationToOffset(param.InsertionPoint.Location) - insertNewMethod.RemovedChars; ExtractMethodAstTransformer transformer = new ExtractMethodAstTransformer(param.VariablesToGenerate); node.AcceptVisitor(transformer, null); if (!param.OneChangedVariable && node is Expression) { ResolveResult resolveResult = resolver.Resolve(new ExpressionResult("(" + provider.OutputNode(options.Dom, node) + ")"), new DomLocation(options.Document.TextEditor.CursorLine, options.Document.TextEditor.CursorColumn)); if (resolveResult.ResolvedType != null) { returnType = options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference(); } } MethodDeclaration methodDecl = new MethodDeclaration(); methodDecl.Name = param.Name; methodDecl.Modifier = param.Modifiers; methodDecl.TypeReference = returnType; if (!param.ReferencesMember) { methodDecl.Modifier |= ICSharpCode.NRefactory.Ast.Modifiers.Static; } if (node is BlockStatement) { methodDecl.Body = new BlockStatement(); methodDecl.Body.AddChild(new EmptyStatement()); if (param.OneChangedVariable) { methodDecl.Body.AddChild(new ReturnStatement(new IdentifierExpression(param.ChangedVariables.First()))); } } else if (node is Expression) { methodDecl.Body = new BlockStatement(); methodDecl.Body.AddChild(new ReturnStatement(node as Expression)); } foreach (VariableDescriptor var in param.VariablesToDefine) { BlockStatement block = methodDecl.Body; LocalVariableDeclaration varDecl = new LocalVariableDeclaration(options.ShortenTypeName(var.ReturnType).ConvertToTypeReference()); varDecl.Variables.Add(new VariableDeclaration(var.Name)); block.Children.Insert(0, varDecl); } foreach (VariableDescriptor var in param.Parameters) { TypeReference typeReference = options.ShortenTypeName(var.ReturnType).ConvertToTypeReference(); ParameterDeclarationExpression pde = new ParameterDeclarationExpression(typeReference, var.Name); if (!param.OneChangedVariable) { if (param.ChangedVariables.Contains(var.Name)) { pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Ref; } if (param.VariablesToGenerate.Where(v => v.Name == var.Name).Any()) { pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Out; } VariableDescriptor outsideVar = null; if (var.GetsAssigned && param.VariablesOutside.TryGetValue(var.Name, out outsideVar)) { if (!outsideVar.GetsAssigned) { pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Out; } } } methodDecl.Parameters.Add(pde); } string indent = options.GetIndent(param.DeclaringMember); StringBuilder methodText = new StringBuilder(); switch (param.InsertionPoint.LineBefore) { case NewLineInsertion.Eol: methodText.AppendLine(); break; case NewLineInsertion.BlankLine: methodText.Append(indent); methodText.AppendLine(); break; } if (param.GenerateComment) { methodText.Append(indent); methodText.AppendLine("/// <summary>"); methodText.Append(indent); methodText.AppendLine("/// TODO: write a comment."); methodText.Append(indent); methodText.AppendLine("/// </summary>"); Ambience ambience = AmbienceService.GetAmbienceForFile(options.Document.FileName); foreach (ParameterDeclarationExpression pde in methodDecl.Parameters) { methodText.Append(indent); methodText.Append("/// <param name=\""); methodText.Append(pde.ParameterName); methodText.Append("\"> A "); methodText.Append(ambience.GetString(pde.TypeReference.ConvertToReturnType(), OutputFlags.IncludeGenerics | OutputFlags.UseFullName)); methodText.Append(" </param>"); methodText.AppendLine(); } if (methodDecl.TypeReference.Type != "System.Void") { methodText.Append(indent); methodText.AppendLine("/// <returns>"); methodText.Append(indent); methodText.Append("/// A "); methodText.AppendLine(ambience.GetString(methodDecl.TypeReference.ConvertToReturnType(), OutputFlags.IncludeGenerics | OutputFlags.UseFullName)); methodText.Append(indent); methodText.AppendLine("/// </returns>"); } } methodText.Append(indent); if (node is BlockStatement) { string text = provider.OutputNode(options.Dom, methodDecl, indent).Trim(); int emptyStatementMarker = text.LastIndexOf(';'); if (param.OneChangedVariable) { emptyStatementMarker = text.LastIndexOf(';', emptyStatementMarker - 1); } StringBuilder sb = new StringBuilder(); sb.Append(text.Substring(0, emptyStatementMarker)); sb.Append(AddIndent(param.Text, indent + "\t")); sb.Append(text.Substring(emptyStatementMarker + 1)); methodText.Append(sb.ToString()); } else { methodText.Append(provider.OutputNode(options.Dom, methodDecl, options.GetIndent(param.DeclaringMember)).Trim()); } switch (param.InsertionPoint.LineAfter) { case NewLineInsertion.Eol: methodText.AppendLine(); break; case NewLineInsertion.BlankLine: methodText.AppendLine(); methodText.AppendLine(); methodText.Append(indent); break; } insertNewMethod.InsertedText = methodText.ToString(); result.Add(insertNewMethod); 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.Editor.GetTextAt (options.Document.Editor.SelectionRange); 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; }
public ExtractMethodParameters CreateParameters (RefactoringOptions options) { var buffer = options.Document.Editor; if (!buffer.IsSomethingSelected) return null; ParsedDocument doc = options.ParseDocument (); if (doc == null || doc.CompilationUnit == null) return null; IMember member = doc.CompilationUnit.GetMemberAt (buffer.Caret.Line, buffer.Caret.Column); if (member == null) return null; ExtractMethodParameters param = new ExtractMethodParameters () { DeclaringMember = member, Location = new DomLocation (buffer.Caret.Line, buffer.Caret.Column) }; Analyze (options, param, true); return param; }
static string GenerateMethodDeclaration(RefactoringOptions options, ExtractMethodParameters param) { StringBuilder methodText = new StringBuilder(); string indent = options.GetIndent(param.DeclaringMember); if (param.InsertionPoint != null) { switch (param.InsertionPoint.LineBefore) { case NewLineInsertion.Eol: methodText.AppendLine(); break; case NewLineInsertion.BlankLine: methodText.Append(indent); methodText.AppendLine(); break; } } else { methodText.AppendLine(); methodText.Append(indent); methodText.AppendLine(); } var codeGenerator = new CSharpCodeGenerator() { UseSpaceIndent = options.Document.Editor.Options.TabsToSpaces, EolMarker = options.Document.Editor.EolMarker, TabSize = options.Document.Editor.Options.TabSize }; var newMethod = GenerateMethodStub(options, param); IType callingType = null; var cu = options.Document.CompilationUnit; if (cu != null) { callingType = newMethod.DeclaringType = options.Document.CompilationUnit.GetTypeAt(options.Document.Editor.Caret.Line, options.Document.Editor.Caret.Column); } var createdMethod = codeGenerator.CreateMemberImplementation(callingType, newMethod, false); if (param.GenerateComment && DocGenerator.Instance != null) { methodText.AppendLine(DocGenerator.Instance.GenerateDocumentation(newMethod, indent + "/// ")); } string code = createdMethod.Code; int idx1 = code.LastIndexOf("throw"); int idx2 = code.LastIndexOf(";"); methodText.Append(code.Substring(0, idx1)); if (param.Nodes != null && (param.Nodes.Count == 1 && param.Nodes[0].NodeType == NodeType.Expression)) { methodText.Append("return "); methodText.Append(param.Text.Trim()); methodText.Append(";"); } else { StringBuilder text = new StringBuilder(); if (param.OneChangedVariable) { var par = param.Variables.First(p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion); if (!par.UsedInCutRegion) { text.Append(new CSharpAmbience().GetString(par.ReturnType, OutputFlags.ClassBrowserEntries)); text.Append(" "); text.Append(par.Name); text.AppendLine(";"); } } text.Append(param.Text); if (param.OneChangedVariable) { text.AppendLine(); text.Append("return "); text.Append(param.Variables.First(p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion).Name); text.Append(";"); } methodText.Append(AddIndent(text.ToString(), indent + "\t")); } methodText.Append(code.Substring(idx2 + 1)); if (param.InsertionPoint != null) { switch (param.InsertionPoint.LineAfter) { case NewLineInsertion.Eol: methodText.AppendLine(); break; case NewLineInsertion.BlankLine: methodText.AppendLine(); methodText.Append(indent); methodText.AppendLine(); break; case NewLineInsertion.None: methodText.AppendLine(); break; } } else { methodText.AppendLine(); methodText.Append(indent); methodText.AppendLine(); } return(methodText.ToString()); }