Browse Source

[CodeAction] Added CreateOverloadWithoutParameterAction

newNRvisualizers
Mansheng Yang 14 years ago
parent
commit
fc6c24cdf6
  1. 1
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  2. 141
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateOverloadWithoutParameterAction.cs
  3. 209
      ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateOverloadWithoutParameterTests.cs
  4. 1
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

1
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -245,6 +245,7 @@ @@ -245,6 +245,7 @@
<Compile Include="Refactoring\CodeActions\ConvertCastToAsAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertIfToSwitchAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertSwitchToIfAction.cs" />
<Compile Include="Refactoring\CodeActions\CreateOverloadWithoutParameterAction.cs" />
<Compile Include="Refactoring\CodeIssues\ExplicitConversionInForEachIssue.cs" />
<Compile Include="Refactoring\DocumentScript.cs" />
<Compile Include="Refactoring\PatternHelper.cs" />

141
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateOverloadWithoutParameterAction.cs

@ -0,0 +1,141 @@ @@ -0,0 +1,141 @@
//
// CreateOverloadWithoutParameterAction.cs
//
// Author:
// Mansheng Yang <lightyang0@gmail.com>
//
// Copyright (c) 2012 Mansheng Yang <lightyang0@gmail.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.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
[ContextAction ("Create overload without parameter", Description = "Create overload without the selected parameter.")]
public class CreateOverloadWithoutParameterAction : SpecializedCodeAction<ParameterDeclaration>
{
protected override CodeAction GetAction (RefactoringContext context, ParameterDeclaration node)
{
if (!node.DefaultExpression.IsNull)
return null;
if (node.ParameterModifier == ParameterModifier.This || node.ParameterModifier == ParameterModifier.Params)
return null;
var methodDecl = node.Parent as MethodDeclaration;
if (methodDecl == null)
return null;
// explicit implementation
if (!methodDecl.PrivateImplementationType.IsNull)
return null;
// find existing method
var method = (IMethod)((MemberResolveResult)context.Resolve (methodDecl)).Member;
var parameters = new List<IParameter> (method.Parameters.Where (param => param.Name != node.Name));
if (method.DeclaringType.GetMethods (
m => m.Name == method.Name && m.TypeParameters.Count == method.TypeParameters.Count)
.Any (m => ParameterListComparer.Instance.Equals (m.Parameters, parameters)))
return null;
return new CodeAction (context.TranslateString ("Create overload without parameter"),
script =>
{
var defaultExpr = GetDefaultValueExpression (context, node.Type);
var body = new BlockStatement ();
Expression argExpr;
if (node.ParameterModifier == ParameterModifier.Ref) {
body.Add (new VariableDeclarationStatement (node.Type.Clone (), node.Name, defaultExpr));
argExpr = new DirectionExpression (FieldDirection.Ref, new IdentifierExpression (node.Name));
} else if (node.ParameterModifier == ParameterModifier.Out) {
body.Add (new VariableDeclarationStatement (node.Type.Clone (), node.Name));
argExpr = new DirectionExpression (FieldDirection.Out, new IdentifierExpression (node.Name));
} else {
argExpr = defaultExpr;
}
body.Add (new InvocationExpression (new IdentifierExpression (methodDecl.Name),
methodDecl.Parameters.Select (param => param == node ? argExpr : new IdentifierExpression (param.Name))));
var decl = (MethodDeclaration)methodDecl.Clone ();
decl.Parameters.Remove (decl.Parameters.First (param => param.Name == node.Name));
decl.Body = body;
script.InsertWithCursor ("Create overload without parameter", Script.InsertPosition.Before, decl);
//if (node.ParameterModifier != ParameterModifier.Out)
// script.Link (defaultExpr);
});
}
static Expression GetDefaultValueExpression (RefactoringContext context, AstType astType)
{
var type = context.ResolveType (astType);
// array
if (type.Kind == TypeKind.Array)
return new ObjectCreateExpression (astType.Clone ());
// enum
if (type.Kind == TypeKind.Enum) {
var members = type.GetMembers ().ToArray();
if (members.Length == 0)
return new DefaultValueExpression (astType.Clone ());
return astType.Member(members[0].Name);
}
// reference, dynamic
if ((type.IsReferenceType ?? false) || type.Kind == TypeKind.Dynamic)
return new NullReferenceExpression ();
var typeDefinition = type.GetDefinition ();
if (typeDefinition != null) {
switch (typeDefinition.KnownTypeCode) {
case KnownTypeCode.Boolean:
return new PrimitiveExpression (false);
case KnownTypeCode.Char:
return new PrimitiveExpression ('\0');
case KnownTypeCode.SByte:
case KnownTypeCode.Byte:
case KnownTypeCode.Int16:
case KnownTypeCode.UInt16:
case KnownTypeCode.Int32:
case KnownTypeCode.UInt32:
case KnownTypeCode.Int64:
case KnownTypeCode.UInt64:
case KnownTypeCode.Single:
case KnownTypeCode.Double:
case KnownTypeCode.Decimal:
return new PrimitiveExpression (0);
case KnownTypeCode.NullableOfT:
return new NullReferenceExpression ();
}
if (type.Kind == TypeKind.Struct)
return new ObjectCreateExpression (astType.Clone ());
}
return new DefaultValueExpression (astType.Clone ());
}
}
}

