Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.types.checker
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.utils.DO_NOTHING_2
// if input type is capturedType, then we approximate it to UpperBound
// null means that type should be leaved as is
fun prepareArgumentTypeRegardingCaptureTypes(argumentType: UnwrappedType): UnwrappedType? {
val simpleType = NewKotlinTypeChecker.transformToNewType(argumentType.lowerIfFlexible())
if (simpleType.constructor is IntersectionTypeConstructor){
var changed = false
val preparedSuperTypes = simpleType.constructor.supertypes.map {
prepareArgumentTypeRegardingCaptureTypes(it.unwrap())?.apply { changed = true } ?: it.unwrap()
}
if (!changed) return null
return intersectTypes(preparedSuperTypes).makeNullableAsSpecified(simpleType.isMarkedNullable)
}
if (simpleType is NewCapturedType) {
// todo may be we should respect flexible/definitelyNotNull captured types also...
return simpleType.constructor.supertypes.takeIf { it.isNotEmpty() }?.let {
intersectTypes(it).makeNullableAsSpecified(simpleType.isMarkedNullable)
} ?: argumentType.builtIns.nullableAnyType
}
return captureFromExpression(simpleType)
}
fun captureFromExpression(type: UnwrappedType): UnwrappedType? = when (type) {
is SimpleType -> captureFromExpression(type)
// i.e. if there is nothing to capture -- no changes, if there is something -- use lowerBound as base type
is FlexibleType -> captureFromExpression(type.lowerBound)
}
fun captureFromExpression(type: SimpleType): UnwrappedType? {
val typeConstructor = type.constructor
if (typeConstructor is IntersectionTypeConstructor) {
var changed = false
val capturedSupertypes = typeConstructor.supertypes.map {
captureFromExpression(it.unwrap())?.apply { changed = true } ?: it.unwrap()
}
if (!changed) return null
return intersectTypes(capturedSupertypes).makeNullableAsSpecified(type.isMarkedNullable)
}
return captureFromArguments(type, CaptureStatus.FROM_EXPRESSION)
}
// this function suppose that input type is simple classifier type
fun captureFromArguments(
type: SimpleType,
status: CaptureStatus,
acceptNewCapturedType: ((argumentIndex: Int, NewCapturedType) -> Unit) = DO_NOTHING_2
): SimpleType? {
if (type.arguments.size != type.constructor.parameters.size) return null
val arguments = type.arguments
if (arguments.all { it.projectionKind == Variance.INVARIANT }) return null
val newArguments = arguments.map {
projection ->
if (projection.projectionKind == Variance.INVARIANT) return@map projection
val lowerType = if (!projection.isStarProjection && projection.projectionKind == Variance.IN_VARIANCE) {
projection.type.unwrap()
} else null
NewCapturedType(status, lowerType, projection).asTypeProjection() // todo optimization: do not create type projection
}
val substitutor = TypeConstructorSubstitution.create(type.constructor, newArguments).buildSubstitutor()
for (index in arguments.indices) {
val oldProjection = arguments[index]
val newProjection = newArguments[index]
if (oldProjection.projectionKind == Variance.INVARIANT) continue
var upperBounds = type.constructor.parameters[index].upperBounds.map {
NewKotlinTypeChecker.transformToNewType(substitutor.safeSubstitute(it, Variance.INVARIANT).unwrap())
}
if (!oldProjection.isStarProjection && oldProjection.projectionKind == Variance.OUT_VARIANCE) {
upperBounds += NewKotlinTypeChecker.transformToNewType(oldProjection.type.unwrap())
}
val capturedType = newProjection.type as NewCapturedType
capturedType.constructor.initializeSupertypes(upperBounds)
acceptNewCapturedType(index, capturedType)
}
return KotlinTypeFactory.simpleType(type.annotations, type.constructor, newArguments, type.isMarkedNullable)
}
enum class CaptureStatus {
FOR_SUBTYPING,
FOR_INCORPORATION,
FROM_EXPRESSION
}
/**
* Now [lowerType] is not null only for in projections.
* Example: `Inv` For `in String` we create CapturedType with [lowerType] = String.
*
* TODO: interface D, D<*, List> -> D>
* We should set [lowerType] for Q as Number. For this we should use constraint system.
*
*/
class NewCapturedType(
val captureStatus: CaptureStatus,
override val constructor: NewCapturedTypeConstructor,
val lowerType: UnwrappedType?, // todo check lower type for nullable captured types
override val annotations: Annotations = Annotations.EMPTY,
override val isMarkedNullable: Boolean = false
): SimpleType() {
internal constructor(captureStatus: CaptureStatus, lowerType: UnwrappedType?, projection: TypeProjection) :
this(captureStatus, NewCapturedTypeConstructor(projection), lowerType)
override val arguments: List get() = listOf()
override val memberScope: MemberScope // todo what about foo().bar() where foo() return captured type?
get() = ErrorUtils.createErrorScope("No member resolution should be done on captured type!", true)
override fun replaceAnnotations(newAnnotations: Annotations) =
NewCapturedType(captureStatus, constructor, lowerType, newAnnotations, isMarkedNullable)
override fun makeNullableAsSpecified(newNullability: Boolean) =
NewCapturedType(captureStatus, constructor, lowerType, annotations, newNullability)
}
class NewCapturedTypeConstructor(val projection: TypeProjection, private var supertypes: List? = null) : TypeConstructor {
fun initializeSupertypes(supertypes: List) {
assert(this.supertypes == null) {
"Already initialized! oldValue = ${this.supertypes}, newValue = $supertypes"
}
this.supertypes = supertypes
}
override fun getSupertypes() = supertypes ?: emptyList()
override fun getParameters(): List = emptyList()
override fun isFinal() = false
override fun isDenotable() = false
override fun getDeclarationDescriptor(): ClassifierDescriptor? = null
override fun getBuiltIns(): KotlinBuiltIns = projection.type.builtIns
override fun toString() = "CapturedType($projection)"
}