IDEA-63968 (drops obsolete Java keyword highlighting inside Javadoc)
[idea/community.git] / java / java-analysis-impl / src / com / intellij / codeInsight / daemon / impl / analysis / HighlightVisitorImpl.java
1 /*
2  * Copyright 2000-2015 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.JavaErrorMessages;
20 import com.intellij.codeInsight.daemon.impl.*;
21 import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil.Feature;
22 import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
23 import com.intellij.codeInsight.intention.QuickFixFactory;
24 import com.intellij.lang.injection.InjectedLanguageManager;
25 import com.intellij.openapi.application.ApplicationManager;
26 import com.intellij.openapi.editor.Document;
27 import com.intellij.openapi.editor.colors.TextAttributesScheme;
28 import com.intellij.openapi.progress.ProgressIndicator;
29 import com.intellij.openapi.progress.ProgressManager;
30 import com.intellij.openapi.project.IndexNotReadyException;
31 import com.intellij.openapi.project.Project;
32 import com.intellij.openapi.projectRoots.JavaSdkVersion;
33 import com.intellij.openapi.projectRoots.JavaVersionService;
34 import com.intellij.openapi.util.Pair;
35 import com.intellij.openapi.util.TextRange;
36 import com.intellij.pom.java.LanguageLevel;
37 import com.intellij.psi.*;
38 import com.intellij.psi.controlFlow.ControlFlowUtil;
39 import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
40 import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
41 import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
42 import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
43 import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
44 import com.intellij.psi.javadoc.PsiDocComment;
45 import com.intellij.psi.javadoc.PsiDocTagValue;
46 import com.intellij.psi.util.*;
47 import com.intellij.util.ArrayUtil;
48 import com.intellij.util.ObjectUtils;
49 import com.intellij.util.containers.MostlySingularMultiMap;
50 import gnu.trove.THashMap;
51 import gnu.trove.TObjectIntHashMap;
52 import org.jetbrains.annotations.NotNull;
53 import org.jetbrains.annotations.Nullable;
54
55 import java.util.Collection;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Set;
59
60 public class HighlightVisitorImpl extends JavaElementVisitor implements HighlightVisitor {
61   @NotNull
62   private final PsiResolveHelper myResolveHelper;
63
64   private HighlightInfoHolder myHolder;
65
66   private RefCountHolder myRefCountHolder;
67
68   // map codeBlock->List of PsiReferenceExpression of uninitialized final variables
69   private final Map<PsiElement, Collection<PsiReferenceExpression>> myUninitializedVarProblems = new THashMap<PsiElement, Collection<PsiReferenceExpression>>();
70   // map codeBlock->List of PsiReferenceExpression of extra initialization of final variable
71   private final Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> myFinalVarProblems = new THashMap<PsiElement, Collection<ControlFlowUtil.VariableInfo>>();
72
73   // value==1: no info if the parameter was reassigned (but the parameter is present in current file), value==2: parameter was reassigned
74   private final TObjectIntHashMap<PsiParameter> myReassignedParameters = new TObjectIntHashMap<PsiParameter>();
75
76   private final Map<String, Pair<PsiImportStaticReferenceElement, PsiClass>> mySingleImportedClasses = new THashMap<String, Pair<PsiImportStaticReferenceElement, PsiClass>>();
77   private final Map<String, Pair<PsiImportStaticReferenceElement, PsiField>> mySingleImportedFields = new THashMap<String, Pair<PsiImportStaticReferenceElement, PsiField>>();
78   private PsiFile myFile;
79   private final PsiElementVisitor REGISTER_REFERENCES_VISITOR = new PsiRecursiveElementWalkingVisitor() {
80     @Override public void visitElement(PsiElement element) {
81       super.visitElement(element);
82       for (PsiReference reference : element.getReferences()) {
83         PsiElement resolved = reference.resolve();
84         if (resolved instanceof PsiNamedElement) {
85           myRefCountHolder.registerLocallyReferenced((PsiNamedElement)resolved);
86         }
87       }
88     }
89   };
90   private final Map<PsiClass, MostlySingularMultiMap<MethodSignature, PsiMethod>> myDuplicateMethods = new THashMap<PsiClass, MostlySingularMultiMap<MethodSignature, PsiMethod>>();
91   private LanguageLevel myLanguageLevel;
92   private JavaSdkVersion myJavaSdkVersion;
93   private static class Holder {
94     private static final boolean CHECK_ELEMENT_LEVEL = ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isInternal();
95   }
96
97   private HighlightVisitorImpl(@NotNull PsiResolveHelper resolveHelper) {
98     myResolveHelper = resolveHelper;
99   }
100
101   @NotNull
102   private MostlySingularMultiMap<MethodSignature, PsiMethod> getDuplicateMethods(@NotNull PsiClass aClass) {
103     MostlySingularMultiMap<MethodSignature, PsiMethod> signatures = myDuplicateMethods.get(aClass);
104     if (signatures == null) {
105       signatures = new MostlySingularMultiMap<MethodSignature, PsiMethod>();
106       for (PsiMethod method : aClass.getMethods()) {
107         if (method instanceof ExternallyDefinedPsiElement) continue; // ignore aspectj-weaved methods; they are checked elsewhere
108         MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY);
109         signatures.add(signature, method);
110       }
111
112       myDuplicateMethods.put(aClass, signatures);
113     }
114     return signatures;
115   }
116
117   @Override
118   @NotNull
119   public HighlightVisitorImpl clone() {
120     return new HighlightVisitorImpl(myResolveHelper);
121   }
122
123   @Override
124   public int order() {
125     return 0;
126   }
127
128   @Override
129   public boolean suitableForFile(@NotNull PsiFile file) {
130     // both PsiJavaFile and PsiCodeFragment must match
131     return file instanceof PsiImportHolder && !InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file);
132   }
133
134   @Override
135   public void visit(@NotNull PsiElement element) {
136     if (Holder.CHECK_ELEMENT_LEVEL) {
137       ((CheckLevelHighlightInfoHolder)myHolder).enterLevel(element);
138       element.accept(this);
139       ((CheckLevelHighlightInfoHolder)myHolder).enterLevel(null);
140     }
141     else {
142       element.accept(this);
143     }
144   }
145
146   private void registerReferencesFromInjectedFragments(@NotNull PsiElement element) {
147     InjectedLanguageManager.getInstance(myFile.getProject()).enumerateEx(element, myFile, false,
148                                                                          new PsiLanguageInjectionHost.InjectedPsiVisitor() {
149                                                                            @Override
150                                                                            public void visit(@NotNull final PsiFile injectedPsi,
151                                                                                              @NotNull final List<PsiLanguageInjectionHost.Shred> places) {
152                                                                              injectedPsi.accept(REGISTER_REFERENCES_VISITOR);
153                                                                            }
154                                                                          }
155     );
156   }
157
158   @Override
159   public boolean analyze(@NotNull final PsiFile file,
160                          final boolean updateWholeFile,
161                          @NotNull final HighlightInfoHolder holder,
162                          @NotNull final Runnable highlight) {
163     myFile = file;
164     myHolder = Holder.CHECK_ELEMENT_LEVEL ? new CheckLevelHighlightInfoHolder(file, holder) : holder;
165     boolean success = true;
166     try {
167       myLanguageLevel = PsiUtil.getLanguageLevel(file);
168       myJavaSdkVersion = ObjectUtils.notNull(JavaVersionService.getInstance().getJavaSdkVersion(file), JavaSdkVersion.fromLanguageLevel(myLanguageLevel));
169       if (updateWholeFile) {
170         final Project project = file.getProject();
171         DaemonCodeAnalyzerEx daemonCodeAnalyzer = DaemonCodeAnalyzerEx.getInstanceEx(project);
172         final FileStatusMap fileStatusMap = daemonCodeAnalyzer.getFileStatusMap();
173         final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
174         if (progress == null) throw new IllegalStateException("Must be run under progress");
175         final RefCountHolder refCountHolder = RefCountHolder.get(file);
176         myRefCountHolder = refCountHolder;
177         final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
178         TextRange dirtyScope = ObjectUtils.notNull(document == null ? null : fileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL), file.getTextRange());
179         success = refCountHolder.analyze(file, dirtyScope, progress, new Runnable(){
180           @Override
181           public void run() {
182             highlight.run();
183             progress.checkCanceled();
184             HighlightingSession highlightingSession = HighlightingSessionImpl.getHighlightingSession(file, progress);
185             PostHighlightingVisitor highlightingVisitor = new PostHighlightingVisitor(file, document, refCountHolder, highlightingSession);
186             highlightingVisitor.collectHighlights(file, holder, progress);
187           }
188         });
189       }
190       else {
191         myRefCountHolder = null;
192         highlight.run();
193       }
194     }
195     finally {
196       myUninitializedVarProblems.clear();
197       myFinalVarProblems.clear();
198       mySingleImportedClasses.clear();
199       mySingleImportedFields.clear();
200       myReassignedParameters.clear();
201
202       myRefCountHolder = null;
203       myFile = null;
204       myHolder = null;
205       myDuplicateMethods.clear();
206     }
207
208     return success;
209   }
210
211   @Override
212   public void visitElement(final PsiElement element) {
213     if (myRefCountHolder != null && myFile instanceof ServerPageFile) {
214       // in jsp XmlAttributeValue may contain java references
215       try {
216         for (PsiReference reference : element.getReferences()) {
217           if(reference instanceof PsiJavaReference){
218             final PsiJavaReference psiJavaReference = (PsiJavaReference)reference;
219             myRefCountHolder.registerReference(psiJavaReference, psiJavaReference.advancedResolve(false));
220           }
221         }
222       }
223       catch (IndexNotReadyException ignored) {
224       }
225     }
226   }
227
228   @Override
229   public void visitAnnotation(PsiAnnotation annotation) {
230     super.visitAnnotation(annotation);
231     if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(annotation, Feature.ANNOTATIONS));
232     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkApplicability(annotation, myLanguageLevel, myFile));
233     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkAnnotationType(annotation));
234     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkMissingAttributes(annotation));
235     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation));
236     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation, myLanguageLevel));
237     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkForeignInnerClassesUsed(annotation));
238     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation, myLanguageLevel));
239     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkRepeatableAnnotation(annotation));
240     if (CommonClassNames.JAVA_LANG_OVERRIDE.equals(annotation.getQualifiedName())) {
241       PsiAnnotationOwner owner = annotation.getOwner();
242       PsiElement parent = owner instanceof PsiModifierList ? ((PsiModifierList)owner).getParent() : null;
243       if (parent instanceof PsiMethod) {
244         myHolder.add(GenericsHighlightUtil.checkOverrideAnnotation((PsiMethod)parent, annotation, myLanguageLevel));
245       }
246     }
247   }
248
249   @Override
250   public void visitAnnotationArrayInitializer(PsiArrayInitializerMemberValue initializer) {
251     PsiMethod method = null;
252     PsiElement parent = initializer.getParent();
253     if (parent instanceof PsiNameValuePair) {
254       method = (PsiMethod)parent.getReference().resolve();
255     }
256     else if (PsiUtil.isAnnotationMethod(parent)) {
257       method = (PsiMethod)parent;
258     }
259     if (method != null) {
260       PsiType type = method.getReturnType();
261       if (type instanceof PsiArrayType) {
262         type = ((PsiArrayType)type).getComponentType();
263         PsiAnnotationMemberValue[] initializers = initializer.getInitializers();
264         for (PsiAnnotationMemberValue initializer1 : initializers) {
265           myHolder.add(AnnotationsHighlightUtil.checkMemberValueType(initializer1, type));
266         }
267       }
268     }
269   }
270
271   @Override
272   public void visitAnnotationMethod(PsiAnnotationMethod method) {
273     PsiType returnType = method.getReturnType();
274     PsiAnnotationMemberValue value = method.getDefaultValue();
275     if (returnType != null && value != null) {
276       myHolder.add(AnnotationsHighlightUtil.checkMemberValueType(value, returnType));
277     }
278
279     myHolder.add(AnnotationsHighlightUtil.checkValidAnnotationType(method.getReturnTypeElement()));
280     final PsiClass aClass = method.getContainingClass();
281     myHolder.add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), aClass));
282     myHolder.add(AnnotationsHighlightUtil.checkClashesWithSuperMethods(method));
283
284     if (!myHolder.hasErrorResults() && aClass != null) {
285       myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass)));
286     }
287   }
288
289   @Override
290   public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
291     super.visitArrayInitializerExpression(expression);
292     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkArrayInitializerApplicable(expression));
293     if (!(expression.getParent() instanceof PsiNewExpression)) {
294       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType()));
295     }
296   }
297
298   @Override
299   public void visitAssignmentExpression(PsiAssignmentExpression assignment) {
300     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentCompatibleTypes(assignment));
301     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentOperatorApplicable(assignment, myFile));
302     if (!myHolder.hasErrorResults()) visitExpression(assignment);
303   }
304
305   @Override
306   public void visitPolyadicExpression(PsiPolyadicExpression expression) {
307     super.visitPolyadicExpression(expression);
308     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkPolyadicOperatorApplicable(expression));
309   }
310
311   @Override
312   public void visitLambdaExpression(PsiLambdaExpression expression) {
313     myHolder.add(checkFeature(expression, Feature.LAMBDA_EXPRESSIONS));
314     if (!myHolder.hasErrorResults()) {
315       if (LambdaUtil.isValidLambdaContext(expression.getParent())) {
316         final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
317         if (functionalInterfaceType != null) {
318           final String notFunctionalMessage = LambdaHighlightingUtil.checkInterfaceFunctional(functionalInterfaceType);
319           if (notFunctionalMessage != null) {
320             HighlightInfo result =
321               HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(notFunctionalMessage)
322                 .create();
323             myHolder.add(result);
324           }
325           else {
326             if (!LambdaUtil.isLambdaFullyInferred(expression, functionalInterfaceType) && !expression.hasFormalParameterTypes()) {
327               String description = InferenceSession.getInferenceErrorMessage(PsiTreeUtil.getParentOfType(expression, PsiCallExpression.class));
328               if (description == null) {
329                 description = "Cyclic inference";
330               }
331               HighlightInfo result =
332                 HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
333               myHolder.add(result);
334             }
335             else {
336               final String incompatibleReturnTypesMessage = LambdaUtil
337                 .checkReturnTypeCompatible(expression, LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType));
338               if (incompatibleReturnTypesMessage != null) {
339                 final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(expression);
340                 final PsiElement returnStatementToHighlight = returnExpressions.size() == 1 ? returnExpressions.get(0) : expression.getBody();
341                 HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(returnStatementToHighlight != null ? returnStatementToHighlight : expression)
342                   .descriptionAndTooltip(incompatibleReturnTypesMessage).create();
343                 myHolder.add(result);
344               }
345               else {
346                 final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
347                 final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
348                 if (interfaceMethod != null) {
349                   final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
350                   HighlightInfo result = LambdaHighlightingUtil
351                     .checkParametersCompatible(expression, parameters, LambdaUtil.getSubstitutor(interfaceMethod, resolveResult));
352                   if (result != null) {
353                     myHolder.add(result);
354                   } else {
355                     final PsiClass samClass = resolveResult.getElement();
356                     if (!PsiUtil.isAccessible(myFile.getProject(), samClass, expression, null)) {
357                       myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
358                                      .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
359                     }
360                   }
361                 }
362               }
363             }
364           }
365         } else if (LambdaUtil.getFunctionalInterfaceType(expression, true) != null) {
366           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip("Cannot infer functional interface type").create());
367         }
368       }
369       else {
370         HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
371           .descriptionAndTooltip("Lambda expression not expected here").create();
372         myHolder.add(result);
373       }
374       if (!myHolder.hasErrorResults()) {
375         final PsiElement body = expression.getBody();
376         if (body instanceof PsiCodeBlock) {
377           myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement((PsiCodeBlock)body));
378         }
379       }
380     }
381   }
382
383   @Override
384   public void visitBreakStatement(PsiBreakStatement statement) {
385     super.visitBreakStatement(statement);
386     if (!myHolder.hasErrorResults()) {
387       myHolder.add(HighlightUtil.checkLabelDefined(statement.getLabelIdentifier(), statement.findExitedStatement()));
388     }
389     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkBreakOutsideLoop(statement));
390   }
391
392   @Override
393   public void visitClass(PsiClass aClass) {
394     super.visitClass(aClass);
395     if (aClass instanceof PsiSyntheticClass) return;
396     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInterfaceMultipleInheritance(aClass));
397     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.areSupersAccessible(aClass));
398     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateTopLevelClass(aClass));
399     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumMustNotBeLocal(aClass));
400     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumWithoutConstantsCantHaveAbstractMethods(aClass));
401     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass, myJavaSdkVersion));
402     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassAndPackageConflict(aClass));
403     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkPublicClassInRightFile(aClass));
404   }
405
406   @Override
407   public void visitClassInitializer(PsiClassInitializer initializer) {
408     super.visitClassInitializer(initializer);
409     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkInitializerCompleteNormally(initializer));
410     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(initializer.getBody()));
411     if (!myHolder.hasErrorResults()) {
412       myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(initializer, initializer.getContainingClass()));
413     }
414   }
415
416   @Override
417   public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
418     super.visitClassObjectAccessExpression(expression);
419     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkClassObjectAccessExpression(expression));
420   }
421
422   @Override
423   public void visitComment(PsiComment comment) {
424     super.visitComment(comment);
425     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnclosedComment(comment));
426     if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(comment);
427   }
428
429   @Override
430   public void visitContinueStatement(PsiContinueStatement statement) {
431     super.visitContinueStatement(statement);
432     if (!myHolder.hasErrorResults()) {
433       myHolder.add(HighlightUtil.checkLabelDefined(statement.getLabelIdentifier(), statement.findContinuedStatement()));
434     }
435     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkContinueOutsideLoop(statement));
436   }
437
438   @Override
439   public void visitJavaToken(PsiJavaToken token) {
440     super.visitJavaToken(token);
441     if (!myHolder.hasErrorResults()
442         && token.getTokenType() == JavaTokenType.RBRACE
443         && token.getParent() instanceof PsiCodeBlock) {
444
445       final PsiElement gParent = token.getParent().getParent();
446       final PsiCodeBlock codeBlock;
447       final PsiType returnType;
448       if (gParent instanceof PsiMethod) {
449         PsiMethod method = (PsiMethod)gParent;
450         codeBlock = method.getBody();
451         returnType = method.getReturnType();
452       }
453       else if (gParent instanceof PsiLambdaExpression) {
454         final PsiElement body = ((PsiLambdaExpression)gParent).getBody();
455         if (!(body instanceof PsiCodeBlock)) return;
456         codeBlock = (PsiCodeBlock)body;
457         returnType = LambdaUtil.getFunctionalInterfaceReturnType((PsiLambdaExpression)gParent);
458       }
459       else {
460         return;
461       }
462       myHolder.add(HighlightControlFlowUtil.checkMissingReturnStatement(codeBlock, returnType));
463     }
464   }
465
466   @Override
467   public void visitDocComment(PsiDocComment comment) {
468     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnclosedComment(comment));
469   }
470
471   @Override
472   public void visitDocTagValue(PsiDocTagValue value) {
473     PsiReference reference = value.getReference();
474     if (reference != null) {
475       PsiElement element = reference.resolve();
476       final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
477       if (element instanceof PsiMethod) {
478         myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)element, ((PsiDocMethodOrFieldRef)value).getNameElement(), false,
479                                                             colorsScheme));
480       }
481       else if (element instanceof PsiParameter) {
482         myHolder.add(HighlightNamesUtil.highlightVariableName((PsiVariable)element, value.getNavigationElement(), colorsScheme));
483       }
484     }
485   }
486
487   @Override
488   public void visitEnumConstant(PsiEnumConstant enumConstant) {
489     super.visitEnumConstant(enumConstant);
490     if (!myHolder.hasErrorResults()) GenericsHighlightUtil.checkEnumConstantForConstructorProblems(enumConstant, myHolder, myJavaSdkVersion);
491     if (!myHolder.hasErrorResults()) registerConstructorCall(enumConstant);
492   }
493
494   @Override
495   public void visitEnumConstantInitializer(PsiEnumConstantInitializer enumConstantInitializer) {
496     super.visitEnumConstantInitializer(enumConstantInitializer);
497     if (!myHolder.hasErrorResults()) {
498       TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(enumConstantInitializer);
499       myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(enumConstantInitializer, textRange));
500     }
501   }
502
503   @Override
504   public void visitExpression(PsiExpression expression) {
505     ProgressManager.checkCanceled(); // visitLiteralExpression is invoked very often in array initializers
506
507     super.visitExpression(expression);
508     PsiType type = expression.getType();
509     if (myHolder.add(HighlightUtil.checkMustBeBoolean(expression, type))) return;
510
511     if (expression instanceof PsiArrayAccessExpression) {
512       myHolder.add(HighlightUtil.checkValidArrayAccessExpression((PsiArrayAccessExpression)expression));
513     }
514
515     PsiElement parent = expression.getParent();
516     if (parent instanceof PsiNewExpression
517         && ((PsiNewExpression)parent).getQualifier() != expression
518         && ((PsiNewExpression)parent).getArrayInitializer() != expression) {
519       // like in 'new String["s"]'
520       myHolder.add(HighlightUtil.checkAssignability(PsiType.INT, expression.getType(), expression, expression));
521     }
522     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkCannotWriteToFinal(expression,myFile));
523     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableExpected(expression));
524     if (!myHolder.hasErrorResults()) myHolder.addAll(HighlightUtil.checkArrayInitializer(expression, type));
525     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTernaryOperatorConditionIsBoolean(expression, type));
526     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssertOperatorTypes(expression, type));
527     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSynchronizedExpressionType(expression, type, myFile));
528     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkConditionalExpressionBranchTypesMatch(expression, type));
529     if (!myHolder.hasErrorResults()
530         && parent instanceof PsiThrowStatement
531         && ((PsiThrowStatement)parent).getException() == expression) {
532       myHolder.add(HighlightUtil.checkMustBeThrowable(type, expression, true));
533     }
534
535     if (!myHolder.hasErrorResults()) {
536       myHolder.add(AnnotationsHighlightUtil.checkConstantExpression(expression));
537     }
538     if (!myHolder.hasErrorResults() && parent instanceof PsiForeachStatement && ((PsiForeachStatement)parent).getIteratedValue() == expression) {
539       myHolder.add(GenericsHighlightUtil.checkForeachExpressionTypeIsIterable(expression));
540     }
541   }
542
543   @Override
544   public void visitExpressionList(PsiExpressionList list) {
545     super.visitExpressionList(list);
546     PsiElement parent = list.getParent();
547     if (parent instanceof PsiMethodCallExpression) {
548       PsiMethodCallExpression expression = (PsiMethodCallExpression)parent;
549       if (expression.getArgumentList() == list) {
550         PsiReferenceExpression referenceExpression = expression.getMethodExpression();
551         JavaResolveResult result;
552         JavaResolveResult[] results;
553         try {
554           results = resolveOptimised(referenceExpression);
555           result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
556         }
557         catch (IndexNotReadyException e) {
558           return;
559         }
560         PsiElement resolved = result.getElement();
561
562         if ((!result.isAccessible() || !result.isStaticsScopeCorrect()) &&
563             !HighlightMethodUtil.isDummyConstructorCall(expression, myResolveHelper, list, referenceExpression) &&
564             // this check is for fake expression from JspMethodCallImpl
565             referenceExpression.getParent() == expression) {
566           try {
567             if (PsiTreeUtil.findChildrenOfType(expression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
568               myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallArguments(referenceExpression, results, list, resolved, result, expression, myResolveHelper, list));
569             }
570           }
571           catch (IndexNotReadyException ignored) {
572           }
573         }
574       }
575     }
576   }
577
578   @Override
579   public void visitField(PsiField field) {
580     super.visitField(field);
581     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalFieldInitialized(field));
582   }
583
584   @Override
585   public void visitForStatement(PsiForStatement statement) {
586     myHolder.add(HighlightUtil.checkForStatement(statement));
587   }
588
589   @Override
590   public void visitForeachStatement(PsiForeachStatement statement) {
591     myHolder.add(checkFeature(statement, Feature.FOR_EACH));
592   }
593
594   @Override
595   public void visitImportStaticStatement(PsiImportStaticStatement statement) {
596     myHolder.add(checkFeature(statement, Feature.STATIC_IMPORTS));
597   }
598
599   @Override
600   public void visitIdentifier(final PsiIdentifier identifier) {
601     TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
602
603     PsiElement parent = identifier.getParent();
604     if (parent instanceof PsiVariable) {
605       PsiVariable variable = (PsiVariable)parent;
606       myHolder.add(HighlightUtil.checkVariableAlreadyDefined(variable));
607
608       if (variable.getInitializer() == null) {
609         final PsiElement child = variable.getLastChild();
610         if (child instanceof PsiErrorElement && child.getPrevSibling() == identifier) return;
611       }
612
613       boolean isMethodParameter = variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiMethod;
614       if (isMethodParameter) {
615         myReassignedParameters.put((PsiParameter)variable, 1); // mark param as present in current file
616       }
617       else {
618         // method params are highlighted in visitMethod since we should make sure the method body was visited before
619         if (HighlightControlFlowUtil.isReassigned(variable, myFinalVarProblems)) {
620           myHolder.add(HighlightNamesUtil.highlightReassignedVariable(variable, identifier));
621         }
622         else {
623           myHolder.add(HighlightNamesUtil.highlightVariableName(variable, identifier, colorsScheme));
624         }
625       }
626
627       myHolder.add(HighlightUtil.checkUnderscore(identifier, variable, myLanguageLevel));
628     }
629     else if (parent instanceof PsiClass) {
630       PsiClass aClass = (PsiClass)parent;
631       if (aClass.isAnnotationType()) {
632         myHolder.add(checkFeature(identifier, Feature.ANNOTATIONS));
633       }
634
635       myHolder.add(HighlightClassUtil.checkClassAlreadyImported(aClass, identifier));
636       if (!(parent instanceof PsiAnonymousClass) && aClass.getNameIdentifier() == identifier) {
637         myHolder.add(HighlightNamesUtil.highlightClassName(aClass, identifier, colorsScheme));
638       }
639       if (!myHolder.hasErrorResults() && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
640         myHolder.add(GenericsHighlightUtil.checkUnrelatedDefaultMethods(aClass, aClass.getVisibleSignatures(), identifier));
641       }
642     }
643     else if (parent instanceof PsiMethod) {
644       PsiMethod method = (PsiMethod)parent;
645       if (method.isConstructor()) {
646         myHolder.add(HighlightMethodUtil.checkConstructorName(method));
647       }
648       myHolder.add(HighlightNamesUtil.highlightMethodName(method, identifier, true, colorsScheme));
649       final PsiClass aClass = method.getContainingClass();
650       if (aClass != null) {
651         myHolder.add(GenericsHighlightUtil.checkDefaultMethodOverrideEquivalentToObjectNonPrivate(myLanguageLevel, aClass, method, identifier));
652       }
653     }
654
655     super.visitIdentifier(identifier);
656   }
657
658   @Override
659   public void visitImportStatement(final PsiImportStatement statement) {
660     if (!myHolder.hasErrorResults()) {
661       myHolder.add(HighlightUtil.checkSingleImportClassConflict(statement, mySingleImportedClasses,myFile));
662     }
663   }
664
665   @Override
666   public void visitImportStaticReferenceElement(final PsiImportStaticReferenceElement ref) {
667     final String refName = ref.getReferenceName();
668     final JavaResolveResult[] results = ref.multiResolve(false);
669
670     final PsiElement referenceNameElement = ref.getReferenceNameElement();
671     if (results.length == 0) {
672       final String description = JavaErrorMessages.message("cannot.resolve.symbol", refName);
673       assert referenceNameElement != null : ref;
674       final HighlightInfo info =
675         HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(referenceNameElement).descriptionAndTooltip(description).create();
676       QuickFixAction.registerQuickFixAction(info, QuickFixFactory.getInstance().createSetupJDKFix());
677       myHolder.add(info);
678     }
679     else {
680       final PsiManager manager = ref.getManager();
681       for (JavaResolveResult result : results) {
682         final PsiElement element = result.getElement();
683
684         String description = null;
685         if (element instanceof PsiClass) {
686           final Pair<PsiImportStaticReferenceElement, PsiClass> imported = mySingleImportedClasses.get(refName);
687           final PsiClass aClass = imported == null ? null : imported.getSecond();
688           if (aClass != null && !manager.areElementsEquivalent(aClass, element)) {
689             description = imported.first == null
690                           ? JavaErrorMessages.message("single.import.class.conflict", refName)
691                           : imported.first.equals(ref)
692                             ? JavaErrorMessages.message("class.is.ambiguous.in.single.static.import", refName)
693                             : JavaErrorMessages.message("class.is.already.defined.in.single.static.import", refName);
694           }
695           mySingleImportedClasses.put(refName, Pair.create(ref, (PsiClass)element));
696         }
697         else if (element instanceof PsiField) {
698           final Pair<PsiImportStaticReferenceElement, PsiField> imported = mySingleImportedFields.get(refName);
699           final PsiField field = imported == null ? null : imported.getSecond();
700           if (field != null && !manager.areElementsEquivalent(field, element)) {
701             description = imported.first.equals(ref)
702                           ? JavaErrorMessages.message("field.is.ambiguous.in.single.static.import", refName)
703                           : JavaErrorMessages.message("field.is.already.defined.in.single.static.import", refName);
704           }
705           mySingleImportedFields.put(refName, Pair.create(ref, (PsiField)element));
706         }
707
708         if (description != null) {
709           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(description).create());
710         }
711       }
712     }
713     if (!myHolder.hasErrorResults()) {
714       final PsiElement resolved = results.length == 1 ? results[0].getElement() : null;
715       final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
716       if (resolved instanceof PsiClass) {
717         myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, ref, colorsScheme));
718       }
719       else{
720         myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(ref, colorsScheme));
721         if (resolved instanceof PsiVariable) {
722           myHolder.add(HighlightNamesUtil.highlightVariableName((PsiVariable)resolved, referenceNameElement, colorsScheme));
723         }
724         else if (resolved instanceof PsiMethod) {
725           myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)resolved, referenceNameElement, false, colorsScheme));
726         }
727       }
728     }
729   }
730
731   @Override
732   public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
733     super.visitInstanceOfExpression(expression);
734     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInstanceOfApplicable(expression));
735     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInstanceOfGenericType(expression));
736   }
737
738   @Override
739   public void visitKeyword(PsiKeyword keyword) {
740     super.visitKeyword(keyword);
741     PsiElement parent = keyword.getParent();
742     String text = keyword.getText();
743     if (parent instanceof PsiModifierList) {
744       PsiModifierList psiModifierList = (PsiModifierList)parent;
745       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkNotAllowedModifier(keyword, psiModifierList));
746       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalModifierCombination(keyword, psiModifierList));
747       if (PsiModifier.ABSTRACT.equals(text) && psiModifierList.getParent() instanceof PsiMethod) {
748         if (!myHolder.hasErrorResults()) {
749           myHolder.add(HighlightMethodUtil.checkAbstractMethodInConcreteClass((PsiMethod)psiModifierList.getParent(), keyword));
750         }
751       }
752     }
753     else if (PsiKeyword.INTERFACE.equals(text) && parent instanceof PsiClass) {
754       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkInterfaceCannotBeLocal((PsiClass)parent));
755     }
756     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkStaticDeclarationInInnerClass(keyword));
757     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalVoidType(keyword));
758   }
759
760   @Override
761   public void visitLabeledStatement(PsiLabeledStatement statement) {
762     super.visitLabeledStatement(statement);
763     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelWithoutStatement(statement));
764     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelAlreadyInUse(statement));
765   }
766
767   @Override
768   public void visitLiteralExpression(PsiLiteralExpression expression) {
769     super.visitLiteralExpression(expression);
770     if (myHolder.hasErrorResults()) return;
771     myHolder.add(HighlightUtil.checkLiteralExpressionParsingError(expression, myLanguageLevel,myFile));
772     if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(expression);
773   }
774
775   @Override
776   public void visitMethod(PsiMethod method) {
777     super.visitMethod(method);
778     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(method.getBody()));
779     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorHandleSuperClassExceptions(method));
780     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkRecursiveConstructorInvocation(method));
781     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSafeVarargsAnnotation(method, myLanguageLevel));
782
783     PsiClass aClass = method.getContainingClass();
784     if (!myHolder.hasErrorResults() && method.isConstructor()) {
785       myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(method, aClass));
786     }
787     if (!myHolder.hasErrorResults() && method.hasModifierProperty(PsiModifier.DEFAULT)) {
788       myHolder.add(checkFeature(method, Feature.EXTENSION_METHODS));
789     }
790     if (!myHolder.hasErrorResults() && aClass != null && aClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) {
791       myHolder.add(checkFeature(method, Feature.EXTENSION_METHODS));
792     }
793     if (!myHolder.hasErrorResults() && aClass != null) {
794       myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass)));
795     }
796
797     // method params are highlighted in visitMethod since we should make sure the method body was visited before
798     PsiParameter[] parameters = method.getParameterList().getParameters();
799     final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
800
801     for (PsiParameter parameter : parameters) {
802       int info = myReassignedParameters.get(parameter);
803       if (info == 0) continue; // out of this file
804       if (info == 2) {// reassigned
805         myHolder.add(HighlightNamesUtil.highlightReassignedVariable(parameter, parameter.getNameIdentifier()));
806       }
807       else {
808         myHolder.add(HighlightNamesUtil.highlightVariableName(parameter, parameter.getNameIdentifier(), colorsScheme));
809       }
810     }
811   }
812
813   private void highlightReferencedMethodOrClassName(PsiJavaCodeReferenceElement element, PsiElement resolved) {
814     PsiElement parent = element.getParent();
815     if (parent instanceof PsiReferenceExpression || parent instanceof PsiJavaCodeReferenceElement) {
816       return;
817     }
818     final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
819     if (parent instanceof PsiMethodCallExpression) {
820       PsiMethod method = ((PsiMethodCallExpression)parent).resolveMethod();
821       PsiElement methodNameElement = element.getReferenceNameElement();
822       if (method != null && methodNameElement != null&& !(methodNameElement instanceof PsiKeyword)) {
823         myHolder.add(HighlightNamesUtil.highlightMethodName(method, methodNameElement, false, colorsScheme));
824         myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(element, colorsScheme));
825       }
826     }
827     else if (parent instanceof PsiConstructorCall) {
828       try {
829         PsiMethod method = ((PsiConstructorCall)parent).resolveConstructor();
830         if (method == null) {
831           if (resolved instanceof PsiClass) {
832             myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, element, colorsScheme));
833           }
834         }
835         else {
836           final PsiElement referenceNameElement = element.getReferenceNameElement();
837           if(referenceNameElement != null) {
838             // exclude type parameters from the highlighted text range
839             TextRange range = new TextRange(element.getTextRange().getStartOffset(), referenceNameElement.getTextRange().getEndOffset());
840             myHolder.add(HighlightNamesUtil.highlightMethodName(method, referenceNameElement, range, colorsScheme, false));
841           }
842         }
843       }
844       catch (IndexNotReadyException ignored) {
845       }
846     }
847     else if (parent instanceof PsiImportStatement && ((PsiImportStatement)parent).isOnDemand()) {
848       // highlight on demand import as class
849       myHolder.add(HighlightNamesUtil.highlightClassName(null, element, colorsScheme));
850     }
851     else if (resolved instanceof PsiClass) {
852       myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, element, colorsScheme));
853     }
854   }
855
856   @Override
857   public void visitMethodCallExpression(PsiMethodCallExpression expression) {
858     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumSuperConstructorCall(expression));
859     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkSuperQualifierType(myFile.getProject(), expression));
860     // in case of JSP synthetic method call, do not check
861     if (myFile.isPhysical() && !myHolder.hasErrorResults()) {
862       try {
863         myHolder.add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper, myLanguageLevel,myJavaSdkVersion));
864       }
865       catch (IndexNotReadyException ignored) {
866       }
867     }
868
869     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallMustBeFirstStatement(expression));
870     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkSuperAbstractMethodDirectCall(expression));
871
872     if (!myHolder.hasErrorResults()) visitExpression(expression);
873   }
874
875   @Override
876   public void visitModifierList(PsiModifierList list) {
877     super.visitModifierList(list);
878     PsiElement parent = list.getParent();
879     if (parent instanceof PsiMethod) {
880       PsiMethod method = (PsiMethod)parent;
881       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method, myLanguageLevel));
882       MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
883       if (!method.isConstructor()) {
884         try {
885           List<HierarchicalMethodSignature> superMethodSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
886           if (!superMethodSignatures.isEmpty()) {
887             if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleReturnType(methodSignature, superMethodSignatures, true));
888             if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleThrows(methodSignature, superMethodSignatures, true, method.getContainingClass()));
889             if (!method.hasModifierProperty(PsiModifier.STATIC)) {
890               if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodWeakerPrivileges(methodSignature, superMethodSignatures, true, myFile));
891               if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodOverridesFinal(methodSignature, superMethodSignatures));
892             }
893           }
894         }
895         catch (IndexNotReadyException ignored) {
896         }
897       }
898       PsiClass aClass = method.getContainingClass();
899       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodMustHaveBody(method, aClass));
900       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallsBaseClassConstructor(method, myRefCountHolder, myResolveHelper));
901       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkStaticMethodOverride(method,myFile));
902     }
903     else if (parent instanceof PsiClass) {
904       PsiClass aClass = (PsiClass)parent;
905       try {
906         if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateNestedClass(aClass));
907         if (!myHolder.hasErrorResults()) {
908           TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass);
909           myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(aClass, textRange));
910         }
911         if (!myHolder.hasErrorResults()) {
912           myHolder.add(HighlightClassUtil.checkClassDoesNotCallSuperConstructorOrHandleExceptions(aClass, myRefCountHolder, myResolveHelper));
913         }
914         if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkOverrideEquivalentInheritedMethods(aClass, myFile, myLanguageLevel));
915         if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass));
916         if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCyclicInheritance(aClass));
917       }
918       catch (IndexNotReadyException ignored) {
919       }
920     }
921     else if (parent instanceof PsiEnumConstant) {
922       if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkEnumConstantModifierList(list));
923     }
924   }
925
926   @Override
927   public void visitNameValuePair(PsiNameValuePair pair) {
928     myHolder.add(AnnotationsHighlightUtil.checkNameValuePair(pair));
929     if (!myHolder.hasErrorResults()) {
930       PsiIdentifier nameId = pair.getNameIdentifier();
931       if (nameId != null) {
932         HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ANNOTATION_ATTRIBUTE_NAME).range(nameId).create();
933         myHolder.add(result);
934       }
935     }
936   }
937
938   @Override
939   public void visitNewExpression(PsiNewExpression expression) {
940     final PsiType type = expression.getType();
941     final PsiClass aClass = PsiUtil.resolveClassInType(type);
942     myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, null));
943     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression));
944     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkQualifiedNew(expression, type, aClass));
945     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(expression, type, aClass));
946     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParameterInstantiation(expression));
947     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(aClass, expression));
948     try {
949       if (!myHolder.hasErrorResults()) HighlightMethodUtil.checkNewExpression(expression, type, myHolder, myJavaSdkVersion);
950     }
951     catch (IndexNotReadyException ignored) {
952     }
953     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, aClass));
954     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, type));
955     if (!myHolder.hasErrorResults()) registerConstructorCall(expression);
956
957     if (!myHolder.hasErrorResults()) visitExpression(expression);
958   }
959
960   @Override
961   public void visitPackageStatement(PsiPackageStatement statement) {
962     super.visitPackageStatement(statement);
963     myHolder.add(AnnotationsHighlightUtil.checkPackageAnnotationContainingFile(statement));
964   }
965
966   @Override
967   public void visitParameter(PsiParameter parameter) {
968     super.visitParameter(parameter);
969
970     final PsiElement parent = parameter.getParent();
971     if (parent instanceof PsiParameterList && parameter.isVarArgs()) {
972       if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(parameter, Feature.VARARGS));
973       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkVarArgParameterIsLast(parameter));
974     }
975     else if (parent instanceof PsiCatchSection) {
976       if (!myHolder.hasErrorResults() && parameter.getType() instanceof PsiDisjunctionType) {
977         myHolder.add(checkFeature(parameter, Feature.MULTI_CATCH));
978       }
979       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkCatchParameterIsThrowable(parameter));
980       if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkCatchParameterIsClass(parameter));
981       if (!myHolder.hasErrorResults()) myHolder.addAll(HighlightUtil.checkCatchTypeIsDisjoint(parameter));
982     }
983     else if (parent instanceof PsiForeachStatement) {
984       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkForEachParameterType((PsiForeachStatement)parent, parameter));
985     }
986   }
987
988   @Override
989   public void visitParameterList(PsiParameterList list) {
990     super.visitParameterList(list);
991     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAnnotationMethodParameters(list));
992   }
993
994   @Override
995   public void visitPostfixExpression(PsiPostfixExpression expression) {
996     super.visitPostfixExpression(expression);
997     if (!myHolder.hasErrorResults()) {
998       myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
999     }
1000   }
1001
1002   @Override
1003   public void visitPrefixExpression(PsiPrefixExpression expression) {
1004     super.visitPrefixExpression(expression);
1005     if (!myHolder.hasErrorResults()) {
1006       myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
1007     }
1008   }
1009
1010   private void registerConstructorCall(@NotNull PsiConstructorCall constructorCall) {
1011     if (myRefCountHolder != null) {
1012       JavaResolveResult resolveResult = constructorCall.resolveMethodGenerics();
1013       final PsiElement resolved = resolveResult.getElement();
1014       if (resolved instanceof PsiNamedElement) {
1015         myRefCountHolder.registerLocallyReferenced((PsiNamedElement)resolved);
1016       }
1017     }
1018   }
1019
1020   @Override
1021   public void visitReferenceElement(PsiJavaCodeReferenceElement ref) {
1022     JavaResolveResult resolveResult = doVisitReferenceElement(ref);
1023     if (resolveResult != null && !myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkRawOnParameterizedType(ref, resolveResult.getElement()));
1024   }
1025
1026   private JavaResolveResult doVisitReferenceElement(@NotNull PsiJavaCodeReferenceElement ref) {
1027     JavaResolveResult result;
1028     try {
1029       result = resolveOptimised(ref);
1030     }
1031     catch (IndexNotReadyException e) {
1032       return null;
1033     }
1034     PsiElement resolved = result.getElement();
1035     PsiElement parent = ref.getParent();
1036
1037     if (myRefCountHolder != null) {
1038       myRefCountHolder.registerReference(ref, result);
1039     }
1040     myHolder.add(HighlightUtil.checkReference(ref, result, myFile, myLanguageLevel));
1041     if (parent instanceof PsiJavaCodeReferenceElement || ref.isQualified()) {
1042       if (!myHolder.hasErrorResults() && resolved instanceof PsiTypeParameter) {
1043         boolean cannotSelectFromTypeParameter = !myJavaSdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7);
1044         if (!cannotSelectFromTypeParameter) {
1045           final PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
1046           if (containingClass != null) {
1047             if (PsiTreeUtil.isAncestor(containingClass.getExtendsList(), ref, false) ||
1048                 PsiTreeUtil.isAncestor(containingClass.getImplementsList(), ref, false)) {
1049               cannotSelectFromTypeParameter = true;
1050             }
1051           }
1052         }
1053         if (cannotSelectFromTypeParameter) {
1054           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Cannot select from a type parameter").range(ref).create());
1055         }
1056       }
1057     }
1058     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAbstractInstantiation(ref));
1059     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsDuplicate(ref, resolved,myFile));
1060     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassExtendsForeignInnerClass(ref, resolved));
1061     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSelectStaticClassFromParameterizedType(resolved, ref));
1062     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, ref,
1063                                                                                                                  result.getSubstitutor(),
1064                                                                                                                  myJavaSdkVersion));
1065     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkCannotPassInner(ref));
1066
1067     if (resolved != null && parent instanceof PsiReferenceList) {
1068       if (!myHolder.hasErrorResults()) {
1069         PsiReferenceList referenceList = (PsiReferenceList)parent;
1070         myHolder.add(HighlightUtil.checkElementInReferenceList(ref, referenceList, result, myLanguageLevel));
1071       }
1072     }
1073
1074     if (parent instanceof PsiAnonymousClass && ref.equals(((PsiAnonymousClass)parent).getBaseClassReference())) {
1075       PsiClass aClass = (PsiClass)parent;
1076       myHolder.addAll(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass));
1077     }
1078
1079     if (resolved instanceof PsiVariable) {
1080       PsiVariable variable = (PsiVariable)resolved;
1081
1082       final PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
1083       if (containingClass instanceof PsiAnonymousClass &&
1084           !PsiTreeUtil.isAncestor(containingClass, variable, false) &&
1085           !(variable instanceof PsiField)) {
1086         if (!PsiTreeUtil.isAncestor(((PsiAnonymousClass) containingClass).getArgumentList(), ref, false)) {
1087           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.IMPLICIT_ANONYMOUS_CLASS_PARAMETER).range(ref).create());
1088         }
1089       }
1090
1091       if (variable instanceof PsiParameter && ref instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression)ref)) {
1092         myReassignedParameters.put((PsiParameter)variable, 2);
1093       }
1094
1095       final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
1096       if (!variable.hasModifierProperty(PsiModifier.FINAL) && isReassigned(variable)) {
1097         myHolder.add(HighlightNamesUtil.highlightReassignedVariable(variable, ref));
1098       }
1099       else {
1100         myHolder.add(HighlightNamesUtil.highlightVariableName(variable, ref.getReferenceNameElement(), colorsScheme));
1101       }
1102       myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(ref, colorsScheme));
1103     }
1104     else {
1105       highlightReferencedMethodOrClassName(ref, resolved);
1106     }
1107
1108     if (parent instanceof PsiNewExpression && !(resolved instanceof PsiClass) && resolved instanceof PsiNamedElement && ((PsiNewExpression)parent).getClassOrAnonymousClassReference() == ref) {
1109        myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref)
1110                       .descriptionAndTooltip("Cannot find symbol " + ((PsiNamedElement)resolved).getName()).create());
1111     }
1112     if (!myHolder.hasErrorResults() && resolved instanceof PsiClass) {
1113       final PsiClass aClass = ((PsiClass)resolved).getContainingClass();
1114       if (aClass != null) {
1115         final PsiElement qualifier = ref.getQualifier();
1116         final PsiElement place;
1117         if (qualifier instanceof PsiJavaCodeReferenceElement) {
1118           place = ((PsiJavaCodeReferenceElement)qualifier).resolve();
1119         }
1120         else {
1121           if (parent instanceof PsiNewExpression) {
1122             final PsiExpression newQualifier = ((PsiNewExpression)parent).getQualifier();
1123             place = newQualifier == null ? ref : PsiUtil.resolveClassInType(newQualifier.getType());
1124           }
1125           else {
1126             place = ref;
1127           }
1128         }
1129         if (place != null && PsiTreeUtil.isAncestor(aClass, place, false) && aClass.hasTypeParameters()) {
1130           myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(ref, place, (PsiClass)resolved));
1131         }
1132       }
1133       else if (resolved instanceof PsiTypeParameter) {
1134         final PsiTypeParameterListOwner owner = ((PsiTypeParameter)resolved).getOwner();
1135         if (owner instanceof PsiClass) {
1136           final PsiClass outerClass = (PsiClass)owner;
1137           if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, false, false)) {
1138             myHolder.add(HighlightClassUtil.reportIllegalEnclosingUsage(ref, null, (PsiClass)owner, ref));
1139           }
1140         }
1141       }
1142     }
1143
1144     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkPackageAndClassConflict(ref, myFile));
1145
1146     return result;
1147   }
1148
1149   @NotNull
1150   private JavaResolveResult resolveOptimised(@NotNull PsiJavaCodeReferenceElement ref) {
1151     JavaResolveResult result;
1152     if (ref instanceof PsiReferenceExpressionImpl) {
1153       JavaResolveResult[] results = JavaResolveUtil.resolveWithContainingFile(ref,
1154                                                                               PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE,
1155                                                                               true, true,
1156                                                                               myFile);
1157       result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1158     }
1159     else {
1160       result = ref.advancedResolve(true);
1161     }
1162     return result;
1163   }
1164
1165   @NotNull
1166   private JavaResolveResult[] resolveOptimised(@NotNull PsiReferenceExpression expression) {
1167     JavaResolveResult[] results;
1168     if (expression instanceof PsiReferenceExpressionImpl) {
1169       results = JavaResolveUtil.resolveWithContainingFile(expression,
1170                                                           PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, true,
1171                                                           myFile);
1172     }
1173     else {
1174       results = expression.multiResolve(true);
1175     }
1176     return results;
1177   }
1178
1179   @Override
1180   public void visitReferenceExpression(PsiReferenceExpression expression) {
1181     JavaResolveResult resultForIncompleteCode = doVisitReferenceElement(expression);
1182     if (!myHolder.hasErrorResults()) {
1183       visitExpression(expression);
1184       if (myHolder.hasErrorResults()) return;
1185     }
1186     JavaResolveResult result;
1187     JavaResolveResult[] results;
1188     try {
1189       results = resolveOptimised(expression);
1190       result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1191     }
1192     catch (IndexNotReadyException e) {
1193       return;
1194     }
1195     PsiElement resolved = result.getElement();
1196     if (resolved instanceof PsiVariable && resolved.getContainingFile() == expression.getContainingFile()) {
1197       if (!myHolder.hasErrorResults()) {
1198         try {
1199           myHolder.add(HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, (PsiVariable)resolved, myUninitializedVarProblems,myFile));
1200         }
1201         catch (IndexNotReadyException ignored) {
1202         }
1203       }
1204       PsiVariable variable = (PsiVariable)resolved;
1205       boolean isFinal = variable.hasModifierProperty(PsiModifier.FINAL);
1206       if (isFinal && !variable.hasInitializer()) {
1207         if (!myHolder.hasErrorResults()) {
1208           myHolder.add(HighlightControlFlowUtil.checkFinalVariableMightAlreadyHaveBeenAssignedTo(variable, expression, myFinalVarProblems));
1209         }
1210         if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalVariableInitializedInLoop(expression, resolved));
1211       }
1212     }
1213
1214     PsiElement parent = expression.getParent();
1215     if (parent instanceof PsiMethodCallExpression && ((PsiMethodCallExpression)parent).getMethodExpression() == expression && (!result.isAccessible() || !result.isStaticsScopeCorrect())) {
1216       PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)parent;
1217       PsiExpressionList list = methodCallExpression.getArgumentList();
1218       if (!HighlightMethodUtil.isDummyConstructorCall(methodCallExpression, myResolveHelper, list, expression)) {
1219         try {
1220           myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallIdentifier(expression, results, list, resolved, result, methodCallExpression, myResolveHelper));
1221           
1222           if (!PsiTreeUtil.findChildrenOfType(methodCallExpression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
1223             myHolder.add(HighlightMethodUtil
1224               .checkAmbiguousMethodCallArguments(expression, results, list, resolved, result, methodCallExpression, myResolveHelper, expression.getReferenceNameElement()));
1225           }
1226         }
1227         catch (IndexNotReadyException ignored) {
1228         }
1229       }
1230     }
1231
1232     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkExpressionRequired(expression, resultForIncompleteCode));
1233     if (!myHolder.hasErrorResults() && resolved instanceof PsiField) {
1234       try {
1235         myHolder.add(HighlightUtil.checkIllegalForwardReferenceToField(expression, (PsiField)resolved));
1236       }
1237       catch (IndexNotReadyException ignored) {
1238       }
1239     }
1240     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkAccessStaticFieldFromEnumConstructor(expression, result));
1241     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkClassReferenceAfterQualifier(expression, resolved));
1242     final PsiExpression qualifierExpression = expression.getQualifierExpression();
1243     myHolder.add(HighlightUtil.checkUnqualifiedSuperInDefaultMethod(myLanguageLevel, expression, qualifierExpression));
1244     if (!myHolder.hasErrorResults() && qualifierExpression != null) {
1245       final PsiClass psiClass = PsiUtil.resolveClassInType(qualifierExpression.getType());
1246       if (psiClass != null) {
1247         myHolder.add(GenericsHighlightUtil.areSupersAccessible(psiClass, qualifierExpression));
1248       }
1249     }
1250   }
1251
1252   @Override
1253   public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
1254     myHolder.add(checkFeature(expression, Feature.METHOD_REFERENCES));
1255
1256     final JavaResolveResult result;
1257     final JavaResolveResult[] results;
1258     try {
1259       results = expression.multiResolve(true);
1260       result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1261     }
1262     catch (IndexNotReadyException e) {
1263       return;
1264     }
1265     if (myRefCountHolder != null) {
1266       myRefCountHolder.registerReference(expression, result);
1267     }
1268     final PsiElement method = result.getElement();
1269     if (method != null && !result.isAccessible()) {
1270       final String accessProblem = HighlightUtil.buildProblemWithAccessDescription(expression, result);
1271       HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(accessProblem).create();
1272       myHolder.add(info);
1273     } else {
1274       final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
1275       if (method instanceof PsiMethod) {
1276         final PsiElement methodNameElement = expression.getReferenceNameElement();
1277         myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)method, methodNameElement, false, colorsScheme));
1278       }
1279       myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(expression, colorsScheme));
1280     }
1281     if (!myHolder.hasErrorResults()) {
1282       final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
1283       if (functionalInterfaceType != null) {
1284         final boolean notFunctional = !LambdaUtil.isFunctionalType(functionalInterfaceType);
1285         if (notFunctional) {
1286           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
1287                          .descriptionAndTooltip(functionalInterfaceType.getPresentableText() + " is not a functional interface").create());
1288         }
1289       }
1290       if (!myHolder.hasErrorResults()) {
1291         final PsiElement referenceNameElement = expression.getReferenceNameElement();
1292         if (referenceNameElement instanceof PsiKeyword) {
1293           if (!PsiMethodReferenceUtil.isValidQualifier(expression)) {
1294             final PsiElement qualifier = expression.getQualifier();
1295             String description = "Cannot find class " + qualifier.getText();
1296             HighlightInfo result1 =
1297               HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description).create();
1298             myHolder.add(result1);
1299           }
1300         }
1301       }
1302       if (!myHolder.hasErrorResults()) {
1303         final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
1304         final PsiClass psiClass = resolveResult.getElement();
1305         if (psiClass != null && !PsiUtil.isAccessible(myFile.getProject(), psiClass, expression, null)) {
1306           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
1307                          .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
1308         }
1309
1310         final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
1311         if (interfaceMethod != null) {
1312           if (!myHolder.hasErrorResults()) {
1313             final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
1314             if (errorMessage != null) {
1315               myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create());
1316             }
1317           }
1318
1319           if (!myHolder.hasErrorResults()) {
1320             final String badReturnTypeMessage = PsiMethodReferenceUtil.checkReturnType(expression, result, functionalInterfaceType);
1321             if (badReturnTypeMessage != null) {
1322               myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(badReturnTypeMessage).create());
1323             }
1324           }
1325         }
1326       }
1327     }
1328
1329     if (!myHolder.hasErrorResults()) {
1330       PsiElement qualifier = expression.getQualifier();
1331       if (qualifier instanceof PsiTypeElement) {
1332         final PsiType psiType = ((PsiTypeElement)qualifier).getType();
1333         final HighlightInfo genericArrayCreationInfo = GenericsHighlightUtil.checkGenericArrayCreation(qualifier, psiType);
1334         if (genericArrayCreationInfo != null) {
1335           myHolder.add(genericArrayCreationInfo);
1336         } else {
1337           final String wildcardMessage = PsiMethodReferenceUtil.checkTypeArguments((PsiTypeElement)qualifier, psiType);
1338           if (wildcardMessage != null) {
1339             myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(wildcardMessage).create());
1340           }
1341         }
1342       }
1343     }
1344
1345     if (!myHolder.hasErrorResults()) {
1346       myHolder.add(PsiMethodReferenceHighlightingUtil.checkRawConstructorReference(expression));
1347     }
1348
1349     if (!myHolder.hasErrorResults()) {
1350       myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
1351     }
1352
1353     if (!myHolder.hasErrorResults() && method instanceof PsiTypeParameterListOwner) {
1354       PsiTypeParameter[] typeParameters = ((PsiTypeParameterListOwner)method).getTypeParameters();
1355       if (method instanceof PsiMethod) {
1356         final PsiClass containingClass = ((PsiMethod)method).getContainingClass();
1357         assert containingClass != null : method;
1358         typeParameters = ArrayUtil.mergeArrays(typeParameters, containingClass.getTypeParameters());
1359       }
1360       myHolder.add(GenericsHighlightUtil.checkInferredTypeArguments(typeParameters, expression, result.getSubstitutor()));
1361     }
1362
1363     if (!myHolder.hasErrorResults()) {
1364       if (results.length == 0) {
1365         String description = null;
1366         if (expression.isConstructor()) {
1367           final PsiClass containingClass = PsiMethodReferenceUtil.getQualifierResolveResult(expression).getContainingClass();
1368
1369           if (containingClass != null) {
1370             if (!myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, expression)) &&
1371                 !myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, containingClass)) &&
1372                 containingClass.isPhysical()) {
1373               description = JavaErrorMessages.message("cannot.resolve.constructor", containingClass.getName());
1374             }
1375           }
1376         }
1377         else {
1378           description = JavaErrorMessages.message("cannot.resolve.method", expression.getReferenceName());
1379         }
1380
1381         if (description != null) {
1382           final PsiElement referenceNameElement = expression.getReferenceNameElement();
1383           final HighlightInfo highlightInfo =
1384             HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).descriptionAndTooltip(description).range(referenceNameElement).create();
1385           myHolder.add(highlightInfo);
1386           final TextRange fixRange = HighlightMethodUtil.getFixRange(referenceNameElement);
1387           QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QuickFixFactory.getInstance().createCreateMethodFromUsageFix(expression));
1388         }
1389       }
1390     }
1391   }
1392
1393   @Override
1394   public void visitReferenceList(PsiReferenceList list) {
1395     if (list.getFirstChild() == null) return;
1396     PsiElement parent = list.getParent();
1397     if (!(parent instanceof PsiTypeParameter)) {
1398       myHolder.add(AnnotationsHighlightUtil.checkAnnotationDeclaration(parent, list));
1399       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsAllowed(list));
1400       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkImplementsAllowed(list));
1401       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassExtendsOnlyOneClass(list));
1402       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericCannotExtendException(list));
1403     }
1404   }
1405
1406   @Override
1407   public void visitReferenceParameterList(PsiReferenceParameterList list) {
1408     if (list.getTextLength() == 0) return;
1409
1410     myHolder.add(checkFeature(list, Feature.GENERICS));
1411     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersAllowed(list));
1412     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersOnRaw(list));
1413     if (!myHolder.hasErrorResults()) {
1414       for (PsiTypeElement typeElement : list.getTypeParameterElements()) {
1415         if (typeElement.getType() instanceof PsiDiamondType) {
1416           myHolder.add(checkFeature(list, Feature.DIAMOND_TYPES));
1417         }
1418       }
1419     }
1420   }
1421
1422   @Override
1423   public void visitReturnStatement(PsiReturnStatement statement) {
1424     try {
1425       myHolder.add(HighlightUtil.checkReturnStatementType(statement));
1426     }
1427     catch (IndexNotReadyException ignore) {
1428     }
1429   }
1430
1431   @Override
1432   public void visitStatement(PsiStatement statement) {
1433     super.visitStatement(statement);
1434     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkNotAStatement(statement));
1435     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkStatementPrependedWithCaseInsideSwitch(statement));
1436   }
1437
1438   @Override
1439   public void visitSuperExpression(PsiSuperExpression expr) {
1440     myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
1441     if (!myHolder.hasErrorResults()) visitExpression(expr);
1442   }
1443
1444   @Override
1445   public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) {
1446     super.visitSwitchLabelStatement(statement);
1447     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkCaseStatement(statement));
1448   }
1449
1450   @Override
1451   public void visitSwitchStatement(PsiSwitchStatement statement) {
1452     super.visitSwitchStatement(statement);
1453     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSwitchSelectorType(statement, myLanguageLevel));
1454   }
1455
1456   @Override
1457   public void visitThisExpression(PsiThisExpression expr) {
1458     if (!(expr.getParent() instanceof PsiReceiverParameter)) {
1459       myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
1460       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null, myFile));
1461       if (!myHolder.hasErrorResults()) visitExpression(expr);
1462     }
1463   }
1464
1465   @Override
1466   public void visitThrowStatement(PsiThrowStatement statement) {
1467     myHolder.add(HighlightUtil.checkUnhandledExceptions(statement, null));
1468     if (!myHolder.hasErrorResults()) visitStatement(statement);
1469   }
1470
1471   @Override
1472   public void visitTryStatement(PsiTryStatement statement) {
1473     super.visitTryStatement(statement);
1474     if (!myHolder.hasErrorResults()) {
1475       final Set<PsiClassType> thrownTypes = HighlightUtil.collectUnhandledExceptions(statement);
1476       for (PsiParameter parameter : statement.getCatchBlockParameters()) {
1477         boolean added = myHolder.addAll(HighlightUtil.checkExceptionAlreadyCaught(parameter));
1478         if (!added) {
1479           added = myHolder.addAll(HighlightUtil.checkExceptionThrownInTry(parameter, thrownTypes));
1480         }
1481         if (!added) {
1482           myHolder.addAll(HighlightUtil.checkWithImprovedCatchAnalysis(parameter, thrownTypes, myFile));
1483         }
1484       }
1485     }
1486   }
1487
1488   @Override
1489   public void visitResourceVariable(final PsiResourceVariable resourceVariable) {
1490     visitVariable(resourceVariable);
1491     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resourceVariable));
1492     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resourceVariable));
1493   }
1494
1495   @Override
1496   public void visitResourceList(PsiResourceList resourceList) {
1497     super.visitResourceList(resourceList);
1498     if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(resourceList, Feature.TRY_WITH_RESOURCES));
1499   }
1500
1501   @Override
1502   public void visitTypeElement(final PsiTypeElement type) {
1503     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalType(type));
1504     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type, myLanguageLevel));
1505     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkWildcardUsage(type));
1506   }
1507
1508   @Override
1509   public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
1510     super.visitTypeCastExpression(typeCast);
1511     try {
1512       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIntersectionInTypeCast(typeCast, myLanguageLevel));
1513       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
1514     }
1515     catch (IndexNotReadyException ignore) {
1516     }
1517   }
1518
1519   @Override
1520   public void visitTypeParameterList(PsiTypeParameterList list) {
1521     PsiTypeParameter[] typeParameters = list.getTypeParameters();
1522     if (typeParameters.length > 0) {
1523       myHolder.add(checkFeature(list, Feature.GENERICS));
1524       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParametersList(list, typeParameters, myLanguageLevel));
1525     }
1526   }
1527
1528   @Override
1529   public void visitVariable(PsiVariable variable) {
1530     super.visitVariable(variable);
1531     try {
1532       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableInitializerType(variable));
1533     }
1534     catch (IndexNotReadyException ignored) {
1535     }
1536   }
1537
1538   private boolean isReassigned(@NotNull PsiVariable variable) {
1539     try {
1540       boolean reassigned;
1541       if (variable instanceof PsiParameter) {
1542         reassigned = myReassignedParameters.get((PsiParameter)variable) == 2;
1543       }
1544       else  {
1545         reassigned = HighlightControlFlowUtil.isReassigned(variable, myFinalVarProblems);
1546       }
1547
1548       return reassigned;
1549     }
1550     catch (IndexNotReadyException e) {
1551       return false;
1552     }
1553   }
1554
1555   @Override
1556   public void visitConditionalExpression(PsiConditionalExpression expression) {
1557     super.visitConditionalExpression(expression);
1558     if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) && PsiPolyExpressionUtil.isPolyExpression(expression)) {
1559       final PsiExpression thenExpression = expression.getThenExpression();
1560       final PsiExpression elseExpression = expression.getElseExpression();
1561       if (thenExpression != null && elseExpression != null) {
1562         final PsiType conditionalType = expression.getType();
1563         if (conditionalType != null) {
1564           final PsiExpression[] sides = {thenExpression, elseExpression};
1565           for (PsiExpression side : sides) {
1566             final PsiType sideType = side.getType();
1567             if (sideType != null && !TypeConversionUtil.isAssignable(conditionalType, sideType)) {
1568               myHolder.add(HighlightUtil.checkAssignability(conditionalType, sideType, side, side));
1569             }
1570           }
1571         }
1572       }
1573     }
1574   }
1575
1576   @Override
1577   public void visitReceiverParameter(PsiReceiverParameter parameter) {
1578     super.visitReceiverParameter(parameter);
1579     if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(parameter, Feature.RECEIVERS));
1580     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkReceiverPlacement(parameter));
1581     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkReceiverType(parameter));
1582   }
1583
1584   @Nullable
1585   private HighlightInfo checkFeature(@NotNull PsiElement element, @NotNull Feature feature) {
1586     return HighlightUtil.checkFeature(element, feature, myLanguageLevel, myFile);
1587   }
1588 }