[Gradle] kgp-idea: Implement IdeaKotlinExtra

KT-55189
This commit is contained in:
Sebastian Sellmair
2022-11-30 16:45:44 +01:00
committed by Space Team
parent 8cee0496f3
commit bb039ae535
18 changed files with 223 additions and 94 deletions
@@ -12,4 +12,7 @@ annotation class IdeaKotlinEntity
annotation class IdeaKotlinModel annotation class IdeaKotlinModel
@IdeaKotlinEntity @IdeaKotlinEntity
annotation class IdeaKotlinService annotation class IdeaKotlinService
@IdeaKotlinEntity
annotation class IdeaKotlinExtra
@@ -1,25 +0,0 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.gradle.idea.tcs
import org.reflections.Reflections
import kotlin.reflect.KClass
object ReflectionTestUtils {
const val ideaTcsPackage = "org.jetbrains.kotlin.gradle.idea.tcs"
val ideaTcsReflections = Reflections(ideaTcsPackage)
const val kotlinPackage = "org.jetbrains.kotlin"
val kotlinReflections = Reflections(kotlinPackage)
fun KClass<*>.displayName() = java.name
.removePrefix("org.jetbrains.kotlin")
.removePrefix(".gradle")
.removePrefix(".idea")
.removePrefix(".tcs")
.removePrefix(".")
}
@@ -3,19 +3,22 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.kpm package org.jetbrains.kotlin.gradle.idea.test.kpm
import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.internal.project.ProjectInternal
import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.create
import org.gradle.testfixtures.ProjectBuilder import org.gradle.testfixtures.ProjectBuilder
import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmFragment
import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmProject
import org.jetbrains.kotlin.gradle.idea.kpm.name
import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.TestIdeaKpmExtra import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.TestIdeaKpmExtra
import org.jetbrains.kotlin.gradle.idea.testFixtures.serialize.TestIdeaExtrasSerializationExtension.anySerializableKey import org.jetbrains.kotlin.gradle.idea.testFixtures.serialize.TestIdeaExtrasSerializationExtension.anySerializableKey
import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.copy import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.copy
import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.createProxyInstance import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.createProxyInstance
import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.unwrapProxyInstance import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.unwrapProxyInstance
import org.jetbrains.kotlin.gradle.idea.testUtils.buildIdeaKpmProject import org.jetbrains.kotlin.gradle.idea.test.testUtils.buildIdeaKpmProject
import org.jetbrains.kotlin.gradle.idea.testUtils.createKpmProject import org.jetbrains.kotlin.gradle.idea.test.testUtils.createKpmProject
import org.jetbrains.kotlin.gradle.idea.testUtils.deserializeIdeaKpmProjectWithBackwardsCompatibleClasses import org.jetbrains.kotlin.gradle.idea.test.testUtils.deserializeIdeaKpmProjectWithBackwardsCompatibleClasses
import org.jetbrains.kotlin.gradle.plugin.KotlinPm20PluginWrapper import org.jetbrains.kotlin.gradle.plugin.KotlinPm20PluginWrapper
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmIosX64Variant import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmIosX64Variant
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmLinuxX64Variant import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmLinuxX64Variant
@@ -3,14 +3,16 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.kpm package org.jetbrains.kotlin.gradle.idea.test.kpm
import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmProject
import org.jetbrains.kotlin.gradle.idea.kpm.name
import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.TestIdeaKpmInstances import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.TestIdeaKpmInstances
import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.assertContainsFragment import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.assertContainsFragment
import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.assertContainsModule import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.assertContainsModule
import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.copy import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.copy
import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.createProxyInstance import org.jetbrains.kotlin.gradle.idea.testFixtures.utils.createProxyInstance
import org.jetbrains.kotlin.gradle.idea.testUtils.deserializeIdeaKpmProjectWithBackwardsCompatibleClasses import org.jetbrains.kotlin.gradle.idea.test.testUtils.deserializeIdeaKpmProjectWithBackwardsCompatibleClasses
import org.junit.Test import org.junit.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@@ -3,8 +3,11 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.kpm package org.jetbrains.kotlin.gradle.idea.test.kpm
import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmProjectBinaryContainer
import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmProjectContainer
import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmProjectInstanceContainer
import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.TestIdeaKpmInstances import org.jetbrains.kotlin.gradle.idea.testFixtures.kpm.TestIdeaKpmInstances
import kotlin.test.* import kotlin.test.*
@@ -3,8 +3,10 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.kpm package org.jetbrains.kotlin.gradle.idea.test.kpm
import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmProject
import org.jetbrains.kotlin.gradle.idea.kpm.WriteReplacedModel
import org.jetbrains.kotlin.tooling.core.AbstractExtras import org.jetbrains.kotlin.tooling.core.AbstractExtras
import org.jetbrains.kotlin.tooling.core.Extras import org.jetbrains.kotlin.tooling.core.Extras
import org.jetbrains.kotlin.tooling.core.MutableExtras import org.jetbrains.kotlin.tooling.core.MutableExtras
@@ -3,8 +3,10 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.serialize package org.jetbrains.kotlin.gradle.idea.test.serialize
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinExtrasSerializer
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinJavaIoSerializableExtrasSerializer
import org.jetbrains.kotlin.gradle.idea.testFixtures.serialize.TestIdeaKotlinSerializationContext import org.jetbrains.kotlin.gradle.idea.testFixtures.serialize.TestIdeaKotlinSerializationContext
import org.jetbrains.kotlin.tooling.core.withLinearClosure import org.jetbrains.kotlin.tooling.core.withLinearClosure
import org.junit.Test import org.junit.Test
@@ -3,8 +3,9 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.serialize package org.jetbrains.kotlin.gradle.idea.test.serialize
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinBooleanExtrasSerializer
import org.jetbrains.kotlin.gradle.idea.testFixtures.serialize.TestIdeaKotlinSerializationContext import org.jetbrains.kotlin.gradle.idea.testFixtures.serialize.TestIdeaKotlinSerializationContext
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.serialize package org.jetbrains.kotlin.gradle.idea.test.serialize
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinIntExtrasSerializer.deserialize import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinIntExtrasSerializer.deserialize
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinIntExtrasSerializer.serialize import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinIntExtrasSerializer.serialize
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.serialize package org.jetbrains.kotlin.gradle.idea.test.serialize
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinStringExtrasSerializer.deserialize import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinStringExtrasSerializer.deserialize
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinStringExtrasSerializer.serialize import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinStringExtrasSerializer.serialize
@@ -3,8 +3,12 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.tcs package org.jetbrains.kotlin.gradle.idea.test.tcs
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinEntity
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinExtra
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinModel
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinService
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.full.allSuperclasses import kotlin.reflect.full.allSuperclasses
import kotlin.reflect.full.findAnnotation import kotlin.reflect.full.findAnnotation
@@ -17,4 +21,6 @@ fun KClass<*>.findIdeaKotlinEntityAnnotations(): List<Annotation> {
val KClass<*>.isIdeaKotlinModel get() = findIdeaKotlinEntityAnnotations().singleOrNull() is IdeaKotlinModel val KClass<*>.isIdeaKotlinModel get() = findIdeaKotlinEntityAnnotations().singleOrNull() is IdeaKotlinModel
val KClass<*>.isIdeaKotlinExtra get() = findIdeaKotlinEntityAnnotations().singleOrNull() is IdeaKotlinExtra
val KClass<*>.isIdeaKotlinService get() = findIdeaKotlinEntityAnnotations().singleOrNull() is IdeaKotlinService val KClass<*>.isIdeaKotlinService get() = findIdeaKotlinEntityAnnotations().singleOrNull() is IdeaKotlinService
@@ -3,14 +3,15 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.tcs package org.jetbrains.kotlin.gradle.idea.test.tcs
import org.jetbrains.kotlin.gradle.idea.tcs.ReflectionTestUtils.displayName import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinEntity
import org.jetbrains.kotlin.gradle.idea.tcs.ReflectionTestUtils.ideaTcsPackage import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.displayName
import org.jetbrains.kotlin.gradle.idea.tcs.ReflectionTestUtils.ideaTcsReflections import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.getAllKotlinClasses
import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.ideaTcsPackage
import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.ideaTcsReflections
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.Parameterized import org.junit.runners.Parameterized
import org.reflections.scanners.Scanners
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.fail import kotlin.test.fail
@@ -35,10 +36,9 @@ class IdeaKotlinEntityTest(private val node: KClass<*>, private val clazzName: S
@JvmStatic @JvmStatic
@Parameterized.Parameters(name = "{1}") @Parameterized.Parameters(name = "{1}")
fun findClasses(): List<Array<Any>> { fun findClasses(): List<Array<Any>> {
return ideaTcsReflections.getAll(Scanners.SubTypes) return ideaTcsReflections.getAllKotlinClasses()
.map { Class.forName(it) } .filter { !it.java.isAnnotation }
.filter { !it.isAnnotation } .filter { !it.isCompanion }
.map { it.kotlin }
.filter { it.qualifiedName.orEmpty().startsWith(ideaTcsPackage) } .filter { it.qualifiedName.orEmpty().startsWith(ideaTcsPackage) }
.map { clazz -> arrayOf(clazz, checkNotNull(clazz.displayName())) } .map { clazz -> arrayOf(clazz, checkNotNull(clazz.displayName())) }
@@ -0,0 +1,70 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.gradle.idea.test.tcs
import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.displayName
import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.getAllKotlinClasses
import org.jetbrains.kotlin.tooling.core.Extras
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.io.Serializable
import kotlin.reflect.KClass
import kotlin.reflect.full.companionObject
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.full.memberProperties
import kotlin.test.Test
import kotlin.test.fail
@RunWith(Parameterized::class)
class IdeaKotlinExtraTest(private val node: KClass<*>, private val clazzName: String) {
@Test
fun `test - node is data class`() {
if (!node.isData) fail("Expected $clazzName to be marked as data class")
}
@Test
fun `test - node is Serializable`() {
if (!node.isSubclassOf(Serializable::class)) fail("Expected $clazzName to implement ${Serializable::class}")
}
@Test
fun `test - contains serialVersionUID`() {
assertNodeContainsSerialVersionUID(node)
}
@Test
fun `test - all members properties are nullable`() {
node.memberProperties.forEach { member ->
if (!member.returnType.isMarkedNullable) fail("Expected $clazzName.${member.name} to be marked nullable")
}
}
@Test
fun `test - node has companion with key`() {
val companion = node.companionObject ?: fail("Missing companion on $clazzName")
val keyProperty = companion.memberProperties.find { it.name == "key" } ?: fail("Missing .key on $clazzName.${companion.simpleName}")
val keyType = keyProperty.returnType
val isCorrectType = when {
keyType.classifier != Extras.Key::class -> false
keyType.arguments.singleOrNull()?.type?.classifier != node -> false
else -> true
}
if (!isCorrectType) fail("Expected key to be type Extras.Key<${node.simpleName}>. Found $keyType")
}
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{1}")
fun findClasses(): List<Array<Any>> {
return ReflectionTestUtils.ideaTcsReflections.getAllKotlinClasses()
.filter { it.isIdeaKotlinExtra }
.map { arrayOf(it, it.displayName()) }
}
}
}
@@ -3,20 +3,19 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.tcs package org.jetbrains.kotlin.gradle.idea.test.tcs
import org.jetbrains.kotlin.gradle.idea.tcs.ReflectionTestUtils.displayName import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.displayName
import org.jetbrains.kotlin.gradle.idea.tcs.ReflectionTestUtils.ideaTcsReflections import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.getAllKotlinClasses
import org.jetbrains.kotlin.gradle.idea.tcs.ReflectionTestUtils.kotlinReflections import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.ideaTcsReflections
import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.kotlinReflections
import org.jetbrains.kotlin.tooling.core.AbstractExtras import org.jetbrains.kotlin.tooling.core.AbstractExtras
import org.jetbrains.kotlin.tooling.core.Extras import org.jetbrains.kotlin.tooling.core.Extras
import org.jetbrains.kotlin.tooling.core.MutableExtras import org.jetbrains.kotlin.tooling.core.MutableExtras
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.Parameterized import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameters import org.junit.runners.Parameterized.Parameters
import org.reflections.scanners.Scanners
import java.io.Serializable import java.io.Serializable
import java.lang.reflect.Field
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.full.memberProperties import kotlin.reflect.full.memberProperties
@@ -25,6 +24,13 @@ import kotlin.test.*
@RunWith(Parameterized::class) @RunWith(Parameterized::class)
class IdeaKotlinModelObjectGraphTest(private val node: KClass<*>, private val clazzName: String) { class IdeaKotlinModelObjectGraphTest(private val node: KClass<*>, private val clazzName: String) {
@Test
fun `test - node is sealed`() {
if (node.java.isInterface || node.isAbstract) {
assertTrue(node.isSealed, "Expected $clazzName to be sealed")
}
}
@Test @Test
fun `test - node implements Serializable`() { fun `test - node implements Serializable`() {
assertTrue( assertTrue(
@@ -33,47 +39,13 @@ class IdeaKotlinModelObjectGraphTest(private val node: KClass<*>, private val cl
) )
} }
@Test
fun `test - node is sealed`() {
if (node.java.isInterface || node.isAbstract) {
assertTrue(node.isSealed, "Expected $clazzName to be sealed")
}
}
@Test @Test
fun `test - node implementations contain serialVersionUID`() { fun `test - node implementations contain serialVersionUID`() {
if (!node.java.isInterface && !Modifier.isAbstract(node.java.modifiers)) { if (!node.java.isInterface && !Modifier.isAbstract(node.java.modifiers)) {
val serialVersionUID = assertNotNull( assertNodeContainsSerialVersionUID(node)
node.java.getDeclaredFieldOrNull("serialVersionUID"),
"Expected $node to declare 'serialVersionUID' field"
)
assertTrue(
Modifier.isStatic(serialVersionUID.modifiers),
"Expected $node to declare 'serialVersionUID' statically"
)
assertTrue(
serialVersionUID.type.isPrimitive,
"Expected $node to declare primitive 'serialVersionUID'"
)
assertEquals(
serialVersionUID.type, Long::class.javaPrimitiveType,
"Expected $node to declare 'serialVersionUID' of type Long"
)
} }
} }
private fun Class<*>.getDeclaredFieldOrNull(name: String): Field? {
return try {
getDeclaredField(name)
} catch (t: NoSuchFieldException) {
return null
}
}
companion object { companion object {
private val ignoredNodes = setOf( private val ignoredNodes = setOf(
/* /*
@@ -90,9 +62,7 @@ class IdeaKotlinModelObjectGraphTest(private val node: KClass<*>, private val cl
val resolveQueue = ArrayDeque<KClass<*>>() val resolveQueue = ArrayDeque<KClass<*>>()
resolveQueue += ideaTcsReflections.getAll(Scanners.SubTypes) resolveQueue += ideaTcsReflections.getAllKotlinClasses()
.map { Class.forName(it) }
.map { it.kotlin }
.filter { it.isIdeaKotlinModel } .filter { it.isIdeaKotlinModel }
while (resolveQueue.isNotEmpty()) { while (resolveQueue.isNotEmpty()) {
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.gradle.idea.test.tcs
import javassist.bytecode.ClassFile
import org.reflections.Reflections
import org.reflections.scanners.Scanner
import org.reflections.scanners.Scanners
import java.lang.reflect.Field
import kotlin.reflect.KClass
import kotlin.reflect.full.superclasses
object ReflectionTestUtils {
const val ideaTcsPackage = "org.jetbrains.kotlin.gradle.idea.tcs"
val ideaTcsReflections = Reflections(ideaTcsPackage, AllClassScanner, Scanners.SubTypes, Scanners.TypesAnnotated)
const val kotlinPackage = "org.jetbrains.kotlin"
val kotlinReflections = Reflections(kotlinPackage, AllClassScanner, Scanners.SubTypes, Scanners.TypesAnnotated)
fun KClass<*>.displayName() = java.name
.removePrefix("org.jetbrains.kotlin")
.removePrefix(".gradle")
.removePrefix(".idea")
.removePrefix(".tcs")
.removePrefix(".")
fun Reflections.getAllKotlinClasses(): Set<KClass<*>> {
return getAll(AllClassScanner)
.mapNotNull { runCatching { Class.forName(it) }.getOrNull() }
.mapNotNull { runCatching { it.kotlin }.getOrNull() }
.filter { runCatching { it.superclasses }.isSuccess } // Filter out Packages and file facades
.filter { !it.qualifiedName.orEmpty().startsWith("$ideaTcsPackage.test") } // Filter out test sources
.toSet()
}
private object AllClassScanner : Scanner {
override fun scan(classFile: ClassFile): MutableList<MutableMap.MutableEntry<String, String>> {
return mutableListOf(entry(classFile.name, classFile.name))
}
}
fun Class<*>.getDeclaredFieldOrNull(name: String): Field? {
return try {
getDeclaredField(name)
} catch (t: NoSuchFieldException) {
return null
}
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.gradle.idea.test.tcs
import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.displayName
import org.jetbrains.kotlin.gradle.idea.test.tcs.ReflectionTestUtils.getDeclaredFieldOrNull
import java.lang.reflect.Modifier
import kotlin.reflect.KClass
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
fun assertNodeContainsSerialVersionUID(node: KClass<*>) {
if (!node.java.isInterface && !Modifier.isAbstract(node.java.modifiers)) {
val serialVersionUID = assertNotNull(
node.java.getDeclaredFieldOrNull("serialVersionUID"),
"Expected ${node.displayName()} to declare 'serialVersionUID' field"
)
assertTrue(
Modifier.isStatic(serialVersionUID.modifiers),
"Expected ${node.displayName()} to declare 'serialVersionUID' statically"
)
assertTrue(
serialVersionUID.type.isPrimitive,
"Expected ${node.displayName()} to declare primitive 'serialVersionUID'"
)
assertEquals(
serialVersionUID.type, Long::class.javaPrimitiveType,
"Expected ${node.displayName()} to declare 'serialVersionUID' of type Long"
)
}
}
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.testUtils package org.jetbrains.kotlin.gradle.idea.test.testUtils
import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmProject import org.jetbrains.kotlin.gradle.idea.kpm.IdeaKpmProject
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationLogger import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinSerializationLogger
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * 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.gradle.idea.testUtils package org.jetbrains.kotlin.gradle.idea.test.testUtils
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.verification.DependencyVerificationMode import org.gradle.api.artifacts.verification.DependencyVerificationMode