2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.codeInspection
.sillyAssignment
;
18 import com
.intellij
.codeInsight
.daemon
.JavaErrorMessages
;
19 import com
.intellij
.codeInspection
.BaseJavaLocalInspectionTool
;
20 import com
.intellij
.codeInspection
.LocalQuickFix
;
21 import com
.intellij
.codeInspection
.ProblemHighlightType
;
22 import com
.intellij
.codeInspection
.ProblemsHolder
;
23 import com
.intellij
.openapi
.util
.Comparing
;
24 import com
.intellij
.psi
.*;
25 import com
.intellij
.psi
.util
.PsiUtil
;
26 import org
.jetbrains
.annotations
.NonNls
;
27 import org
.jetbrains
.annotations
.NotNull
;
33 public class SillyAssignmentInspection
extends BaseJavaLocalInspectionTool
{
35 public String
getGroupDisplayName() {
40 public String
getDisplayName() {
41 return JavaErrorMessages
.message("assignment.to.itself");
46 public String
getShortName() {
47 return "SillyAssignment";
50 public boolean isEnabledByDefault() {
55 public PsiElementVisitor
buildVisitor(@NotNull final ProblemsHolder holder
, boolean isOnTheFly
) {
56 return new JavaElementVisitor() {
58 @Override public void visitAssignmentExpression(PsiAssignmentExpression expression
) {
59 checkSillyAssignment(expression
, holder
);
62 @Override public void visitReferenceExpression(PsiReferenceExpression expression
) {
63 visitElement(expression
);
66 @Override public void visitVariable(final PsiVariable variable
) {
67 final PsiExpression initializer
= variable
.getInitializer();
68 if (initializer
instanceof PsiAssignmentExpression
) {
69 final PsiExpression lExpr
= ((PsiAssignmentExpression
)initializer
).getLExpression();
70 if (lExpr
instanceof PsiReferenceExpression
) {
71 final PsiReferenceExpression refExpr
= (PsiReferenceExpression
)lExpr
;
72 if (!refExpr
.isQualified() && refExpr
.isReferenceTo(variable
)) {
73 holder
.registerProblem(lExpr
, JavaErrorMessages
.message("assignment.to.declared.variable", variable
.getName()),
74 ProblemHighlightType
.LIKE_UNUSED_SYMBOL
, (LocalQuickFix
[])null);
82 private static void checkSillyAssignment(PsiAssignmentExpression assignment
, ProblemsHolder holder
) {
83 if (assignment
.getOperationSign().getTokenType() != JavaTokenType
.EQ
) return;
84 PsiExpression lExpression
= assignment
.getLExpression();
85 PsiExpression rExpression
= assignment
.getRExpression();
86 if (rExpression
== null) return;
87 lExpression
= PsiUtil
.deparenthesizeExpression(lExpression
);
88 rExpression
= PsiUtil
.deparenthesizeExpression(rExpression
);
89 if (!(lExpression
instanceof PsiReferenceExpression
)) return;
90 PsiReferenceExpression rRef
;
91 if (!(rExpression
instanceof PsiReferenceExpression
)) {
92 if (!(rExpression
instanceof PsiAssignmentExpression
)) return;
93 final PsiAssignmentExpression rAssignmentExpression
= (PsiAssignmentExpression
)rExpression
;
94 final PsiExpression assignee
= rAssignmentExpression
.getLExpression();
95 if (!(assignee
instanceof PsiReferenceExpression
)) return;
96 rRef
= (PsiReferenceExpression
)assignee
;
98 rRef
= (PsiReferenceExpression
)rExpression
;
100 PsiReferenceExpression lRef
= (PsiReferenceExpression
)lExpression
;
101 PsiManager manager
= assignment
.getManager();
102 if (!sameInstanceReferences(lRef
, rRef
, manager
)) return;
103 holder
.registerProblem(assignment
, JavaErrorMessages
.message("assignment.to.itself"), ProblemHighlightType
.LIKE_UNUSED_SYMBOL
, (LocalQuickFix
[])null);
107 * @return true if both expressions resolve to the same variable/class or field in the same instance of the class
109 private static boolean sameInstanceReferences(PsiReferenceExpression lRef
, PsiReferenceExpression rRef
, PsiManager manager
) {
110 PsiElement lResolved
= lRef
.resolve();
111 PsiElement rResolved
= rRef
.resolve();
112 if (!manager
.areElementsEquivalent(lResolved
, rResolved
)) return false;
114 PsiExpression lQualifier
= lRef
.getQualifierExpression();
115 PsiExpression rQualifier
= rRef
.getQualifierExpression();
116 if (lQualifier
instanceof PsiReferenceExpression
&& rQualifier
instanceof PsiReferenceExpression
) {
117 return sameInstanceReferences((PsiReferenceExpression
)lQualifier
, (PsiReferenceExpression
)rQualifier
, manager
);
119 if (Comparing
.equal(lQualifier
, rQualifier
)) return true;
120 boolean lThis
= lQualifier
== null || lQualifier
instanceof PsiThisExpression
;
121 boolean rThis
= rQualifier
== null || rQualifier
instanceof PsiThisExpression
;
122 return lThis
&& rThis
;