Browse Source

Improved "Extract Method" and added IsReferenceType to IReturnType

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3512 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 18 years ago
parent
commit
e0c660f7bb
  1. 51
      src/AddIns/Misc/SharpRefactoring/Src/CSharpMethodExtractor.cs
  2. 25
      src/AddIns/Misc/SharpRefactoring/Src/MethodExtractorBase.cs
  3. 30
      src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs
  4. 36
      src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
  5. 6
      src/Main/Base/Test/Utils/MockDefaultReturnType.cs
  6. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs
  7. 8
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs
  8. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs
  9. 9
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs
  10. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs
  11. 9
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs

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

@ -4,18 +4,23 @@ @@ -4,18 +4,23 @@
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision: 3287 $</version>
// </file>
using ICSharpCode.SharpDevelop;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.AstBuilder;
using ICSharpCode.NRefactory.PrettyPrinter;
using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.TextEditor.Document;
using SharpRefactoring.Transformers;
using SharpRefactoring.Visitors;
using Dom = ICSharpCode.SharpDevelop.Dom;
namespace SharpRefactoring
{
@ -52,6 +57,8 @@ namespace SharpRefactoring @@ -52,6 +57,8 @@ namespace SharpRefactoring
this.specialsList = parser.Lexer.SpecialTracker.RetrieveSpecials();
}
this.currentProjectContent = ParserService.GetProjectContent(ProjectService.CurrentProject);
MethodDeclaration newMethod = new MethodDeclaration();
List<VariableDeclaration> possibleReturnValues = new List<VariableDeclaration>();
@ -74,7 +81,7 @@ namespace SharpRefactoring @@ -74,7 +81,7 @@ namespace SharpRefactoring
newMethod.Modifier = parentNode.Modifier;
newMethod.Modifier &= ~(Modifiers.Internal | Modifiers.Protected | Modifiers.Private | Modifiers.Public);
newMethod.Modifier &= ~(Modifiers.Internal | Modifiers.Protected | Modifiers.Private | Modifiers.Public | Modifiers.Override);
foreach (ParameterDeclarationExpression pde in parentNode.Parameters)
{
@ -105,36 +112,40 @@ namespace SharpRefactoring @@ -105,36 +112,40 @@ namespace SharpRefactoring
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);
foreach (KeyValuePair<string, List<LocalLookupVariable>> pair in ltv.Variables) {
foreach (LocalLookupVariable variable in pair.Value) {
if (variable.StartPos > end)
continue;
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));
}
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);
FindReferenceVisitor frv = new FindReferenceVisitor(true, variable.Name, start, end);
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 hasOccurrencesAfter = 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)
if (hasOccurrencesAfter && isInitialized)
newMethod.Parameters.Add(new ParameterDeclarationExpression(variable.TypeRef, variable.Name, ParameterModifiers.Ref));
else {
if (hasOccurrences && hasAssignment)
if (hasOccurrencesAfter && hasAssignment)
newMethod.Parameters.Add(new ParameterDeclarationExpression(variable.TypeRef, variable.Name, ParameterModifiers.Out));
else {
if (!hasOccurrences && getsAssigned)
if (!hasOccurrencesAfter && getsAssigned)
newMethod.Parameters.Add(new ParameterDeclarationExpression(variable.TypeRef, variable.Name, ParameterModifiers.None));
else {
if (!hasOccurrences && !isInitialized)
if (!hasOccurrencesAfter && !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));
@ -159,12 +170,32 @@ namespace SharpRefactoring @@ -159,12 +170,32 @@ namespace SharpRefactoring
this.beforeCallDeclarations.Add(new LocalVariableDeclaration(varDecl));
}
}
ReplaceUnnecessaryVariableDeclarationsTransformer t = new ReplaceUnnecessaryVariableDeclarationsTransformer(paramsAsVarDecls);
newMethod.AcceptVisitor(t, null);
CreateReturnStatement(newMethod, possibleReturnValues);
bool hasReturnStatement = false;
foreach (INode node in newMethod.Body.Children) {
if (node is ReturnStatement) {
hasReturnStatement = true;
}
}
if (!hasReturnStatement) {
Dom.IMember member = GetParentMember(this.textEditor, this.currentSelection.StartPosition);
Dom.IReturnType returnType = TypeVisitor.CreateReturnType(newMethod.TypeReference, member.DeclaringType, member,
this.currentSelection.StartPosition.Line, this.currentSelection.StartPosition.Column, member.DeclaringType.ProjectContent, true);
if (returnType.IsReferenceType == null || returnType.IsReferenceType == true)
newMethod.Body.AddChild(new ReturnStatement(new PrimitiveExpression(null, "null")));
else
newMethod.Body.AddChild(new ReturnStatement(ExpressionBuilder.CreateDefaultValueForType(newMethod.TypeReference)));
}
this.extractedMethod = newMethod;

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

