From aa8576f3ce9f4888aebb942feb321d8495d988b5 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Mon, 2 Oct 2017 11:00:19 +0200 Subject: [PATCH] LVTI: shrink the highlighting range move functional expression errors to var declaration --- .../daemon/impl/analysis/HighlightUtil.java | 13 ++++++++++--- .../daemon/impl/analysis/HighlightVisitorImpl.java | 14 ++++++++++++-- .../advLVTI/SimpleAvailability.java | 12 ++++++------ 3 files changed, 28 insertions(+), 11 deletions(-) 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 e5b89ed7b9dc..f9fe48793d1e 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 @@ -426,7 +426,14 @@ public class HighlightUtil extends HighlightUtilBase { if (initializer == null) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip("Cannot infer type: 'var' on variable without initializer") - .range(variable).create(); + .range(typeElement).create(); + } + + if (initializer instanceof PsiFunctionalExpression) { + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .descriptionAndTooltip("Cannot infer type: " + (initializer instanceof PsiLambdaExpression ? "lambda expression" : "method reference") + + " requires an explicit target type") + .range(typeElement).create(); } PsiLocalVariable[] localVariables = PsiTreeUtil.getChildrenOfType(parent, PsiLocalVariable.class); @@ -440,14 +447,14 @@ public class HighlightUtil extends HighlightUtilBase { if (lType instanceof PsiArrayType && !lType.equals(typeElement.getType())) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip("'var' is not allowed as an element type of an array") - .range(variable) + .range(typeElement) .create(); } if (PsiType.NULL.equals(lType)) { return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .descriptionAndTooltip("Cannot infer type: variable initializer is 'null'") - .range(variable).create(); + .range(typeElement).create(); } } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 1f09ff28b412..577ed4e83bd7 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -320,7 +320,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh public void visitLambdaExpression(PsiLambdaExpression expression) { myHolder.add(checkFeature(expression, Feature.LAMBDA_EXPRESSIONS)); final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); - if (parent instanceof PsiExpressionStatement) return; + if (toReportFunctionalExpressionProblemOnParent(parent)) return; if (!myHolder.hasErrorResults() && !LambdaUtil.isValidLambdaContext(parent)) { myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression) .descriptionAndTooltip("Lambda expression not expected here").create()); @@ -1311,7 +1311,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { myHolder.add(checkFeature(expression, Feature.METHOD_REFERENCES)); final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent()); - if (parent instanceof PsiExpressionStatement) return; + if (toReportFunctionalExpressionProblemOnParent(parent)) return; final JavaResolveResult result; final JavaResolveResult[] results; @@ -1460,6 +1460,16 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } } + /** + * @return true for {@code functional_expression;} or {@code var l = functional_expression;} + */ + private static boolean toReportFunctionalExpressionProblemOnParent(PsiElement parent) { + if (parent instanceof PsiLocalVariable) { + return ((PsiLocalVariable)parent).getTypeElement().isInferredType(); + } + return parent instanceof PsiExpressionStatement; + } + // 15.13 | 15.27 // It is a compile-time error if any class or interface mentioned by either U or the function type of U // is not accessible from the class or interface in which the method reference expression appears. diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advLVTI/SimpleAvailability.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advLVTI/SimpleAvailability.java index 623df4cc8f88..b4779d13fe91 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advLVTI/SimpleAvailability.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advLVTI/SimpleAvailability.java @@ -3,10 +3,10 @@ class Main { private static void localVariableDeclaration() { var a = 1; var b = 2, c = 3.0; - var d[] = new int[4]; + var d[] = new int[4]; var d1 = new int[] {4}; var d2 = new int[4]; - var e; + var e; var f = { 6 }; var g = (g = 7); } @@ -26,9 +26,9 @@ class Main { var e = (CharSequence & Comparable) "x"; int el = e.compareTo(""); - var f = () -> "hello"; - var m = Main::localVariableDeclaration; - var g = null; + var f = () -> "hello"; + var m = Main::localVariableDeclaration; + var g = null; } private void forEachType(String[] strs, Iterable it, Iterable raw) { @@ -53,7 +53,7 @@ class Main { } private void tryWithResources(AutoCloseable c) throws Exception { - try (var v = null) { } + try (var v = null) { } try (var v = c) { } }