2
// CreateOverloadWithoutParameterAction.cs
5
// Mansheng Yang <lightyang0@gmail.com>
7
// Copyright (c) 2012 Mansheng Yang <lightyang0@gmail.com>
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
using System.Collections.Generic;
29
using ICSharpCode.NRefactory.Semantics;
30
using ICSharpCode.NRefactory.TypeSystem;
32
namespace ICSharpCode.NRefactory.CSharp.Refactoring
34
[ContextAction ("Create overload without parameter", Description = "Create overload without the selected parameter.")]
35
public class CreateOverloadWithoutParameterAction : SpecializedCodeAction<ParameterDeclaration>
37
protected override CodeAction GetAction (RefactoringContext context, ParameterDeclaration node)
39
if (!node.DefaultExpression.IsNull)
41
if (node.ParameterModifier == ParameterModifier.This || node.ParameterModifier == ParameterModifier.Params)
44
var methodDecl = node.Parent as MethodDeclaration;
45
if (methodDecl == null)
48
// explicit implementation
49
if (!methodDecl.PrivateImplementationType.IsNull)
52
// find existing method
53
var method = (IMethod)((MemberResolveResult)context.Resolve (methodDecl)).Member;
54
var parameters = new List<IParameter> (method.Parameters.Where (param => param.Name != node.Name));
55
if (method.DeclaringType.GetMethods (
56
m => m.Name == method.Name && m.TypeParameters.Count == method.TypeParameters.Count)
57
.Any (m => ParameterListComparer.Instance.Equals (m.Parameters, parameters)))
60
return new CodeAction (context.TranslateString ("Create overload without parameter"),
63
var defaultExpr = GetDefaultValueExpression (context, node.Type);
65
var body = new BlockStatement ();
67
if (node.ParameterModifier == ParameterModifier.Ref) {
68
body.Add (new VariableDeclarationStatement (node.Type.Clone (), node.Name, defaultExpr));
69
argExpr = GetArgumentExpression (node);
70
} else if (node.ParameterModifier == ParameterModifier.Out) {
71
body.Add (new VariableDeclarationStatement (node.Type.Clone (), node.Name));
72
argExpr = GetArgumentExpression (node);
74
argExpr = defaultExpr;
76
body.Add (new InvocationExpression (new IdentifierExpression (methodDecl.Name),
77
methodDecl.Parameters.Select (param => param == node ? argExpr : GetArgumentExpression(param))));
79
var decl = (MethodDeclaration)methodDecl.Clone ();
80
decl.Parameters.Remove (decl.Parameters.First (param => param.Name == node.Name));
83
script.InsertWithCursor ("Create overload without parameter", Script.InsertPosition.Before, decl);
85
//if (node.ParameterModifier != ParameterModifier.Out)
86
// script.Link (defaultExpr);
90
static Expression GetArgumentExpression(ParameterDeclaration parameter)
92
var identifierExpr = new IdentifierExpression(parameter.Name);
93
switch (parameter.ParameterModifier) {
94
case ParameterModifier.Out:
95
return new DirectionExpression (FieldDirection.Out, identifierExpr);
96
case ParameterModifier.Ref:
97
return new DirectionExpression (FieldDirection.Ref, identifierExpr);
99
return identifierExpr;
102
static Expression GetDefaultValueExpression (RefactoringContext context, AstType astType)
104
var type = context.ResolveType (astType);
107
if (type.Kind == TypeKind.Array)
108
return new ObjectCreateExpression (astType.Clone ());
111
if (type.Kind == TypeKind.Enum) {
112
var members = type.GetMembers ().ToArray();
113
if (members.Length == 0)
114
return new DefaultValueExpression (astType.Clone ());
115
return astType.Member(members[0].Name).Clone ();
118
if ((type.IsReferenceType ?? false) || type.Kind == TypeKind.Dynamic)
119
return new NullReferenceExpression ();
121
var typeDefinition = type.GetDefinition ();
122
if (typeDefinition != null) {
123
switch (typeDefinition.KnownTypeCode) {
124
case KnownTypeCode.Boolean:
125
return new PrimitiveExpression (false);
127
case KnownTypeCode.Char:
128
return new PrimitiveExpression ('\0');
130
case KnownTypeCode.SByte:
131
case KnownTypeCode.Byte:
132
case KnownTypeCode.Int16:
133
case KnownTypeCode.UInt16:
134
case KnownTypeCode.Int32:
135
case KnownTypeCode.UInt32:
136
case KnownTypeCode.Int64:
137
case KnownTypeCode.UInt64:
138
case KnownTypeCode.Single:
139
case KnownTypeCode.Double:
140
case KnownTypeCode.Decimal:
141
return new PrimitiveExpression (0);
143
case KnownTypeCode.NullableOfT:
144
return new NullReferenceExpression ();
146
if (type.Kind == TypeKind.Struct)
147
return new ObjectCreateExpression (astType.Clone ());
149
return new DefaultValueExpression (astType.Clone ());