917095adc2c99ee598918860198103abc6e4ac97
[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     if (PsiTreeUtil.getParentOfType(keyword, PsiDocTagValue.class) != null) {
760       HighlightInfo result = HighlightInfo.newHighlightInfo(JavaHighlightInfoTypes.JAVA_KEYWORD).range(keyword).create();
761       myHolder.add(result);
762     }
763   }
764
765   @Override
766   public void visitLabeledStatement(PsiLabeledStatement statement) {
767     super.visitLabeledStatement(statement);
768     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelWithoutStatement(statement));
769     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelAlreadyInUse(statement));
770   }
771
772   @Override
773   public void visitLiteralExpression(PsiLiteralExpression expression) {
774     super.visitLiteralExpression(expression);
775     if (myHolder.hasErrorResults()) return;
776     myHolder.add(HighlightUtil.checkLiteralExpressionParsingError(expression, myLanguageLevel,myFile));
777     if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(expression);
778   }
779
780   @Override
781   public void visitMethod(PsiMethod method) {
782     super.visitMethod(method);
783     if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(method.getBody()));
784     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorHandleSuperClassExceptions(method));
785     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkRecursiveConstructorInvocation(method));
786     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSafeVarargsAnnotation(method, myLanguageLevel));
787
788     PsiClass aClass = method.getContainingClass();
789     if (!myHolder.hasErrorResults() && method.isConstructor()) {
790       myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(method, aClass));
791     }
792     if (!myHolder.hasErrorResults() && method.hasModifierProperty(PsiModifier.DEFAULT)) {
793       myHolder.add(checkFeature(method, Feature.EXTENSION_METHODS));
794     }
795     if (!myHolder.hasErrorResults() && aClass != null && aClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) {
796       myHolder.add(checkFeature(method, Feature.EXTENSION_METHODS));
797     }
798     if (!myHolder.hasErrorResults() && aClass != null) {
799       myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass)));
800     }
801
802     // method params are highlighted in visitMethod since we should make sure the method body was visited before
803     PsiParameter[] parameters = method.getParameterList().getParameters();
804     final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
805
806     for (PsiParameter parameter : parameters) {
807       int info = myReassignedParameters.get(parameter);
808       if (info == 0) continue; // out of this file
809       if (info == 2) {// reassigned
810         myHolder.add(HighlightNamesUtil.highlightReassignedVariable(parameter, parameter.getNameIdentifier()));
811       }
812       else {
813         myHolder.add(HighlightNamesUtil.highlightVariableName(parameter, parameter.getNameIdentifier(), colorsScheme));
814       }
815     }
816   }
817
818   private void highlightReferencedMethodOrClassName(PsiJavaCodeReferenceElement element, PsiElement resolved) {
819     PsiElement parent = element.getParent();
820     if (parent instanceof PsiReferenceExpression || parent instanceof PsiJavaCodeReferenceElement) {
821       return;
822     }
823     final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
824     if (parent instanceof PsiMethodCallExpression) {
825       PsiMethod method = ((PsiMethodCallExpression)parent).resolveMethod();
826       PsiElement methodNameElement = element.getReferenceNameElement();
827       if (method != null && methodNameElement != null&& !(methodNameElement instanceof PsiKeyword)) {
828         myHolder.add(HighlightNamesUtil.highlightMethodName(method, methodNameElement, false, colorsScheme));
829         myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(element, colorsScheme));
830       }
831     }
832     else if (parent instanceof PsiConstructorCall) {
833       try {
834         PsiMethod method = ((PsiConstructorCall)parent).resolveConstructor();
835         if (method == null) {
836           if (resolved instanceof PsiClass) {
837             myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, element, colorsScheme));
838           }
839         }
840         else {
841           final PsiElement referenceNameElement = element.getReferenceNameElement();
842           if(referenceNameElement != null) {
843             // exclude type parameters from the highlighted text range
844             TextRange range = new TextRange(element.getTextRange().getStartOffset(), referenceNameElement.getTextRange().getEndOffset());
845             myHolder.add(HighlightNamesUtil.highlightMethodName(method, referenceNameElement, range, colorsScheme, false));
846           }
847         }
848       }
849       catch (IndexNotReadyException ignored) {
850       }
851     }
852     else if (parent instanceof PsiImportStatement && ((PsiImportStatement)parent).isOnDemand()) {
853       // highlight on demand import as class
854       myHolder.add(HighlightNamesUtil.highlightClassName(null, element, colorsScheme));
855     }
856     else if (resolved instanceof PsiClass) {
857       myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, element, colorsScheme));
858     }
859   }
860
861   @Override
862   public void visitMethodCallExpression(PsiMethodCallExpression expression) {
863     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumSuperConstructorCall(expression));
864     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkSuperQualifierType(myFile.getProject(), expression));
865     // in case of JSP synthetic method call, do not check
866     if (myFile.isPhysical() && !myHolder.hasErrorResults()) {
867       try {
868         myHolder.add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper, myLanguageLevel,myJavaSdkVersion));
869       }
870       catch (IndexNotReadyException ignored) {
871       }
872     }
873
874     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallMustBeFirstStatement(expression));
875     if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkSuperAbstractMethodDirectCall(expression));
876
877     if (!myHolder.hasErrorResults()) visitExpression(expression);
878   }
879
880   @Override
881   public void visitModifierList(PsiModifierList list) {
882     super.visitModifierList(list);
883     PsiElement parent = list.getParent();
884     if (parent instanceof PsiMethod) {
885       PsiMethod method = (PsiMethod)parent;
886       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method, myLanguageLevel));
887       MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
888       if (!method.isConstructor()) {
889         try {
890           List<HierarchicalMethodSignature> superMethodSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
891           if (!superMethodSignatures.isEmpty()) {
892             if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleReturnType(methodSignature, superMethodSignatures, true));
893             if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleThrows(methodSignature, superMethodSignatures, true, method.getContainingClass()));
894             if (!method.hasModifierProperty(PsiModifier.STATIC)) {
895               if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodWeakerPrivileges(methodSignature, superMethodSignatures, true, myFile));
896               if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodOverridesFinal(methodSignature, superMethodSignatures));
897             }
898           }
899         }
900         catch (IndexNotReadyException ignored) {
901         }
902       }
903       PsiClass aClass = method.getContainingClass();
904       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodMustHaveBody(method, aClass));
905       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallsBaseClassConstructor(method, myRefCountHolder, myResolveHelper));
906       if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkStaticMethodOverride(method,myFile));
907     }
908     else if (parent instanceof PsiClass) {
909       PsiClass aClass = (PsiClass)parent;
910       try {
911         if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateNestedClass(aClass));
912         if (!myHolder.hasErrorResults()) {
913           TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass);
914           myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(aClass, textRange));
915         }
916         if (!myHolder.hasErrorResults()) {
917           myHolder.add(HighlightClassUtil.checkClassDoesNotCallSuperConstructorOrHandleExceptions(aClass, myRefCountHolder, myResolveHelper));
918         }
919         if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkOverrideEquivalentInheritedMethods(aClass, myFile, myLanguageLevel));
920         if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass));
921         if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCyclicInheritance(aClass));
922       }
923       catch (IndexNotReadyException ignored) {
924       }
925     }
926     else if (parent instanceof PsiEnumConstant) {
927       if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkEnumConstantModifierList(list));
928     }
929   }
930
931   @Override
932   public void visitNameValuePair(PsiNameValuePair pair) {
933     myHolder.add(AnnotationsHighlightUtil.checkNameValuePair(pair));
934     if (!myHolder.hasErrorResults()) {
935       PsiIdentifier nameId = pair.getNameIdentifier();
936       if (nameId != null) {
937         HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ANNOTATION_ATTRIBUTE_NAME).range(nameId).create();
938         myHolder.add(result);
939       }
940     }
941   }
942
943   @Override
944   public void visitNewExpression(PsiNewExpression expression) {
945     final PsiType type = expression.getType();
946     final PsiClass aClass = PsiUtil.resolveClassInType(type);
947     myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, null));
948     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression));
949     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkQualifiedNew(expression, type, aClass));
950     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(expression, type, aClass));
951     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParameterInstantiation(expression));
952     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(aClass, expression));
953     try {
954       if (!myHolder.hasErrorResults()) HighlightMethodUtil.checkNewExpression(expression, type, myHolder, myJavaSdkVersion);
955     }
956     catch (IndexNotReadyException ignored) {
957     }
958     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, aClass));
959     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, type));
960     if (!myHolder.hasErrorResults()) registerConstructorCall(expression);
961
962     if (!myHolder.hasErrorResults()) visitExpression(expression);
963   }
964
965   @Override
966   public void visitPackageStatement(PsiPackageStatement statement) {
967     super.visitPackageStatement(statement);
968     myHolder.add(AnnotationsHighlightUtil.checkPackageAnnotationContainingFile(statement));
969   }
970
971   @Override
972   public void visitParameter(PsiParameter parameter) {
973     super.visitParameter(parameter);
974
975     final PsiElement parent = parameter.getParent();
976     if (parent instanceof PsiParameterList && parameter.isVarArgs()) {
977       if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(parameter, Feature.VARARGS));
978       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkVarArgParameterIsLast(parameter));
979     }
980     else if (parent instanceof PsiCatchSection) {
981       if (!myHolder.hasErrorResults() && parameter.getType() instanceof PsiDisjunctionType) {
982         myHolder.add(checkFeature(parameter, Feature.MULTI_CATCH));
983       }
984       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkCatchParameterIsThrowable(parameter));
985       if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkCatchParameterIsClass(parameter));
986       if (!myHolder.hasErrorResults()) myHolder.addAll(HighlightUtil.checkCatchTypeIsDisjoint(parameter));
987     }
988     else if (parent instanceof PsiForeachStatement) {
989       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkForEachParameterType((PsiForeachStatement)parent, parameter));
990     }
991   }
992
993   @Override
994   public void visitParameterList(PsiParameterList list) {
995     super.visitParameterList(list);
996     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAnnotationMethodParameters(list));
997   }
998
999   @Override
1000   public void visitPostfixExpression(PsiPostfixExpression expression) {
1001     super.visitPostfixExpression(expression);
1002     if (!myHolder.hasErrorResults()) {
1003       myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
1004     }
1005   }
1006
1007   @Override
1008   public void visitPrefixExpression(PsiPrefixExpression expression) {
1009     super.visitPrefixExpression(expression);
1010     if (!myHolder.hasErrorResults()) {
1011       myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
1012     }
1013   }
1014
1015   private void registerConstructorCall(@NotNull PsiConstructorCall constructorCall) {
1016     if (myRefCountHolder != null) {
1017       JavaResolveResult resolveResult = constructorCall.resolveMethodGenerics();
1018       final PsiElement resolved = resolveResult.getElement();
1019       if (resolved instanceof PsiNamedElement) {
1020         myRefCountHolder.registerLocallyReferenced((PsiNamedElement)resolved);
1021       }
1022     }
1023   }
1024
1025   @Override
1026   public void visitReferenceElement(PsiJavaCodeReferenceElement ref) {
1027     JavaResolveResult resolveResult = doVisitReferenceElement(ref);
1028     if (resolveResult != null && !myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkRawOnParameterizedType(ref, resolveResult.getElement()));
1029   }
1030
1031   private JavaResolveResult doVisitReferenceElement(@NotNull PsiJavaCodeReferenceElement ref) {
1032     JavaResolveResult result;
1033     try {
1034       result = resolveOptimised(ref);
1035     }
1036     catch (IndexNotReadyException e) {
1037       return null;
1038     }
1039     PsiElement resolved = result.getElement();
1040     PsiElement parent = ref.getParent();
1041
1042     if (myRefCountHolder != null) {
1043       myRefCountHolder.registerReference(ref, result);
1044     }
1045     myHolder.add(HighlightUtil.checkReference(ref, result, myFile, myLanguageLevel));
1046     if (parent instanceof PsiJavaCodeReferenceElement || ref.isQualified()) {
1047       if (!myHolder.hasErrorResults() && resolved instanceof PsiTypeParameter) {
1048         boolean cannotSelectFromTypeParameter = !myJavaSdkVersion.isAtLeast(JavaSdkVersion.JDK_1_7);
1049         if (!cannotSelectFromTypeParameter) {
1050           final PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
1051           if (containingClass != null) {
1052             if (PsiTreeUtil.isAncestor(containingClass.getExtendsList(), ref, false) ||
1053                 PsiTreeUtil.isAncestor(containingClass.getImplementsList(), ref, false)) {
1054               cannotSelectFromTypeParameter = true;
1055             }
1056           }
1057         }
1058         if (cannotSelectFromTypeParameter) {
1059           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Cannot select from a type parameter").range(ref).create());
1060         }
1061       }
1062     }
1063     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAbstractInstantiation(ref));
1064     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsDuplicate(ref, resolved,myFile));
1065     if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassExtendsForeignInnerClass(ref, resolved));
1066     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSelectStaticClassFromParameterizedType(resolved, ref));
1067     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, ref,
1068                                                                                                                  result.getSubstitutor(),
1069                                                                                                                  myJavaSdkVersion));
1070     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkCannotPassInner(ref));
1071
1072     if (resolved != null && parent instanceof PsiReferenceList) {
1073       if (!myHolder.hasErrorResults()) {
1074         PsiReferenceList referenceList = (PsiReferenceList)parent;
1075         myHolder.add(HighlightUtil.checkElementInReferenceList(ref, referenceList, result, myLanguageLevel));
1076       }
1077     }
1078
1079     if (parent instanceof PsiAnonymousClass && ref.equals(((PsiAnonymousClass)parent).getBaseClassReference())) {
1080       PsiClass aClass = (PsiClass)parent;
1081       myHolder.addAll(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass));
1082     }
1083
1084     if (resolved instanceof PsiVariable) {
1085       PsiVariable variable = (PsiVariable)resolved;
1086
1087       final PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
1088       if (containingClass instanceof PsiAnonymousClass &&
1089           !PsiTreeUtil.isAncestor(containingClass, variable, false) &&
1090           !(variable instanceof PsiField)) {
1091         if (!PsiTreeUtil.isAncestor(((PsiAnonymousClass) containingClass).getArgumentList(), ref, false)) {
1092           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.IMPLICIT_ANONYMOUS_CLASS_PARAMETER).range(ref).create());
1093         }
1094       }
1095
1096       if (variable instanceof PsiParameter && ref instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression)ref)) {
1097         myReassignedParameters.put((PsiParameter)variable, 2);
1098       }
1099
1100       final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
1101       if (!variable.hasModifierProperty(PsiModifier.FINAL) && isReassigned(variable)) {
1102         myHolder.add(HighlightNamesUtil.highlightReassignedVariable(variable, ref));
1103       }
1104       else {
1105         myHolder.add(HighlightNamesUtil.highlightVariableName(variable, ref.getReferenceNameElement(), colorsScheme));
1106       }
1107       myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(ref, colorsScheme));
1108     }
1109     else {
1110       highlightReferencedMethodOrClassName(ref, resolved);
1111     }
1112
1113     if (parent instanceof PsiNewExpression && !(resolved instanceof PsiClass) && resolved instanceof PsiNamedElement && ((PsiNewExpression)parent).getClassOrAnonymousClassReference() == ref) {
1114        myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref)
1115                       .descriptionAndTooltip("Cannot find symbol " + ((PsiNamedElement)resolved).getName()).create());
1116     }
1117     if (!myHolder.hasErrorResults() && resolved instanceof PsiClass) {
1118       final PsiClass aClass = ((PsiClass)resolved).getContainingClass();
1119       if (aClass != null) {
1120         final PsiElement qualifier = ref.getQualifier();
1121         final PsiElement place;
1122         if (qualifier instanceof PsiJavaCodeReferenceElement) {
1123           place = ((PsiJavaCodeReferenceElement)qualifier).resolve();
1124         }
1125         else {
1126           if (parent instanceof PsiNewExpression) {
1127             final PsiExpression newQualifier = ((PsiNewExpression)parent).getQualifier();
1128             place = newQualifier == null ? ref : PsiUtil.resolveClassInType(newQualifier.getType());
1129           }
1130           else {
1131             place = ref;
1132           }
1133         }
1134         if (place != null && PsiTreeUtil.isAncestor(aClass, place, false) && aClass.hasTypeParameters()) {
1135           myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(ref, place, (PsiClass)resolved));
1136         }
1137       }
1138       else if (resolved instanceof PsiTypeParameter) {
1139         final PsiTypeParameterListOwner owner = ((PsiTypeParameter)resolved).getOwner();
1140         if (owner instanceof PsiClass) {
1141           final PsiClass outerClass = (PsiClass)owner;
1142           if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, false, false)) {
1143             myHolder.add(HighlightClassUtil.reportIllegalEnclosingUsage(ref, null, (PsiClass)owner, ref));
1144           }
1145         }
1146       }
1147     }
1148
1149     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkPackageAndClassConflict(ref, myFile));
1150
1151     return result;
1152   }
1153
1154   @NotNull
1155   private JavaResolveResult resolveOptimised(@NotNull PsiJavaCodeReferenceElement ref) {
1156     JavaResolveResult result;
1157     if (ref instanceof PsiReferenceExpressionImpl) {
1158       JavaResolveResult[] results = JavaResolveUtil.resolveWithContainingFile(ref,
1159                                                                               PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE,
1160                                                                               true, true,
1161                                                                               myFile);
1162       result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1163     }
1164     else {
1165       result = ref.advancedResolve(true);
1166     }
1167     return result;
1168   }
1169
1170   @NotNull
1171   private JavaResolveResult[] resolveOptimised(@NotNull PsiReferenceExpression expression) {
1172     JavaResolveResult[] results;
1173     if (expression instanceof PsiReferenceExpressionImpl) {
1174       results = JavaResolveUtil.resolveWithContainingFile(expression,
1175                                                           PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, true,
1176                                                           myFile);
1177     }
1178     else {
1179       results = expression.multiResolve(true);
1180     }
1181     return results;
1182   }
1183
1184   @Override
1185   public void visitReferenceExpression(PsiReferenceExpression expression) {
1186     JavaResolveResult resultForIncompleteCode = doVisitReferenceElement(expression);
1187     if (!myHolder.hasErrorResults()) {
1188       visitExpression(expression);
1189       if (myHolder.hasErrorResults()) return;
1190     }
1191     JavaResolveResult result;
1192     JavaResolveResult[] results;
1193     try {
1194       results = resolveOptimised(expression);
1195       result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1196     }
1197     catch (IndexNotReadyException e) {
1198       return;
1199     }
1200     PsiElement resolved = result.getElement();
1201     if (resolved instanceof PsiVariable && resolved.getContainingFile() == expression.getContainingFile()) {
1202       if (!myHolder.hasErrorResults()) {
1203         try {
1204           myHolder.add(HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, (PsiVariable)resolved, myUninitializedVarProblems,myFile));
1205         }
1206         catch (IndexNotReadyException ignored) {
1207         }
1208       }
1209       PsiVariable variable = (PsiVariable)resolved;
1210       boolean isFinal = variable.hasModifierProperty(PsiModifier.FINAL);
1211       if (isFinal && !variable.hasInitializer()) {
1212         if (!myHolder.hasErrorResults()) {
1213           myHolder.add(HighlightControlFlowUtil.checkFinalVariableMightAlreadyHaveBeenAssignedTo(variable, expression, myFinalVarProblems));
1214         }
1215         if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalVariableInitializedInLoop(expression, resolved));
1216       }
1217     }
1218
1219     PsiElement parent = expression.getParent();
1220     if (parent instanceof PsiMethodCallExpression && ((PsiMethodCallExpression)parent).getMethodExpression() == expression && (!result.isAccessible() || !result.isStaticsScopeCorrect())) {
1221       PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)parent;
1222       PsiExpressionList list = methodCallExpression.getArgumentList();
1223       if (!HighlightMethodUtil.isDummyConstructorCall(methodCallExpression, myResolveHelper, list, expression)) {
1224         try {
1225           myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallIdentifier(expression, results, list, resolved, result, methodCallExpression, myResolveHelper));
1226           
1227           if (!PsiTreeUtil.findChildrenOfType(methodCallExpression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
1228             myHolder.add(HighlightMethodUtil
1229               .checkAmbiguousMethodCallArguments(expression, results, list, resolved, result, methodCallExpression, myResolveHelper, expression.getReferenceNameElement()));
1230           }
1231         }
1232         catch (IndexNotReadyException ignored) {
1233         }
1234       }
1235     }
1236
1237     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkExpressionRequired(expression, resultForIncompleteCode));
1238     if (!myHolder.hasErrorResults() && resolved instanceof PsiField) {
1239       try {
1240         myHolder.add(HighlightUtil.checkIllegalForwardReferenceToField(expression, (PsiField)resolved));
1241       }
1242       catch (IndexNotReadyException ignored) {
1243       }
1244     }
1245     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkAccessStaticFieldFromEnumConstructor(expression, result));
1246     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkClassReferenceAfterQualifier(expression, resolved));
1247     final PsiExpression qualifierExpression = expression.getQualifierExpression();
1248     myHolder.add(HighlightUtil.checkUnqualifiedSuperInDefaultMethod(myLanguageLevel, expression, qualifierExpression));
1249     if (!myHolder.hasErrorResults() && qualifierExpression != null) {
1250       final PsiClass psiClass = PsiUtil.resolveClassInType(qualifierExpression.getType());
1251       if (psiClass != null) {
1252         myHolder.add(GenericsHighlightUtil.areSupersAccessible(psiClass, qualifierExpression));
1253       }
1254     }
1255   }
1256
1257   @Override
1258   public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
1259     myHolder.add(checkFeature(expression, Feature.METHOD_REFERENCES));
1260
1261     final JavaResolveResult result;
1262     final JavaResolveResult[] results;
1263     try {
1264       results = expression.multiResolve(true);
1265       result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1266     }
1267     catch (IndexNotReadyException e) {
1268       return;
1269     }
1270     if (myRefCountHolder != null) {
1271       myRefCountHolder.registerReference(expression, result);
1272     }
1273     final PsiElement method = result.getElement();
1274     if (method != null && !result.isAccessible()) {
1275       final String accessProblem = HighlightUtil.buildProblemWithAccessDescription(expression, result);
1276       HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(accessProblem).create();
1277       myHolder.add(info);
1278     } else {
1279       final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
1280       if (method instanceof PsiMethod) {
1281         final PsiElement methodNameElement = expression.getReferenceNameElement();
1282         myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)method, methodNameElement, false, colorsScheme));
1283       }
1284       myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(expression, colorsScheme));
1285     }
1286     if (!myHolder.hasErrorResults()) {
1287       final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
1288       if (functionalInterfaceType != null) {
1289         final boolean notFunctional = !LambdaUtil.isFunctionalType(functionalInterfaceType);
1290         if (notFunctional) {
1291           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
1292                          .descriptionAndTooltip(functionalInterfaceType.getPresentableText() + " is not a functional interface").create());
1293         }
1294       }
1295       if (!myHolder.hasErrorResults()) {
1296         final PsiElement referenceNameElement = expression.getReferenceNameElement();
1297         if (referenceNameElement instanceof PsiKeyword) {
1298           if (!PsiMethodReferenceUtil.isValidQualifier(expression)) {
1299             final PsiElement qualifier = expression.getQualifier();
1300             String description = "Cannot find class " + qualifier.getText();
1301             HighlightInfo result1 =
1302               HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description).create();
1303             myHolder.add(result1);
1304           }
1305         }
1306       }
1307       if (!myHolder.hasErrorResults()) {
1308         final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
1309         final PsiClass psiClass = resolveResult.getElement();
1310         if (psiClass != null && !PsiUtil.isAccessible(myFile.getProject(), psiClass, expression, null)) {
1311           myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
1312                          .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
1313         }
1314
1315         final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
1316         if (interfaceMethod != null) {
1317           if (!myHolder.hasErrorResults()) {
1318             final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
1319             if (errorMessage != null) {
1320               myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create());
1321             }
1322           }
1323
1324           if (!myHolder.hasErrorResults()) {
1325             final String badReturnTypeMessage = PsiMethodReferenceUtil.checkReturnType(expression, result, functionalInterfaceType);
1326             if (badReturnTypeMessage != null) {
1327               myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(badReturnTypeMessage).create());
1328             }
1329           }
1330         }
1331       }
1332     }
1333
1334     if (!myHolder.hasErrorResults()) {
1335       PsiElement qualifier = expression.getQualifier();
1336       if (qualifier instanceof PsiTypeElement) {
1337         final PsiType psiType = ((PsiTypeElement)qualifier).getType();
1338         final HighlightInfo genericArrayCreationInfo = GenericsHighlightUtil.checkGenericArrayCreation(qualifier, psiType);
1339         if (genericArrayCreationInfo != null) {
1340           myHolder.add(genericArrayCreationInfo);
1341         } else {
1342           final String wildcardMessage = PsiMethodReferenceUtil.checkTypeArguments((PsiTypeElement)qualifier, psiType);
1343           if (wildcardMessage != null) {
1344             myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(wildcardMessage).create());
1345           }
1346         }
1347       }
1348     }
1349
1350     if (!myHolder.hasErrorResults()) {
1351       myHolder.add(PsiMethodReferenceHighlightingUtil.checkRawConstructorReference(expression));
1352     }
1353
1354     if (!myHolder.hasErrorResults()) {
1355       myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
1356     }
1357
1358     if (!myHolder.hasErrorResults() && method instanceof PsiTypeParameterListOwner) {
1359       PsiTypeParameter[] typeParameters = ((PsiTypeParameterListOwner)method).getTypeParameters();
1360       if (method instanceof PsiMethod) {
1361         final PsiClass containingClass = ((PsiMethod)method).getContainingClass();
1362         assert containingClass != null : method;
1363         typeParameters = ArrayUtil.mergeArrays(typeParameters, containingClass.getTypeParameters());
1364       }
1365       myHolder.add(GenericsHighlightUtil.checkInferredTypeArguments(typeParameters, expression, result.getSubstitutor()));
1366     }
1367
1368     if (!myHolder.hasErrorResults()) {
1369       if (results.length == 0) {
1370         String description = null;
1371         if (expression.isConstructor()) {
1372           final PsiClass containingClass = PsiMethodReferenceUtil.getQualifierResolveResult(expression).getContainingClass();
1373
1374           if (containingClass != null) {
1375             if (!myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, expression)) &&
1376                 !myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, containingClass)) &&
1377                 containingClass.isPhysical()) {
1378               description = JavaErrorMessages.message("cannot.resolve.constructor", containingClass.getName());
1379             }
1380           }
1381         }
1382         else {
1383           description = JavaErrorMessages.message("cannot.resolve.method", expression.getReferenceName());
1384         }
1385
1386         if (description != null) {
1387           final PsiElement referenceNameElement = expression.getReferenceNameElement();
1388           final HighlightInfo highlightInfo =
1389             HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).descriptionAndTooltip(description).range(referenceNameElement).create();
1390           myHolder.add(highlightInfo);
1391           final TextRange fixRange = HighlightMethodUtil.getFixRange(referenceNameElement);
1392           QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QuickFixFactory.getInstance().createCreateMethodFromUsageFix(expression));
1393         }
1394       }
1395     }
1396   }
1397
1398   @Override
1399   public void visitReferenceList(PsiReferenceList list) {
1400     if (list.getFirstChild() == null) return;
1401     PsiElement parent = list.getParent();
1402     if (!(parent instanceof PsiTypeParameter)) {
1403       myHolder.add(AnnotationsHighlightUtil.checkAnnotationDeclaration(parent, list));
1404       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsAllowed(list));
1405       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkImplementsAllowed(list));
1406       if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassExtendsOnlyOneClass(list));
1407       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericCannotExtendException(list));
1408     }
1409   }
1410
1411   @Override
1412   public void visitReferenceParameterList(PsiReferenceParameterList list) {
1413     if (list.getTextLength() == 0) return;
1414
1415     myHolder.add(checkFeature(list, Feature.GENERICS));
1416     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersAllowed(list));
1417     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersOnRaw(list));
1418     if (!myHolder.hasErrorResults()) {
1419       for (PsiTypeElement typeElement : list.getTypeParameterElements()) {
1420         if (typeElement.getType() instanceof PsiDiamondType) {
1421           myHolder.add(checkFeature(list, Feature.DIAMOND_TYPES));
1422         }
1423       }
1424     }
1425   }
1426
1427   @Override
1428   public void visitReturnStatement(PsiReturnStatement statement) {
1429     try {
1430       myHolder.add(HighlightUtil.checkReturnStatementType(statement));
1431     }
1432     catch (IndexNotReadyException ignore) {
1433     }
1434   }
1435
1436   @Override
1437   public void visitStatement(PsiStatement statement) {
1438     super.visitStatement(statement);
1439     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkNotAStatement(statement));
1440     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkStatementPrependedWithCaseInsideSwitch(statement));
1441   }
1442
1443   @Override
1444   public void visitSuperExpression(PsiSuperExpression expr) {
1445     myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
1446     if (!myHolder.hasErrorResults()) visitExpression(expr);
1447   }
1448
1449   @Override
1450   public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) {
1451     super.visitSwitchLabelStatement(statement);
1452     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkCaseStatement(statement));
1453   }
1454
1455   @Override
1456   public void visitSwitchStatement(PsiSwitchStatement statement) {
1457     super.visitSwitchStatement(statement);
1458     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSwitchSelectorType(statement, myLanguageLevel));
1459   }
1460
1461   @Override
1462   public void visitThisExpression(PsiThisExpression expr) {
1463     if (!(expr.getParent() instanceof PsiReceiverParameter)) {
1464       myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
1465       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null, myFile));
1466       if (!myHolder.hasErrorResults()) visitExpression(expr);
1467     }
1468   }
1469
1470   @Override
1471   public void visitThrowStatement(PsiThrowStatement statement) {
1472     myHolder.add(HighlightUtil.checkUnhandledExceptions(statement, null));
1473     if (!myHolder.hasErrorResults()) visitStatement(statement);
1474   }
1475
1476   @Override
1477   public void visitTryStatement(PsiTryStatement statement) {
1478     super.visitTryStatement(statement);
1479     if (!myHolder.hasErrorResults()) {
1480       final Set<PsiClassType> thrownTypes = HighlightUtil.collectUnhandledExceptions(statement);
1481       for (PsiParameter parameter : statement.getCatchBlockParameters()) {
1482         boolean added = myHolder.addAll(HighlightUtil.checkExceptionAlreadyCaught(parameter));
1483         if (!added) {
1484           added = myHolder.addAll(HighlightUtil.checkExceptionThrownInTry(parameter, thrownTypes));
1485         }
1486         if (!added) {
1487           myHolder.addAll(HighlightUtil.checkWithImprovedCatchAnalysis(parameter, thrownTypes, myFile));
1488         }
1489       }
1490     }
1491   }
1492
1493   @Override
1494   public void visitResourceVariable(final PsiResourceVariable resourceVariable) {
1495     visitVariable(resourceVariable);
1496     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resourceVariable));
1497     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resourceVariable));
1498   }
1499
1500   @Override
1501   public void visitResourceList(PsiResourceList resourceList) {
1502     super.visitResourceList(resourceList);
1503     if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(resourceList, Feature.TRY_WITH_RESOURCES));
1504   }
1505
1506   @Override
1507   public void visitTypeElement(final PsiTypeElement type) {
1508     if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalType(type));
1509     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type, myLanguageLevel));
1510     if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkWildcardUsage(type));
1511   }
1512
1513   @Override
1514   public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
1515     super.visitTypeCastExpression(typeCast);
1516     try {
1517       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIntersectionInTypeCast(typeCast, myLanguageLevel));
1518       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
1519     }
1520     catch (IndexNotReadyException ignore) {
1521     }
1522   }
1523
1524   @Override
1525   public void visitTypeParameterList(PsiTypeParameterList list) {
1526     PsiTypeParameter[] typeParameters = list.getTypeParameters();
1527     if (typeParameters.length > 0) {
1528       myHolder.add(checkFeature(list, Feature.GENERICS));
1529       if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParametersList(list, typeParameters, myLanguageLevel));
1530     }
1531   }
1532
1533   @Override
1534   public void visitVariable(PsiVariable variable) {
1535     super.visitVariable(variable);
1536     try {
1537       if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableInitializerType(variable));
1538     }
1539     catch (IndexNotReadyException ignored) {
1540     }
1541   }
1542
1543   private boolean isReassigned(@NotNull PsiVariable variable) {
1544     try {
1545       boolean reassigned;
1546       if (variable instanceof PsiParameter) {
1547         reassigned = myReassignedParameters.get((PsiParameter)variable) == 2;
1548       }
1549       else  {
1550         reassigned = HighlightControlFlowUtil.isReassigned(variable, myFinalVarProblems);
1551       }
1552
1553       return reassigned;
1554     }
1555     catch (IndexNotReadyException e) {
1556       return false;
1557     }
1558   }
1559
1560   @Override
1561   public void visitConditionalExpression(PsiConditionalExpression expression) {
1562     super.visitConditionalExpression(expression);
1563     if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) && PsiPolyExpressionUtil.isPolyExpression(expression)) {
1564       final PsiExpression thenExpression = expression.getThenExpression();
1565       final PsiExpression elseExpression = expression.getElseExpression();
1566       if (thenExpression != null && elseExpression != null) {
1567         final PsiType conditionalType = expression.getType();
1568         if (conditionalType != null) {
1569           final PsiExpression[] sides = {thenExpression, elseExpression};
1570           for (PsiExpression side : sides) {
1571             final PsiType sideType = side.getType();
1572             if (sideType != null && !TypeConversionUtil.isAssignable(conditionalType, sideType)) {
1573               myHolder.add(HighlightUtil.checkAssignability(conditionalType, sideType, side, side));
1574             }
1575           }
1576         }
1577       }
1578     }
1579   }
1580
1581   @Override
1582   public void visitReceiverParameter(PsiReceiverParameter parameter) {
1583     super.visitReceiverParameter(parameter);
1584     if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(parameter, Feature.RECEIVERS));
1585     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkReceiverPlacement(parameter));
1586     if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkReceiverType(parameter));
1587   }
1588
1589   @Nullable
1590   private HighlightInfo checkFeature(@NotNull PsiElement element, @NotNull Feature feature) {
1591     return HighlightUtil.checkFeature(element, feature, myLanguageLevel, myFile);
1592   }
1593 }