diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt index e1ecc95e87b..2ee7e8bb67a 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt @@ -5,6 +5,8 @@ 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 @@ -21,6 +23,7 @@ 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.run.multiplatform.KotlinMultiplatformRunLocationsProvider import org.jetbrains.kotlin.idea.util.string.joinWithEscape import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind @@ -61,13 +64,15 @@ class JsIdePlatformKindTooling : IdePlatformKindTooling() { 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>() .filter { it.isForTests } - .mapNotNull { it.getConfigurationData(declaration) } - .firstOrNull() ?: return null + .flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } } + .firstOrNull { it != null } ?: return null val locations = ArrayList() @@ -93,13 +98,22 @@ class JsIdePlatformKindTooling : IdePlatformKindTooling() { } override fun acceptsAsEntryPoint(function: KtFunction): Boolean { + val contexts by lazy { computeConfigurationContexts(function) } + return RunConfigurationProducer .getProducers(function.project) .asSequence() .filterIsInstance>() .filter { !it.isForTests } - .mapNotNull { it.getConfigurationData(function) } - .firstOrNull() != null + .flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } } + .any { it != null } + } + + private fun computeConfigurationContexts(declaration: KtNamedDeclaration): Sequence { + val location = PsiLocation(declaration) + return KotlinMultiplatformRunLocationsProvider().getAlternativeLocations(location).map { + ConfigurationContext.createEmptyContextForLocation(it) + }.ifEmpty { listOf(ConfigurationContext.createEmptyContextForLocation(location)) }.asSequence() } private fun DeclarationDescriptor.isIgnored(): Boolean = diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt.181 b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt.181 new file mode 100644 index 00000000000..915a1aabbc9 --- /dev/null +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt.181 @@ -0,0 +1,127 @@ +/* + * 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 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>() + .filter { it.isForTests } + .flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } } + .firstOrNull { it != null } ?: return null + + val locations = ArrayList() + + 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().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>() + .filter { !it.isForTests } + .flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } } + .any { it != null } + } + + private fun computeConfigurationContexts(declaration: KtNamedDeclaration): Sequence { + 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 + } +} \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt.as33 b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt.as33 new file mode 100644 index 00000000000..915a1aabbc9 --- /dev/null +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/platform/JsIdePlatformKindTooling.kt.as33 @@ -0,0 +1,127 @@ +/* + * 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 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>() + .filter { it.isForTests } + .flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } } + .firstOrNull { it != null } ?: return null + + val locations = ArrayList() + + 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().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>() + .filter { !it.isForTests } + .flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } } + .any { it != null } + } + + private fun computeConfigurationContexts(declaration: KtNamedDeclaration): Sequence { + 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 + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/js/KotlinJSRunConfigurationDataProvider.kt b/idea/src/org/jetbrains/kotlin/idea/js/KotlinJSRunConfigurationDataProvider.kt index 68302b19da3..12fa2f9a43d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/js/KotlinJSRunConfigurationDataProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/js/KotlinJSRunConfigurationDataProvider.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.js +import com.intellij.execution.actions.ConfigurationContext import com.intellij.openapi.module.Module import com.intellij.psi.PsiElement @@ -16,5 +17,5 @@ interface KotlinJSRunConfigurationData { interface KotlinJSRunConfigurationDataProvider { val isForTests: Boolean - fun getConfigurationData(element: PsiElement): T? + fun getConfigurationData(context: ConfigurationContext): T? } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt b/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt index c13a8e9d000..82b68271e75 100644 --- a/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt @@ -19,12 +19,10 @@ package org.jetbrains.kotlin.idea.js import com.intellij.openapi.module.Module import com.intellij.openapi.roots.CompilerModuleExtension import org.jetbrains.jps.util.JpsPathUtil -import org.jetbrains.kotlin.idea.caches.project.implementingModules import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.framework.isGradleModule -import org.jetbrains.kotlin.idea.project.TargetPlatformDetector -import org.jetbrains.kotlin.js.resolve.JsPlatform -import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.kotlin.idea.project.platform +import org.jetbrains.kotlin.platform.impl.isJavaScript import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings val Module.jsTestOutputFilePath: String? @@ -49,11 +47,7 @@ val Module.jsProductionOutputFilePath: String? return JpsPathUtil.urlToPath("$outputDir/$name.js") } -fun Module.jsOrJsImpl() = when (TargetPlatformDetector.getPlatform(this)) { - is TargetPlatform.Common -> implementingModules.firstOrNull { TargetPlatformDetector.getPlatform(it) is JsPlatform } - is JsPlatform -> this - else -> null -} +fun Module.asJsModule(): Module? = takeIf { it.platform.isJavaScript } val Module.shouldUseJpsOutput: Boolean get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt.181 b/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt.181 new file mode 100644 index 00000000000..56891cb072d --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt.181 @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2017 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.js + +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.CompilerModuleExtension +import org.jetbrains.jps.util.JpsPathUtil +import org.jetbrains.kotlin.idea.caches.project.implementingModules +import org.jetbrains.kotlin.idea.facet.KotlinFacet +import org.jetbrains.kotlin.idea.framework.isGradleModule +import org.jetbrains.kotlin.idea.project.TargetPlatformDetector +import org.jetbrains.kotlin.js.resolve.JsPlatform +import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings + +val Module.jsTestOutputFilePath: String? + get() { + if (!shouldUseJpsOutput) { + (KotlinFacet.get(this)?.configuration?.settings?.testOutputPath)?.let { return it } + } + + val compilerExtension = CompilerModuleExtension.getInstance(this) + val outputDir = compilerExtension?.compilerOutputUrlForTests ?: return null + return JpsPathUtil.urlToPath("$outputDir/${name}_test.js") + } + +val Module.jsProductionOutputFilePath: String? + get() { + if (!shouldUseJpsOutput) { + (KotlinFacet.get(this)?.configuration?.settings?.productionOutputPath)?.let { return it } + } + + val compilerExtension = CompilerModuleExtension.getInstance(this) + val outputDir = compilerExtension?.compilerOutputUrl ?: return null + return JpsPathUtil.urlToPath("$outputDir/$name.js") + } + +fun Module.asJsModule(): Module? = when (TargetPlatformDetector.getPlatform(this)) { + is TargetPlatform.Common -> implementingModules.firstOrNull { TargetPlatformDetector.getPlatform(it) is JsPlatform } + is JsPlatform -> this + else -> null +} + +val Module.shouldUseJpsOutput: Boolean + get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt.as33 b/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt.as33 new file mode 100644 index 00000000000..56891cb072d --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/js/jsUtils.kt.as33 @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2017 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.js + +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.CompilerModuleExtension +import org.jetbrains.jps.util.JpsPathUtil +import org.jetbrains.kotlin.idea.caches.project.implementingModules +import org.jetbrains.kotlin.idea.facet.KotlinFacet +import org.jetbrains.kotlin.idea.framework.isGradleModule +import org.jetbrains.kotlin.idea.project.TargetPlatformDetector +import org.jetbrains.kotlin.js.resolve.JsPlatform +import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings + +val Module.jsTestOutputFilePath: String? + get() { + if (!shouldUseJpsOutput) { + (KotlinFacet.get(this)?.configuration?.settings?.testOutputPath)?.let { return it } + } + + val compilerExtension = CompilerModuleExtension.getInstance(this) + val outputDir = compilerExtension?.compilerOutputUrlForTests ?: return null + return JpsPathUtil.urlToPath("$outputDir/${name}_test.js") + } + +val Module.jsProductionOutputFilePath: String? + get() { + if (!shouldUseJpsOutput) { + (KotlinFacet.get(this)?.configuration?.settings?.productionOutputPath)?.let { return it } + } + + val compilerExtension = CompilerModuleExtension.getInstance(this) + val outputDir = compilerExtension?.compilerOutputUrl ?: return null + return JpsPathUtil.urlToPath("$outputDir/$name.js") + } + +fun Module.asJsModule(): Module? = when (TargetPlatformDetector.getPlatform(this)) { + is TargetPlatform.Common -> implementingModules.firstOrNull { TargetPlatformDetector.getPlatform(it) is JsPlatform } + is JsPlatform -> this + else -> null +} + +val Module.shouldUseJpsOutput: Boolean + get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) \ No newline at end of file diff --git a/ultimate/build.gradle.kts b/ultimate/build.gradle.kts index 14f46caa45e..6f2d765eaee 100644 --- a/ultimate/build.gradle.kts +++ b/ultimate/build.gradle.kts @@ -36,6 +36,8 @@ dependencies { compile(project(":idea:idea-core")) { isTransitive = false } compile(project(":idea:ide-common")) { isTransitive = false } compile(project(":idea:idea-gradle")) { isTransitive = false } + compile(project(":compiler:util")) { isTransitive = false } + compile(project(":idea:idea-jps-common")) { isTransitive = false } compileOnly(intellijCoreDep()) { includeJars("intellij-core") } if (intellijUltimateEnabled) { diff --git a/ultimate/build.gradle.kts.173 b/ultimate/build.gradle.kts.173 index 3e3c8d2f49c..b72de2580c2 100644 --- a/ultimate/build.gradle.kts.173 +++ b/ultimate/build.gradle.kts.173 @@ -36,6 +36,8 @@ dependencies { compile(project(":idea:idea-core")) { isTransitive = false } compile(project(":idea:ide-common")) { isTransitive = false } compile(project(":idea:idea-gradle")) { isTransitive = false } + compile(project(":compiler:util")) { isTransitive = false } + compile(project(":idea:idea-jps-common")) { isTransitive = false } compileOnly(intellijCoreDep()) { includeJars("intellij-core") } if (intellijUltimateEnabled) { diff --git a/ultimate/build.gradle.kts.as31 b/ultimate/build.gradle.kts.as31 index e5eb2ab1f02..e42960b4851 100644 --- a/ultimate/build.gradle.kts.as31 +++ b/ultimate/build.gradle.kts.as31 @@ -38,6 +38,8 @@ dependencies { compile(project(":idea:idea-core")) { isTransitive = false } compile(project(":idea:ide-common")) { isTransitive = false } compile(project(":idea:idea-gradle")) { isTransitive = false } + compile(project(":compiler:util")) { isTransitive = false } + compile(project(":idea:idea-jps-common")) { isTransitive = false } compileOnly(intellijCoreDep()) { includeJars("intellij-core") } if (intellijUltimateEnabled) { diff --git a/ultimate/build.gradle.kts.as32 b/ultimate/build.gradle.kts.as32 index 69f74a289b0..fb17b06057f 100644 --- a/ultimate/build.gradle.kts.as32 +++ b/ultimate/build.gradle.kts.as32 @@ -38,6 +38,8 @@ dependencies { compile(project(":idea:idea-core")) { isTransitive = false } compile(project(":idea:ide-common")) { isTransitive = false } compile(project(":idea:idea-gradle")) { isTransitive = false } + compile(project(":compiler:util")) { isTransitive = false } + compile(project(":idea:idea-jps-common")) { isTransitive = false } compileOnly(intellijCoreDep()) { includeJars("intellij-core") } if (intellijUltimateEnabled) { diff --git a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/cli/KotlinNodeJsRunConfigurationProducer.kt b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/cli/KotlinNodeJsRunConfigurationProducer.kt index 1d60fe91e24..7308cd4a275 100644 --- a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/cli/KotlinNodeJsRunConfigurationProducer.kt +++ b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/cli/KotlinNodeJsRunConfigurationProducer.kt @@ -17,12 +17,11 @@ import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationData import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider -import org.jetbrains.kotlin.idea.js.jsOrJsImpl +import org.jetbrains.kotlin.idea.js.asJsModule import org.jetbrains.kotlin.idea.js.jsProductionOutputFilePath import org.jetbrains.kotlin.idea.nodejs.TestElementPath import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars import org.jetbrains.kotlin.idea.run.addBuildTask -import org.jetbrains.kotlin.idea.util.module import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType @@ -45,27 +44,27 @@ private class KotlinNodeJsRunConfigurationProducer : override val isForTests: Boolean get() = false - private fun getConfigurationData(element: PsiElement, context: ConfigurationContext?): NodeJsConfigData? { - if (context != null && !context.isAcceptable) return null - val jsModule = element.module?.jsOrJsImpl() ?: return null - val jsFilePath = jsModule.jsProductionOutputFilePath ?: return null + override fun getConfigurationData(context: ConfigurationContext): NodeJsConfigData? { + if (!context.isAcceptable) return null + val element = context.psiLocation ?: return null + val module = context.module?.asJsModule() ?: return null + + val jsFilePath = module.jsProductionOutputFilePath ?: return null val declaration = element.getNonStrictParentOfType() if (declaration is KtNamedFunction) { val detector = MainFunctionDetector { it.resolveToDescriptorIfAny() } if (!detector.isMain(declaration, false)) return null - } else if (!TestElementPath.isModuleAssociatedDir(element, jsModule)) return null - return NodeJsConfigData(element, jsModule, jsFilePath) + } else if (!TestElementPath.isModuleAssociatedDir(element, module)) return null + return NodeJsConfigData(element, module, jsFilePath) } - override fun getConfigurationData(element: PsiElement) = getConfigurationData(element, null) - override fun setupConfigurationFromContext( configuration: NodeJsRunConfiguration, context: ConfigurationContext, sourceElement: Ref ): Boolean { val psiElement = sourceElement.get() ?: return false - val configData = getConfigurationData(psiElement, context) ?: return false + val configData = getConfigurationData(context) ?: return false if (configuration.workingDirectory.isNullOrBlank()) { configuration.workingDirectory = FileUtil.toSystemDependentName(psiElement.project.baseDir.path) @@ -79,8 +78,7 @@ private class KotlinNodeJsRunConfigurationProducer : } override fun isConfigurationFromContext(configuration: NodeJsRunConfiguration, context: ConfigurationContext): Boolean { - val contextPsi = context.psiLocation ?: return false - val configData = getConfigurationData(contextPsi, context) ?: return false + val configData = getConfigurationData(context) ?: return false return configuration.inputPath == configData.jsOutputFilePath } } \ No newline at end of file diff --git a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/jest/KotlinJestRunConfigurationProducer.kt b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/jest/KotlinJestRunConfigurationProducer.kt index 466a2086295..d59c2a9bd63 100644 --- a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/jest/KotlinJestRunConfigurationProducer.kt +++ b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/jest/KotlinJestRunConfigurationProducer.kt @@ -14,16 +14,14 @@ import com.intellij.openapi.module.Module import com.intellij.openapi.util.Ref import com.intellij.openapi.util.io.FileUtil import com.intellij.psi.PsiElement -import com.intellij.psi.util.PsiUtilCore import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationData -import org.jetbrains.kotlin.idea.js.jsOrJsImpl -import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider +import org.jetbrains.kotlin.idea.js.asJsModule +import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath import org.jetbrains.kotlin.idea.nodejs.TestElementInfo import org.jetbrains.kotlin.idea.nodejs.TestElementPath import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars import org.jetbrains.kotlin.idea.run.addBuildTask -import org.jetbrains.kotlin.idea.util.projectStructure.module typealias JestTestElementInfo = TestElementInfo @@ -74,29 +72,24 @@ class KotlinJestRunConfigurationProducer : override val isForTests: Boolean get() = true - override fun getConfigurationData(element: PsiElement): JestConfigData? { - val module = element.module - val jsModule = module?.jsOrJsImpl() ?: return null + override fun getConfigurationData( + context: ConfigurationContext + ): JestConfigData? { + val element = context.psiLocation ?: return null + val module = context.module?.asJsModule() ?: return null - val file = if (jsModule != module) { - jsModule.moduleFile - } else { - PsiUtilCore.getVirtualFile(element) - } ?: return null + val file = module.moduleFile - val project = module.project - - if (!isTestRunnerPackageAvailableFor(project, file)) return null + if (!isTestRunnerPackageAvailableFor(module.project, file)) return null val testFilePath = module.jsTestOutputFilePath ?: return null val testElementPath = TestElementPath.forElement(element, module) ?: return null - return JestConfigData(element, jsModule, testFilePath, testElementPath) + return JestConfigData(element, module, testFilePath, testElementPath) } override fun isConfigurationFromCompatibleContext(configuration: JestRunConfiguration, context: ConfigurationContext): Boolean { - val element = context.psiLocation ?: return false - val configData = getConfigurationData(element) ?: return false + val configData = getConfigurationData(context) ?: return false val (thisRunSettings, _) = createTestElementRunInfo(configData, configuration.runSettings) val thatRunSettings = configuration.runSettings @@ -117,8 +110,7 @@ class KotlinJestRunConfigurationProducer : context: ConfigurationContext, sourceElement: Ref ): Boolean { - val element = context.psiLocation ?: return false - val configData = getConfigurationData(element) ?: return false + val configData = getConfigurationData(context) ?: return false val (runSettings, enclosingTestElement) = createTestElementRunInfo(configData, configuration.runSettings) configuration.runSettings = runSettings sourceElement.set(enclosingTestElement) diff --git a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/mocha/KotlinMochaRunConfigurationProducer.kt b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/mocha/KotlinMochaRunConfigurationProducer.kt index 1048ccf2f2a..9d90aac0594 100644 --- a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/mocha/KotlinMochaRunConfigurationProducer.kt +++ b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/mocha/KotlinMochaRunConfigurationProducer.kt @@ -26,20 +26,18 @@ import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiElement -import com.intellij.psi.util.PsiUtilCore import com.intellij.util.SmartList import com.intellij.util.containers.SmartHashSet import com.jetbrains.nodejs.mocha.MochaUtil import com.jetbrains.nodejs.mocha.execution.* import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationData import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider -import org.jetbrains.kotlin.idea.js.jsOrJsImpl +import org.jetbrains.kotlin.idea.js.asJsModule import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath import org.jetbrains.kotlin.idea.nodejs.TestElementInfo import org.jetbrains.kotlin.idea.nodejs.TestElementPath import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars import org.jetbrains.kotlin.idea.run.addBuildTask -import org.jetbrains.kotlin.idea.util.projectStructure.module private typealias MochaTestElementInfo = TestElementInfo @@ -104,22 +102,18 @@ class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer(), Kot return MochaTestElementInfo(builder.build(), configData.element) } - private fun getConfigurationData(element: PsiElement, context: ConfigurationContext?): MochaConfigData? { - val module = element.module - val jsModule = module?.jsOrJsImpl() ?: return null - val file = if (jsModule != module) { - jsModule.moduleFile - } else { - PsiUtilCore.getVirtualFile(element) - } ?: return null + override fun getConfigurationData(context: ConfigurationContext): MochaConfigData? { + val module = context.module?.asJsModule() ?: return null + val element = context.psiLocation ?: return null + val file = module.moduleFile ?: return null val project = module.project val testFilePath = module.jsTestOutputFilePath ?: return null val testElementPath = TestElementPath.forElement(element, module) ?: return null - val configData = MochaConfigData(element, jsModule, testFilePath, testElementPath) + val configData = MochaConfigData(element, module, testFilePath, testElementPath) - if (context?.getOriginalConfiguration(MochaConfigurationType.getInstance()) is MochaRunConfiguration) return configData + if (context.getOriginalConfiguration(MochaConfigurationType.getInstance()) is MochaRunConfiguration) return configData if (isTestRunnerPackageAvailableFor(project, file)) return configData @@ -139,13 +133,8 @@ class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer(), Kot override val isForTests: Boolean get() = true - override fun getConfigurationData(element: PsiElement): MochaConfigData? { - return getConfigurationData(element, null) - } - override fun isConfigurationFromCompatibleContext(configuration: MochaRunConfiguration, context: ConfigurationContext): Boolean { - val element = context.psiLocation ?: return false - val configData = getConfigurationData(element) ?: return false + val configData = getConfigurationData(context) ?: return false val (thisRunSettings, _) = createTestElementRunInfo(configData, configuration.runSettings) val thatRunSettings = configuration.runSettings val thisTestKind = thisRunSettings.testKind @@ -165,8 +154,7 @@ class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer(), Kot context: ConfigurationContext, sourceElement: Ref ): Boolean { - val element = context.psiLocation ?: return false - val configData = getConfigurationData(element, context) ?: return false + val configData = getConfigurationData(context) ?: return false val (runSettings, enclosingTestElement) = createTestElementRunInfo(configData, configuration.runSettings) if (runSettings.testKind == MochaTestKind.DIRECTORY) return false configuration.runSettings = runSettings diff --git a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/protractor/KotlinProtractorRunConfigurationProducer.kt b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/protractor/KotlinProtractorRunConfigurationProducer.kt index a76b268c571..6f495553041 100644 --- a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/protractor/KotlinProtractorRunConfigurationProducer.kt +++ b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/protractor/KotlinProtractorRunConfigurationProducer.kt @@ -19,13 +19,12 @@ package org.jetbrains.kotlin.idea.nodejs.protractor import com.intellij.execution.actions.CompatibleRunConfigurationProducer import com.intellij.execution.actions.ConfigurationContext import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleUtilCore import com.intellij.openapi.util.Ref import com.intellij.openapi.util.io.FileUtil import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationData import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider -import org.jetbrains.kotlin.idea.js.jsOrJsImpl +import org.jetbrains.kotlin.idea.js.asJsModule import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath import org.jetbrains.kotlin.idea.nodejs.TestElementPath import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars @@ -43,11 +42,13 @@ class KotlinProtractorRunConfigurationProducer : override val isForTests: Boolean get() = true - override fun getConfigurationData(element: PsiElement): ProtractorConfigData? { - val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return null + override fun getConfigurationData( + context: ConfigurationContext + ): ProtractorConfigData? { + val module = context.module?.asJsModule() ?: return null + val element = context.psiLocation ?: return null if (!TestElementPath.isModuleAssociatedDir(element, module)) return null - val jsModule = module.jsOrJsImpl() ?: return null - val testFilePath = jsModule.jsTestOutputFilePath ?: return null + val testFilePath = module.jsTestOutputFilePath ?: return null return ProtractorConfigData(element, module, testFilePath) } @@ -55,8 +56,7 @@ class KotlinProtractorRunConfigurationProducer : configuration: KotlinProtractorRunConfiguration, context: ConfigurationContext ): Boolean { - val contextPsi = context.psiLocation ?: return false - val configData = getConfigurationData(contextPsi) ?: return false + val configData = getConfigurationData(context) ?: return false return configuration.runSettings.testFileSystemDependentPath == FileUtil.toSystemDependentName(configData.jsOutputFilePath) } @@ -66,7 +66,7 @@ class KotlinProtractorRunConfigurationProducer : sourceElement: Ref ): Boolean { val element = context.psiLocation ?: return false - val configData = getConfigurationData(element) ?: return false + val configData = getConfigurationData(context) ?: return false sourceElement.set(element) configuration.runSettings = configuration.runSettings.copy( testFilePath = configData.jsOutputFilePath,