Add AdditionalBuiltInsMembersSignatureListsTest
This test checks that every signature listed within JvmBuiltInsAdditionalClassPartsProvider corresponds to some real JDK member
This commit is contained in:
+95
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-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.
|
||||||
|
* 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.serialization.builtins
|
||||||
|
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
|
import org.jetbrains.kotlin.context.ModuleContext
|
||||||
|
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||||
|
import org.jetbrains.kotlin.descriptors.resolveClassByFqName
|
||||||
|
import org.jetbrains.kotlin.frontend.java.di.createContainerForTopDownAnalyzerForJvm
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.JvmBuiltInsAdditionalClassPartsProvider
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.platform.JvmBuiltIns
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
|
||||||
|
import org.jetbrains.kotlin.test.TestJdkKind
|
||||||
|
|
||||||
|
class AdditionalBuiltInsMembersSignatureListsTest : KotlinTestWithEnvironment() {
|
||||||
|
override fun createEnvironment(): KotlinCoreEnvironment {
|
||||||
|
return createEnvironmentWithJdk(ConfigurationKind.JDK_ONLY, TestJdkKind.FULL_JDK)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testAllListedSignaturesExistInJdk() {
|
||||||
|
val jvmBuiltIns = JvmBuiltIns(LockBasedStorageManager.NO_LOCKS)
|
||||||
|
val emptyModule = KotlinTestUtils.createEmptyModule("<empty>", JvmPlatform, jvmBuiltIns)
|
||||||
|
jvmBuiltIns.setOwnerModuleDescriptor(emptyModule)
|
||||||
|
|
||||||
|
val moduleContext = ModuleContext(emptyModule, environment.project)
|
||||||
|
val providerFactory = FileBasedDeclarationProviderFactory(moduleContext.storageManager, emptyList())
|
||||||
|
|
||||||
|
val container = createContainerForTopDownAnalyzerForJvm(
|
||||||
|
moduleContext,
|
||||||
|
CliLightClassGenerationSupport.CliBindingTrace(), providerFactory,
|
||||||
|
GlobalSearchScope.allScope(environment.project), LookupTracker.DO_NOTHING, PackagePartProvider.EMPTY)
|
||||||
|
|
||||||
|
emptyModule.initialize(container.javaDescriptorResolver.packageFragmentProvider)
|
||||||
|
emptyModule.setDependencies(emptyModule)
|
||||||
|
|
||||||
|
val blackList =
|
||||||
|
JvmBuiltInsAdditionalClassPartsProvider.BLACK_LIST_METHOD_SIGNATURES +
|
||||||
|
JvmBuiltInsAdditionalClassPartsProvider.MUTABLE_METHOD_SIGNATURES +
|
||||||
|
JvmBuiltInsAdditionalClassPartsProvider.BLACK_LIST_CONSTRUCTOR_SIGNATURES
|
||||||
|
|
||||||
|
val groupedByInternalName = blackList.groupBy({ it.split(".")[0] }) { it.split(".")[1] }
|
||||||
|
|
||||||
|
groupedByInternalName.entries.forEach {
|
||||||
|
it ->
|
||||||
|
val (internalName, jvmDescriptors) = it
|
||||||
|
val classDescriptor =
|
||||||
|
emptyModule.resolveClassByFqName(
|
||||||
|
JvmClassName.byInternalName(internalName).fqNameForClassNameWithoutDollars, NoLookupLocation.FROM_TEST
|
||||||
|
)!!
|
||||||
|
|
||||||
|
val scope = classDescriptor.unsubstitutedMemberScope
|
||||||
|
|
||||||
|
jvmDescriptors.forEach {
|
||||||
|
jvmDescriptor ->
|
||||||
|
val stringName = jvmDescriptor.split("(")[0]
|
||||||
|
val functions =
|
||||||
|
if (stringName == "<init>")
|
||||||
|
classDescriptor.constructors
|
||||||
|
else
|
||||||
|
scope.getContributedFunctions(Name.identifier(stringName), NoLookupLocation.FROM_TEST)
|
||||||
|
|
||||||
|
functions.singleOrNull {
|
||||||
|
it.isEffectivelyPublicApi && it.computeJvmDescriptor() == jvmDescriptor
|
||||||
|
} ?: fail("Expected single function with signature $jvmDescriptor in $internalName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-5
@@ -227,7 +227,7 @@ open class JvmBuiltInsAdditionalClassPartsProvider(
|
|||||||
return Serializable::class.java.isAssignableFrom(classViaReflection)
|
return Serializable::class.java.isAssignableFrom(classViaReflection)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val BLACK_LIST_METHOD_SIGNATURES: Set<String> =
|
val BLACK_LIST_METHOD_SIGNATURES: Set<String> =
|
||||||
signatures {
|
signatures {
|
||||||
buildPrimitiveValueMethodsSet() +
|
buildPrimitiveValueMethodsSet() +
|
||||||
|
|
||||||
@@ -264,12 +264,12 @@ open class JvmBuiltInsAdditionalClassPartsProvider(
|
|||||||
|
|
||||||
private fun buildPrimitiveValueMethodsSet(): Set<String> =
|
private fun buildPrimitiveValueMethodsSet(): Set<String> =
|
||||||
signatures {
|
signatures {
|
||||||
JvmPrimitiveType.values().flatMapTo(LinkedHashSet()) {
|
listOf(JvmPrimitiveType.BOOLEAN, JvmPrimitiveType.CHAR).flatMapTo(LinkedHashSet()) {
|
||||||
inJavaLang(it.wrapperFqName.shortName().asString(), "${it.javaKeywordName}Value()${it.desc}")
|
inJavaLang(it.wrapperFqName.shortName().asString(), "${it.javaKeywordName}Value()${it.desc}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val MUTABLE_METHOD_SIGNATURES: Set<String> =
|
val MUTABLE_METHOD_SIGNATURES: Set<String> =
|
||||||
signatures {
|
signatures {
|
||||||
inJavaUtil("Collection", "removeIf(Ljava/util/function/Predicate;)Z") +
|
inJavaUtil("Collection", "removeIf(Ljava/util/function/Predicate;)Z") +
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ open class JvmBuiltInsAdditionalClassPartsProvider(
|
|||||||
"replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z")
|
"replace(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val BLACK_LIST_CONSTRUCTOR_SIGNATURES: Set<String> =
|
val BLACK_LIST_CONSTRUCTOR_SIGNATURES: Set<String> =
|
||||||
signatures {
|
signatures {
|
||||||
buildPrimitiveStringConstructorsSet() +
|
buildPrimitiveStringConstructorsSet() +
|
||||||
inJavaLang("Float", *constructors("D")) +
|
inJavaLang("Float", *constructors("D")) +
|
||||||
@@ -304,7 +304,10 @@ open class JvmBuiltInsAdditionalClassPartsProvider(
|
|||||||
|
|
||||||
private fun buildPrimitiveStringConstructorsSet(): Set<String> =
|
private fun buildPrimitiveStringConstructorsSet(): Set<String> =
|
||||||
signatures {
|
signatures {
|
||||||
JvmPrimitiveType.values().flatMapTo(LinkedHashSet()) {
|
listOf(JvmPrimitiveType.BOOLEAN, JvmPrimitiveType.BYTE, JvmPrimitiveType.DOUBLE, JvmPrimitiveType.FLOAT,
|
||||||
|
JvmPrimitiveType.BYTE, JvmPrimitiveType.INT, JvmPrimitiveType.LONG, JvmPrimitiveType.SHORT
|
||||||
|
).flatMapTo(LinkedHashSet()) {
|
||||||
|
// java/lang/<Wrapper>.<init>(Ljava/lang/String;)V
|
||||||
inJavaLang(it.wrapperFqName.shortName().asString(), *constructors("Ljava/lang/String;"))
|
inJavaLang(it.wrapperFqName.shortName().asString(), *constructors("Ljava/lang/String;"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user