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 @@ -61,54 +61,73 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (service != null && !service.IsValidName(resolveResult.Identifier, AffectedEntity.Class)) {
yield break;
}
ClassType classType = GuessClassType (node);
yield return new CodeAction(context.TranslateString("Create class"), script => {
script.CreateNewType(CreateType(context, service, node));
yield return new CodeAction(classType == ClassType.Interface ? context.TranslateString("Create interface") : context.TranslateString("Create class"), script => {
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 => {
script.InsertWithCursor(
context.TranslateString("Create nested class"),
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;
if (node is SimpleType) {
result = CreateClassFromType(context, (SimpleType)node);
result = CreateClassFromType(context, classType, (SimpleType)node);
} else if (node is ObjectCreateExpression) {
result = CreateClassFromObjectCreation(context, (ObjectCreateExpression)node);
} else {
result = CreateClassFromIdentifier(context, (IdentifierExpression)node);
result = CreateClassFromIdentifier(context, classType, (IdentifierExpression)node);
}
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>();
if (entity != null)
result.Modifiers |= entity.Modifiers & Modifiers.Public;
return result;
}
static TypeDeclaration CreateClassFromType(RefactoringContext context, SimpleType simpleType)
static TypeDeclaration CreateClassFromType(RefactoringContext context, ClassType classType, SimpleType simpleType)
{
TypeDeclaration result;
string className = simpleType.Identifier;
if (simpleType.Parent is Attribute) {
if (simpleType.Parent is Attribute && classType == ClassType.Class) {
if (!className.EndsWith("Attribute", System.StringComparison.Ordinal))
className += "Attribute";
}
result = new TypeDeclaration { Name = className };
result = new TypeDeclaration { Name = className, ClassType = classType };
var entity = simpleType.GetParent<EntityDeclaration>();
if (entity != null)
result.Modifiers |= entity.Modifiers & Modifiers.Public;

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

@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
using System;
using NUnit.Framework;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.CodeActions
{
@ -62,7 +63,7 @@ class TestClass @@ -62,7 +63,7 @@ class TestClass
");
}
[Test()]
[Test]
public void TestNestedCreateClass()
{
Test<CreateClassDeclarationAction>(
@ -92,7 +93,7 @@ class TestClass @@ -92,7 +93,7 @@ class TestClass
", 1);
}
[Test()]
[Test]
public void TestEmptyConstructor ()
{
Test<CreateClassDeclarationAction> (
@ -118,7 +119,7 @@ class TestClass @@ -118,7 +119,7 @@ class TestClass
");
}
[Test()]
[Test]
public void TestCreatePublicEventArgs ()
{
Test<CreateClassDeclarationAction> (
@ -138,7 +139,7 @@ class TestClass @@ -138,7 +139,7 @@ class TestClass
");
}
[Test()]
[Test]
public void TestCreateInternalEventArgs ()
{
Test<CreateClassDeclarationAction> (
@ -158,7 +159,7 @@ class TestClass @@ -158,7 +159,7 @@ class TestClass
");
}
[Test()]
[Test]
public void TestCreateAttribute ()
{
Test<CreateClassDeclarationAction> (
@ -178,7 +179,7 @@ class TestClass @@ -178,7 +179,7 @@ class TestClass
");
}
[Test()]
[Test]
public void TestCreateAttributeCase2 ()
{
Test<CreateClassDeclarationAction> (
@ -198,7 +199,7 @@ class TestClass @@ -198,7 +199,7 @@ class TestClass
");
}
[Test()]
[Test]
public void TestCreateException ()
{
Test<CreateClassDeclarationAction> (
@ -348,5 +349,49 @@ class TestClass @@ -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