[codeInsight] IDEA-244252 IDEA shows no error for @PreviewFeature

This patch fixes the problems with reporting errors when:

- a class that is annotated with PreviewFeature instantiated;
- a method that is annotated with PreviewFeature used in a method reference;
- a class or an interface that is annotated with PreviewFeature is inherited

Signed-off-by: Nikita Eshkeev <nikita.eshkeev@jetbrains.com>

GitOrigin-RevId: 586caeddae4446ad398878e0bd4bf66858e4518c
This commit is contained in:
Nikita Eshkeev
2020-06-30 17:07:59 +00:00
committed by intellij-monorepo-bot
parent 17c57985d4
commit 4d0743574a
11 changed files with 70 additions and 7 deletions
@@ -18,6 +18,7 @@ import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
import com.intellij.codeInspection.LocalQuickFixOnPsiElementAsIntentionAdapter;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.lang.findUsages.LanguageFindUsages;
import com.intellij.lang.jvm.JvmModifier;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.EffectiveLanguageLevelUtil;
import com.intellij.openapi.module.Module;
@@ -1625,6 +1626,11 @@ public final class HighlightUtil {
final PsiAnnotation annotation = owner.getAnnotation(HighlightingFeature.JDK_INTERNAL_PREVIEW_FEATURE);
if (annotation != null) return annotation;
if (!(owner instanceof PsiClass) || !owner.hasModifier(JvmModifier.STATIC)) {
final PsiAnnotation result = getPreviewFeatureAnnotation(PsiTreeUtil.getParentOfType(owner, PsiClass.class));
if (result != null) return result;
}
final PsiPackage psiPackage = JavaResolveUtil.getContainingPackage(owner);
if (psiPackage == null) return null;
@@ -1177,6 +1177,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (result != null) {
PsiElement resolved = result.getElement();
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkRawOnParameterizedType(ref, resolved));
if (!myHolder.hasErrorResults() && resolved instanceof PsiModifierListOwner) {
myHolder.add(HighlightUtil.checkPreviewFeatureElement(ref, (PsiModifierListOwner)resolved, myLanguageLevel));
}
}
}
@@ -1615,6 +1618,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
myHolder.add(info);
}
}
if (!myHolder.hasErrorResults() && method instanceof PsiModifierListOwner) {
myHolder.add(HighlightUtil.checkPreviewFeatureElement(expression, (PsiModifierListOwner)method, myLanguageLevel));
}
}
/**
@@ -15,9 +15,19 @@ class Main {
<error descr="Records are not supported at language level '9'">new Main(42l)</error>;
<error descr="Text block literals are not supported at language level '9'">new Main("42")</error>;
new Main(42);
<error descr="Patterns in 'instanceof' are not supported at language level '9'">new org.myorg.preview.FromPreview() {
new <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error>() {
public void g(){}
}</error>;
};
new <error descr="Text block literals are not supported at language level '9'">NotDirectlyAnnotatedConstructor</error>();
<error descr="Text block literals are not supported at language level '9'">new DirectlyAnnotatedConstructor()</error>;
}
}
@PreviewFeature(feature=Feature.TEXT_BLOCKS)
class NotDirectlyAnnotatedConstructor { }
class DirectlyAnnotatedConstructor {
@PreviewFeature(feature=Feature.TEXT_BLOCKS)
DirectlyAnnotatedConstructor() {}
}
@@ -1,11 +1,15 @@
import jdk.internal.PreviewFeature;
import jdk.internal.PreviewFeature.Feature;
import <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error>;
class Main {
static {
<error descr="Patterns in 'instanceof' are not supported at language level '9'">requirePatternMatching</error>();
<error descr="Text block literals are not supported at language level '9'">Main.requireTextBlocks</error>();
<error descr="Records are not supported at language level '9'">new Main().requireRecords</error>();
final <error descr="Text block literals are not supported at language level '9'">NotDirectlyAnnotatedMethod</error> a = new <error descr="Text block literals are not supported at language level '9'">NotDirectlyAnnotatedMethod</error>();
<error descr="Text block literals are not supported at language level '9'">a.f</error>();
<error descr="Text block literals are not supported at language level '9'">NotDirectlyAnnotatedMethod</error>.g();
}
@PreviewFeature(feature=Feature.PATTERN_MATCHING_IN_INSTANCEOF)
@@ -18,3 +22,9 @@ class Main {
void requireRecords(){}
}
@PreviewFeature(feature=Feature.TEXT_BLOCKS)
class NotDirectlyAnnotatedMethod {
void f(){}
static void g(){}
}
@@ -0,0 +1,11 @@
import jdk.internal.PreviewFeature;
import jdk.internal.PreviewFeature.Feature;
import <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error>;
class Custom1 implements <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error> {
public void g() {}
}
class Custom2 implements <error descr="Patterns in 'instanceof' are not supported at language level '9'">FromPreview</error> {
public void g() {}
}
@@ -18,5 +18,13 @@ class Main {
int k = new Main().i;
<error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error> local = null;
}
void f(<error descr="Text block literals are not supported at language level '9'">NotDirectlyAnnotatedField</error> a) {
<error descr="Text block literals are not supported at language level '9'">a.id</error> = 0;
}
}
@PreviewFeature(feature=Feature.TEXT_BLOCKS)
class NotDirectlyAnnotatedField {
int id;
}
@@ -1,6 +1,6 @@
<error descr="Patterns in 'instanceof' are not supported at language level '9'">import org.myorg.preview.FromPreview;</error>
<error descr="Patterns in 'instanceof' are not supported at language level '9'">import static org.myorg.preview.FromPreview.f;</error>
<error descr="Patterns in 'instanceof' are not supported at language level '9'">import static org.myorg.preview.FromPreview.*;</error>
import <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error>;
import static <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error>.f;
import static <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error>.*;
class Main {
static {
@@ -0,0 +1,10 @@
import <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error>;
class Main {
static {
Runnable r = <error descr="Patterns in 'instanceof' are not supported at language level '9'">FromPreview</error>::f;
}
void f(<error descr="Patterns in 'instanceof' are not supported at language level '9'">FromPreview</error> fp) {
Runnable r = <error descr="Patterns in 'instanceof' are not supported at language level '9'">fp::g</error>;
}
}
@@ -1,5 +1,5 @@
module consumer {
<error descr="Text block literals are not supported at language level '9'">requires producer;</error>
<error descr="Patterns in 'instanceof' are not supported at language level '9'">provides org.myorg.preview.FromPreview with org.myorg.preview.impl.FromPreviewImpl;</error>
provides <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.FromPreview</error> with <error descr="Patterns in 'instanceof' are not supported at language level '9'">org.myorg.preview.impl.FromPreviewImpl</error>;
}
@@ -1,6 +1,6 @@
package org.myorg.preview;
public interface FromPreview {
static void f();
static void f() {};
void g();
}
@@ -41,6 +41,8 @@ public class PreviewFeatureAnnotationTest extends LightJavaCodeInsightFixtureTes
public void testImportWithPreviewFeature() { doTest(); }
public void testReferenceWithPreviewFeature() { doTest(); }
public void testRequiresModuleWithPreviewFeature() { doTest(); }
public void testMethodReferenceWithPreviewFeature() { doTest(); }
public void testClassImplementsWithPreviewFeature() { doTest(); }
private void doTest() {
String filePath = BASE_PATH + "/" + getTestName(false) + ".java";