2
// AssignmentMadeToSameVariableIssue.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
28
using System.Collections.Generic;
29
using ICSharpCode.NRefactory.Semantics;
30
using ICSharpCode.NRefactory.TypeSystem;
31
using ICSharpCode.NRefactory.PatternMatching;
34
namespace ICSharpCode.NRefactory.CSharp.Refactoring
36
[IssueDescription ("CS1717:Assignment made to same variable",
37
Description = "CS1717:Assignment made to same variable.",
38
Category = IssueCategories.CompilerWarnings,
39
Severity = Severity.Warning,
40
IssueMarker = IssueMarker.GrayOut)]
41
public class AssignmentMadeToSameVariableIssue : ICodeIssueProvider
43
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
45
return new GatherVisitor (context).GetIssues ();
48
class GatherVisitor : GatherVisitorBase<AssignmentMadeToSameVariableIssue>
50
public GatherVisitor (BaseRefactoringContext ctx)
55
public override void VisitAssignmentExpression (AssignmentExpression assignmentExpression)
57
base.VisitAssignmentExpression (assignmentExpression);
59
if (assignmentExpression.Operator != AssignmentOperatorType.Assign)
61
if (!(assignmentExpression.Left is IdentifierExpression) &&
62
!(assignmentExpression.Left is MemberReferenceExpression))
65
var resolveResult = ctx.Resolve (assignmentExpression.Left);
66
var memberResolveResult = resolveResult as MemberResolveResult;
67
if (memberResolveResult != null) {
68
var memberResolveResult2 = ctx.Resolve (assignmentExpression.Right) as MemberResolveResult;
69
if (memberResolveResult2 == null || !AreEquivalent(memberResolveResult, memberResolveResult2))
71
} else if (resolveResult is LocalResolveResult) {
72
if (!assignmentExpression.Left.Match (assignmentExpression.Right).Success)
79
Action<Script> action;
80
if (assignmentExpression.Parent is ExpressionStatement) {
81
node = assignmentExpression.Parent;
82
action = script => script.Remove (assignmentExpression.Parent);
84
node = assignmentExpression;
85
action = script => script.Replace (assignmentExpression, assignmentExpression.Left.Clone ());
87
AddIssue (node, ctx.TranslateString ("CS1717:Assignment made to same variable"),
88
new [] { new CodeAction (ctx.TranslateString ("Remove assignment"), action, node) });
91
static bool AreEquivalent(ResolveResult first, ResolveResult second)
93
var firstPath = AccessPath.FromResolveResult(first);
94
var secondPath = AccessPath.FromResolveResult(second);
95
return firstPath != null && firstPath.Equals(secondPath) && !firstPath.MemberPath.Any(m => !(m is IField));