Rework TypeSubstituion, now it applies to types instead of constructors
Also introduce IndexedParametersSubstitution
This commit is contained in:
@@ -199,7 +199,7 @@ class CollectionStubMethodGenerator(
|
||||
child.setVisibility(Visibilities.PUBLIC)
|
||||
val typeParameters = descriptor.getTypeConstructor().getParameters()
|
||||
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size())
|
||||
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitutor.EMPTY, child, newTypeParameters)
|
||||
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
|
||||
child.setTypeParameterDescriptors(typeParameters)
|
||||
return Pair(child, newTypeParameters)
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ public class JavaResolverUtils {
|
||||
typeSubstitutionContext.put(originalToAltTypeParameter.getKey().getTypeConstructor(),
|
||||
new TypeProjectionImpl(originalToAltTypeParameter.getValue().getDefaultType()));
|
||||
}
|
||||
// TODO: Use IndexedParametersSubstitution here instead of map creation
|
||||
return TypeSubstitutor.create(typeSubstitutionContext);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -271,7 +271,7 @@ class JavaSyntheticExtensionsScope(storageManager: StorageManager) : JetScope by
|
||||
init {
|
||||
val classTypeParams = ownerClass.typeConstructor.parameters
|
||||
val typeParameters = ArrayList<TypeParameterDescriptor>(classTypeParams.size())
|
||||
val typeSubstitutor = DescriptorSubstitutor.substituteTypeParameters(classTypeParams, TypeSubstitutor.EMPTY, this, typeParameters)
|
||||
val typeSubstitutor = DescriptorSubstitutor.substituteTypeParameters(classTypeParams, TypeSubstitution.EMPTY, this, typeParameters)
|
||||
|
||||
val propertyType = typeSubstitutor.safeSubstitute(type, Variance.INVARIANT)
|
||||
val receiverType = typeSubstitutor.safeSubstitute(ownerClass.defaultType, Variance.INVARIANT)
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.scopes.RedeclarationHandler;
|
||||
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilPackage;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -36,7 +37,7 @@ public class FunctionDescriptorUtil {
|
||||
private static final TypeSubstitutor MAKE_TYPE_PARAMETERS_FRESH = TypeSubstitutor.create(new TypeSubstitution() {
|
||||
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
public TypeProjection get(@NotNull JetType key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -49,23 +50,13 @@ public class FunctionDescriptorUtil {
|
||||
private FunctionDescriptorUtil() {
|
||||
}
|
||||
|
||||
public static Map<TypeConstructor, TypeProjection> createSubstitutionContext(
|
||||
public static TypeSubstitution createSubstitution(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull List<JetType> typeArguments
|
||||
) {
|
||||
if (functionDescriptor.getTypeParameters().isEmpty()) return Collections.emptyMap();
|
||||
if (functionDescriptor.getTypeParameters().isEmpty()) return TypeSubstitution.getEMPTY();
|
||||
|
||||
Map<TypeConstructor, TypeProjection> result = new HashMap<TypeConstructor, TypeProjection>();
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
||||
assert typeArguments.size() >= typeParameters.size() :
|
||||
"Insufficient number of type arguments.\nType arguments: " + typeArguments + "\nType parameters: " + typeParameters;
|
||||
for (int i = 0; i < typeParameters.size(); i++) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
|
||||
JetType typeArgument = typeArguments.get(i);
|
||||
result.put(typeParameterDescriptor.getTypeConstructor(), new TypeProjectionImpl(typeArgument));
|
||||
}
|
||||
return result;
|
||||
return new IndexedParametersSubstitution(functionDescriptor.getTypeParameters(), TypeUtilPackage.defaultProjections(typeArguments));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -645,16 +645,12 @@ public class OverrideResolver {
|
||||
List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
|
||||
if (subTypeParameters.size() != superTypeParameters.size()) return null;
|
||||
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = Maps.newHashMapWithExpectedSize(superTypeParameters.size());
|
||||
ArrayList<TypeProjection> arguments = new ArrayList<TypeProjection>(subTypeParameters.size());
|
||||
for (int i = 0; i < superTypeParameters.size(); i++) {
|
||||
TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
|
||||
TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);
|
||||
substitutionContext.put(
|
||||
superTypeParameter.getTypeConstructor(),
|
||||
new TypeProjectionImpl(subTypeParameter.getDefaultType())
|
||||
);
|
||||
arguments.add(new TypeProjectionImpl(subTypeParameters.get(i).getDefaultType()));
|
||||
}
|
||||
return TypeSubstitutor.create(substitutionContext);
|
||||
|
||||
return new IndexedParametersSubstitution(superTypeParameters, arguments).buildSubstitutor();
|
||||
}
|
||||
|
||||
public static boolean isPropertyTypeOkForOverride(
|
||||
|
||||
@@ -139,8 +139,8 @@ public class CandidateResolver(
|
||||
typeArguments.add(ErrorUtils.createErrorType(
|
||||
"Explicit type argument expected for " + candidateDescriptor.getTypeParameters().get(index).getName()))
|
||||
}
|
||||
val substitutionContext = FunctionDescriptorUtil.createSubstitutionContext(candidateDescriptor as FunctionDescriptor, typeArguments)
|
||||
val substitutor = TypeSubstitutor.create(substitutionContext)
|
||||
val substitution = FunctionDescriptorUtil.createSubstitution(candidateDescriptor as FunctionDescriptor, typeArguments)
|
||||
val substitutor = TypeSubstitutor.create(substitution)
|
||||
|
||||
if (expectedTypeArgumentCount != jetTypeArguments.size()) {
|
||||
candidateCall.addStatus(OTHER_ERROR)
|
||||
|
||||
+1
-1
@@ -162,7 +162,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
|
||||
assert resultingDescriptor != null : candidateDescriptor;
|
||||
|
||||
for (TypeParameterDescriptor typeParameter : candidateDescriptor.getTypeParameters()) {
|
||||
TypeProjection typeArgumentProjection = substitutor.getSubstitution().get(typeParameter.getTypeConstructor());
|
||||
TypeProjection typeArgumentProjection = substitutor.getSubstitution().get(typeParameter.getDefaultType());
|
||||
if (typeArgumentProjection != null) {
|
||||
typeArguments.put(typeParameter, typeArgumentProjection.getType());
|
||||
}
|
||||
|
||||
+1
-4
@@ -90,10 +90,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor {
|
||||
+ " for " + getTypeConstructor() + " " + getTypeConstructor().getParameters();
|
||||
if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope();
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = getTypeConstructor().getParameters();
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext = TypeSubstitutor.buildSubstitutionContext(typeParameters, typeArguments);
|
||||
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(substitutionContext);
|
||||
TypeSubstitutor substitutor = new IndexedParametersSubstitution(getTypeConstructor(), typeArguments).buildSubstitutor();
|
||||
return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -228,7 +228,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
|
||||
List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
|
||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
|
||||
originalTypeParameters, originalSubstitutor, substitutedDescriptor, substitutedTypeParameters
|
||||
originalTypeParameters, originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
|
||||
);
|
||||
|
||||
JetType substitutedReceiverParameterType = null;
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
|
||||
List<TypeParameterDescriptor> originalTypeParameters = original.getTypeConstructor().getParameters();
|
||||
typeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
|
||||
newSubstitutor = DescriptorSubstitutor.substituteTypeParameters(
|
||||
originalTypeParameters, originalSubstitutor, this, typeParameters
|
||||
originalTypeParameters, originalSubstitutor.getSubstitution(), this, typeParameters
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -212,7 +212,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorImpl implements Pr
|
||||
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
|
||||
List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
|
||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
|
||||
originalTypeParameters, originalSubstitutor, substitutedDescriptor, substitutedTypeParameters
|
||||
originalTypeParameters, originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
|
||||
);
|
||||
|
||||
JetType originalOutType = getType();
|
||||
|
||||
+3
-3
@@ -131,7 +131,7 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
substituteOriginal: Boolean
|
||||
): TypeSubstitutor {
|
||||
val parameterToInferredValueMap = getParameterToInferredValueMap(allTypeParameterBounds, getDefaultValue, substituteOriginal)
|
||||
return TypeUtils.makeSubstitutorForTypeParametersMap(parameterToInferredValueMap)
|
||||
return TypeConstructorSubstitution.createByParametersMap(parameterToInferredValueMap).buildSubstitutor()
|
||||
}
|
||||
|
||||
override fun getStatus(): ConstraintSystemStatus = constraintSystemStatus
|
||||
@@ -525,7 +525,7 @@ private fun TypeSubstitutor.setApproximateCapturedTypes(): TypeSubstitutor {
|
||||
}
|
||||
|
||||
private class SubstitutionWithCapturedTypeApproximation(val substitution: TypeSubstitution) : TypeSubstitution() {
|
||||
override fun get(key: TypeConstructor) = substitution[key]
|
||||
override fun get(key: JetType) = substitution[key]
|
||||
override fun isEmpty() = substitution.isEmpty()
|
||||
override fun approximateCapturedTypes() = true
|
||||
}
|
||||
@@ -542,7 +542,7 @@ public fun ConstraintSystemImpl.registerTypeVariables(
|
||||
}
|
||||
|
||||
public fun createTypeSubstitutor(conversion: (TypeParameterDescriptor) -> TypeParameterDescriptor?): TypeSubstitutor {
|
||||
return TypeSubstitutor.create(object : TypeSubstitution() {
|
||||
return TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor): TypeProjection? {
|
||||
val descriptor = key.getDeclarationDescriptor()
|
||||
if (descriptor !is TypeParameterDescriptor) return null
|
||||
|
||||
@@ -16,23 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.types.typesApproximation
|
||||
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
||||
import org.jetbrains.kotlin.types.TypeProjection
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.types.JetTypeImpl
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.TypeSubstitution
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.types.LazyType
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.isCaptured
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
||||
import java.util.ArrayList
|
||||
|
||||
public data class ApproximationBounds<T>(
|
||||
public val lower: T,
|
||||
@@ -89,7 +80,7 @@ public fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?):
|
||||
}
|
||||
|
||||
private fun substituteCapturedTypes(typeProjection: TypeProjection): TypeProjection? {
|
||||
val typeSubstitutor = TypeSubstitutor.create(object : TypeSubstitution() {
|
||||
val typeSubstitutor = TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor): TypeProjection? {
|
||||
return (key as? CapturedTypeConstructor)?.typeProjection
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CompositeTypeSubstitution extends TypeSubstitution {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
public TypeProjection get(@NotNull JetType key) {
|
||||
for (TypeSubstitution substitution : inner) {
|
||||
TypeProjection value = substitution.get(key);
|
||||
if (value != null) return value;
|
||||
|
||||
@@ -35,35 +35,11 @@ public class DescriptorSubstitutor {
|
||||
@NotNull
|
||||
public static TypeSubstitutor substituteTypeParameters(
|
||||
@ReadOnly @NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@NotNull final TypeSubstitutor originalSubstitutor,
|
||||
@NotNull TypeSubstitution originalSubstitution,
|
||||
@NotNull DeclarationDescriptor newContainingDeclaration,
|
||||
@NotNull @Mutable List<TypeParameterDescriptor> result
|
||||
) {
|
||||
final Map<TypeConstructor, TypeProjection> mutableSubstitution = new HashMap<TypeConstructor, TypeProjection>();
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(new TypeSubstitution() {
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
if (originalSubstitutor.inRange(key)) {
|
||||
return originalSubstitutor.getSubstitution().get(key);
|
||||
}
|
||||
return mutableSubstitution.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return originalSubstitutor.isEmpty() && mutableSubstitution.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean approximateCapturedTypes() {
|
||||
return originalSubstitutor.getSubstitution().approximateCapturedTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DescriptorSubstitutor.substituteTypeParameters(" + mutableSubstitution + " / " + originalSubstitutor.getSubstitution() + ")";
|
||||
}
|
||||
});
|
||||
Map<TypeConstructor, TypeProjection> mutableSubstitution = new HashMap<TypeConstructor, TypeProjection>();
|
||||
|
||||
Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> substitutedMap =
|
||||
new HashMap<TypeParameterDescriptor, TypeParameterDescriptorImpl>();
|
||||
@@ -85,6 +61,10 @@ public class DescriptorSubstitutor {
|
||||
result.add(substituted);
|
||||
}
|
||||
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(
|
||||
originalSubstitution, TypeConstructorSubstitution.createByConstructorsMap(mutableSubstitution)
|
||||
);
|
||||
|
||||
for (TypeParameterDescriptor descriptor : typeParameters) {
|
||||
TypeParameterDescriptorImpl substituted = substitutedMap.get(descriptor);
|
||||
for (JetType upperBound : descriptor.getUpperBounds()) {
|
||||
|
||||
@@ -38,7 +38,7 @@ public fun TypeParameterDescriptor.starProjectionType(): JetType {
|
||||
val classDescriptor = this.getContainingDeclaration() as ClassDescriptor
|
||||
val typeParameters = classDescriptor.getTypeConstructor().getParameters().map { it.getTypeConstructor() }
|
||||
return TypeSubstitutor.create(
|
||||
object : TypeSubstitution() {
|
||||
object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor) =
|
||||
if (key in typeParameters)
|
||||
TypeUtils.makeStarProjection(key.getDeclarationDescriptor() as TypeParameterDescriptor)
|
||||
|
||||
@@ -16,20 +16,77 @@
|
||||
|
||||
package org.jetbrains.kotlin.types
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import kotlin.platform.platformStatic
|
||||
|
||||
public abstract class TypeSubstitution {
|
||||
companion object {
|
||||
platformStatic public val EMPTY: TypeSubstitution = object : TypeSubstitution() {
|
||||
override fun get(key: TypeConstructor) = null
|
||||
override fun get(key: JetType) = null
|
||||
override fun isEmpty() = true
|
||||
override fun toString() = "Empty TypeSubstitution"
|
||||
}
|
||||
}
|
||||
|
||||
public abstract fun get(key: TypeConstructor): TypeProjection?
|
||||
public abstract fun get(key: JetType): TypeProjection?
|
||||
|
||||
public open fun isEmpty(): Boolean = false
|
||||
|
||||
public open fun approximateCapturedTypes(): Boolean = false
|
||||
|
||||
public fun buildSubstitutor(): TypeSubstitutor = TypeSubstitutor.create(this)
|
||||
}
|
||||
|
||||
public abstract class TypeConstructorSubstitution : TypeSubstitution() {
|
||||
override fun get(key: JetType) = get(key.constructor)
|
||||
|
||||
public abstract fun get(key: TypeConstructor): TypeProjection?
|
||||
|
||||
companion object {
|
||||
platformStatic
|
||||
public fun createByConstructorsMap(map: Map<TypeConstructor, TypeProjection>): TypeConstructorSubstitution =
|
||||
object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor) = map[key]
|
||||
override fun isEmpty() = map.isEmpty()
|
||||
}
|
||||
|
||||
platformStatic
|
||||
public fun createByParametersMap(map: Map<TypeParameterDescriptor, TypeProjection>): TypeConstructorSubstitution =
|
||||
object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor) = map[key.declarationDescriptor]
|
||||
override fun isEmpty() = map.isEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IndexedParametersSubstitution(
|
||||
private val parameters: Array<TypeParameterDescriptor>,
|
||||
private val arguments: Array<TypeProjection>
|
||||
) : TypeSubstitution() {
|
||||
init {
|
||||
assert(parameters.size() <= arguments.size()) {
|
||||
"Number of arguments should not be less then number of parameters, but: parameters=${parameters.size()}, args=${arguments.size()}"
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
typeConstructor: TypeConstructor, argumentsList: List<TypeProjection>
|
||||
) : this(typeConstructor.parameters, argumentsList)
|
||||
|
||||
constructor(
|
||||
parameters: List<TypeParameterDescriptor>, argumentsList: List<TypeProjection>
|
||||
) : this(parameters.toTypedArray(), argumentsList.toTypedArray())
|
||||
|
||||
override fun isEmpty(): Boolean = arguments.isEmpty()
|
||||
|
||||
override fun get(key: JetType): TypeProjection? {
|
||||
val parameter = key.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return null
|
||||
val index = parameter.index
|
||||
|
||||
if (index < parameters.size() && parameters[index].typeConstructor == parameter.typeConstructor) {
|
||||
return arguments[index]
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,29 +32,6 @@ public class TypeSubstitutor {
|
||||
|
||||
private static final int MAX_RECURSION_DEPTH = 100;
|
||||
|
||||
public static class MapToTypeSubstitutionAdapter extends TypeSubstitution {
|
||||
private final @NotNull Map<TypeConstructor, TypeProjection> substitutionContext;
|
||||
|
||||
public MapToTypeSubstitutionAdapter(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||
this.substitutionContext = substitutionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
return substitutionContext.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return substitutionContext.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return substitutionContext.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static final TypeSubstitutor EMPTY = create(TypeSubstitution.EMPTY);
|
||||
|
||||
private static final class SubstitutionException extends Exception {
|
||||
@@ -75,29 +52,12 @@ public class TypeSubstitutor {
|
||||
|
||||
@NotNull
|
||||
public static TypeSubstitutor create(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
|
||||
return create(new MapToTypeSubstitutionAdapter(substitutionContext));
|
||||
return create(TypeConstructorSubstitution.createByConstructorsMap(substitutionContext));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TypeSubstitutor create(@NotNull JetType context) {
|
||||
return create(buildSubstitutionContext(context.getConstructor().getParameters(), context.getArguments()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<TypeConstructor, TypeProjection> buildSubstitutionContext(
|
||||
@NotNull List<TypeParameterDescriptor> parameters,
|
||||
@NotNull List<? extends TypeProjection> contextArguments
|
||||
) {
|
||||
Map<TypeConstructor, TypeProjection> parameterValues = new HashMap<TypeConstructor, TypeProjection>();
|
||||
if (parameters.size() != contextArguments.size()) {
|
||||
throw new IllegalArgumentException("type parameter count != context arguments: \n" +
|
||||
"parameters=" + parameters + "\n" +
|
||||
"contextArgs=" + contextArguments);
|
||||
}
|
||||
for (int i = 0, size = parameters.size(); i < size; i++) {
|
||||
parameterValues.put(parameters.get(i).getTypeConstructor(), contextArguments.get(i));
|
||||
}
|
||||
return parameterValues;
|
||||
return create(new IndexedParametersSubstitution(context.getConstructor(), context.getArguments()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -108,10 +68,6 @@ public class TypeSubstitutor {
|
||||
this.substitution = substitution;
|
||||
}
|
||||
|
||||
public boolean inRange(@NotNull TypeConstructor typeConstructor) {
|
||||
return substitution.get(typeConstructor) != null;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return substitution.isEmpty();
|
||||
}
|
||||
@@ -170,8 +126,9 @@ public class TypeSubstitutor {
|
||||
|
||||
// The type is within the substitution range, i.e. T or T?
|
||||
JetType type = originalProjection.getType();
|
||||
TypeProjection replacement = substitution.get(type);
|
||||
Variance originalProjectionKind = originalProjection.getProjectionKind();
|
||||
if (TypesPackage.isFlexible(type) && !TypesPackage.isCustomTypeVariable(type)) {
|
||||
if (replacement == null && TypesPackage.isFlexible(type) && !TypesPackage.isCustomTypeVariable(type)) {
|
||||
Flexibility flexibility = TypesPackage.flexibility(type);
|
||||
TypeProjection substitutedLower =
|
||||
unsafeSubstitute(new TypeProjectionImpl(originalProjectionKind, flexibility.getLowerBound()), recursionDepth + 1);
|
||||
@@ -190,8 +147,6 @@ public class TypeSubstitutor {
|
||||
|
||||
if (KotlinBuiltIns.isNothing(type) || type.isError()) return originalProjection;
|
||||
|
||||
TypeProjection replacement = substitution.get(type.getConstructor());
|
||||
|
||||
if (replacement != null) {
|
||||
VarianceConflictType varianceConflict = conflictType(originalProjectionKind, replacement.getProjectionKind());
|
||||
|
||||
@@ -262,8 +217,8 @@ public class TypeSubstitutor {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
return containedOrCapturedTypeParameters.contains(key) ? substitution.get(key) : null;
|
||||
public TypeProjection get(@NotNull JetType key) {
|
||||
return containedOrCapturedTypeParameters.contains(key.getConstructor()) ? substitution.get(key) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -714,9 +714,9 @@ public class TypeUtils {
|
||||
}
|
||||
final TypeProjection projection = new TypeProjectionImpl(type);
|
||||
|
||||
return TypeSubstitutor.create(new TypeSubstitution() {
|
||||
return TypeSubstitutor.create(new TypeConstructorSubstitution() {
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
public TypeProjection get(@NotNull TypeConstructor key) {
|
||||
if (constructors.contains(key)) {
|
||||
return projection;
|
||||
}
|
||||
@@ -730,34 +730,6 @@ public class TypeUtils {
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TypeSubstitutor makeSubstitutorForTypeParametersMap(
|
||||
@NotNull final Map<TypeParameterDescriptor, TypeProjection> substitutionContext
|
||||
) {
|
||||
return TypeSubstitutor.create(new TypeSubstitution() {
|
||||
@Nullable
|
||||
@Override
|
||||
public TypeProjection get(TypeConstructor key) {
|
||||
DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor();
|
||||
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
||||
TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor;
|
||||
return substitutionContext.get(descriptor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return substitutionContext.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return substitutionContext.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isTypeParameter(@NotNull JetType type) {
|
||||
return getTypeParameterDescriptorOrNull(type) != null;
|
||||
}
|
||||
|
||||
@@ -131,4 +131,6 @@ fun JetType.getNestedArguments(): List<TypeProjection> {
|
||||
|
||||
fun JetType.containsError() = ErrorUtils.containsErrorType(this)
|
||||
|
||||
public fun List<JetType>.defaultProjections(): List<TypeProjection> = map { TypeProjectionImpl(it) }
|
||||
|
||||
public fun JetType.isDefaultBound(): Boolean = KotlinBuiltIns.isDefaultBound(getSupertypeRepresentative())
|
||||
|
||||
+2
-7
@@ -31,10 +31,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.UsageLocation
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.types.SubstitutionUtils
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import java.util.HashMap
|
||||
|
||||
public object HeuristicSignatures {
|
||||
@@ -89,9 +86,7 @@ public object HeuristicSignatures {
|
||||
|
||||
val type = typeFromText(typeStr, typeParameters, moduleDescriptor, project)
|
||||
|
||||
// now substitute type parameters with actual arguments
|
||||
val typeArgsMap = typeParameters.zip(ownerType.getArguments()).toMap()
|
||||
val substitutor = TypeUtils.makeSubstitutorForTypeParametersMap(typeArgsMap)
|
||||
val substitutor = IndexedParametersSubstitution(ownerClass.typeConstructor, ownerType.arguments).buildSubstitutor()
|
||||
return substitutor.substitute(type, Variance.INVARIANT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import java.util.ArrayList
|
||||
@@ -66,8 +67,7 @@ public object SuperClassNotInitialized : JetIntentionActionsFactory() {
|
||||
if (classOrObjectDeclaration is JetClass) {
|
||||
val superType = classDescriptor.getTypeConstructor().getSupertypes().firstOrNull { it.getConstructor().getDeclarationDescriptor() == superClass }
|
||||
if (superType != null) {
|
||||
val typeArgsMap = superClass.getTypeConstructor().getParameters().zip(superType.getArguments()).toMap()
|
||||
val substitutor = TypeUtils.makeSubstitutorForTypeParametersMap(typeArgsMap)
|
||||
val substitutor = IndexedParametersSubstitution(superClass.typeConstructor, superType.arguments).buildSubstitutor()
|
||||
|
||||
val substitutedConstructors = constructors
|
||||
.filter { it.getValueParameters().isNotEmpty() }
|
||||
|
||||
Reference in New Issue
Block a user