2
// CheckIfParameterIsNull.cs
5
// Mike Krüger <mkrueger@novell.com>
7
// Copyright (c) 2011 Mike Krüger <mkrueger@novell.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 ICSharpCode.NRefactory.PatternMatching;
28
using System.Collections.Generic;
30
namespace ICSharpCode.NRefactory.CSharp.Refactoring
33
/// Creates a 'if (param == null) throw new System.ArgumentNullException ();' contruct for a parameter.
35
[ContextAction("Check if parameter is null", Description = "Checks function parameter is not null.")]
36
public class CheckIfParameterIsNullAction : SpecializedCodeAction<ParameterDeclaration>
38
protected override CodeAction GetAction(RefactoringContext context, ParameterDeclaration parameter)
40
BlockStatement bodyStatement;
41
if (parameter.Parent is LambdaExpression) {
42
bodyStatement = parameter.Parent.GetChildByRole (LambdaExpression.BodyRole) as BlockStatement;
44
bodyStatement = parameter.Parent.GetChildByRole (Roles.Body);
46
if (bodyStatement == null || bodyStatement.IsNull)
48
var type = context.ResolveType(parameter.Type);
49
if (type.IsReferenceType == false || HasNullCheck(parameter))
52
return new CodeAction(context.TranslateString("Add null check for parameter"), script => {
53
var statement = new IfElseStatement() {
54
Condition = new BinaryOperatorExpression (new IdentifierExpression (parameter.Name), BinaryOperatorType.Equality, new NullReferenceExpression ()),
55
TrueStatement = new ThrowStatement (new ObjectCreateExpression (context.CreateShortType("System", "ArgumentNullException"), new PrimitiveExpression (parameter.Name)))
57
System.Console.WriteLine(bodyStatement.StartLocation +"/" + bodyStatement.EndLocation);
58
script.AddTo(bodyStatement, statement);
62
static bool HasNullCheck (ParameterDeclaration parameter)
64
var visitor = new CheckNullVisitor (parameter);
65
parameter.Parent.AcceptVisitor (visitor, null);
66
return visitor.ContainsNullCheck;
69
class CheckNullVisitor : DepthFirstAstVisitor<object, object>
71
readonly Expression pattern;
73
internal bool ContainsNullCheck;
75
public CheckNullVisitor (ParameterDeclaration parameter)
77
pattern = PatternHelper.CommutativeOperator(new IdentifierExpression(parameter.Name), BinaryOperatorType.Any, new NullReferenceExpression());
80
public override object VisitIfElseStatement (IfElseStatement ifElseStatement, object data)
82
if (ifElseStatement.Condition is BinaryOperatorExpression) {
83
var binOp = ifElseStatement.Condition as BinaryOperatorExpression;
84
if ((binOp.Operator == BinaryOperatorType.Equality || binOp.Operator == BinaryOperatorType.InEquality) && pattern.IsMatch(binOp)) {
85
ContainsNullCheck = true;
89
return base.VisitIfElseStatement (ifElseStatement, data);