Move more common parts from :compiler:descriptors.jvm
This commit is contained in:
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.java
|
||||
|
||||
enum class AnnotationQualifierApplicabilityType {
|
||||
METHOD_RETURN_TYPE, VALUE_PARAMETER, FIELD, TYPE_USE
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.java
|
||||
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQualifierNickname")
|
||||
val TYPE_QUALIFIER_FQNAME = FqName("javax.annotation.meta.TypeQualifier")
|
||||
val TYPE_QUALIFIER_DEFAULT_FQNAME = FqName("javax.annotation.meta.TypeQualifierDefault")
|
||||
|
||||
val MIGRATION_ANNOTATION_FQNAME = FqName("kotlin.annotations.jvm.UnderMigration")
|
||||
|
||||
val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf(
|
||||
FqName("javax.annotation.ParametersAreNullableByDefault") to
|
||||
NullabilityQualifierWithApplicability(
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE),
|
||||
listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER)
|
||||
),
|
||||
FqName("javax.annotation.ParametersAreNonnullByDefault") to
|
||||
NullabilityQualifierWithApplicability(
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL),
|
||||
listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER)
|
||||
)
|
||||
)
|
||||
|
||||
val BUILT_IN_TYPE_QUALIFIER_FQ_NAMES = setOf(JAVAX_NONNULL_ANNOTATION, JAVAX_CHECKFORNULL_ANNOTATION)
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.java
|
||||
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.JavaTypeQualifiers
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus
|
||||
import java.util.*
|
||||
|
||||
typealias QualifierByApplicabilityType = EnumMap<AnnotationQualifierApplicabilityType, NullabilityQualifierWithMigrationStatus?>
|
||||
|
||||
class JavaTypeQualifiersByElementType(val nullabilityQualifiers: QualifierByApplicabilityType) {
|
||||
operator fun get(applicabilityType: AnnotationQualifierApplicabilityType?): JavaTypeQualifiers? {
|
||||
val nullabilityQualifierWithMigrationStatus = nullabilityQualifiers[applicabilityType] ?: return null
|
||||
|
||||
return JavaTypeQualifiers(
|
||||
nullabilityQualifierWithMigrationStatus.qualifier, null,
|
||||
isNotNullTypeParameter = false,
|
||||
isNullabilityQualifierForWarning = nullabilityQualifierWithMigrationStatus.isForWarningOnly
|
||||
)
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.java
|
||||
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus
|
||||
|
||||
data class NullabilityQualifierWithApplicability(
|
||||
val nullabilityQualifier: NullabilityQualifierWithMigrationStatus,
|
||||
val qualifierApplicabilityTypes: Collection<AnnotationQualifierApplicabilityType>
|
||||
)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.java.descriptors
|
||||
|
||||
sealed class AnnotationDefaultValue
|
||||
|
||||
class StringDefaultValue(val value: String) : AnnotationDefaultValue()
|
||||
|
||||
object NullDefaultValue : AnnotationDefaultValue()
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.java.typeEnhancement
|
||||
|
||||
data class NullabilityQualifierWithMigrationStatus(
|
||||
val qualifier: NullabilityQualifier,
|
||||
val isForWarningOnly: Boolean = false
|
||||
)
|
||||
+2
@@ -10,3 +10,5 @@ enum class TypeComponentPosition {
|
||||
FLEXIBLE_UPPER,
|
||||
INFLEXIBLE
|
||||
}
|
||||
|
||||
fun TypeComponentPosition.shouldEnhance(): Boolean = this != TypeComponentPosition.INFLEXIBLE
|
||||
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* 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.load.java.typeEnhancement
|
||||
|
||||
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||
import org.jetbrains.kotlin.load.kotlin.signatures
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType.BOOLEAN
|
||||
|
||||
class TypeEnhancementInfo(val map: Map<Int, JavaTypeQualifiers>) {
|
||||
constructor(vararg pairs: Pair<Int, JavaTypeQualifiers>) : this(mapOf(*pairs))
|
||||
}
|
||||
|
||||
class PredefinedFunctionEnhancementInfo(
|
||||
val returnTypeInfo: TypeEnhancementInfo? = null,
|
||||
val parametersInfo: List<TypeEnhancementInfo?> = emptyList()
|
||||
)
|
||||
|
||||
/** Type is always nullable: `T?` */
|
||||
private val NULLABLE = JavaTypeQualifiers(NullabilityQualifier.NULLABLE, null, isNotNullTypeParameter = false)
|
||||
/** Nullability depends on substitution, but the type is not platform: `T` */
|
||||
private val NOT_PLATFORM = JavaTypeQualifiers(NullabilityQualifier.NOT_NULL, null, isNotNullTypeParameter = false)
|
||||
/** Type is always non-nullable: `T & Any` */
|
||||
private val NOT_NULLABLE = JavaTypeQualifiers(NullabilityQualifier.NOT_NULL, null, isNotNullTypeParameter = true)
|
||||
|
||||
@Suppress("LocalVariableName")
|
||||
val PREDEFINED_FUNCTION_ENHANCEMENT_INFO_BY_SIGNATURE = signatures {
|
||||
val JLObject = javaLang("Object")
|
||||
val JFPredicate = javaFunction("Predicate")
|
||||
val JFFunction = javaFunction("Function")
|
||||
val JFConsumer = javaFunction("Consumer")
|
||||
val JFBiFunction = javaFunction("BiFunction")
|
||||
val JFBiConsumer = javaFunction("BiConsumer")
|
||||
val JFUnaryOperator = javaFunction("UnaryOperator")
|
||||
val JUStream = javaUtil("stream/Stream")
|
||||
val JUOptional = javaUtil("Optional")
|
||||
|
||||
enhancement {
|
||||
forClass(javaUtil("Iterator")) {
|
||||
function("forEachRemaining") {
|
||||
parameter(JFConsumer, NOT_PLATFORM, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
forClass(javaLang("Iterable")) {
|
||||
function("spliterator") {
|
||||
returns(javaUtil("Spliterator"), NOT_PLATFORM, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
forClass(javaUtil("Collection")) {
|
||||
function("removeIf") {
|
||||
parameter(JFPredicate, NOT_PLATFORM, NOT_PLATFORM)
|
||||
returns(BOOLEAN)
|
||||
}
|
||||
function("stream") {
|
||||
returns(JUStream, NOT_PLATFORM, NOT_PLATFORM)
|
||||
}
|
||||
function("parallelStream") {
|
||||
returns(JUStream, NOT_PLATFORM, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
forClass(javaUtil("List")) {
|
||||
function("replaceAll") {
|
||||
parameter(JFUnaryOperator, NOT_PLATFORM, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
forClass(javaUtil("Map")) {
|
||||
function("forEach") {
|
||||
parameter(JFBiConsumer, NOT_PLATFORM, NOT_PLATFORM, NOT_PLATFORM)
|
||||
}
|
||||
function("putIfAbsent") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
returns(JLObject, NULLABLE)
|
||||
}
|
||||
function("replace") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
returns(JLObject, NULLABLE)
|
||||
|
||||
}
|
||||
function("replace") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
returns(BOOLEAN)
|
||||
}
|
||||
function("replaceAll") {
|
||||
parameter(JFBiFunction, NOT_PLATFORM, NOT_PLATFORM, NOT_PLATFORM, NOT_PLATFORM)
|
||||
}
|
||||
function("compute") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JFBiFunction, NOT_PLATFORM, NOT_PLATFORM, NULLABLE, NULLABLE)
|
||||
returns(JLObject, NULLABLE)
|
||||
}
|
||||
// while it is possible to return nullable value from lambda in computeIfAbsent,
|
||||
// we deliberately make it just NOT_PLATFORM V in order to have the return type V and not V?
|
||||
function("computeIfAbsent") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JFFunction, NOT_PLATFORM, NOT_PLATFORM, NOT_PLATFORM)
|
||||
returns(JLObject, NOT_PLATFORM)
|
||||
}
|
||||
function("computeIfPresent") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JFBiFunction, NOT_PLATFORM, NOT_PLATFORM, NOT_NULLABLE, NULLABLE)
|
||||
returns(JLObject, NULLABLE)
|
||||
}
|
||||
function("merge") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JLObject, NOT_NULLABLE)
|
||||
parameter(JFBiFunction, NOT_PLATFORM, NOT_NULLABLE, NOT_NULLABLE, NULLABLE)
|
||||
returns(JLObject, NULLABLE)
|
||||
}
|
||||
}
|
||||
forClass(JUOptional) {
|
||||
function("empty") {
|
||||
returns(JUOptional, NOT_PLATFORM, NOT_NULLABLE)
|
||||
}
|
||||
function("of") {
|
||||
parameter(JLObject, NOT_NULLABLE)
|
||||
returns(JUOptional, NOT_PLATFORM, NOT_NULLABLE)
|
||||
}
|
||||
function("ofNullable") {
|
||||
parameter(JLObject, NULLABLE)
|
||||
returns(JUOptional, NOT_PLATFORM, NOT_NULLABLE)
|
||||
}
|
||||
function("get") {
|
||||
returns(JLObject, NOT_NULLABLE)
|
||||
}
|
||||
function("ifPresent") {
|
||||
parameter(JFConsumer, NOT_PLATFORM, NOT_NULLABLE)
|
||||
}
|
||||
}
|
||||
|
||||
forClass(javaLang("ref/Reference")) {
|
||||
function("get") {
|
||||
returns(JLObject, NULLABLE)
|
||||
}
|
||||
}
|
||||
|
||||
forClass(JFPredicate) {
|
||||
function("test") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
returns(BOOLEAN)
|
||||
}
|
||||
}
|
||||
forClass(javaFunction("BiPredicate")) {
|
||||
function("test") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
returns(BOOLEAN)
|
||||
}
|
||||
}
|
||||
forClass(JFConsumer) {
|
||||
function("accept") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
forClass(JFBiConsumer) {
|
||||
function("accept") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
forClass(JFFunction) {
|
||||
function("apply") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
returns(JLObject, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
forClass(JFBiFunction) {
|
||||
function("apply") {
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
parameter(JLObject, NOT_PLATFORM)
|
||||
returns(JLObject, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
forClass(javaFunction("Supplier")) {
|
||||
function("get") {
|
||||
returns(JLObject, NOT_PLATFORM)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private inline fun enhancement(block: SignatureEnhancementBuilder.() -> Unit): Map<String, PredefinedFunctionEnhancementInfo> =
|
||||
SignatureEnhancementBuilder().apply(block).build()
|
||||
|
||||
private class SignatureEnhancementBuilder {
|
||||
private val signatures = mutableMapOf<String, PredefinedFunctionEnhancementInfo>()
|
||||
|
||||
inline fun forClass(internalName: String, block: ClassEnhancementBuilder.() -> Unit) =
|
||||
ClassEnhancementBuilder(internalName).block()
|
||||
|
||||
inner class ClassEnhancementBuilder(val className: String) {
|
||||
fun function(name: String, block: FunctionEnhancementBuilder.() -> Unit) {
|
||||
signatures += FunctionEnhancementBuilder(name).apply(block).build()
|
||||
}
|
||||
|
||||
inner class FunctionEnhancementBuilder(val functionName: String) {
|
||||
private val parameters = mutableListOf<Pair<String, TypeEnhancementInfo?>>()
|
||||
private var returnType: Pair<String, TypeEnhancementInfo?> = "V" to null
|
||||
|
||||
fun parameter(type: String, vararg pairs: Pair<Int, JavaTypeQualifiers>) {
|
||||
parameters += type to
|
||||
if (pairs.isEmpty()) null else TypeEnhancementInfo(*pairs)
|
||||
}
|
||||
|
||||
fun parameter(type: String, vararg qualifiers: JavaTypeQualifiers) {
|
||||
parameters += type to
|
||||
if (qualifiers.isEmpty()) null else TypeEnhancementInfo(
|
||||
qualifiers.withIndex().associateBy(
|
||||
{ it.index },
|
||||
{ it.value })
|
||||
)
|
||||
}
|
||||
|
||||
fun returns(type: String, vararg pairs: Pair<Int, JavaTypeQualifiers>) {
|
||||
returnType = type to TypeEnhancementInfo(*pairs)
|
||||
}
|
||||
|
||||
fun returns(type: String, vararg qualifiers: JavaTypeQualifiers) {
|
||||
returnType = type to TypeEnhancementInfo(qualifiers.withIndex().associateBy({ it.index }, { it.value }))
|
||||
}
|
||||
|
||||
fun returns(type: JvmPrimitiveType) {
|
||||
returnType = type.desc to null
|
||||
}
|
||||
|
||||
fun build() = with(SignatureBuildingComponents) {
|
||||
signature(className, jvmDescriptor(functionName, parameters.map { it.first }, returnType.first)) to
|
||||
PredefinedFunctionEnhancementInfo(returnType.second, parameters.map { it.second })
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun build(): Map<String, PredefinedFunctionEnhancementInfo> = signatures
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.java.typeEnhancement
|
||||
|
||||
fun createJavaTypeQualifiers(
|
||||
nullability: NullabilityQualifier?,
|
||||
mutability: MutabilityQualifier?,
|
||||
forWarning: Boolean,
|
||||
isAnyNonNullTypeParameter: Boolean
|
||||
): JavaTypeQualifiers {
|
||||
if (!isAnyNonNullTypeParameter || nullability != NullabilityQualifier.NOT_NULL) {
|
||||
return JavaTypeQualifiers(nullability, mutability, false, forWarning)
|
||||
}
|
||||
return JavaTypeQualifiers(nullability, mutability, true, forWarning)
|
||||
}
|
||||
|
||||
fun <T : Any> Set<T>.select(low: T, high: T, own: T?, isCovariant: Boolean): T? {
|
||||
if (isCovariant) {
|
||||
val supertypeQualifier = if (low in this) low else if (high in this) high else null
|
||||
return if (supertypeQualifier == low && own == high) null else own ?: supertypeQualifier
|
||||
}
|
||||
|
||||
// isInvariant
|
||||
val effectiveSet = own?.let { (this + own).toSet() } ?: this
|
||||
// if this set contains exactly one element, it is the qualifier everybody agrees upon,
|
||||
// otherwise (no qualifiers, or multiple qualifiers), there's no single such qualifier
|
||||
// and all qualifiers are discarded
|
||||
return effectiveSet.singleOrNull()
|
||||
}
|
||||
|
||||
fun Set<NullabilityQualifier>.select(own: NullabilityQualifier?, isCovariant: Boolean) =
|
||||
if (own == NullabilityQualifier.FORCE_FLEXIBILITY)
|
||||
NullabilityQualifier.FORCE_FLEXIBILITY
|
||||
else
|
||||
select(NullabilityQualifier.NOT_NULL, NullabilityQualifier.NULLABLE, own, isCovariant)
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.java.typeEnhancement
|
||||
|
||||
enum class NullabilityQualifier {
|
||||
NULLABLE,
|
||||
NOT_NULL,
|
||||
FORCE_FLEXIBILITY
|
||||
}
|
||||
|
||||
enum class MutabilityQualifier {
|
||||
READ_ONLY,
|
||||
MUTABLE
|
||||
}
|
||||
|
||||
class JavaTypeQualifiers(
|
||||
val nullability: NullabilityQualifier?,
|
||||
val mutability: MutabilityQualifier?,
|
||||
val isNotNullTypeParameter: Boolean,
|
||||
val isNullabilityQualifierForWarning: Boolean = false
|
||||
) {
|
||||
companion object {
|
||||
val NONE = JavaTypeQualifiers(null, null, false)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassData
|
||||
|
||||
interface PackagePartProvider {
|
||||
/**
|
||||
* @return JVM internal names of package parts existing in the package with the given FQ name.
|
||||
*
|
||||
* For example, if a file named foo.kt in package org.test is compiled to a library, PackagePartProvider for such library
|
||||
* must return the list `["org/test/FooKt"]` for the query `"org.test"`
|
||||
* (in case the file is not annotated with @JvmName, @JvmPackageName or @JvmMultifileClass).
|
||||
*/
|
||||
fun findPackageParts(packageFqName: String): List<String>
|
||||
|
||||
fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId>
|
||||
|
||||
fun getAllOptionalAnnotationClasses(): List<ClassData>
|
||||
|
||||
object Empty : PackagePartProvider {
|
||||
override fun findPackageParts(packageFqName: String): List<String> = emptyList()
|
||||
|
||||
override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> = emptyList()
|
||||
|
||||
override fun getAllOptionalAnnotationClasses(): List<ClassData> = emptyList()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user