mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
[java, complete, import-module] Complete the name of the current module for Module Import Declarations IDEA-355531
GitOrigin-RevId: c3eb0b36ebb8b221d6484ee4fd26927c19571464
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a75d78bf10
commit
013eb83aa8
@@ -551,7 +551,7 @@ public final class JavaCompletionContributor extends CompletionContributor imple
|
||||
}
|
||||
|
||||
if (!smart && parent instanceof PsiJavaModuleReferenceElement) {
|
||||
addModuleReferences(parent, parameters.getOriginalFile(), result);
|
||||
addModuleReferences(parent, position, parameters.getOriginalFile(), result);
|
||||
}
|
||||
|
||||
if (JavaPatternCompletionUtil.insideDeconstructionList(parameters.getPosition())) {
|
||||
@@ -1384,7 +1384,7 @@ public final class JavaCompletionContributor extends CompletionContributor imple
|
||||
return added[0];
|
||||
}
|
||||
|
||||
private static void addModuleReferences(PsiElement moduleRef, PsiFile originalFile, CompletionResultSet result) {
|
||||
private static void addModuleReferences(PsiElement moduleRef, PsiElement position, PsiFile originalFile, CompletionResultSet result) {
|
||||
PsiElement statement = moduleRef.getParent();
|
||||
boolean withAutoModules;
|
||||
if ((withAutoModules = statement instanceof PsiRequiresStatement || statement instanceof PsiImportModuleStatement) || statement instanceof PsiPackageAccessibilityStatement) {
|
||||
@@ -1392,11 +1392,24 @@ public final class JavaCompletionContributor extends CompletionContributor imple
|
||||
if (parent != null) {
|
||||
Project project = moduleRef.getProject();
|
||||
Set<String> filter = new HashSet<>();
|
||||
if (parent instanceof PsiJavaModule psiJavaModule) {
|
||||
filter.add(psiJavaModule.getName());
|
||||
} else {
|
||||
PsiJavaModule psiJavaModule = JavaModuleGraphHelper.getInstance().findDescriptorByElement(originalFile);
|
||||
if (psiJavaModule != null) filter.add(psiJavaModule.getName());
|
||||
Function<PsiJavaModule, String> getModuleName = psiJavaModule -> {
|
||||
if (psiJavaModule == null) return null;
|
||||
return psiJavaModule.getName();
|
||||
};
|
||||
String currentJavaModuleName = getModuleName.apply(PsiTreeUtil.getParentOfType(statement, PsiJavaModule.class));
|
||||
if (currentJavaModuleName == null) currentJavaModuleName = getModuleName.apply(JavaModuleGraphHelper.getInstance().findDescriptorByElement(originalFile));
|
||||
if (currentJavaModuleName == null) currentJavaModuleName = findModuleName(originalFile, position);
|
||||
|
||||
if (currentJavaModuleName != null) {
|
||||
// "importing a module declaration" can declare its own module.
|
||||
if (statement instanceof PsiImportModuleStatement) {
|
||||
LookupElement lookup = TailTypeDecorator.withTail(LookupElementBuilder.create(currentJavaModuleName)
|
||||
.withIcon(AllIcons.Nodes.JavaModule),
|
||||
TailTypes.semicolonType());
|
||||
result.addElement(lookup);
|
||||
}
|
||||
|
||||
filter.add(currentJavaModuleName);
|
||||
}
|
||||
|
||||
JavaModuleNameIndex index = JavaModuleNameIndex.getInstance();
|
||||
@@ -1443,6 +1456,43 @@ public final class JavaCompletionContributor extends CompletionContributor imple
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searching for a module name in a broken PsiFile when import module declaration typing before the module description.
|
||||
* <pre>{@code
|
||||
* import module current.<caret>
|
||||
* module current.module.name {
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param originalFile The module-info.java file
|
||||
* @param position the position within the file
|
||||
* @return The module name if found, otherwise null.
|
||||
*/
|
||||
private static @Nullable String findModuleName(@NotNull PsiFile originalFile, @NotNull PsiElement position) {
|
||||
if (!PsiJavaModule.MODULE_INFO_FILE.equals(originalFile.getName())) return null;
|
||||
if(!(position.getNode() instanceof PsiIdentifier intellijIdeaRulezzz)) return null;
|
||||
StringBuilder name = new StringBuilder();
|
||||
PsiElement cursor = intellijIdeaRulezzz;
|
||||
PsiElement prev = null;
|
||||
while ((cursor = cursor.getNextSibling()) != null) {
|
||||
if (cursor instanceof PsiErrorElement) {
|
||||
name.setLength(0);
|
||||
}
|
||||
else if (cursor instanceof PsiIdentifier && prev instanceof PsiIdentifier) {
|
||||
name.setLength(0);
|
||||
name.append(cursor.getText());
|
||||
}
|
||||
else if (!(cursor instanceof PsiWhiteSpace)){
|
||||
name.append(cursor.getText());
|
||||
}
|
||||
prev = cursor;
|
||||
}
|
||||
String result = name.toString();
|
||||
if (result.trim().isEmpty()) return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void addAutoModuleReference(String name, PsiElement parent, Set<? super String> filter, CompletionResultSet result) {
|
||||
if (PsiNameHelper.isValidModuleName(name, parent) && filter.add(name)) {
|
||||
LookupElement lookup = LookupElementBuilder.create(name).withIcon(AllIcons.FileTypes.Archive);
|
||||
|
||||
@@ -154,23 +154,59 @@ class ModuleCompletionTest : LightJava9ModulesCodeInsightFixtureTestCase() {
|
||||
""")
|
||||
|
||||
@NeedsIndex.Full
|
||||
fun testModuleImportDeclarationsBare() =
|
||||
fun testModuleImportDeclarationsBare() {
|
||||
addFile("module-info.java", "module current.module.name { }")
|
||||
fileVariants("Test.java", """
|
||||
import module <caret>
|
||||
class Test { }
|
||||
""".trimIndent(),
|
||||
"M2", "java.base", "java.non.root", "java.se", "java.xml.bind", "java.xml.ws",
|
||||
"lib.multi.release", "lib.named", "lib.auto", "lib.claimed", "all.fours", "lib.with.module.info")
|
||||
"lib.multi.release", "lib.named", "lib.auto", "lib.claimed", "all.fours", "lib.with.module.info", "current.module.name")
|
||||
}
|
||||
|
||||
@NeedsIndex.Full
|
||||
fun testModuleImportDeclarationsIgnoreCurrentModule() {
|
||||
fun testModuleImportDeclarationsUseOwnModule() {
|
||||
addFile("module-info.java", "module current.module.name { }")
|
||||
fileVariants("Test.java", """
|
||||
import module current<caret>
|
||||
class Test { }
|
||||
fileComplete("Test.java", """
|
||||
import module current.<caret>
|
||||
public class Test { }
|
||||
""".trimIndent(), """
|
||||
import module current.module.name;
|
||||
public class Test { }
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@NeedsIndex.Full
|
||||
fun testModuleImportDeclarationsUseOwnModule2() = complete("""
|
||||
import module current.<caret>
|
||||
module current.module.name { }
|
||||
""".trimIndent(), """
|
||||
import module current.module.name;
|
||||
module current.module.name { }
|
||||
""".trimIndent())
|
||||
|
||||
@NeedsIndex.Full
|
||||
fun testModuleImportDeclarationsUseOwnModule3() = complete("""
|
||||
import module curr<caret>
|
||||
module current
|
||||
.module .name { }
|
||||
""".trimIndent(), """
|
||||
import module current.module.name;
|
||||
module current
|
||||
.module .name { }
|
||||
""".trimIndent())
|
||||
|
||||
@NeedsIndex.Full
|
||||
fun testModuleImportDeclarationsUseOwnModule4() = complete("""
|
||||
import module curr<caret>
|
||||
import module java.base;
|
||||
module current.module.name { }
|
||||
""".trimIndent(), """
|
||||
import module current.module.name;
|
||||
import module java.base;
|
||||
module current.module.name { }
|
||||
""".trimIndent())
|
||||
|
||||
//<editor-fold desc="Helpers.">
|
||||
private fun complete(text: String, expected: String) = fileComplete("module-info.java", text, expected)
|
||||
private fun fileComplete(fileName: String, text: String, expected: String) {
|
||||
|
||||
@@ -63,8 +63,10 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() {
|
||||
|
||||
fun testModuleImportDeclarationUnresolvedModule() {
|
||||
IdeaTestUtil.withLevel(module, LanguageLevel.JDK_23_PREVIEW) {
|
||||
addFile("moodule-info.java", "module current.module.name {}");
|
||||
highlight("Test.java", """
|
||||
import module M2;
|
||||
import module current.module.name;
|
||||
import module <error descr="Module is not in dependencies: M3">M3</error>;
|
||||
import module <error descr="Module not found: M4">M4</error>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user