diff --git a/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties b/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties index b02475453732..aeb253b187f2 100644 --- a/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties +++ b/java/java-frontback-psi-api/resources/messages/JavaPsiBundle.properties @@ -121,6 +121,7 @@ feature.stream.gatherers=Stream Gatherers feature.foreign.functions=Foreign Function & Memory API feature.virtual.threads=Virtual Threads feature.statements.before.super=Statements before super() +feature.module.imports=Module imports else.without.if='else' without 'if' enum.constant.context=Enum constant ''{0}'' in ''{1}'' diff --git a/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java b/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java index cd86e717328e..7a601e76dcad 100644 --- a/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java +++ b/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java @@ -115,6 +115,8 @@ public enum JavaFeature { INHERITED_STATIC_MAIN_METHOD(LanguageLevel.JDK_22_PREVIEW, "feature.inherited.static.main.method"), IMPLICIT_IMPORT_IN_IMPLICIT_CLASSES(LanguageLevel.JDK_23_PREVIEW, "feature.implicit.import.in.implicit.classes"), PRIMITIVE_TYPES_IN_PATTERNS(LanguageLevel.JDK_23_PREVIEW, "feature.primitive.types.in.patterns"), + + MODULE_IMPORTS(LanguageLevel.JDK_23_PREVIEW, "feature.module.imports"), ; private final @NotNull LanguageLevel myLevel; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java index 32b23c06da3d..47a4be8dcb50 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java @@ -822,7 +822,7 @@ public class JavaKeywordCompletion { StreamEx.of(implicitClass.getChildren()).select(PsiMember.class).findFirst().orElse(null) == field; if (myPrevLeaf == null || bogusDeclarationInImplicitClass && file instanceof PsiJavaFile javaFile && javaFile.getPackageStatement() == null && - javaFile.getImportList() != null && javaFile.getImportList().getAllImportStatements().length == 0) { + javaFile.getImportList() != null && javaFile.getImportList().getAllImportDeclarations().length == 0) { addKeyword(new OverridableSpace(createKeyword(PsiKeyword.PACKAGE), TailTypes.humbleSpaceBeforeWordType())); addKeyword(new OverridableSpace(createKeyword(PsiKeyword.IMPORT), TailTypes.humbleSpaceBeforeWordType())); } @@ -838,6 +838,10 @@ public class JavaKeywordCompletion { if (PsiUtil.isAvailable(JavaFeature.STATIC_IMPORTS, file) && myPrevLeaf != null && myPrevLeaf.textMatches(PsiKeyword.IMPORT)) { addKeyword(new OverridableSpace(createKeyword(PsiKeyword.STATIC), TailTypes.humbleSpaceBeforeWordType())); } + + if (PsiUtil.isAvailable(JavaFeature.MODULE_IMPORTS, file) && myPrevLeaf != null && myPrevLeaf.textMatches(PsiKeyword.IMPORT)) { + addKeyword(new OverridableSpace(createKeyword(PsiKeyword.MODULE), TailTypes.humbleSpaceBeforeWordType())); + } } private void addInstanceof() { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java index 3bfc83745cee..88df41b45de7 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java @@ -884,7 +884,9 @@ public final class PsiImplUtil { List modules = new ArrayList<>(); // import module java.base; for implicit classes - if (PsiUtil.isAvailable(JavaFeature.IMPLICIT_IMPORT_IN_IMPLICIT_CLASSES, file) && file instanceof PsiJavaFile) { + if (PsiUtil.isAvailable(JavaFeature.IMPLICIT_IMPORT_IN_IMPLICIT_CLASSES, file) && + PsiUtil.isAvailable(JavaFeature.MODULE_IMPORTS, file) && + file instanceof PsiJavaFile) { PsiClass[] classes = ((PsiJavaFile)file).getClasses(); if (classes.length == 1 && classes[0] instanceof PsiImplicitClass) { modules.add(ImplicitlyImportedModule.create(JAVA_BASE)); diff --git a/java/java-tests/testData/codeInsight/completion/keywords/importModule.java b/java/java-tests/testData/codeInsight/completion/keywords/importModule.java new file mode 100644 index 000000000000..584e5b98c13c --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/keywords/importModule.java @@ -0,0 +1 @@ +import \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java index cc7e4a4f5db7..b507562f4456 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.java.codeInsight.completion; import com.intellij.JavaTestUtil; @@ -186,6 +186,11 @@ public class KeywordCompletionTest extends LightCompletionTestCase { public void testNoClassKeywordsInFieldArrayInitializer() { doTest(0, "class", "interface", "enum"); } public void testImportStatic() { doTest(1, "static"); } + + public void testImportModule() { + setLanguageLevel(JavaFeature.MODULE_IMPORTS.getMinimumLevel()); + doTest(2, "static", "module"); + } public void testAbstractInInterface() { doTest(1, "abstract"); } public void testCharInAnnotatedParameter() { doTest(1, "char"); } public void testReturnInTernary() { doTest(1, "return"); }