Skip to content

Commit

Permalink
Fix launch configuration for main in companion and top-level objects
Browse files Browse the repository at this point in the history
 #KT-10233 Fixed
  • Loading branch information
zarechenskiy committed Feb 26, 2016
1 parent 2585918 commit d7b882e
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 140 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -66,17 +65,6 @@ public class ProjectUtils {
public static final String KT_HOME = getKtHome();


public static IFile findFilesWithMain(Collection<IFile> files) {
for (IFile file : files) {
KtFile jetFile = KotlinPsiManager.INSTANCE.getParsedFile(file);
if (JetMainDetector.hasMain(jetFile.getDeclarations())) {
return file;
}
}

return null;
}

public static IJavaProject getJavaProjectFromCollection(Collection<IFile> files) {
IJavaProject javaProject = null;
for (IFile file : files) {
Expand All @@ -87,10 +75,6 @@ public static IJavaProject getJavaProjectFromCollection(Collection<IFile> files)
return javaProject;
}

public static boolean hasMain(IFile file) {
return findFilesWithMain(Arrays.asList(file)) != null;
}

@Nullable
public static String getPackageByFile(IFile file) {
KtFile jetFile = KotlinPsiManager.INSTANCE.getParsedFile(file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,40 @@

public class KotlinLaunchTest extends KotlinLaunchTestCase {

private static final String SOURCE_CODE = "fun main(args : Array<String>) { print(\"ok\") }";
private static final String MAIN_FUNCTION = "fun main(args : Array<String>) { print(\"ok\") }";

@Test
public void launchSimpleProject() {
doTest(SOURCE_CODE, "test_project", "org.jet.pckg", null);
doTest(MAIN_FUNCTION, "test_project", "org.jet.pckg", null);
}

@Test
public void launchWhenProjectNameHaveSpace() {
doTest(SOURCE_CODE, "test project", "pckg", null);
doTest(MAIN_FUNCTION, "test project", "pckg", null);
}

@Test
public void launchWithTwoSourceFolders() {
doTest(SOURCE_CODE, "testProject", "pckg", "src2");
doTest(MAIN_FUNCTION, "testProject", "pckg", "src2");
}

@Test
public void launchWhenSourceFolderHaveSpace() {
doTest(SOURCE_CODE, "testProject", "pckg", "src directory");
doTest(MAIN_FUNCTION, "testProject", "pckg", "src directory");
}

@Test
public void launchFileWithJvmNameAnnotation() {
doTest("@file:JvmName(\"some\") " + SOURCE_CODE, "testProject", "some.pckg", null);
doTest("@file:JvmName(\"some\") " + MAIN_FUNCTION, "testProject", "some.pckg", null);
}

@Test
public void launchMainFromObject() {
doTest("object SomeObj { @JvmStatic " + MAIN_FUNCTION + " }", "testProject", "pckg", null);
}

@Test
public void launchMainFromCompanionObject() {
doTest("class SomeClass { companion object { @JvmStatic " + MAIN_FUNCTION + " } }", "testProject", "pckg", null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import org.eclipse.ui.console.IConsoleManager
import org.jetbrains.kotlin.core.log.KotlinLogger
import org.jetbrains.kotlin.testframework.editor.KotlinEditorTestCase
import org.jetbrains.kotlin.ui.launch.KotlinLaunchShortcut
import org.jetbrains.kotlin.ui.launch.getEntryPoint
import org.junit.Assert
import org.eclipse.core.runtime.NullProgressMonitor
import org.jetbrains.kotlin.testframework.utils.KotlinTestUtils
Expand Down Expand Up @@ -74,7 +75,8 @@ abstract class KotlinLaunchTestCase : KotlinEditorTestCase() {

var launch: ILaunch? = null
try {
val launchConfiguration = KotlinLaunchShortcut.createConfiguration(testEditor.getEditingFile())
val entryPoint = getEntryPoint(getEditor().parsedFile!!, getEditor().javaProject!!)
val launchConfiguration = KotlinLaunchShortcut.createConfiguration(entryPoint!!, testEditor.getEclipseProject())
launch = DebugUIPlugin.buildAndLaunch(launchConfiguration, "run", NullProgressMonitor())

synchronized (launch) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -43,13 +43,18 @@ import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.ui.editors.KotlinFileEditor
import org.eclipse.jdt.core.JavaCore
import org.jetbrains.kotlin.psi.KtDeclaration

class KotlinLaunchShortcut : ILaunchShortcut {
companion object {
fun createConfiguration(file: IFile): ILaunchConfiguration {
val configWC = getLaunchConfigurationType().newInstance(null, "Config - " + file.getName())
configWC.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, getFileClassName(file).asString())
configWC.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, file.getProject().getName())
fun createConfiguration(entryPoint: KtDeclaration, project: IProject): ILaunchConfiguration? {
val classFqName = getStartClassFqName(entryPoint)
if (classFqName == null) return null

val configWC = getLaunchConfigurationType().newInstance(null, "Config - " + entryPoint.getContainingKtFile().getName())
configWC.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, classFqName.asString())
configWC.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName())

return configWC.doSave()
}
Expand All @@ -75,50 +80,59 @@ class KotlinLaunchShortcut : ILaunchShortcut {
}
}

val fileWithMain = ProjectUtils.findFilesWithMain(files)
if (fileWithMain != null) {
launchWithMainClass(fileWithMain, mode)
return
}
if (files.isEmpty()) return

launchProject(files[0].getProject(), mode)
val mainFile = files.first()
val javaProject = JavaCore.create(mainFile.getProject())
val ktFile = KotlinPsiManager.INSTANCE.getParsedFile(mainFile)
val entryPoint = getEntryPoint(ktFile, javaProject)
if (entryPoint != null) {
launchWithMainClass(entryPoint, javaProject.project, mode)
}
}

override fun launch(editor: IEditorPart, mode: String) {
if (editor !is KotlinFileEditor) return

val file = EditorUtil.getFile(editor)
val file = editor.getFile()
if (file == null) {
KotlinLogger.logError("Failed to retrieve IFile from editor " + editor, null)
return
}

if (ProjectUtils.hasMain(file)) {
launchWithMainClass(file, mode)
val parsedFile = editor.parsedFile
if (parsedFile == null) return

val javaProject = editor.javaProject
if (javaProject == null) return

val entryPoint = getEntryPoint(parsedFile, javaProject)
if (entryPoint != null) {
launchWithMainClass(entryPoint, javaProject.project, mode)
return
}

launchProject(file.getProject(), mode)
}

private fun launchProject(project: IProject, mode: String) {
val fileWithMain = ProjectUtils.findFilesWithMain(KotlinPsiManager.INSTANCE.getFilesByProject(project))
if (fileWithMain != null) {
launchWithMainClass(fileWithMain, mode)
private fun launchWithMainClass(entryPoint: KtDeclaration, project: IProject, mode: String) {
val configuration = findLaunchConfiguration(getLaunchConfigurationType(), entryPoint, project) ?:
createConfiguration(entryPoint, project)

if (configuration != null) {
DebugUITools.launch(configuration, mode)
}
}

private fun launchWithMainClass(fileWithMain: IFile, mode: String) {
val configuration = findLaunchConfiguration(getLaunchConfigurationType(), fileWithMain) ?: createConfiguration(fileWithMain)
DebugUITools.launch(configuration, mode)
}

private fun findLaunchConfiguration(configurationType: ILaunchConfigurationType, mainClass: IFile): ILaunchConfiguration? {
private fun findLaunchConfiguration(
configurationType: ILaunchConfigurationType,
entryPoint: KtDeclaration,
project: IProject): ILaunchConfiguration? {
val configs = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations(configurationType)
val mainClassName = getFileClassName(mainClass).asString()
val mainClassName = getStartClassFqName(entryPoint)?.asString()
if (mainClassName == null) return null

for (config in configs) {
if (config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, null as String?) == mainClassName &&
config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, null as String?) == mainClass.project.name) {
config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, null as String?) == project.name) {
return config
}
}
Expand Down
Loading

0 comments on commit d7b882e

Please sign in to comment.