From 2fcfda59c09144dfb0fee6b63a924a86e6e69854 Mon Sep 17 00:00:00 2001
From: Aleksey Dobrynin
Date: Fri, 16 Feb 2024 10:56:00 +0100
Subject: [PATCH] [java, fix] handle invalid module names
GitOrigin-RevId: 2b2a88ae4536a47376ee5e9d21d418c7165e4d69
---
.../impl/analysis/JavaModuleGraphUtil.java | 3 +-
.../ide/actions/CreateModuleInfoAction.java | 9 ++++--
.../psi/impl/light/LightJavaModule.java | 6 ++--
.../invalidLibraryName/after/.idea/misc.xml | 6 ++++
.../after/.idea/modules.xml | 8 +++++
.../invalidLibraryName/after/main.iml | 29 ++++++++++++++++++
.../after/test/MainTest.java | 9 ++++++
.../after/test/module-info.java | 3 ++
.../invalidLibraryName/before/.idea/misc.xml | 6 ++++
.../before/.idea/modules.xml | 8 +++++
.../invalidLibraryName/before/main.iml | 29 ++++++++++++++++++
.../before/test/MainTest.java | 9 ++++++
.../before/test/module-info.java | 2 ++
.../emptyModuleInfoFile/lib/lib-for-test.jar | Bin 0 -> 732 bytes
...JavaEmptyModuleInfoFileInspectionTest.java | 6 +++-
.../ide/actions/CreateModuleInfoActionTest.kt | 24 +++++++++++++--
.../impl/light/JavaModuleNameDetectionTest.kt | 5 ++-
17 files changed, 150 insertions(+), 12 deletions(-)
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/.idea/misc.xml
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/.idea/modules.xml
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/main.iml
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/test/MainTest.java
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/test/module-info.java
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/.idea/misc.xml
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/.idea/modules.xml
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/main.iml
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/test/MainTest.java
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/test/module-info.java
create mode 100644 java/java-tests/testData/inspection/emptyModuleInfoFile/lib/lib-for-test.jar
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java
index 462abf70f99d..78f8dfdbd597 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java
@@ -99,7 +99,7 @@ public final class JavaModuleGraphUtil {
return CachedValuesManager.getCachedValue(rootPsi, () -> {
VirtualFile _root = rootPsi.getVirtualFile();
LightJavaModule result = LightJavaModule.create(rootPsi.getManager(), _root, LightJavaModule.moduleName(_root));
- return Result.create(result, _root, ProjectRootModificationTracker.getInstance(rootPsi.getProject()));
+ return Result.create(result, _root, ProjectRootModificationTracker.getInstance(rootPsi.getProject()));
});
}
}
@@ -249,6 +249,7 @@ public final class JavaModuleGraphUtil {
@Nullable DependencyScope scope) {
if (to.getName().equals(JAVA_BASE)) return false;
if (!PsiUtil.isAvailable(JavaFeature.MODULES, from)) return false;
+ if (!PsiNameHelper.isValidModuleName(to.getName(), to)) return false;
if (alreadyContainsRequires(from, to.getName())) return false;
PsiUtil.addModuleStatement(from, PsiKeyword.REQUIRES + " " +
(isStaticModule(to.getName(), scope) ? PsiKeyword.STATIC + " " : "") +
diff --git a/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java b/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java
index 540e9bfdea0a..607f39d2df1e 100644
--- a/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java
+++ b/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2021 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.
package com.intellij.ide.actions;
import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil;
@@ -18,6 +18,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.JavaFeature;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiNameHelper;
import com.intellij.psi.impl.light.LightJavaModule;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
@@ -32,6 +33,8 @@ import static com.intellij.ide.fileTemplates.JavaTemplateUtil.INTERNAL_MODULE_IN
import static com.intellij.psi.PsiJavaModule.MODULE_INFO_CLASS;
public class CreateModuleInfoAction extends CreateFromTemplateActionBase {
+ private static final String DEFAULT_MODULE_NAME = "module_name";
+
public CreateModuleInfoAction() {
super(JavaBundle.messagePointer("action.create.new.module-info.title"), JavaBundle.messagePointer("action.create.new.module-info.description"), AllIcons.FileTypes.Java);
}
@@ -86,6 +89,8 @@ public class CreateModuleInfoAction extends CreateFromTemplateActionBase {
@Override
protected Map getLiveTemplateDefaults(@NotNull DataContext ctx, @NotNull PsiFile file) {
Module module = PlatformCoreDataKeys.MODULE.getData(ctx);
- return Collections.singletonMap("MODULE_NAME", module != null ? LightJavaModule.moduleName(module.getName()) : "module_name");
+ String moduleName = module != null ? LightJavaModule.moduleName(module.getName()) : DEFAULT_MODULE_NAME;
+ moduleName = PsiNameHelper.isValidModuleName(moduleName, file) ? moduleName : DEFAULT_MODULE_NAME;
+ return Collections.singletonMap("MODULE_NAME", moduleName);
}
}
\ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightJavaModule.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightJavaModule.java
index 56aa29fb3775..1b32ec64ba0d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightJavaModule.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightJavaModule.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.impl.light;
import com.intellij.lang.java.JavaLanguage;
@@ -254,7 +254,7 @@ public final class LightJavaModule extends LightElement implements PsiJavaModule
public static @Nullable String claimedModuleName(@NotNull VirtualFile manifest) {
try (InputStream stream = manifest.getInputStream()) {
- return new Manifest(stream).getMainAttributes().getValue(PsiJavaModule.AUTO_MODULE_NAME);
+ return new Manifest(stream).getMainAttributes().getValue(AUTO_MODULE_NAME);
}
catch (IOException e) {
Logger.getInstance(LightJavaModule.class).warn(manifest.getPath(), e);
@@ -274,7 +274,7 @@ public final class LightJavaModule extends LightElement implements PsiJavaModule
* Implements a name deriving for automatic modules as described in ModuleFinder.of(Path...) method documentation.
*
* Please note that the result may not be a valid module name when the source contains a sequence that starts with a digit
- * (e.g. "org.7gnomes..."). One may validate the result with {@link PsiNameHelper#isValidModuleName}.
+ * (e.g. "org.7gnomes...", "module.for...."). One may validate the result with {@link PsiNameHelper#isValidModuleName}.
*
* @param name a .jar file name without the extension
* @see ModuleFinder.of(Path...)
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/.idea/misc.xml b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/.idea/misc.xml
new file mode 100644
index 000000000000..07115cdf15dd
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/.idea/modules.xml b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/.idea/modules.xml
new file mode 100644
index 000000000000..122a9054e101
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/main.iml b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/main.iml
new file mode 100644
index 000000000000..10ee07cacd4b
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/main.iml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/test/MainTest.java b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/test/MainTest.java
new file mode 100644
index 000000000000..9ad4a2508071
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/test/MainTest.java
@@ -0,0 +1,9 @@
+import org.jetbrains.org.jetbrains.intellij.java.test.library.*;
+import l.InLib;
+
+public class MainTest {
+ public static void main(String[] args) {
+ System.out.println(Util.name());
+ System.out.println(InLib.class);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/test/module-info.java b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/test/module-info.java
new file mode 100644
index 000000000000..f09df9a06253
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/after/test/module-info.java
@@ -0,0 +1,3 @@
+module main {
+ requires intellij.java.test.library;
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/.idea/misc.xml b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/.idea/misc.xml
new file mode 100644
index 000000000000..07115cdf15dd
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/.idea/modules.xml b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/.idea/modules.xml
new file mode 100644
index 000000000000..122a9054e101
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/main.iml b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/main.iml
new file mode 100644
index 000000000000..10ee07cacd4b
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/main.iml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/test/MainTest.java b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/test/MainTest.java
new file mode 100644
index 000000000000..9ad4a2508071
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/test/MainTest.java
@@ -0,0 +1,9 @@
+import org.jetbrains.org.jetbrains.intellij.java.test.library.*;
+import l.InLib;
+
+public class MainTest {
+ public static void main(String[] args) {
+ System.out.println(Util.name());
+ System.out.println(InLib.class);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/test/module-info.java b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/test/module-info.java
new file mode 100644
index 000000000000..2bae5daaa7ad
--- /dev/null
+++ b/java/java-tests/testData/inspection/emptyModuleInfoFile/invalidLibraryName/before/test/module-info.java
@@ -0,0 +1,2 @@
+module main {
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/emptyModuleInfoFile/lib/lib-for-test.jar b/java/java-tests/testData/inspection/emptyModuleInfoFile/lib/lib-for-test.jar
new file mode 100644
index 0000000000000000000000000000000000000000..5b7ca99b6ad69ce11c225121a9837800dbc19ae0
GIT binary patch
literal 732
zcmWIWW@Zs#-~hscNHJ3eB*4kQ!r%LW
z$)nOUG&5MHKhyk?rY8PWJX~!0l4oMt70*;(XMQUBSi}f+h~J~Rr`&m_W+bP+?
zO5jXt*_4*J6+t^S*H1k2UCC?4m%}<@Cmo-7{g#?_H1aOTS_95&nJX4a9=w~HDtCJ7
zrRwdACU@`P=2z2c3RdUbx6D!LQt*aeJtIAXhJ*88D&_TUzV)W*6!WzooK+tZ4kT{X
zezEA}tG~<{8?QfqtM&9RI9#fw;?M5|`sxc12Y53wi7=qXFD&vv@rw%J5eABFbgjt2
z4T@a^umv*VT9M)!WC9lh?r1@na16)Bm;2DsaqmLA60p6@^AZZpL
Ld;z5IF@ksi()7NY
literal 0
HcmV?d00001
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/java19api/JavaEmptyModuleInfoFileInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/java19api/JavaEmptyModuleInfoFileInspectionTest.java
index 629b92fe086e..d4376a142dff 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInspection/java19api/JavaEmptyModuleInfoFileInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/java19api/JavaEmptyModuleInfoFileInspectionTest.java
@@ -55,6 +55,10 @@ public class JavaEmptyModuleInfoFileInspectionTest extends LightMultiFileTestCas
doTest("test/module-info.java");
}
+ public void testInvalidLibraryName() {
+ doTest("test/module-info.java");
+ }
+
public void testMultiModuleProject() {
doTest("src/module-info.java", "main/");
}
@@ -76,6 +80,6 @@ public class JavaEmptyModuleInfoFileInspectionTest extends LightMultiFileTestCas
myFixture.launchAction(intention);
NonBlockingReadActionImpl.waitForAsyncTaskCompletion();
}
- myFixture.checkResultByFile(getTestName(false) + "/after/" + dir + path);
+ myFixture.checkResultByFile(getTestName(true) + "/after/" + dir + path);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/java/ide/actions/CreateModuleInfoActionTest.kt b/java/java-tests/testSrc/com/intellij/java/ide/actions/CreateModuleInfoActionTest.kt
index 0b14e8e00ba4..889d1a96c5da 100644
--- a/java/java-tests/testSrc/com/intellij/java/ide/actions/CreateModuleInfoActionTest.kt
+++ b/java/java-tests/testSrc/com/intellij/java/ide/actions/CreateModuleInfoActionTest.kt
@@ -1,14 +1,16 @@
-// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.ide.actions
import com.intellij.ide.IdeView
import com.intellij.ide.fileTemplates.FileTemplateManager
import com.intellij.java.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase
+import com.intellij.java.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.M2
import com.intellij.java.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.MAIN
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.LangDataKeys
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys
+import com.intellij.openapi.module.ModuleManager
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiJavaModule
import com.intellij.psi.PsiManager
@@ -17,6 +19,24 @@ import com.intellij.testFramework.PlatformTestUtil
class CreateModuleInfoActionTest : LightJava9ModulesCodeInsightFixtureTestCase() {
fun test() {
+ val testModule = ModuleManager.getInstance(project).findModuleByName(M2.moduleName)!!
+ val dir = PsiManager.getInstance(project).findDirectory(M2.sourceRoot()!!)!!
+ val ctx = MapDataContext(mapOf(LangDataKeys.IDE_VIEW to TestIdeView(dir), PlatformCoreDataKeys.MODULE to testModule))
+ val event = AnActionEvent.createFromDataContext("", null, ctx)
+ ActionManager.getInstance().getAction("NewModuleInfo")!!.actionPerformed(event)
+
+ val file = dir.findFile(PsiJavaModule.MODULE_INFO_FILE)!!
+ val p = FileTemplateManager.getInstance(project).defaultProperties
+ assertEquals("""
+ /**
+ * Created by ${p["USER"]} on ${p["DATE"]}.
+ */
+ module light.idea.test.m2 {
+ }""".trimIndent(), file.text)
+ }
+
+ fun testNotValidName() {
+ module.name
val dir = PsiManager.getInstance(project).findDirectory(MAIN.sourceRoot()!!)!!
val ctx = MapDataContext(mapOf(LangDataKeys.IDE_VIEW to TestIdeView(dir), PlatformCoreDataKeys.MODULE to module))
val event = AnActionEvent.createFromDataContext("", null, ctx)
@@ -28,7 +48,7 @@ class CreateModuleInfoActionTest : LightJava9ModulesCodeInsightFixtureTestCase()
/**
* Created by ${p["USER"]} on ${p["DATE"]}.
*/
- module light.idea.test.case {
+ module module_name {
}""".trimIndent(), file.text)
}
diff --git a/java/java-tests/testSrc/com/intellij/java/psi/impl/light/JavaModuleNameDetectionTest.kt b/java/java-tests/testSrc/com/intellij/java/psi/impl/light/JavaModuleNameDetectionTest.kt
index f252904b72fb..cf1671adab12 100644
--- a/java/java-tests/testSrc/com/intellij/java/psi/impl/light/JavaModuleNameDetectionTest.kt
+++ b/java/java-tests/testSrc/com/intellij/java/psi/impl/light/JavaModuleNameDetectionTest.kt
@@ -1,6 +1,4 @@
-/*
- * Copyright 2000-2018 JetBrains s.r.o. 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.
package com.intellij.java.psi.impl.light
import com.intellij.psi.impl.light.LightJavaModule
@@ -15,6 +13,7 @@ class JavaModuleNameDetectionTest {
@Test fun collapsing() = doTest("foo...bar", "foo.bar")
@Test fun trimming() = doTest("...foo.bar...", "foo.bar")
@Test fun invalid() = doTest("lib_invalid_1_2", "lib.invalid.1.2")
+ @Test fun withKeywords() = doTest("lib.for.ide", "lib.for.ide")
private fun doTest(original: String, expected: String) = assertEquals(expected, LightJavaModule.moduleName(original))
}
\ No newline at end of file