From f4166d3f0578c3f6acae006a2795f7dfd7ea492d Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 25 Oct 2017 19:30:36 +0200 Subject: [PATCH] check function type's parameters/return type accessibility (IDEA-181036) --- .../impl/analysis/HighlightVisitorImpl.java | 21 +++++++++++++++---- .../InaccessibleFunctionalTypeParameter.java | 9 ++++++++ .../LightAdvHighlightingFixtureTest.java | 9 ++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advFixture/InaccessibleFunctionalTypeParameter.java 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 ef9d2ae6ef74..37089aef7b37 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 @@ -334,7 +334,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh .descriptionAndTooltip(notFunctionalMessage).create()); } else { - checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType); + checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType, true); } } else if (LambdaUtil.getFunctionalInterfaceType(expression, true) != null) { @@ -1372,7 +1372,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } } if (!myHolder.hasErrorResults()) { - checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType); + checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType, true); } if (!myHolder.hasErrorResults()) { String errorMessage = PsiMethodReferenceUtil.checkMethodReferenceContext(expression); @@ -1474,7 +1474,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh // 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. - private void checkFunctionalInterfaceTypeAccessible(@NotNull PsiFunctionalExpression expression, PsiType functionalInterfaceType) { + private boolean checkFunctionalInterfaceTypeAccessible(@NotNull PsiFunctionalExpression expression, PsiType functionalInterfaceType, + boolean checkFunctionalTypeSignature) { PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); PsiClass psiClass = resolveResult.getElement(); if (psiClass != null) { @@ -1486,13 +1487,25 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh if (problem.second != null) { problem.second.forEach(fix -> QuickFixAction.registerQuickFixAction(info, fix)); } + return true; } else { for (PsiType type : resolveResult.getSubstitutor().getSubstitutionMap().values()) { - checkFunctionalInterfaceTypeAccessible(expression, type); + if (checkFunctionalInterfaceTypeAccessible(expression, type, false)) return true; + } + + PsiMethod psiMethod = checkFunctionalTypeSignature ? LambdaUtil.getFunctionalInterfaceMethod(resolveResult) : null; + if (psiMethod != null) { + PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(psiMethod, resolveResult); + for (PsiParameter parameter : psiMethod.getParameterList().getParameters()) { + if (checkFunctionalInterfaceTypeAccessible(expression, substitutor.substitute(parameter.getType()), false)) return true; + } + + if (checkFunctionalInterfaceTypeAccessible(expression, substitutor.substitute(psiMethod.getReturnType()), false)) return true; } } } + return false; } @Override diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advFixture/InaccessibleFunctionalTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advFixture/InaccessibleFunctionalTypeParameter.java new file mode 100644 index 000000000000..f936db9d9882 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advFixture/InaccessibleFunctionalTypeParameter.java @@ -0,0 +1,9 @@ +package p; +import test.*; + +class Test { + { + I i = (a) -> {}; + J j = () -> null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingFixtureTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingFixtureTest.java index 2818bde20783..3fe6bdef4dc6 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingFixtureTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingFixtureTest.java @@ -48,6 +48,15 @@ public class LightAdvHighlightingFixtureTest extends LightCodeInsightFixtureTest assertNull(ReferencesSearch.search(aClass).findFirst()); } + public void testInaccessibleFunctionalTypeParameter() { + myFixture.addClass("package test; class A {}"); + myFixture.addClass("package test; public interface I { void m(A a);}"); + myFixture.addClass("package test; public interface J { A m();}"); + + myFixture.configureByFile(getTestName(false) + ".java"); + myFixture.checkHighlighting(); + } + public void testBoundsPromotionWithCapturedWildcards() { myFixture.addClass("package a; public interface Provider {}"); myFixture.addClass("package b; public interface Provider {}");