2 * Copyright 2000-2016 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.codeInsight.daemon.impl.analysis;
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.PsiPolyExpressionUtil;
42 import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl;
43 import com.intellij.psi.infos.CandidateInfo;
44 import com.intellij.psi.infos.MethodCandidateInfo;
45 import com.intellij.psi.javadoc.PsiDocComment;
46 import com.intellij.psi.javadoc.PsiDocTagValue;
47 import com.intellij.psi.util.*;
48 import com.intellij.util.ObjectUtils;
49 import com.intellij.util.containers.MostlySingularMultiMap;
50 import gnu.trove.THashMap;
51 import gnu.trove.THashSet;
52 import gnu.trove.TObjectIntHashMap;
53 import org.jetbrains.annotations.NotNull;
54 import org.jetbrains.annotations.Nullable;
56 import java.util.Collection;
57 import java.util.List;
61 public class HighlightVisitorImpl extends JavaElementVisitor implements HighlightVisitor {
63 private final PsiResolveHelper myResolveHelper;
65 private HighlightInfoHolder myHolder;
67 private RefCountHolder myRefCountHolder;
69 // map codeBlock->List of PsiReferenceExpression of uninitialized final variables
70 private final Map<PsiElement, Collection<PsiReferenceExpression>> myUninitializedVarProblems = new THashMap<>();
71 // map codeBlock->List of PsiReferenceExpression of extra initialization of final variable
72 private final Map<PsiElement, Collection<ControlFlowUtil.VariableInfo>> myFinalVarProblems = new THashMap<>();
74 // value==1: no info if the parameter was reassigned (but the parameter is present in current file), value==2: parameter was reassigned
75 private final TObjectIntHashMap<PsiParameter> myReassignedParameters = new TObjectIntHashMap<>();
77 private final Map<String, Pair<PsiImportStaticReferenceElement, PsiClass>> mySingleImportedClasses = new THashMap<>();
78 private final Map<String, Pair<PsiImportStaticReferenceElement, PsiField>> mySingleImportedFields = new THashMap<>();
79 private PsiFile myFile;
80 private final PsiElementVisitor REGISTER_REFERENCES_VISITOR = new PsiRecursiveElementWalkingVisitor() {
81 @Override public void visitElement(PsiElement element) {
82 super.visitElement(element);
83 for (PsiReference reference : element.getReferences()) {
84 PsiElement resolved = reference.resolve();
85 if (resolved instanceof PsiNamedElement) {
86 myRefCountHolder.registerLocallyReferenced((PsiNamedElement)resolved);
87 if (resolved instanceof PsiMember) {
88 myRefCountHolder.registerReference(reference, new CandidateInfo(resolved, PsiSubstitutor.EMPTY));
94 private final Map<PsiClass, MostlySingularMultiMap<MethodSignature, PsiMethod>> myDuplicateMethods = new THashMap<>();
95 private final Set<PsiClass> myOverrideEquivalentMethodsVisitedClasses = new THashSet<>();
96 private LanguageLevel myLanguageLevel;
97 private JavaSdkVersion myJavaSdkVersion;
99 private static class Holder {
100 private static final boolean CHECK_ELEMENT_LEVEL = ApplicationManager.getApplication().isUnitTestMode() || ApplicationManager.getApplication().isInternal();
103 protected HighlightVisitorImpl(@NotNull PsiResolveHelper resolveHelper) {
104 myResolveHelper = resolveHelper;
108 private MostlySingularMultiMap<MethodSignature, PsiMethod> getDuplicateMethods(@NotNull PsiClass aClass) {
109 MostlySingularMultiMap<MethodSignature, PsiMethod> signatures = myDuplicateMethods.get(aClass);
110 if (signatures == null) {
111 signatures = new MostlySingularMultiMap<>();
112 for (PsiMethod method : aClass.getMethods()) {
113 if (method instanceof ExternallyDefinedPsiElement) continue; // ignore aspectj-weaved methods; they are checked elsewhere
114 MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY);
115 signatures.add(signature, method);
118 myDuplicateMethods.put(aClass, signatures);
125 public HighlightVisitorImpl clone() {
126 return new HighlightVisitorImpl(myResolveHelper);
135 public boolean suitableForFile(@NotNull PsiFile file) {
136 // both PsiJavaFile and PsiCodeFragment must match
137 return file instanceof PsiImportHolder && !InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file);
141 public void visit(@NotNull PsiElement element) {
142 if (Holder.CHECK_ELEMENT_LEVEL) {
143 ((CheckLevelHighlightInfoHolder)myHolder).enterLevel(element);
144 element.accept(this);
145 ((CheckLevelHighlightInfoHolder)myHolder).enterLevel(null);
148 element.accept(this);
152 private void registerReferencesFromInjectedFragments(@NotNull PsiElement element) {
153 InjectedLanguageManager.getInstance(myFile.getProject()).enumerateEx(element, myFile, false,
154 (injectedPsi, places) -> injectedPsi.accept(REGISTER_REFERENCES_VISITOR)
159 public boolean analyze(@NotNull final PsiFile file,
160 final boolean updateWholeFile,
161 @NotNull final HighlightInfoHolder holder,
162 @NotNull final Runnable highlight) {
164 myHolder = Holder.CHECK_ELEMENT_LEVEL ? new CheckLevelHighlightInfoHolder(file, holder) : holder;
165 boolean success = true;
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, () -> {
181 progress.checkCanceled();
182 PostHighlightingVisitor highlightingVisitor = new PostHighlightingVisitor(file, document, refCountHolder);
183 highlightingVisitor.collectHighlights(holder, progress);
187 myRefCountHolder = null;
192 myUninitializedVarProblems.clear();
193 myFinalVarProblems.clear();
194 mySingleImportedClasses.clear();
195 mySingleImportedFields.clear();
196 myReassignedParameters.clear();
198 myRefCountHolder = null;
201 myDuplicateMethods.clear();
202 myOverrideEquivalentMethodsVisitedClasses.clear();
209 public void visitElement(PsiElement element) {
210 if (myRefCountHolder != null && myFile instanceof ServerPageFile) {
211 // in JSP, XmlAttributeValue may contain java references
213 for (PsiReference reference : element.getReferences()) {
214 if (reference instanceof PsiJavaReference) {
215 PsiJavaReference psiJavaReference = (PsiJavaReference)reference;
216 myRefCountHolder.registerReference(psiJavaReference, psiJavaReference.advancedResolve(false));
220 catch (IndexNotReadyException ignored) { }
223 if (!(myFile instanceof ServerPageFile)) {
224 myHolder.add(DefaultHighlightUtil.checkBadCharacter(element));
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));
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();
256 else if (PsiUtil.isAnnotationMethod(parent)) {
257 method = (PsiMethod)parent;
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));
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));
279 myHolder.add(AnnotationsHighlightUtil.checkValidAnnotationType(method.getReturnType(), method.getReturnTypeElement()));
280 final PsiClass aClass = method.getContainingClass();
281 myHolder.add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), aClass));
282 myHolder.add(AnnotationsHighlightUtil.checkClashesWithSuperMethods(method));
284 if (!myHolder.hasErrorResults() && aClass != null) {
285 myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass)));
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()));
299 public void visitAssignmentExpression(PsiAssignmentExpression assignment) {
300 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentCompatibleTypes(assignment));
301 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssignmentOperatorApplicable(assignment));
302 if (!myHolder.hasErrorResults()) visitExpression(assignment);
306 public void visitPolyadicExpression(PsiPolyadicExpression expression) {
307 super.visitPolyadicExpression(expression);
308 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkPolyadicOperatorApplicable(expression));
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)
323 myHolder.add(result);
326 final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
327 final PsiCallExpression callExpression = parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression ?
328 (PsiCallExpression)parent.getParent() : null;
329 final JavaResolveResult containingCallResolveResult = callExpression != null ? callExpression.resolveMethodGenerics() : null;
330 final String errorMessage;
331 if (containingCallResolveResult instanceof MethodCandidateInfo) {
332 errorMessage = ((MethodCandidateInfo)containingCallResolveResult).getParentInferenceErrorMessage((PsiExpressionList)parent);
337 if (errorMessage != null) {
338 HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
339 .range(expression).descriptionAndTooltip(errorMessage).create();
340 myHolder.add(result);
343 final Map<PsiElement, String> returnErrors = LambdaUtil
344 .checkReturnTypeCompatible(expression, LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType));
345 if (returnErrors != null) {
346 for (Map.Entry<PsiElement, String> entry : returnErrors.entrySet()) {
347 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
348 .range(entry.getKey())
349 .descriptionAndTooltip(entry.getValue()).create());
353 final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
354 final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
355 if (interfaceMethod != null) {
356 final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters();
357 HighlightInfo result = LambdaHighlightingUtil
358 .checkParametersCompatible(expression, parameters, LambdaUtil.getSubstitutor(interfaceMethod, resolveResult));
359 if (result != null) {
360 myHolder.add(result);
363 checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType);
370 else if (LambdaUtil.getFunctionalInterfaceType(expression, true) != null) {
371 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip("Cannot infer functional interface type").create());
375 HighlightInfo result = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
376 .descriptionAndTooltip("Lambda expression not expected here").create();
377 myHolder.add(result);
379 if (!myHolder.hasErrorResults()) {
380 final PsiElement body = expression.getBody();
381 if (body instanceof PsiCodeBlock) {
382 myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement((PsiCodeBlock)body));
389 public void visitBreakStatement(PsiBreakStatement statement) {
390 super.visitBreakStatement(statement);
391 if (!myHolder.hasErrorResults()) {
392 myHolder.add(HighlightUtil.checkLabelDefined(statement.getLabelIdentifier(), statement.findExitedStatement()));
394 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkBreakOutsideLoop(statement));
398 public void visitClass(PsiClass aClass) {
399 super.visitClass(aClass);
400 if (aClass instanceof PsiSyntheticClass) return;
401 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInterfaceMultipleInheritance(aClass));
402 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.areSupersAccessible(aClass));
403 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateTopLevelClass(aClass));
404 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumMustNotBeLocal(aClass));
405 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumWithoutConstantsCantHaveAbstractMethods(aClass));
406 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass, myJavaSdkVersion));
407 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassAndPackageConflict(aClass));
408 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkPublicClassInRightFile(aClass));
409 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParameterOverrideEquivalentMethods(aClass, myLanguageLevel));
413 public void visitClassInitializer(PsiClassInitializer initializer) {
414 super.visitClassInitializer(initializer);
415 if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkInitializerCompleteNormally(initializer));
416 if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(initializer.getBody()));
417 if (!myHolder.hasErrorResults()) {
418 myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(initializer, initializer.getContainingClass()));
423 public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
424 super.visitClassObjectAccessExpression(expression);
425 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkClassObjectAccessExpression(expression));
429 public void visitComment(PsiComment comment) {
430 super.visitComment(comment);
431 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnclosedComment(comment));
432 if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(comment);
436 public void visitContinueStatement(PsiContinueStatement statement) {
437 super.visitContinueStatement(statement);
438 if (!myHolder.hasErrorResults()) {
439 myHolder.add(HighlightUtil.checkLabelDefined(statement.getLabelIdentifier(), statement.findContinuedStatement()));
441 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkContinueOutsideLoop(statement));
445 public void visitJavaToken(PsiJavaToken token) {
446 super.visitJavaToken(token);
447 if (!myHolder.hasErrorResults()
448 && token.getTokenType() == JavaTokenType.RBRACE
449 && token.getParent() instanceof PsiCodeBlock) {
451 final PsiElement gParent = token.getParent().getParent();
452 final PsiCodeBlock codeBlock;
453 final PsiType returnType;
454 if (gParent instanceof PsiMethod) {
455 PsiMethod method = (PsiMethod)gParent;
456 codeBlock = method.getBody();
457 returnType = method.getReturnType();
459 else if (gParent instanceof PsiLambdaExpression) {
460 final PsiElement body = ((PsiLambdaExpression)gParent).getBody();
461 if (!(body instanceof PsiCodeBlock)) return;
462 codeBlock = (PsiCodeBlock)body;
463 returnType = LambdaUtil.getFunctionalInterfaceReturnType((PsiLambdaExpression)gParent);
468 myHolder.add(HighlightControlFlowUtil.checkMissingReturnStatement(codeBlock, returnType));
473 public void visitDocComment(PsiDocComment comment) {
474 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnclosedComment(comment));
478 public void visitDocTagValue(PsiDocTagValue value) {
479 PsiReference reference = value.getReference();
480 if (reference != null) {
481 PsiElement element = reference.resolve();
482 final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
483 if (element instanceof PsiMethod) {
484 myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)element, ((PsiDocMethodOrFieldRef)value).getNameElement(), false,
487 else if (element instanceof PsiParameter) {
488 myHolder.add(HighlightNamesUtil.highlightVariableName((PsiVariable)element, value.getNavigationElement(), colorsScheme));
494 public void visitEnumConstant(PsiEnumConstant enumConstant) {
495 super.visitEnumConstant(enumConstant);
496 if (!myHolder.hasErrorResults()) GenericsHighlightUtil.checkEnumConstantForConstructorProblems(enumConstant, myHolder, myJavaSdkVersion);
497 if (!myHolder.hasErrorResults()) registerConstructorCall(enumConstant);
498 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledExceptions(enumConstant, null));
502 public void visitEnumConstantInitializer(PsiEnumConstantInitializer enumConstantInitializer) {
503 super.visitEnumConstantInitializer(enumConstantInitializer);
504 if (!myHolder.hasErrorResults()) {
505 TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(enumConstantInitializer);
506 myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(enumConstantInitializer, textRange));
511 public void visitExpression(PsiExpression expression) {
512 ProgressManager.checkCanceled(); // visitLiteralExpression is invoked very often in array initializers
514 super.visitExpression(expression);
515 PsiType type = expression.getType();
516 if (myHolder.add(HighlightUtil.checkMustBeBoolean(expression, type))) return;
518 if (expression instanceof PsiArrayAccessExpression) {
519 myHolder.add(HighlightUtil.checkValidArrayAccessExpression((PsiArrayAccessExpression)expression));
522 PsiElement parent = expression.getParent();
523 if (parent instanceof PsiNewExpression
524 && ((PsiNewExpression)parent).getQualifier() != expression
525 && ((PsiNewExpression)parent).getArrayInitializer() != expression) {
526 // like in 'new String["s"]'
527 myHolder.add(HighlightUtil.checkAssignability(PsiType.INT, expression.getType(), expression, expression));
529 if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkCannotWriteToFinal(expression,myFile));
530 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableExpected(expression));
531 if (!myHolder.hasErrorResults()) myHolder.addAll(HighlightUtil.checkArrayInitializer(expression, type));
532 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTernaryOperatorConditionIsBoolean(expression, type));
533 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAssertOperatorTypes(expression, type));
534 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSynchronizedExpressionType(expression, type, myFile));
535 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkConditionalExpressionBranchTypesMatch(expression, type));
536 if (!myHolder.hasErrorResults()
537 && parent instanceof PsiThrowStatement
538 && ((PsiThrowStatement)parent).getException() == expression) {
539 myHolder.add(HighlightUtil.checkMustBeThrowable(type, expression, true));
542 if (!myHolder.hasErrorResults()) {
543 myHolder.add(AnnotationsHighlightUtil.checkConstantExpression(expression));
545 if (!myHolder.hasErrorResults() && parent instanceof PsiForeachStatement && ((PsiForeachStatement)parent).getIteratedValue() == expression) {
546 myHolder.add(GenericsHighlightUtil.checkForeachExpressionTypeIsIterable(expression));
551 public void visitExpressionList(PsiExpressionList list) {
552 super.visitExpressionList(list);
553 PsiElement parent = list.getParent();
554 if (parent instanceof PsiMethodCallExpression) {
555 PsiMethodCallExpression expression = (PsiMethodCallExpression)parent;
556 if (expression.getArgumentList() == list) {
557 PsiReferenceExpression referenceExpression = expression.getMethodExpression();
558 JavaResolveResult result;
559 JavaResolveResult[] results;
561 results = resolveOptimised(referenceExpression);
562 result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
564 catch (IndexNotReadyException e) {
567 PsiElement resolved = result.getElement();
569 if ((!result.isAccessible() || !result.isStaticsScopeCorrect()) &&
570 !HighlightMethodUtil.isDummyConstructorCall(expression, myResolveHelper, list, referenceExpression) &&
571 // this check is for fake expression from JspMethodCallImpl
572 referenceExpression.getParent() == expression) {
574 if (PsiTreeUtil.findChildrenOfType(expression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
575 myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallArguments(referenceExpression, results, list, resolved, result, expression, myResolveHelper, list));
578 catch (IndexNotReadyException ignored) { }
585 public void visitField(PsiField field) {
586 super.visitField(field);
587 if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalFieldInitialized(field));
591 public void visitForStatement(PsiForStatement statement) {
592 myHolder.add(HighlightUtil.checkForStatement(statement));
596 public void visitForeachStatement(PsiForeachStatement statement) {
597 myHolder.add(checkFeature(statement, Feature.FOR_EACH));
601 public void visitImportStaticStatement(PsiImportStaticStatement statement) {
602 myHolder.add(checkFeature(statement, Feature.STATIC_IMPORTS));
606 public void visitIdentifier(final PsiIdentifier identifier) {
607 TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
609 PsiElement parent = identifier.getParent();
610 if (parent instanceof PsiVariable) {
611 PsiVariable variable = (PsiVariable)parent;
612 myHolder.add(HighlightUtil.checkVariableAlreadyDefined(variable));
614 if (variable.getInitializer() == null) {
615 final PsiElement child = variable.getLastChild();
616 if (child instanceof PsiErrorElement && child.getPrevSibling() == identifier) return;
619 boolean isMethodParameter = variable instanceof PsiParameter && ((PsiParameter)variable).getDeclarationScope() instanceof PsiMethod;
620 if (isMethodParameter) {
621 myReassignedParameters.put((PsiParameter)variable, 1); // mark param as present in current file
624 // method params are highlighted in visitMethod since we should make sure the method body was visited before
625 if (HighlightControlFlowUtil.isReassigned(variable, myFinalVarProblems)) {
626 myHolder.add(HighlightNamesUtil.highlightReassignedVariable(variable, identifier));
629 myHolder.add(HighlightNamesUtil.highlightVariableName(variable, identifier, colorsScheme));
633 else if (parent instanceof PsiClass) {
634 PsiClass aClass = (PsiClass)parent;
635 if (aClass.isAnnotationType()) {
636 myHolder.add(checkFeature(identifier, Feature.ANNOTATIONS));
639 myHolder.add(HighlightClassUtil.checkClassAlreadyImported(aClass, identifier));
640 if (!(parent instanceof PsiAnonymousClass) && aClass.getNameIdentifier() == identifier) {
641 myHolder.add(HighlightNamesUtil.highlightClassName(aClass, identifier, colorsScheme));
643 if (!myHolder.hasErrorResults() && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
644 myHolder.add(GenericsHighlightUtil.checkUnrelatedDefaultMethods(aClass, identifier));
647 if (!myHolder.hasErrorResults()) {
648 myHolder.add(GenericsHighlightUtil.checkUnrelatedConcrete(aClass, identifier));
651 else if (parent instanceof PsiMethod) {
652 PsiMethod method = (PsiMethod)parent;
653 if (method.isConstructor()) {
654 myHolder.add(HighlightMethodUtil.checkConstructorName(method));
656 myHolder.add(HighlightNamesUtil.highlightMethodName(method, identifier, true, colorsScheme));
657 final PsiClass aClass = method.getContainingClass();
658 if (aClass != null) {
659 myHolder.add(GenericsHighlightUtil.checkDefaultMethodOverrideEquivalentToObjectNonPrivate(myLanguageLevel, aClass, method, identifier));
663 myHolder.add(HighlightUtil.checkUnderscore(identifier, myLanguageLevel));
665 super.visitIdentifier(identifier);
669 public void visitImportStatement(final PsiImportStatement statement) {
670 if (!myHolder.hasErrorResults()) {
671 myHolder.add(HighlightUtil.checkSingleImportClassConflict(statement, mySingleImportedClasses,myFile));
676 public void visitImportStaticReferenceElement(@NotNull PsiImportStaticReferenceElement ref) {
677 final String refName = ref.getReferenceName();
678 final JavaResolveResult[] results = ref.multiResolve(false);
680 final PsiElement referenceNameElement = ref.getReferenceNameElement();
681 if (results.length == 0) {
682 final String description = JavaErrorMessages.message("cannot.resolve.symbol", refName);
683 assert referenceNameElement != null : ref;
684 final HighlightInfo info =
685 HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(referenceNameElement).descriptionAndTooltip(description).create();
686 QuickFixAction.registerQuickFixAction(info, QuickFixFactory.getInstance().createSetupJDKFix());
690 final PsiManager manager = ref.getManager();
691 for (JavaResolveResult result : results) {
692 final PsiElement element = result.getElement();
694 String description = null;
695 if (element instanceof PsiClass) {
696 final Pair<PsiImportStaticReferenceElement, PsiClass> imported = mySingleImportedClasses.get(refName);
697 final PsiClass aClass = imported == null ? null : imported.getSecond();
698 if (aClass != null && !manager.areElementsEquivalent(aClass, element)) {
699 description = imported.first == null
700 ? JavaErrorMessages.message("single.import.class.conflict", refName)
701 : imported.first.equals(ref)
702 ? JavaErrorMessages.message("class.is.ambiguous.in.single.static.import", refName)
703 : JavaErrorMessages.message("class.is.already.defined.in.single.static.import", refName);
705 mySingleImportedClasses.put(refName, Pair.create(ref, (PsiClass)element));
707 else if (element instanceof PsiField) {
708 final Pair<PsiImportStaticReferenceElement, PsiField> imported = mySingleImportedFields.get(refName);
709 final PsiField field = imported == null ? null : imported.getSecond();
710 if (field != null && !manager.areElementsEquivalent(field, element)) {
711 description = imported.first.equals(ref)
712 ? JavaErrorMessages.message("field.is.ambiguous.in.single.static.import", refName)
713 : JavaErrorMessages.message("field.is.already.defined.in.single.static.import", refName);
715 mySingleImportedFields.put(refName, Pair.create(ref, (PsiField)element));
718 if (description != null) {
719 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(description).create());
723 if (!myHolder.hasErrorResults()) {
724 final PsiElement resolved = results.length == 1 ? results[0].getElement() : null;
725 final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
726 if (resolved instanceof PsiClass) {
727 myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, ref, colorsScheme));
730 myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(ref, colorsScheme));
731 if (resolved instanceof PsiVariable) {
732 myHolder.add(HighlightNamesUtil.highlightVariableName((PsiVariable)resolved, referenceNameElement, colorsScheme));
734 else if (resolved instanceof PsiMethod) {
735 myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)resolved, referenceNameElement, false, colorsScheme));
742 public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
743 super.visitInstanceOfExpression(expression);
744 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInstanceOfApplicable(expression));
745 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInstanceOfGenericType(expression));
749 public void visitKeyword(PsiKeyword keyword) {
750 super.visitKeyword(keyword);
751 PsiElement parent = keyword.getParent();
752 String text = keyword.getText();
753 if (parent instanceof PsiModifierList) {
754 PsiModifierList psiModifierList = (PsiModifierList)parent;
755 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkNotAllowedModifier(keyword, psiModifierList));
756 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalModifierCombination(keyword, psiModifierList));
757 if (PsiModifier.ABSTRACT.equals(text) && psiModifierList.getParent() instanceof PsiMethod) {
758 if (!myHolder.hasErrorResults()) {
759 myHolder.add(HighlightMethodUtil.checkAbstractMethodInConcreteClass((PsiMethod)psiModifierList.getParent(), keyword));
763 else if (PsiKeyword.INTERFACE.equals(text) && parent instanceof PsiClass) {
764 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkInterfaceCannotBeLocal((PsiClass)parent));
766 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkStaticDeclarationInInnerClass(keyword));
767 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalVoidType(keyword));
771 public void visitLabeledStatement(PsiLabeledStatement statement) {
772 super.visitLabeledStatement(statement);
773 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelWithoutStatement(statement));
774 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkLabelAlreadyInUse(statement));
778 public void visitLiteralExpression(PsiLiteralExpression expression) {
779 super.visitLiteralExpression(expression);
780 if (myHolder.hasErrorResults()) return;
781 myHolder.add(HighlightUtil.checkLiteralExpressionParsingError(expression, myLanguageLevel,myFile));
782 if (myRefCountHolder != null && !myHolder.hasErrorResults()) registerReferencesFromInjectedFragments(expression);
786 public void visitMethod(PsiMethod method) {
787 super.visitMethod(method);
788 if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkUnreachableStatement(method.getBody()));
789 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorHandleSuperClassExceptions(method));
790 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkRecursiveConstructorInvocation(method));
791 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkSafeVarargsAnnotation(method, myLanguageLevel));
793 PsiClass aClass = method.getContainingClass();
794 if (!myHolder.hasErrorResults() && method.isConstructor()) {
795 myHolder.add(HighlightClassUtil.checkThingNotAllowedInInterface(method, aClass));
797 if (!myHolder.hasErrorResults() && method.hasModifierProperty(PsiModifier.DEFAULT)) {
798 myHolder.add(checkFeature(method, Feature.EXTENSION_METHODS));
800 if (!myHolder.hasErrorResults() && aClass != null && aClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) {
801 myHolder.add(checkFeature(method, Feature.EXTENSION_METHODS));
803 if (!myHolder.hasErrorResults() && aClass != null) {
804 myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass)));
807 // method params are highlighted in visitMethod since we should make sure the method body was visited before
808 PsiParameter[] parameters = method.getParameterList().getParameters();
809 final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
811 for (PsiParameter parameter : parameters) {
812 int info = myReassignedParameters.get(parameter);
813 if (info == 0) continue; // out of this file
814 if (info == 2) {// reassigned
815 myHolder.add(HighlightNamesUtil.highlightReassignedVariable(parameter, parameter.getNameIdentifier()));
818 myHolder.add(HighlightNamesUtil.highlightVariableName(parameter, parameter.getNameIdentifier(), colorsScheme));
823 private void highlightReferencedMethodOrClassName(@NotNull PsiJavaCodeReferenceElement element, PsiElement resolved) {
824 PsiElement parent = element.getParent();
825 final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
826 if (parent instanceof PsiMethodCallExpression) {
827 PsiMethod method = ((PsiMethodCallExpression)parent).resolveMethod();
828 PsiElement methodNameElement = element.getReferenceNameElement();
829 if (method != null && methodNameElement != null&& !(methodNameElement instanceof PsiKeyword)) {
830 myHolder.add(HighlightNamesUtil.highlightMethodName(method, methodNameElement, false, colorsScheme));
831 myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(element, colorsScheme));
834 else if (parent instanceof PsiConstructorCall) {
836 PsiMethod method = ((PsiConstructorCall)parent).resolveConstructor();
837 PsiMember methodOrClass = method != null ? method : resolved instanceof PsiClass ? (PsiClass)resolved : null;
838 if (methodOrClass != null) {
839 final PsiElement referenceNameElement = element.getReferenceNameElement();
840 if(referenceNameElement != null) {
841 // exclude type parameters from the highlighted text range
842 TextRange range = referenceNameElement.getTextRange();
843 myHolder.add(HighlightNamesUtil.highlightMethodName(methodOrClass, referenceNameElement, range, colorsScheme, false));
847 catch (IndexNotReadyException ignored) { }
849 else if (resolved instanceof PsiPackage) {
850 // highlight package (and following dot) as a class
851 myHolder.add(HighlightNamesUtil.highlightPackage(resolved, element, colorsScheme));
853 else if (resolved instanceof PsiClass) {
854 myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, element, colorsScheme));
859 public void visitMethodCallExpression(PsiMethodCallExpression expression) {
860 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumSuperConstructorCall(expression));
861 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkSuperQualifierType(myFile.getProject(), expression));
862 // in case of JSP synthetic method call, do not check
863 if (myFile.isPhysical() && !myHolder.hasErrorResults()) {
865 myHolder.add(HighlightMethodUtil.checkMethodCall(expression, myResolveHelper, myLanguageLevel,myJavaSdkVersion));
867 catch (IndexNotReadyException ignored) { }
870 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallMustBeFirstStatement(expression));
871 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkSuperAbstractMethodDirectCall(expression));
873 if (!myHolder.hasErrorResults()) visitExpression(expression);
877 public void visitModifierList(PsiModifierList list) {
878 super.visitModifierList(list);
879 PsiElement parent = list.getParent();
880 if (parent instanceof PsiMethod) {
881 PsiMethod method = (PsiMethod)parent;
882 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodCanHaveBody(method, myLanguageLevel));
883 MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
884 if (!method.isConstructor()) {
886 List<HierarchicalMethodSignature> superMethodSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
887 if (!superMethodSignatures.isEmpty()) {
888 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleReturnType(methodSignature, superMethodSignatures, true));
889 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleThrows(methodSignature, superMethodSignatures, true, method.getContainingClass()));
890 if (!method.hasModifierProperty(PsiModifier.STATIC)) {
891 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodWeakerPrivileges(methodSignature, superMethodSignatures, true, myFile));
892 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodOverridesFinal(methodSignature, superMethodSignatures));
896 catch (IndexNotReadyException ignored) { }
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 if (!myHolder.hasErrorResults() && aClass != null &&
903 myOverrideEquivalentMethodsVisitedClasses.add(aClass)) {
904 myHolder.addAll(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass));
907 else if (parent instanceof PsiClass) {
908 PsiClass aClass = (PsiClass)parent;
910 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateNestedClass(aClass));
911 if (!myHolder.hasErrorResults()) {
912 TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass);
913 myHolder.add(HighlightClassUtil.checkClassMustBeAbstract(aClass, textRange));
915 if (!myHolder.hasErrorResults()) {
916 myHolder.add(HighlightClassUtil.checkClassDoesNotCallSuperConstructorOrHandleExceptions(aClass, myRefCountHolder, myResolveHelper));
918 if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkOverrideEquivalentInheritedMethods(aClass, myFile, myLanguageLevel));
919 if (!myHolder.hasErrorResults() && myOverrideEquivalentMethodsVisitedClasses.add(aClass)) {
920 myHolder.addAll(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass));
922 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCyclicInheritance(aClass));
924 catch (IndexNotReadyException ignored) {
927 else if (parent instanceof PsiEnumConstant) {
928 if (!myHolder.hasErrorResults()) myHolder.addAll(GenericsHighlightUtil.checkEnumConstantModifierList(list));
933 public void visitNameValuePair(PsiNameValuePair pair) {
934 myHolder.add(AnnotationsHighlightUtil.checkNameValuePair(pair));
935 if (!myHolder.hasErrorResults()) {
936 PsiIdentifier nameId = pair.getNameIdentifier();
937 if (nameId != null) {
938 HighlightInfo result = HighlightInfo.newHighlightInfo(JavaHighlightInfoTypes.ANNOTATION_ATTRIBUTE_NAME).range(nameId).create();
939 myHolder.add(result);
945 public void visitNewExpression(PsiNewExpression expression) {
946 final PsiType type = expression.getType();
947 final PsiClass aClass = PsiUtil.resolveClassInType(type);
948 myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, null));
949 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression));
950 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkQualifiedNew(expression, type, aClass));
951 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(expression, type, aClass));
952 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParameterInstantiation(expression));
953 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(aClass, expression));
955 if (!myHolder.hasErrorResults()) HighlightMethodUtil.checkNewExpression(expression, type, myHolder, myJavaSdkVersion);
957 catch (IndexNotReadyException ignored) { }
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);
962 if (!myHolder.hasErrorResults()) visitExpression(expression);
966 public void visitPackageStatement(PsiPackageStatement statement) {
967 super.visitPackageStatement(statement);
968 myHolder.add(AnnotationsHighlightUtil.checkPackageAnnotationContainingFile(statement));
972 public void visitParameter(PsiParameter parameter) {
973 super.visitParameter(parameter);
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));
980 else if (parent instanceof PsiCatchSection) {
981 if (!myHolder.hasErrorResults() && parameter.getType() instanceof PsiDisjunctionType) {
982 myHolder.add(checkFeature(parameter, Feature.MULTI_CATCH));
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));
988 else if (parent instanceof PsiForeachStatement) {
989 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkForEachParameterType((PsiForeachStatement)parent, parameter));
994 public void visitParameterList(PsiParameterList list) {
995 super.visitParameterList(list);
996 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkAnnotationMethodParameters(list));
1000 public void visitPostfixExpression(PsiPostfixExpression expression) {
1001 super.visitPostfixExpression(expression);
1002 if (!myHolder.hasErrorResults()) {
1003 myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
1008 public void visitPrefixExpression(PsiPrefixExpression expression) {
1009 super.visitPrefixExpression(expression);
1010 if (!myHolder.hasErrorResults()) {
1011 myHolder.add(HighlightUtil.checkUnaryOperatorApplicable(expression.getOperationSign(), expression.getOperand()));
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);
1026 public void visitReferenceElement(PsiJavaCodeReferenceElement ref) {
1027 JavaResolveResult resolveResult = doVisitReferenceElement(ref);
1028 if (resolveResult != null && !myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkRawOnParameterizedType(ref, resolveResult.getElement()));
1031 private JavaResolveResult doVisitReferenceElement(@NotNull PsiJavaCodeReferenceElement ref) {
1032 JavaResolveResult result;
1034 result = resolveOptimised(ref);
1036 catch (IndexNotReadyException e) {
1039 PsiElement resolved = result.getElement();
1040 PsiElement parent = ref.getParent();
1042 if (myRefCountHolder != null) {
1043 myRefCountHolder.registerReference(ref, result);
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;
1058 if (cannotSelectFromTypeParameter) {
1059 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Cannot select from a type parameter").range(ref).create());
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(),
1070 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkCannotPassInner(ref));
1072 if (resolved != null && parent instanceof PsiReferenceList) {
1073 if (!myHolder.hasErrorResults()) {
1074 PsiReferenceList referenceList = (PsiReferenceList)parent;
1075 myHolder.add(HighlightUtil.checkElementInReferenceList(ref, referenceList, result));
1079 if (parent instanceof PsiAnonymousClass && ref.equals(((PsiAnonymousClass)parent).getBaseClassReference()) &&
1080 myOverrideEquivalentMethodsVisitedClasses.add((PsiClass)parent)) {
1081 PsiClass aClass = (PsiClass)parent;
1082 myHolder.addAll(GenericsHighlightUtil.checkOverrideEquivalentMethods(aClass));
1085 if (resolved instanceof PsiVariable) {
1086 PsiVariable variable = (PsiVariable)resolved;
1088 final PsiElement containingClass = PsiTreeUtil.getNonStrictParentOfType(ref, PsiClass.class, PsiLambdaExpression.class);
1089 if ((containingClass instanceof PsiAnonymousClass || containingClass instanceof PsiLambdaExpression) &&
1090 !PsiTreeUtil.isAncestor(containingClass, variable, false) &&
1091 !(variable instanceof PsiField)) {
1092 if (containingClass instanceof PsiLambdaExpression || !PsiTreeUtil.isAncestor(((PsiAnonymousClass) containingClass).getArgumentList(), ref, false)) {
1093 myHolder.add(HighlightInfo.newHighlightInfo(JavaHighlightInfoTypes.IMPLICIT_ANONYMOUS_CLASS_PARAMETER).range(ref).create());
1097 if (variable instanceof PsiParameter && ref instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression)ref)) {
1098 myReassignedParameters.put((PsiParameter)variable, 2);
1101 final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
1102 if (!variable.hasModifierProperty(PsiModifier.FINAL) && isReassigned(variable)) {
1103 myHolder.add(HighlightNamesUtil.highlightReassignedVariable(variable, ref));
1106 myHolder.add(HighlightNamesUtil.highlightVariableName(variable, ref.getReferenceNameElement(), colorsScheme));
1108 myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(ref, colorsScheme));
1111 highlightReferencedMethodOrClassName(ref, resolved);
1114 if (parent instanceof PsiNewExpression && !(resolved instanceof PsiClass) && resolved instanceof PsiNamedElement && ((PsiNewExpression)parent).getClassOrAnonymousClassReference() == ref) {
1115 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref)
1116 .descriptionAndTooltip("Cannot find symbol " + ((PsiNamedElement)resolved).getName()).create());
1118 if (!myHolder.hasErrorResults() && resolved instanceof PsiClass) {
1119 final PsiClass aClass = ((PsiClass)resolved).getContainingClass();
1120 if (aClass != null) {
1121 final PsiElement qualifier = ref.getQualifier();
1122 final PsiElement place;
1123 if (qualifier instanceof PsiJavaCodeReferenceElement) {
1124 place = ((PsiJavaCodeReferenceElement)qualifier).resolve();
1127 if (parent instanceof PsiNewExpression) {
1128 final PsiExpression newQualifier = ((PsiNewExpression)parent).getQualifier();
1129 place = newQualifier == null ? ref : PsiUtil.resolveClassInType(newQualifier.getType());
1135 if (place != null && PsiTreeUtil.isAncestor(aClass, place, false) && aClass.hasTypeParameters()) {
1136 myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(ref, place, (PsiClass)resolved));
1139 else if (resolved instanceof PsiTypeParameter) {
1140 final PsiTypeParameterListOwner owner = ((PsiTypeParameter)resolved).getOwner();
1141 if (owner instanceof PsiClass) {
1142 final PsiClass outerClass = (PsiClass)owner;
1143 if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, false, false)) {
1144 myHolder.add(HighlightClassUtil.reportIllegalEnclosingUsage(ref, null, (PsiClass)owner, ref));
1150 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkPackageAndClassConflict(ref, myFile));
1156 private JavaResolveResult resolveOptimised(@NotNull PsiJavaCodeReferenceElement ref) {
1157 JavaResolveResult result;
1158 if (ref instanceof PsiReferenceExpressionImpl) {
1159 JavaResolveResult[] results = JavaResolveUtil.resolveWithContainingFile(ref,
1160 PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE,
1163 result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1166 result = ref.advancedResolve(true);
1172 private JavaResolveResult[] resolveOptimised(@NotNull PsiReferenceExpression expression) {
1173 JavaResolveResult[] results;
1174 if (expression instanceof PsiReferenceExpressionImpl) {
1175 results = JavaResolveUtil.resolveWithContainingFile(expression,
1176 PsiReferenceExpressionImpl.OurGenericsResolver.INSTANCE, true, true,
1180 results = expression.multiResolve(true);
1186 public void visitReferenceExpression(PsiReferenceExpression expression) {
1187 JavaResolveResult resultForIncompleteCode = doVisitReferenceElement(expression);
1188 if (!myHolder.hasErrorResults()) {
1189 visitExpression(expression);
1190 if (myHolder.hasErrorResults()) return;
1192 JavaResolveResult result;
1193 JavaResolveResult[] results;
1195 results = resolveOptimised(expression);
1196 result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1198 catch (IndexNotReadyException e) {
1201 PsiElement resolved = result.getElement();
1202 if (resolved instanceof PsiVariable && resolved.getContainingFile() == expression.getContainingFile()) {
1203 if (!myHolder.hasErrorResults()) {
1205 myHolder.add(HighlightControlFlowUtil.checkVariableInitializedBeforeUsage(expression, (PsiVariable)resolved, myUninitializedVarProblems,myFile));
1207 catch (IndexNotReadyException ignored) { }
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));
1215 if (!myHolder.hasErrorResults()) myHolder.add(HighlightControlFlowUtil.checkFinalVariableInitializedInLoop(expression, resolved));
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)) {
1225 myHolder.add(HighlightMethodUtil.checkAmbiguousMethodCallIdentifier(expression, results, list, resolved, result, methodCallExpression, myResolveHelper));
1227 if (!PsiTreeUtil.findChildrenOfType(methodCallExpression.getArgumentList(), PsiLambdaExpression.class).isEmpty()) {
1228 myHolder.add(HighlightMethodUtil
1229 .checkAmbiguousMethodCallArguments(expression, results, list, resolved, result, methodCallExpression, myResolveHelper, expression.getReferenceNameElement()));
1232 catch (IndexNotReadyException ignored) { }
1236 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkExpressionRequired(expression, resultForIncompleteCode));
1237 if (!myHolder.hasErrorResults() && resolved instanceof PsiField) {
1239 myHolder.add(HighlightUtil.checkIllegalForwardReferenceToField(expression, (PsiField)resolved));
1241 catch (IndexNotReadyException ignored) { }
1243 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkAccessStaticFieldFromEnumConstructor(expression, result));
1244 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkClassReferenceAfterQualifier(expression, resolved));
1245 final PsiExpression qualifierExpression = expression.getQualifierExpression();
1246 myHolder.add(HighlightUtil.checkUnqualifiedSuperInDefaultMethod(myLanguageLevel, expression, qualifierExpression));
1247 if (!myHolder.hasErrorResults() && qualifierExpression != null) {
1248 PsiType type = qualifierExpression.getType();
1249 if (type instanceof PsiCapturedWildcardType) {
1250 type = ((PsiCapturedWildcardType)type).getUpperBound();
1252 final PsiClass psiClass = PsiUtil.resolveClassInType(type);
1253 if (psiClass != null) {
1254 myHolder.add(GenericsHighlightUtil.areSupersAccessible(psiClass, expression));
1260 public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
1261 myHolder.add(checkFeature(expression, Feature.METHOD_REFERENCES));
1263 final JavaResolveResult result;
1264 final JavaResolveResult[] results;
1266 results = expression.multiResolve(true);
1267 result = results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
1269 catch (IndexNotReadyException e) {
1272 if (myRefCountHolder != null) {
1273 myRefCountHolder.registerReference(expression, result);
1275 final PsiElement method = result.getElement();
1276 if (method != null && !result.isAccessible()) {
1277 final String accessProblem = HighlightUtil.buildProblemWithAccessDescription(expression, result);
1278 HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(accessProblem).create();
1281 final TextAttributesScheme colorsScheme = myHolder.getColorsScheme();
1282 if (method instanceof PsiMethod && !expression.isConstructor()) {
1283 final PsiElement methodNameElement = expression.getReferenceNameElement();
1284 myHolder.add(HighlightNamesUtil.highlightMethodName((PsiMethod)method, methodNameElement, false, colorsScheme));
1286 myHolder.add(HighlightNamesUtil.highlightClassNameInQualifier(expression, colorsScheme));
1289 if (!LambdaUtil.isValidLambdaContext(expression.getParent())) {
1290 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
1291 .descriptionAndTooltip("Method reference expression is not expected here").create());
1294 if (!myHolder.hasErrorResults()) {
1295 final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
1296 if (functionalInterfaceType != null) {
1297 final boolean notFunctional = !LambdaUtil.isFunctionalType(functionalInterfaceType);
1298 if (notFunctional) {
1299 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
1300 .descriptionAndTooltip(functionalInterfaceType.getPresentableText() + " is not a functional interface").create());
1303 if (!myHolder.hasErrorResults()) {
1304 final PsiElement referenceNameElement = expression.getReferenceNameElement();
1305 if (referenceNameElement instanceof PsiKeyword) {
1306 if (!PsiMethodReferenceUtil.isValidQualifier(expression)) {
1307 final PsiElement qualifier = expression.getQualifier();
1308 String description = "Cannot find class " + qualifier.getText();
1309 HighlightInfo result1 =
1310 HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(description).create();
1311 myHolder.add(result1);
1315 if (!myHolder.hasErrorResults()) {
1316 final PsiClassType.ClassResolveResult resolveResult = checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType);
1318 final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
1319 if (interfaceMethod != null) {
1320 if (!myHolder.hasErrorResults()) {
1321 final String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression);
1322 if (errorMessage != null) {
1323 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(errorMessage).create());
1327 if (!myHolder.hasErrorResults()) {
1328 final String badReturnTypeMessage = PsiMethodReferenceUtil.checkReturnType(expression, result, functionalInterfaceType);
1329 if (badReturnTypeMessage != null) {
1330 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(badReturnTypeMessage).create());
1337 if (!myHolder.hasErrorResults()) {
1338 PsiElement qualifier = expression.getQualifier();
1339 if (qualifier instanceof PsiTypeElement) {
1340 final PsiType psiType = ((PsiTypeElement)qualifier).getType();
1341 final HighlightInfo genericArrayCreationInfo = GenericsHighlightUtil.checkGenericArrayCreation(qualifier, psiType);
1342 if (genericArrayCreationInfo != null) {
1343 myHolder.add(genericArrayCreationInfo);
1345 final String wildcardMessage = PsiMethodReferenceUtil.checkTypeArguments((PsiTypeElement)qualifier, psiType);
1346 if (wildcardMessage != null) {
1347 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(qualifier).descriptionAndTooltip(wildcardMessage).create());
1353 if (!myHolder.hasErrorResults()) {
1354 myHolder.add(PsiMethodReferenceHighlightingUtil.checkRawConstructorReference(expression));
1357 if (!myHolder.hasErrorResults()) {
1358 myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
1361 if (!myHolder.hasErrorResults()) {
1362 if (results.length == 0 || results[0] instanceof MethodCandidateInfo &&
1363 !((MethodCandidateInfo)results[0]).isApplicable() &&
1364 expression.getFunctionalInterfaceType() != null) {
1365 String description = null;
1366 if (results.length == 1) {
1367 description = ((MethodCandidateInfo)results[0]).getInferenceErrorMessage();
1369 if (expression.isConstructor()) {
1370 final PsiClass containingClass = PsiMethodReferenceUtil.getQualifierResolveResult(expression).getContainingClass();
1372 if (containingClass != null) {
1373 if (!myHolder.add(HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, expression)) &&
1374 !myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression, containingClass)) &&
1375 containingClass.isPhysical() &&
1376 description == null) {
1377 description = JavaErrorMessages.message("cannot.resolve.constructor", containingClass.getName());
1381 else if (description == null){
1382 description = JavaErrorMessages.message("cannot.resolve.method", expression.getReferenceName());
1385 if (description != null) {
1386 final PsiElement referenceNameElement = expression.getReferenceNameElement();
1387 final HighlightInfo highlightInfo =
1388 HighlightInfo.newHighlightInfo(results.length == 0 ? HighlightInfoType.WRONG_REF : HighlightInfoType.ERROR)
1389 .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));
1399 // It is a compile-time error if any class or interface mentioned by either U or the function type of U
1400 // is not accessible from the class or interface in which the method reference expression appears.
1402 private PsiClassType.ClassResolveResult checkFunctionalInterfaceTypeAccessible(@NotNull PsiFunctionalExpression expression,
1403 PsiType functionalInterfaceType) {
1404 PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
1405 final PsiClass psiClass = resolveResult.getElement();
1406 if (psiClass != null) {
1407 if (!PsiUtil.isAccessible(myFile.getProject(), psiClass, expression, null)) {
1408 myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
1409 .descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
1412 for (PsiType type : resolveResult.getSubstitutor().getSubstitutionMap().values()) {
1413 checkFunctionalInterfaceTypeAccessible(expression, type);
1417 return resolveResult;
1421 public void visitReferenceList(PsiReferenceList list) {
1422 if (list.getFirstChild() == null) return;
1423 PsiElement parent = list.getParent();
1424 if (!(parent instanceof PsiTypeParameter)) {
1425 myHolder.add(AnnotationsHighlightUtil.checkAnnotationDeclaration(parent, list));
1426 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkExtendsAllowed(list));
1427 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkImplementsAllowed(list));
1428 if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkClassExtendsOnlyOneClass(list));
1429 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericCannotExtendException(list));
1434 public void visitReferenceParameterList(PsiReferenceParameterList list) {
1435 if (list.getTextLength() == 0) return;
1437 myHolder.add(checkFeature(list, Feature.GENERICS));
1438 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersAllowed(list));
1439 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkParametersOnRaw(list));
1440 if (!myHolder.hasErrorResults()) {
1441 for (PsiTypeElement typeElement : list.getTypeParameterElements()) {
1442 if (typeElement.getType() instanceof PsiDiamondType) {
1443 myHolder.add(checkFeature(list, Feature.DIAMOND_TYPES));
1450 public void visitReturnStatement(PsiReturnStatement statement) {
1452 myHolder.add(HighlightUtil.checkReturnStatementType(statement));
1454 catch (IndexNotReadyException ignore) { }
1458 public void visitStatement(PsiStatement statement) {
1459 super.visitStatement(statement);
1460 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkNotAStatement(statement));
1464 public void visitSuperExpression(PsiSuperExpression expr) {
1465 myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
1466 if (!myHolder.hasErrorResults()) visitExpression(expr);
1470 public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) {
1471 super.visitSwitchLabelStatement(statement);
1472 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkCaseStatement(statement));
1476 public void visitSwitchStatement(PsiSwitchStatement statement) {
1477 super.visitSwitchStatement(statement);
1478 myHolder.add(HighlightUtil.checkStatementPrependedWithCaseInsideSwitch(statement));
1479 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkSwitchSelectorType(statement, myLanguageLevel));
1483 public void visitThisExpression(PsiThisExpression expr) {
1484 if (!(expr.getParent() instanceof PsiReceiverParameter)) {
1485 myHolder.add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
1486 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null, myFile));
1487 if (!myHolder.hasErrorResults()) visitExpression(expr);
1492 public void visitThrowStatement(PsiThrowStatement statement) {
1493 myHolder.add(HighlightUtil.checkUnhandledExceptions(statement, null));
1494 if (!myHolder.hasErrorResults()) visitStatement(statement);
1498 public void visitTryStatement(PsiTryStatement statement) {
1499 super.visitTryStatement(statement);
1500 if (!myHolder.hasErrorResults()) {
1501 final Set<PsiClassType> thrownTypes = HighlightUtil.collectUnhandledExceptions(statement);
1502 for (PsiParameter parameter : statement.getCatchBlockParameters()) {
1503 boolean added = myHolder.addAll(HighlightUtil.checkExceptionAlreadyCaught(parameter));
1505 added = myHolder.addAll(HighlightUtil.checkExceptionThrownInTry(parameter, thrownTypes));
1508 myHolder.addAll(HighlightUtil.checkWithImprovedCatchAnalysis(parameter, thrownTypes, myFile));
1515 public void visitResourceList(PsiResourceList resourceList) {
1516 super.visitResourceList(resourceList);
1517 if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(resourceList, Feature.TRY_WITH_RESOURCES));
1521 public void visitResourceVariable(PsiResourceVariable resource) {
1522 super.visitResourceVariable(resource);
1523 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resource));
1524 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resource));
1528 public void visitResourceExpression(PsiResourceExpression resource) {
1529 super.visitResourceExpression(resource);
1530 if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(resource, Feature.REFS_AS_RESOURCE));
1531 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkResourceVariableIsFinal(resource));
1532 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkTryResourceIsAutoCloseable(resource));
1533 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledCloserExceptions(resource));
1537 public void visitTypeElement(PsiTypeElement type) {
1538 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIllegalType(type));
1539 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkReferenceTypeUsedAsTypeArgument(type, myLanguageLevel));
1540 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkWildcardUsage(type));
1544 public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
1545 super.visitTypeCastExpression(typeCast);
1547 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIntersectionInTypeCast(typeCast, myLanguageLevel));
1548 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
1550 catch (IndexNotReadyException ignored) { }
1554 public void visitTypeParameterList(PsiTypeParameterList list) {
1555 PsiTypeParameter[] typeParameters = list.getTypeParameters();
1556 if (typeParameters.length > 0) {
1557 myHolder.add(checkFeature(list, Feature.GENERICS));
1558 if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParametersList(list, typeParameters, myLanguageLevel));
1563 public void visitVariable(PsiVariable variable) {
1564 super.visitVariable(variable);
1566 if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkVariableInitializerType(variable));
1568 catch (IndexNotReadyException ignored) { }
1571 private boolean isReassigned(@NotNull PsiVariable variable) {
1574 if (variable instanceof PsiParameter) {
1575 reassigned = myReassignedParameters.get((PsiParameter)variable) == 2;
1578 reassigned = HighlightControlFlowUtil.isReassigned(variable, myFinalVarProblems);
1583 catch (IndexNotReadyException e) {
1589 public void visitConditionalExpression(PsiConditionalExpression expression) {
1590 super.visitConditionalExpression(expression);
1591 if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) && PsiPolyExpressionUtil.isPolyExpression(expression)) {
1592 final PsiExpression thenExpression = expression.getThenExpression();
1593 final PsiExpression elseExpression = expression.getElseExpression();
1594 if (thenExpression != null && elseExpression != null) {
1595 final PsiType conditionalType = expression.getType();
1596 if (conditionalType != null) {
1597 final PsiExpression[] sides = {thenExpression, elseExpression};
1598 for (PsiExpression side : sides) {
1599 final PsiType sideType = side.getType();
1600 if (sideType != null && !TypeConversionUtil.isAssignable(conditionalType, sideType)) {
1601 myHolder.add(HighlightUtil.checkAssignability(conditionalType, sideType, side, side));
1610 public void visitReceiverParameter(PsiReceiverParameter parameter) {
1611 super.visitReceiverParameter(parameter);
1612 if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(parameter, Feature.RECEIVERS));
1613 if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkReceiverPlacement(parameter));
1614 if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkReceiverType(parameter));
1618 public void visitModule(PsiJavaModule module) {
1619 super.visitModule(module);
1620 if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(module, Feature.MODULES));
1621 if (!myHolder.hasErrorResults()) myHolder.add(ModuleHighlightUtil.checkFileName(module, myFile));
1622 if (!myHolder.hasErrorResults()) myHolder.add(ModuleHighlightUtil.checkFileDuplicates(module, myFile));
1623 if (!myHolder.hasErrorResults()) myHolder.addAll(ModuleHighlightUtil.checkDuplicateRequires(module));
1624 if (!myHolder.hasErrorResults()) myHolder.add(ModuleHighlightUtil.checkFileLocation(module, myFile));
1628 public void visitRequiresStatement(PsiRequiresStatement statement) {
1629 super.visitRequiresStatement(statement);
1630 if (PsiUtil.isLanguageLevel9OrHigher(myFile)) {
1631 PsiJavaModuleReferenceElement ref = statement.getReferenceElement();
1632 if (!myHolder.hasErrorResults()) myHolder.add(ModuleHighlightUtil.checkModuleReference(ref));
1637 private HighlightInfo checkFeature(@NotNull PsiElement element, @NotNull Feature feature) {
1638 return HighlightUtil.checkFeature(element, feature, myLanguageLevel, myFile);
1641 protected void prepareToRunAsInspection(@NotNull HighlightInfoHolder holder) {
1642 PsiFile file = holder.getContextFile();
1643 JavaSdkVersion sdkVersion = JavaVersionService.getInstance().getJavaSdkVersion(file);
1647 myLanguageLevel = PsiUtil.getLanguageLevel(file);
1648 myJavaSdkVersion = sdkVersion != null ? sdkVersion : JavaSdkVersion.fromLanguageLevel(myLanguageLevel);