Minor: refactoring & fix warnings
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
+29
-44
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user