209
ICSharpCode.NRefactory.Tests/CSharp/CodeActions/CreateOverloadWithoutParameterTests.cs

@ -0,0 +1,209 @@ @@ -0,0 +1,209 @@
//
// CreateOverloadWithoutParameterTests.cs
//
// Author:
// Mansheng Yang <lightyang0@gmail.com>
//
// Copyright (c) 2012 Mansheng Yang <lightyang0@gmail.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 NUnit.Framework;
using ICSharpCode.NRefactory.CSharp.Refactoring;
namespace ICSharpCode.NRefactory.CSharp.CodeActions
{
[TestFixture]
public class CreateOverloadWithoutParameterTests : ContextActionTestBase
{
[Test]
public void Test ()
{
Test<CreateOverloadWithoutParameterAction> (@"
class Test
{
void TestMethod (int $i)
{
}
}", @"
class Test
{
void TestMethod ()
{
TestMethod (0);
}
void TestMethod (int i)
{
}
}");
}
[Test]
public void TestByRefParameter ()
{
Test<CreateOverloadWithoutParameterAction> (
@"class Test
{
void TestMethod (ref int $i)
{
}
}",
@"class Test
{
void TestMethod ()
{
int i = 0;
TestMethod (ref i);
}
void TestMethod (ref int i)
{
}
}");
}
[Test]
public void TestOutParameter ()
{
Test<CreateOverloadWithoutParameterAction> (
@"class Test
{
void TestMethod (out int $i)
{
}
}",
@"class Test
{
void TestMethod ()
{
int i;
TestMethod (out i);
}
void TestMethod (out int i)
{
}
}");
}
[Test]
public void TestDefaultValue ()
{
TestDefaultValue ("object", "null");
TestDefaultValue ("dynamic", "null");
TestDefaultValue ("int?", "null");
TestDefaultValue ("bool", "false");
TestDefaultValue ("double", "0");
TestDefaultValue ("char", "'\\0'");
TestDefaultValue ("System.DateTime", "new System.DateTime ()");
Test<CreateOverloadWithoutParameterAction> (@"
class Test
{
void TestMethod<T> (T $i)
{
}
}", @"
class Test
{
void TestMethod<T> ()
{
TestMethod (default(T));
}
void TestMethod<T> (T i)
{
}
}");
}
void TestDefaultValue (string type, string expectedValue)
{
Test<CreateOverloadWithoutParameterAction> (@"
class Test
{
void TestMethod (" + type + @" $i)
{
}
}", @"
class Test
{
void TestMethod ()
{
TestMethod (" + expectedValue + @");
}
void TestMethod (" + type + @" i)
{
}
}");
}
[Test]
public void TestOptionalParameter ()
{
TestWrongContext<CreateOverloadWithoutParameterAction> (
@"class Test
{
void TestMethod (int $i = 0)
{
}
}");
}
[Test]
public void TestExistingMethod ()
{
TestWrongContext<CreateOverloadWithoutParameterAction> (
@"class Test
{
void TestMethod (int c)
{
}
void TestMethod (int a, int $b)
{
}
}");
TestWrongContext<CreateOverloadWithoutParameterAction> (
@"class Test
{
void TestMethod <T> (T c)
{
}
void TestMethod <T> (T a, T $b)
{
}
}");
}
[Test]
public void TestExplicitImpl ()
{
TestWrongContext<CreateOverloadWithoutParameterAction> (
@"
interface ITest
{
void Test (int a, int b);
}
class Test : ITest
{
void ITest.Test (int a, int $b)
{
}
}");
}
}
}

1
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -85,6 +85,7 @@ @@ -85,6 +85,7 @@
<Compile Include="CSharp\CodeActions\ConvertCastToAsTests.cs" />
<Compile Include="CSharp\CodeActions\ConvertIfToSwtichTests.cs" />
<Compile Include="CSharp\CodeActions\ConvertSwitchToIfTests.cs" />
<Compile Include="CSharp\CodeActions\CreateOverloadWithoutParameterTests.cs" />
<Compile Include="CSharp\CodeIssues\ExplicitConversionInForEachIssueTests.cs" />
<Compile Include="CSharp\CSharpAmbienceTests.cs" />
<Compile Include="CSharp\CodeDomConvertVisitorTests.cs" />

Loading…
Cancel
Save