Remove as33 bunches specific to mpp run configs
It is now compatible with 182 branch
This commit is contained in:
-127
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.platform.impl
|
||||
|
||||
import com.intellij.execution.PsiLocation
|
||||
import com.intellij.execution.actions.ConfigurationContext
|
||||
import com.intellij.execution.actions.RunConfigurationProducer
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.gradle.KotlinPlatform
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.JsAnalyzerFacade
|
||||
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder
|
||||
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription
|
||||
import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil
|
||||
import org.jetbrains.kotlin.idea.highlighter.KotlinTestRunLineMarkerContributor.Companion.getTestStateIcon
|
||||
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
|
||||
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
|
||||
import org.jetbrains.kotlin.idea.util.string.joinWithEscape
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import javax.swing.Icon
|
||||
|
||||
class JsIdePlatformKindTooling : IdePlatformKindTooling() {
|
||||
companion object {
|
||||
private const val MAVEN_OLD_JS_STDLIB_ID = "kotlin-js-library"
|
||||
|
||||
private val TEST_FQ_NAME = FqName("kotlin.test.Test")
|
||||
private val IGNORE_FQ_NAME = FqName("kotlin.test.Ignore")
|
||||
}
|
||||
|
||||
override val kind = JsIdePlatformKind
|
||||
|
||||
override fun compilerArgumentsForProject(project: Project) = Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings
|
||||
|
||||
override val resolverForModuleFactory = JsAnalyzerFacade
|
||||
|
||||
override val mavenLibraryIds = listOf(PathUtil.JS_LIB_NAME, MAVEN_OLD_JS_STDLIB_ID)
|
||||
override val gradlePluginId = "kotlin-platform-js"
|
||||
override val gradlePlatformIds: List<KotlinPlatform> get() = listOf(KotlinPlatform.JS)
|
||||
|
||||
override val libraryKind = JSLibraryKind
|
||||
override fun getLibraryDescription(project: Project) = JSLibraryStdDescription(project)
|
||||
|
||||
override fun getLibraryVersionProvider(project: Project) = { library: Library ->
|
||||
JsLibraryStdDetectionUtil.getJsLibraryStdVersion(library, project)
|
||||
}
|
||||
|
||||
override fun getTestIcon(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor): Icon? {
|
||||
if (!descriptor.isTest()) return null
|
||||
|
||||
val contexts by lazy { computeConfigurationContexts(declaration) }
|
||||
|
||||
val runConfigData = RunConfigurationProducer
|
||||
.getProducers(declaration.project)
|
||||
.asSequence()
|
||||
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
|
||||
.filter { it.isForTests }
|
||||
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
|
||||
.firstOrNull { it != null } ?: return null
|
||||
|
||||
val locations = ArrayList<String>()
|
||||
|
||||
locations += FileUtil.toSystemDependentName(runConfigData.jsOutputFilePath)
|
||||
|
||||
val klass = when (declaration) {
|
||||
is KtClassOrObject -> declaration
|
||||
is KtNamedFunction -> declaration.containingClassOrObject ?: return null
|
||||
else -> return null
|
||||
}
|
||||
locations += klass.parentsWithSelf.filterIsInstance<KtNamedDeclaration>().mapNotNull { it.name }.toList().asReversed()
|
||||
|
||||
val testName = (declaration as? KtNamedFunction)?.name
|
||||
if (testName != null) {
|
||||
locations += "$testName"
|
||||
}
|
||||
|
||||
val prefix = if (testName != null) "test://" else "suite://"
|
||||
|
||||
val url = prefix + locations.joinWithEscape('.')
|
||||
|
||||
return getTestStateIcon(url, declaration.project)
|
||||
}
|
||||
|
||||
override fun acceptsAsEntryPoint(function: KtFunction): Boolean {
|
||||
val contexts by lazy { computeConfigurationContexts(function) }
|
||||
|
||||
return RunConfigurationProducer
|
||||
.getProducers(function.project)
|
||||
.asSequence()
|
||||
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
|
||||
.filter { !it.isForTests }
|
||||
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
|
||||
.any { it != null }
|
||||
}
|
||||
|
||||
private fun computeConfigurationContexts(declaration: KtNamedDeclaration): Sequence<ConfigurationContext> {
|
||||
return sequenceOf(ConfigurationContext(declaration))
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.isIgnored(): Boolean =
|
||||
annotations.any { it.fqName == IGNORE_FQ_NAME } || ((containingDeclaration as? ClassDescriptor)?.isIgnored() ?: false)
|
||||
|
||||
private fun DeclarationDescriptor.isTest(): Boolean {
|
||||
if (isIgnored()) return false
|
||||
|
||||
if (annotations.any { it.fqName == TEST_FQ_NAME }) return true
|
||||
if (this is ClassDescriptorWithResolutionScopes) {
|
||||
return declaredCallableMembers.any { it.isTest() }
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
-180
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-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/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.run
|
||||
|
||||
import com.intellij.execution.*
|
||||
import com.intellij.execution.actions.ConfigurationContext
|
||||
import com.intellij.execution.actions.ConfigurationFromContext
|
||||
import com.intellij.execution.actions.RunConfigurationProducer
|
||||
import com.intellij.execution.configurations.ModuleBasedConfiguration
|
||||
import com.intellij.execution.junit.*
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.idea.util.module
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
|
||||
class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfiguration>(JUnitConfigurationType.getInstance()) {
|
||||
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
||||
return other.isProducedBy(JUnitConfigurationProducer::class.java) || other.isProducedBy(PatternConfigurationProducer::class.java)
|
||||
}
|
||||
|
||||
override fun isConfigurationFromContext(
|
||||
configuration: JUnitConfiguration,
|
||||
context: ConfigurationContext
|
||||
): Boolean {
|
||||
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
|
||||
return false
|
||||
}
|
||||
|
||||
val leaf = context.location?.psiElement ?: return false
|
||||
val methodLocation = getTestMethodLocation(leaf)
|
||||
val testClass = getTestClass(leaf)
|
||||
val testObject = configuration.testObject
|
||||
|
||||
if (!testObject.isConfiguredByElement(configuration, testClass, methodLocation?.psiElement, null, null)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return settingsMatchTemplate(configuration, context)
|
||||
}
|
||||
|
||||
// copied from JUnitConfigurationProducer in IDEA
|
||||
private fun settingsMatchTemplate(configuration: JUnitConfiguration, context: ConfigurationContext): Boolean {
|
||||
val predefinedConfiguration = context.getOriginalConfiguration(JUnitConfigurationType.getInstance())
|
||||
|
||||
val vmParameters = (predefinedConfiguration as? CommonJavaRunConfigurationParameters)?.vmParameters
|
||||
if (vmParameters != null && configuration.vmParameters != vmParameters) return false
|
||||
|
||||
val template = RunManager.getInstance(configuration.project).getConfigurationTemplate(configurationFactory)
|
||||
val predefinedModule = (template.configuration as ModuleBasedConfiguration<*>).configurationModule.module
|
||||
val configurationModule = configuration.configurationModule.module
|
||||
return configurationModule == context.location?.module || configurationModule == predefinedModule
|
||||
}
|
||||
|
||||
override fun setupConfigurationFromContext(
|
||||
configuration: JUnitConfiguration,
|
||||
context: ConfigurationContext,
|
||||
sourceElement: Ref<PsiElement>
|
||||
): Boolean {
|
||||
if (DumbService.getInstance(context.project).isDumb) return false
|
||||
|
||||
val location = context.location ?: return false
|
||||
val leaf = location.psiElement
|
||||
|
||||
if (!ProjectRootsUtil.isInProjectOrLibSource(leaf)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (leaf.containingFile !is KtFile) {
|
||||
return false
|
||||
}
|
||||
|
||||
val ktFile = leaf.containingFile as KtFile
|
||||
|
||||
val targetPlatform = TargetPlatformDetector.getPlatform(ktFile)
|
||||
if (targetPlatform != JvmPlatform && targetPlatform != TargetPlatform.Common) {
|
||||
return false
|
||||
}
|
||||
|
||||
val methodLocation = getTestMethodLocation(leaf)
|
||||
if (methodLocation != null) {
|
||||
val originalModule = configuration.configurationModule.module
|
||||
configuration.beMethodConfiguration(methodLocation)
|
||||
configuration.restoreOriginalModule(originalModule)
|
||||
JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
|
||||
fixJdkForCommonModule(ktFile, configuration)
|
||||
return true
|
||||
}
|
||||
|
||||
val testClass = getTestClass(leaf)
|
||||
if (testClass != null) {
|
||||
val originalModule = configuration.configurationModule.module
|
||||
configuration.beClassConfiguration(testClass)
|
||||
configuration.restoreOriginalModule(originalModule)
|
||||
JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
|
||||
fixJdkForCommonModule(ktFile, configuration)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun fixJdkForCommonModule(ktFile: KtFile, configuration: JUnitConfiguration) {
|
||||
val implModule = ktFile.module?.findJvmImplementationModule() ?: return
|
||||
val sdk = ModuleRootManager.getInstance(implModule).sdk
|
||||
if (sdk != null) {
|
||||
configuration.setModule(implModule)
|
||||
configuration.isAlternativeJrePathEnabled = true
|
||||
configuration.alternativeJrePath = sdk.homePath
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
|
||||
val leaf = fromContext.sourceElement
|
||||
getTestClass(leaf)?.let { testClass ->
|
||||
val fromContextSubstitute = object : ConfigurationFromContext() {
|
||||
override fun getConfigurationSettings() = fromContext.configurationSettings
|
||||
|
||||
override fun setConfigurationSettings(configurationSettings: RunnerAndConfigurationSettings) {
|
||||
fromContext.configurationSettings = configurationSettings
|
||||
}
|
||||
|
||||
override fun getSourceElement() = testClass
|
||||
}
|
||||
// TODO: use TestClassConfigurationProducer when constructor becomes public
|
||||
return object : AbstractTestClassConfigurationProducer(JUnitConfigurationType.getInstance()){}
|
||||
.onFirstRun(fromContextSubstitute, context, performRunnable)
|
||||
}
|
||||
|
||||
super.onFirstRun(fromContext, context, performRunnable)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getTestClass(leaf: PsiElement): PsiClass? {
|
||||
val containingFile = leaf.containingFile as? KtFile ?: return null
|
||||
var ktClass = leaf.getParentOfType<KtClass>(false)
|
||||
if (!ktClass.isJUnitTestClass()) {
|
||||
ktClass = getTestClassInFile(containingFile)
|
||||
}
|
||||
return ktClass?.toLightClass()
|
||||
}
|
||||
|
||||
fun getTestMethodLocation(leaf: PsiElement): Location<PsiMethod>? {
|
||||
val function = leaf.getParentOfType<KtNamedFunction>(false) ?: return null
|
||||
val owner = PsiTreeUtil.getParentOfType(function, KtFunction::class.java, KtClass::class.java)
|
||||
|
||||
if (owner is KtClass) {
|
||||
val delegate = owner.toLightClass() ?: return null
|
||||
val method = delegate.methods.firstOrNull() { it.navigationElement == function } ?: return null
|
||||
val methodLocation = PsiLocation.fromPsiElement(method)
|
||||
if (JUnitUtil.isTestMethod(methodLocation, false)) {
|
||||
return methodLocation
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun KtClass?.isJUnitTestClass() =
|
||||
this?.toLightClass()?.let { JUnitUtil.isTestClass(it, false, true) } ?: false
|
||||
|
||||
private fun getTestClassInFile(ktFile: KtFile) =
|
||||
ktFile.declarations.filterIsInstance<KtClass>().singleOrNull { it.isJUnitTestClass() }
|
||||
}
|
||||
}
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.run
|
||||
|
||||
import com.intellij.execution.Location
|
||||
import com.intellij.execution.actions.ConfigurationContext
|
||||
import com.intellij.execution.actions.RunConfigurationProducer
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.ClassUtil
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.idea.caches.project.implementingModules
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.project.platform
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.platform.impl.isCommon
|
||||
import org.jetbrains.kotlin.platform.impl.isJvm
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class KotlinRunConfigurationProducer : RunConfigurationProducer<KotlinRunConfiguration>(KotlinRunConfigurationType.getInstance()) {
|
||||
|
||||
override fun setupConfigurationFromContext(configuration: KotlinRunConfiguration,
|
||||
context: ConfigurationContext,
|
||||
sourceElement: Ref<PsiElement>): Boolean {
|
||||
val location = context.location ?: return false
|
||||
val module = location.module ?: return false
|
||||
val container = getEntryPointContainer(location)
|
||||
val startClassFQName = getStartClassFqName(container) ?: return false
|
||||
|
||||
configuration.setModule(module)
|
||||
configuration.runClass = startClassFQName
|
||||
configuration.setGeneratedName()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getEntryPointContainer(location: Location<*>?): KtDeclarationContainer? {
|
||||
if (location == null) return null
|
||||
if (DumbService.getInstance(location.project).isDumb) return null
|
||||
|
||||
val module = location.module ?: return null
|
||||
|
||||
if (TargetPlatformDetector.getPlatform(module) !is JvmPlatform && module.findJvmImplementationModule() == null) {
|
||||
return null
|
||||
}
|
||||
val locationElement = location.psiElement
|
||||
|
||||
return getEntryPointContainer(locationElement)
|
||||
}
|
||||
|
||||
override fun isConfigurationFromContext(configuration: KotlinRunConfiguration, context: ConfigurationContext): Boolean {
|
||||
val startClassFQName = getStartClassFqName(getEntryPointContainer(context.location)) ?: return false
|
||||
|
||||
return configuration.runClass == startClassFQName &&
|
||||
context.module == configuration.configurationModule.module
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getEntryPointContainer(locationElement: PsiElement): KtDeclarationContainer? {
|
||||
val psiFile = locationElement.containingFile
|
||||
if (!(psiFile is KtFile && ProjectRootsUtil.isInProjectOrLibSource(psiFile))) return null
|
||||
|
||||
val mainFunctionDetector =
|
||||
MainFunctionDetector(psiFile.languageVersionSettings) { it.resolveToDescriptorIfAny(BodyResolveMode.FULL) }
|
||||
|
||||
var currentElement = locationElement.declarationContainer(false)
|
||||
while (currentElement != null) {
|
||||
var entryPointContainer = currentElement
|
||||
if (entryPointContainer is KtClass) {
|
||||
entryPointContainer = entryPointContainer.companionObjects.singleOrNull()
|
||||
}
|
||||
if (entryPointContainer != null && mainFunctionDetector.hasMain(entryPointContainer.declarations)) return entryPointContainer
|
||||
currentElement = (currentElement as PsiElement).declarationContainer(true)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun getStartClassFqName(container: KtDeclarationContainer?): String? = when(container) {
|
||||
null -> null
|
||||
is KtFile -> container.javaFileFacadeFqName.asString()
|
||||
is KtClassOrObject -> {
|
||||
if (!container.isValid) {
|
||||
null
|
||||
}
|
||||
else if (container is KtObjectDeclaration && container.isCompanion()) {
|
||||
val containerClass = container.getParentOfType<KtClass>(true)
|
||||
containerClass?.toLightClass()?.let { ClassUtil.getJVMClassName(it) }
|
||||
}
|
||||
else {
|
||||
container.toLightClass()?.let { ClassUtil.getJVMClassName(it) }
|
||||
}
|
||||
}
|
||||
else -> throw IllegalArgumentException("Invalid entry-point container: " + (container as PsiElement).text)
|
||||
}
|
||||
|
||||
private fun PsiElement.declarationContainer(strict: Boolean): KtDeclarationContainer? {
|
||||
val element = if (strict)
|
||||
PsiTreeUtil.getParentOfType(this, KtClassOrObject::class.java, KtFile::class.java)
|
||||
else
|
||||
PsiTreeUtil.getNonStrictParentOfType(this, KtClassOrObject::class.java, KtFile::class.java)
|
||||
return element as KtDeclarationContainer?
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun Module.findJvmImplementationModule(): Module? {
|
||||
if (!platform.isCommon) return null
|
||||
return implementingModules.firstOrNull { it.platform.isJvm }
|
||||
}
|
||||
Reference in New Issue
Block a user