support @FunctionalInterface

This commit is contained in:
Anna Kozlova
2013-01-28 16:16:55 +04:00
parent 6d40026bd4
commit f1c1c6ee42
6 changed files with 34 additions and 0 deletions

View File

@@ -406,6 +406,14 @@ public class AnnotationsHighlightUtil {
return null; return null;
} }
public static HighlightInfo checkFunctionalInterface(PsiAnnotation annotation) {
final String errorMessage = LambdaUtil.checkFunctionalInterface(annotation);
if (errorMessage != null) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, annotation, errorMessage);
}
return null;
}
public static class AnnotationReturnTypeVisitor extends PsiTypeVisitor<Boolean> { public static class AnnotationReturnTypeVisitor extends PsiTypeVisitor<Boolean> {
public static final AnnotationReturnTypeVisitor INSTANCE = new AnnotationReturnTypeVisitor(); public static final AnnotationReturnTypeVisitor INSTANCE = new AnnotationReturnTypeVisitor();
@Override @Override

View File

@@ -182,6 +182,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation)); if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation)); if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkForeignInnerClassesUsed(annotation)); if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkForeignInnerClassesUsed(annotation));
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation));
} }
@Override @Override

View File

@@ -25,6 +25,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.*; import com.intellij.psi.util.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -37,6 +38,7 @@ import java.util.*;
public class LambdaUtil { public class LambdaUtil {
private static final Logger LOG = Logger.getInstance("#" + LambdaUtil.class.getName()); private static final Logger LOG = Logger.getInstance("#" + LambdaUtil.class.getName());
public static ThreadLocal<Set<PsiParameterList>> ourParams = new ThreadLocal<Set<PsiParameterList>>(); public static ThreadLocal<Set<PsiParameterList>> ourParams = new ThreadLocal<Set<PsiParameterList>>();
@NonNls public static final String JAVA_LANG_FUNCTIONAL_INTERFACE = "java.lang.FunctionalInterface";
@Nullable @Nullable
public static PsiType getFunctionalInterfaceReturnType(PsiLambdaExpression expr) { public static PsiType getFunctionalInterfaceReturnType(PsiLambdaExpression expr) {
@@ -659,6 +661,20 @@ public class LambdaUtil {
return getFunctionalInterfaceReturnType(functionalInterfaceType); return getFunctionalInterfaceReturnType(functionalInterfaceType);
} }
@Nullable
public static String checkFunctionalInterface(PsiAnnotation annotation) {
if (PsiUtil.isLanguageLevel8OrHigher(annotation) && Comparing.strEqual(annotation.getQualifiedName(), JAVA_LANG_FUNCTIONAL_INTERFACE)) {
final PsiAnnotationOwner owner = annotation.getOwner();
if (owner instanceof PsiModifierList) {
final PsiElement parent = ((PsiModifierList)owner).getParent();
if (parent instanceof PsiClass) {
return LambdaHighlightingUtil.checkInterfaceFunctional((PsiClass)parent);
}
}
}
return null;
}
static class TypeParamsChecker extends PsiTypeVisitor<Boolean> { static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
private PsiMethod myMethod; private PsiMethod myMethod;
private final PsiClass myClass; private final PsiClass myClass;

View File

@@ -0,0 +1,5 @@
<error descr="Multiple non-overriding abstract methods found">@FunctionalInterface</error>
interface Test {
void foo();
void bar();
}

View File

@@ -200,6 +200,10 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest(true); doTest(true);
} }
public void testFunctionalInterfaceAnnotation() throws Exception {
doTest();
}
private void doTest() throws Exception { private void doTest() throws Exception {
doTest(false); doTest(false);
} }

Binary file not shown.