private static Map<ClassDescriptor, JetType> getSuperclassToSupertypeMap( ClassDescriptor containingClass) { Map<ClassDescriptor, JetType> superclassToSupertype = Maps.newHashMap(); for (JetType supertype : TypeUtils.getAllSupertypes(containingClass.getDefaultType())) { ClassifierDescriptor superclass = supertype.getConstructor().getDeclarationDescriptor(); assert superclass instanceof ClassDescriptor; superclassToSupertype.put((ClassDescriptor) superclass, supertype); } return superclassToSupertype; }
@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; }
@NotNull private static FunctionDescriptor substituteSuperFunction( @NotNull Map<ClassDescriptor, JetType> superclassToSupertype, @NotNull FunctionDescriptor superFun) { DeclarationDescriptor superFunContainer = superFun.getContainingDeclaration(); assert superFunContainer instanceof ClassDescriptor : superFunContainer; JetType supertype = superclassToSupertype.get(superFunContainer); assert supertype != null : "Couldn't find super type for super function: " + superFun; TypeSubstitutor supertypeSubstitutor = TypeSubstitutor.create(supertype); FunctionDescriptor substitutedSuperFun = superFun.substitute(supertypeSubstitutor); assert substitutedSuperFun != null; return substitutedSuperFun; }
private List<TypeParameterDescriptor> modifyTypeParametersAccordingToSuperMethods( List<TypeParameterDescriptor> autoTypeParameters) { List<TypeParameterDescriptor> result = Lists.newArrayList(); for (TypeParameterDescriptor autoParameter : autoTypeParameters) { int index = autoParameter.getIndex(); TypeParameterDescriptorImpl modifiedTypeParameter = autoTypeParameterToModified.get(autoParameter); List<Iterator<JetType>> upperBoundFromSuperFunctionsIterators = Lists.newArrayList(); for (FunctionDescriptor superFunction : superFunctions) { upperBoundFromSuperFunctionsIterators.add( superFunction.getTypeParameters().get(index).getUpperBounds().iterator()); } for (JetType autoUpperBound : autoParameter.getUpperBounds()) { List<TypeAndVariance> upperBoundsFromSuperFunctions = Lists.newArrayList(); for (Iterator<JetType> iterator : upperBoundFromSuperFunctionsIterators) { assert iterator.hasNext(); upperBoundsFromSuperFunctions.add(new TypeAndVariance(iterator.next(), INVARIANT)); } JetType modifiedUpperBound = modifyTypeAccordingToSuperMethods( autoUpperBound, upperBoundsFromSuperFunctions, UPPER_BOUND); modifiedTypeParameter.addUpperBound(modifiedUpperBound); } for (Iterator<JetType> iterator : upperBoundFromSuperFunctionsIterators) { assert !iterator.hasNext(); } modifiedTypeParameter.setInitialized(); result.add(modifiedTypeParameter); } return result; }