001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.resolve.jvm.kotlinSignature;
018
019 import com.google.common.collect.Lists;
020 import com.google.common.collect.Multimap;
021 import com.google.common.collect.Sets;
022 import com.intellij.util.Function;
023 import com.intellij.util.containers.ContainerUtil;
024 import kotlin.CollectionsKt;
025 import kotlin.jvm.functions.Function1;
026 import org.jetbrains.annotations.NotNull;
027 import org.jetbrains.annotations.Nullable;
028 import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
029 import org.jetbrains.kotlin.descriptors.*;
030 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
031 import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
032 import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
033 import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
034 import org.jetbrains.kotlin.load.java.components.TypeUsage;
035 import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
036 import org.jetbrains.kotlin.load.java.structure.JavaMethod;
037 import org.jetbrains.kotlin.name.FqNameUnsafe;
038 import org.jetbrains.kotlin.name.Name;
039 import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
040 import org.jetbrains.kotlin.renderer.DescriptorRenderer;
041 import org.jetbrains.kotlin.resolve.DescriptorUtils;
042 import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
043 import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolverKt;
044 import org.jetbrains.kotlin.resolve.jvm.JavaResolverUtils;
045 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
046 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapper;
047 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapperKt;
048 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
049 import org.jetbrains.kotlin.types.*;
050
051 import java.util.*;
052
053 import static org.jetbrains.kotlin.load.java.components.TypeUsage.*;
054 import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
055 import static org.jetbrains.kotlin.types.Variance.INVARIANT;
056
057 public class SignaturesPropagationData {
058
059 private static final KotlinToJvmSignatureMapper SIGNATURE_MAPPER = ServiceLoader.load(
060 KotlinToJvmSignatureMapper.class,
061 KotlinToJvmSignatureMapper.class.getClassLoader()
062 ).iterator().next();
063
064 private final JavaMethodDescriptor autoMethodDescriptor;
065
066 private final List<TypeParameterDescriptor> modifiedTypeParameters;
067 private final ValueParameters modifiedValueParameters;
068
069 private final KotlinType modifiedReturnType;
070 private final List<String> signatureErrors = Lists.newArrayList();
071 private final List<FunctionDescriptor> superFunctions;
072 private final Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> autoTypeParameterToModified;
073 final ClassDescriptor containingClass;
074
075 public SignaturesPropagationData(
076 @NotNull ClassDescriptor containingClass,
077 @NotNull KotlinType autoReturnType, // type built by JavaTypeTransformer from Java signature and @NotNull annotations
078 @Nullable KotlinType receiverType,
079 @NotNull List<ValueParameterDescriptor> autoValueParameters, // descriptors built by parameters resolver
080 @NotNull List<TypeParameterDescriptor> autoTypeParameters, // descriptors built by signature resolver
081 @NotNull JavaMethod method
082 ) {
083 this.containingClass = containingClass;
084
085 autoMethodDescriptor =
086 createAutoMethodDescriptor(containingClass, method, autoReturnType, receiverType, autoValueParameters, autoTypeParameters);
087
088 superFunctions = getSuperFunctionsForMethod(method, autoMethodDescriptor, containingClass);
089
090 autoTypeParameterToModified = JavaResolverUtils.recreateTypeParametersAndReturnMapping(autoTypeParameters, null);
091
092 modifiedTypeParameters = modifyTypeParametersAccordingToSuperMethods(autoTypeParameters);
093 modifiedReturnType = modifyReturnTypeAccordingToSuperMethods(autoReturnType);
094 modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(receiverType, autoValueParameters);
095 }
096
097 @NotNull
098 private static JavaMethodDescriptor createAutoMethodDescriptor(
099 @NotNull ClassDescriptor containingClass,
100 @NotNull JavaMethod method, KotlinType autoReturnType,
101 @Nullable KotlinType receiverType,
102 @NotNull List<ValueParameterDescriptor> autoValueParameters,
103 @NotNull List<TypeParameterDescriptor> autoTypeParameters
104 ) {
105 JavaMethodDescriptor autoMethodDescriptor = JavaMethodDescriptor.createJavaMethod(
106 containingClass,
107 Annotations.Companion.getEMPTY(),
108 method.getName(),
109 //TODO: what to do?
110 SourceElement.NO_SOURCE
111 );
112 autoMethodDescriptor.initialize(
113 receiverType,
114 containingClass.getThisAsReceiverParameter(),
115 autoTypeParameters,
116 autoValueParameters,
117 autoReturnType,
118 Modality.OPEN,
119 Visibilities.PUBLIC
120 );
121 return autoMethodDescriptor;
122 }
123
124 public List<TypeParameterDescriptor> getModifiedTypeParameters() {
125 return modifiedTypeParameters;
126 }
127
128 public KotlinType getModifiedReceiverType() {
129 return modifiedValueParameters.receiverType;
130 }
131
132 public List<ValueParameterDescriptor> getModifiedValueParameters() {
133 return modifiedValueParameters.descriptors;
134 }
135
136 public boolean getModifiedHasStableParameterNames() {
137 return modifiedValueParameters.hasStableParameterNames;
138 }
139
140 public KotlinType getModifiedReturnType() {
141 return modifiedReturnType;
142 }
143
144 public List<String> getSignatureErrors() {
145 return signatureErrors;
146 }
147
148 public List<FunctionDescriptor> getSuperFunctions() {
149 return superFunctions;
150 }
151
152 void reportError(String error) {
153 signatureErrors.add(error);
154 }
155
156 private KotlinType modifyReturnTypeAccordingToSuperMethods(
157 @NotNull KotlinType autoType // type built by JavaTypeTransformer
158 ) {
159 if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoType;
160
161 List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map(superFunctions,
162 new Function<FunctionDescriptor, TypeAndVariance>() {
163 @Override
164 public TypeAndVariance fun(FunctionDescriptor superFunction) {
165 return new TypeAndVariance(superFunction.getReturnType(),
166 Variance.OUT_VARIANCE);
167 }
168 });
169
170 return modifyTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, MEMBER_SIGNATURE_COVARIANT);
171 }
172
173 private List<TypeParameterDescriptor> modifyTypeParametersAccordingToSuperMethods(List<TypeParameterDescriptor> autoTypeParameters) {
174 if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoTypeParameters;
175
176 List<TypeParameterDescriptor> result = Lists.newArrayList();
177
178 for (TypeParameterDescriptor autoParameter : autoTypeParameters) {
179 int index = autoParameter.getIndex();
180 TypeParameterDescriptorImpl modifiedTypeParameter = autoTypeParameterToModified.get(autoParameter);
181
182 List<Iterator<KotlinType>> upperBoundFromSuperFunctionsIterators = Lists.newArrayList();
183 for (FunctionDescriptor superFunction : superFunctions) {
184 upperBoundFromSuperFunctionsIterators.add(superFunction.getTypeParameters().get(index).getUpperBounds().iterator());
185 }
186
187 for (KotlinType autoUpperBound : autoParameter.getUpperBounds()) {
188 List<TypeAndVariance> upperBoundsFromSuperFunctions = Lists.newArrayList();
189
190 for (Iterator<KotlinType> iterator : upperBoundFromSuperFunctionsIterators) {
191 assert iterator.hasNext();
192 upperBoundsFromSuperFunctions.add(new TypeAndVariance(iterator.next(), INVARIANT));
193 }
194
195 KotlinType modifiedUpperBound = modifyTypeAccordingToSuperMethods(autoUpperBound, upperBoundsFromSuperFunctions, UPPER_BOUND);
196 modifiedTypeParameter.addUpperBound(modifiedUpperBound);
197 }
198
199 for (Iterator<KotlinType> iterator : upperBoundFromSuperFunctionsIterators) {
200 assert !iterator.hasNext();
201 }
202
203 modifiedTypeParameter.setInitialized();
204 result.add(modifiedTypeParameter);
205 }
206
207 return result;
208 }
209
210 private ValueParameters modifyValueParametersAccordingToSuperMethods(
211 @Nullable KotlinType receiverType,
212 @NotNull List<ValueParameterDescriptor> parameters // descriptors built by parameters resolver
213 ) {
214 assert receiverType == null : "Parameters before propagation have receiver type," +
215 " but propagation should be disabled for functions compiled from Kotlin in class: " +
216 DescriptorUtils.getFqName(containingClass);
217
218 KotlinType resultReceiverType = null;
219 List<ValueParameterDescriptor> resultParameters = new ArrayList<ValueParameterDescriptor>(parameters.size());
220
221 boolean shouldBeExtension = checkIfShouldBeExtension();
222
223 for (final ValueParameterDescriptor originalParam : parameters) {
224 final int originalIndex = originalParam.getIndex();
225 List<TypeAndName> typesFromSuperMethods = ContainerUtil.map(superFunctions,
226 new Function<FunctionDescriptor, TypeAndName>() {
227 @Override
228 public TypeAndName fun(FunctionDescriptor superFunction) {
229 ReceiverParameterDescriptor receiver = superFunction.getExtensionReceiverParameter();
230 int index = receiver != null ? originalIndex - 1 : originalIndex;
231 if (index == -1) {
232 assert receiver != null : "can't happen: index is -1, while function is not extension";
233 return new TypeAndName(receiver.getType(), originalParam.getName());
234 }
235 ValueParameterDescriptor parameter = superFunction.getValueParameters().get(index);
236 return new TypeAndName(parameter.getType(), parameter.getName());
237 }
238 });
239
240 VarargCheckResult varargCheckResult = checkVarargInSuperFunctions(originalParam);
241
242 KotlinType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType,
243 convertToTypeVarianceList(typesFromSuperMethods),
244 MEMBER_SIGNATURE_CONTRAVARIANT);
245
246 if (shouldBeExtension && originalIndex == 0) {
247 resultReceiverType = altType;
248 }
249 else {
250 Name stableName = null;
251 for (int i = 0; i < superFunctions.size(); i++) {
252 if (superFunctions.get(i).hasStableParameterNames()) {
253 // When there's more than one stable name in super functions, we pick the first one. This behaviour is similar to
254 // the compiler front-end, except that it reports a warning in such cases
255 // TODO: report a warning somewhere if there's more than one stable name in super functions
256 stableName = typesFromSuperMethods.get(i).name;
257 break;
258 }
259 }
260
261 resultParameters.add(new ValueParameterDescriptorImpl(
262 originalParam.getContainingDeclaration(),
263 null,
264 shouldBeExtension ? originalIndex - 1 : originalIndex,
265 originalParam.getAnnotations(),
266 stableName != null ? stableName : originalParam.getName(),
267 altType,
268 originalParam.declaresDefaultValue(),
269 originalParam.isCrossinline(),
270 originalParam.isNoinline(),
271 varargCheckResult.isVararg ? DescriptorUtilsKt.getBuiltIns(originalParam).getArrayElementType(altType) : null,
272 SourceElement.NO_SOURCE
273 ));
274 }
275 }
276
277 boolean hasStableParameterNames = CollectionsKt.any(superFunctions, new Function1<FunctionDescriptor, Boolean>() {
278 @Override
279 public Boolean invoke(FunctionDescriptor descriptor) {
280 return descriptor.hasStableParameterNames();
281 }
282 });
283
284 return new ValueParameters(resultReceiverType, resultParameters, hasStableParameterNames);
285 }
286
287 @NotNull
288 private static List<TypeAndVariance> convertToTypeVarianceList(@NotNull List<TypeAndName> list) {
289 return CollectionsKt.map(list, new Function1<TypeAndName, TypeAndVariance>() {
290 @Override
291 public TypeAndVariance invoke(TypeAndName tvn) {
292 return new TypeAndVariance(tvn.type, INVARIANT);
293 }
294 });
295 }
296
297 private static List<FunctionDescriptor> getSuperFunctionsForMethod(
298 @NotNull JavaMethod method,
299 @NotNull JavaMethodDescriptor autoMethodDescriptor,
300 @NotNull ClassDescriptor containingClass
301 ) {
302 List<FunctionDescriptor> superFunctions = Lists.newArrayList();
303
304 // TODO: Add propagation for other kotlin descriptors (KT-3621)
305 Name name = method.getName();
306 JvmMethodSignature autoSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(autoMethodDescriptor);
307 for (KotlinType supertype : containingClass.getTypeConstructor().getSupertypes()) {
308 Collection<FunctionDescriptor> superFunctionCandidates = supertype.getMemberScope().getContributedFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS);
309 for (FunctionDescriptor candidate : superFunctionCandidates) {
310 JvmMethodSignature candidateSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(candidate);
311 if (KotlinToJvmSignatureMapperKt.erasedSignaturesEqualIgnoringReturnTypes(autoSignature, candidateSignature)) {
312 superFunctions.add(candidate);
313 }
314 }
315 }
316
317 // sorting for diagnostic stability
318 Collections.sort(superFunctions, new Comparator<FunctionDescriptor>() {
319 @Override
320 public int compare(@NotNull FunctionDescriptor fun1, @NotNull FunctionDescriptor fun2) {
321 FqNameUnsafe fqName1 = getFqName(fun1.getContainingDeclaration());
322 FqNameUnsafe fqName2 = getFqName(fun2.getContainingDeclaration());
323 return fqName1.asString().compareTo(fqName2.asString());
324 }
325 });
326 return superFunctions;
327 }
328
329 private boolean checkIfShouldBeExtension() {
330 boolean someSupersExtension = false;
331 boolean someSupersNotExtension = false;
332
333 for (FunctionDescriptor superFunction : superFunctions) {
334 if (superFunction.getExtensionReceiverParameter() != null) {
335 someSupersExtension = true;
336 }
337 else {
338 someSupersNotExtension = true;
339 }
340 }
341
342 if (someSupersExtension) {
343 if (someSupersNotExtension) {
344 reportError("Incompatible super methods: some are extension functions, some are not");
345 }
346 else {
347 return true;
348 }
349 }
350 return false;
351 }
352
353 @NotNull
354 private VarargCheckResult checkVarargInSuperFunctions(@NotNull ValueParameterDescriptor originalParam) {
355 boolean someSupersVararg = false;
356 boolean someSupersNotVararg = false;
357 for (FunctionDescriptor superFunction : superFunctions) {
358 int originalIndex = originalParam.getIndex();
359 int index = superFunction.getExtensionReceiverParameter() != null ? originalIndex - 1 : originalIndex;
360 if (index != -1 && superFunction.getValueParameters().get(index).getVarargElementType() != null) {
361 someSupersVararg = true;
362 }
363 else {
364 someSupersNotVararg = true;
365 }
366 }
367
368 KotlinType originalVarargElementType = originalParam.getVarargElementType();
369 KotlinType originalType = originalParam.getType();
370
371 if (someSupersVararg && someSupersNotVararg) {
372 reportError("Incompatible super methods: some have vararg parameter, some have not");
373 return new VarargCheckResult(originalType, originalVarargElementType != null);
374 }
375
376 if (someSupersVararg && originalVarargElementType == null) {
377 // convert to vararg
378
379 assert isArrayType(originalType);
380 return new VarargCheckResult(TypeUtils.makeNotNullable(originalType), true);
381 }
382 else if (someSupersNotVararg && originalVarargElementType != null) {
383 // convert to non-vararg
384
385 assert isArrayType(originalType);
386 return new VarargCheckResult(TypeUtils.makeNullable(originalType), false);
387 }
388 return new VarargCheckResult(originalType, originalVarargElementType != null);
389 }
390
391 @NotNull
392 private KotlinType modifyTypeAccordingToSuperMethods(
393 @NotNull KotlinType autoType,
394 @NotNull List<TypeAndVariance> typesFromSuper,
395 @NotNull TypeUsage howThisTypeIsUsed
396 ) {
397 if (autoType.isError()) return autoType;
398
399 if (JavaDescriptorResolverKt.getPLATFORM_TYPES()) return autoType;
400
401 boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, howThisTypeIsUsed);
402 ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper);
403 List<TypeProjection> resultArguments = getTypeArgsOfType(autoType, resultClassifier, typesFromSuper);
404 MemberScope resultScope;
405 if (resultClassifier instanceof ClassDescriptor) {
406 resultScope = ((ClassDescriptor) resultClassifier).getMemberScope(resultArguments);
407 }
408 else {
409 resultScope = autoType.getMemberScope();
410 }
411
412 KotlinType type = KotlinTypeImpl.create(autoType.getAnnotations(),
413 resultClassifier.getTypeConstructor(),
414 resultNullable,
415 resultArguments,
416 resultScope);
417
418 PropagationHeuristics.checkArrayInReturnType(this, type, typesFromSuper);
419 return type;
420 }
421
422 @NotNull
423 private List<TypeProjection> getTypeArgsOfType(
424 @NotNull KotlinType autoType,
425 @NotNull ClassifierDescriptor classifier,
426 @NotNull List<TypeAndVariance> typesFromSuper
427 ) {
428 if (typesFromSuper.isEmpty()) return autoType.getArguments();
429
430 List<TypeProjection> autoArguments = autoType.getArguments();
431
432 if (!(classifier instanceof ClassDescriptor)) {
433 assert autoArguments.isEmpty() :
434 "Unexpected type arguments when type constructor is not ClassDescriptor, type = " + autoType +
435 ", classifier = " + classifier + ", classifier class = " + classifier.getClass();
436 return autoArguments;
437 }
438
439 List<List<TypeProjectionAndVariance>> typeArgumentsFromSuper = calculateTypeArgumentsFromSuper((ClassDescriptor) classifier,
440 typesFromSuper);
441
442 // Modify type arguments using info from typesFromSuper
443 List<TypeProjection> resultArguments = Lists.newArrayList();
444 for (TypeParameterDescriptor parameter : classifier.getTypeConstructor().getParameters()) {
445 TypeProjection argument = autoArguments.get(parameter.getIndex());
446
447 KotlinType argumentType = argument.getType();
448 List<TypeProjectionAndVariance> projectionsFromSuper = typeArgumentsFromSuper.get(parameter.getIndex());
449 List<TypeAndVariance> argTypesFromSuper = getTypes(projectionsFromSuper);
450
451 KotlinType type = modifyTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, TYPE_ARGUMENT);
452 Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper);
453
454 resultArguments.add(new TypeProjectionImpl(projectionKind, type));
455 }
456 return resultArguments;
457 }
458
459 private Variance calculateArgumentProjectionKindFromSuper(
460 @NotNull TypeProjection argument,
461 @NotNull List<TypeProjectionAndVariance> projectionsFromSuper
462 ) {
463 if (projectionsFromSuper.isEmpty()) return argument.getProjectionKind();
464
465 Set<Variance> projectionKindsInSuper = Sets.newLinkedHashSet();
466 for (TypeProjectionAndVariance projectionAndVariance : projectionsFromSuper) {
467 projectionKindsInSuper.add(projectionAndVariance.typeProjection.getProjectionKind());
468 }
469
470 Variance defaultProjectionKind = argument.getProjectionKind();
471 if (projectionKindsInSuper.size() == 0) {
472 return defaultProjectionKind;
473 }
474 else if (projectionKindsInSuper.size() == 1) {
475 Variance projectionKindInSuper = projectionKindsInSuper.iterator().next();
476 if (defaultProjectionKind == INVARIANT || defaultProjectionKind == projectionKindInSuper) {
477 return projectionKindInSuper;
478 }
479 else {
480 reportError("Incompatible projection kinds in type arguments of super methods' return types: "
481 + projectionsFromSuper + ", defined in current: " + argument);
482 return defaultProjectionKind;
483 }
484 }
485 else {
486 reportError("Incompatible projection kinds in type arguments of super methods' return types: " + projectionsFromSuper);
487 return defaultProjectionKind;
488 }
489 }
490
491 @NotNull
492 private static List<TypeAndVariance> getTypes(@NotNull List<TypeProjectionAndVariance> projections) {
493 List<TypeAndVariance> types = Lists.newArrayList();
494 for (TypeProjectionAndVariance projection : projections) {
495 types.add(new TypeAndVariance(projection.typeProjection.getType(),
496 merge(projection.varianceOfPosition, projection.typeProjection.getProjectionKind())));
497 }
498 return types;
499 }
500
501 private static Variance merge(Variance positionOfOuter, Variance projectionKind) {
502 // Inv<Inv<out X>>, X is in invariant position
503 if (positionOfOuter == INVARIANT) return INVARIANT;
504 // Out<X>, X is in out-position
505 if (projectionKind == INVARIANT) return positionOfOuter;
506 // Out<Out<X>>, X is in out-position
507 // In<In<X>>, X is in out-position
508 // Out<In<X>>, X is in in-position
509 // In<Out<X>>, X is in in-position
510 return positionOfOuter.superpose(projectionKind);
511 }
512
513 // Returns list with type arguments info from supertypes
514 // Example:
515 // - Foo<A, B> is a subtype of Bar<A, List<B>>, Baz<Boolean, A>
516 // - input: klass = Foo, typesFromSuper = [Bar<String, List<Int>>, Baz<Boolean, CharSequence>]
517 // - output[0] = [String, CharSequence], output[1] = []
518 private static List<List<TypeProjectionAndVariance>> calculateTypeArgumentsFromSuper(
519 @NotNull ClassDescriptor klass,
520 @NotNull Collection<TypeAndVariance> typesFromSuper
521 ) {
522 // For each superclass of klass and its parameters, hold their mapping to klass' parameters
523 // #0 of Bar -> A
524 // #1 of Bar -> List<B>
525 // #0 of Baz -> Boolean
526 // #1 of Baz -> A
527 // #0 of Foo -> A (mapped to itself)
528 // #1 of Foo -> B (mapped to itself)
529 Multimap<TypeConstructor, TypeProjection> substitution = SubstitutionUtils.buildDeepSubstitutionMultimap(
530 TypeUtils.makeUnsubstitutedType(klass, ErrorUtils.createErrorScope("Do not access this scope", true)));
531
532 // for each parameter of klass, hold arguments in corresponding supertypes
533 List<List<TypeProjectionAndVariance>> parameterToArgumentsFromSuper = Lists.newArrayList();
534 for (TypeParameterDescriptor ignored : klass.getTypeConstructor().getParameters()) {
535 parameterToArgumentsFromSuper.add(new ArrayList<TypeProjectionAndVariance>());
536 }
537
538 // Enumerate all types from super and all its parameters
539 for (TypeAndVariance typeFromSuper : typesFromSuper) {
540 for (TypeParameterDescriptor parameter : typeFromSuper.type.getConstructor().getParameters()) {
541 TypeProjection argument = typeFromSuper.type.getArguments().get(parameter.getIndex());
542
543 // for given example, this block is executed four times:
544 // 1. typeFromSuper = Bar<String, List<Int>>, parameter = "#0 of Bar", argument = String
545 // 2. typeFromSuper = Bar<String, List<Int>>, parameter = "#1 of Bar", argument = List<Int>
546 // 3. typeFromSuper = Baz<Boolean, CharSequence>, parameter = "#0 of Baz", argument = Boolean
547 // 4. typeFromSuper = Baz<Boolean, CharSequence>, parameter = "#1 of Baz", argument = CharSequence
548
549 // if it is mapped to klass' parameter, then store it into map
550 for (TypeProjection projection : substitution.get(parameter.getTypeConstructor())) {
551 // 1. projection = A
552 // 2. projection = List<B>
553 // 3. projection = Boolean
554 // 4. projection = A
555 ClassifierDescriptor classifier = projection.getType().getConstructor().getDeclarationDescriptor();
556
557 // this condition is true for 1 and 4, false for 2 and 3
558 if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == klass) {
559 int parameterIndex = ((TypeParameterDescriptor) classifier).getIndex();
560 Variance effectiveVariance = parameter.getVariance().superpose(typeFromSuper.varianceOfPosition);
561 parameterToArgumentsFromSuper.get(parameterIndex).add(new TypeProjectionAndVariance(argument, effectiveVariance));
562 }
563 }
564 }
565 }
566 return parameterToArgumentsFromSuper;
567 }
568
569 private boolean typeMustBeNullable(
570 @NotNull KotlinType autoType,
571 @NotNull List<TypeAndVariance> typesFromSuper,
572 @NotNull TypeUsage howThisTypeIsUsed
573 ) {
574 boolean someSupersNotCovariantNullable = false;
575 boolean someSupersCovariantNullable = false;
576 boolean someSupersNotNull = false;
577 for (TypeAndVariance typeFromSuper : typesFromSuper) {
578 if (!TypeUtils.isNullableType(typeFromSuper.type)) {
579 someSupersNotNull = true;
580 }
581 else {
582 if (typeFromSuper.varianceOfPosition == Variance.OUT_VARIANCE) {
583 someSupersCovariantNullable = true;
584 }
585 else {
586 someSupersNotCovariantNullable = true;
587 }
588 }
589 }
590
591 if (someSupersNotNull && someSupersNotCovariantNullable) {
592 reportError("Incompatible types in superclasses: " + typesFromSuper);
593 return TypeUtils.isNullableType(autoType);
594 }
595 else if (someSupersNotNull) {
596 return false;
597 }
598 else if (someSupersNotCovariantNullable || someSupersCovariantNullable) {
599 boolean annotatedAsNotNull = howThisTypeIsUsed != TYPE_ARGUMENT && !TypeUtils.isNullableType(autoType);
600
601 if (annotatedAsNotNull && someSupersNotCovariantNullable) {
602 DescriptorRenderer renderer = DescriptorRenderer.SHORT_NAMES_IN_TYPES;
603 reportError("In superclass type is nullable: " + typesFromSuper + ", in subclass it is not: " + renderer.renderType(autoType));
604 return true;
605 }
606
607 return !annotatedAsNotNull;
608 }
609 return TypeUtils.isNullableType(autoType);
610 }
611
612 @NotNull
613 private ClassifierDescriptor modifyTypeClassifier(
614 @NotNull KotlinType autoType,
615 @NotNull List<TypeAndVariance> typesFromSuper
616 ) {
617 ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
618 if (!(classifier instanceof ClassDescriptor)) {
619 assert classifier != null : "no declaration descriptor for type " + autoType + ", auto method descriptor: " + autoMethodDescriptor;
620
621 if (classifier instanceof TypeParameterDescriptor && autoTypeParameterToModified.containsKey(classifier)) {
622 return autoTypeParameterToModified.get(classifier);
623 }
624 return classifier;
625 }
626 ClassDescriptor klass = (ClassDescriptor) classifier;
627
628 boolean someSupersMutable = false;
629 boolean someSupersCovariantReadOnly = false;
630 boolean someSupersNotCovariantReadOnly = false;
631 for (TypeAndVariance typeFromSuper : typesFromSuper) {
632 ClassifierDescriptor classifierFromSuper = typeFromSuper.type.getConstructor().getDeclarationDescriptor();
633 if (classifierFromSuper instanceof ClassDescriptor) {
634 ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper;
635
636 if (JavaToKotlinClassMap.INSTANCE.isMutable(classFromSuper)) {
637 someSupersMutable = true;
638 }
639 else if (JavaToKotlinClassMap.INSTANCE.isReadOnly(classFromSuper)) {
640 if (typeFromSuper.varianceOfPosition == Variance.OUT_VARIANCE) {
641 someSupersCovariantReadOnly = true;
642 }
643 else {
644 someSupersNotCovariantReadOnly = true;
645 }
646 }
647 }
648 }
649
650 if (someSupersMutable && someSupersNotCovariantReadOnly) {
651 reportError("Incompatible types in superclasses: " + typesFromSuper);
652 return classifier;
653 }
654 else if (someSupersMutable) {
655 if (JavaToKotlinClassMap.INSTANCE.isReadOnly(klass)) {
656 return JavaToKotlinClassMap.INSTANCE.convertReadOnlyToMutable(klass);
657 }
658 }
659 else if (someSupersNotCovariantReadOnly || someSupersCovariantReadOnly) {
660 if (JavaToKotlinClassMap.INSTANCE.isMutable(klass)) {
661 return JavaToKotlinClassMap.INSTANCE.convertMutableToReadOnly(klass);
662 }
663 }
664
665 ClassifierDescriptor fixed = PropagationHeuristics.tryToFixOverridingTWithRawType(this, typesFromSuper);
666 return fixed != null ? fixed : classifier;
667 }
668
669 private static boolean isArrayType(@NotNull KotlinType type) {
670 return KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type);
671 }
672
673 private static class VarargCheckResult {
674 public final KotlinType parameterType;
675 public final boolean isVararg;
676
677 public VarargCheckResult(KotlinType parameterType, boolean isVararg) {
678 this.parameterType = parameterType;
679 this.isVararg = isVararg;
680 }
681 }
682
683 private static class TypeProjectionAndVariance {
684 public final TypeProjection typeProjection;
685 public final Variance varianceOfPosition;
686
687 public TypeProjectionAndVariance(TypeProjection typeProjection, Variance varianceOfPosition) {
688 this.typeProjection = typeProjection;
689 this.varianceOfPosition = varianceOfPosition;
690 }
691
692 public String toString() {
693 return typeProjection.toString();
694 }
695 }
696
697 static class TypeAndVariance {
698 public final KotlinType type;
699 public final Variance varianceOfPosition;
700
701 public TypeAndVariance(KotlinType type, Variance varianceOfPosition) {
702 this.type = type;
703 this.varianceOfPosition = varianceOfPosition;
704 }
705
706 public String toString() {
707 return type.toString();
708 }
709 }
710
711 private static class TypeAndName {
712 public final KotlinType type;
713 public final Name name;
714
715 public TypeAndName(KotlinType type, Name name) {
716 this.type = type;
717 this.name = name;
718 }
719 }
720
721 private static class ValueParameters {
722 private final KotlinType receiverType;
723 private final List<ValueParameterDescriptor> descriptors;
724 private final boolean hasStableParameterNames;
725
726 public ValueParameters(
727 @Nullable KotlinType receiverType,
728 @NotNull List<ValueParameterDescriptor> descriptors,
729 boolean hasStableParameterNames
730 ) {
731 this.receiverType = receiverType;
732 this.descriptors = descriptors;
733 this.hasStableParameterNames = hasStableParameterNames;
734 }
735 }
736 }