JetRunConfigurationProducer: J2K

This commit is contained in:
Dmitry Jemerov
2015-07-02 17:18:20 +02:00
committed by Nikolay Krasko
parent 3ca30af615
commit 9d650b6154
2 changed files with 85 additions and 117 deletions
+1 -1
View File
@@ -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;
} }
} }