Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3330 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
9 changed files with 639 additions and 453 deletions
@ -0,0 +1,171 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
|
||||||
|
// <version>$Revision: 3287 $</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.NRefactory; |
||||||
|
using ICSharpCode.NRefactory.Ast; |
||||||
|
using ICSharpCode.NRefactory.PrettyPrinter; |
||||||
|
using ICSharpCode.NRefactory.Visitors; |
||||||
|
using ICSharpCode.TextEditor.Document; |
||||||
|
using SharpRefactoring.Transformers; |
||||||
|
using SharpRefactoring.Visitors; |
||||||
|
|
||||||
|
namespace SharpRefactoring |
||||||
|
{ |
||||||
|
public class CSharpMethodExtractor : MethodExtractorBase |
||||||
|
{ |
||||||
|
public CSharpMethodExtractor(ICSharpCode.TextEditor.TextEditorControl textEditor, ISelection selection) |
||||||
|
: base(textEditor, selection, new CSharpOutputVisitor()) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
protected override string GenerateCode(INode unit, bool installSpecials) |
||||||
|
{ |
||||||
|
CSharpOutputVisitor visitor = new CSharpOutputVisitor(); |
||||||
|
|
||||||
|
if (installSpecials) { |
||||||
|
SpecialNodesInserter.Install(this.specialsList, visitor); |
||||||
|
} |
||||||
|
|
||||||
|
unit.AcceptVisitor(visitor, null); |
||||||
|
return visitor.Text; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Extract() |
||||||
|
{ |
||||||
|
using (IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader("class Tmp { void Test() {\n " + this.currentSelection.SelectedText + "\n}}"))) { |
||||||
|
parser.Parse(); |
||||||
|
|
||||||
|
if (parser.Errors.Count > 0) { |
||||||
|
MessageService.ShowError("Errors occured during parsing! Cannot extract a new method!"); |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
this.specialsList = parser.Lexer.SpecialTracker.RetrieveSpecials(); |
||||||
|
} |
||||||
|
|
||||||
|
MethodDeclaration newMethod = new MethodDeclaration(); |
||||||
|
|
||||||
|
List<VariableDeclaration> possibleReturnValues = new List<VariableDeclaration>(); |
||||||
|
|
||||||
|
List<VariableDeclaration> otherReturnValues = new List<VariableDeclaration>(); |
||||||
|
|
||||||
|
// Initialise new method
|
||||||
|
newMethod.Body = GetBlock(this.currentSelection.SelectedText); |
||||||
|
newMethod.Body.StartLocation = new Location(0,0); |
||||||
|
|
||||||
|
this.parentNode = GetParentMember(this.currentSelection.StartPosition.Line, this.currentSelection.StartPosition.Column, this.currentSelection.EndPosition.Line, this.currentSelection.EndPosition.Column); |
||||||
|
|
||||||
|
if (parentNode == null) { |
||||||
|
MessageService.ShowError("Invalid selection! Please select a valid range."); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (!CheckForJumpInstructions(newMethod, this.currentSelection)) |
||||||
|
return false; |
||||||
|
|
||||||
|
newMethod.Modifier = parentNode.Modifier; |
||||||
|
|
||||||
|
newMethod.Modifier &= ~(Modifiers.Internal | Modifiers.Protected | Modifiers.Private | Modifiers.Public); |
||||||
|
|
||||||
|
foreach (ParameterDeclarationExpression pde in parentNode.Parameters) |
||||||
|
{ |
||||||
|
FindReferenceVisitor frv = new FindReferenceVisitor(true, pde.ParameterName, newMethod.Body.StartLocation, newMethod.Body.EndLocation); |
||||||
|
|
||||||
|
newMethod.AcceptVisitor(frv, null); |
||||||
|
|
||||||
|
if (frv.Identifiers.Count > 0) { |
||||||
|
bool isIn = true; |
||||||
|
foreach (IdentifierExpression identifier in frv.Identifiers) { |
||||||
|
if (!IsInSel(identifier.StartLocation, this.currentSelection)) |
||||||
|
isIn = false; |
||||||
|
} |
||||||
|
|
||||||
|
if (isIn) { |
||||||
|
possibleReturnValues.Add(new VariableDeclaration(pde.ParameterName, null, pde.TypeReference)); |
||||||
|
} |
||||||
|
|
||||||
|
bool hasOccurrences = HasOccurrencesAfter(true, parentNode, new Location(this.currentSelection.EndPosition.Column + 1, this.currentSelection.EndPosition.Line + 1), pde.ParameterName, newMethod.Body.StartLocation, newMethod.Body.EndLocation); |
||||||
|
if (hasOccurrences) |
||||||
|
newMethod.Parameters.Add(new ParameterDeclarationExpression(pde.TypeReference, pde.ParameterName, ParameterModifiers.Ref)); |
||||||
|
else |
||||||
|
newMethod.Parameters.Add(new ParameterDeclarationExpression(pde.TypeReference, pde.ParameterName, pde.ParamModifier)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
LookupTableVisitor ltv = new LookupTableVisitor(SupportedLanguage.CSharp); |
||||||
|
|
||||||
|
parentNode.AcceptVisitor(ltv, null); |
||||||
|
|
||||||
|
foreach (KeyValuePair<string, List<LocalLookupVariable>> pair in ltv.Variables) { |
||||||
|
foreach (LocalLookupVariable variable in pair.Value) { |
||||||
|
if (IsInSel(variable.StartPos, this.currentSelection) && HasOccurrencesAfter(true, this.parentNode, new Location(this.currentSelection.EndPosition.Column + 1, this.currentSelection.EndPosition.Line + 1), variable.Name, variable.StartPos, variable.EndPos)) { |
||||||
|
possibleReturnValues.Add(new VariableDeclaration(variable.Name, variable.Initializer, variable.TypeRef)); |
||||||
|
otherReturnValues.Add(new VariableDeclaration(variable.Name, variable.Initializer, variable.TypeRef)); |
||||||
|
} |
||||||
|
|
||||||
|
FindReferenceVisitor frv = new FindReferenceVisitor(true, variable.Name, variable.StartPos, variable.EndPos); |
||||||
|
|
||||||
|
parentNode.AcceptVisitor(frv, null); |
||||||
|
|
||||||
|
if ((frv.Identifiers.Count > 0) && (!(IsInSel(variable.StartPos, this.currentSelection) || IsInSel(variable.EndPos, this.currentSelection)))) { |
||||||
|
bool hasOccurrences = HasOccurrencesAfter(true, this.parentNode, new Location(this.currentSelection.EndPosition.Column + 1, this.currentSelection.EndPosition.Line + 1), variable.Name, variable.StartPos, variable.EndPos); |
||||||
|
bool isInitialized = IsInitializedVariable(true, this.parentNode, variable); |
||||||
|
bool hasAssignment = HasAssignment(newMethod, variable); |
||||||
|
bool getsAssigned = pair.Value.Count > 0; |
||||||
|
|
||||||
|
if (hasOccurrences && isInitialized) |
||||||
|
newMethod.Parameters.Add(new ParameterDeclarationExpression(variable.TypeRef, variable.Name, ParameterModifiers.Ref)); |
||||||
|
else { |
||||||
|
if (hasOccurrences && hasAssignment) |
||||||
|
newMethod.Parameters.Add(new ParameterDeclarationExpression(variable.TypeRef, variable.Name, ParameterModifiers.Out)); |
||||||
|
else { |
||||||
|
if (!hasOccurrences && getsAssigned) |
||||||
|
newMethod.Parameters.Add(new ParameterDeclarationExpression(variable.TypeRef, variable.Name, ParameterModifiers.None)); |
||||||
|
else { |
||||||
|
if (!hasOccurrences && !isInitialized) |
||||||
|
newMethod.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(variable.Name, variable.Initializer, variable.TypeRef))); |
||||||
|
else |
||||||
|
newMethod.Parameters.Add(new ParameterDeclarationExpression(variable.TypeRef, variable.Name, ParameterModifiers.In)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
List<VariableDeclaration> paramsAsVarDecls = new List<VariableDeclaration>(); |
||||||
|
this.beforeCallDeclarations = new List<LocalVariableDeclaration>(); |
||||||
|
|
||||||
|
for (int i = 0; i < otherReturnValues.Count - 1; i++) { |
||||||
|
VariableDeclaration varDecl = otherReturnValues[i]; |
||||||
|
paramsAsVarDecls.Add(varDecl); |
||||||
|
ParameterDeclarationExpression p = new ParameterDeclarationExpression(varDecl.TypeReference, varDecl.Name); |
||||||
|
p.ParamModifier = ParameterModifiers.Out; |
||||||
|
if (!newMethod.Parameters.Contains(p)) { |
||||||
|
newMethod.Parameters.Add(p); |
||||||
|
} else { |
||||||
|
this.beforeCallDeclarations.Add(new LocalVariableDeclaration(varDecl)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ReplaceUnnecessaryVariableDeclarationsTransformer t = new ReplaceUnnecessaryVariableDeclarationsTransformer(paramsAsVarDecls); |
||||||
|
|
||||||
|
newMethod.AcceptVisitor(t, null); |
||||||
|
|
||||||
|
CreateReturnStatement(newMethod, possibleReturnValues); |
||||||
|
|
||||||
|
this.extractedMethod = newMethod; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,411 +0,0 @@ |
|||||||
using System; |
|
||||||
using System.Collections.Generic; |
|
||||||
using System.IO; |
|
||||||
|
|
||||||
using ICSharpCode.Core; |
|
||||||
using ICSharpCode.SharpDevelop.Project; |
|
||||||
using ICSharpCode.NRefactory; |
|
||||||
using ICSharpCode.NRefactory.Ast; |
|
||||||
using ICSharpCode.NRefactory.PrettyPrinter; |
|
||||||
using ICSharpCode.SharpDevelop; |
|
||||||
using ICSharpCode.SharpDevelop.Refactoring; |
|
||||||
using ICSharpCode.TextEditor.Document; |
|
||||||
using SharpRefactoring.Visitors; |
|
||||||
using Dom = ICSharpCode.SharpDevelop.Dom; |
|
||||||
using SharpRefactoring.Forms; |
|
||||||
using System.Text.RegularExpressions; |
|
||||||
|
|
||||||
namespace SharpRefactoring |
|
||||||
{ |
|
||||||
public class ExtractMethod : AbstractRefactoringCommand |
|
||||||
{ |
|
||||||
ISelection currentSelection; |
|
||||||
IDocument currentDocument; |
|
||||||
ICSharpCode.SharpDevelop.Dom.Refactoring.CodeGenerator generator; |
|
||||||
ParametrizedNode parent; |
|
||||||
VariableDeclaration returnVar; |
|
||||||
IList<ISpecial> specialsList; |
|
||||||
|
|
||||||
protected override void Run(ICSharpCode.TextEditor.TextEditorControl textEditor, ICSharpCode.SharpDevelop.Dom.Refactoring.RefactoringProvider provider) |
|
||||||
{ |
|
||||||
if (textEditor.ActiveTextAreaControl.SelectionManager.HasSomethingSelected) |
|
||||||
{ |
|
||||||
this.currentDocument = textEditor.Document; |
|
||||||
this.currentSelection = textEditor.ActiveTextAreaControl.SelectionManager.SelectionCollection[0]; |
|
||||||
this.generator = ProjectService.CurrentProject.LanguageProperties.CodeGenerator; |
|
||||||
|
|
||||||
MethodDeclaration method = GetMethod(this.currentDocument, this.currentSelection); |
|
||||||
|
|
||||||
if (method == null) return; |
|
||||||
|
|
||||||
Statement caller; |
|
||||||
InvocationExpression expr = new InvocationExpression(new IdentifierExpression(method.Name), CreateArgumentExpressions(method.Parameters)); |
|
||||||
|
|
||||||
if (method.TypeReference.Type != "void") { |
|
||||||
if (parent is MethodDeclaration) { |
|
||||||
if (method.TypeReference == (parent as MethodDeclaration).TypeReference) |
|
||||||
caller = new ReturnStatement(expr); |
|
||||||
else { |
|
||||||
this.returnVar.Initializer = expr; |
|
||||||
caller = new LocalVariableDeclaration(this.returnVar); |
|
||||||
} |
|
||||||
} else { |
|
||||||
this.returnVar.Initializer = expr; |
|
||||||
caller = new LocalVariableDeclaration(this.returnVar); |
|
||||||
} |
|
||||||
} else { |
|
||||||
caller = new ExpressionStatement(expr); |
|
||||||
} |
|
||||||
|
|
||||||
TextEditorDocument doc = new TextEditorDocument(this.currentDocument); |
|
||||||
|
|
||||||
string line = this.currentDocument.GetText(this.currentDocument.GetLineSegment(this.currentSelection.StartPosition.Line)); |
|
||||||
string indent = ""; |
|
||||||
|
|
||||||
foreach (char c in line) { |
|
||||||
if ((c == ' ') || (c == '\t')) |
|
||||||
indent += c; |
|
||||||
else |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
textEditor.Document.UndoStack.StartUndoGroup(); |
|
||||||
|
|
||||||
// TODO : Implement VB.NET support
|
|
||||||
IOutputAstVisitor csOutput = new CSharpOutputVisitor(); |
|
||||||
|
|
||||||
// FIXME : Problems with comments at the begin of the selection
|
|
||||||
RemoveUnneededSpecials(); |
|
||||||
|
|
||||||
using (SpecialNodesInserter.Install(this.specialsList, csOutput)) { |
|
||||||
method.AcceptVisitor(csOutput, null); |
|
||||||
string code = "\n\n" + csOutput.Text; |
|
||||||
|
|
||||||
code = code.TrimEnd('\n', ' ', '\t'); |
|
||||||
|
|
||||||
Dom.IMember p = GetParentMember(textEditor, this.currentSelection.StartPosition.Line, this.currentSelection.StartPosition.Column); |
|
||||||
|
|
||||||
textEditor.Document.Insert(textEditor.Document.PositionToOffset( |
|
||||||
new ICSharpCode.TextEditor.TextLocation( |
|
||||||
p.BodyRegion.EndColumn - 1, p.BodyRegion.EndLine - 1) |
|
||||||
), code); |
|
||||||
} |
|
||||||
|
|
||||||
string call = indent + GenerateCode(new CSharpOutputVisitor(), caller); |
|
||||||
|
|
||||||
call += (textEditor.ActiveTextAreaControl.SelectionManager.SelectedText.EndsWith("\n")) ? "\n" : ""; |
|
||||||
textEditor.Document.Replace(currentSelection.Offset, currentSelection.Length, call); |
|
||||||
textEditor.Document.FormattingStrategy.IndentLines(textEditor.ActiveTextAreaControl.TextArea, 0, textEditor.Document.TotalNumberOfLines - 1); |
|
||||||
|
|
||||||
textEditor.Document.UndoStack.EndUndoGroup(); |
|
||||||
|
|
||||||
textEditor.ActiveTextAreaControl.SelectionManager.ClearSelection(); |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void RemoveUnneededSpecials() |
|
||||||
{ |
|
||||||
int i = 0; |
|
||||||
|
|
||||||
while (i < this.specialsList.Count) { |
|
||||||
ISpecial spec = this.specialsList[i]; |
|
||||||
if (!IsInSel(spec.EndPosition, this.currentSelection) || !IsInSel(spec.StartPosition, this.currentSelection)) { |
|
||||||
this.specialsList.RemoveAt(i); |
|
||||||
continue; |
|
||||||
} else { |
|
||||||
if (spec is Comment) { |
|
||||||
Comment comment = spec as Comment; |
|
||||||
this.specialsList[i] = new Comment(comment.CommentType, comment.CommentText, |
|
||||||
new Location(spec.StartPosition.Column, spec.StartPosition.Line - this.currentSelection.StartPosition.Line + 1), |
|
||||||
new Location(spec.EndPosition.Column, spec.EndPosition.Line - this.currentSelection.StartPosition.Line + 1)); |
|
||||||
} else { |
|
||||||
if (spec is PreprocessingDirective) { |
|
||||||
PreprocessingDirective ppd = spec as PreprocessingDirective; |
|
||||||
|
|
||||||
this.specialsList[i] = new PreprocessingDirective(ppd.Cmd, ppd.Arg, |
|
||||||
new Location(spec.StartPosition.Column, spec.StartPosition.Line - this.currentSelection.StartPosition.Line + 1), |
|
||||||
new Location(spec.EndPosition.Column, spec.EndPosition.Line - this.currentSelection.StartPosition.Line + 1)); |
|
||||||
} else { |
|
||||||
this.specialsList[i] = new BlankLine(new Location(spec.StartPosition.Column, spec.StartPosition.Line - this.currentSelection.StartPosition.Line + 1)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
i++; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static List<Expression> CreateArgumentExpressions(List<ParameterDeclarationExpression> parameters) |
|
||||||
{ |
|
||||||
List<Expression> expressions = new List<Expression>(); |
|
||||||
|
|
||||||
foreach (ParameterDeclarationExpression pde in parameters) |
|
||||||
{ |
|
||||||
expressions.Add(new DirectionExpression( |
|
||||||
(FieldDirection)Enum.Parse(typeof(FieldDirection),pde.ParamModifier.ToString()), |
|
||||||
new IdentifierExpression(pde.ParameterName))); |
|
||||||
} |
|
||||||
|
|
||||||
return expressions; |
|
||||||
} |
|
||||||
|
|
||||||
CompilationUnit GetCurrentCompilationUnit(IDocument doc) |
|
||||||
{ |
|
||||||
using (IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(doc.TextContent))) { |
|
||||||
parser.Parse(); |
|
||||||
this.specialsList = parser.Lexer.SpecialTracker.RetrieveSpecials(); |
|
||||||
|
|
||||||
if (parser.Errors.Count > 0) { |
|
||||||
MessageService.ShowError(null, parser.Errors.ErrorOutput); |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
return parser.CompilationUnit; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
MethodDeclaration GetMethod(ICSharpCode.TextEditor.Document.IDocument doc, ISelection sel) |
|
||||||
{ |
|
||||||
MethodDeclaration newMethod = new MethodDeclaration(); |
|
||||||
|
|
||||||
CompilationUnit unit = GetCurrentCompilationUnit(doc); |
|
||||||
|
|
||||||
if (unit == null) |
|
||||||
return null; |
|
||||||
|
|
||||||
// Initialise new method
|
|
||||||
newMethod.Body = GetBlock(sel.SelectedText); |
|
||||||
newMethod.Body.StartLocation = new Location(0,0); |
|
||||||
|
|
||||||
this.parent = GetParentMember(unit, sel.StartPosition.Line, sel.StartPosition.Column, sel.EndPosition.Line, sel.EndPosition.Column); |
|
||||||
|
|
||||||
if (parent == null) { |
|
||||||
MessageService.ShowError("Invalid selection! Please select a valid range."); |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
if (!CheckForJumpInstructions(newMethod, sel)) |
|
||||||
return null; |
|
||||||
|
|
||||||
newMethod.Modifier = parent.Modifier; |
|
||||||
|
|
||||||
newMethod.Modifier &= ~(Modifiers.Internal | Modifiers.Protected | Modifiers.Private | Modifiers.Public); |
|
||||||
|
|
||||||
List<VariableDeclaration> possibleReturnValues = new List<VariableDeclaration>(); |
|
||||||
|
|
||||||
foreach (ParameterDeclarationExpression pde in parent.Parameters) |
|
||||||
{ |
|
||||||
FindReferenceVisitor frv = new FindReferenceVisitor(pde.ParameterName, pde.TypeReference); |
|
||||||
|
|
||||||
newMethod.AcceptVisitor(frv, null); |
|
||||||
|
|
||||||
if (frv.Identifiers.Count > 0) { |
|
||||||
bool isIn = true; |
|
||||||
foreach (IdentifierExpression identifier in frv.Identifiers) { |
|
||||||
if (!IsInSel(identifier.StartLocation, sel)) |
|
||||||
isIn = false; |
|
||||||
} |
|
||||||
|
|
||||||
if (isIn) { |
|
||||||
possibleReturnValues.Add(new VariableDeclaration(pde.ParameterName, null, pde.TypeReference)); |
|
||||||
} |
|
||||||
|
|
||||||
bool hasOccurrences = HasOccurrencesAfter(parent, new Location(sel.EndPosition.Column + 1, sel.EndPosition.Line + 1), pde.ParameterName, pde.TypeReference); if (hasOccurrences) |
|
||||||
newMethod.Parameters.Add(new ParameterDeclarationExpression(pde.TypeReference, pde.ParameterName, ParameterModifiers.Ref)); |
|
||||||
else |
|
||||||
newMethod.Parameters.Add(new ParameterDeclarationExpression(pde.TypeReference, pde.ParameterName, ParameterModifiers.In)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
FindLocalVariablesVisitor flvv = new FindLocalVariablesVisitor(); |
|
||||||
|
|
||||||
parent.AcceptVisitor(flvv, null); |
|
||||||
|
|
||||||
foreach (VariableDeclaration lvd in flvv.Variables) |
|
||||||
{ |
|
||||||
FindReferenceVisitor frv = new FindReferenceVisitor(lvd.Name, lvd.TypeReference); |
|
||||||
|
|
||||||
newMethod.AcceptVisitor(frv, null); |
|
||||||
|
|
||||||
if (IsInSel(lvd.StartLocation, sel) && HasOccurrencesAfter(parent, new Location(sel.EndPosition.Column + 1, sel.EndPosition.Line + 1), lvd.Name, lvd.TypeReference)) |
|
||||||
possibleReturnValues.Add(new VariableDeclaration(lvd.Name, null, lvd.TypeReference)); |
|
||||||
|
|
||||||
if ((frv.Identifiers.Count > 0) && (!(IsInSel(lvd.StartLocation, sel) || IsInSel(lvd.EndLocation, sel)))) { |
|
||||||
bool hasOccurrences = HasOccurrencesAfter(parent, new Location(sel.EndPosition.Column + 1, sel.EndPosition.Line + 1), lvd.Name, lvd.TypeReference); |
|
||||||
bool isInitialized = IsInitializedVariable(parent, lvd); |
|
||||||
bool hasAssignment = HasAssignment(newMethod, lvd); |
|
||||||
if (hasOccurrences && isInitialized) |
|
||||||
newMethod.Parameters.Add(new ParameterDeclarationExpression(lvd.TypeReference, lvd.Name, ParameterModifiers.Ref)); |
|
||||||
else { |
|
||||||
if (hasOccurrences && hasAssignment) |
|
||||||
newMethod.Parameters.Add(new ParameterDeclarationExpression(lvd.TypeReference, lvd.Name, ParameterModifiers.Out)); |
|
||||||
else { |
|
||||||
if (!hasOccurrences && !isInitialized) |
|
||||||
newMethod.Body.Children.Insert(0, new LocalVariableDeclaration(lvd)); |
|
||||||
else |
|
||||||
newMethod.Parameters.Add(new ParameterDeclarationExpression(lvd.TypeReference, lvd.Name, ParameterModifiers.In)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
HasReturnStatementVisitor hrsv = new HasReturnStatementVisitor(); |
|
||||||
|
|
||||||
newMethod.AcceptVisitor(hrsv, null); |
|
||||||
|
|
||||||
if (hrsv.HasReturn) { |
|
||||||
if (parent is MethodDeclaration) |
|
||||||
newMethod.TypeReference = (parent as MethodDeclaration).TypeReference; |
|
||||||
if (parent is PropertyDeclaration) |
|
||||||
newMethod.TypeReference = (parent as PropertyDeclaration).TypeReference; |
|
||||||
if (parent is OperatorDeclaration) |
|
||||||
newMethod.TypeReference = (parent as OperatorDeclaration).TypeReference; |
|
||||||
} else { |
|
||||||
if (possibleReturnValues.Count > 0) { |
|
||||||
newMethod.TypeReference = possibleReturnValues[0].TypeReference; |
|
||||||
newMethod.Body.Children.Add(new ReturnStatement(new IdentifierExpression(possibleReturnValues[0].Name))); |
|
||||||
this.returnVar = possibleReturnValues[0]; |
|
||||||
} else |
|
||||||
newMethod.TypeReference = new TypeReference("void"); |
|
||||||
} |
|
||||||
|
|
||||||
IOutputAstVisitor output = new CSharpOutputVisitor(); |
|
||||||
|
|
||||||
newMethod.Name = "NewMethod"; |
|
||||||
|
|
||||||
BlockStatement body = newMethod.Body; |
|
||||||
newMethod.Body = new BlockStatement(); |
|
||||||
|
|
||||||
newMethod.AcceptVisitor(output, null); |
|
||||||
|
|
||||||
string preview = output.Text; |
|
||||||
|
|
||||||
ExtractMethodForm form = new ExtractMethodForm("NewMethod", preview); |
|
||||||
|
|
||||||
if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK) |
|
||||||
{ |
|
||||||
newMethod.Name = form.Text; |
|
||||||
newMethod.Body = body; |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
return newMethod; |
|
||||||
} |
|
||||||
|
|
||||||
Dom.IMember GetParentMember(ICSharpCode.TextEditor.TextEditorControl textEditor, int line, int column) |
|
||||||
{ |
|
||||||
Dom.ParseInformation parseInfo = ParserService.GetParseInformation(textEditor.FileName); |
|
||||||
if (parseInfo != null) { |
|
||||||
Dom.IClass c = parseInfo.MostRecentCompilationUnit.GetInnermostClass(line, column); |
|
||||||
if (c != null) { |
|
||||||
foreach (Dom.IMember member in c.Properties) { |
|
||||||
if (member.BodyRegion.IsInside(line, column)) { |
|
||||||
return member; |
|
||||||
} |
|
||||||
} |
|
||||||
foreach (Dom.IMember member in c.Methods) { |
|
||||||
if (member.BodyRegion.IsInside(line, column)) { |
|
||||||
return member; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
static bool CheckForJumpInstructions(MethodDeclaration method, ISelection selection) |
|
||||||
{ |
|
||||||
FindJumpInstructionsVisitor fjiv = new FindJumpInstructionsVisitor(method, selection); |
|
||||||
|
|
||||||
method.AcceptVisitor(fjiv, null); |
|
||||||
|
|
||||||
return fjiv.IsOk; |
|
||||||
} |
|
||||||
|
|
||||||
static bool IsInSel(Location location, ISelection sel) |
|
||||||
{ |
|
||||||
bool result = (sel.ContainsPosition(new ICSharpCode.TextEditor.TextLocation(location.Column - 1, location.Line - 1))); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
static BlockStatement GetBlock(string data) |
|
||||||
{ |
|
||||||
data = "class Temp { public void t() {" + data + "} }"; |
|
||||||
|
|
||||||
using (IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(data))) { |
|
||||||
parser.Parse(); |
|
||||||
|
|
||||||
if (parser.Errors.Count > 0) { |
|
||||||
throw new ArgumentException("Invalid selection! Please select a valid range!"); |
|
||||||
} |
|
||||||
|
|
||||||
MethodDeclaration method = (MethodDeclaration)(parser.CompilationUnit.Children[0].Children[0]); |
|
||||||
|
|
||||||
return method.Body; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static string GenerateCode(IOutputAstVisitor outputVisitor, INode unit) |
|
||||||
{ |
|
||||||
unit.AcceptVisitor(outputVisitor, null); |
|
||||||
return outputVisitor.Text; |
|
||||||
} |
|
||||||
|
|
||||||
static ParametrizedNode GetParentMember(CompilationUnit unit, int startLine, int startColumn, int endLine, int endColumn) |
|
||||||
{ |
|
||||||
FindMemberVisitor fmv = new FindMemberVisitor(startColumn, startLine, endColumn, endLine); |
|
||||||
|
|
||||||
unit.AcceptVisitor(fmv, null); |
|
||||||
|
|
||||||
return fmv.Member; |
|
||||||
} |
|
||||||
|
|
||||||
static bool HasOccurrencesAfter(ParametrizedNode member, Location location, string name, TypeReference type) |
|
||||||
{ |
|
||||||
FindReferenceVisitor frv = new FindReferenceVisitor(name, type); |
|
||||||
|
|
||||||
member.AcceptVisitor(frv, null); |
|
||||||
|
|
||||||
foreach (IdentifierExpression identifier in frv.Identifiers) |
|
||||||
{ |
|
||||||
if (identifier.StartLocation > location) |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
bool IsInitializedVariable(ParametrizedNode member, VariableDeclaration variable) |
|
||||||
{ |
|
||||||
if (!(variable.Initializer.IsNull)) { |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
FindReferenceVisitor frv = new FindReferenceVisitor(variable.Name, variable.TypeReference); |
|
||||||
|
|
||||||
member.AcceptVisitor(frv, null); |
|
||||||
|
|
||||||
foreach (IdentifierExpression expr in frv.Identifiers) { |
|
||||||
if ((expr.EndLocation < new Location(currentSelection.StartPosition.Column, currentSelection.StartPosition.Line)) && |
|
||||||
!(expr.IsNull)) |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
static bool HasAssignment(MethodDeclaration method, VariableDeclaration variable) |
|
||||||
{ |
|
||||||
HasAssignmentsVisitor hav = new HasAssignmentsVisitor(variable.Name, variable.TypeReference); |
|
||||||
|
|
||||||
method.AcceptVisitor(hav, null); |
|
||||||
|
|
||||||
return hav.HasAssignment; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,64 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using ICSharpCode.TextEditor; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.IO; |
||||||
|
using System.Text.RegularExpressions; |
||||||
|
using System.Windows.Forms; |
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.NRefactory; |
||||||
|
using ICSharpCode.NRefactory.Ast; |
||||||
|
using ICSharpCode.NRefactory.PrettyPrinter; |
||||||
|
using ICSharpCode.SharpDevelop; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.SharpDevelop.Gui; |
||||||
|
using ICSharpCode.SharpDevelop.Project; |
||||||
|
using ICSharpCode.SharpDevelop.Refactoring; |
||||||
|
using ICSharpCode.TextEditor.Document; |
||||||
|
using SharpRefactoring.Forms; |
||||||
|
using SharpRefactoring.Transformers; |
||||||
|
using SharpRefactoring.Visitors; |
||||||
|
|
||||||
|
namespace SharpRefactoring |
||||||
|
{ |
||||||
|
public class ExtractMethodCommand : AbstractRefactoringCommand |
||||||
|
{ |
||||||
|
protected override void Run(ICSharpCode.TextEditor.TextEditorControl textEditor, ICSharpCode.SharpDevelop.Dom.Refactoring.RefactoringProvider provider) |
||||||
|
{ |
||||||
|
if (textEditor.ActiveTextAreaControl.SelectionManager.HasSomethingSelected) |
||||||
|
{ |
||||||
|
MethodExtractorBase extractor = GetCurrentExtractor(textEditor); |
||||||
|
|
||||||
|
if (extractor.Extract()) { |
||||||
|
ExtractMethodForm form = new ExtractMethodForm("NewMethod", extractor.CreatePreview()); |
||||||
|
|
||||||
|
if (form.ShowDialog() == DialogResult.OK) { |
||||||
|
extractor.ExtractedMethod.Name = form.Text; |
||||||
|
textEditor.Document.UndoStack.StartUndoGroup(); |
||||||
|
extractor.InsertAfterCurrentMethod(); |
||||||
|
extractor.InsertCall(); |
||||||
|
textEditor.Document.FormattingStrategy.IndentLines(textEditor.ActiveTextAreaControl.TextArea, 0, textEditor.Document.TotalNumberOfLines - 1); |
||||||
|
textEditor.Document.UndoStack.EndUndoGroup(); |
||||||
|
textEditor.ActiveTextAreaControl.SelectionManager.ClearSelection(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
MethodExtractorBase GetCurrentExtractor(TextEditorControl editor) |
||||||
|
{ |
||||||
|
switch (ProjectService.CurrentProject.Language) { |
||||||
|
case "C#": |
||||||
|
return new CSharpMethodExtractor(editor, editor.ActiveTextAreaControl.SelectionManager.SelectionCollection[0]); |
||||||
|
default: |
||||||
|
throw new NotSupportedException("Extracting methods in the current language is not supported!"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,302 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
|
||||||
|
// <version>$Revision: 3287 $</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.IO; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.NRefactory; |
||||||
|
using ICSharpCode.NRefactory.Ast; |
||||||
|
using ICSharpCode.NRefactory.PrettyPrinter; |
||||||
|
using ICSharpCode.NRefactory.Visitors; |
||||||
|
using ICSharpCode.SharpDevelop; |
||||||
|
using ICSharpCode.TextEditor.Document; |
||||||
|
using SharpRefactoring.Visitors; |
||||||
|
using Dom = ICSharpCode.SharpDevelop.Dom; |
||||||
|
|
||||||
|
namespace SharpRefactoring |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of MethodExtractorBase.
|
||||||
|
/// </summary>
|
||||||
|
public class MethodExtractorBase |
||||||
|
{ |
||||||
|
protected ICSharpCode.TextEditor.TextEditorControl textEditor; |
||||||
|
protected ISelection currentSelection; |
||||||
|
protected IDocument currentDocument; |
||||||
|
protected MethodDeclaration extractedMethod; |
||||||
|
protected ParametrizedNode parentNode; |
||||||
|
protected Statement caller; |
||||||
|
protected List<LocalVariableDeclaration> beforeCallDeclarations; |
||||||
|
protected IOutputAstVisitor output; |
||||||
|
protected VariableDeclaration returnedVariable; |
||||||
|
protected List<ISpecial> specialsList; |
||||||
|
|
||||||
|
public Statement Caller { |
||||||
|
get { return caller; } |
||||||
|
} |
||||||
|
|
||||||
|
public MethodDeclaration ExtractedMethod { |
||||||
|
get { return extractedMethod; } |
||||||
|
} |
||||||
|
|
||||||
|
public MethodExtractorBase(ICSharpCode.TextEditor.TextEditorControl textEditor, ISelection selection, IOutputAstVisitor output) |
||||||
|
{ |
||||||
|
this.currentDocument = textEditor.Document; |
||||||
|
this.textEditor = textEditor; |
||||||
|
this.currentSelection = selection; |
||||||
|
this.output = output; |
||||||
|
} |
||||||
|
|
||||||
|
protected static Statement CreateCaller(ParametrizedNode parent, MethodDeclaration method, VariableDeclaration returnVariable) |
||||||
|
{ |
||||||
|
Statement caller; |
||||||
|
InvocationExpression expr = new InvocationExpression(new IdentifierExpression(method.Name), CreateArgumentExpressions(method.Parameters)); |
||||||
|
|
||||||
|
if (method.TypeReference.Type != "void") { |
||||||
|
if (parent is MethodDeclaration) { |
||||||
|
if (method.TypeReference == (parent as MethodDeclaration).TypeReference) |
||||||
|
caller = new ReturnStatement(expr); |
||||||
|
else { |
||||||
|
returnVariable.Initializer = expr; |
||||||
|
caller = new LocalVariableDeclaration(returnVariable); |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
returnVariable.Initializer = expr; |
||||||
|
caller = new LocalVariableDeclaration(returnVariable); |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
caller = new ExpressionStatement(expr); |
||||||
|
} |
||||||
|
return caller; |
||||||
|
} |
||||||
|
|
||||||
|
protected void CreateReturnStatement(MethodDeclaration newMethod, List<VariableDeclaration> possibleReturnValues) |
||||||
|
{ |
||||||
|
HasReturnStatementVisitor hrsv = new HasReturnStatementVisitor(); |
||||||
|
|
||||||
|
newMethod.AcceptVisitor(hrsv, null); |
||||||
|
|
||||||
|
if (hrsv.HasReturn) { |
||||||
|
if (this.parentNode is MethodDeclaration) newMethod.TypeReference = (this.parentNode as MethodDeclaration).TypeReference; |
||||||
|
if (this.parentNode is PropertyDeclaration) newMethod.TypeReference = (this.parentNode as PropertyDeclaration).TypeReference; |
||||||
|
if (this.parentNode is OperatorDeclaration) newMethod.TypeReference = (this.parentNode as OperatorDeclaration).TypeReference; |
||||||
|
} |
||||||
|
else { |
||||||
|
if (possibleReturnValues.Count > 0) { |
||||||
|
newMethod.TypeReference = possibleReturnValues[possibleReturnValues.Count - 1].TypeReference; |
||||||
|
newMethod.Body.Children.Add(new ReturnStatement(new IdentifierExpression(possibleReturnValues[possibleReturnValues.Count - 1].Name))); |
||||||
|
} |
||||||
|
else newMethod.TypeReference = new TypeReference("void"); |
||||||
|
} |
||||||
|
|
||||||
|
if (newMethod.TypeReference.Type == "void") { |
||||||
|
this.returnedVariable = null; |
||||||
|
} else { |
||||||
|
this.returnedVariable = possibleReturnValues[possibleReturnValues.Count - 1]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public string CreatePreview() |
||||||
|
{ |
||||||
|
BlockStatement body = this.extractedMethod.Body; |
||||||
|
this.extractedMethod.Body = new BlockStatement(); |
||||||
|
|
||||||
|
this.extractedMethod.AcceptVisitor(output, null); |
||||||
|
|
||||||
|
this.extractedMethod.Body = body; |
||||||
|
|
||||||
|
return output.Text; |
||||||
|
} |
||||||
|
|
||||||
|
public void InsertCall() |
||||||
|
{ |
||||||
|
string call = GenerateCode(CreateCaller(this.parentNode, this.extractedMethod, this.returnedVariable), false); |
||||||
|
StringBuilder builder = new StringBuilder(); |
||||||
|
|
||||||
|
foreach (LocalVariableDeclaration v in this.beforeCallDeclarations) { |
||||||
|
builder.AppendLine(GenerateCode(v, false)); |
||||||
|
} |
||||||
|
|
||||||
|
this.currentDocument.Replace(this.currentSelection.Offset, this.currentSelection.Length, /*builder.ToString() + "\n" +*/ call); |
||||||
|
} |
||||||
|
|
||||||
|
public void InsertAfterCurrentMethod() |
||||||
|
{ |
||||||
|
using (SpecialNodesInserter.Install(this.specialsList, this.output)) { |
||||||
|
string code = "\n\n" + GenerateCode(this.extractedMethod, true); |
||||||
|
|
||||||
|
code = code.TrimEnd('\n', ' ', '\t'); |
||||||
|
|
||||||
|
Dom.IMember p = GetParentMember(this.textEditor, this.currentSelection.StartPosition.Line, this.currentSelection.StartPosition.Column); |
||||||
|
|
||||||
|
textEditor.Document.Insert(textEditor.Document.PositionToOffset( |
||||||
|
new ICSharpCode.TextEditor.TextLocation( |
||||||
|
p.BodyRegion.EndColumn - 1, p.BodyRegion.EndLine - 1) |
||||||
|
), code); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static bool CheckForJumpInstructions(MethodDeclaration method, ISelection selection) |
||||||
|
{ |
||||||
|
FindJumpInstructionsVisitor fjiv = new FindJumpInstructionsVisitor(method, selection); |
||||||
|
|
||||||
|
method.AcceptVisitor(fjiv, null); |
||||||
|
|
||||||
|
return fjiv.IsOk; |
||||||
|
} |
||||||
|
|
||||||
|
protected static bool IsInSel(Location location, ISelection sel) |
||||||
|
{ |
||||||
|
bool result = (sel.ContainsPosition(new ICSharpCode.TextEditor.TextLocation(location.Column - 1, location.Line - 1))); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
protected static BlockStatement GetBlock(string data) |
||||||
|
{ |
||||||
|
data = "class Temp { public void t() {" + data + "} }"; |
||||||
|
|
||||||
|
using (IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(data))) { |
||||||
|
parser.Parse(); |
||||||
|
|
||||||
|
if (parser.Errors.Count > 0) { |
||||||
|
MessageService.ShowError("Invalid selection! Please select a valid range!"); |
||||||
|
} |
||||||
|
|
||||||
|
MethodDeclaration method = (MethodDeclaration)(parser.CompilationUnit.Children[0].Children[0]); |
||||||
|
|
||||||
|
return method.Body; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static string GetIndentation(string line) |
||||||
|
{ |
||||||
|
string indent = ""; |
||||||
|
|
||||||
|
foreach (char c in line) { |
||||||
|
if ((c == ' ') || (c == '\t')) |
||||||
|
indent += c; |
||||||
|
else |
||||||
|
break; |
||||||
|
} |
||||||
|
return indent; |
||||||
|
} |
||||||
|
|
||||||
|
protected static List<Expression> CreateArgumentExpressions(List<ParameterDeclarationExpression> parameters) |
||||||
|
{ |
||||||
|
List<Expression> expressions = new List<Expression>(); |
||||||
|
|
||||||
|
foreach (ParameterDeclarationExpression pde in parameters) |
||||||
|
{ |
||||||
|
expressions.Add(new DirectionExpression( |
||||||
|
(FieldDirection)Enum.Parse(typeof(FieldDirection),pde.ParamModifier.ToString()), |
||||||
|
new IdentifierExpression(pde.ParameterName))); |
||||||
|
} |
||||||
|
|
||||||
|
return expressions; |
||||||
|
} |
||||||
|
|
||||||
|
protected virtual string GenerateCode(INode unit, bool installSpecials) |
||||||
|
{ |
||||||
|
throw new InvalidOperationException("Cannot use plain MethodExtractor, please use a language specific implementation!"); |
||||||
|
} |
||||||
|
|
||||||
|
protected Dom.IMember GetParentMember(ICSharpCode.TextEditor.TextEditorControl textEditor, int line, int column) |
||||||
|
{ |
||||||
|
Dom.ParseInformation parseInfo = ParserService.GetParseInformation(textEditor.FileName); |
||||||
|
if (parseInfo != null) { |
||||||
|
Dom.IClass c = parseInfo.MostRecentCompilationUnit.GetInnermostClass(line, column); |
||||||
|
if (c != null) { |
||||||
|
foreach (Dom.IMember member in c.Properties) { |
||||||
|
if (member.BodyRegion.IsInside(line, column)) { |
||||||
|
return member; |
||||||
|
} |
||||||
|
} |
||||||
|
foreach (Dom.IMember member in c.Methods) { |
||||||
|
if (member.BodyRegion.IsInside(line, column)) { |
||||||
|
return member; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
protected ParametrizedNode GetParentMember(int startLine, int startColumn, int endLine, int endColumn) |
||||||
|
{ |
||||||
|
using (IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(this.currentDocument.TextContent))) { |
||||||
|
parser.Parse(); |
||||||
|
|
||||||
|
if (parser.Errors.Count > 0) { |
||||||
|
MessageService.ShowError(null, parser.Errors.ErrorOutput); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
FindMemberVisitor fmv = new FindMemberVisitor(startColumn, startLine, endColumn, endLine); |
||||||
|
|
||||||
|
parser.CompilationUnit.AcceptVisitor(fmv, null); |
||||||
|
|
||||||
|
return fmv.Member; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static bool HasOccurrencesAfter(bool caseSensitive, ParametrizedNode member, Location location, string name, Location start, Location end) |
||||||
|
{ |
||||||
|
FindReferenceVisitor frv = new FindReferenceVisitor(caseSensitive, name, start, end); |
||||||
|
|
||||||
|
member.AcceptVisitor(frv, null); |
||||||
|
|
||||||
|
foreach (IdentifierExpression identifier in frv.Identifiers) |
||||||
|
{ |
||||||
|
if (identifier.StartLocation > location) |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
protected bool IsInitializedVariable(bool caseSensitive, ParametrizedNode member, LocalLookupVariable variable) |
||||||
|
{ |
||||||
|
if (!(variable.Initializer.IsNull)) { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
FindReferenceVisitor frv = new FindReferenceVisitor(caseSensitive, variable.Name, variable.StartPos, variable.EndPos); |
||||||
|
|
||||||
|
member.AcceptVisitor(frv, null); |
||||||
|
|
||||||
|
foreach (IdentifierExpression expr in frv.Identifiers) { |
||||||
|
if ((expr.EndLocation < new Location(currentSelection.StartPosition.Column, currentSelection.StartPosition.Line)) && |
||||||
|
!(expr.IsNull)) |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
protected static bool HasAssignment(MethodDeclaration method, LocalLookupVariable variable) |
||||||
|
{ |
||||||
|
HasAssignmentsVisitor hav = new HasAssignmentsVisitor(variable.Name, variable.TypeRef); |
||||||
|
|
||||||
|
method.AcceptVisitor(hav, null); |
||||||
|
|
||||||
|
return hav.HasAssignment; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public virtual bool Extract() |
||||||
|
{ |
||||||
|
throw new InvalidOperationException("Cannot use plain MethodExtractor, please use a language specific implementation!"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,65 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
|
||||||
|
// <version>$Revision: 3287 $</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using ICSharpCode.NRefactory.Ast; |
||||||
|
using ICSharpCode.NRefactory.Visitors; |
||||||
|
using System.Collections.Generic; |
||||||
|
|
||||||
|
namespace SharpRefactoring.Transformers |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Description of ReplaceUnnecessaryVariableDeclarationsTransformer.
|
||||||
|
/// </summary>
|
||||||
|
public class ReplaceUnnecessaryVariableDeclarationsTransformer : AbstractAstTransformer |
||||||
|
{ |
||||||
|
List<VariableDeclaration> unneededVarDecls; |
||||||
|
|
||||||
|
public ReplaceUnnecessaryVariableDeclarationsTransformer(List<VariableDeclaration> unneededVarDecls) |
||||||
|
{ |
||||||
|
this.unneededVarDecls = unneededVarDecls; |
||||||
|
} |
||||||
|
|
||||||
|
bool Contains(VariableDeclaration varDecl) |
||||||
|
{ |
||||||
|
foreach (VariableDeclaration v in this.unneededVarDecls) { |
||||||
|
if (v.Name == varDecl.Name) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public override object VisitLocalVariableDeclaration(ICSharpCode.NRefactory.Ast.LocalVariableDeclaration localVariableDeclaration, object data) |
||||||
|
{ |
||||||
|
bool containsAll = true; |
||||||
|
foreach (VariableDeclaration v in localVariableDeclaration.Variables) { |
||||||
|
if (Contains(v)) { |
||||||
|
localVariableDeclaration.Parent.Children.Add(new ExpressionStatement( |
||||||
|
new AssignmentExpression(new IdentifierExpression(v.Name), |
||||||
|
AssignmentOperatorType.Assign, |
||||||
|
v.Initializer))); |
||||||
|
} else |
||||||
|
containsAll = false; |
||||||
|
} |
||||||
|
|
||||||
|
if (containsAll) |
||||||
|
this.RemoveCurrentNode(); |
||||||
|
|
||||||
|
return base.VisitLocalVariableDeclaration(localVariableDeclaration, data); |
||||||
|
} |
||||||
|
|
||||||
|
public override object VisitVariableDeclaration(ICSharpCode.NRefactory.Ast.VariableDeclaration variableDeclaration, object data) |
||||||
|
{ |
||||||
|
if (!(variableDeclaration.Parent is LocalVariableDeclaration)) { |
||||||
|
this.ReplaceCurrentNode(new ExpressionStatement(new AssignmentExpression(new IdentifierExpression(variableDeclaration.Name), AssignmentOperatorType.Assign, variableDeclaration.Initializer))); |
||||||
|
} |
||||||
|
return base.VisitVariableDeclaration(variableDeclaration, data); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue