@NotNull private JetType modifyTypeAccordingToSuperMethods( @NotNull JetType autoType, @NotNull List<TypeAndVariance> typesFromSuper, @NotNull TypeUsage howThisTypeIsUsed) { if (ErrorUtils.isErrorType(autoType)) { return autoType; } boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, howThisTypeIsUsed); ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper); List<TypeProjection> resultArguments = getTypeArgsOfType(autoType, resultClassifier, typesFromSuper); JetScope resultScope; if (resultClassifier instanceof ClassDescriptor) { resultScope = ((ClassDescriptor) resultClassifier).getMemberScope(resultArguments); } else { resultScope = autoType.getMemberScope(); } JetTypeImpl type = new JetTypeImpl( autoType.getAnnotations(), resultClassifier.getTypeConstructor(), resultNullable, resultArguments, resultScope); PropagationHeuristics.checkArrayInReturnType(this, type, typesFromSuper); return type; }
@NotNull private ClassifierDescriptor modifyTypeClassifier( @NotNull JetType autoType, @NotNull List<TypeAndVariance> typesFromSuper) { ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor(); if (!(classifier instanceof ClassDescriptor)) { assert classifier != null : "no declaration descriptor for type " + autoType; if (classifier instanceof TypeParameterDescriptor && autoTypeParameterToModified.containsKey(classifier)) { return autoTypeParameterToModified.get(classifier); } return classifier; } ClassDescriptor klass = (ClassDescriptor) classifier; CollectionClassMapping collectionMapping = CollectionClassMapping.getInstance(); 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 (collectionMapping.isMutableCollection(classFromSuper)) { someSupersMutable = true; } else if (collectionMapping.isReadOnlyCollection(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 (collectionMapping.isReadOnlyCollection(klass)) { return collectionMapping.convertReadOnlyToMutable(klass); } } else if (someSupersNotCovariantReadOnly || someSupersCovariantReadOnly) { if (collectionMapping.isMutableCollection(klass)) { return collectionMapping.convertMutableToReadOnly(klass); } } ClassifierDescriptor fixed = PropagationHeuristics.tryToFixOverridingTWithRawType(this, typesFromSuper); return fixed != null ? fixed : classifier; }