Recognize common tests marked with annotations typealiased to @Test
This commit is contained in:
+7
@@ -232,6 +232,13 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
|||||||
fun MemberDescriptor.findCompatibleImplForHeader(platformModule: ModuleDescriptor): List<MemberDescriptor> =
|
fun MemberDescriptor.findCompatibleImplForHeader(platformModule: ModuleDescriptor): List<MemberDescriptor> =
|
||||||
findImplForHeader(this, platformModule, false)?.get(Compatible).orEmpty()
|
findImplForHeader(this, platformModule, false)?.get(Compatible).orEmpty()
|
||||||
|
|
||||||
|
fun MemberDescriptor.findAnyImplForHeader(platformModule: ModuleDescriptor): List<MemberDescriptor> {
|
||||||
|
val implsGroupedByCompatibility = findImplForHeader(this, platformModule, false)
|
||||||
|
return implsGroupedByCompatibility?.get(Compatible)
|
||||||
|
?: implsGroupedByCompatibility?.values?.flatten()
|
||||||
|
?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
fun MemberDescriptor.findCompatibleHeaderForImpl(commonModule: ModuleDescriptor): List<MemberDescriptor> =
|
fun MemberDescriptor.findCompatibleHeaderForImpl(commonModule: ModuleDescriptor): List<MemberDescriptor> =
|
||||||
findHeaderForImpl(this, commonModule)?.get(Compatible).orEmpty()
|
findHeaderForImpl(this, commonModule)?.get(Compatible).orEmpty()
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.intellij.ide.highlighter.ArchiveFileType
|
|||||||
import com.intellij.ide.highlighter.JavaClassFileType
|
import com.intellij.ide.highlighter.JavaClassFileType
|
||||||
import com.intellij.injected.editor.VirtualFileWindow
|
import com.intellij.injected.editor.VirtualFileWindow
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.module.ModuleUtilCore
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.roots.FileIndex
|
import com.intellij.openapi.roots.FileIndex
|
||||||
import com.intellij.openapi.roots.ModuleRootManager
|
import com.intellij.openapi.roots.ModuleRootManager
|
||||||
@@ -140,3 +141,6 @@ object ProjectRootsUtil {
|
|||||||
|
|
||||||
val Module.rootManager: ModuleRootManager
|
val Module.rootManager: ModuleRootManager
|
||||||
get() = ModuleRootManager.getInstance(this)
|
get() = ModuleRootManager.getInstance(this)
|
||||||
|
|
||||||
|
val PsiElement.module: Module?
|
||||||
|
get() = ModuleUtilCore.findModuleForPsiElement(this)
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.run
|
||||||
|
|
||||||
|
import com.intellij.execution.JUnitRecognizer
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.config.TargetPlatformKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules
|
||||||
|
import org.jetbrains.kotlin.idea.highlighter.markers.implementationsOf
|
||||||
|
import org.jetbrains.kotlin.idea.project.targetPlatform
|
||||||
|
import org.jetbrains.kotlin.idea.util.module
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
|
class KotlinMultiplatformJUnitRecognizer : JUnitRecognizer() {
|
||||||
|
override fun isTestAnnotated(method: PsiMethod): Boolean {
|
||||||
|
if (method !is KtLightMethod) return false
|
||||||
|
val origin = method.kotlinOrigin ?: return false
|
||||||
|
if (origin.module?.targetPlatform !is TargetPlatformKind.Common) return false
|
||||||
|
|
||||||
|
val moduleDescriptor = origin.containingKtFile.findModuleDescriptor()
|
||||||
|
val implModules = moduleDescriptor.allImplementingCompatibleModules
|
||||||
|
if (implModules.isEmpty()) return false
|
||||||
|
|
||||||
|
val bindingContext = origin.analyze(BodyResolveMode.PARTIAL)
|
||||||
|
val methodDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, origin] ?: return false
|
||||||
|
return methodDescriptor.annotations.getAllAnnotations().any { it.isHeaderOfAnnotation("org.junit.Test", implModules) }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun AnnotationWithTarget.isHeaderOfAnnotation(fqName: String, implModules: Collection<ModuleDescriptor>): Boolean {
|
||||||
|
val annotationClass = annotation.type.constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters ?: return false
|
||||||
|
if (!annotationClass.isHeader) return false
|
||||||
|
|
||||||
|
return implModules
|
||||||
|
.any { module ->
|
||||||
|
module.implementationsOf(annotationClass, checkCompatible = false)
|
||||||
|
.filterIsInstance<TypeAliasDescriptor>()
|
||||||
|
.any { it.classDescriptor?.fqNameSafe?.asString() == fqName }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,5 +2,6 @@
|
|||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinJUnitRunConfigurationProducer"/>
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinJUnitRunConfigurationProducer"/>
|
||||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinPatternConfigurationProducer"/>
|
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinPatternConfigurationProducer"/>
|
||||||
|
<junitRecognizer implementation="org.jetbrains.kotlin.idea.run.KotlinMultiplatformJUnitRecognizer"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
|||||||
@@ -34,9 +34,14 @@ import java.awt.event.MouseEvent
|
|||||||
fun ModuleDescriptor.hasImplementationsOf(descriptor: MemberDescriptor) =
|
fun ModuleDescriptor.hasImplementationsOf(descriptor: MemberDescriptor) =
|
||||||
implementationsOf(descriptor).isNotEmpty()
|
implementationsOf(descriptor).isNotEmpty()
|
||||||
|
|
||||||
private fun ModuleDescriptor.implementationsOf(descriptor: MemberDescriptor): List<DeclarationDescriptor> =
|
fun ModuleDescriptor.implementationsOf(descriptor: MemberDescriptor, checkCompatible: Boolean = true): List<DeclarationDescriptor> =
|
||||||
with(HeaderImplDeclarationChecker) {
|
with(HeaderImplDeclarationChecker) {
|
||||||
descriptor.findCompatibleImplForHeader(this@implementationsOf)
|
if (checkCompatible) {
|
||||||
|
descriptor.findCompatibleImplForHeader(this@implementationsOf)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
descriptor.findAnyImplForHeader(this@implementationsOf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPlatformImplementationTooltip(declaration: KtDeclaration): String? {
|
fun getPlatformImplementationTooltip(declaration: KtDeclaration): String? {
|
||||||
|
|||||||
Reference in New Issue
Block a user