2 * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
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
.siyeh
.ig
.threading
;
18 import com
.intellij
.psi
.*;
19 import com
.intellij
.psi
.util
.PsiTreeUtil
;
20 import com
.siyeh
.InspectionGadgetsBundle
;
21 import com
.siyeh
.ig
.BaseInspection
;
22 import com
.siyeh
.ig
.BaseInspectionVisitor
;
23 import org
.jetbrains
.annotations
.NotNull
;
25 public class AwaitWithoutCorrespondingSignalInspection
extends BaseInspection
{
28 public String
getDisplayName() {
29 return InspectionGadgetsBundle
.message(
30 "await.without.corresponding.signal.display.name");
34 protected String
buildErrorString(Object
... infos
) {
35 return InspectionGadgetsBundle
.message(
36 "await.without.corresponding.signal.problem.descriptor");
38 public BaseInspectionVisitor
buildVisitor() {
39 return new AwaitWithoutCorrespondingSignalVisitor();
42 private static class AwaitWithoutCorrespondingSignalVisitor
43 extends BaseInspectionVisitor
{
45 @Override public void visitMethodCallExpression(
46 @NotNull PsiMethodCallExpression expression
) {
47 super.visitMethodCallExpression(expression
);
48 if (!ThreadingUtils
.isAwaitCall(expression
)) {
52 final PsiReferenceExpression methodExpression
=
53 expression
.getMethodExpression();
54 final PsiExpression qualifier
=
55 methodExpression
.getQualifierExpression();
56 if (!(qualifier
instanceof PsiReferenceExpression
)) {
59 final PsiElement referent
= ((PsiReference
) qualifier
).resolve();
60 if (!(referent
instanceof PsiField
)) {
63 final PsiField field
= (PsiField
) referent
;
64 final PsiClass fieldClass
= field
.getContainingClass();
65 if (fieldClass
== null) {
68 if (!PsiTreeUtil
.isAncestor(fieldClass
, expression
, true)) {
71 if (containsSignalCall(fieldClass
, field
)) {
74 registerMethodCallError(expression
);
77 private static boolean containsSignalCall(PsiClass fieldClass
,
79 final ContainsSignalVisitor visitor
=
80 new ContainsSignalVisitor(field
);
81 fieldClass
.accept(visitor
);
82 return visitor
.containsSignal();
86 private static class ContainsSignalVisitor
87 extends JavaRecursiveElementVisitor
{
89 private final PsiField target
;
90 private boolean containsSignal
= false;
92 ContainsSignalVisitor(PsiField target
) {
97 @Override public void visitElement(PsiElement element
) {
101 super.visitElement(element
);
104 @Override public void visitMethodCallExpression(
105 PsiMethodCallExpression expression
) {
106 super.visitMethodCallExpression(expression
);
107 if (!ThreadingUtils
.isSignalOrSignalAllCall(expression
)) {
110 final PsiReferenceExpression methodExpression
=
111 expression
.getMethodExpression();
112 final PsiExpression qualifier
=
113 methodExpression
.getQualifierExpression();
114 if (qualifier
== null) {
117 if (!(qualifier
instanceof PsiReferenceExpression
)) {
120 final PsiElement referent
= ((PsiReference
) qualifier
).resolve();
121 if (referent
== null) {
124 if (!target
.equals(referent
)) {
127 containsSignal
= true;
130 public boolean containsSignal() {
131 return containsSignal
;