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.KtScope; 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().getFunctions(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 KtScope 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 }