@ -4,17 +4,18 @@ @@ -4,17 +4,18 @@
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision: 3287 $</version>
// </file>
using ICSharpCode.TextEditor;
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.SharpDevelop.Project;
using ICSharpCode.TextEditor.Document;
using SharpRefactoring.Visitors;
using Dom = ICSharpCode.SharpDevelop.Dom;
@ -37,6 +38,9 @@ namespace SharpRefactoring @@ -37,6 +38,9 @@ namespace SharpRefactoring
protected VariableDeclaration returnedVariable;
protected List<ISpecial> specialsList;
protected Dom.IClass currentClass;
protected Dom.IProjectContent currentProjectContent;
public Statement Caller {
get { return caller; }
}
@ -88,19 +92,15 @@ namespace SharpRefactoring @@ -88,19 +92,15 @@ namespace SharpRefactoring
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 {
} 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)));
this.returnedVariable = possibleReturnValues[possibleReturnValues.Count - 1];
} else {
newMethod.TypeReference = new TypeReference("void");
this.returnedVariable = null;
}
else newMethod.TypeReference = new TypeReference("void");
}
if (newMethod.TypeReference.Type == "void") {
this.returnedVariable = null;
} else {
this.returnedVariable = possibleReturnValues[possibleReturnValues.Count - 1];
}
}
@ -208,6 +208,11 @@ namespace SharpRefactoring @@ -208,6 +208,11 @@ namespace SharpRefactoring
throw new InvalidOperationException("Cannot use plain MethodExtractor, please use a language specific implementation!");
}
protected Dom.IMember GetParentMember(ICSharpCode.TextEditor.TextEditorControl textEditor, TextLocation location)
{
return GetParentMember(textEditor, location.Line, location.Column);
}
protected Dom.IMember GetParentMember(ICSharpCode.TextEditor.TextEditorControl textEditor, int line, int column)
{
Dom.ParseInformation parseInfo = ParserService.GetParseInformation(textEditor.FileName);

30
src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs

@ -53,6 +53,36 @@ namespace ICSharpCode.NRefactory.AstBuilder @@ -53,6 +53,36 @@ namespace ICSharpCode.NRefactory.AstBuilder
throw new ArgumentNullException("arguments");
return new ObjectCreateExpression(createType, new List<Expression>(arguments));
}
public static Expression CreateDefaultValueForType(TypeReference type)
{
if (type != null && !type.IsArrayType) {
switch (type.SystemType) {
case "System.SByte":
case "System.Byte":
case "System.Int16":
case "System.UInt16":
case "System.Int32":
case "System.UInt32":
case "System.Int64":
case "System.UInt64":
case "System.Single":
case "System.Double":
return new PrimitiveExpression(0, "0");
case "System.Char":
return new PrimitiveExpression('\0', "'\\0'");
case "System.Object":
case "System.String":
return new PrimitiveExpression(null, "null");
case "System.Boolean":
return new PrimitiveExpression(false, "false");
default:
return new DefaultValueExpression(type);
}
} else {
return new PrimitiveExpression(null, "null");
}
}
}
#endif
}

36
src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs

