diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
index 369a6b98a1..74a8bd2586 100644
--- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
+++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
@@ -355,6 +355,7 @@
+
diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateClassDeclarationAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateClassDeclarationAction.cs
new file mode 100644
index 0000000000..75f54a02f9
--- /dev/null
+++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateClassDeclarationAction.cs
@@ -0,0 +1,83 @@
+//
+// CreateClassDeclarationAction.cs
+//
+// Author:
+// Mike Krüger
+//
+// Copyright (c) 2012 Xamarin
+//
+// 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.Collections.Generic;
+using ICSharpCode.NRefactory.Semantics;
+using System.Linq;
+
+namespace ICSharpCode.NRefactory.CSharp.Refactoring
+{
+ [ContextAction("Create class", Description = "Creates a class declaration out of an object creation.")]
+ public class CreateClassDeclarationAction : ICodeActionProvider
+ {
+ public IEnumerable GetActions(RefactoringContext context)
+ {
+ var createExpression = context.GetNode();
+ if (createExpression == null)
+ yield break;
+
+ var resolveResult = context.Resolve(createExpression) as UnknownIdentifierResolveResult;
+ if (resolveResult == null)
+ yield break;
+
+ var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
+ if (service != null && !service.IsValidName(resolveResult.Identifier, AffectedEntity.Class)) {
+ yield break;
+ }
+
+ yield return new CodeAction(context.TranslateString("Create class"), script => {
+ script.CreateNewType(CreateClassDeclaration(context, createExpression));
+ });
+
+ yield return new CodeAction(context.TranslateString("Create nested class"), script => {
+ script.InsertWithCursor(context.TranslateString("Create nested class"), CreateClassDeclaration(context, createExpression), Script.InsertPosition.Before);
+ });
+ }
+
+ static TypeDeclaration CreateClassDeclaration(RefactoringContext context, ObjectCreateExpression createExpression)
+ {
+ string className = createExpression.Type.GetText();
+ if (!createExpression.Arguments.Any()) {
+ return new TypeDeclaration() { Name = className };
+ }
+ var decl = new ConstructorDeclaration() {
+ Name = className,
+ Modifiers = Modifiers.Public,
+ Body = new BlockStatement() {
+ new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
+ }
+ };
+ decl.Parameters.AddRange(CreateMethodDeclarationAction.GenerateParameters(context, createExpression.Arguments));
+
+ return new TypeDeclaration() {
+ Name = className,
+ Members = {
+ decl
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateConstructorDeclarationAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateConstructorDeclarationAction.cs
index cab66dd7e3..0b4161dc22 100644
--- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateConstructorDeclarationAction.cs
+++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateConstructorDeclarationAction.cs
@@ -35,14 +35,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public IEnumerable GetActions(RefactoringContext context)
{
var createExpression = context.GetNode();
- if (createExpression == null) {
+ if (createExpression == null)
yield break;
- }
var resolveResult = context.Resolve(createExpression) as CSharpInvocationResolveResult;
- if (resolveResult == null || !resolveResult.IsError || resolveResult.Member.DeclaringTypeDefinition == null || resolveResult.Member.DeclaringTypeDefinition.IsSealed || resolveResult.Member.DeclaringTypeDefinition.Region.IsEmpty) {
+ if (resolveResult == null || !resolveResult.IsError || resolveResult.Member.DeclaringTypeDefinition == null || resolveResult.Member.DeclaringTypeDefinition.IsSealed || resolveResult.Member.DeclaringTypeDefinition.Region.IsEmpty)
yield break;
- }
yield return new CodeAction(context.TranslateString("Create constructor"), script => {
var decl = new ConstructorDeclaration() {
@@ -52,10 +50,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
- foreach (var parameter in CreateMethodDeclarationAction.GenerateParameters (context, createExpression.Arguments)) {
- decl.Parameters.Add(parameter);
- }
-
+ decl.Parameters.AddRange(CreateMethodDeclarationAction.GenerateParameters (context, createExpression.Arguments));
+
script.InsertWithCursor(context.TranslateString("Create constructor"), decl, resolveResult.Member.DeclaringTypeDefinition);
});
}
diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateIndexerAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateIndexerAction.cs
index cc088df5dc..2be158da91 100644
--- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateIndexerAction.cs
+++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateIndexerAction.cs
@@ -75,9 +75,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
},
};
- foreach (var parameter in CreateMethodDeclarationAction.GenerateParameters (context, indexer.Arguments)) {
- decl.Parameters.Add(parameter);
- }
+ decl.Parameters.AddRange(CreateMethodDeclarationAction.GenerateParameters (context, indexer.Arguments));
if (isStatic)
decl.Modifiers |= Modifiers.Static;
diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs
index 5ee83581c1..2245e2e9a3 100644
--- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs
+++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs
@@ -145,9 +145,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
- foreach (var parameter in GenerateParameters (context, invocation.Arguments)) {
- decl.Parameters.Add(parameter);
- }
+ decl.Parameters.AddRange(GenerateParameters (context, invocation.Arguments));
if (isStatic) {
decl.Modifiers |= Modifiers.Static;
}
diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs
index ebda9297f7..80ac57b120 100644
--- a/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs
+++ b/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs
@@ -333,6 +333,32 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public virtual void Dispose()
{
}
+
+ public enum NewTypeContext {
+ ///
+ /// The class should be placed in a new file to the current namespace.
+ ///
+ CurrentNamespace,
+
+ ///
+ /// The class should be placed in the unit tests. (not implemented atm.)
+ ///
+ UnitTests
+ }
+
+ ///
+ /// Creates a new file containing the type, namespace and correct usings.
+ /// (Note: Should take care of IDE specific things, file headers, add to project, correct name).
+ ///
+ ///
+ /// New type to be created.
+ ///
+ ///
+ /// The Context in which the new type should be created.
+ ///
+ public virtual void CreateNewType(TypeDeclaration newType, NewTypeContext context = NewTypeContext.CurrentNamespace)
+ {
+ }
}
}
diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateClassDeclarationTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateClassDeclarationTests.cs
new file mode 100644
index 0000000000..f2ce577c6e
--- /dev/null
+++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateClassDeclarationTests.cs
@@ -0,0 +1,122 @@
+//
+// CreateClassDeclarationTests.cs
+//
+// Author:
+// Mike Krüger
+//
+// Copyright (c) 2012 Xamarin
+//
+// 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 NUnit.Framework;
+using ICSharpCode.NRefactory.CSharp.Refactoring;
+
+namespace ICSharpCode.NRefactory.CSharp.CodeActions
+{
+ [TestFixture]
+ public class CreateClassDeclarationTests : ContextActionTestBase
+ {
+ [Test()]
+ public void TestCreateClass ()
+ {
+ Test (
+@"
+class TestClass
+{
+ void TestMethod ()
+ {
+ $new Foo (0, ""Hello"");
+ }
+}
+", @"
+class Foo
+{
+ public Foo (int i, string hello)
+ {
+ throw new System.NotImplementedException ();
+ }
+}
+class TestClass
+{
+ void TestMethod ()
+ {
+ new Foo (0, ""Hello"");
+ }
+}
+");
+ }
+
+ [Test()]
+ public void TestNestedCreateClass ()
+ {
+ Test (
+@"
+class TestClass
+{
+ void TestMethod ()
+ {
+ $new Foo (0);
+ }
+}
+", @"
+class TestClass
+{
+ class Foo
+ {
+ public Foo (int i)
+ {
+ throw new System.NotImplementedException ();
+ }
+ }
+ void TestMethod ()
+ {
+ new Foo (0);
+ }
+}
+", 1);
+ }
+
+ [Test()]
+ public void TestEmptyConstructor ()
+ {
+ Test (
+@"
+class TestClass
+{
+ void TestMethod ()
+ {
+ $new Foo ();
+ }
+}
+", @"
+class Foo
+{
+}
+class TestClass
+{
+ void TestMethod ()
+ {
+ new Foo ();
+ }
+}
+");
+ }
+
+ }
+}
diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateConstructorDeclarationActionTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateConstructorDeclarationTests.cs
similarity index 97%
rename from ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateConstructorDeclarationActionTests.cs
rename to ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateConstructorDeclarationTests.cs
index 9f1819b8fc..dffc01e08b 100644
--- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateConstructorDeclarationActionTests.cs
+++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateConstructorDeclarationTests.cs
@@ -31,7 +31,7 @@ using ICSharpCode.NRefactory.CSharp.Refactoring;
namespace ICSharpCode.NRefactory.CSharp.CodeActions
{
[TestFixture]
- public class CreateConstructorDeclarationActionTests : ContextActionTestBase
+ public class CreateConstructorDeclarationTests : ContextActionTestBase
{
[Test()]
public void TestCreateConstructor ()
diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs
index b58f3564f7..676f7608bf 100644
--- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs
+++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs
@@ -166,6 +166,11 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions
context.CancellationToken);
}
+ public override void CreateNewType (TypeDeclaration newType, NewTypeContext context)
+ {
+ var output = OutputNode (0, newType, true);
+ InsertText (0, output.Text);
+ }
}
#region Text stuff
diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
index eed14292e6..4a4c9755b1 100644
--- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
+++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
@@ -256,7 +256,8 @@
-
+
+