Browse Source

Extract Method: clean up and bug fixes

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4042 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 16 years ago
parent
commit
feb47eeec8
  1. 2
      src/AddIns/Misc/SharpRefactoring/SharpRefactoring.csproj
  2. 147
      src/AddIns/Misc/SharpRefactoring/Src/CSharpMethodExtractor.cs
  3. 11
      src/AddIns/Misc/SharpRefactoring/Src/ExtractMethodCommand.cs
  4. 45
      src/AddIns/Misc/SharpRefactoring/Src/MethodExtractorBase.cs
  5. 65
      src/AddIns/Misc/SharpRefactoring/Src/Transformers/ReplaceUnnecessaryVariableDeclarationsTransformer.cs

2
src/AddIns/Misc/SharpRefactoring/SharpRefactoring.csproj

@ -66,7 +66,6 @@ @@ -66,7 +66,6 @@
</Compile>
<Compile Include="Src\MethodExtractorBase.cs" />
<Compile Include="Src\ParameterCheckRefactoringMenuBuilder.cs" />
<Compile Include="Src\Transformers\ReplaceUnnecessaryVariableDeclarationsTransformer.cs" />
<Compile Include="Src\Visitors\FindJumpInstructionsVisitor.cs" />
<Compile Include="Src\Visitors\FindMemberVisitor.cs" />
<Compile Include="Src\Visitors\FindReferenceVisitor.cs" />
@ -107,6 +106,5 @@ @@ -107,6 +106,5 @@
<Name>ICSharpCode.SharpDevelop.Dom</Name>
<Private>False</Private>
</ProjectReference>
<Folder Include="Src\Transformers" />
</ItemGroup>
</Project>

147
src/AddIns/Misc/SharpRefactoring/Src/CSharpMethodExtractor.cs