@ -5,10 +5,10 @@ @@ -5,10 +5,10 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.NRefactory.AstBuilder;
using System;
using System.Collections.Generic;
using System.Reflection;
using ICSharpCode.NRefactory.Ast;
using Attribute = ICSharpCode.NRefactory.Ast.Attribute;
@ -244,7 +244,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -244,7 +244,7 @@ namespace ICSharpCode.NRefactory.Visitors
methodDeclaration.Body.AcceptVisitor(visitor, null);
if (visitor.replacementCount > 0) {
Expression init;
init = GetDefaultValueForType(methodDeclaration.TypeReference);
init = ExpressionBuilder.CreateDefaultValueForType(methodDeclaration.TypeReference);
methodDeclaration.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, methodDeclaration.TypeReference)));
methodDeclaration.Body.Children[0].Parent = methodDeclaration.Body;
methodDeclaration.Body.AddChild(new ReturnStatement(new IdentifierExpression(FunctionReturnValueName)));
@ -497,41 +497,11 @@ namespace ICSharpCode.NRefactory.Visitors @@ -497,41 +497,11 @@ namespace ICSharpCode.NRefactory.Visitors
VariableDeclaration decl = localVariableDeclaration.Variables[i];
if (decl.FixedArrayInitialization.IsNull && decl.Initializer.IsNull) {
TypeReference type = localVariableDeclaration.GetTypeForVariable(i);
decl.Initializer = GetDefaultValueForType(type);
decl.Initializer = ExpressionBuilder.CreateDefaultValueForType(type);
}
}
}
return base.VisitLocalVariableDeclaration(localVariableDeclaration, data);
}
Expression GetDefaultValueForType(TypeReference type)
{
if (type != null && !type.IsArrayType) {
switch (type.SystemType) {
case "System.SByte":
case "System.Byte":
case "System.Int16":
case "System.UInt16":
case "System.Int32":
case "System.UInt32":
case "System.Int64":
case "System.UInt64":
case "System.Single":
case "System.Double":
return new PrimitiveExpression(0, "0");
case "System.Char":
return new PrimitiveExpression('\0', "'\\0'");
case "System.Object":
case "System.String":
return new PrimitiveExpression(null, "null");
case "System.Boolean":
return new PrimitiveExpression(false, "false");
default:
return new DefaultValueExpression(type);
}
} else {
return new PrimitiveExpression(null, "null");
}
}
}
}

6
src/Main/Base/Test/Utils/MockDefaultReturnType.cs

@ -148,5 +148,11 @@ namespace ICSharpCode.SharpDevelop.Tests.Utils @@ -148,5 +148,11 @@ namespace ICSharpCode.SharpDevelop.Tests.Utils
{
throw new NotImplementedException();
}
public Nullable<bool> IsReferenceType {
get {
throw new NotImplementedException();
}
}
}
}

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs

@ -129,5 +129,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -129,5 +129,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{
return null;
}
public virtual bool? IsReferenceType { get { return null; } }
}
}

8
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs

@ -226,5 +226,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -226,5 +226,13 @@ namespace ICSharpCode.SharpDevelop.Dom
return c.DotNetName;
}
}
public override Nullable<bool> IsReferenceType {
get {
return (this.c.ClassType == ClassType.Class
|| this.c.ClassType == ClassType.Interface
|| this.c.ClassType == ClassType.Delegate);
}
}
}
}

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs

@ -117,6 +117,10 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -117,6 +117,10 @@ namespace ICSharpCode.SharpDevelop.Dom
return list;
}
public override Nullable<bool> IsReferenceType {
get { return null; }
}
public override string ToString()
{
return String.Format("[GenericReturnType: {0}]", typeParameter);

9
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs

@ -217,5 +217,14 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -217,5 +217,14 @@ namespace ICSharpCode.SharpDevelop.Dom
{
return CastToDecoratingReturnType<ConstructedReturnType>();
}
public virtual bool? IsReferenceType {
get {
IReturnType baseType = BaseType;
bool? tmp = (baseType != null && TryEnter()) ? baseType.IsReferenceType : null;
Leave();
return tmp;
}
}
}
}

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs

@ -126,5 +126,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -126,5 +126,7 @@ namespace ICSharpCode.SharpDevelop.Dom
bool IsConstructedReturnType { get; }
ConstructedReturnType CastToConstructedReturnType();
bool? IsReferenceType { get; }
}
}

9
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs

@ -717,5 +717,14 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring @@ -717,5 +717,14 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring
document.EndUndoableAction();
}
#endregion
public static NR.Expression CreateDefaultValueForType(IReturnType type)
{
if (type.IsReferenceType != null && type.IsReferenceType != false) {
return null;
}
return null;
}
}
}

Loading…
Cancel
Save