use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.
the class ReifiedTypeParameterSubstitutionChecker method check.
@Override
public void check(@NotNull ResolvedCall<?> resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) {
Map<TypeParameterDescriptor, KotlinType> typeArguments = resolvedCall.getTypeArguments();
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
TypeParameterDescriptor parameter = entry.getKey();
KotlinType argument = entry.getValue();
ClassifierDescriptor argumentDeclarationDescriptor = argument.getConstructor().getDeclarationDescriptor();
if (!parameter.isReified() && !isTypeParameterOfKotlinArray(parameter)) {
continue;
}
KtTypeProjection typeProjection = CollectionsKt.getOrNull(resolvedCall.getCall().getTypeArguments(), parameter.getIndex());
PsiElement reportErrorOn = typeProjection != null ? typeProjection : reportOn;
if (argumentDeclarationDescriptor instanceof TypeParameterDescriptor && !((TypeParameterDescriptor) argumentDeclarationDescriptor).isReified()) {
context.getTrace().report(Errors.TYPE_PARAMETER_AS_REIFIED.on(reportErrorOn, (TypeParameterDescriptor) argumentDeclarationDescriptor));
} else if (TypeUtilsKt.cannotBeReified(argument)) {
context.getTrace().report(Errors.REIFIED_TYPE_FORBIDDEN_SUBSTITUTION.on(reportErrorOn, argument));
}
// REIFIED_TYPE_UNSAFE_SUBSTITUTION is temporary disabled because it seems too strict now (see KT-10847)
//else if (TypeUtilsKt.unsafeAsReifiedArgument(argument) && !hasPureReifiableAnnotation(parameter)) {
// context.getTrace().report(Errors.REIFIED_TYPE_UNSAFE_SUBSTITUTION.on(reportErrorOn, argument));
//}
}
}
use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.
the class MemberMatching method typeParametersMatch.
static boolean typeParametersMatch(@NotNull KtTypeParameterListOwner typeParameterListOwner, @NotNull List<TypeParameterDescriptor> typeParameterDescriptors) {
List<KtTypeParameter> decompiledParameters = typeParameterListOwner.getTypeParameters();
if (decompiledParameters.size() != typeParameterDescriptors.size()) {
return false;
}
Multimap<Name, String> decompiledParameterToBounds = HashMultimap.create();
for (KtTypeParameter parameter : decompiledParameters) {
KtTypeReference extendsBound = parameter.getExtendsBound();
if (extendsBound != null) {
decompiledParameterToBounds.put(parameter.getNameAsName(), extendsBound.getText());
}
}
for (KtTypeConstraint typeConstraint : typeParameterListOwner.getTypeConstraints()) {
KtSimpleNameExpression typeParameterName = typeConstraint.getSubjectTypeParameterName();
assert typeParameterName != null;
KtTypeReference bound = typeConstraint.getBoundTypeReference();
assert bound != null;
decompiledParameterToBounds.put(typeParameterName.getReferencedNameAsName(), bound.getText());
}
for (int i = 0; i < decompiledParameters.size(); i++) {
KtTypeParameter decompiledParameter = decompiledParameters.get(i);
TypeParameterDescriptor descriptor = typeParameterDescriptors.get(i);
Name name = decompiledParameter.getNameAsName();
assert name != null;
if (!name.equals(descriptor.getName())) {
return false;
}
Set<String> descriptorUpperBounds = Sets.newHashSet(ContainerUtil.map(descriptor.getUpperBounds(), new Function<KotlinType, String>() {
@Override
public String fun(KotlinType type) {
return DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type);
}
}));
KotlinBuiltIns builtIns = DescriptorUtilsKt.getBuiltIns(descriptor);
Set<String> decompiledUpperBounds = decompiledParameterToBounds.get(descriptor.getName()).isEmpty() ? Sets.newHashSet(DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(builtIns.getDefaultBound())) : Sets.newHashSet(decompiledParameterToBounds.get(descriptor.getName()));
if (!descriptorUpperBounds.equals(decompiledUpperBounds)) {
return false;
}
}
return true;
}
use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.
the class DescriptorSubstitutor method substituteTypeParameters.
@NotNull
public static TypeSubstitutor substituteTypeParameters(@ReadOnly @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull TypeSubstitution originalSubstitution, @NotNull DeclarationDescriptor newContainingDeclaration, @NotNull @Mutable List<TypeParameterDescriptor> result) {
Map<TypeConstructor, TypeProjection> mutableSubstitution = new HashMap<TypeConstructor, TypeProjection>();
Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> substitutedMap = new HashMap<TypeParameterDescriptor, TypeParameterDescriptorImpl>();
int index = 0;
for (TypeParameterDescriptor descriptor : typeParameters) {
TypeParameterDescriptorImpl substituted = TypeParameterDescriptorImpl.createForFurtherModification(newContainingDeclaration, descriptor.getAnnotations(), descriptor.isReified(), descriptor.getVariance(), descriptor.getName(), index++, SourceElement.NO_SOURCE);
mutableSubstitution.put(descriptor.getTypeConstructor(), new TypeProjectionImpl(substituted.getDefaultType()));
substitutedMap.put(descriptor, substituted);
result.add(substituted);
}
TypeSubstitutor substitutor = TypeSubstitutor.createChainedSubstitutor(originalSubstitution, TypeConstructorSubstitution.createByConstructorsMap(mutableSubstitution));
for (TypeParameterDescriptor descriptor : typeParameters) {
TypeParameterDescriptorImpl substituted = substitutedMap.get(descriptor);
for (KotlinType upperBound : descriptor.getUpperBounds()) {
KotlinType substitutedBound = substitutor.substitute(upperBound, Variance.IN_VARIANCE);
assert substitutedBound != null : "Upper bound failed to substitute: " + descriptor;
substituted.addUpperBound(substitutedBound);
}
substituted.setInitialized();
}
return substitutor;
}
use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.
the class TypeSubstitutor method substituteTypeArguments.
private List<TypeProjection> substituteTypeArguments(List<TypeParameterDescriptor> typeParameters, List<TypeProjection> typeArguments, int recursionDepth) throws SubstitutionException {
List<TypeProjection> substitutedArguments = new ArrayList<TypeProjection>(typeParameters.size());
for (int i = 0; i < typeParameters.size(); i++) {
TypeParameterDescriptor typeParameter = typeParameters.get(i);
TypeProjection typeArgument = typeArguments.get(i);
TypeProjection substitutedTypeArgument = unsafeSubstitute(typeArgument, recursionDepth + 1);
switch(conflictType(typeParameter.getVariance(), substitutedTypeArgument.getProjectionKind())) {
case NO_CONFLICT:
// if the corresponding type parameter is already co/contra-variant, there's not need for an explicit projection
if (typeParameter.getVariance() != Variance.INVARIANT && !substitutedTypeArgument.isStarProjection()) {
substitutedTypeArgument = new TypeProjectionImpl(Variance.INVARIANT, substitutedTypeArgument.getType());
}
break;
case OUT_IN_IN_POSITION:
case IN_IN_OUT_POSITION:
substitutedTypeArgument = TypeUtils.makeStarProjection(typeParameter);
break;
}
substitutedArguments.add(substitutedTypeArgument);
}
return substitutedArguments;
}
use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.
the class TypeUtils method canHaveSubtypes.
public static boolean canHaveSubtypes(KotlinTypeChecker typeChecker, @NotNull KotlinType type) {
if (type.isMarkedNullable()) {
return true;
}
if (!type.getConstructor().isFinal()) {
return true;
}
List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
List<TypeProjection> arguments = type.getArguments();
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
TypeParameterDescriptor parameterDescriptor = parameters.get(i);
TypeProjection typeProjection = arguments.get(i);
if (typeProjection.isStarProjection())
return true;
Variance projectionKind = typeProjection.getProjectionKind();
KotlinType argument = typeProjection.getType();
switch(parameterDescriptor.getVariance()) {
case INVARIANT:
switch(projectionKind) {
case INVARIANT:
if (lowerThanBound(typeChecker, argument, parameterDescriptor) || canHaveSubtypes(typeChecker, argument)) {
return true;
}
break;
case IN_VARIANCE:
if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
return true;
}
break;
case OUT_VARIANCE:
if (canHaveSubtypes(typeChecker, argument)) {
return true;
}
break;
}
break;
case IN_VARIANCE:
if (projectionKind != Variance.OUT_VARIANCE) {
if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
return true;
}
} else {
if (canHaveSubtypes(typeChecker, argument)) {
return true;
}
}
break;
case OUT_VARIANCE:
if (projectionKind != Variance.IN_VARIANCE) {
if (canHaveSubtypes(typeChecker, argument)) {
return true;
}
} else {
if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
return true;
}
}
break;
}
}
return false;
}
Aggregations