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