Browse Source

Fixed some create class action issues.

pull/32/merge
Mike Krüger 13 years ago
parent
commit
0cabc8818e
  1. 41
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateClassDeclarationAction.cs
  2. 59
      ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateClassDeclarationTests.cs

41
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateClassDeclarationAction.cs

@ -61,54 +61,73 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (service != null && !service.IsValidName(resolveResult.Identifier, AffectedEntity.Class)) { if (service != null && !service.IsValidName(resolveResult.Identifier, AffectedEntity.Class)) {
yield break; yield break;
} }
ClassType classType = GuessClassType (node);
yield return new CodeAction(context.TranslateString("Create class"), script => { yield return new CodeAction(classType == ClassType.Interface ? context.TranslateString("Create interface") : context.TranslateString("Create class"), script => {
script.CreateNewType(CreateType(context, service, node)); script.CreateNewType(CreateType(context, service, node, classType));
}); });
if (node.Parent is TypeDeclaration || classType == ClassType.Interface)
yield break;
yield return new CodeAction(context.TranslateString("Create nested class"), script => { yield return new CodeAction(context.TranslateString("Create nested class"), script => {
script.InsertWithCursor( script.InsertWithCursor(
context.TranslateString("Create nested class"), context.TranslateString("Create nested class"),
Script.InsertPosition.Before, Script.InsertPosition.Before,
CreateType(context, service, node) CreateType(context, service, node, classType)
); );
}); });
} }
static TypeDeclaration CreateType(RefactoringContext context, NamingConventionService service, AstNode node) static ClassType GuessClassTypeByName(string identifier)
{
if (identifier.Length > 0 && identifier[0] == 'I' && char.IsUpper (identifier[1]))
return ClassType.Interface;
return ClassType.Class;
}
static ClassType GuessClassType(AstNode node)
{
if (node is SimpleType)
return GuessClassTypeByName (((SimpleType)node).Identifier);
if (node is IdentifierExpression)
return GuessClassTypeByName (((IdentifierExpression)node).Identifier);
return ClassType.Class;
}
static TypeDeclaration CreateType(RefactoringContext context, NamingConventionService service, AstNode node, ClassType classType)
{ {
TypeDeclaration result; TypeDeclaration result;
if (node is SimpleType) { if (node is SimpleType) {
result = CreateClassFromType(context, (SimpleType)node); result = CreateClassFromType(context, classType, (SimpleType)node);
} else if (node is ObjectCreateExpression) { } else if (node is ObjectCreateExpression) {
result = CreateClassFromObjectCreation(context, (ObjectCreateExpression)node); result = CreateClassFromObjectCreation(context, (ObjectCreateExpression)node);
} else { } else {
result = CreateClassFromIdentifier(context, (IdentifierExpression)node); result = CreateClassFromIdentifier(context, classType, (IdentifierExpression)node);
} }
return AddBaseTypesAccordingToNamingRules(context, service, result); return AddBaseTypesAccordingToNamingRules(context, service, result);
} }
static TypeDeclaration CreateClassFromIdentifier(RefactoringContext context, IdentifierExpression identifierExpression) static TypeDeclaration CreateClassFromIdentifier(RefactoringContext context, ClassType classType, IdentifierExpression identifierExpression)
{ {
var result = new TypeDeclaration { Name = identifierExpression.Identifier }; var result = new TypeDeclaration { Name = identifierExpression.Identifier, ClassType = classType };
var entity = identifierExpression.GetParent<EntityDeclaration>(); var entity = identifierExpression.GetParent<EntityDeclaration>();
if (entity != null) if (entity != null)
result.Modifiers |= entity.Modifiers & Modifiers.Public; result.Modifiers |= entity.Modifiers & Modifiers.Public;
return result; return result;
} }
static TypeDeclaration CreateClassFromType(RefactoringContext context, SimpleType simpleType) static TypeDeclaration CreateClassFromType(RefactoringContext context, ClassType classType, SimpleType simpleType)
{ {
TypeDeclaration result; TypeDeclaration result;
string className = simpleType.Identifier; string className = simpleType.Identifier;
if (simpleType.Parent is Attribute) { if (simpleType.Parent is Attribute && classType == ClassType.Class) {
if (!className.EndsWith("Attribute", System.StringComparison.Ordinal)) if (!className.EndsWith("Attribute", System.StringComparison.Ordinal))
className += "Attribute"; className += "Attribute";
} }
result = new TypeDeclaration { Name = className }; result = new TypeDeclaration { Name = className, ClassType = classType };
var entity = simpleType.GetParent<EntityDeclaration>(); var entity = simpleType.GetParent<EntityDeclaration>();
if (entity != null) if (entity != null)
result.Modifiers |= entity.Modifiers & Modifiers.Public; result.Modifiers |= entity.Modifiers & Modifiers.Public;

59
ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateClassDeclarationTests.cs

@ -26,6 +26,7 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using ICSharpCode.NRefactory.CSharp.Refactoring; using ICSharpCode.NRefactory.CSharp.Refactoring;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.CodeActions namespace ICSharpCode.NRefactory.CSharp.CodeActions
{ {
@ -62,7 +63,7 @@ class TestClass
"); ");
} }
[Test()] [Test]
public void TestNestedCreateClass() public void TestNestedCreateClass()
{ {
Test<CreateClassDeclarationAction>( Test<CreateClassDeclarationAction>(
@ -92,7 +93,7 @@ class TestClass
", 1); ", 1);
} }
[Test()] [Test]
public void TestEmptyConstructor () public void TestEmptyConstructor ()
{ {
Test<CreateClassDeclarationAction> ( Test<CreateClassDeclarationAction> (
@ -118,7 +119,7 @@ class TestClass
"); ");
} }
[Test()] [Test]
public void TestCreatePublicEventArgs () public void TestCreatePublicEventArgs ()
{ {
Test<CreateClassDeclarationAction> ( Test<CreateClassDeclarationAction> (
@ -138,7 +139,7 @@ class TestClass
"); ");
} }
[Test()] [Test]
public void TestCreateInternalEventArgs () public void TestCreateInternalEventArgs ()
{ {
Test<CreateClassDeclarationAction> ( Test<CreateClassDeclarationAction> (
@ -158,7 +159,7 @@ class TestClass
"); ");
} }
[Test()] [Test]
public void TestCreateAttribute () public void TestCreateAttribute ()
{ {
Test<CreateClassDeclarationAction> ( Test<CreateClassDeclarationAction> (
@ -178,7 +179,7 @@ class TestClass
"); ");
} }
[Test()] [Test]
public void TestCreateAttributeCase2 () public void TestCreateAttributeCase2 ()
{ {
Test<CreateClassDeclarationAction> ( Test<CreateClassDeclarationAction> (
@ -198,7 +199,7 @@ class TestClass
"); ");
} }
[Test()] [Test]
public void TestCreateException () public void TestCreateException ()
{ {
Test<CreateClassDeclarationAction> ( Test<CreateClassDeclarationAction> (
@ -348,5 +349,49 @@ class TestClass
"); ");
} }
/// <summary>
/// Bug 10671 - Auto-Fix of Base Class is wrong (generates invalid code)
/// </summary>
[Test]
public void TestBug10671 ()
{
var input = @"
namespace TestConsole
{
public class Test : $BaseMissing
{
}
}
";
// action allowed to create a nested class
var context = TestRefactoringContext.Create (input, false);
var actions = new CreateClassDeclarationAction().GetActions (context);
Assert.AreEqual (1, actions.Count ());
}
[Test]
public void TestCreateInterface ()
{
Test<CreateClassDeclarationAction> (
@"
class TestClass
{
private readonly $IFoo _foo;
}
", @"
interface IFoo
{
}
class TestClass
{
private readonly IFoo _foo;
}
");
}
} }
} }

Loading…
Cancel
Save