From b2cc1fde7548add9e3bd487d98d156fd72cfe1e6 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 29 May 2023 15:40:14 +0200 Subject: [PATCH] Java: more clear error message on trying to reference member of primitive type (IDEA-321123) GitOrigin-RevId: 7244dcae3a1a93396930b6a7e4b1303a8482dbf0 --- .../impl/analysis/HighlightMethodUtil.java | 17 +++++++++++++---- .../daemon/impl/analysis/HighlightUtil.java | 9 +++++++++ .../src/messages/JavaErrorBundle.properties | 2 ++ .../advHighlighting/InvalidExpressions.java | 3 +++ .../fixture/AvoidWarningAtNotInferredType.java | 1 + 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 9030b4d33987..4634dfdc9acc 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -868,11 +868,20 @@ public final class HighlightMethodUtil { } else if (candidates.length == 0) { PsiClass qualifierClass = RefactoringChangeUtil.getQualifierClass(referenceToMethod); - String qualifier = qualifierClass != null ? qualifierClass.getName() : null; + String className = qualifierClass != null ? qualifierClass.getName() : null; + PsiExpression qualifierExpression = referenceToMethod.getQualifierExpression(); - description = qualifier != null - ? JavaErrorBundle.message("ambiguous.method.call.no.match", referenceToMethod.getReferenceName(), qualifier) - : JavaErrorBundle.message("cannot.resolve.method", referenceToMethod.getReferenceName() + buildArgTypesList(list, true)); + if (className != null) { + description = JavaErrorBundle.message("ambiguous.method.call.no.match", referenceToMethod.getReferenceName(), className); + } + else { + description = + qualifierExpression != null && + qualifierExpression.getType() instanceof PsiPrimitiveType primitiveType && + !primitiveType.equals(PsiTypes.nullType()) && !primitiveType.equals(PsiTypes.voidType()) + ? JavaErrorBundle.message("cannot.call.method.on.type", qualifierExpression.getText(), primitiveType.getPresentableText(false)) + : JavaErrorBundle.message("cannot.resolve.method", referenceToMethod.getReferenceName() + buildArgTypesList(list, true)); + } highlightInfoType = HighlightInfoType.WRONG_REF; } else { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 9871da58cdd6..5d30acb51d2c 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -3266,6 +3266,15 @@ public final class HighlightUtil { } else { description = JavaErrorBundle.message("cannot.resolve.symbol", refName.getText()); + if (ref instanceof PsiReferenceExpression expression) { + PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (qualifierExpression != null && + qualifierExpression.getType() instanceof PsiPrimitiveType primitiveType && + !primitiveType.equals(PsiTypes.nullType()) && !primitiveType.equals(PsiTypes.voidType())) { + description = JavaErrorBundle.message("cannot.access.member.on.type", qualifierExpression.getText(), + primitiveType.getPresentableText(false)); + } + } } HighlightInfo.Builder info = diff --git a/java/java-psi-impl/src/messages/JavaErrorBundle.properties b/java/java-psi-impl/src/messages/JavaErrorBundle.properties index 94efe17724d3..af9747519f51 100644 --- a/java/java-psi-impl/src/messages/JavaErrorBundle.properties +++ b/java/java-psi-impl/src/messages/JavaErrorBundle.properties @@ -305,6 +305,8 @@ deprecated.symbol=''{0}'' is deprecated marked.for.removal.symbol=''{0}'' is deprecated and marked for removal qualifier.must.be.expression=Qualifier must be an expression cannot.resolve.symbol=Cannot resolve symbol ''{0}'' +cannot.access.member.on.type=Cannot access member because ''{0}'' has primitive type {1} +cannot.call.method.on.type=Cannot call method because ''{0}'' has primitive type {1} class.is.already.defined.in.single.static.import=Class ''{0}'' is already defined in a single static import class.is.ambiguous.in.single.static.import=Class ''{0}'' is ambiguous in a single static import field.is.already.defined.in.single.static.import=Field ''{0}'' is already defined in a single static import diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InvalidExpressions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InvalidExpressions.java index 0182f9959a0c..9e6ab8a158fc 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InvalidExpressions.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InvalidExpressions.java @@ -50,6 +50,9 @@ public class a12 { foo123Unresolved(String); foo123Unresolved(xxxx); + int i = 0; + System.out.println(i.x); + System.out.println(true.toString()); xxxxxx(xxxxxx); diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/AvoidWarningAtNotInferredType.java b/java/java-tests/testData/inspection/dataFlow/fixture/AvoidWarningAtNotInferredType.java index 0380c5da2f3d..a48ff3773520 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/AvoidWarningAtNotInferredType.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/AvoidWarningAtNotInferredType.java @@ -2,5 +2,6 @@ class Test { void test() { var x = unresolved(); System.out.println(x.hashCode()); + System.out.println(x.x); } } \ No newline at end of file