Browse Source

Added more context actions.

newNRvisualizers
Mike Krüger 15 years ago
parent
commit
be5139a776
  1. 25
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/AddAnotherAccessor.cs
  2. 109
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/CreateEventInvocator.cs
  3. 76
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/CreateField.cs
  4. 129
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/CreateLocalVariable.cs
  5. 66
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/CreateProperty.cs
  6. 95
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/GenerateGetter.cs
  7. 86
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/GenerateSwitchLabels.cs
  8. 99
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/InsertAnonymousMethodSignature.cs
  9. 122
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/RemoveBackingStore.cs
  10. 2
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/SplitDeclarationAndAssignment.cs
  11. 5
      ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/UseExplicitType.cs
  12. 16
      ICSharpCode.NRefactory/CSharp/Refactoring/NodeOutputAction.cs
  13. 7
      ICSharpCode.NRefactory/CSharp/Refactoring/RefactoringContext.cs
  14. 40
      ICSharpCode.NRefactory/CSharp/Refactoring/Script.cs
  15. 6
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

25
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/AddAnotherAccessor.cs

@ -55,26 +55,25 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -55,26 +55,25 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
pdecl.AddChild (accessor, pdecl.Setter.IsNull ? PropertyDeclaration.SetterRole : PropertyDeclaration.GetterRole);
using (var script = context.StartScript ()) {
script.Select (accessorStatement);
script.InsertBefore (pdecl.RBraceToken, accessor);
script.Select (accessorStatement);
script.FormatText (ctx => GetPropertyDeclaration (context));
}
}
static Statement BuildAccessorStatement (RefactoringContext context, PropertyDeclaration pdecl)
{
// TODO:
// if (pdecl.Setter.IsNull && !pdecl.Getter.IsNull) {
// var field = RemoveBackingStore.ScanGetter (context, pdecl);
// if (field != null)
// return new ExpressionStatement (new AssignmentExpression (new IdentifierExpression (field.Name), AssignmentOperatorType.Assign, new IdentifierExpression ("value")));
// }
//
// if (!pdecl.Setter.IsNull && pdecl.Getter.IsNull) {
// var field = RemoveBackingStore.ScanSetter (context, pdecl);
// if (field != null)
// return new ReturnStatement (new IdentifierExpression (field.Name));
// }
if (pdecl.Setter.IsNull && !pdecl.Getter.IsNull) {
var field = RemoveBackingStore.ScanGetter (context, pdecl);
if (field != null)
return new ExpressionStatement (new AssignmentExpression (new IdentifierExpression (field.Name), AssignmentOperatorType.Assign, new IdentifierExpression ("value")));
}
if (!pdecl.Setter.IsNull && pdecl.Getter.IsNull) {
var field = RemoveBackingStore.ScanSetter (context, pdecl);
if (field != null)
return new ReturnStatement (new IdentifierExpression (field.Name));
}
return new ThrowStatement (new ObjectCreateExpression (context.CreateShortType ("System.NotImplementedException")));
}

109
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/CreateEventInvocator.cs

@ -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;
}
}
}

76
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/CreateField.cs

@ -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> ();
}
}
}

129
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/CreateLocalVariable.cs

@ -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;
}
}
}

66
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/CreateProperty.cs

@ -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> ();
}
}
}

95
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/GenerateGetter.cs

@ -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> ();
}
}
}

86
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/GenerateSwitchLabels.cs

@ -24,60 +24,59 @@ @@ -24,60 +24,59 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
public class GenerateSwitchLabels : IContextAction
{
// TODO: Resolver!
public bool IsValid (RefactoringContext context)
{
return false;
// var switchStatement = GetSwitchStatement (context);
// if (switchStatement == null)
// return false;
// var resolver = context.Resolver;
// var result = resolver.Resolve (switchStatement.Expression.ToString (), new DomLocation (switchStatement.StartLocation.Line, switchStatement.StartLocation.Column));
// if (result == null || result.ResolvedType == null)
// return false;
// var type = context.Document.Dom.GetType (result.ResolvedType);
//
// return type != null && type.ClassType == ClassType.Enum;
var switchStatement = GetSwitchStatement (context);
if (switchStatement == null)
return false;
var result = context.ResolveType (switchStatement.Expression);
if (result == null)
return false;
var type = context.GetDefinition (result);
return type != null && type.ClassType == ClassType.Enum;
}
public void Run (RefactoringContext context)
{
// var switchStatement = GetSwitchStatement (context);
// var resolver = context.Resolver;
//
// var result = resolver.Resolve (switchStatement.Expression.ToString (), new DomLocation (switchStatement.StartLocation.Line, switchStatement.StartLocation.Column));
// var type = context.Document.Dom.GetType (result.ResolvedType);
//
// var target = new TypeReferenceExpression (ShortenTypeName (context.Document, result.ResolvedType));
// foreach (var field in type.Fields) {
// if (!(field.IsLiteral || field.IsConst))
// continue;
// switchStatement.SwitchSections.Add (new SwitchSection () {
// CaseLabels = {
// new CaseLabel (new MemberReferenceExpression ( target.Clone (), field.Name))
// },
// Statements = {
// new BreakStatement ()
// }
// });
// }
//
// switchStatement.SwitchSections.Add (new SwitchSection () {
// CaseLabels = {
// new CaseLabel ()
// },
// Statements = {
// new ThrowStatement (new ObjectCreateExpression (ShortenTypeName (context.Document, "System.ArgumentOutOfRangeException")))
// }
// });
//
// context.Do (switchStatement.Replace (context.Document, switchStatement));
var switchStatement = GetSwitchStatement (context);
var result = context.ResolveType (switchStatement.Expression);
var type = context.GetDefinition (result);
var newSwitch = (SwitchStatement)switchStatement.Clone ();
var target = new TypeReferenceExpression (context.CreateShortType (result));
foreach (var field in type.Fields) {
if (field.IsSynthetic || !field.IsConst)
continue;
newSwitch.SwitchSections.Add (new SwitchSection () {
CaseLabels = {
new CaseLabel (new MemberReferenceExpression (target.Clone (), field.Name))
},
Statements = {
new BreakStatement ()
}
});
}
newSwitch.SwitchSections.Add (new SwitchSection () {
CaseLabels = {
new CaseLabel ()
},
Statements = {
new ThrowStatement (new ObjectCreateExpression (context.CreateShortType ("System.ArgumentOutOfRangeException")))
}
});
using (var script = context.StartScript ()) {
script.Replace (switchStatement, newSwitch);
}
}
static SwitchStatement GetSwitchStatement (RefactoringContext context)
@ -89,4 +88,3 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -89,4 +88,3 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
}

99
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/InsertAnonymousMethodSignature.cs

@ -24,66 +24,71 @@ @@ -24,66 +24,71 @@
// 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;
using System.Text;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
public class InsertAnonymousMethodSignature : IContextAction
{
//TODO: Resolve
public bool IsValid (RefactoringContext context)
{
return false;
// IType type;
// return GetAnonymousMethodExpression (context, out type) != null;
ITypeDefinition type;
return GetAnonymousMethodExpression (context, out type) != null;
}
public void Run (RefactoringContext context)
{
// IType type;
// var anonymousMethodExpression = GetAnonymousMethodExpression (context, out type);
//
// var delegateMethod = type.Methods.First ();
//
// var sb = new StringBuilder ("(");
// for (int k = 0; k < delegateMethod.Parameters.Count; k++) {
// if (k > 0)
// sb.Append (", ");
// var parameterType = context.Document.Dom.GetType (delegateMethod.Parameters [k].ReturnType);
// IReturnType returnType = parameterType != null ? new DomReturnType (parameterType) : delegateMethod.Parameters [k].ReturnType;
// sb.Append (context.OutputNode (ShortenTypeName (context.Document, returnType), 0));
// sb.Append (" ");
// sb.Append (delegateMethod.Parameters [k].Name);
// }
// sb.Append (")");
//
// context.DoInsert (context.Document.Editor.LocationToOffset (anonymousMethodExpression.DelegateToken.EndLocation.Line, anonymousMethodExpression.DelegateToken.EndLocation.Column), sb.ToString ());
ITypeDefinition type;
var anonymousMethodExpression = GetAnonymousMethodExpression (context, out type);
var delegateMethod = type.Methods.First ();
var sb = new StringBuilder ("(");
for (int k = 0; k < delegateMethod.Parameters.Count; k++) {
if (k > 0)
sb.Append (", ");
var paramType = delegateMethod.Parameters [k].Type;
sb.Append (paramType.ToString ());
sb.Append (" ");
sb.Append (delegateMethod.Parameters [k].Name);
}
sb.Append (")");
using (var script = context.StartScript ()) {
script.InsertText (context.GetOffset (anonymousMethodExpression.DelegateToken.EndLocation), sb.ToString ());
}
}
// AnonymousMethodExpression GetAnonymousMethodExpression (RefactoringContext context, out IType delegateType)
// {
// delegateType = null;
//
// var anonymousMethodExpression = context.GetNode<AnonymousMethodExpression> ();
// if (anonymousMethodExpression == null || !anonymousMethodExpression.DelegateToken.Contains (context.Location.Line, context.Location.Column) || anonymousMethodExpression.HasParameterList)
// return null;
// MonoDevelop.Projects.Dom.ResolveResult resolveResult = null;
// var parent = anonymousMethodExpression.Parent;
// if (parent is AssignmentExpression) {
// resolveResult = context.Resolver.Resolve (((AssignmentExpression)parent).Left.ToString (), context.Location);
// } else if (parent is VariableDeclarationStatement) {
// resolveResult = context.Resolver.Resolve (((VariableDeclarationStatement)parent).Type.ToString (), context.Location);
// } else if (parent is InvocationExpression) {
// // TODO: handle invocations
// }
//
// if (resolveResult == null || resolveResult.ResolvedType == null)
// return null;
// delegateType = context.Document.Dom.GetType (resolveResult.ResolvedType);
// if (delegateType == null || delegateType.ClassType != ClassType.Delegate)
// return null;
//
// return anonymousMethodExpression;
// }
static AnonymousMethodExpression GetAnonymousMethodExpression (RefactoringContext context, out ITypeDefinition delegateType)
{
delegateType = null;
var anonymousMethodExpression = context.GetNode<AnonymousMethodExpression> ();
if (anonymousMethodExpression == null || !anonymousMethodExpression.DelegateToken.Contains (context.Location.Line, context.Location.Column) || anonymousMethodExpression.HasParameterList)
return null;
AstType resolvedType = null;
var parent = anonymousMethodExpression.Parent;
if (parent is AssignmentExpression) {
resolvedType = context.ResolveType (((AssignmentExpression)parent).Left);
} else if (parent is VariableDeclarationStatement) {
resolvedType = context.ResolveType (((VariableDeclarationStatement)parent).Type);
} else if (parent is InvocationExpression) {
// TODO: handle invocations
}
if (resolvedType == null)
return null;
delegateType = context.GetDefinition (resolvedType);
if (delegateType == null || delegateType.ClassType != ClassType.Delegate)
return null;
return anonymousMethodExpression;
}
}
}

122
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/RemoveBackingStore.cs

@ -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;
}
}
}

2
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/SplitDeclarationAndAssignment.cs

@ -52,8 +52,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -52,8 +52,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
newVarDecl.Variables.First ().Initializer = Expression.Null;
using (var script = context.StartScript ()) {
script.Replace (varDecl, varDecl.Parent is ForStatement ? (AstNode)assign : new ExpressionStatement (assign));
script.InsertBefore (varDecl, newVarDecl);
script.Replace (varDecl, varDecl.Parent is ForStatement ? (AstNode)assign : new ExpressionStatement (assign));
}
}

5
ICSharpCode.NRefactory/CSharp/Refactoring/ContextAction/UseExplicitType.cs

@ -24,6 +24,8 @@ @@ -24,6 +24,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
@ -37,7 +39,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -37,7 +39,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public void Run (RefactoringContext context)
{
var varDecl = GetVariableDeclarationStatement (context);
var resolver = context.Resolver;
using (var script = context.StartScript ()) {
script.Replace (varDecl.Type, context.ResolveType (varDecl.Variables.First ().Initializer));
@ -47,7 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -47,7 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
static VariableDeclarationStatement GetVariableDeclarationStatement (RefactoringContext context)
{
var result = context.GetNode<VariableDeclarationStatement> ();
if (result.Variables.Count == 1 && !result.Variables.First ().Initializer.IsNull && result.Type.Contains (context.Location.Line, context.Location.Column) && result.Type.IsMatch (new SimpleType ("var"))) {
if (result != null && result.Variables.Count == 1 && !result.Variables.First ().Initializer.IsNull && result.Type.Contains (context.Location.Line, context.Location.Column) && result.Type.IsMatch (new SimpleType ("var"))) {
if (context.ResolveType (result.Variables.First ().Initializer) == null)
return null;
return result;

16
ICSharpCode.NRefactory/CSharp/Refactoring/NodeOutputAction.cs

@ -40,6 +40,22 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -40,6 +40,22 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
get;
set;
}
public void Trim ()
{
for (int i = 0; i < Text.Length; i++) {
char ch = Text [i];
if (ch != ' ' && ch != '\t') {
if (i > 0) {
Text = Text.Substring (i);
foreach (var seg in NodeSegments.Values) {
seg.Offset -= i;
}
}
break;
}
}
}
public class Segment : ISegment
{

7
ICSharpCode.NRefactory/CSharp/Refactoring/RefactoringContext.cs

@ -25,6 +25,8 @@ @@ -25,6 +25,8 @@
// THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
@ -51,6 +53,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -51,6 +53,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public abstract AstType CreateShortType (AstType fullType);
public abstract AstType CreateShortType (string fullTypeName);
public abstract ITypeDefinition GetDefinition (AstType resolvedType);
public abstract void ReplaceReferences (IMember member, MemberDeclaration member);
public AstNode GetNode ()
{
@ -82,6 +88,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -82,6 +88,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
#region Resolving
public abstract AstType ResolveType (AstNode node);
public abstract IEnumerable<IMember> ResolveMember (Expression expression);
#endregion
public string GetNameProposal (string name, bool camelCase = true)

40
ICSharpCode.NRefactory/CSharp/Refactoring/Script.cs

@ -62,15 +62,19 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -62,15 +62,19 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public void InsertBefore (AstNode node, AstNode insertNode)
{
var startOffset = Context.GetOffset (node.StartLocation);
var startOffset = Context.GetOffset (node.StartLocation.Line, 1);
var output = OutputNode (GetIndentLevelAt (startOffset), insertNode);
if (!(insertNode is Expression || insertNode is AstType))
output.Text += Context.EolMarker;
Queue (Context.CreateNodeOutputAction (startOffset, 0, output));
}
public void AddTo (BlockStatement bodyStatement, AstNode insertNode)
{
var startOffset = Context.GetOffset (bodyStatement.LBraceToken.StartLocation) + 1;
var output = OutputNode (GetIndentLevelAt (startOffset), insertNode);
var output = OutputNode (GetIndentLevelAt (startOffset), insertNode, true);
Queue (Context.CreateNodeOutputAction (startOffset, 0, output));
}
@ -106,9 +110,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -106,9 +110,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var startOffset = Context.GetOffset (node.StartLocation);
var endOffset = Context.GetOffset (node.EndLocation);
int level = 0;
if (!(replaceWith is Expression))
if (!(replaceWith is Expression) && !(replaceWith is AstType))
level = GetIndentLevelAt (startOffset);
Queue (Context.CreateNodeOutputAction (startOffset, endOffset - startOffset, OutputNode (level, replaceWith)));
NodeOutput output = OutputNode (level, replaceWith);
output.Trim ();
Queue (Context.CreateNodeOutputAction (startOffset, endOffset - startOffset, output));
}
public void FormatText (Func<RefactoringContext, AstNode> callback)
@ -120,8 +126,17 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -120,8 +126,17 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
Queue (Context.CreateNodeSelectionAction (node));
}
public enum InsertPosition {
Start,
Before,
After,
End
}
public abstract void InsertWithCursor (string operation, AstNode node, InsertPosition defaultPosition);
int GetIndentLevelAt (int offset)
protected int GetIndentLevelAt (int offset)
{
var node = Context.Unit.GetNodeAt (Context.GetLocation (offset));
int level = 0;
@ -133,20 +148,21 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -133,20 +148,21 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return level;
}
NodeOutput OutputNode (int indentLevel, AstNode node)
protected NodeOutput OutputNode (int indentLevel, AstNode node, bool startWithNewLine = false)
{
NodeOutput result = new NodeOutput ();
var formatter = new StringBuilderOutputFormatter ();
var result = new NodeOutput ();
var stringWriter = new System.IO.StringWriter ();
var formatter = new TextWriterOutputFormatter (stringWriter);
formatter.Indentation = indentLevel;
formatter.EolMarker = Context.EolMarker;
if (node is Statement)
stringWriter.NewLine = Context.EolMarker;
if (startWithNewLine)
formatter.NewLine ();
var visitor = new OutputVisitor (formatter, Context.FormattingOptions);
visitor.OutputStarted += (sender, e) => {
result.NodeSegments [e.AstNode] = new NodeOutput.Segment (formatter.Length);
result.NodeSegments [e.AstNode] = new NodeOutput.Segment (stringWriter.GetStringBuilder ().Length);
};
visitor.OutputFinished += (sender, e) => {
result.NodeSegments [e.AstNode].EndOffset = formatter.Length;
result.NodeSegments [e.AstNode].EndOffset = stringWriter.GetStringBuilder ().Length;
};
node.AcceptVisitor (visitor, null);
result.Text = formatter.ToString ().TrimEnd ();

6
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -386,6 +386,12 @@ @@ -386,6 +386,12 @@
<Compile Include="CSharp\Refactoring\ContextAction\SplitString.cs" />
<Compile Include="CSharp\Refactoring\ContextAction\UseExplicitType.cs" />
<Compile Include="CSharp\Refactoring\ContextAction\UseVarKeyword.cs" />
<Compile Include="CSharp\Refactoring\ContextAction\CreateEventInvocator.cs" />
<Compile Include="CSharp\Refactoring\ContextAction\CreateField.cs" />
<Compile Include="CSharp\Refactoring\ContextAction\CreateLocalVariable.cs" />
<Compile Include="CSharp\Refactoring\ContextAction\CreateProperty.cs" />
<Compile Include="CSharp\Refactoring\ContextAction\RemoveBackingStore.cs" />
<Compile Include="CSharp\Refactoring\ContextAction\GenerateGetter.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="CSharp\" />

Loading…
Cancel
Save