15 changed files with 764 additions and 119 deletions
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// CreateEventInvocator.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@novell.com>
|
||||
//
|
||||
// Copyright (c) 2011 Mike Krüger <mkrueger@novell.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
using System.Linq; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring |
||||
{ |
||||
public class CreateEventInvocator : IContextAction |
||||
{ |
||||
public bool IsValid (RefactoringContext context) |
||||
{ |
||||
VariableInitializer initializer; |
||||
var eventDeclaration = GetEventDeclaration (context, out initializer); |
||||
if (eventDeclaration == null) |
||||
return false; |
||||
var type = (TypeDeclaration)eventDeclaration.Parent; |
||||
return !type.Members.Any (m => m is MethodDeclaration && ((MethodDeclaration)m).Name == "On" + initializer.Name); |
||||
} |
||||
|
||||
public void Run (RefactoringContext context) |
||||
{ |
||||
VariableInitializer initializer; |
||||
var eventDeclaration = GetEventDeclaration (context, out initializer); |
||||
var type = context.GetDefinition (context.ResolveType (eventDeclaration.ReturnType)); |
||||
if (type == null) |
||||
return; |
||||
var invokeMethod = type.Methods.Where (m => m.Name == "Invoke").FirstOrDefault (); |
||||
if (invokeMethod == null) |
||||
return; |
||||
|
||||
bool hasSenderParam = false; |
||||
/* var pars = invokeMethod.Parameters; |
||||
if (invokeMethod.Parameters.Any ()) { |
||||
var first = invokeMethod.Parameters [0]; |
||||
if (first.Name == "sender" && first.Type.FullName == "System.Object") { |
||||
hasSenderParam = true; |
||||
pars = invokeMethod.Parameters.Skip (1); |
||||
} |
||||
} |
||||
|
||||
foreach (var par in pars) { |
||||
var typeName = ShortenTypeName (context.Document, par.ReturnType); |
||||
var decl = new ParameterDeclaration (typeName, par.Name); |
||||
methodDeclaration.Parameters.Add (decl); |
||||
}*/ |
||||
|
||||
const string handlerName = "handler"; |
||||
|
||||
var arguments = new List<Expression> (); |
||||
if (hasSenderParam) |
||||
arguments.Add (new ThisReferenceExpression ()); |
||||
// foreach (var par in pars)
|
||||
// arguments.Add (new IdentifierExpression (par.Name));
|
||||
|
||||
var methodDeclaration = new MethodDeclaration () { |
||||
Name = "On" + initializer.Name, |
||||
ReturnType = context.CreateShortType (eventDeclaration.ReturnType), |
||||
Modifiers = ICSharpCode.NRefactory.CSharp.Modifiers.Protected | ICSharpCode.NRefactory.CSharp.Modifiers.Virtual, |
||||
Body = new BlockStatement () { |
||||
new VariableDeclarationStatement (context.CreateShortType (eventDeclaration.ReturnType), handlerName, new MemberReferenceExpression (new ThisReferenceExpression (), initializer.Name)), |
||||
new IfElseStatement () { |
||||
Condition = new BinaryOperatorExpression (new IdentifierExpression (handlerName), BinaryOperatorType.InEquality, new PrimitiveExpression (null)), |
||||
TrueStatement = new ExpressionStatement (new InvocationExpression (new IdentifierExpression (handlerName), arguments)) |
||||
} |
||||
} |
||||
}; |
||||
|
||||
using (var script = context.StartScript ()) { |
||||
script.InsertWithCursor ("Create event invocator", methodDeclaration, Script.InsertPosition.After); |
||||
} |
||||
} |
||||
|
||||
static EventDeclaration GetEventDeclaration (RefactoringContext context, out VariableInitializer initializer) |
||||
{ |
||||
var result = context.GetNode<EventDeclaration> (); |
||||
if (result == null) { |
||||
initializer = null; |
||||
return null; |
||||
} |
||||
initializer = result.Variables.First (v => v.NameToken.Contains (context.Location)); |
||||
return initializer != null ? result : null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// CreateField.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@novell.com>
|
||||
//
|
||||
// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory.PatternMatching; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring |
||||
{ |
||||
public class CreateField : IContextAction |
||||
{ |
||||
public bool IsValid (RefactoringContext context) |
||||
{ |
||||
var identifier = GetIdentifier (context); |
||||
if (identifier == null) |
||||
return false; |
||||
return context.ResolveType (identifier) == null && GuessType (context, identifier) != null; |
||||
} |
||||
|
||||
public void Run (RefactoringContext context) |
||||
{ |
||||
var identifier = GetIdentifier (context); |
||||
|
||||
using (var script = context.StartScript ()) { |
||||
script.InsertWithCursor ("Create field", GenerateFieldDeclaration (context, identifier), Script.InsertPosition.Before); |
||||
} |
||||
} |
||||
|
||||
static AstNode GenerateFieldDeclaration (RefactoringContext context, IdentifierExpression identifier) |
||||
{ |
||||
return new FieldDeclaration () { |
||||
ReturnType = GuessType (context, identifier), |
||||
Variables = { new VariableInitializer (identifier.Identifier) } |
||||
}; |
||||
} |
||||
|
||||
internal static AstType GuessType (RefactoringContext context, IdentifierExpression identifier) |
||||
{ |
||||
if (identifier.Parent is AssignmentExpression) { |
||||
var assign = (AssignmentExpression)identifier.Parent; |
||||
var other = assign.Left == identifier ? assign.Right : assign.Left; |
||||
return context.ResolveType (other); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static IdentifierExpression GetIdentifier (RefactoringContext context) |
||||
{ |
||||
return context.GetNode<IdentifierExpression> (); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// CreateLocalVariable.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@novell.com>
|
||||
//
|
||||
// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
using ICSharpCode.NRefactory.PatternMatching; |
||||
using System.Linq; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring |
||||
{ |
||||
public class CreateLocalVariable : IContextAction |
||||
{ |
||||
public List<IdentifierExpression> GetUnresolvedArguments (RefactoringContext context) |
||||
{ |
||||
var expressions = new List<IdentifierExpression> (); |
||||
|
||||
var invocation = GetInvocation (context); |
||||
if (invocation != null) { |
||||
foreach (var arg in invocation.Arguments) { |
||||
IdentifierExpression identifier; |
||||
if (arg is DirectionExpression) { |
||||
identifier = ((DirectionExpression)arg).Expression as IdentifierExpression; |
||||
} else if (arg is NamedArgumentExpression) { |
||||
identifier = ((NamedArgumentExpression)arg).Expression as IdentifierExpression; |
||||
} else { |
||||
identifier = arg as IdentifierExpression; |
||||
} |
||||
if (identifier == null) |
||||
continue; |
||||
|
||||
if (context.ResolveType (identifier) == null && GuessType (context, identifier) != null) |
||||
expressions.Insert (0, identifier); |
||||
} |
||||
} |
||||
return expressions; |
||||
} |
||||
|
||||
public bool IsValid (RefactoringContext context) |
||||
{ |
||||
if (GetUnresolvedArguments (context).Count > 0) |
||||
return true; |
||||
var identifier = CreateField.GetIdentifier (context); |
||||
if (identifier == null) |
||||
return false; |
||||
if (context.GetNode<Statement> () == null) |
||||
return false; |
||||
return context.ResolveType (identifier) == null && GuessType (context, identifier) != null; |
||||
} |
||||
|
||||
public void Run (RefactoringContext context) |
||||
{ |
||||
var stmt = context.GetNode<Statement> (); |
||||
var unresolvedArguments = GetUnresolvedArguments (context); |
||||
if (unresolvedArguments.Count > 0) { |
||||
using (var script = context.StartScript ()) { |
||||
foreach (var id in unresolvedArguments) { |
||||
script.InsertBefore (stmt, GenerateLocalVariableDeclaration (context, id)); |
||||
} |
||||
} |
||||
return; |
||||
} |
||||
|
||||
using (var script = context.StartScript ()) { |
||||
script.InsertBefore (stmt, GenerateLocalVariableDeclaration (context, CreateField.GetIdentifier (context))); |
||||
} |
||||
} |
||||
|
||||
AstNode GenerateLocalVariableDeclaration (RefactoringContext context, IdentifierExpression identifier) |
||||
{ |
||||
return new VariableDeclarationStatement () { |
||||
Type = GuessType (context, identifier), |
||||
Variables = { new VariableInitializer (identifier.Identifier) } |
||||
}; |
||||
} |
||||
|
||||
InvocationExpression GetInvocation (RefactoringContext context) |
||||
{ |
||||
return context.GetNode<InvocationExpression> (); |
||||
} |
||||
|
||||
AstType GuessType (RefactoringContext context, IdentifierExpression identifier) |
||||
{ |
||||
var type = CreateField.GuessType (context, identifier); |
||||
if (type != null) |
||||
return type; |
||||
|
||||
if (identifier != null && (identifier.Parent is InvocationExpression || identifier.Parent.Parent is InvocationExpression)) { |
||||
var invocation = (identifier.Parent as InvocationExpression) ?? (identifier.Parent.Parent as InvocationExpression); |
||||
var result = context.ResolveMember (invocation).FirstOrDefault () as IMethod; |
||||
if (result == null) |
||||
return null; |
||||
int i = 0; |
||||
foreach (var arg in invocation.Arguments) { |
||||
if (arg.Contains (identifier.StartLocation)) |
||||
break; |
||||
i++; |
||||
} |
||||
if (result.Parameters.Count < i) |
||||
return null; |
||||
return null; // context.CreateShortType (result.Parameters[i].Type);
|
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// CreateProperty.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@novell.com>
|
||||
//
|
||||
// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
using ICSharpCode.NRefactory.PatternMatching; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring |
||||
{ |
||||
public class CreateProperty : IContextAction |
||||
{ |
||||
public bool IsValid (RefactoringContext context) |
||||
{ |
||||
var identifier = CreateField.GetIdentifier (context); |
||||
if (identifier == null) |
||||
return false; |
||||
return context.ResolveType (identifier) == null && CreateField.GuessType (context, identifier) != null; |
||||
} |
||||
|
||||
public void Run (RefactoringContext context) |
||||
{ |
||||
var identifier = GetIdentifier (context); |
||||
using (var script = context.StartScript ()) { |
||||
script.InsertWithCursor ("Create property", GeneratePropertyDeclaration (context, identifier), Script.InsertPosition.Before); |
||||
} |
||||
} |
||||
|
||||
AstNode GeneratePropertyDeclaration (RefactoringContext context, IdentifierExpression identifier) |
||||
{ |
||||
return new PropertyDeclaration () { |
||||
ReturnType = CreateField.GuessType (context, identifier), |
||||
Name = identifier.Identifier, |
||||
Getter = new Accessor (), |
||||
Setter = new Accessor () |
||||
}; |
||||
} |
||||
|
||||
IdentifierExpression GetIdentifier (RefactoringContext context) |
||||
{ |
||||
return context.GetNode<IdentifierExpression> (); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,95 @@
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// GenerateGetter.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@novell.com>
|
||||
//
|
||||
// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory.PatternMatching; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring |
||||
{ |
||||
public class GenerateGetter : IContextAction |
||||
{ |
||||
public bool IsValid (RefactoringContext context) |
||||
{ |
||||
var initializer = GetVariableInitializer (context); |
||||
if (initializer == null || !initializer.NameToken.Contains (context.Location.Line, context.Location.Column)) |
||||
return false; |
||||
var type = initializer.Parent.Parent as TypeDeclaration; |
||||
if (type == null) |
||||
return false; |
||||
foreach (var member in type.Members) { |
||||
if (member is PropertyDeclaration && ContainsGetter ((PropertyDeclaration)member, initializer)) |
||||
return false; |
||||
} |
||||
return initializer.Parent is FieldDeclaration; |
||||
} |
||||
|
||||
public void Run (RefactoringContext context) |
||||
{ |
||||
var initializer = GetVariableInitializer (context); |
||||
var field = initializer.Parent as FieldDeclaration; |
||||
|
||||
using (var script = context.StartScript ()) { |
||||
script.InsertWithCursor ("Create getter", GeneratePropertyDeclaration (context, field, initializer), Script.InsertPosition.After); |
||||
} |
||||
} |
||||
|
||||
static PropertyDeclaration GeneratePropertyDeclaration (RefactoringContext context, FieldDeclaration field, VariableInitializer initializer) |
||||
{ |
||||
var mod = ICSharpCode.NRefactory.CSharp.Modifiers.Public; |
||||
if (field.HasModifier (ICSharpCode.NRefactory.CSharp.Modifiers.Static)) |
||||
mod |= ICSharpCode.NRefactory.CSharp.Modifiers.Static; |
||||
|
||||
return new PropertyDeclaration () { |
||||
Modifiers = mod, |
||||
Name = context.GetNameProposal (initializer.Name, false), |
||||
ReturnType = field.ReturnType.Clone (), |
||||
Getter = new Accessor () { |
||||
Body = new BlockStatement () { |
||||
new ReturnStatement (new IdentifierExpression (initializer.Name)) |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
|
||||
bool ContainsGetter (PropertyDeclaration property, VariableInitializer initializer) |
||||
{ |
||||
if (property.Getter.IsNull || property.Getter.Body.Statements.Count () != 1) |
||||
return false; |
||||
var ret = property.Getter.Body.Statements.Single () as ReturnStatement; |
||||
if (ret == null) |
||||
return false; |
||||
return ret.Expression.IsMatch (new IdentifierExpression (initializer.Name)) || |
||||
ret.Expression.IsMatch (new MemberReferenceExpression (new ThisReferenceExpression (), initializer.Name)); |
||||
} |
||||
|
||||
VariableInitializer GetVariableInitializer (RefactoringContext context) |
||||
{ |
||||
return context.GetNode<VariableInitializer> (); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// RemoveBackingStore.cs
|
||||
//
|
||||
// Author:
|
||||
// Mike Krüger <mkrueger@novell.com>
|
||||
//
|
||||
// Copyright (c) 2011 Mike Krüger <mkrueger@novell.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Refactoring |
||||
{ |
||||
public class RemoveBackingStore : IContextAction |
||||
{ |
||||
public bool IsValid (RefactoringContext context) |
||||
{ |
||||
return GetBackingField (context) != null; |
||||
} |
||||
|
||||
public void Run (RefactoringContext context) |
||||
{ |
||||
var property = context.GetNode<PropertyDeclaration> (); |
||||
var field = GetBackingField (context); |
||||
|
||||
context.ReplaceReferences (field, property); |
||||
|
||||
// create new auto property
|
||||
var newProperty = (PropertyDeclaration)property.Clone (); |
||||
newProperty.Getter.Body = BlockStatement.Null; |
||||
newProperty.Setter.Body = BlockStatement.Null; |
||||
|
||||
using (var script = context.StartScript ()) { |
||||
script.Remove (context.Unit.GetNodeAt<FieldDeclaration> (field.Region.BeginLine, field.Region.BeginColumn)); |
||||
script.Replace (property, newProperty); |
||||
} |
||||
|
||||
} |
||||
|
||||
// void ReplaceBackingFieldReferences (MDRefactoringContext context, IField backingStore, PropertyDeclaration property)
|
||||
// {
|
||||
// using (var monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true)) {
|
||||
// foreach (var memberRef in MonoDevelop.Ide.FindInFiles.ReferenceFinder.FindReferences (backingStore, monitor)) {
|
||||
// if (property.Contains (memberRef.Line, memberRef.Column))
|
||||
// continue;
|
||||
// if (backingStore.Location.Line == memberRef.Line && backingStore.Location.Column == memberRef.Column)
|
||||
// continue;
|
||||
// context.Do (new TextReplaceChange () {
|
||||
// FileName = memberRef.FileName,
|
||||
// Offset = memberRef.Position,
|
||||
// RemovedChars = memberRef.Name.Length,
|
||||
// InsertedText = property.Name
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
static IField GetBackingField (RefactoringContext context) |
||||
{ |
||||
var propertyDeclaration = context.GetNode<PropertyDeclaration> (); |
||||
// automatic properties always need getter & setter
|
||||
if (propertyDeclaration == null || propertyDeclaration.Getter.IsNull || propertyDeclaration.Setter.IsNull || propertyDeclaration.Getter.Body.IsNull || propertyDeclaration.Setter.Body.IsNull) |
||||
return null; |
||||
if (!context.HasCSharp3Support || propertyDeclaration.HasModifier (ICSharpCode.NRefactory.CSharp.Modifiers.Abstract) || ((TypeDeclaration)propertyDeclaration.Parent).ClassType == ICSharpCode.NRefactory.TypeSystem.ClassType.Interface) |
||||
return null; |
||||
var getterField = ScanGetter (context, propertyDeclaration); |
||||
if (getterField == null) |
||||
return null; |
||||
var setterField = ScanSetter (context, propertyDeclaration); |
||||
if (setterField == null) |
||||
return null; |
||||
if (getterField.Region != setterField.Region) |
||||
return null; |
||||
return getterField; |
||||
} |
||||
|
||||
internal static IField ScanGetter (RefactoringContext context, PropertyDeclaration propertyDeclaration) |
||||
{ |
||||
if (propertyDeclaration.Getter.Body.Statements.Count != 1) |
||||
return null; |
||||
var returnStatement = propertyDeclaration.Getter.Body.Statements.First () as ReturnStatement; |
||||
|
||||
var result = context.ResolveMember (returnStatement.Expression); |
||||
if (result == null) |
||||
return null; |
||||
return result.FirstOrDefault () as IField; |
||||
} |
||||
|
||||
internal static IField ScanSetter (RefactoringContext context, PropertyDeclaration propertyDeclaration) |
||||
{ |
||||
if (propertyDeclaration.Setter.Body.Statements.Count != 1) |
||||
return null; |
||||
var setAssignment = propertyDeclaration.Setter.Body.Statements.First () as ExpressionStatement; |
||||
var assignment = setAssignment != null ? setAssignment.Expression as AssignmentExpression : null; |
||||
if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign) |
||||
return null; |
||||
var result = context.ResolveMember (assignment.Left); |
||||
if (result == null) |
||||
return null; |
||||
return result.FirstOrDefault () as IField; |
||||
} |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue