update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInspection / equalsAndHashcode / EqualsAndHashcode.java
blob599b1b344dafa1f8aa239d55d9668117187d9d09
1 /*
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.equalsAndHashcode;
18 import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
19 import com.intellij.codeInspection.InspectionsBundle;
20 import com.intellij.codeInspection.LocalQuickFix;
21 import com.intellij.codeInspection.ProblemsHolder;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.util.Computable;
25 import com.intellij.psi.*;
26 import com.intellij.psi.util.MethodSignatureUtil;
27 import org.jetbrains.annotations.NonNls;
28 import org.jetbrains.annotations.NotNull;
29 import org.jetbrains.annotations.Nullable;
31 import java.util.concurrent.atomic.AtomicBoolean;
33 /**
34 * @author max
36 public class EqualsAndHashcode extends BaseJavaLocalInspectionTool {
38 private PsiMethod myHashCode;
39 private PsiMethod myEquals;
40 private JavaPsiFacade myPsiFacade;
41 private final AtomicBoolean myInitialized = new AtomicBoolean();
43 public void projectOpened(Project project) {
44 myPsiFacade = JavaPsiFacade.getInstance(project);
47 @NotNull
48 public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
49 if (!myInitialized.getAndSet(true)) {
50 final PsiClass psiObjectClass = ApplicationManager.getApplication().runReadAction(
51 new Computable<PsiClass>() {
52 @Nullable
53 public PsiClass compute() {
54 return myPsiFacade.findClass("java.lang.Object");
58 if (psiObjectClass != null) {
59 PsiMethod[] methods = psiObjectClass.getMethods();
60 for (PsiMethod method : methods) {
61 @NonNls final String name = method.getName();
62 if ("equals".equals(name)) {
63 myEquals = method;
65 else if ("hashCode".equals(name)) {
66 myHashCode = method;
72 //jdk wasn't configured for the project
73 if (myEquals == null || myHashCode == null || !myEquals.isValid() || !myHashCode.isValid()) return new PsiElementVisitor() {};
75 return new JavaElementVisitor() {
76 @Override public void visitClass(PsiClass aClass) {
77 super.visitClass(aClass);
78 boolean [] hasEquals = new boolean[] {false};
79 boolean [] hasHashCode = new boolean[] {false};
80 processClass(aClass, hasEquals, hasHashCode);
81 if (hasEquals[0] != hasHashCode[0]) {
82 PsiIdentifier identifier = aClass.getNameIdentifier();
83 holder.registerProblem(identifier != null ? identifier : aClass,
84 hasEquals[0]
85 ? InspectionsBundle.message("inspection.equals.hashcode.only.one.defined.problem.descriptor", "<code>equals()</code>", "<code>hashCode()</code>")
86 : InspectionsBundle.message("inspection.equals.hashcode.only.one.defined.problem.descriptor","<code>hashCode()</code>", "<code>equals()</code>"),
87 (LocalQuickFix[])null);
91 @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
92 //do nothing
97 private void processClass(final PsiClass aClass, final boolean[] hasEquals, final boolean[] hasHashCode) {
98 final PsiMethod[] methods = aClass.getMethods();
99 for (PsiMethod method : methods) {
100 if (MethodSignatureUtil.areSignaturesEqual(method, myEquals)) {
101 hasEquals[0] = true;
103 else if (MethodSignatureUtil.areSignaturesEqual(method, myHashCode)) {
104 hasHashCode[0] = true;
109 @NotNull
110 public String getDisplayName() {
111 return InspectionsBundle.message("inspection.equals.hashcode.display.name");
114 @NotNull
115 public String getGroupDisplayName() {
116 return "";
119 @NotNull
120 public String getShortName() {
121 return "EqualsAndHashcode";
124 public void projectClosed(Project project) {
125 myEquals = null;
126 myHashCode = null;
127 myPsiFacade = null;