diff --git a/src/AddIns/Misc/SharpRefactoring/Src/CSharpMethodExtractor.cs b/src/AddIns/Misc/SharpRefactoring/Src/CSharpMethodExtractor.cs
index dbb8723c59..ac35964eb5 100644
--- a/src/AddIns/Misc/SharpRefactoring/Src/CSharpMethodExtractor.cs
+++ b/src/AddIns/Misc/SharpRefactoring/Src/CSharpMethodExtractor.cs
@@ -4,18 +4,23 @@
//
// $Revision: 3287 $
//
+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
this.specialsList = parser.Lexer.SpecialTracker.RetrieveSpecials();
}
+ this.currentProjectContent = ParserService.GetProjectContent(ProjectService.CurrentProject);
+
MethodDeclaration newMethod = new MethodDeclaration();
List possibleReturnValues = new List();
@@ -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
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> 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
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;
diff --git a/src/AddIns/Misc/SharpRefactoring/Src/MethodExtractorBase.cs b/src/AddIns/Misc/SharpRefactoring/Src/MethodExtractorBase.cs
index 529f6e4b2b..84a51be665 100644
--- a/src/AddIns/Misc/SharpRefactoring/Src/MethodExtractorBase.cs
+++ b/src/AddIns/Misc/SharpRefactoring/Src/MethodExtractorBase.cs
@@ -4,17 +4,18 @@
//
// $Revision: 3287 $
//
+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
protected VariableDeclaration returnedVariable;
protected List specialsList;
+ protected Dom.IClass currentClass;
+ protected Dom.IProjectContent currentProjectContent;
+
public Statement Caller {
get { return caller; }
}
@@ -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
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);
diff --git a/src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs b/src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs
index 373c84e98d..59856ff762 100644
--- a/src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs
+++ b/src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs
@@ -53,6 +53,36 @@ namespace ICSharpCode.NRefactory.AstBuilder
throw new ArgumentNullException("arguments");
return new ObjectCreateExpression(createType, new List(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
}
diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
index 505b8b9ed1..257960c7c3 100644
--- a/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
+++ b/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
@@ -5,10 +5,10 @@
// $Revision$
//
+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
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
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");
- }
- }
}
}
diff --git a/src/Main/Base/Test/Utils/MockDefaultReturnType.cs b/src/Main/Base/Test/Utils/MockDefaultReturnType.cs
index cd7ef8af72..fdbbde1ff4 100644
--- a/src/Main/Base/Test/Utils/MockDefaultReturnType.cs
+++ b/src/Main/Base/Test/Utils/MockDefaultReturnType.cs
@@ -148,5 +148,11 @@ namespace ICSharpCode.SharpDevelop.Tests.Utils
{
throw new NotImplementedException();
}
+
+ public Nullable IsReferenceType {
+ get {
+ throw new NotImplementedException();
+ }
+ }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs
index 43d8e21c5f..a571031e4b 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs
@@ -129,5 +129,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{
return null;
}
+
+ public virtual bool? IsReferenceType { get { return null; } }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs
index 1b04b0699f..9fe6cb188b 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs
@@ -226,5 +226,13 @@ namespace ICSharpCode.SharpDevelop.Dom
return c.DotNetName;
}
}
+
+ public override Nullable IsReferenceType {
+ get {
+ return (this.c.ClassType == ClassType.Class
+ || this.c.ClassType == ClassType.Interface
+ || this.c.ClassType == ClassType.Delegate);
+ }
+ }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs
index fb11589903..14aba0d875 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs
@@ -117,6 +117,10 @@ namespace ICSharpCode.SharpDevelop.Dom
return list;
}
+ public override Nullable IsReferenceType {
+ get { return null; }
+ }
+
public override string ToString()
{
return String.Format("[GenericReturnType: {0}]", typeParameter);
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs
index 55f620de41..f50acf3618 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ProxyReturnType.cs
@@ -217,5 +217,14 @@ namespace ICSharpCode.SharpDevelop.Dom
{
return CastToDecoratingReturnType();
}
+
+ public virtual bool? IsReferenceType {
+ get {
+ IReturnType baseType = BaseType;
+ bool? tmp = (baseType != null && TryEnter()) ? baseType.IsReferenceType : null;
+ Leave();
+ return tmp;
+ }
+ }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs
index 0addea2fe9..128c66acf6 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IReturnType.cs
@@ -126,5 +126,7 @@ namespace ICSharpCode.SharpDevelop.Dom
bool IsConstructedReturnType { get; }
ConstructedReturnType CastToConstructedReturnType();
+
+ bool? IsReferenceType { get; }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs
index 95cc86ee3a..ade32f0bc6 100644
--- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs
@@ -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;
+ }
}
}