[java-highlighting] Avoid TextRange computation until necessary

GitOrigin-RevId: 8d2b32d3b5353a1ff4b855acc779d69907f935af
This commit is contained in:
Tagir Valeev
2020-09-23 16:43:41 +07:00
committed by intellij-monorepo-bot
parent b49b61e9c4
commit 044abd82e1
7 changed files with 55 additions and 52 deletions

View File

@@ -1428,7 +1428,7 @@ public final class GenericsHighlightUtil {
}
}
static HighlightInfo checkInferredIntersections(@NotNull PsiSubstitutor substitutor, @NotNull TextRange ref) {
static HighlightInfo checkInferredIntersections(@NotNull PsiSubstitutor substitutor, @NotNull PsiMethodCallExpression call) {
for (Map.Entry<PsiTypeParameter, PsiType> typeEntry : substitutor.getSubstitutionMap().entrySet()) {
final String parameterName = typeEntry.getKey().getName();
final PsiType type = typeEntry.getValue();
@@ -1438,7 +1438,7 @@ public final class GenericsHighlightUtil {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.descriptionAndTooltip(
JavaErrorBundle.message("type.parameter.has.incompatible.upper.bounds", parameterName, conflictingConjunctsMessage))
.range(ref).create();
.range(HighlightMethodUtil.getFixRange(call)).create();
}
}
}
@@ -1446,17 +1446,18 @@ public final class GenericsHighlightUtil {
}
static HighlightInfo checkClassSupersAccessibility(@NotNull PsiClass aClass) {
return checkClassSupersAccessibility(aClass, aClass.getResolveScope(), HighlightNamesUtil.getClassDeclarationTextRange(aClass), true);
HighlightInfo.Builder builder = checkClassSupersAccessibility(aClass, aClass.getResolveScope(), true);
return builder == null ? null : builder.range(HighlightNamesUtil.getClassDeclarationTextRange(aClass)).create();
}
static HighlightInfo checkClassSupersAccessibility(@NotNull PsiClass aClass, @NotNull PsiElement ref) {
return checkClassSupersAccessibility(aClass, ref.getResolveScope(), ref.getTextRange(), false);
static HighlightInfo checkClassSupersAccessibility(@NotNull PsiClass aClass, @NotNull PsiElement ref, @NotNull GlobalSearchScope scope) {
HighlightInfo.Builder builder = checkClassSupersAccessibility(aClass, scope, false);
return builder == null ? null : builder.range(ref.getTextRange()).create();
}
private static HighlightInfo checkClassSupersAccessibility(@NotNull PsiClass aClass,
@NotNull GlobalSearchScope resolveScope,
@NotNull TextRange range,
boolean checkParameters) {
private static HighlightInfo.Builder checkClassSupersAccessibility(@NotNull PsiClass aClass,
@NotNull GlobalSearchScope resolveScope,
boolean checkParameters) {
final JavaPsiFacade factory = JavaPsiFacade.getInstance(aClass.getProject());
for (PsiClassType superType : aClass.getSuperTypes()) {
HashSet<PsiClass> checked = new HashSet<>();
@@ -1464,9 +1465,7 @@ public final class GenericsHighlightUtil {
final String notAccessibleErrorMessage = isTypeAccessible(superType, checked, checkParameters, resolveScope, factory);
if (notAccessibleErrorMessage != null) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.descriptionAndTooltip(notAccessibleErrorMessage)
.range(range)
.create();
.descriptionAndTooltip(notAccessibleErrorMessage);
}
}
return null;

View File

@@ -381,9 +381,7 @@ public final class HighlightMethodUtil {
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
if (resolved instanceof PsiMethod && resolveResult.isValidResult()) {
PsiElement nameElement = referenceToMethod.getReferenceNameElement();
TextRange fixRange = getFixRange(methodCall);
highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, nameElement != null ? nameElement.getTextRange() : fixRange);
highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall);
if (highlightInfo == null && ((PsiMethod)resolved).hasModifierProperty(PsiModifier.STATIC)) {
PsiClass containingClass = ((PsiMethod)resolved).getContainingClass();
@@ -391,14 +389,13 @@ public final class HighlightMethodUtil {
PsiElement element = ObjectUtils.notNull(referenceToMethod.getReferenceNameElement(), referenceToMethod);
highlightInfo = HighlightUtil.checkFeature(element, HighlightingFeature.STATIC_INTERFACE_CALLS, languageLevel, file);
if (highlightInfo == null) {
highlightInfo =
checkStaticInterfaceCallQualifier(referenceToMethod, resolveResult, fixRange, containingClass);
highlightInfo = checkStaticInterfaceCallQualifier(referenceToMethod, resolveResult, methodCall, containingClass);
}
}
}
if (highlightInfo == null) {
highlightInfo = GenericsHighlightUtil.checkInferredIntersections(substitutor, fixRange);
highlightInfo = GenericsHighlightUtil.checkInferredIntersections(substitutor, methodCall);
}
if (highlightInfo == null) {
@@ -406,7 +403,7 @@ public final class HighlightMethodUtil {
}
if (highlightInfo == null) {
highlightInfo = createIncompatibleTypeHighlightInfo(methodCall, resolveHelper, (MethodCandidateInfo)resolveResult, fixRange);
highlightInfo = createIncompatibleTypeHighlightInfo(methodCall, resolveHelper, (MethodCandidateInfo)resolveResult, methodCall);
}
}
else {
@@ -560,13 +557,14 @@ public final class HighlightMethodUtil {
static HighlightInfo createIncompatibleTypeHighlightInfo(@NotNull PsiCallExpression methodCall,
@NotNull PsiResolveHelper resolveHelper,
@NotNull MethodCandidateInfo resolveResult,
TextRange fixRange) {
@NotNull PsiElement elementToHighlight) {
String errorMessage = resolveResult.getInferenceErrorMessage();
if (errorMessage == null) return null;
PsiMethod method = resolveResult.getElement();
HighlightInfo highlightInfo;
PsiType expectedTypeByParent = InferenceSession.getTargetTypeByParent(methodCall);
PsiType actualType = resolveResult.getSubstitutor(false).substitute(method.getReturnType());
TextRange fixRange = getFixRange(elementToHighlight);
if (expectedTypeByParent != null && actualType != null && !expectedTypeByParent.isAssignableFrom(actualType)) {
highlightInfo = HighlightUtil
.createIncompatibleTypeHighlightInfo(expectedTypeByParent, actualType, fixRange, 0, XmlStringUtil.escapeString(errorMessage));
@@ -631,11 +629,12 @@ public final class HighlightMethodUtil {
static HighlightInfo checkStaticInterfaceCallQualifier(@NotNull PsiReferenceExpression referenceToMethod,
@NotNull JavaResolveResult resolveResult,
@NotNull TextRange fixRange,
@NotNull PsiElement elementToHighlight,
@NotNull PsiClass containingClass) {
String message = checkStaticInterfaceMethodCallQualifier(referenceToMethod, resolveResult.getCurrentFileResolveScope(), containingClass);
if (message != null) {
HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip(message).range(fixRange).create();
HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip(message)
.range(getFixRange(elementToHighlight)).create();
QuickFixAction
.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createAccessStaticViaInstanceFix(referenceToMethod, resolveResult));
return highlightInfo;
@@ -760,7 +759,7 @@ public final class HighlightMethodUtil {
if (containingClass != null && containingClass.isInterface()) {
HighlightInfo info = HighlightUtil.checkFeature(elementToHighlight, HighlightingFeature.STATIC_INTERFACE_CALLS, languageLevel, file);
if (info != null) return info;
info = checkStaticInterfaceCallQualifier(referenceToMethod, resolveResult, elementToHighlight.getTextRange(), containingClass);
info = checkStaticInterfaceCallQualifier(referenceToMethod, resolveResult, elementToHighlight, containingClass);
if (info != null) return info;
}
}

View File

@@ -33,22 +33,10 @@ public final class HighlightNamesUtil {
private static final Logger LOG = Logger.getInstance(HighlightNamesUtil.class);
@Nullable
static HighlightInfo highlightMethodName(@NotNull PsiMethod method,
static HighlightInfo highlightMethodName(@NotNull PsiMember methodOrClass,
@NotNull PsiElement elementToHighlight,
final boolean isDeclaration,
@NotNull TextAttributesScheme colorsScheme) {
return highlightMethodName(method, elementToHighlight, elementToHighlight.getTextRange(), colorsScheme, isDeclaration);
}
/**
* @param methodOrClass method to highlight; class is passed instead of implicit constructor
*/
@Nullable
static HighlightInfo highlightMethodName(@NotNull PsiMember methodOrClass,
@NotNull PsiElement elementToHighlight,
@NotNull TextRange range,
@NotNull TextAttributesScheme colorsScheme,
final boolean isDeclaration) {
boolean isInherited = false;
boolean isStaticallyImported = false;
@@ -70,7 +58,7 @@ public final class HighlightNamesUtil {
: JavaHighlightInfoTypes.CONSTRUCTOR_CALL;
if (type != null) {
TextAttributes attributes = mergeWithScopeAttributes(methodOrClass, type, colorsScheme);
HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(type).range(range);
HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(type).range(elementToHighlight.getTextRange());
if (attributes != null) {
builder.textAttributes(attributes);
}

View File

@@ -781,20 +781,39 @@ public final class HighlightUtil {
return PsiFormatUtil.formatVariable(field, PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_NAME, PsiSubstitutor.EMPTY);
}
static HighlightInfo checkUnhandledExceptions(@NotNull PsiElement element, @Nullable TextRange textRange) {
static HighlightInfo checkUnhandledExceptions(@NotNull PsiElement element) {
List<PsiClassType> unhandled = ExceptionUtil.getOwnUnhandledExceptions(element);
if (unhandled.isEmpty()) return null;
HighlightInfoType highlightType = getUnhandledExceptionHighlightType(element);
if (highlightType == null) return null;
if (textRange == null) textRange = element.getTextRange();
TextRange textRange = computeRange(element);
String description = getUnhandledExceptionsDescriptor(unhandled);
HighlightInfo errorResult = HighlightInfo.newHighlightInfo(highlightType).range(textRange).descriptionAndTooltip(description).create();
HighlightFixUtil.registerUnhandledExceptionFixes(element, errorResult);
return errorResult;
}
private static TextRange computeRange(@NotNull PsiElement element) {
if (element instanceof PsiNewExpression) {
PsiJavaCodeReferenceElement reference = ((PsiNewExpression)element).getClassReference();
if (reference != null) {
return reference.getTextRange();
}
}
if (element instanceof PsiEnumConstant) {
return ((PsiEnumConstant)element).getNameIdentifier().getTextRange();
}
if (element instanceof PsiMethodCallExpression) {
PsiElement nameElement = ((PsiMethodCallExpression)element).getMethodExpression().getReferenceNameElement();
if (nameElement != null) {
return nameElement.getTextRange();
}
}
return HighlightMethodUtil.getFixRange(element);
}
static HighlightInfo checkUnhandledCloserExceptions(@NotNull PsiResourceListElement resource) {
List<PsiClassType> unhandled = ExceptionUtil.getUnhandledCloserExceptions(resource, null);
if (unhandled.isEmpty()) return null;

View File

@@ -413,7 +413,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (parentInferenceErrorMessage != null && (returnErrors == null || !returnErrors.containsValue(parentInferenceErrorMessage))) {
if (returnErrors == null) return;
HighlightInfo info = HighlightMethodUtil.createIncompatibleTypeHighlightInfo(callExpression, getResolveHelper(myHolder.getProject()),
(MethodCandidateInfo)containingCallResolveResult, expression.getTextRange());
(MethodCandidateInfo)containingCallResolveResult, expression);
returnErrors.keySet().forEach(k -> QuickFixAction.registerQuickFixAction(info, AdjustFunctionContextFix.createFix(k)));
myHolder.add(info);
}
@@ -569,7 +569,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
super.visitEnumConstant(enumConstant);
if (!myHolder.hasErrorResults()) GenericsHighlightUtil.checkEnumConstantForConstructorProblems(enumConstant, myHolder, myJavaSdkVersion);
if (!myHolder.hasErrorResults()) registerConstructorCall(enumConstant);
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledExceptions(enumConstant, enumConstant.getNameIdentifier().getTextRange()));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkUnhandledExceptions(enumConstant));
}
@Override
@@ -680,7 +680,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (importReference != null) {
PsiElement referenceNameElement = importReference.getReferenceNameElement();
if (referenceNameElement != null && targetClass != null) {
myHolder.add(GenericsHighlightUtil.checkClassSupersAccessibility(targetClass, referenceNameElement));
myHolder.add(GenericsHighlightUtil.checkClassSupersAccessibility(targetClass, referenceNameElement, myFile.getResolveScope()));
}
}
if (!myHolder.hasErrorResults()) {
@@ -968,8 +968,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
final PsiElement referenceNameElement = element.getReferenceNameElement();
if(referenceNameElement != null) {
// exclude type parameters from the highlighted text range
TextRange range = referenceNameElement.getTextRange();
myHolder.add(HighlightNamesUtil.highlightMethodName(methodOrClass, referenceNameElement, range, colorsScheme, false));
myHolder.add(HighlightNamesUtil.highlightMethodName(methodOrClass, referenceNameElement, false, colorsScheme));
}
}
}
@@ -1075,8 +1074,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
public void visitNewExpression(PsiNewExpression expression) {
final PsiType type = expression.getType();
final PsiClass aClass = PsiUtil.resolveClassInType(type);
PsiJavaCodeReferenceElement classReference = expression.getClassReference();
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, classReference != null ? classReference.getTextRange() : null));
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritProhibited(expression));
if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousSealedProhibited(expression));
@@ -1443,7 +1441,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (parent instanceof PsiMethodCallExpression) {
PsiClass psiClass = RefactoringChangeUtil.getQualifierClass(expression);
if (psiClass != null) {
myHolder.add(GenericsHighlightUtil.checkClassSupersAccessibility(psiClass, expression));
myHolder.add(GenericsHighlightUtil.checkClassSupersAccessibility(psiClass, expression, myFile.getResolveScope()));
}
}
if (!myHolder.hasErrorResults()) {
@@ -1567,7 +1565,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
PsiClass containingClass = ((PsiMethod)method).getContainingClass();
if (!myHolder.hasErrorResults() && containingClass != null && containingClass.isInterface()) {
myHolder.add(HighlightMethodUtil.checkStaticInterfaceCallQualifier(expression, result, expression.getTextRange(), containingClass));
myHolder.add(HighlightMethodUtil.checkStaticInterfaceCallQualifier(expression, result, expression, containingClass));
}
}
@@ -1576,7 +1574,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
if (!myHolder.hasErrorResults()) {
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, expression.getTextRange()));
myHolder.add(HighlightUtil.checkUnhandledExceptions(expression));
}
if (!myHolder.hasErrorResults()) {
@@ -1804,7 +1802,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
@Override
public void visitThrowStatement(PsiThrowStatement statement) {
myHolder.add(HighlightUtil.checkUnhandledExceptions(statement, null));
myHolder.add(HighlightUtil.checkUnhandledExceptions(statement));
if (!myHolder.hasErrorResults()) visitStatement(statement);
}

View File

@@ -5,7 +5,7 @@ interface I {
class A implements I {
{
System.out.println(A./*c1*/<error descr="Static method may be invoked on containing interface class only">foo</error>());
Runnable r = <error descr="Static method may be invoked on containing interface class only">A/*c2*/::<String>foo</error>;
Runnable r = <error descr="Static method may be invoked on containing interface class only">A/*c2*/::<String>foo;</error>
System.out.println(r);
}
}

View File

@@ -4,7 +4,7 @@ public class ExTest {
}
{
Block<String> b = <error descr="Unhandled exception: ExTest.Ex">ExTest::maybeThrow</error>;
Block<String> b = <error descr="Unhandled exception: ExTest.Ex">ExTest::maybeThrow;</error>
}