Rework TypeSubstituion, now it applies to types instead of constructors

Also introduce IndexedParametersSubstitution
This commit is contained in:
Denis Zharkov
2015-07-27 19:07:01 +03:00
parent 1aef9b77f1
commit a07a1829c5
22 changed files with 108 additions and 171 deletions
@@ -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);
}
}
@@ -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)
@@ -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());
}