Run configurations with module path for Java 9 named modules (KT-19886)

#KT-19886 Fixed

(cherry picked from commit 1e12828)
This commit is contained in:
Nikolay Krasko
2017-09-27 18:32:34 +03:00
parent 166682937f
commit 4cdd4c04a3
8 changed files with 67 additions and 9 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.run; package org.jetbrains.kotlin.idea.run;
import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil;
import com.intellij.diagnostic.logging.LogConfigurationPanel; import com.intellij.diagnostic.logging.LogConfigurationPanel;
import com.intellij.execution.*; import com.intellij.execution.*;
import com.intellij.execution.application.BaseJavaApplicationCommandLineState; import com.intellij.execution.application.BaseJavaApplicationCommandLineState;
@@ -30,19 +31,20 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.options.SettingsEditorGroup; import com.intellij.openapi.options.SettingsEditorGroup;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass; import com.intellij.psi.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.listeners.RefactoringElementAdapter; import com.intellij.refactoring.listeners.RefactoringElementAdapter;
import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.util.PathsList;
import kotlin.collections.ArraysKt; import kotlin.collections.ArraysKt;
import kotlin.collections.CollectionsKt; import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function1;
@@ -62,7 +64,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import java.util.*; import java.util.*;
public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurationModule> public class JetRunConfiguration extends ModuleBasedConfiguration<JavaRunConfigurationModule>
implements CommonJavaRunConfigurationParameters, RefactoringListenerProvider { implements CommonJavaRunConfigurationParameters, RefactoringListenerProvider {
public String MAIN_CLASS_NAME; public String MAIN_CLASS_NAME;
@@ -75,7 +77,7 @@ public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurati
private Map<String, String> myEnvs = new LinkedHashMap<String, String>(); private Map<String, String> myEnvs = new LinkedHashMap<String, String>();
public boolean PASS_PARENT_ENVS = true; public boolean PASS_PARENT_ENVS = true;
public JetRunConfiguration(String name, RunConfigurationModule runConfigurationModule, ConfigurationFactory factory) { public JetRunConfiguration(String name, JavaRunConfigurationModule runConfigurationModule, ConfigurationFactory factory) {
super(name, runConfigurationModule, factory); super(name, runConfigurationModule, factory);
runConfigurationModule.init(); runConfigurationModule.init();
} }
@@ -343,7 +345,7 @@ public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurati
@Override @Override
protected JavaParameters createJavaParameters() throws ExecutionException { protected JavaParameters createJavaParameters() throws ExecutionException {
JavaParameters params = new JavaParameters(); JavaParameters params = new JavaParameters();
RunConfigurationModule module = myConfiguration.getConfigurationModule(); JavaRunConfigurationModule module = myConfiguration.getConfigurationModule();
int classPathType = getClasspathType(module); int classPathType = getClasspathType(module);
@@ -352,6 +354,7 @@ public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurati
setupJavaParameters(params); setupJavaParameters(params);
params.setMainClass(myConfiguration.getRunClass()); params.setMainClass(myConfiguration.getRunClass());
setupModulePath(params, module);
return params; return params;
} }
@@ -402,5 +405,20 @@ public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurati
} }
return String.format("Top-level function 'main' not found in package '%s'", classFqName.parent()); return String.format("Top-level function 'main' not found in package '%s'", classFqName.parent());
} }
private static void setupModulePath(JavaParameters params, JavaRunConfigurationModule module) {
if (JavaSdkUtil.isJdkAtLeast(params.getJdk(), JavaSdkVersion.JDK_1_9)) {
PsiJavaModule mainModule = DumbService.getInstance(module.getProject()).computeWithAlternativeResolveEnabled(
() -> JavaModuleGraphUtil.findDescriptorByElement(module.findClass(params.getMainClass())));
if (mainModule != null) {
params.setModuleName(mainModule.getName());
PathsList classPath = params.getClassPath();
PathsList modulePath = params.getModulePath();
modulePath.addAll(classPath.getPathList());
classPath.clear();
}
}
}
} }
} }
@@ -37,9 +37,10 @@ public class JetRunConfigurationType extends ConfigurationTypeBase {
super(type); super(type);
} }
@NotNull
@Override @Override
public RunConfiguration createTemplateConfiguration(Project project) { public RunConfiguration createTemplateConfiguration(@NotNull Project project) {
return new JetRunConfiguration("", new RunConfigurationModule(project), this); return new JetRunConfiguration("", new JavaRunConfigurationModule(project, true), this);
} }
} }
} }
@@ -0,0 +1,4 @@
package some
fun main(args: Array<String>) {
}
@@ -0,0 +1,3 @@
module MAIN {
requires kotlin.stdlib;
}
@@ -0,0 +1,4 @@
package some
fun main(args: Array<String>) {
}
@@ -0,0 +1,3 @@
module MAIN {
requires kotlin.stdlib;
}
@@ -0,0 +1,4 @@
package some
fun main(args: Array<String>) {
}
@@ -166,6 +166,27 @@ class RunConfigurationTest: KotlinCodeInsightTestCase() {
Assert.assertEquals("afterRenameTest.Foo", runConfiguration.MAIN_CLASS_NAME) Assert.assertEquals("afterRenameTest.Foo", runConfiguration.MAIN_CLASS_NAME)
} }
fun testWithModuleForJdk6() {
checkModuleInfoName(null, PluginTestCaseBase.mockJdk())
}
fun testWithModuleForJdk9() {
checkModuleInfoName("MAIN", PluginTestCaseBase.mockJdk9())
}
fun testWithModuleForJdk9WithoutModuleInfo() {
checkModuleInfoName(null, PluginTestCaseBase.mockJdk9())
}
private fun checkModuleInfoName(moduleName: String?, sdk: Sdk) {
val module = configureModule(moduleDirPath("module"), getTestProject().baseDir!!).module
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(module, sdk)
val javaParameters = getJavaRunParameters(createConfigurationFromMain("some.main"))
Assert.assertEquals(moduleName, javaParameters.moduleName)
}
private fun doTest(configureRuntime: (Module, Sdk) -> Unit) { private fun doTest(configureRuntime: (Module, Sdk) -> Unit) {
val baseDir = getTestProject().baseDir!! val baseDir = getTestProject().baseDir!!
val createModuleResult = configureModule(moduleDirPath("module"), baseDir) val createModuleResult = configureModule(moduleDirPath("module"), baseDir)