Introduce CustomSubstitutionCapability.substitutionToComposeWith

Mainly it's needed to prevent creation of subsituions composition
everytime we replacing arguments, because it's both unoptimal and wrong

When replace arguments in `A<E, F>` with <String, E> you got `A<String, String>`
as a result, that is unexpected.

But composition is only needed when previous substituion was abnormal
(e.g. RawSubsitution that should actually wrap new arguments), see RawTypes tests
This commit is contained in:
Denis Zharkov
2015-12-21 20:01:38 +03:00
parent 8d0a90a838
commit 7aaa6422b4
3 changed files with 8 additions and 10 deletions
@@ -28,7 +28,10 @@ public object RawTypeTag : TypeCapability
public object RawTypeCapabilities : TypeCapabilities {
private object RawSubstitutionCapability : CustomSubstitutionCapability {
override val substitution = RawSubstitution
override val substitution: TypeSubstitution?
get() = RawSubstitution
override val substitutionToComposeWith: TypeSubstitution?
get() = RawSubstitution
}
private object RawFlexibleRendering : CustomFlexibleRendering {
@@ -99,7 +99,8 @@ public fun sameTypeConstructors(first: KotlinType, second: KotlinType): Boolean
}
interface CustomSubstitutionCapability : TypeCapability {
public val substitution: TypeSubstitution
public val substitution: TypeSubstitution?
public val substitutionToComposeWith: TypeSubstitution?
}
interface PossiblyInnerTypeCapability : TypeCapability {
@@ -105,17 +105,11 @@ public fun KotlinType.computeNewSubstitution(
typeConstructor: TypeConstructor,
newArguments: List<TypeProjection>
): TypeSubstitution {
val previousSubstitution = getSubstitution()
if (newArguments.isEmpty()) return previousSubstitution
val newSubstitution = TypeConstructorSubstitution.create(typeConstructor, newArguments)
// If previous substitution was trivial just replace it with indexed one
if (previousSubstitution is IndexedParametersSubstitution || previousSubstitution.isEmpty()) {
return newSubstitution
}
val composedSubstitution = CompositeTypeSubstitution(newSubstitution, previousSubstitution)
val substitutionToComposeWith = getCapability<CustomSubstitutionCapability>()?.substitutionToComposeWith ?: return newSubstitution
val composedSubstitution = CompositeTypeSubstitution(newSubstitution, substitutionToComposeWith)
return composedSubstitution
}