JetRunConfigurationProducer: J2K
This commit is contained in:
committed by
Nikolay Krasko
parent
3ca30af615
commit
9d650b6154
@@ -391,7 +391,7 @@
|
|||||||
<configurationType implementation="org.jetbrains.kotlin.idea.run.JetRunConfigurationType"/>
|
<configurationType implementation="org.jetbrains.kotlin.idea.run.JetRunConfigurationType"/>
|
||||||
<configurationType implementation="org.jetbrains.kotlin.idea.k2jsrun.K2JSRunConfigurationType"/>
|
<configurationType implementation="org.jetbrains.kotlin.idea.k2jsrun.K2JSRunConfigurationType"/>
|
||||||
<programRunner implementation="org.jetbrains.kotlin.idea.k2jsrun.K2JSBrowserProgramRunner"/>
|
<programRunner implementation="org.jetbrains.kotlin.idea.k2jsrun.K2JSBrowserProgramRunner"/>
|
||||||
<configurationProducer implementation="org.jetbrains.kotlin.idea.run.JetRunConfigurationProducer"/>
|
<configurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer"/>
|
||||||
<codeInsight.lineMarkerProvider language="jet" implementationClass="org.jetbrains.kotlin.idea.highlighter.markers.KotlinLineMarkerProvider"/>
|
<codeInsight.lineMarkerProvider language="jet" implementationClass="org.jetbrains.kotlin.idea.highlighter.markers.KotlinLineMarkerProvider"/>
|
||||||
<codeInsight.lineMarkerProvider language="jet" implementationClass="org.jetbrains.kotlin.idea.highlighter.KotlinRecursiveCallLineMarkerProvider"/>
|
<codeInsight.lineMarkerProvider language="jet" implementationClass="org.jetbrains.kotlin.idea.highlighter.KotlinRecursiveCallLineMarkerProvider"/>
|
||||||
<codeInsight.lineMarkerProvider language="JAVA"
|
<codeInsight.lineMarkerProvider language="JAVA"
|
||||||
|
|||||||
@@ -14,157 +14,125 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.run;
|
package org.jetbrains.kotlin.idea.run
|
||||||
|
|
||||||
import com.intellij.execution.Location;
|
import com.intellij.execution.Location
|
||||||
import com.intellij.execution.RunnerAndConfigurationSettings;
|
import com.intellij.execution.RunnerAndConfigurationSettings
|
||||||
import com.intellij.execution.actions.ConfigurationContext;
|
import com.intellij.execution.actions.ConfigurationContext
|
||||||
import com.intellij.execution.junit.RuntimeConfigurationProducer;
|
import com.intellij.execution.junit.RuntimeConfigurationProducer
|
||||||
import com.intellij.openapi.module.Module;
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.project.DumbService;
|
import com.intellij.openapi.project.DumbService
|
||||||
import com.intellij.openapi.util.Comparing;
|
import com.intellij.openapi.util.Comparing
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.impl.ElementBase
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.util.NotNullFunction;
|
import com.intellij.util.NotNullFunction
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.MainFunctionDetector;
|
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade;
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
||||||
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil;
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil;
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
|
||||||
import org.jetbrains.kotlin.psi.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
public class KotlinRunConfigurationProducer : RuntimeConfigurationProducer(JetRunConfigurationType.getInstance()), Cloneable {
|
||||||
|
override fun clone(): KotlinRunConfigurationProducer {
|
||||||
import static kotlin.KotlinPackage.singleOrNull;
|
return super<RuntimeConfigurationProducer>.clone() as KotlinRunConfigurationProducer
|
||||||
|
|
||||||
public class JetRunConfigurationProducer extends RuntimeConfigurationProducer implements Cloneable {
|
|
||||||
@Nullable
|
|
||||||
private PsiElement mySourceElement;
|
|
||||||
|
|
||||||
public JetRunConfigurationProducer() {
|
|
||||||
super(JetRunConfigurationType.getInstance());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private var mySourceElement: PsiElement? = null
|
||||||
@Override
|
|
||||||
public PsiElement getSourceElement() {
|
override fun getSourceElement(): PsiElement? {
|
||||||
return mySourceElement;
|
return mySourceElement
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun createConfigurationByElement(location: Location<*>, configurationContext: ConfigurationContext): RunnerAndConfigurationSettings? {
|
||||||
protected RunnerAndConfigurationSettings createConfigurationByElement(@NotNull Location location, ConfigurationContext configurationContext) {
|
val container = getEntryPointContainer(location) ?: return null
|
||||||
JetDeclarationContainer container = getEntryPointContainer(location);
|
|
||||||
if (container == null) return null;
|
|
||||||
|
|
||||||
mySourceElement = (PsiElement) container;
|
mySourceElement = container as PsiElement?
|
||||||
|
|
||||||
FqName startClassFQName = getStartClassFqName(container);
|
val startClassFQName = getStartClassFqName(container)
|
||||||
if (startClassFQName == null) return null;
|
if (startClassFQName == null) return null
|
||||||
|
|
||||||
Module module = location.getModule();
|
val module = location.getModule()
|
||||||
assert module != null;
|
assert(module != null)
|
||||||
|
|
||||||
return createConfigurationByQName(module, configurationContext, startClassFQName);
|
return createConfigurationByQName(module, configurationContext, startClassFQName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private fun getStartClassFqName(container: JetDeclarationContainer?): FqName? {
|
||||||
private static FqName getStartClassFqName(@Nullable JetDeclarationContainer container) {
|
if (container == null) return null
|
||||||
if (container == null) return null;
|
if (container is JetFile) return PackageClassUtils.getPackageClassFqName((container as JetFile?).getPackageFqName())
|
||||||
if (container instanceof JetFile) return PackageClassUtils.getPackageClassFqName(((JetFile) container).getPackageFqName());
|
if (container is JetClassOrObject) {
|
||||||
if (container instanceof JetClassOrObject) {
|
if (container is JetObjectDeclaration && container.isCompanion()) {
|
||||||
JetClassOrObject classOrObject = (JetClassOrObject) container;
|
val containerClass = PsiTreeUtil.getParentOfType<JetClass>(container, javaClass<JetClass>())
|
||||||
if (classOrObject instanceof JetObjectDeclaration && ((JetObjectDeclaration) classOrObject).isCompanion()) {
|
return containerClass?.getFqName()
|
||||||
classOrObject = PsiTreeUtil.getParentOfType(classOrObject, JetClass.class);
|
|
||||||
}
|
}
|
||||||
return classOrObject != null ? classOrObject.getFqName() : null;
|
return container?.getFqName()
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Invalid entry-point container: " + ((PsiElement) container).getText());
|
throw IllegalArgumentException("Invalid entry-point container: " + (container as PsiElement?).getText())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
private fun getEntryPointContainer(location: Location<*>): JetDeclarationContainer? {
|
||||||
private static JetDeclarationContainer getEntryPointContainer(@NotNull Location location) {
|
if (DumbService.getInstance(location.getProject()).isDumb()) return null
|
||||||
if (DumbService.getInstance(location.getProject()).isDumb()) return null;
|
|
||||||
|
|
||||||
Module module = location.getModule();
|
val module = location.getModule() ?: return null
|
||||||
if (module == null) return null;
|
|
||||||
|
|
||||||
if (ProjectStructureUtil.isJsKotlinModule(module)) return null;
|
if (ProjectStructureUtil.isJsKotlinModule(module)) return null
|
||||||
|
|
||||||
PsiElement locationElement = location.getPsiElement();
|
val locationElement = location.getPsiElement()
|
||||||
|
|
||||||
PsiFile psiFile = locationElement.getContainingFile();
|
val psiFile = locationElement.getContainingFile()
|
||||||
if (!(psiFile instanceof JetFile && ProjectRootsUtil.isInProjectOrLibSource(psiFile))) return null;
|
if (!(psiFile is JetFile && ProjectRootsUtil.isInProjectOrLibSource(psiFile))) return null
|
||||||
|
|
||||||
JetFile jetFile = (JetFile) psiFile;
|
val resolutionFacade = psiFile.getResolutionFacade()
|
||||||
final ResolutionFacade resolutionFacade = ResolvePackage.getResolutionFacade(jetFile);
|
val mainFunctionDetector = MainFunctionDetector(object : NotNullFunction<JetNamedFunction, FunctionDescriptor> {
|
||||||
MainFunctionDetector mainFunctionDetector = new MainFunctionDetector(
|
override fun `fun`(function: JetNamedFunction): FunctionDescriptor {
|
||||||
new NotNullFunction<JetNamedFunction, FunctionDescriptor>() {
|
return resolutionFacade.resolveToDescriptor(function) as FunctionDescriptor
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public FunctionDescriptor fun(JetNamedFunction function) {
|
|
||||||
return (FunctionDescriptor) resolutionFacade.resolveToDescriptor(function);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (JetDeclarationContainer currentElement = PsiTreeUtil.getNonStrictParentOfType(locationElement, JetClassOrObject.class,
|
|
||||||
JetFile.class);
|
|
||||||
currentElement != null;
|
|
||||||
currentElement = PsiTreeUtil.getParentOfType((PsiElement) currentElement, JetClassOrObject.class, JetFile.class)) {
|
|
||||||
JetDeclarationContainer entryPointContainer = currentElement;
|
|
||||||
if (entryPointContainer instanceof JetClass) {
|
|
||||||
entryPointContainer = singleOrNull(((JetClass) currentElement).getCompanionObjects());
|
|
||||||
}
|
}
|
||||||
if (entryPointContainer != null && mainFunctionDetector.hasMain(entryPointContainer.getDeclarations())) return entryPointContainer;
|
})
|
||||||
|
|
||||||
|
var currentElement = PsiTreeUtil.getNonStrictParentOfType<PsiElement>(locationElement, javaClass<JetClassOrObject>(), javaClass<JetFile>()) as JetDeclarationContainer
|
||||||
|
while (currentElement != null) {
|
||||||
|
var entryPointContainer = currentElement
|
||||||
|
if (entryPointContainer is JetClass) {
|
||||||
|
entryPointContainer = entryPointContainer.getCompanionObjects().singleOrNull() as JetDeclarationContainer
|
||||||
|
}
|
||||||
|
if (entryPointContainer != null && mainFunctionDetector.hasMain(entryPointContainer.getDeclarations())) return entryPointContainer
|
||||||
|
currentElement = PsiTreeUtil.getParentOfType<PsiElement>(currentElement as PsiElement?, javaClass<JetClassOrObject>(), javaClass<JetFile>()) as JetDeclarationContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private fun createConfigurationByQName(module: Module, context: ConfigurationContext, fqName: FqName): RunnerAndConfigurationSettings {
|
||||||
private RunnerAndConfigurationSettings createConfigurationByQName(
|
val settings = cloneTemplateConfiguration(module.getProject(), context)
|
||||||
@NotNull Module module,
|
val configuration = settings.getConfiguration() as JetRunConfiguration
|
||||||
ConfigurationContext context,
|
configuration.setModule(module)
|
||||||
@NotNull FqName fqName
|
configuration.setName(StringUtil.trimEnd(fqName.asString(), "." + PackageClassUtils.getPackageClassName(fqName)))
|
||||||
) {
|
configuration.setRunClass(fqName.asString())
|
||||||
RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(module.getProject(), context);
|
return settings
|
||||||
JetRunConfiguration configuration = (JetRunConfiguration) settings.getConfiguration();
|
|
||||||
configuration.setModule(module);
|
|
||||||
configuration.setName(StringUtil.trimEnd(fqName.asString(), "." + PackageClassUtils.getPackageClassName(fqName)));
|
|
||||||
configuration.setRunClass(fqName.asString());
|
|
||||||
return settings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun findExistingByElement(location: Location<*>?, existingConfigurations: List<RunnerAndConfigurationSettings>, context: ConfigurationContext?): RunnerAndConfigurationSettings? {
|
||||||
protected RunnerAndConfigurationSettings findExistingByElement(
|
val startClassFQName = getStartClassFqName(getEntryPointContainer(location)) ?: return null
|
||||||
Location location,
|
|
||||||
@NotNull List<RunnerAndConfigurationSettings> existingConfigurations,
|
|
||||||
ConfigurationContext context
|
|
||||||
) {
|
|
||||||
FqName startClassFQName = getStartClassFqName(getEntryPointContainer(location));
|
|
||||||
if (startClassFQName == null) return null;
|
|
||||||
|
|
||||||
for (RunnerAndConfigurationSettings existingConfiguration : existingConfigurations) {
|
for (existingConfiguration in existingConfigurations) {
|
||||||
if (existingConfiguration.getType() instanceof JetRunConfigurationType) {
|
if (existingConfiguration.getType() is JetRunConfigurationType) {
|
||||||
JetRunConfiguration jetConfiguration = (JetRunConfiguration)existingConfiguration.getConfiguration();
|
val jetConfiguration = existingConfiguration.getConfiguration() as JetRunConfiguration
|
||||||
if (Comparing.equal(jetConfiguration.getRunClass(), startClassFQName.asString())) {
|
if (Comparing.equal(jetConfiguration.getRunClass(), startClassFQName.asString())) {
|
||||||
if (Comparing.equal(location.getModule(), jetConfiguration.getConfigurationModule().getModule())) {
|
if (Comparing.equal<Module>(location!!.getModule(), jetConfiguration.getConfigurationModule().getModule())) {
|
||||||
return existingConfiguration;
|
return existingConfiguration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun compareTo(o: Any?): Int {
|
||||||
public int compareTo(Object o) {
|
return RuntimeConfigurationProducer.PREFERED
|
||||||
return PREFERED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user