Minor: refactoring & fix warnings

This commit is contained in:
Dmitry Gridin
2019-03-05 11:25:07 +03:00
parent f1e66d0654
commit 57040f6f9d
7 changed files with 168 additions and 168 deletions
@@ -29,40 +29,40 @@ fun ClassifierDescriptorWithTypeParameters.computeConstructorTypeParameters(): L
if (!isInner && containingDeclaration !is CallableDescriptor) return declaredParameters if (!isInner && containingDeclaration !is CallableDescriptor) return declaredParameters
val parametersFromContainingFunctions = val parametersFromContainingFunctions =
parents.takeWhile { it is CallableDescriptor } parents.takeWhile { it is CallableDescriptor }
.flatMap { (it as CallableDescriptor).typeParameters.asSequence() }.toList() .flatMap { (it as CallableDescriptor).typeParameters.asSequence() }.toList()
val containingClassTypeConstructorParameters = parents.firstIsInstanceOrNull<ClassDescriptor>()?.typeConstructor?.parameters.orEmpty() val containingClassTypeConstructorParameters = parents.firstIsInstanceOrNull<ClassDescriptor>()?.typeConstructor?.parameters.orEmpty()
if (parametersFromContainingFunctions.isEmpty() && containingClassTypeConstructorParameters.isEmpty()) return declaredTypeParameters if (parametersFromContainingFunctions.isEmpty() && containingClassTypeConstructorParameters.isEmpty()) return declaredTypeParameters
val additional = val additional =
(parametersFromContainingFunctions + containingClassTypeConstructorParameters) (parametersFromContainingFunctions + containingClassTypeConstructorParameters)
.map { it.capturedCopyForInnerDeclaration(this, declaredParameters.size) } .map { it.capturedCopyForInnerDeclaration(this, declaredParameters.size) }
return declaredParameters + additional return declaredParameters + additional
} }
private fun TypeParameterDescriptor.capturedCopyForInnerDeclaration( private fun TypeParameterDescriptor.capturedCopyForInnerDeclaration(
declarationDescriptor: DeclarationDescriptor, declarationDescriptor: DeclarationDescriptor,
declaredTypeParametersCount: Int declaredTypeParametersCount: Int
) = CapturedTypeParameterDescriptor(this, declarationDescriptor, declaredTypeParametersCount) ) = CapturedTypeParameterDescriptor(this, declarationDescriptor, declaredTypeParametersCount)
private class CapturedTypeParameterDescriptor( private class CapturedTypeParameterDescriptor(
private val originalDescriptor: TypeParameterDescriptor, private val originalDescriptor: TypeParameterDescriptor,
private val declarationDescriptor: DeclarationDescriptor, private val declarationDescriptor: DeclarationDescriptor,
private val declaredTypeParametersCount: Int private val declaredTypeParametersCount: Int
) : TypeParameterDescriptor by originalDescriptor { ) : TypeParameterDescriptor by originalDescriptor {
override fun isCapturedFromOuterDeclaration() = true override fun isCapturedFromOuterDeclaration() = true
override fun getOriginal() = originalDescriptor.original override fun getOriginal() = originalDescriptor.original
override fun getContainingDeclaration() = declarationDescriptor override fun getContainingDeclaration() = declarationDescriptor
override fun getIndex() = declaredTypeParametersCount + originalDescriptor.index override fun getIndex() = declaredTypeParametersCount + originalDescriptor.index
override fun toString() = originalDescriptor.toString() + "[inner-copy]" override fun toString() = "$originalDescriptor[inner-copy]"
} }
class PossiblyInnerType( class PossiblyInnerType(
val classifierDescriptor: ClassifierDescriptorWithTypeParameters, val classifierDescriptor: ClassifierDescriptorWithTypeParameters,
val arguments: List<TypeProjection>, val arguments: List<TypeProjection>,
val outerType: PossiblyInnerType? val outerType: PossiblyInnerType?
) { ) {
val classDescriptor: ClassDescriptor val classDescriptor: ClassDescriptor
get() = classifierDescriptor as ClassDescriptor get() = classifierDescriptor as ClassDescriptor
@@ -74,7 +74,10 @@ fun KotlinType.buildPossiblyInnerType(): PossiblyInnerType? {
return buildPossiblyInnerType(constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters, 0) return buildPossiblyInnerType(constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters, 0)
} }
private fun KotlinType.buildPossiblyInnerType(classifierDescriptor: ClassifierDescriptorWithTypeParameters?, index: Int): PossiblyInnerType? { private fun KotlinType.buildPossiblyInnerType(
classifierDescriptor: ClassifierDescriptorWithTypeParameters?,
index: Int
): PossiblyInnerType? {
if (classifierDescriptor == null || ErrorUtils.isError(classifierDescriptor)) return null if (classifierDescriptor == null || ErrorUtils.isError(classifierDescriptor)) return null
val toIndex = classifierDescriptor.declaredTypeParameters.size + index val toIndex = classifierDescriptor.declaredTypeParameters.size + index
@@ -88,6 +91,7 @@ private fun KotlinType.buildPossiblyInnerType(classifierDescriptor: ClassifierDe
val argumentsSubList = arguments.subList(index, toIndex) val argumentsSubList = arguments.subList(index, toIndex)
return PossiblyInnerType( return PossiblyInnerType(
classifierDescriptor, argumentsSubList, classifierDescriptor, argumentsSubList,
buildPossiblyInnerType(classifierDescriptor.containingDeclaration as? ClassifierDescriptorWithTypeParameters, toIndex)) buildPossiblyInnerType(classifierDescriptor.containingDeclaration as? ClassifierDescriptorWithTypeParameters, toIndex)
)
} }
@@ -82,7 +82,7 @@ abstract class WrappedType : KotlinType() {
override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable
override val memberScope: MemberScope get() = delegate.memberScope override val memberScope: MemberScope get() = delegate.memberScope
override final fun unwrap(): UnwrappedType { final override fun unwrap(): UnwrappedType {
var result = delegate var result = delegate
while (result is WrappedType) { while (result is WrappedType) {
result = result.delegate result = result.delegate
@@ -93,8 +93,7 @@ abstract class WrappedType : KotlinType() {
override fun toString(): String { override fun toString(): String {
return if (isComputed()) { return if (isComputed()) {
delegate.toString() delegate.toString()
} } else {
else {
"<Not computed yet>" "<Not computed yet>"
} }
} }
@@ -111,11 +110,11 @@ abstract class WrappedType : KotlinType() {
* *
* todo: specify what happens with internal structure when we apply some [TypeSubstitutor] * todo: specify what happens with internal structure when we apply some [TypeSubstitutor]
*/ */
sealed class UnwrappedType: KotlinType() { sealed class UnwrappedType : KotlinType() {
abstract fun replaceAnnotations(newAnnotations: Annotations): UnwrappedType abstract fun replaceAnnotations(newAnnotations: Annotations): UnwrappedType
abstract fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType abstract fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType
override final fun unwrap(): UnwrappedType = this final override fun unwrap(): UnwrappedType = this
} }
/** /**
@@ -134,7 +133,7 @@ abstract class SimpleType : UnwrappedType(), SimpleTypeMarker, TypeArgumentListM
} }
append(constructor) append(constructor)
if (!arguments.isEmpty()) arguments.joinTo(this, separator = ", ", prefix = "<", postfix = ">") if (arguments.isNotEmpty()) arguments.joinTo(this, separator = ", ", prefix = "<", postfix = ">")
if (isMarkedNullable) append("?") if (isMarkedNullable) append("?")
} }
} }
@@ -142,7 +141,7 @@ abstract class SimpleType : UnwrappedType(), SimpleTypeMarker, TypeArgumentListM
// lowerBound is a subtype of upperBound // lowerBound is a subtype of upperBound
abstract class FlexibleType(val lowerBound: SimpleType, val upperBound: SimpleType) : abstract class FlexibleType(val lowerBound: SimpleType, val upperBound: SimpleType) :
UnwrappedType(), SubtypingRepresentatives, FlexibleTypeMarker { UnwrappedType(), SubtypingRepresentatives, FlexibleTypeMarker {
abstract val delegate: SimpleType abstract val delegate: SimpleType
@@ -167,5 +166,5 @@ abstract class FlexibleType(val lowerBound: SimpleType, val upperBound: SimpleTy
val KotlinType.isError: Boolean val KotlinType.isError: Boolean
get() = unwrap().let { unwrapped -> get() = unwrap().let { unwrapped ->
unwrapped is ErrorType || unwrapped is ErrorType ||
(unwrapped is FlexibleType && unwrapped.delegate is ErrorType) (unwrapped is FlexibleType && unwrapped.delegate is ErrorType)
} }
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
import java.lang.IllegalStateException
object KotlinTypeFactory { object KotlinTypeFactory {
private fun computeMemberScope(constructor: TypeConstructor, arguments: List<TypeProjection>): MemberScope { private fun computeMemberScope(constructor: TypeConstructor, arguments: List<TypeProjection>): MemberScope {
@@ -41,48 +40,54 @@ object KotlinTypeFactory {
@JvmStatic @JvmStatic
fun simpleType( fun simpleType(
annotations: Annotations, annotations: Annotations,
constructor: TypeConstructor, constructor: TypeConstructor,
arguments: List<TypeProjection>, arguments: List<TypeProjection>,
nullable: Boolean nullable: Boolean
): SimpleType { ): SimpleType {
if (annotations.isEmpty() && arguments.isEmpty() && !nullable && constructor.declarationDescriptor != null) { if (annotations.isEmpty() && arguments.isEmpty() && !nullable && constructor.declarationDescriptor != null) {
return constructor.declarationDescriptor!!.defaultType return constructor.declarationDescriptor!!.defaultType
} }
return simpleTypeWithNonTrivialMemberScope(annotations, constructor, arguments, nullable, computeMemberScope(constructor, arguments)) return simpleTypeWithNonTrivialMemberScope(
annotations,
constructor,
arguments,
nullable,
computeMemberScope(constructor, arguments)
)
} }
@JvmStatic @JvmStatic
fun simpleTypeWithNonTrivialMemberScope( fun simpleTypeWithNonTrivialMemberScope(
annotations: Annotations, annotations: Annotations,
constructor: TypeConstructor, constructor: TypeConstructor,
arguments: List<TypeProjection>, arguments: List<TypeProjection>,
nullable: Boolean, nullable: Boolean,
memberScope: MemberScope memberScope: MemberScope
): SimpleType = ): SimpleType =
SimpleTypeImpl(constructor, arguments, nullable, memberScope) SimpleTypeImpl(constructor, arguments, nullable, memberScope)
.let { .let {
if (annotations.isEmpty()) if (annotations.isEmpty())
it it
else else
AnnotatedSimpleType(it, annotations) AnnotatedSimpleType(it, annotations)
} }
@JvmStatic @JvmStatic
fun simpleNotNullType( fun simpleNotNullType(
annotations: Annotations, annotations: Annotations,
descriptor: ClassDescriptor, descriptor: ClassDescriptor,
arguments: List<TypeProjection> arguments: List<TypeProjection>
): SimpleType = simpleType(annotations, descriptor.typeConstructor, arguments, nullable = false) ): SimpleType = simpleType(annotations, descriptor.typeConstructor, arguments, nullable = false)
@JvmStatic @JvmStatic
fun simpleType( fun simpleType(
baseType: SimpleType, baseType: SimpleType,
annotations: Annotations = baseType.annotations, annotations: Annotations = baseType.annotations,
constructor: TypeConstructor = baseType.constructor, constructor: TypeConstructor = baseType.constructor,
arguments: List<TypeProjection> = baseType.arguments, arguments: List<TypeProjection> = baseType.arguments,
nullable: Boolean = baseType.isMarkedNullable nullable: Boolean = baseType.isMarkedNullable
): SimpleType = simpleType(annotations, constructor, arguments, nullable) ): SimpleType = simpleType(annotations, constructor, arguments, nullable)
@JvmStatic @JvmStatic
@@ -93,26 +98,24 @@ object KotlinTypeFactory {
} }
private class SimpleTypeImpl( private class SimpleTypeImpl(
override val constructor: TypeConstructor, override val constructor: TypeConstructor,
override val arguments: List<TypeProjection>, override val arguments: List<TypeProjection>,
override val isMarkedNullable: Boolean, override val isMarkedNullable: Boolean,
override val memberScope: MemberScope override val memberScope: MemberScope
) : SimpleType() { ) : SimpleType() {
override val annotations: Annotations get() = Annotations.EMPTY override val annotations: Annotations get() = Annotations.EMPTY
override fun replaceAnnotations(newAnnotations: Annotations) = override fun replaceAnnotations(newAnnotations: Annotations) =
if (newAnnotations.isEmpty()) if (newAnnotations.isEmpty())
this this
else else
AnnotatedSimpleType(this, newAnnotations) AnnotatedSimpleType(this, newAnnotations)
override fun makeNullableAsSpecified(newNullability: Boolean) = override fun makeNullableAsSpecified(newNullability: Boolean) = when {
if (newNullability == isMarkedNullable) newNullability == isMarkedNullable -> this
this newNullability -> NullableSimpleType(this)
else if (newNullability) else -> NotNullSimpleType(this)
NullableSimpleType(this) }
else
NotNullSimpleType(this)
init { init {
if (memberScope is ErrorUtils.ErrorScope) { if (memberScope is ErrorUtils.ErrorScope) {
@@ -123,10 +126,10 @@ private class SimpleTypeImpl(
abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : DelegatingSimpleType() { abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : DelegatingSimpleType() {
override fun replaceAnnotations(newAnnotations: Annotations) = override fun replaceAnnotations(newAnnotations: Annotations) =
if (newAnnotations !== annotations) if (newAnnotations !== annotations)
AnnotatedSimpleType(this, newAnnotations) AnnotatedSimpleType(this, newAnnotations)
else else
this this
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType { override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType {
if (newNullability == isMarkedNullable) return this if (newNullability == isMarkedNullable) return this
@@ -135,8 +138,8 @@ abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : Del
} }
private class AnnotatedSimpleType( private class AnnotatedSimpleType(
delegate: SimpleType, delegate: SimpleType,
override val annotations: Annotations override val annotations: Annotations
) : DelegatingSimpleTypeImpl(delegate) ) : DelegatingSimpleTypeImpl(delegate)
private class NullableSimpleType(delegate: SimpleType) : DelegatingSimpleTypeImpl(delegate) { private class NullableSimpleType(delegate: SimpleType) : DelegatingSimpleTypeImpl(delegate) {
@@ -27,7 +27,7 @@ import java.util.*
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
class SmartSet<T> private constructor() : AbstractSet<T>() { class SmartSet<T> private constructor() : AbstractSet<T>() {
companion object { companion object {
private val ARRAY_THRESHOLD = 5 private const val ARRAY_THRESHOLD = 5
@JvmStatic @JvmStatic
fun <T> create() = SmartSet<T>() fun <T> create() = SmartSet<T>()
@@ -42,11 +42,11 @@ class SmartSet<T> private constructor() : AbstractSet<T>() {
override var size: Int = 0 override var size: Int = 0
override fun iterator(): MutableIterator<T> = when { override fun iterator(): MutableIterator<T> = when {
size == 0 -> Collections.emptySet<T>().iterator() size == 0 -> Collections.emptySet<T>().iterator()
size == 1 -> SingletonIterator(data as T) size == 1 -> SingletonIterator(data as T)
size < ARRAY_THRESHOLD -> ArrayIterator(data as Array<T>) size < ARRAY_THRESHOLD -> ArrayIterator(data as Array<T>)
else -> (data as MutableSet<T>).iterator() else -> (data as MutableSet<T>).iterator()
} }
override fun add(element: T): Boolean { override fun add(element: T): Boolean {
when { when {
@@ -61,7 +61,7 @@ class SmartSet<T> private constructor() : AbstractSet<T>() {
val arr = data as Array<T> val arr = data as Array<T>
if (element in arr) return false if (element in arr) return false
data = if (size == ARRAY_THRESHOLD - 1) linkedSetOf(*arr).apply { add(element) } data = if (size == ARRAY_THRESHOLD - 1) linkedSetOf(*arr).apply { add(element) }
else Arrays.copyOf(arr, size + 1).apply { set(size - 1, element) } else arr.copyOf(size + 1).apply { set(size - 1, element) }
} }
else -> { else -> {
val set = data as MutableSet<T> val set = data as MutableSet<T>
@@ -89,11 +89,10 @@ class SmartSet<T> private constructor() : AbstractSet<T>() {
private var hasNext = true private var hasNext = true
override fun next(): T = override fun next(): T =
if (hasNext) { if (hasNext) {
hasNext = false hasNext = false
element element
} } else throw NoSuchElementException()
else throw NoSuchElementException()
override fun hasNext() = hasNext override fun hasNext() = hasNext
@@ -33,16 +33,16 @@ import org.jetbrains.kotlin.types.typeUtil.*
import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.SmartSet
fun KotlinType.approximateFlexibleTypes( fun KotlinType.approximateFlexibleTypes(
preferNotNull: Boolean = false, preferNotNull: Boolean = false,
preferStarForRaw: Boolean = false preferStarForRaw: Boolean = false
): KotlinType { ): KotlinType {
if (isDynamic()) return this if (isDynamic()) return this
return unwrapEnhancement().approximateNonDynamicFlexibleTypes(preferNotNull, preferStarForRaw) return unwrapEnhancement().approximateNonDynamicFlexibleTypes(preferNotNull, preferStarForRaw)
} }
private fun KotlinType.approximateNonDynamicFlexibleTypes( private fun KotlinType.approximateNonDynamicFlexibleTypes(
preferNotNull: Boolean = false, preferNotNull: Boolean = false,
preferStarForRaw: Boolean = false preferStarForRaw: Boolean = false
): SimpleType { ): SimpleType {
if (this is ErrorType) return this if (this is ErrorType) return this
@@ -55,10 +55,10 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes(
// Foo! -> Foo? // Foo! -> Foo?
// Foo<Bar!>! -> Foo<Bar>? // Foo<Bar!>! -> Foo<Bar>?
var approximation = var approximation =
if (isCollection) if (isCollection)
flexible.lowerBound.makeNullableAsSpecified(!preferNotNull) flexible.lowerBound.makeNullableAsSpecified(!preferNotNull)
else else
if (this is RawType && preferStarForRaw) flexible.upperBound.makeNullableAsSpecified(!preferNotNull) if (this is RawType && preferStarForRaw) flexible.upperBound.makeNullableAsSpecified(!preferNotNull)
else else
if (preferNotNull) flexible.lowerBound else flexible.upperBound if (preferNotNull) flexible.lowerBound else flexible.upperBound
@@ -66,7 +66,10 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes(
approximation = if (nullability() == TypeNullability.NOT_NULL) approximation.makeNullableAsSpecified(false) else approximation approximation = if (nullability() == TypeNullability.NOT_NULL) approximation.makeNullableAsSpecified(false) else approximation
if (approximation.isMarkedNullable && !flexible.lowerBound.isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType(approximation)) { if (approximation.isMarkedNullable && !flexible.lowerBound.isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType(
approximation
)
) {
approximation = approximation.makeNullableAsSpecified(false) approximation = approximation.makeNullableAsSpecified(false)
} }
@@ -76,11 +79,12 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes(
(unwrap() as? AbbreviatedType)?.let { (unwrap() as? AbbreviatedType)?.let {
return AbbreviatedType(it.expandedType, it.abbreviation.approximateNonDynamicFlexibleTypes(preferNotNull)) return AbbreviatedType(it.expandedType, it.abbreviation.approximateNonDynamicFlexibleTypes(preferNotNull))
} }
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(annotations, return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
constructor, annotations,
arguments.map { it.substitute { type -> type.approximateFlexibleTypes(preferNotNull = true) } }, constructor,
isMarkedNullable, arguments.map { it.substitute { type -> type.approximateFlexibleTypes(preferNotNull = true) } },
ErrorUtils.createErrorScope("This type is not supposed to be used in member resolution", true) isMarkedNullable,
ErrorUtils.createErrorScope("This type is not supposed to be used in member resolution", true)
) )
} }
@@ -102,7 +106,7 @@ fun KotlinType.isResolvableInScope(scope: LexicalScope?, checkTypeParameters: Bo
fun KotlinType.approximateWithResolvableType(scope: LexicalScope?, checkTypeParameters: Boolean): KotlinType { fun KotlinType.approximateWithResolvableType(scope: LexicalScope?, checkTypeParameters: Boolean): KotlinType {
if (isError || isResolvableInScope(scope, checkTypeParameters)) return this if (isError || isResolvableInScope(scope, checkTypeParameters)) return this
return supertypes().firstOrNull { it.isResolvableInScope(scope, checkTypeParameters) } return supertypes().firstOrNull { it.isResolvableInScope(scope, checkTypeParameters) }
?: builtIns.anyType ?: builtIns.anyType
} }
fun KotlinType.anonymousObjectSuperTypeOrNull(): KotlinType? { fun KotlinType.anonymousObjectSuperTypeOrNull(): KotlinType? {
@@ -114,34 +118,39 @@ fun KotlinType.anonymousObjectSuperTypeOrNull(): KotlinType? {
} }
fun KotlinType.getResolvableApproximations( fun KotlinType.getResolvableApproximations(
scope: LexicalScope?, scope: LexicalScope?,
checkTypeParameters: Boolean, checkTypeParameters: Boolean,
allowIntersections: Boolean = false allowIntersections: Boolean = false
): Sequence<KotlinType> { ): Sequence<KotlinType> {
return (listOf(this) + TypeUtils.getAllSupertypes(this)) return (listOf(this) + TypeUtils.getAllSupertypes(this))
.asSequence() .asSequence()
.filter { it.isResolvableInScope(scope, checkTypeParameters, allowIntersections) } .filter { it.isResolvableInScope(scope, checkTypeParameters, allowIntersections) }
.mapNotNull mapArgs@ { .mapNotNull mapArgs@{
val resolvableArgs = it.arguments.filterTo(SmartSet.create()) { it.type.isResolvableInScope(scope, checkTypeParameters) } val resolvableArgs = it.arguments.filterTo(SmartSet.create()) { typeProjection ->
if (resolvableArgs.containsAll(it.arguments)) return@mapArgs it typeProjection.type.isResolvableInScope(
scope,
val newArguments = (it.arguments zip it.constructor.parameters).map { checkTypeParameters
val (arg, param) = it )
when {
arg in resolvableArgs -> arg
arg.projectionKind == Variance.OUT_VARIANCE ||
param.variance == Variance.OUT_VARIANCE -> TypeProjectionImpl(
arg.projectionKind,
arg.type.approximateWithResolvableType(scope, checkTypeParameters)
)
else -> return@mapArgs null
}
}
it.replace(newArguments)
} }
if (resolvableArgs.containsAll(it.arguments)) return@mapArgs it
val newArguments = (it.arguments zip it.constructor.parameters).map { pair ->
val (arg, param) = pair
when {
arg in resolvableArgs -> arg
arg.projectionKind == Variance.OUT_VARIANCE ||
param.variance == Variance.OUT_VARIANCE -> TypeProjectionImpl(
arg.projectionKind,
arg.type.approximateWithResolvableType(scope, checkTypeParameters)
)
else -> return@mapArgs null
}
}
it.replace(newArguments)
}
} }
fun KotlinType.isAbstract(): Boolean { fun KotlinType.isAbstract(): Boolean {
@@ -185,7 +185,8 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention<KtCallableDec
private class TypeChooseValueExpression( private class TypeChooseValueExpression(
items: List<KotlinType>, defaultItem: KotlinType items: List<KotlinType>, defaultItem: KotlinType
) : ChooseValueExpression<KotlinType>(items, defaultItem) { ) : ChooseValueExpression<KotlinType>(items, defaultItem) {
override fun getLookupString(element: KotlinType) = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(element) override fun getLookupString(element: KotlinType) =
IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(element)
override fun getResult(element: KotlinType): String { override fun getResult(element: KotlinType): String {
val renderType = IdeDescriptorRenderers.SOURCE_CODE.renderType(element) val renderType = IdeDescriptorRenderers.SOURCE_CODE.renderType(element)
@@ -107,11 +107,12 @@ private fun List<Instruction>.getVarDescriptorsAccessedAfterwards(bindingContext
fun doTraversal(instruction: Instruction) { fun doTraversal(instruction: Instruction) {
traverseFollowingInstructions(instruction, visitedInstructions) { traverseFollowingInstructions(instruction, visitedInstructions) {
when { when {
it is AccessValueInstruction && it !in this -> it is AccessValueInstruction && it !in this -> PseudocodeUtil.extractVariableDescriptorIfAny(
PseudocodeUtil.extractVariableDescriptorIfAny(it, bindingContext)?.let { accessedAfterwards.add(it) } it,
bindingContext
)?.let { descriptor -> accessedAfterwards.add(descriptor) }
it is LocalFunctionDeclarationInstruction -> it is LocalFunctionDeclarationInstruction -> doTraversal(it.body.enterInstruction)
doTraversal(it.body.enterInstruction)
} }
TraverseInstructionResult.CONTINUE TraverseInstructionResult.CONTINUE
@@ -238,26 +239,18 @@ private fun ExtractionData.analyzeControlFlow(
val jumpExits = ArrayList<AbstractJumpInstruction>() val jumpExits = ArrayList<AbstractJumpInstruction>()
exitPoints.forEach { exitPoints.forEach {
val e = (it as? UnconditionalJumpInstruction)?.element val e = (it as? UnconditionalJumpInstruction)?.element
val inst =
when {
it !is ReturnValueInstruction && it !is ReturnNoValueInstruction && it.owner != pseudocode ->
null
it is UnconditionalJumpInstruction && it.targetLabel.isJumpToError ->
it
e != null && e !is KtBreakExpression && e !is KtContinueExpression ->
it.previousInstructions.firstOrNull()
else ->
it
}
when (inst) { when (val inst = when {
is ReturnValueInstruction -> { it !is ReturnValueInstruction && it !is ReturnNoValueInstruction && it.owner != pseudocode -> null
if (inst.owner == pseudocode) { it is UnconditionalJumpInstruction && it.targetLabel.isJumpToError -> it
if (inst.returnExpressionIfAny == null) { e != null && e !is KtBreakExpression && e !is KtContinueExpression -> it.previousInstructions.firstOrNull()
defaultExits.add(inst) else -> it
} else { }) {
valuedReturnExits.add(inst) is ReturnValueInstruction -> if (inst.owner == pseudocode) {
} if (inst.returnExpressionIfAny == null) {
defaultExits.add(inst)
} else {
valuedReturnExits.add(inst)
} }
} }
@@ -266,16 +259,10 @@ private fun ExtractionData.analyzeControlFlow(
if ((element is KtReturnExpression && inst.owner == pseudocode) if ((element is KtReturnExpression && inst.owner == pseudocode)
|| element is KtBreakExpression || element is KtBreakExpression
|| element is KtContinueExpression || element is KtContinueExpression
) { ) jumpExits.add(inst) else if (element !is KtThrowExpression && !inst.targetLabel.isJumpToError) defaultExits.add(inst)
jumpExits.add(inst)
} else if (element !is KtThrowExpression && !inst.targetLabel.isJumpToError) {
defaultExits.add(inst)
}
} }
else -> if (inst != null && inst !is LocalFunctionDeclarationInstruction) { else -> if (inst != null && inst !is LocalFunctionDeclarationInstruction) defaultExits.add(inst)
defaultExits.add(inst)
}
} }
} }
@@ -306,9 +293,7 @@ private fun ExtractionData.analyzeControlFlow(
val controlFlow = if (defaultReturnType.isMeaningful()) { val controlFlow = if (defaultReturnType.isMeaningful()) {
emptyControlFlow.copy(outputValues = Collections.singletonList(ExpressionValue(false, defaultResultExpressions, defaultReturnType))) emptyControlFlow.copy(outputValues = Collections.singletonList(ExpressionValue(false, defaultResultExpressions, defaultReturnType)))
} else { } else emptyControlFlow
emptyControlFlow
}
if (declarationsToReport.isNotEmpty()) { if (declarationsToReport.isNotEmpty()) {
val localVarStr = declarationsToReport.map { it.renderForMessage(bindingContext)!! }.distinct().sorted() val localVarStr = declarationsToReport.map { it.renderForMessage(bindingContext)!! }.distinct().sorted()
@@ -670,16 +655,16 @@ fun ExtractionData.performAnalysis(): AnalysisResult {
val modifiedVarDescriptorsForControlFlow = HashMap(modifiedVarDescriptorsWithExpressions) val modifiedVarDescriptorsForControlFlow = HashMap(modifiedVarDescriptorsWithExpressions)
modifiedVarDescriptorsForControlFlow.keys.retainAll(localInstructions.getVarDescriptorsAccessedAfterwards(bindingContext)) modifiedVarDescriptorsForControlFlow.keys.retainAll(localInstructions.getVarDescriptorsAccessedAfterwards(bindingContext))
val (controlFlow, controlFlowMessage) = val (controlFlow, controlFlowMessage) =
analyzeControlFlow( analyzeControlFlow(
localInstructions, localInstructions,
pseudocode, pseudocode,
originalFile.findModuleDescriptor(), originalFile.findModuleDescriptor(),
bindingContext, bindingContext,
modifiedVarDescriptorsForControlFlow, modifiedVarDescriptorsForControlFlow,
options, options,
targetScope, targetScope,
paramsInfo.parameters paramsInfo.parameters
) )
controlFlowMessage?.let { messages.add(it) } controlFlowMessage?.let { messages.add(it) }
val returnType = controlFlow.outputValueBoxer.returnType val returnType = controlFlow.outputValueBoxer.returnType