Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jetbrains.kotlin.resolve.jvm.kotlinSignature.SignaturesPropagationData Maven / Gradle / Ivy
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.jvm.kotlinSignature;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import kotlin.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.java.components.TypeUsage;
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
import org.jetbrains.kotlin.load.java.structure.JavaMethod;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolverKt;
import org.jetbrains.kotlin.resolve.jvm.JavaResolverUtils;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapper;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapperKt;
import org.jetbrains.kotlin.resolve.scopes.KtScope;
import org.jetbrains.kotlin.types.*;
import java.util.*;
import static org.jetbrains.kotlin.load.java.components.TypeUsage.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
import static org.jetbrains.kotlin.types.Variance.INVARIANT;
public class SignaturesPropagationData {
private static final KotlinToJvmSignatureMapper SIGNATURE_MAPPER = ServiceLoader.load(
KotlinToJvmSignatureMapper.class,
KotlinToJvmSignatureMapper.class.getClassLoader()
).iterator().next();
private final JavaMethodDescriptor autoMethodDescriptor;
private final List modifiedTypeParameters;
private final ValueParameters modifiedValueParameters;
private final KotlinType modifiedReturnType;
private final List signatureErrors = Lists.newArrayList();
private final List superFunctions;
private final Map autoTypeParameterToModified;
final ClassDescriptor containingClass;
public SignaturesPropagationData(
@NotNull ClassDescriptor containingClass,
@NotNull KotlinType autoReturnType, // type built by JavaTypeTransformer from Java signature and @NotNull annotations
@Nullable KotlinType receiverType,
@NotNull List autoValueParameters, // descriptors built by parameters resolver
@NotNull List autoTypeParameters, // descriptors built by signature resolver
@NotNull JavaMethod method
) {
this.containingClass = containingClass;
autoMethodDescriptor =
createAutoMethodDescriptor(containingClass, method, autoReturnType, receiverType, autoValueParameters, autoTypeParameters);
superFunctions = getSuperFunctionsForMethod(method, autoMethodDescriptor, containingClass);
autoTypeParameterToModified = JavaResolverUtils.recreateTypeParametersAndReturnMapping(autoTypeParameters, null);
modifiedTypeParameters = modifyTypeParametersAccordingToSuperMethods(autoTypeParameters);
modifiedReturnType = modifyReturnTypeAccordingToSuperMethods(autoReturnType);
modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(receiverType, autoValueParameters);
}
@NotNull
private static JavaMethodDescriptor createAutoMethodDescriptor(
@NotNull ClassDescriptor containingClass,
@NotNull JavaMethod method, KotlinType autoReturnType,
@Nullable KotlinType receiverType,
@NotNull List autoValueParameters,
@NotNull List autoTypeParameters
) {
JavaMethodDescriptor autoMethodDescriptor = JavaMethodDescriptor.createJavaMethod(
containingClass,
Annotations.Companion.getEMPTY(),
method.getName(),
//TODO: what to do?
SourceElement.NO_SOURCE
);
autoMethodDescriptor.initialize(
receiverType,
containingClass.getThisAsReceiverParameter(),
autoTypeParameters,
autoValueParameters,
autoReturnType,
Modality.OPEN,
Visibilities.PUBLIC
);
return autoMethodDescriptor;
}
public List getModifiedTypeParameters() {
return modifiedTypeParameters;
}
public KotlinType getModifiedReceiverType() {
return modifiedValueParameters.receiverType;
}
public List getModifiedValueParameters() {
return modifiedValueParameters.descriptors;
}
public boolean getModifiedHasStableParameterNames() {
return modifiedValueParameters.hasStableParameterNames;
}
public KotlinType getModifiedReturnType() {
return modifiedReturnType;
}
public List getSignatureErrors() {
return signatureErrors;
}
public List getSuperFunctions() {
return superFunctions;
}
void reportError(String error) {
signatureErrors.add(error);
}
private KotlinType modifyReturnTypeAccordingToSuperMethods(
@NotNull KotlinType autoType // type built by JavaTypeTransformer
) {
if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoType;
List typesFromSuperMethods = ContainerUtil.map(superFunctions,
new Function() {
@Override
public TypeAndVariance fun(FunctionDescriptor superFunction) {
return new TypeAndVariance(superFunction.getReturnType(),
Variance.OUT_VARIANCE);
}
});
return modifyTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, MEMBER_SIGNATURE_COVARIANT);
}
private List modifyTypeParametersAccordingToSuperMethods(List autoTypeParameters) {
if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoTypeParameters;
List result = Lists.newArrayList();
for (TypeParameterDescriptor autoParameter : autoTypeParameters) {
int index = autoParameter.getIndex();
TypeParameterDescriptorImpl modifiedTypeParameter = autoTypeParameterToModified.get(autoParameter);
List> upperBoundFromSuperFunctionsIterators = Lists.newArrayList();
for (FunctionDescriptor superFunction : superFunctions) {
upperBoundFromSuperFunctionsIterators.add(superFunction.getTypeParameters().get(index).getUpperBounds().iterator());
}
for (KotlinType autoUpperBound : autoParameter.getUpperBounds()) {
List upperBoundsFromSuperFunctions = Lists.newArrayList();
for (Iterator iterator : upperBoundFromSuperFunctionsIterators) {
assert iterator.hasNext();
upperBoundsFromSuperFunctions.add(new TypeAndVariance(iterator.next(), INVARIANT));
}
KotlinType modifiedUpperBound = modifyTypeAccordingToSuperMethods(autoUpperBound, upperBoundsFromSuperFunctions, UPPER_BOUND);
modifiedTypeParameter.addUpperBound(modifiedUpperBound);
}
for (Iterator iterator : upperBoundFromSuperFunctionsIterators) {
assert !iterator.hasNext();
}
modifiedTypeParameter.setInitialized();
result.add(modifiedTypeParameter);
}
return result;
}
private ValueParameters modifyValueParametersAccordingToSuperMethods(
@Nullable KotlinType receiverType,
@NotNull List parameters // descriptors built by parameters resolver
) {
assert receiverType == null : "Parameters before propagation have receiver type," +
" but propagation should be disabled for functions compiled from Kotlin in class: " +
DescriptorUtils.getFqName(containingClass);
KotlinType resultReceiverType = null;
List resultParameters = new ArrayList(parameters.size());
boolean shouldBeExtension = checkIfShouldBeExtension();
for (final ValueParameterDescriptor originalParam : parameters) {
final int originalIndex = originalParam.getIndex();
List typesFromSuperMethods = ContainerUtil.map(superFunctions,
new Function() {
@Override
public TypeAndName fun(FunctionDescriptor superFunction) {
ReceiverParameterDescriptor receiver = superFunction.getExtensionReceiverParameter();
int index = receiver != null ? originalIndex - 1 : originalIndex;
if (index == -1) {
assert receiver != null : "can't happen: index is -1, while function is not extension";
return new TypeAndName(receiver.getType(), originalParam.getName());
}
ValueParameterDescriptor parameter = superFunction.getValueParameters().get(index);
return new TypeAndName(parameter.getType(), parameter.getName());
}
});
VarargCheckResult varargCheckResult = checkVarargInSuperFunctions(originalParam);
KotlinType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType,
convertToTypeVarianceList(typesFromSuperMethods),
MEMBER_SIGNATURE_CONTRAVARIANT);
if (shouldBeExtension && originalIndex == 0) {
resultReceiverType = altType;
}
else {
Name stableName = null;
for (int i = 0; i < superFunctions.size(); i++) {
if (superFunctions.get(i).hasStableParameterNames()) {
// When there's more than one stable name in super functions, we pick the first one. This behaviour is similar to
// the compiler front-end, except that it reports a warning in such cases
// TODO: report a warning somewhere if there's more than one stable name in super functions
stableName = typesFromSuperMethods.get(i).name;
break;
}
}
resultParameters.add(new ValueParameterDescriptorImpl(
originalParam.getContainingDeclaration(),
null,
shouldBeExtension ? originalIndex - 1 : originalIndex,
originalParam.getAnnotations(),
stableName != null ? stableName : originalParam.getName(),
altType,
originalParam.declaresDefaultValue(),
originalParam.isCrossinline(),
originalParam.isNoinline(),
varargCheckResult.isVararg ? DescriptorUtilsKt.getBuiltIns(originalParam).getArrayElementType(altType) : null,
SourceElement.NO_SOURCE
));
}
}
boolean hasStableParameterNames = CollectionsKt.any(superFunctions, new Function1() {
@Override
public Boolean invoke(FunctionDescriptor descriptor) {
return descriptor.hasStableParameterNames();
}
});
return new ValueParameters(resultReceiverType, resultParameters, hasStableParameterNames);
}
@NotNull
private static List convertToTypeVarianceList(@NotNull List list) {
return CollectionsKt.map(list, new Function1() {
@Override
public TypeAndVariance invoke(TypeAndName tvn) {
return new TypeAndVariance(tvn.type, INVARIANT);
}
});
}
private static List getSuperFunctionsForMethod(
@NotNull JavaMethod method,
@NotNull JavaMethodDescriptor autoMethodDescriptor,
@NotNull ClassDescriptor containingClass
) {
List superFunctions = Lists.newArrayList();
// TODO: Add propagation for other kotlin descriptors (KT-3621)
Name name = method.getName();
JvmMethodSignature autoSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(autoMethodDescriptor);
for (KotlinType supertype : containingClass.getTypeConstructor().getSupertypes()) {
Collection superFunctionCandidates = supertype.getMemberScope().getFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS);
for (FunctionDescriptor candidate : superFunctionCandidates) {
JvmMethodSignature candidateSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(candidate);
if (KotlinToJvmSignatureMapperKt.erasedSignaturesEqualIgnoringReturnTypes(autoSignature, candidateSignature)) {
superFunctions.add(candidate);
}
}
}
// sorting for diagnostic stability
Collections.sort(superFunctions, new Comparator() {
@Override
public int compare(@NotNull FunctionDescriptor fun1, @NotNull FunctionDescriptor fun2) {
FqNameUnsafe fqName1 = getFqName(fun1.getContainingDeclaration());
FqNameUnsafe fqName2 = getFqName(fun2.getContainingDeclaration());
return fqName1.asString().compareTo(fqName2.asString());
}
});
return superFunctions;
}
private boolean checkIfShouldBeExtension() {
boolean someSupersExtension = false;
boolean someSupersNotExtension = false;
for (FunctionDescriptor superFunction : superFunctions) {
if (superFunction.getExtensionReceiverParameter() != null) {
someSupersExtension = true;
}
else {
someSupersNotExtension = true;
}
}
if (someSupersExtension) {
if (someSupersNotExtension) {
reportError("Incompatible super methods: some are extension functions, some are not");
}
else {
return true;
}
}
return false;
}
@NotNull
private VarargCheckResult checkVarargInSuperFunctions(@NotNull ValueParameterDescriptor originalParam) {
boolean someSupersVararg = false;
boolean someSupersNotVararg = false;
for (FunctionDescriptor superFunction : superFunctions) {
int originalIndex = originalParam.getIndex();
int index = superFunction.getExtensionReceiverParameter() != null ? originalIndex - 1 : originalIndex;
if (index != -1 && superFunction.getValueParameters().get(index).getVarargElementType() != null) {
someSupersVararg = true;
}
else {
someSupersNotVararg = true;
}
}
KotlinType originalVarargElementType = originalParam.getVarargElementType();
KotlinType originalType = originalParam.getType();
if (someSupersVararg && someSupersNotVararg) {
reportError("Incompatible super methods: some have vararg parameter, some have not");
return new VarargCheckResult(originalType, originalVarargElementType != null);
}
if (someSupersVararg && originalVarargElementType == null) {
// convert to vararg
assert isArrayType(originalType);
return new VarargCheckResult(TypeUtils.makeNotNullable(originalType), true);
}
else if (someSupersNotVararg && originalVarargElementType != null) {
// convert to non-vararg
assert isArrayType(originalType);
return new VarargCheckResult(TypeUtils.makeNullable(originalType), false);
}
return new VarargCheckResult(originalType, originalVarargElementType != null);
}
@NotNull
private KotlinType modifyTypeAccordingToSuperMethods(
@NotNull KotlinType autoType,
@NotNull List typesFromSuper,
@NotNull TypeUsage howThisTypeIsUsed
) {
if (autoType.isError()) return autoType;
if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoType;
boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, howThisTypeIsUsed);
ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper);
List resultArguments = getTypeArgsOfType(autoType, resultClassifier, typesFromSuper);
KtScope resultScope;
if (resultClassifier instanceof ClassDescriptor) {
resultScope = ((ClassDescriptor) resultClassifier).getMemberScope(resultArguments);
}
else {
resultScope = autoType.getMemberScope();
}
KotlinType type = KotlinTypeImpl.create(autoType.getAnnotations(),
resultClassifier.getTypeConstructor(),
resultNullable,
resultArguments,
resultScope);
PropagationHeuristics.checkArrayInReturnType(this, type, typesFromSuper);
return type;
}
@NotNull
private List getTypeArgsOfType(
@NotNull KotlinType autoType,
@NotNull ClassifierDescriptor classifier,
@NotNull List typesFromSuper
) {
if (typesFromSuper.isEmpty()) return autoType.getArguments();
List autoArguments = autoType.getArguments();
if (!(classifier instanceof ClassDescriptor)) {
assert autoArguments.isEmpty() :
"Unexpected type arguments when type constructor is not ClassDescriptor, type = " + autoType +
", classifier = " + classifier + ", classifier class = " + classifier.getClass();
return autoArguments;
}
List> typeArgumentsFromSuper = calculateTypeArgumentsFromSuper((ClassDescriptor) classifier,
typesFromSuper);
// Modify type arguments using info from typesFromSuper
List resultArguments = Lists.newArrayList();
for (TypeParameterDescriptor parameter : classifier.getTypeConstructor().getParameters()) {
TypeProjection argument = autoArguments.get(parameter.getIndex());
KotlinType argumentType = argument.getType();
List projectionsFromSuper = typeArgumentsFromSuper.get(parameter.getIndex());
List argTypesFromSuper = getTypes(projectionsFromSuper);
KotlinType type = modifyTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, TYPE_ARGUMENT);
Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper);
resultArguments.add(new TypeProjectionImpl(projectionKind, type));
}
return resultArguments;
}
private Variance calculateArgumentProjectionKindFromSuper(
@NotNull TypeProjection argument,
@NotNull List projectionsFromSuper
) {
if (projectionsFromSuper.isEmpty()) return argument.getProjectionKind();
Set projectionKindsInSuper = Sets.newLinkedHashSet();
for (TypeProjectionAndVariance projectionAndVariance : projectionsFromSuper) {
projectionKindsInSuper.add(projectionAndVariance.typeProjection.getProjectionKind());
}
Variance defaultProjectionKind = argument.getProjectionKind();
if (projectionKindsInSuper.size() == 0) {
return defaultProjectionKind;
}
else if (projectionKindsInSuper.size() == 1) {
Variance projectionKindInSuper = projectionKindsInSuper.iterator().next();
if (defaultProjectionKind == INVARIANT || defaultProjectionKind == projectionKindInSuper) {
return projectionKindInSuper;
}
else {
reportError("Incompatible projection kinds in type arguments of super methods' return types: "
+ projectionsFromSuper + ", defined in current: " + argument);
return defaultProjectionKind;
}
}
else {
reportError("Incompatible projection kinds in type arguments of super methods' return types: " + projectionsFromSuper);
return defaultProjectionKind;
}
}
@NotNull
private static List getTypes(@NotNull List projections) {
List types = Lists.newArrayList();
for (TypeProjectionAndVariance projection : projections) {
types.add(new TypeAndVariance(projection.typeProjection.getType(),
merge(projection.varianceOfPosition, projection.typeProjection.getProjectionKind())));
}
return types;
}
private static Variance merge(Variance positionOfOuter, Variance projectionKind) {
// Inv>, X is in invariant position
if (positionOfOuter == INVARIANT) return INVARIANT;
// Out, X is in out-position
if (projectionKind == INVARIANT) return positionOfOuter;
// Out>, X is in out-position
// In>, X is in out-position
// Out>, X is in in-position
// In>, X is in in-position
return positionOfOuter.superpose(projectionKind);
}
// Returns list with type arguments info from supertypes
// Example:
// - Foo is a subtype of Bar >, Baz
// - input: klass = Foo, typesFromSuper = [Bar>, Baz]
// - output[0] = [String, CharSequence], output[1] = []
private static List> calculateTypeArgumentsFromSuper(
@NotNull ClassDescriptor klass,
@NotNull Collection typesFromSuper
) {
// For each superclass of klass and its parameters, hold their mapping to klass' parameters
// #0 of Bar -> A
// #1 of Bar -> List
// #0 of Baz -> Boolean
// #1 of Baz -> A
// #0 of Foo -> A (mapped to itself)
// #1 of Foo -> B (mapped to itself)
Multimap substitution = SubstitutionUtils.buildDeepSubstitutionMultimap(
TypeUtils.makeUnsubstitutedType(klass, ErrorUtils.createErrorScope("Do not access this scope", true)));
// for each parameter of klass, hold arguments in corresponding supertypes
List> parameterToArgumentsFromSuper = Lists.newArrayList();
for (TypeParameterDescriptor ignored : klass.getTypeConstructor().getParameters()) {
parameterToArgumentsFromSuper.add(new ArrayList());
}
// Enumerate all types from super and all its parameters
for (TypeAndVariance typeFromSuper : typesFromSuper) {
for (TypeParameterDescriptor parameter : typeFromSuper.type.getConstructor().getParameters()) {
TypeProjection argument = typeFromSuper.type.getArguments().get(parameter.getIndex());
// for given example, this block is executed four times:
// 1. typeFromSuper = Bar>, parameter = "#0 of Bar", argument = String
// 2. typeFromSuper = Bar>, parameter = "#1 of Bar", argument = List
// 3. typeFromSuper = Baz, parameter = "#0 of Baz", argument = Boolean
// 4. typeFromSuper = Baz, parameter = "#1 of Baz", argument = CharSequence
// if it is mapped to klass' parameter, then store it into map
for (TypeProjection projection : substitution.get(parameter.getTypeConstructor())) {
// 1. projection = A
// 2. projection = List
// 3. projection = Boolean
// 4. projection = A
ClassifierDescriptor classifier = projection.getType().getConstructor().getDeclarationDescriptor();
// this condition is true for 1 and 4, false for 2 and 3
if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == klass) {
int parameterIndex = ((TypeParameterDescriptor) classifier).getIndex();
Variance effectiveVariance = parameter.getVariance().superpose(typeFromSuper.varianceOfPosition);
parameterToArgumentsFromSuper.get(parameterIndex).add(new TypeProjectionAndVariance(argument, effectiveVariance));
}
}
}
}
return parameterToArgumentsFromSuper;
}
private boolean typeMustBeNullable(
@NotNull KotlinType autoType,
@NotNull List typesFromSuper,
@NotNull TypeUsage howThisTypeIsUsed
) {
boolean someSupersNotCovariantNullable = false;
boolean someSupersCovariantNullable = false;
boolean someSupersNotNull = false;
for (TypeAndVariance typeFromSuper : typesFromSuper) {
if (!TypeUtils.isNullableType(typeFromSuper.type)) {
someSupersNotNull = true;
}
else {
if (typeFromSuper.varianceOfPosition == Variance.OUT_VARIANCE) {
someSupersCovariantNullable = true;
}
else {
someSupersNotCovariantNullable = true;
}
}
}
if (someSupersNotNull && someSupersNotCovariantNullable) {
reportError("Incompatible types in superclasses: " + typesFromSuper);
return TypeUtils.isNullableType(autoType);
}
else if (someSupersNotNull) {
return false;
}
else if (someSupersNotCovariantNullable || someSupersCovariantNullable) {
boolean annotatedAsNotNull = howThisTypeIsUsed != TYPE_ARGUMENT && !TypeUtils.isNullableType(autoType);
if (annotatedAsNotNull && someSupersNotCovariantNullable) {
DescriptorRenderer renderer = DescriptorRenderer.SHORT_NAMES_IN_TYPES;
reportError("In superclass type is nullable: " + typesFromSuper + ", in subclass it is not: " + renderer.renderType(autoType));
return true;
}
return !annotatedAsNotNull;
}
return TypeUtils.isNullableType(autoType);
}
@NotNull
private ClassifierDescriptor modifyTypeClassifier(
@NotNull KotlinType autoType,
@NotNull List typesFromSuper
) {
ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
if (!(classifier instanceof ClassDescriptor)) {
assert classifier != null : "no declaration descriptor for type " + autoType + ", auto method descriptor: " + autoMethodDescriptor;
if (classifier instanceof TypeParameterDescriptor && autoTypeParameterToModified.containsKey(classifier)) {
return autoTypeParameterToModified.get(classifier);
}
return classifier;
}
ClassDescriptor klass = (ClassDescriptor) classifier;
boolean someSupersMutable = false;
boolean someSupersCovariantReadOnly = false;
boolean someSupersNotCovariantReadOnly = false;
for (TypeAndVariance typeFromSuper : typesFromSuper) {
ClassifierDescriptor classifierFromSuper = typeFromSuper.type.getConstructor().getDeclarationDescriptor();
if (classifierFromSuper instanceof ClassDescriptor) {
ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper;
if (JavaToKotlinClassMap.INSTANCE.isMutable(classFromSuper)) {
someSupersMutable = true;
}
else if (JavaToKotlinClassMap.INSTANCE.isReadOnly(classFromSuper)) {
if (typeFromSuper.varianceOfPosition == Variance.OUT_VARIANCE) {
someSupersCovariantReadOnly = true;
}
else {
someSupersNotCovariantReadOnly = true;
}
}
}
}
if (someSupersMutable && someSupersNotCovariantReadOnly) {
reportError("Incompatible types in superclasses: " + typesFromSuper);
return classifier;
}
else if (someSupersMutable) {
if (JavaToKotlinClassMap.INSTANCE.isReadOnly(klass)) {
return JavaToKotlinClassMap.INSTANCE.convertReadOnlyToMutable(klass);
}
}
else if (someSupersNotCovariantReadOnly || someSupersCovariantReadOnly) {
if (JavaToKotlinClassMap.INSTANCE.isMutable(klass)) {
return JavaToKotlinClassMap.INSTANCE.convertMutableToReadOnly(klass);
}
}
ClassifierDescriptor fixed = PropagationHeuristics.tryToFixOverridingTWithRawType(this, typesFromSuper);
return fixed != null ? fixed : classifier;
}
private static boolean isArrayType(@NotNull KotlinType type) {
return KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type);
}
private static class VarargCheckResult {
public final KotlinType parameterType;
public final boolean isVararg;
public VarargCheckResult(KotlinType parameterType, boolean isVararg) {
this.parameterType = parameterType;
this.isVararg = isVararg;
}
}
private static class TypeProjectionAndVariance {
public final TypeProjection typeProjection;
public final Variance varianceOfPosition;
public TypeProjectionAndVariance(TypeProjection typeProjection, Variance varianceOfPosition) {
this.typeProjection = typeProjection;
this.varianceOfPosition = varianceOfPosition;
}
public String toString() {
return typeProjection.toString();
}
}
static class TypeAndVariance {
public final KotlinType type;
public final Variance varianceOfPosition;
public TypeAndVariance(KotlinType type, Variance varianceOfPosition) {
this.type = type;
this.varianceOfPosition = varianceOfPosition;
}
public String toString() {
return type.toString();
}
}
private static class TypeAndName {
public final KotlinType type;
public final Name name;
public TypeAndName(KotlinType type, Name name) {
this.type = type;
this.name = name;
}
}
private static class ValueParameters {
private final KotlinType receiverType;
private final List descriptors;
private final boolean hasStableParameterNames;
public ValueParameters(
@Nullable KotlinType receiverType,
@NotNull List descriptors,
boolean hasStableParameterNames
) {
this.receiverType = receiverType;
this.descriptors = descriptors;
this.hasStableParameterNames = hasStableParameterNames;
}
}
}