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 eb5ff19c098c..06a12b9e8ad3 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
@@ -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;
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 02004e79246f..22d246ffba94 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
@@ -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));
+ }
}
/**
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/CallConstructorWithPreviewFeature.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/CallConstructorWithPreviewFeature.java
index b6d0c16ab3b5..f0d16e38cfff 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/CallConstructorWithPreviewFeature.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/CallConstructorWithPreviewFeature.java
@@ -15,9 +15,19 @@ class Main {
new Main(42l);
new Main("42");
new Main(42);
- new org.myorg.preview.FromPreview() {
+ new org.myorg.preview.FromPreview() {
public void g(){}
- };
+ };
+ new NotDirectlyAnnotatedConstructor();
+ new DirectlyAnnotatedConstructor();
}
}
+
+@PreviewFeature(feature=Feature.TEXT_BLOCKS)
+class NotDirectlyAnnotatedConstructor { }
+
+class DirectlyAnnotatedConstructor {
+ @PreviewFeature(feature=Feature.TEXT_BLOCKS)
+ DirectlyAnnotatedConstructor() {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/CallMethodsWithPreviewFeature.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/CallMethodsWithPreviewFeature.java
index 8682e4b1dbda..e3b779af2956 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/CallMethodsWithPreviewFeature.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/CallMethodsWithPreviewFeature.java
@@ -1,11 +1,15 @@
import jdk.internal.PreviewFeature;
import jdk.internal.PreviewFeature.Feature;
+import org.myorg.preview.FromPreview;
class Main {
static {
requirePatternMatching();
Main.requireTextBlocks();
new Main().requireRecords();
+ final NotDirectlyAnnotatedMethod a = new NotDirectlyAnnotatedMethod();
+ a.f();
+ NotDirectlyAnnotatedMethod.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(){}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/ClassImplementsWithPreviewFeature.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/ClassImplementsWithPreviewFeature.java
new file mode 100644
index 000000000000..6aad1e999aa0
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/ClassImplementsWithPreviewFeature.java
@@ -0,0 +1,11 @@
+import jdk.internal.PreviewFeature;
+import jdk.internal.PreviewFeature.Feature;
+import org.myorg.preview.FromPreview;
+
+class Custom1 implements org.myorg.preview.FromPreview {
+ public void g() {}
+}
+
+class Custom2 implements FromPreview {
+ public void g() {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/FieldsWithPreviewFeature.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/FieldsWithPreviewFeature.java
index 3953efbf7e34..330c2225303a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/FieldsWithPreviewFeature.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/FieldsWithPreviewFeature.java
@@ -18,5 +18,13 @@ class Main {
int k = new Main().i;
org.myorg.preview.FromPreview local = null;
}
+ void f(NotDirectlyAnnotatedField a) {
+ a.id = 0;
+ }
}
+
+@PreviewFeature(feature=Feature.TEXT_BLOCKS)
+class NotDirectlyAnnotatedField {
+ int id;
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/ImportWithPreviewFeature.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/ImportWithPreviewFeature.java
index 4f7bbb53d072..9e6aec0b9dca 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/ImportWithPreviewFeature.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/ImportWithPreviewFeature.java
@@ -1,6 +1,6 @@
-import org.myorg.preview.FromPreview;
-import static org.myorg.preview.FromPreview.f;
-import static org.myorg.preview.FromPreview.*;
+import org.myorg.preview.FromPreview;
+import static org.myorg.preview.FromPreview.f;
+import static org.myorg.preview.FromPreview.*;
class Main {
static {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/MethodReferenceWithPreviewFeature.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/MethodReferenceWithPreviewFeature.java
new file mode 100644
index 000000000000..4c53135b182d
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/MethodReferenceWithPreviewFeature.java
@@ -0,0 +1,10 @@
+import org.myorg.preview.FromPreview;
+
+class Main {
+ static {
+ Runnable r = FromPreview::f;
+ }
+ void f(FromPreview fp) {
+ Runnable r = fp::g;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/RequiresModuleWithPreviewFeature.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/RequiresModuleWithPreviewFeature.java
index 1adb941ef95e..de7bd0db1cc8 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/RequiresModuleWithPreviewFeature.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/RequiresModuleWithPreviewFeature.java
@@ -1,5 +1,5 @@
module consumer {
requires producer;
- provides org.myorg.preview.FromPreview with org.myorg.preview.impl.FromPreviewImpl;
+ provides org.myorg.preview.FromPreview with org.myorg.preview.impl.FromPreviewImpl;
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/packagepreview/FromPreview.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/packagepreview/FromPreview.java
index 593e6c475fa9..1288fd517dd2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/packagepreview/FromPreview.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/previewfeature/packagepreview/FromPreview.java
@@ -1,6 +1,6 @@
package org.myorg.preview;
public interface FromPreview {
- static void f();
+ static void f() {};
void g();
}
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/previewfeature/PreviewFeatureAnnotationTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/previewfeature/PreviewFeatureAnnotationTest.java
index b6c1d7b3347d..1eae8135bdbc 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/previewfeature/PreviewFeatureAnnotationTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/previewfeature/PreviewFeatureAnnotationTest.java
@@ -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";