cleanup
[idea/community.git] / java / java-impl / src / com / intellij / codeInsight / daemon / impl / analysis / HighlightVisitorImpl.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.codeInsight.daemon.impl.analysis;
17
18 import com.intellij.codeHighlighting.Pass;
19 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
20 import com.intellij.codeInsight.daemon.JavaErrorMessages;
21 import com.intellij.codeInsight.daemon.impl.*;
22 import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
23 import com.intellij.codeInsight.daemon.impl.quickfix.SetupJDKFix;
24 import com.intellij.lang.injection.InjectedLanguageManager;
25 import com.intellij.openapi.diagnostic.Logger;
26 import com.intellij.openapi.editor.Document;
27 import com.intellij.openapi.progress.ProgressManager;
28 import com.intellij.openapi.project.DumbAware;
29 import com.intellij.openapi.project.IndexNotReadyException;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.openapi.util.Pair;
32 import com.intellij.openapi.util.TextRange;
33 import com.intellij.pom.java.LanguageLevel;
34 import com.intellij.psi.*;
35 import com.intellij.psi.controlFlow.ControlFlowUtil;
36 import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
37 import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
38 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
39 import com.intellij.psi.javadoc.PsiDocComment;
40 import com.intellij.psi.javadoc.PsiDocTagValue;
41 import com.intellij.psi.templateLanguages.OuterLanguageElement;
42 import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
43 import com.intellij.psi.util.PsiTreeUtil;
44 import com.intellij.psi.util.PsiUtil;
45 import com.intellij.psi.xml.XmlAttributeValue;
46 import gnu.trove.THashMap;
47 import org.jetbrains.annotations.NonNls;
48 import org.jetbrains.annotations.NotNull;
49
50 import java.util.Collection;
51 import java.util.List;
52 import java.util.Map;
53
54 public class HighlightVisitorImpl extends JavaElementVisitor implements HighlightVisitor, DumbAware {
55   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.analysis.HighlightVisitorImpl");
56
57   private final PsiResolveHelper myResolveHelper;
58
59   private HighlightInfoHolder myHolder;
60
61   private RefCountHolder myRefCountHolder;
62
63   // map codeBlock->List of PsiReferenceExpression of uninitialized final variables
64   private final Map<PsiElement, Collection<PsiReferenceExpression>> myUninitializedVarProblems = new THashMap<PsiElement, Collection<PsiReferenceExpression>>();
65   // map codeBlock->List of PsiReferenceExpression of extra initialization of final variable
66   private final Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> myFinalVarProblems = new THashMap<PsiElement, Collection<ControlFlowUtil.VariableInfo>>();
67   private final Map<PsiParameter, Boolean> myParameterIsReassigned = new THashMap<PsiParameter, Boolean>();
68
69   private final Map<String, Pair<PsiImportStatementBase, PsiClass>> mySingleImportedClasses = new THashMap<String, Pair<PsiImportStatementBase, PsiClass>>();
70   private final Map<String, Pair<PsiImportStaticReferenceElement, PsiField>> mySingleImportedFields = new THashMap<String, Pair<PsiImportStaticReferenceElement, PsiField>>();
71   private PsiFile myFile;
72   private final PsiElementVisitor REGISTER_REFERENCES_VISITOR = new PsiRecursiveElementWalkingVisitor() {
73     @Override public void visitElement(PsiElement element) {
74       super.visitElement(element);
75       for (PsiReference reference : element.getReferences()) {
76         PsiElement resolved = reference.resolve();
77         if (resolved instanceof PsiNamedElement) {
78           myRefCountHolder.registerLocallyReferenced((PsiNamedElement)resolved);
79         }
80       }
81     }
82   };
83   
84   @SuppressWarnings({"UnusedDeclaration"}) //in plugin.xml
85   public HighlightVisitorImpl(Project project) {
86     this(JavaPsiFacade.getInstance(project).getResolveHelper());
87   }
88
89   private HighlightVisitorImpl(@NotNull PsiResolveHelper resolveHelper) {
90     myResolveHelper = resolveHelper;
91   }
92
93   public HighlightVisitorImpl clone() {
94     return new HighlightVisitorImpl(myResolveHelper);
95   }
96
97   public int order() {
98     return 0;
99   }  
100
101   public boolean suitableForFile(PsiFile file) {
102     return !InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file);
103   }
104
105   public void visit(PsiElement element, HighlightInfoHolder holder) {
106     myHolder = holder;
107
108     if (LOG.isDebugEnabled()) {
109       LOG.assertTrue(element.isValid());
110     }
111     element.accept(this);
112   }
113
114   private void registerReferencesFromInjectedFragments(final PsiElement element) {
115     InjectedLanguageUtil.enumerate(element, myFile, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
116       public void visit(@NotNull final PsiFile injectedPsi, @NotNull final List<PsiLanguageInjectionHost.Shred> places) {
117         injectedPsi.accept(REGISTER_REFERENCES_VISITOR);
118       }
119     }, false);
120   }
121
122   public boolean analyze(final Runnable action, final boolean updateWholeFile, final PsiFile file) {
123     myFile = file;
124     boolean success = true;
125     try {
126       if (updateWholeFile) {
127         Project project = file.getProject();
128         DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(project);
129         FileStatusMap fileStatusMap = ((DaemonCodeAnalyzerImpl)daemonCodeAnalyzer).getFileStatusMap();
130         RefCountHolder refCountHolder = RefCountHolder.getInstance(file);
131         myRefCountHolder = refCountHolder;
132         Document document = PsiDocumentManager.getInstance(project).getDocument(file);
133         TextRange dirtyScope = document == null ? file.getTextRange() : fileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL);
134         success = refCountHolder.analyze(action, dirtyScope, file);
135       }
136       else {
137         myRefCountHolder = null;
138         action.run();
139       }
140     }
141     finally {
142       myUninitializedVarProblems.clear();
143       myFinalVarProblems.clear();
144       mySingleImportedClasses.clear();
145       mySingleImportedFields.clear();
146       myParameterIsReassigned.clear();
147
148       myRefCountHolder = null;
149       myFile = null;
150       myHolder = null;
151     }
152
153     return success;
154   }
155
156   public void visitElement(final PsiElement element) {
157     if (element instanceof XmlAttributeValue) {
158       try {
159         for (PsiReference reference : element.getReferences()) {
160           if(reference instanceof PsiJavaReference && myRefCountHolder != null){
161             final PsiJavaReference psiJavaReference = (PsiJavaReference)reference;
162             myRefCountHolder.registerReference(psiJavaReference, psiJavaReference.advancedResolve(false));
163           }
164         }
165       }
166       catch (IndexNotReadyException ignored) {
167       }
168     }
169   }
170
171   @Override public void visitAnnotation(PsiAnnotation annotation) {
172     super.visitAnnotation(annotation);
173     if (!PsiUtil.isLanguageLevel5OrHigher(annotation)) {
174       HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, annotation, JavaErrorMessages.message("annotations.prior.15"));
175       QuickFixAction.registerQuickFixAction(info, new IncreaseLanguageLevelFix(LanguageLevel.JDK_1_5));
176       myHolder.add(info);
177       return;
178     }
179
180     myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation));
181     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkAnnotationType(annotation));
182     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkMissingAttributes(annotation));
183     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation));
184     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation));
185   }
186
187   @Override public void visitAnnotationArrayInitializer(PsiArrayInitializerMemberValue initializer) {
188     PsiMethod method = null;
189     PsiElement parent = initializer.getParent();
190     if (parent instanceof PsiNameValuePair) {
191       method = (PsiMethod)parent.getReference().resolve();
192     }
193     else if (parent instanceof PsiAnnotationMethod) {
194       method = (PsiMethod)parent;
195     }
196     if (method != null) {
197       PsiType type = method.getReturnType();
198       if (type instanceof PsiArrayType) {
199         type = ((PsiArrayType)type).getComponentType();
200         PsiAnnotationMemberValue[] initializers = initializer.getInitializers();
201         for (PsiAnnotationMemberValue initializer1 : initializers) {
202           myHolder.add(AnnotationsHighlightUtil.checkMemberValueType(initializer1, type));
203         }
204       }
205     }
206   }
207
208   @Override public void visitAnnotationMethod(PsiAnnotationMethod method) {
209     PsiType returnType = method.getReturnType();
210     PsiAnnotationMemberValue value = method.getDefaultValue();
211     if (returnType != null && value != null) {
212       myHolder.add(AnnotationsHighlightUtil.checkMemberValueType(value, returnType));
213     }
214
215     myHolder.add(AnnotationsHighlightUtil.checkValidAnnotationType(method.getReturnTypeElement()));
216     myHolder.add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), method.getContainingClass()));
217   }
218
219   @Override public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
220     super.visitArrayInitializerExpression(expression);
221     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkArrayInitializerApplicable(expression));
222     if (!(expression.getParent() instanceof PsiNewExpression)) {
223       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType()));
224     }
225   }
226
227   @Override public void visitAssignmentExpression(PsiAssignmentExpression assignment) {
228     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentCompatibleTypes(assignment));
229     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentOperatorApplicable(assignment));
230     if (!myHolder.hasErrorResults()) visitExpression(assignment);
231   }
232
233   @Override public void visitBinaryExpression(PsiBinaryExpression expression) {
234     super.visitBinaryExpression(expression);
235     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkBinaryOperatorApplicable(expression));
236   }
237
238   @Override public void visitBreakStatement(PsiBreakStatement statement) {
239     super.visitBreakStatement(statement);
240     if (!myHolder.hasErrorResults()) {
241       myHolder.add(HighlightUtil.checkLabelDefined(statement.getLabelIdentifier(), statement.findExitedStatement()));
242     }
243   }
244
245   @Override public void visitClass(PsiClass aClass) {
246     super.visitClass(aClass);
247     if (aClass instanceof JspClass) return;
248     if (aClass.isAnnotationType()) {
249       if (!PsiUtil.isLanguageLevel5OrHigher(aClass)) {
250         HighlightInfo info = HighlightInfo
251             .createHighlightInfo(HighlightInfoType.ERROR, aClass.getNameIdentifier(), JavaErrorMessages.message("annotations.prior.15"));
252         QuickFixAction.registerQuickFixAction(info, new IncreaseLanguageLevelFix(LanguageLevel.JDK_1_5));
253         myHolder.add(info);
254       }
255     }
256     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInterfaceMultipleInheritance(aClass));
257     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateTopLevelClass(aClass));
258     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumMustNotBeLocal(aClass));
259     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass));
260   }
261
262   @Override public void visitClassInitializer(PsiClassInitializer initializer) {
263     super.visitClassInitializer(initializer);
264     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkInitializerCompleteNormally(initializer));
265     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(initializer.getBody()));
266     if (!myHolder.hasErrorResults()) {
267       myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(initializer, initializer.getContainingClass()));
268     }
269   }
270
271   @Override public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
272     super.visitClassObjectAccessExpression(expression);
273     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkClassObjectAccessExpression(expression));
274   }
275
276   @Override public void visitComment(PsiComment comment) {
277     super.visitComment(comment);
278     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnclosedComment(comment));
279     if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(comment);
280   }
281
282   @Override public void visitContinueStatement(PsiContinueStatement statement) {
283     super.visitContinueStatement(statement);
284     if (!myHolder.hasErrorResults()) {
285       myHolder.add(HighlightUtil.checkLabelDefined(statement.getLabelIdentifier(), statement.findContinuedStatement()));
286     }
287   }
288
289   @Override public void visitJavaToken(PsiJavaToken token) {
290     super.visitJavaToken(token);
291     if (!myHolder.hasErrorResults()
292         && token.getTokenType() == JavaTokenType.RBRACE
293         && token.getParent() instanceof PsiCodeBlock
294         && token.getParent().getParent() instanceof PsiMethod) {
295       PsiMethod method = (PsiMethod)token.getParent().getParent();
296       myHolder.add(HighlightControlFlowUtil.checkMissingReturnStatement(method));
297     }
298
299   }
300
301   @Override public void visitDocComment(PsiDocComment comment) {
302     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnclosedComment(comment));
303   }
304
305   @Override public void visitDocTagValue(PsiDocTagValue value) {
306     PsiReference reference = value.getReference();
307     if (reference != null) {
308       PsiElement element = reference.resolve();
309       if (element instanceof PsiMethod) {
310         myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)element, ((PsiDocMethodOrFieldRef)value).getNameElement(), false));
311       }
312       else if (element instanceof PsiParameter) {
313         myHolder.add(HighlightNamesUtil.highlightVariable((PsiVariable)element, value.getNavigationElement()));
314       }
315     }
316   }
317
318   @Override public void visitEnumConstant(PsiEnumConstant enumConstant) {
319     super.visitEnumConstant(enumConstant);
320     if (!myHolder.hasErrorResults()) GenericsHighlightUtil.checkEnumConstantForConstructorProblems(enumConstant, myHolder);
321     if (!myHolder.hasErrorResults()) registerConstructorCall(enumConstant);
322   }
323
324   @Override public void visitEnumConstantInitializer(PsiEnumConstantInitializer enumConstantInitializer) {
325     super.visitEnumConstantInitializer(enumConstantInitializer);
326     if (!myHolder.hasErrorResults()) {
327       TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(enumConstantInitializer);
328       myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(enumConstantInitializer, textRange));
329     }
330   }
331
332   @Override public void visitExpression(PsiExpression expression) {
333     ProgressManager.checkCanceled(); // visitLiteralExpression is invoked very often in array initializers
334     
335     super.visitExpression(expression);
336     if (myHolder.add(HighlightUtil.checkMustBeBoolean(expression))) return;
337     if (expression instanceof PsiArrayAccessExpression
338         && ((PsiArrayAccessExpression)expression).getIndexExpression() != null) {
339       myHolder.add(HighlightUtil.checkValidArrayAccessExpression(((PsiArrayAccessExpression)expression).getArrayExpression(),
340                                                                  ((PsiArrayAccessExpression)expression).getIndexExpression()));
341     }
342     if (expression.getParent() instanceof PsiNewExpression
343              && ((PsiNewExpression)expression.getParent()).getQualifier() != expression
344              && ((PsiNewExpression)expression.getParent()).getArrayInitializer() != expression) {
345       // like in 'new String["s"]'
346       myHolder.add(HighlightUtil.checkValidArrayAccessExpression(null, expression));
347     }
348     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkCannotWriteToFinal(expression));
349     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableExpected(expression));
350     if (!myHolder.hasErrorResults()) HighlightUtil.checkArrayInitalizer(expression, myHolder);
351     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTernaryOperatorConditionIsBoolean(expression));
352     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssertOperatorTypes(expression));
353     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSynchronizedExpressionType(expression));
354     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkConditionalExpressionBranchTypesMatch(expression));
355     if (!myHolder.hasErrorResults()
356         && expression.getParent() instanceof PsiThrowStatement
357         && ((PsiThrowStatement)expression.getParent()).getException() == expression) {
358       PsiType type = expression.getType();
359       myHolder.add(HighlightUtil.checkMustBeThrowable(type, expression, true));
360     }
361
362     if (!myHolder.hasErrorResults()) {
363       myHolder.add(AnnotationsHighlightUtil.checkConstantExpression(expression));
364     }
365   }
366
367   @Override public void visitField(PsiField field) {
368     super.visitField(field);
369     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalFieldInitialized(field));
370   }
371
372   @Override public void visitForeachStatement(PsiForeachStatement statement) {
373     if (!PsiUtil.isLanguageLevel5OrHigher(statement)) {
374       HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, statement.getFirstChild(), JavaErrorMessages.message("foreach.prior.15"));
375       QuickFixAction.registerQuickFixAction(info, new IncreaseLanguageLevelFix(LanguageLevel.JDK_1_5));
376       myHolder.add(info);
377     }
378   }
379
380   @Override public void visitImportStaticStatement(PsiImportStaticStatement statement) {
381     if (!PsiUtil.isLanguageLevel5OrHigher(statement)) {
382       HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, statement.getFirstChild(), JavaErrorMessages.message("static.imports.prior.15"));
383       QuickFixAction.registerQuickFixAction(info, new IncreaseLanguageLevelFix(LanguageLevel.JDK_1_5));
384       myHolder.add(info);
385     }
386   }
387
388   @Override public void visitIdentifier(PsiIdentifier identifier) {
389     PsiElement parent = identifier.getParent();
390     if (parent instanceof PsiVariable) {
391       myHolder.add(HighlightUtil.checkVariableAlreadyDefined((PsiVariable)parent));
392     }
393     else if (parent instanceof PsiClass) {
394       myHolder.add(HighlightClassUtil.checkClassAlreadyImported((PsiClass)parent, identifier));
395       myHolder.add(HighlightClassUtil.checkExternalizableHasPublicNoArgsConstructor((PsiClass)parent, identifier));
396       if (!(parent instanceof PsiAnonymousClass)) {
397         myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)parent, ((PsiClass)parent).getNameIdentifier()));
398       }
399     }
400     else if (parent instanceof PsiMethod) {
401       PsiMethod method = (PsiMethod)parent;
402       if (method.isConstructor()) {
403         myHolder.add(HighlightMethodUtil.checkConstructorName(method));
404       }
405     }
406     super.visitIdentifier(identifier);
407   }
408
409   @Override public void visitImportStatement(PsiImportStatement statement) {
410     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSingleImportClassConflict(statement, mySingleImportedClasses));
411   }
412
413   @Override public void visitImportStaticReferenceElement(PsiImportStaticReferenceElement ref) {
414     String refName = ref.getReferenceName();
415     JavaResolveResult[] results = ref.multiResolve(false);
416
417     if (results.length == 0) {
418       String description = JavaErrorMessages.message("cannot.resolve.symbol", refName);
419       HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.WRONG_REF, ref.getReferenceNameElement(), description);
420       myHolder.add(info);
421       QuickFixAction.registerQuickFixAction(info, SetupJDKFix.getInstnace());
422     }
423     else {
424       PsiManager manager = ref.getManager();
425       for (JavaResolveResult result : results) {
426         PsiElement element = result.getElement();
427         if (!(element instanceof PsiModifierListOwner) || !((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) {
428           continue;
429         }
430         @NonNls String messageKey = null;
431         if (element instanceof PsiClass) {
432           Pair<PsiImportStatementBase, PsiClass> imported = mySingleImportedClasses.get(refName);
433           PsiClass aClass = imported == null ? null : imported.getSecond();
434           PsiImportStaticStatement statement = (PsiImportStaticStatement)ref.getParent();
435
436           if (aClass != null && !manager.areElementsEquivalent(aClass, element) && !imported.getFirst().equals(statement)) {
437             messageKey = "class.is.already.defined.in.single.type.import";
438           }
439           mySingleImportedClasses.put(refName, Pair.<PsiImportStatementBase, PsiClass>create(statement, (PsiClass)element));
440         }
441         else if (element instanceof PsiField) {
442           Pair<PsiImportStaticReferenceElement, PsiField> imported = mySingleImportedFields.get(refName);
443           PsiField field = imported == null ? null : imported.getSecond();
444
445           if (field != null && !manager.areElementsEquivalent(field, element) && !imported.getFirst().equals(ref.getParent())) {
446             messageKey = "field.is.already.defined.in.single.type.import";
447           }
448           mySingleImportedFields.put(refName, Pair.create(ref, (PsiField)element));
449         }
450
451         if (messageKey != null) {
452           String description = JavaErrorMessages.message(messageKey, refName);
453           myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, ref, description));
454         }
455       }
456     }
457   }
458
459   @Override public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
460     super.visitInstanceOfExpression(expression);
461     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInstanceOfApplicable(expression));
462     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInstanceOfGenericType(expression));
463   }
464
465   @Override public void visitKeyword(PsiKeyword keyword) {
466     super.visitKeyword(keyword);
467     PsiElement parent = keyword.getParent();
468     if (parent instanceof PsiModifierList) {
469       PsiModifierList psiModifierList = (PsiModifierList)parent;
470       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkNotAllowedModifier(keyword, psiModifierList));
471       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalModifierCombination(keyword, psiModifierList));
472       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkPublicClassInRightFile(keyword, psiModifierList));
473       if (PsiModifier.ABSTRACT.equals(keyword.getText()) && psiModifierList.getParent() instanceof PsiMethod) {
474         if (!myHolder.hasErrorResults()) {
475           myHolder.add(HighlightMethodUtil.checkAbstractMethodInConcreteClass((PsiMethod)psiModifierList.getParent(), keyword));
476         }
477       }
478     }
479     else if (keyword.getText().equals(PsiKeyword.CONTINUE) && parent instanceof PsiContinueStatement) {
480       PsiContinueStatement statement = (PsiContinueStatement)parent;
481       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkContinueOutsideLoop(statement));
482     }
483     else if (keyword.getText().equals(PsiKeyword.BREAK) && parent instanceof PsiBreakStatement) {
484       PsiBreakStatement statement = (PsiBreakStatement)parent;
485       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkBreakOutsideLoop(statement));
486     }
487     else if (PsiKeyword.INTERFACE.equals(keyword.getText()) && parent instanceof PsiClass) {
488       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkInterfaceCannotBeLocal((PsiClass)parent));
489     }
490     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkStaticDeclarationInInnerClass(keyword));
491     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalVoidType(keyword));
492
493     if (PsiTreeUtil.getParentOfType(keyword, PsiDocTagValue.class) != null) {
494       myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.JAVA_KEYWORD, keyword, null));
495     }
496   }
497
498   @Override public void visitLabeledStatement(PsiLabeledStatement statement) {
499     super.visitLabeledStatement(statement);
500     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelWithoutStatement(statement));
501     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelAlreadyInUse(statement));
502   }
503
504   @Override public void visitLiteralExpression(PsiLiteralExpression expression) {
505     super.visitLiteralExpression(expression);
506     if (myHolder.hasErrorResults()) return;
507     myHolder.add(HighlightUtil.checkLiteralExpressionParsingError(expression));
508     if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(expression);
509   }
510
511   @Override public void visitMethod(PsiMethod method) {
512     super.visitMethod(method);
513     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(method.getBody()));
514     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorHandleSuperClassExceptions(method));
515     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkRecursiveConstructorInvocation(method));
516     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkOverrideAnnotation(method));
517     if (!myHolder.hasErrorResults() && method.isConstructor()) {
518       myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(method, method.getContainingClass()));
519     }
520     myHolder.add(HighlightNamesUtil.highlightMethodName(method, method.getNameIdentifier(), true));
521   }
522
523   private void highlightMethodOrClassName(PsiJavaCodeReferenceElement element) {
524     PsiElement parent = element.getParent();
525     if (parent instanceof PsiReferenceExpression || parent instanceof PsiJavaCodeReferenceElement) {
526       return;
527     }
528     if (parent instanceof PsiMethodCallExpression) {
529       PsiMethod method = ((PsiMethodCallExpression)parent).resolveMethod();
530       PsiElement methodNameElement = element.getReferenceNameElement();
531       if (method != null && methodNameElement != null) {
532         myHolder.add(HighlightNamesUtil.highlightMethodName(method, methodNameElement, false));
533         myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(element));
534       }
535     }
536     else if (parent instanceof PsiConstructorCall) {
537       try {
538         PsiMethod method = ((PsiConstructorCall)parent).resolveConstructor();
539         if (method == null) {
540           PsiElement resolved = element.resolve();
541           if (resolved instanceof PsiClass) {
542             myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, element));
543           }
544         }
545         else {
546           myHolder.add(HighlightNamesUtil.highlightMethodName(method, element, false));
547         }
548       }
549       catch (IndexNotReadyException ignored) {
550       }
551     }
552     else if (parent instanceof PsiImportStatement && ((PsiImportStatement)parent).isOnDemand()) {
553       // highlight on demand import as class
554       myHolder.add(HighlightNamesUtil.highlightClassName(null, element));
555     }
556     else {
557       PsiElement resolved = element.resolve();
558       if (resolved instanceof PsiClass) {
559         myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, element));
560       }
561     }
562   }
563
564   @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) {
565     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumSuperConstructorCall(expression));
566     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkSuperQualifierType(expression));
567     // in case of JSP syntethic method call, do not check
568     if (expression.getMethodExpression().isPhysical() && !myHolder.hasErrorResults()) {
569       try {
570         myHolder.add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper));
571       }
572       catch (IndexNotReadyException ignored) {
573       }
574     }
575
576     if (!myHolder.hasErrorResults()) visitExpression(expression);
577   }
578
579   @Override public void visitModifierList(PsiModifierList list) {
580     super.visitModifierList(list);
581     PsiElement parent = list.getParent();
582     if (!myHolder.hasErrorResults() && parent instanceof PsiMethod) {
583       myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody((PsiMethod)parent));
584     }
585     if (parent instanceof PsiMethod) {
586       PsiMethod method = (PsiMethod)parent;
587       MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
588       if (!method.isConstructor()) {
589         List<HierarchicalMethodSignature> superMethodSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
590         if (!superMethodSignatures.isEmpty()) {
591           if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleReturnType(methodSignature, superMethodSignatures, true));
592           if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleThrows(methodSignature, superMethodSignatures, true, method.getContainingClass()));
593           if (!method.hasModifierProperty(PsiModifier.STATIC)) {
594             if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodWeakerPrivileges(methodSignature, superMethodSignatures, true));
595             if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedOverriding(method, superMethodSignatures));
596             if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodOverridesFinal(methodSignature, superMethodSignatures));
597           }
598         }
599       }
600       PsiClass aClass = method.getContainingClass();
601       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodMustHaveBody(method, aClass));
602       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method));
603       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallsBaseClassConstructor(method, myRefCountHolder, myResolveHelper));
604       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkStaticMethodOverride(method));
605     }
606     else if (parent instanceof PsiClass) {
607       PsiClass aClass = (PsiClass)parent;
608       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateNestedClass(aClass));
609       if (!myHolder.hasErrorResults()) {
610         TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass);
611         myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(aClass, textRange));
612       }
613       if (!myHolder.hasErrorResults()) {
614         myHolder.add(HighlightClassUtil.checkClassDoesNotCallSuperConstructorOrHandleExceptions(aClass, myRefCountHolder, myResolveHelper));
615       }
616       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkOverrideEquivalentInheritedMethods(aClass));
617       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass));
618       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCyclicInheritance(aClass));
619     }
620     else if (parent instanceof PsiEnumConstant) {
621       if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkEnumConstantModifierList(list));
622     }
623   }
624
625   @Override public void visitNameValuePair(PsiNameValuePair pair) {
626     myHolder.add(AnnotationsHighlightUtil.checkNameValuePair(pair));
627     if (!myHolder.hasErrorResults()) {
628       PsiIdentifier nameId = pair.getNameIdentifier();
629       if (nameId != null) myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ANNOTATION_ATTRIBUTE_NAME, nameId, null));
630     }
631   }
632
633   @Override public void visitNewExpression(PsiNewExpression expression) {
634     myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, null));
635     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression));
636     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkQualifiedNewOfStaticClass(expression));
637     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(expression));
638     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParameterInstantiation(expression));
639     try {
640       if (!myHolder.hasErrorResults()) HighlightMethodUtil.checkNewExpression(expression, myHolder);
641     }
642     catch (IndexNotReadyException ignored) {
643     }
644     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression));
645     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType()));
646     if (!myHolder.hasErrorResults()) registerConstructorCall(expression);
647
648     if (!myHolder.hasErrorResults()) visitExpression(expression);
649   }
650
651   @Override public void visitOuterLanguageElement(OuterLanguageElement element) {
652     XmlHighlightVisitor.visitJspElement(element);
653     super.visitOuterLanguageElement(element);
654   }
655
656   @Override public void visitPackageStatement(PsiPackageStatement statement) {
657     super.visitPackageStatement(statement);
658     myHolder.add(AnnotationsHighlightUtil.checkPackageAnnotationContainingFile(statement));
659   }
660
661   @Override public void visitParameter(PsiParameter parameter) {
662     super.visitParameter(parameter);
663     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkVarArgParameterIsLast(parameter));
664     if (!myHolder.hasErrorResults() && parameter.getParent() instanceof PsiForeachStatement) {
665       myHolder.add(GenericsHighlightUtil.checkForeachLoopParameterType((PsiForeachStatement)parameter.getParent()));
666     }
667   }
668
669   @Override public void visitParameterList(PsiParameterList list) {
670     PsiElement parent = list.getParent();
671     if (parent instanceof PsiAnnotationMethod && list.getParametersCount() > 0) {
672       myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
673                                                      list,
674                                                      JavaErrorMessages.message("annotation.interface.members.may.not.have.parameters")));
675     }
676   }
677
678   @Override public void visitPostfixExpression(PsiPostfixExpression expression) {
679     super.visitPostfixExpression(expression);
680     if (!myHolder.hasErrorResults()) {
681       myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
682     }
683   }
684
685   @Override public void visitPrefixExpression(PsiPrefixExpression expression) {
686     super.visitPrefixExpression(expression);
687     if (!myHolder.hasErrorResults()) {
688       myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
689     }
690   }
691
692   private void registerConstructorCall(PsiConstructorCall constructorCall) {
693     if (myRefCountHolder != null) {
694       JavaResolveResult resolveResult = constructorCall.resolveMethodGenerics();
695       final PsiElement resolved = resolveResult.getElement();
696       if (resolved instanceof PsiNamedElement) {
697         myRefCountHolder.registerLocallyReferenced((PsiNamedElement)resolved);
698       }
699     }
700   }
701
702   @Override public void visitReferenceElement(PsiJavaCodeReferenceElement ref) {
703     JavaResolveResult result;
704     try {
705       result = ref.advancedResolve(true);
706     }
707     catch (IndexNotReadyException e) {
708       return;
709     }
710     PsiElement resolved = result.getElement();
711     PsiElement parent = ref.getParent();
712     if (myRefCountHolder != null) {
713       myRefCountHolder.registerReference(ref, result);
714     }
715
716     myHolder.add(HighlightUtil.checkReference(ref, result, resolved));
717     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAbstractInstantiation(ref));
718     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsDuplicate(ref, resolved));
719     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkExceptionAlreadyCaught(ref, resolved));
720     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassExtendsForeignInnerClass(ref, resolved));
721     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSelectStaticClassFromParameterizedType(resolved, ref));
722     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, ref, result.getSubstitutor()));
723
724     if (resolved != null && parent instanceof PsiReferenceList) {
725       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkElementInReferenceList(ref, (PsiReferenceList)parent, result));
726     }
727
728     if (parent instanceof PsiAnonymousClass && ref.equals(((PsiAnonymousClass)parent).getBaseClassReference())) {
729       myHolder.add(GenericsHighlightUtil.checkOverrideEquivalentMethods((PsiClass)parent));
730     }
731
732     if (resolved instanceof PsiVariable) {
733       PsiVariable variable = (PsiVariable)resolved;
734
735       final PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
736       if (containingClass instanceof PsiAnonymousClass && !PsiTreeUtil.isAncestor(containingClass, variable, false) && !(variable instanceof PsiField)) {
737         if (!PsiTreeUtil.isAncestor(((PsiAnonymousClass) containingClass).getArgumentList(), ref, false)) {
738           myHolder.add(HighlightInfo.createHighlightInfo(HighlightInfoType.IMPLICIT_ANONYMOUS_CLASS_PARAMETER, ref, null));
739         }
740       }
741
742       if (!variable.hasModifierProperty(PsiModifier.FINAL) && isReassigned(variable)) {
743         myHolder.add(HighlightNamesUtil.highlightReassignedVariable(variable, ref));
744       }
745       else {
746         myHolder.add(HighlightNamesUtil.highlightVariable(variable, ref.getReferenceNameElement()));
747       }
748       myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(ref));
749     }
750     else {
751       highlightMethodOrClassName(ref);
752     }
753   }
754
755   @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
756     visitReferenceElement(expression);
757     if (!myHolder.hasErrorResults()) {
758       visitExpression(expression);
759       if (myHolder.hasErrorResults()) return;
760     }
761     JavaResolveResult result;
762     try {
763       result = expression.advancedResolve(false);
764     }
765     catch (IndexNotReadyException e) {
766       return;
767     }
768     PsiElement resolved = result.getElement();
769     if (resolved instanceof PsiVariable && resolved.getContainingFile() == expression.getContainingFile()) {
770       if (!myHolder.hasErrorResults()) {
771         try {
772           myHolder.add(HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, (PsiVariable)resolved, myUninitializedVarProblems));
773         }
774         catch (IndexNotReadyException ignored) {
775         }
776       }
777       PsiVariable variable = (PsiVariable)resolved;
778       boolean isFinal = variable.hasModifierProperty(PsiModifier.FINAL);
779       if (isFinal && !variable.hasInitializer()) {
780         if (!myHolder.hasErrorResults()) {
781           myHolder.add(HighlightControlFlowUtil.checkFinalVariableMightAlreadyHaveBeenAssignedTo(variable, expression, myFinalVarProblems));
782         }
783         if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalVariableInitalizedInLoop(expression, resolved));
784       }
785     }
786
787     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkExpressionRequired(expression));
788     if (!myHolder.hasErrorResults() && resolved instanceof PsiField) {
789       try {
790         myHolder.add(HighlightUtil.checkIllegalForwardReferenceToField(expression, (PsiField)resolved));
791       }
792       catch (IndexNotReadyException ignored) {
793       }
794     }
795     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallMustBeFirstStatement(expression));
796     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkAccessStaticFieldFromEnumConstructor(expression, result));
797     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkClassReferenceAfterQualifier(expression, resolved));
798   }
799
800   @Override public void visitReferenceList(PsiReferenceList list) {
801     if (list.getFirstChild() == null) return;
802     PsiElement parent = list.getParent();
803     if (!(parent instanceof PsiTypeParameter)) {
804       myHolder.add(AnnotationsHighlightUtil.checkAnnotationDeclaration(parent, list));
805       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsAllowed(list));
806       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkImplementsAllowed(list));      
807       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassExtendsOnlyOneClass(list));
808       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericCannotExtendException(list));
809     }
810   }
811
812   @Override public void visitReferenceParameterList(PsiReferenceParameterList list) {
813     myHolder.add(GenericsHighlightUtil.checkParametersOnRaw(list));
814   }
815
816   @Override public void visitReturnStatement(PsiReturnStatement statement) {
817     myHolder.add(HighlightUtil.checkReturnStatementType(statement));
818   }
819
820   @Override public void visitStatement(PsiStatement statement) {
821     super.visitStatement(statement);
822     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkNotAStatement(statement));
823     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkStatementPrependedWithCaseInsideSwitch(statement));
824   }
825
826   @Override public void visitSuperExpression(PsiSuperExpression expr) {
827     myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier()));
828     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkAbstractMethodDirectCall(expr));
829     if (!myHolder.hasErrorResults()) visitExpression(expr);
830   }
831
832   @Override public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) {
833     super.visitSwitchLabelStatement(statement);
834     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkCaseStatement(statement));
835   }
836
837   @Override public void visitSwitchStatement(PsiSwitchStatement statement) {
838     super.visitSwitchStatement(statement);
839     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSwitchSelectorType(statement));
840   }
841
842   @Override public void visitThisExpression(PsiThisExpression expr) {
843     myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier()));
844     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr));
845     if (!myHolder.hasErrorResults()) {
846       visitExpression(expr);
847     }
848   }
849
850   @Override public void visitThrowStatement(PsiThrowStatement statement) {
851     myHolder.add(HighlightUtil.checkUnhandledExceptions(statement, null));
852     if (!myHolder.hasErrorResults()) visitStatement(statement);
853   }
854
855   @Override public void visitTryStatement(PsiTryStatement statement) {
856     super.visitTryStatement(statement);
857     if (!myHolder.hasErrorResults()) {
858       PsiParameter[] parameters = statement.getCatchBlockParameters();
859       for (PsiParameter parameter : parameters) {
860         myHolder.add(HighlightUtil.checkExceptionThrownInTry(parameter));
861         myHolder.add(HighlightUtil.checkCatchParameterIsThrowable(parameter));
862         myHolder.add(GenericsHighlightUtil.checkCatchParameterIsClass(parameter));
863       }
864     }
865   }
866
867   @Override public void visitTypeElement(PsiTypeElement type) {
868     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalType(type));
869     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type));
870     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkWildcardUsage(type));
871   }
872
873   @Override public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
874     super.visitTypeCastExpression(typeCast);
875     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
876     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedTypeCast(typeCast));
877   }
878
879   @Override public void visitTypeParameterList(PsiTypeParameterList list) {
880     myHolder.add(GenericsHighlightUtil.checkTypeParametersList(list));
881   }
882
883   @Override public void visitVariable(PsiVariable variable) {
884     super.visitVariable(variable);
885     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableInitializerType(variable));
886
887     if (isReassigned(variable)) {
888       myHolder.add(HighlightNamesUtil.highlightReassignedVariable(variable, variable.getNameIdentifier()));
889     }
890     else {
891       if (variable.getInitializer() == null) {
892         final PsiElement child = variable.getLastChild();
893         if (child instanceof PsiErrorElement && child.getPrevSibling() == variable.getNameIdentifier()) return;
894       }
895       myHolder.add(HighlightNamesUtil.highlightVariable(variable, variable.getNameIdentifier()));
896     }
897   }
898
899   private boolean isReassigned(PsiVariable variable) {
900     try {
901       return HighlightControlFlowUtil.isReassigned(variable, myFinalVarProblems, myParameterIsReassigned);
902     }
903     catch (IndexNotReadyException e) {
904       return false;
905     }
906   }
907 }