@ -8,6 +8,8 @@ @@ -8,6 +8,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
@ -17,7 +19,6 @@ using ICSharpCode.SharpDevelop; @@ -17,7 +19,6 @@ using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.TextEditor.Document;
using SharpRefactoring.Transformers;
using SharpRefactoring.Visitors;
using Dom = ICSharpCode.SharpDevelop.Dom;
@ -84,92 +85,48 @@ namespace SharpRefactoring @@ -84,92 +85,48 @@ namespace SharpRefactoring
newMethod.Modifier &= ~(Modifiers.Internal | Modifiers.Protected | Modifiers.Private | Modifiers.Public | Modifiers.Override);
foreach (ParameterDeclarationExpression pde in parentNode.Parameters)
{
FindReferenceVisitor frv = new FindReferenceVisitor(CSharpNameComparer, pde.ParameterName, newMethod.Body.StartLocation, newMethod.Body.EndLocation);
pde.ParamModifier &= ~(ParameterModifiers.Params);
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(CSharpNameComparer, 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);
Location start = new Location(this.currentSelection.StartPosition.Column + 1, this.currentSelection.StartPosition.Line + 1);
Location end = new Location(this.currentSelection.EndPosition.Column + 1, this.currentSelection.EndPosition.Line + 1);
var variablesList = (from list in ltv.Variables.Values from item in list select new Variable(item))
.Where(v => !(v.StartPos > end || v.EndPos < start))
.Union(FromParameters(newMethod))
.Select(va => ResolveVariable(va));
foreach (KeyValuePair<string, List<LocalLookupVariable>> pair in ltv.Variables) {
foreach (LocalLookupVariable v in pair.Value) {
Variable variable = new Variable(v);
if (variable.StartPos > end || variable.EndPos < start)
continue;
Dom.ParseInformation info = ParserService.GetParseInformation(this.textEditor.FileName);
Dom.ExpressionResult res = new Dom.ExpressionResult(variable.Name, Dom.DomRegion.FromLocation(variable.StartPos, variable.EndPos), Dom.ExpressionContext.Default, null);
Dom.ResolveResult result = this.GetResolver().Resolve(res, info, this.textEditor.Document.TextContent);
if (variable.Type.Type == "var")
variable.Type = Dom.Refactoring.CodeGenerator.ConvertType(result.ResolvedType, new Dom.ClassFinder(result.CallingMember));
variable.IsReferenceType = result.ResolvedType.IsReferenceType == true;
if (IsInSel(variable.StartPos, this.currentSelection) && HasOccurrencesAfter(CSharpNameComparer, 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.Type));
otherReturnValues.Add(new VariableDeclaration(variable.Name, variable.Initializer, variable.Type));
}
foreach (var variable in variablesList) {
LoggingService.Debug(variable);
bool hasOccurrencesAfter = HasOccurrencesAfter(CSharpNameComparer, this.parentNode, end, variable.Name, variable.StartPos, variable.EndPos);
bool isInitialized = !variable.Initializer.IsNull;
bool hasAssignment = HasAssignment(newMethod, variable);
if (IsInSel(variable.StartPos, this.currentSelection) && hasOccurrencesAfter) {
possibleReturnValues.Add(new VariableDeclaration(variable.Name, variable.Initializer, variable.Type));
otherReturnValues.Add(new VariableDeclaration(variable.Name, variable.Initializer, variable.Type));
}
if (!(IsInSel(variable.StartPos, this.currentSelection) || IsInSel(variable.EndPos, this.currentSelection))) {
ParameterDeclarationExpression newParam = null;
FindReferenceVisitor frv = new FindReferenceVisitor(CSharpNameComparer, variable.Name, start, end);
parentNode.AcceptVisitor(frv, null);
if ((frv.Identifiers.Count > 0) && (!(IsInSel(variable.StartPos, this.currentSelection) || IsInSel(variable.EndPos, this.currentSelection)))) {
bool hasOccurrencesAfter = HasOccurrencesAfter(CSharpNameComparer, this.parentNode, new Location(this.currentSelection.EndPosition.Column + 1, this.currentSelection.EndPosition.Line + 1), variable.Name, variable.StartPos, variable.EndPos);
bool isInitialized = IsInitializedVariable(CSharpNameComparer, this.parentNode, variable);
bool hasAssignment = HasAssignment(newMethod, variable);
bool getsAssigned = pair.Value.Count > 0;
ParameterDeclarationExpression newParam = null;
if (hasOccurrencesAfter && isInitialized)
newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, (variable.IsReferenceType) ? ParameterModifiers.None : ParameterModifiers.Ref);
if ((hasOccurrencesAfter && isInitialized) || variable.WasRefParam)
newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.Ref);
else {
if ((hasOccurrencesAfter && hasAssignment) || variable.WasOutParam)
newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.Out);
else {
if (hasOccurrencesAfter && hasAssignment)
newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.Out);
if (!hasOccurrencesAfter)
newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.None);
else {
if (!hasOccurrencesAfter && getsAssigned)
newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.None);
else {
if (!hasOccurrencesAfter && !isInitialized)
newMethod.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(variable.Name, variable.Initializer, variable.Type)));
else
newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.In);
}
if (!hasOccurrencesAfter && !isInitialized)
newMethod.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(variable.Name, variable.Initializer, variable.Type)));
else
newParam = new ParameterDeclarationExpression(variable.Type, variable.Name, ParameterModifiers.In);
}
}
if (newParam != null)
newMethod.Parameters.Add(newParam);
}
if (newParam != null)
newMethod.Parameters.Add(newParam);
}
}
@ -187,10 +144,6 @@ namespace SharpRefactoring @@ -187,10 +144,6 @@ namespace SharpRefactoring
this.beforeCallDeclarations.Add(new LocalVariableDeclaration(varDecl));
}
}
ReplaceUnnecessaryVariableDeclarationsTransformer t = new ReplaceUnnecessaryVariableDeclarationsTransformer(paramsAsVarDecls);
newMethod.AcceptVisitor(t, null);
CreateReturnStatement(newMethod, possibleReturnValues);
@ -200,6 +153,40 @@ namespace SharpRefactoring @@ -200,6 +153,40 @@ namespace SharpRefactoring
return true;
}
Variable ResolveVariable(Variable variable)
{
Dom.ParseInformation info = ParserService.GetParseInformation(this.textEditor.FileName);
Dom.ExpressionResult res = new Dom.ExpressionResult(variable.Name,
Dom.DomRegion.FromLocation(variable.StartPos, variable.EndPos),
Dom.ExpressionContext.Default, null);
Dom.ResolveResult result = this.GetResolver().Resolve(res, info, this.textEditor.Document.TextContent);
if (variable.Type.Type == "var")
variable.Type = Dom.Refactoring.CodeGenerator.ConvertType(result.ResolvedType, new Dom.ClassFinder(result.CallingMember));
variable.IsReferenceType = result.ResolvedType.IsReferenceType == true;
return variable;
}
IEnumerable<Variable> FromParameters(MethodDeclaration newMethod)
{
foreach (ParameterDeclarationExpression pde in parentNode.Parameters) {
FindReferenceVisitor frv = new FindReferenceVisitor(CSharpNameComparer, pde.ParameterName, newMethod.Body.StartLocation, newMethod.Body.EndLocation);
newMethod.AcceptVisitor(frv, null);
if (frv.Identifiers.Count > 0) {
pde.ParamModifier &= ~(ParameterModifiers.Params);
if (parentNode is MethodDeclaration) {
yield return new Variable((parentNode as MethodDeclaration).Body, pde);
} else {
throw new NotSupportedException("not supported!");
}
}
}
}
public override IOutputAstVisitor GetOutputVisitor()
{

11
src/AddIns/Misc/SharpRefactoring/Src/ExtractMethodCommand.cs

@ -6,24 +6,13 @@ @@ -6,24 +6,13 @@
// </file>
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;
using ICSharpCode.TextEditor.Document;
using SharpRefactoring.Forms;
using SharpRefactoring.Transformers;
using SharpRefactoring.Visitors;
namespace SharpRefactoring
{

45
src/AddIns/Misc/SharpRefactoring/Src/MethodExtractorBase.cs

@ -40,6 +40,8 @@ namespace SharpRefactoring @@ -40,6 +40,8 @@ namespace SharpRefactoring
protected Dom.IClass currentClass;
protected Dom.IProjectContent currentProjectContent;
protected Location start, end;
public Statement Caller {
get { return caller; }
}
@ -53,6 +55,9 @@ namespace SharpRefactoring @@ -53,6 +55,9 @@ namespace SharpRefactoring
this.currentDocument = textEditor.Document;
this.textEditor = textEditor;
this.currentSelection = selection;
this.start = new Location(this.currentSelection.StartPosition.Column + 1, this.currentSelection.StartPosition.Line + 1);
this.end = new Location(this.currentSelection.EndPosition.Column + 1, this.currentSelection.EndPosition.Line + 1);
}
protected static Statement CreateCaller(ParametrizedNode parent, MethodDeclaration method, VariableDeclaration returnVariable)
@ -249,8 +254,7 @@ namespace SharpRefactoring @@ -249,8 +254,7 @@ namespace SharpRefactoring
member.AcceptVisitor(frv, null);
foreach (IdentifierExpression identifier in frv.Identifiers)
{
foreach (IdentifierExpression identifier in frv.Identifiers) {
if (identifier.StartLocation > location)
return true;
}
@ -258,25 +262,6 @@ namespace SharpRefactoring @@ -258,25 +262,6 @@ namespace SharpRefactoring
return false;
}
protected bool IsInitializedVariable(StringComparer nameComparer, ParametrizedNode member, Variable variable)
{
if (!(variable.Initializer.IsNull)) {
return true;
} else {
FindReferenceVisitor frv = new FindReferenceVisitor(nameComparer, 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, Variable variable)
{
HasAssignmentsVisitor hav = new HasAssignmentsVisitor(variable.Name, variable.Type, variable.StartPos, variable.EndPos);
@ -300,6 +285,8 @@ namespace SharpRefactoring @@ -300,6 +285,8 @@ namespace SharpRefactoring
public Location EndPos { get; set; }
public Expression Initializer { get; set; }
public bool IsReferenceType { get; set; }
public bool WasOutParam { get; set; }
public bool WasRefParam { get; set; }
public Variable(LocalLookupVariable v)
{
@ -309,5 +296,21 @@ namespace SharpRefactoring @@ -309,5 +296,21 @@ namespace SharpRefactoring
this.EndPos = v.EndPos;
this.Initializer = v.Initializer;
}
public Variable(BlockStatement block, ParameterDeclarationExpression param)
{
this.Type = param.TypeReference;
this.Name = param.ParameterName;
this.StartPos = block.StartLocation;
this.EndPos = block.EndLocation;
this.Initializer = param.DefaultValue;
this.WasOutParam = (param.ParamModifier & ParameterModifiers.Out) == ParameterModifiers.Out;
this.WasRefParam = (param.ParamModifier & ParameterModifiers.Ref) == ParameterModifiers.Ref;
}
public override string ToString()
{
return "[ " + this.Type.Type + " " + this.Name + " ]";
}
}
}

65
src/AddIns/Misc/SharpRefactoring/Src/Transformers/ReplaceUnnecessaryVariableDeclarationsTransformer.cs

@ -1,65 +0,0 @@ @@ -1,65 +0,0 @@
// <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…
Cancel
Save