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.builtins; 018 019 import kotlin.collections.SetsKt; 020 import kotlin.jvm.functions.Function1; 021 import org.jetbrains.annotations.NotNull; 022 import org.jetbrains.annotations.Nullable; 023 import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory; 024 import org.jetbrains.kotlin.descriptors.*; 025 import org.jetbrains.kotlin.descriptors.annotations.*; 026 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; 027 import org.jetbrains.kotlin.incremental.components.NoLookupLocation; 028 import org.jetbrains.kotlin.name.ClassId; 029 import org.jetbrains.kotlin.name.FqName; 030 import org.jetbrains.kotlin.name.FqNameUnsafe; 031 import org.jetbrains.kotlin.name.Name; 032 import org.jetbrains.kotlin.resolve.DescriptorUtils; 033 import org.jetbrains.kotlin.resolve.scopes.MemberScope; 034 import org.jetbrains.kotlin.serialization.deserialization.AdditionalSupertypes; 035 import org.jetbrains.kotlin.storage.LockBasedStorageManager; 036 import org.jetbrains.kotlin.types.*; 037 import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; 038 039 import java.io.InputStream; 040 import java.util.*; 041 042 import static kotlin.collections.CollectionsKt.single; 043 import static kotlin.collections.SetsKt.setOf; 044 import static org.jetbrains.kotlin.builtins.PrimitiveType.*; 045 import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName; 046 047 public abstract class KotlinBuiltIns { 048 public static final Name BUILT_INS_PACKAGE_NAME = Name.identifier("kotlin"); 049 public static final FqName BUILT_INS_PACKAGE_FQ_NAME = FqName.topLevel(BUILT_INS_PACKAGE_NAME); 050 private static final FqName ANNOTATION_PACKAGE_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("annotation")); 051 public static final FqName COLLECTIONS_PACKAGE_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("collections")); 052 public static final FqName RANGES_PACKAGE_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("ranges")); 053 054 public static final Set<FqName> BUILT_INS_PACKAGE_FQ_NAMES = setOf( 055 BUILT_INS_PACKAGE_FQ_NAME, 056 COLLECTIONS_PACKAGE_FQ_NAME, 057 RANGES_PACKAGE_FQ_NAME, 058 ANNOTATION_PACKAGE_FQ_NAME, 059 ReflectionTypesKt.getKOTLIN_REFLECT_FQ_NAME(), 060 BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("internal")) 061 ); 062 063 protected final ModuleDescriptorImpl builtInsModule; 064 private final BuiltInsPackageFragment builtInsPackageFragment; 065 private final BuiltInsPackageFragment collectionsPackageFragment; 066 private final BuiltInsPackageFragment rangesPackageFragment; 067 private final BuiltInsPackageFragment annotationPackageFragment; 068 069 private final Set<BuiltInsPackageFragment> builtInsPackageFragments; 070 071 private final Map<PrimitiveType, KotlinType> primitiveTypeToArrayKotlinType; 072 private final Map<KotlinType, KotlinType> primitiveKotlinTypeToKotlinArrayType; 073 private final Map<KotlinType, KotlinType> kotlinArrayTypeToPrimitiveKotlinType; 074 private final Map<FqName, BuiltInsPackageFragment> packageNameToPackageFragment; 075 076 public static final FqNames FQ_NAMES = new FqNames(); 077 078 protected KotlinBuiltIns() { 079 LockBasedStorageManager storageManager = new LockBasedStorageManager(); 080 builtInsModule = new ModuleDescriptorImpl( 081 Name.special("<built-ins module>"), storageManager, ModuleParameters.Empty.INSTANCE, this 082 ); 083 084 PackageFragmentProvider packageFragmentProvider = BuiltInsPackageFragmentProviderKt.createBuiltInPackageFragmentProvider( 085 storageManager, builtInsModule, BUILT_INS_PACKAGE_FQ_NAMES, 086 new BuiltInFictitiousFunctionClassFactory(storageManager, builtInsModule), 087 getAdditionalSupertypesProvider(), 088 new Function1<String, InputStream>() { 089 @Override 090 public InputStream invoke(String path) { 091 return KotlinBuiltIns.class.getClassLoader().getResourceAsStream(path); 092 } 093 } 094 ); 095 096 builtInsModule.initialize(packageFragmentProvider); 097 builtInsModule.setDependencies(builtInsModule); 098 099 packageNameToPackageFragment = new LinkedHashMap<FqName, BuiltInsPackageFragment>(); 100 101 builtInsPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, BUILT_INS_PACKAGE_FQ_NAME); 102 collectionsPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, COLLECTIONS_PACKAGE_FQ_NAME); 103 rangesPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, RANGES_PACKAGE_FQ_NAME); 104 annotationPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, ANNOTATION_PACKAGE_FQ_NAME); 105 106 builtInsPackageFragments = new LinkedHashSet<BuiltInsPackageFragment>(packageNameToPackageFragment.values()); 107 108 primitiveTypeToArrayKotlinType = new EnumMap<PrimitiveType, KotlinType>(PrimitiveType.class); 109 primitiveKotlinTypeToKotlinArrayType = new HashMap<KotlinType, KotlinType>(); 110 kotlinArrayTypeToPrimitiveKotlinType = new HashMap<KotlinType, KotlinType>(); 111 for (PrimitiveType primitive : PrimitiveType.values()) { 112 makePrimitive(primitive); 113 } 114 } 115 116 @NotNull 117 protected AdditionalSupertypes getAdditionalSupertypesProvider() { 118 return AdditionalSupertypes.None.INSTANCE; 119 } 120 121 private void makePrimitive(@NotNull PrimitiveType primitiveType) { 122 KotlinType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString()); 123 KotlinType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString()); 124 125 primitiveTypeToArrayKotlinType.put(primitiveType, arrayType); 126 primitiveKotlinTypeToKotlinArrayType.put(type, arrayType); 127 kotlinArrayTypeToPrimitiveKotlinType.put(arrayType, type); 128 } 129 130 131 @NotNull 132 private static BuiltInsPackageFragment createPackage( 133 @NotNull PackageFragmentProvider fragmentProvider, 134 @NotNull Map<FqName, BuiltInsPackageFragment> packageNameToPackageFragment, 135 @NotNull FqName packageFqName 136 ) { 137 BuiltInsPackageFragment packageFragment = (BuiltInsPackageFragment) single(fragmentProvider.getPackageFragments(packageFqName)); 138 packageNameToPackageFragment.put(packageFqName, packageFragment); 139 return packageFragment; 140 } 141 142 @SuppressWarnings("WeakerAccess") 143 public static class FqNames { 144 public final FqNameUnsafe any = fqNameUnsafe("Any"); 145 public final FqNameUnsafe nothing = fqNameUnsafe("Nothing"); 146 public final FqNameUnsafe cloneable = fqNameUnsafe("Cloneable"); 147 public final FqNameUnsafe suppress = fqNameUnsafe("Suppress"); 148 public final FqNameUnsafe unit = fqNameUnsafe("Unit"); 149 public final FqNameUnsafe charSequence = fqNameUnsafe("CharSequence"); 150 public final FqNameUnsafe string = fqNameUnsafe("String"); 151 public final FqNameUnsafe array = fqNameUnsafe("Array"); 152 153 public final FqNameUnsafe _boolean = fqNameUnsafe("Boolean"); 154 public final FqNameUnsafe _char = fqNameUnsafe("Char"); 155 public final FqNameUnsafe _byte = fqNameUnsafe("Byte"); 156 public final FqNameUnsafe _short = fqNameUnsafe("Short"); 157 public final FqNameUnsafe _int = fqNameUnsafe("Int"); 158 public final FqNameUnsafe _long = fqNameUnsafe("Long"); 159 public final FqNameUnsafe _float = fqNameUnsafe("Float"); 160 public final FqNameUnsafe _double = fqNameUnsafe("Double"); 161 public final FqNameUnsafe number = fqNameUnsafe("Number"); 162 163 public final FqNameUnsafe _enum = fqNameUnsafe("Enum"); 164 165 166 167 public final FqName throwable = fqName("Throwable"); 168 169 public final FqName deprecated = fqName("Deprecated"); 170 public final FqName deprecationLevel = fqName("DeprecationLevel"); 171 public final FqName extensionFunctionType = fqName("ExtensionFunctionType"); 172 public final FqName target = annotationName("Target"); 173 public final FqName annotationTarget = annotationName("AnnotationTarget"); 174 public final FqName annotationRetention = annotationName("AnnotationRetention"); 175 public final FqName retention = annotationName("Retention"); 176 public final FqName repeatable = annotationName("Repeatable"); 177 public final FqName mustBeDocumented = annotationName("MustBeDocumented"); 178 public final FqName unsafeVariance = fqName("UnsafeVariance"); 179 180 public final FqName iterator = collectionsFqName("Iterator"); 181 public final FqName iterable = collectionsFqName("Iterable"); 182 public final FqName collection = collectionsFqName("Collection"); 183 public final FqName list = collectionsFqName("List"); 184 public final FqName listIterator = collectionsFqName("ListIterator"); 185 public final FqName set = collectionsFqName("Set"); 186 public final FqName map = collectionsFqName("Map"); 187 public final FqName mapEntry = map.child(Name.identifier("Entry")); 188 public final FqName mutableIterator = collectionsFqName("MutableIterator"); 189 public final FqName mutableIterable = collectionsFqName("MutableIterable"); 190 public final FqName mutableCollection = collectionsFqName("MutableCollection"); 191 public final FqName mutableList = collectionsFqName("MutableList"); 192 public final FqName mutableListIterator = collectionsFqName("MutableListIterator"); 193 public final FqName mutableSet = collectionsFqName("MutableSet"); 194 public final FqName mutableMap = collectionsFqName("MutableMap"); 195 public final FqName mutableMapEntry = mutableMap.child(Name.identifier("MutableEntry")); 196 197 private final FqNameUnsafe _collection = collection.toUnsafe(); 198 private final FqNameUnsafe _list = list.toUnsafe(); 199 private final FqNameUnsafe _set = set.toUnsafe(); 200 private final FqNameUnsafe _iterable = iterable.toUnsafe(); 201 202 public final FqNameUnsafe kClass = reflect("KClass"); 203 public final FqNameUnsafe kCallable = reflect("KCallable"); 204 public final ClassId kProperty = ClassId.topLevel(reflect("KProperty").toSafe()); 205 206 public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType; 207 public final Map<FqNameUnsafe, PrimitiveType> arrayClassFqNameToPrimitiveType; 208 { 209 fqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0); 210 arrayClassFqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0); 211 for (PrimitiveType primitiveType : PrimitiveType.values()) { 212 fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType); 213 arrayClassFqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getArrayTypeName().asString()), primitiveType); 214 } 215 } 216 217 @NotNull 218 private static FqNameUnsafe fqNameUnsafe(@NotNull String simpleName) { 219 return fqName(simpleName).toUnsafe(); 220 } 221 222 @NotNull 223 private static FqName fqName(@NotNull String simpleName) { 224 return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)); 225 } 226 227 @NotNull 228 private static FqName collectionsFqName(@NotNull String simpleName) { 229 return COLLECTIONS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)); 230 } 231 232 @NotNull 233 private static FqNameUnsafe reflect(@NotNull String simpleName) { 234 return ReflectionTypesKt.getKOTLIN_REFLECT_FQ_NAME().child(Name.identifier(simpleName)).toUnsafe(); 235 } 236 237 @NotNull 238 private static FqName annotationName(@NotNull String simpleName) { 239 return ANNOTATION_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)); 240 } 241 } 242 243 @NotNull 244 public ModuleDescriptorImpl getBuiltInsModule() { 245 return builtInsModule; 246 } 247 248 @NotNull 249 public Set<BuiltInsPackageFragment> getBuiltInsPackageFragments() { 250 return builtInsPackageFragments; 251 } 252 253 @NotNull 254 public PackageFragmentDescriptor getBuiltInsPackageFragment() { 255 return builtInsPackageFragment; 256 } 257 258 public boolean isBuiltInPackageFragment(@Nullable PackageFragmentDescriptor packageFragment) { 259 return packageFragment != null && packageFragment.getContainingDeclaration() == getBuiltInsModule(); 260 } 261 262 @NotNull 263 public MemberScope getBuiltInsPackageScope() { 264 return builtInsPackageFragment.getMemberScope(); 265 } 266 267 @NotNull 268 private ClassDescriptor getAnnotationClassByName(@NotNull Name simpleName) { 269 return getBuiltInClassByName(simpleName, annotationPackageFragment); 270 } 271 272 @NotNull 273 public ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName) { 274 return getBuiltInClassByName(simpleName, getBuiltInsPackageFragment()); 275 } 276 277 @NotNull 278 private static ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName, @NotNull PackageFragmentDescriptor packageFragment) { 279 ClassDescriptor classDescriptor = getBuiltInClassByNameNullable(simpleName, packageFragment); 280 assert classDescriptor != null : "Built-in class " + simpleName + " is not found"; 281 return classDescriptor; 282 } 283 284 @Nullable 285 public ClassDescriptor getBuiltInClassByNameNullable(@NotNull Name simpleName) { 286 return getBuiltInClassByNameNullable(simpleName, getBuiltInsPackageFragment()); 287 } 288 289 @Nullable 290 public ClassDescriptor getBuiltInClassByFqNameNullable(@NotNull FqName fqName) { 291 if (!fqName.isRoot()) { 292 FqName parent = fqName.parent(); 293 BuiltInsPackageFragment packageFragment = packageNameToPackageFragment.get(parent); 294 if (packageFragment != null) { 295 return getBuiltInClassByNameNullable(fqName.shortName(), packageFragment); 296 } 297 } 298 return null; 299 } 300 301 @Nullable 302 private static ClassDescriptor getBuiltInClassByNameNullable(@NotNull Name simpleName, @NotNull PackageFragmentDescriptor packageFragment) { 303 ClassifierDescriptor classifier = packageFragment.getMemberScope().getContributedClassifier( 304 simpleName, 305 NoLookupLocation.FROM_BUILTINS); 306 307 assert classifier == null || 308 classifier instanceof ClassDescriptor : "Must be a class descriptor " + simpleName + ", but was " + classifier; 309 return (ClassDescriptor) classifier; 310 } 311 312 @NotNull 313 private ClassDescriptor getBuiltInClassByName(@NotNull String simpleName) { 314 return getBuiltInClassByName(Name.identifier(simpleName)); 315 } 316 317 @NotNull 318 private static ClassDescriptor getBuiltInClassByName(@NotNull String simpleName, PackageFragmentDescriptor packageFragment) { 319 return getBuiltInClassByName(Name.identifier(simpleName), packageFragment); 320 } 321 322 @NotNull 323 public ClassDescriptor getAny() { 324 return getBuiltInClassByName("Any"); 325 } 326 327 @NotNull 328 public ClassDescriptor getNothing() { 329 return getBuiltInClassByName("Nothing"); 330 } 331 332 @NotNull 333 public ClassDescriptor getPrimitiveClassDescriptor(@NotNull PrimitiveType type) { 334 return getBuiltInClassByName(type.getTypeName().asString()); 335 } 336 337 @NotNull 338 public ClassDescriptor getByte() { 339 return getPrimitiveClassDescriptor(BYTE); 340 } 341 342 @NotNull 343 public ClassDescriptor getShort() { 344 return getPrimitiveClassDescriptor(SHORT); 345 } 346 347 @NotNull 348 public ClassDescriptor getInt() { 349 return getPrimitiveClassDescriptor(INT); 350 } 351 352 @NotNull 353 public ClassDescriptor getLong() { 354 return getPrimitiveClassDescriptor(LONG); 355 } 356 357 @NotNull 358 public ClassDescriptor getFloat() { 359 return getPrimitiveClassDescriptor(FLOAT); 360 } 361 362 @NotNull 363 public ClassDescriptor getDouble() { 364 return getPrimitiveClassDescriptor(DOUBLE); 365 } 366 367 @NotNull 368 public ClassDescriptor getChar() { 369 return getPrimitiveClassDescriptor(CHAR); 370 } 371 372 @NotNull 373 public ClassDescriptor getBoolean() { 374 return getPrimitiveClassDescriptor(BOOLEAN); 375 } 376 377 @NotNull 378 public Set<DeclarationDescriptor> getIntegralRanges() { 379 return SetsKt.<DeclarationDescriptor>setOf( 380 getBuiltInClassByName("CharRange", rangesPackageFragment), 381 getBuiltInClassByName("IntRange", rangesPackageFragment) 382 // TODO: contains in LongRange should be optimized too 383 ); 384 } 385 386 @NotNull 387 public ClassDescriptor getArray() { 388 return getBuiltInClassByName("Array"); 389 } 390 391 @NotNull 392 public ClassDescriptor getPrimitiveArrayClassDescriptor(@NotNull PrimitiveType type) { 393 return getBuiltInClassByName(type.getArrayTypeName().asString()); 394 } 395 396 @NotNull 397 public ClassDescriptor getNumber() { 398 return getBuiltInClassByName("Number"); 399 } 400 401 @NotNull 402 public ClassDescriptor getUnit() { 403 return getBuiltInClassByName("Unit"); 404 } 405 406 @NotNull 407 public static String getFunctionName(int parameterCount) { 408 return "Function" + parameterCount; 409 } 410 411 @NotNull 412 public ClassDescriptor getFunction(int parameterCount) { 413 return getBuiltInClassByName(getFunctionName(parameterCount)); 414 } 415 416 @NotNull 417 public ClassDescriptor getThrowable() { 418 return getBuiltInClassByName("Throwable"); 419 } 420 421 @NotNull 422 public ClassDescriptor getCloneable() { 423 return getBuiltInClassByName("Cloneable"); 424 } 425 426 @NotNull 427 public ClassDescriptor getDeprecatedAnnotation() { 428 return getBuiltInClassByName(FQ_NAMES.deprecated.shortName()); 429 } 430 431 @Nullable 432 private static ClassDescriptor getEnumEntry(@NotNull ClassDescriptor enumDescriptor, @NotNull String entryName) { 433 ClassifierDescriptor result = enumDescriptor.getUnsubstitutedInnerClassesScope().getContributedClassifier( 434 Name.identifier(entryName), NoLookupLocation.FROM_BUILTINS 435 ); 436 return result instanceof ClassDescriptor ? (ClassDescriptor) result : null; 437 } 438 439 @Nullable 440 public ClassDescriptor getDeprecationLevelEnumEntry(@NotNull String level) { 441 return getEnumEntry(getBuiltInClassByName(FQ_NAMES.deprecationLevel.shortName()), level); 442 } 443 444 @NotNull 445 public ClassDescriptor getTargetAnnotation() { 446 return getAnnotationClassByName(FQ_NAMES.target.shortName()); 447 } 448 449 @NotNull 450 public ClassDescriptor getRetentionAnnotation() { 451 return getAnnotationClassByName(FQ_NAMES.retention.shortName()); 452 } 453 454 @NotNull 455 public ClassDescriptor getRepeatableAnnotation() { 456 return getAnnotationClassByName(FQ_NAMES.repeatable.shortName()); 457 } 458 459 @NotNull 460 public ClassDescriptor getMustBeDocumentedAnnotation() { 461 return getAnnotationClassByName(FQ_NAMES.mustBeDocumented.shortName()); 462 } 463 464 @Nullable 465 public ClassDescriptor getAnnotationTargetEnumEntry(@NotNull KotlinTarget target) { 466 return getEnumEntry(getAnnotationClassByName(FQ_NAMES.annotationTarget.shortName()), target.name()); 467 } 468 469 @Nullable 470 public ClassDescriptor getAnnotationRetentionEnumEntry(@NotNull KotlinRetention retention) { 471 return getEnumEntry(getAnnotationClassByName(FQ_NAMES.annotationRetention.shortName()), retention.name()); 472 } 473 474 @NotNull 475 public ClassDescriptor getString() { 476 return getBuiltInClassByName("String"); 477 } 478 479 @NotNull 480 public ClassDescriptor getCharSequence() { 481 return getBuiltInClassByName("CharSequence"); 482 } 483 484 @NotNull 485 public ClassDescriptor getComparable() { 486 return getBuiltInClassByName("Comparable"); 487 } 488 489 @NotNull 490 public ClassDescriptor getEnum() { 491 return getBuiltInClassByName("Enum"); 492 } 493 494 @NotNull 495 public ClassDescriptor getAnnotation() { 496 return getBuiltInClassByName("Annotation"); 497 } 498 499 @NotNull 500 public ClassDescriptor getIterator() { 501 return getBuiltInClassByName("Iterator", collectionsPackageFragment); 502 } 503 504 @NotNull 505 public ClassDescriptor getIterable() { 506 return getBuiltInClassByName("Iterable", collectionsPackageFragment); 507 } 508 509 @NotNull 510 public ClassDescriptor getMutableIterable() { 511 return getBuiltInClassByName("MutableIterable", collectionsPackageFragment); 512 } 513 514 @NotNull 515 public ClassDescriptor getMutableIterator() { 516 return getBuiltInClassByName("MutableIterator", collectionsPackageFragment); 517 } 518 519 @NotNull 520 public ClassDescriptor getCollection() { 521 return getBuiltInClassByName("Collection", collectionsPackageFragment); 522 } 523 524 @NotNull 525 public ClassDescriptor getMutableCollection() { 526 return getBuiltInClassByName("MutableCollection", collectionsPackageFragment); 527 } 528 529 @NotNull 530 public ClassDescriptor getList() { 531 return getBuiltInClassByName("List", collectionsPackageFragment); 532 } 533 534 @NotNull 535 public ClassDescriptor getMutableList() { 536 return getBuiltInClassByName("MutableList", collectionsPackageFragment); 537 } 538 539 @NotNull 540 public ClassDescriptor getSet() { 541 return getBuiltInClassByName("Set", collectionsPackageFragment); 542 } 543 544 @NotNull 545 public ClassDescriptor getMutableSet() { 546 return getBuiltInClassByName("MutableSet", collectionsPackageFragment); 547 } 548 549 @NotNull 550 public ClassDescriptor getMap() { 551 return getBuiltInClassByName("Map", collectionsPackageFragment); 552 } 553 554 @NotNull 555 public ClassDescriptor getMutableMap() { 556 return getBuiltInClassByName("MutableMap", collectionsPackageFragment); 557 } 558 559 @NotNull 560 public ClassDescriptor getMapEntry() { 561 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMap(), "Entry", NoLookupLocation.FROM_BUILTINS); 562 assert classDescriptor != null : "Can't find Map.Entry"; 563 return classDescriptor; 564 } 565 566 @NotNull 567 public ClassDescriptor getMutableMapEntry() { 568 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMutableMap(), "MutableEntry", NoLookupLocation.FROM_BUILTINS); 569 assert classDescriptor != null : "Can't find MutableMap.MutableEntry"; 570 return classDescriptor; 571 } 572 573 @NotNull 574 public ClassDescriptor getListIterator() { 575 return getBuiltInClassByName("ListIterator", collectionsPackageFragment); 576 } 577 578 @NotNull 579 public ClassDescriptor getMutableListIterator() { 580 return getBuiltInClassByName("MutableListIterator", collectionsPackageFragment); 581 } 582 583 @NotNull 584 private KotlinType getBuiltInTypeByClassName(@NotNull String classSimpleName) { 585 return getBuiltInClassByName(classSimpleName).getDefaultType(); 586 } 587 588 @NotNull 589 public KotlinType getNothingType() { 590 return getNothing().getDefaultType(); 591 } 592 593 @NotNull 594 public KotlinType getNullableNothingType() { 595 return TypeUtils.makeNullable(getNothingType()); 596 } 597 598 @NotNull 599 public KotlinType getAnyType() { 600 return getAny().getDefaultType(); 601 } 602 603 @NotNull 604 public KotlinType getNullableAnyType() { 605 return TypeUtils.makeNullable(getAnyType()); 606 } 607 608 @NotNull 609 public KotlinType getDefaultBound() { 610 return getNullableAnyType(); 611 } 612 613 @NotNull 614 public KotlinType getPrimitiveKotlinType(@NotNull PrimitiveType type) { 615 return getPrimitiveClassDescriptor(type).getDefaultType(); 616 } 617 618 @NotNull 619 public KotlinType getByteType() { 620 return getPrimitiveKotlinType(BYTE); 621 } 622 623 @NotNull 624 public KotlinType getShortType() { 625 return getPrimitiveKotlinType(SHORT); 626 } 627 628 @NotNull 629 public KotlinType getIntType() { 630 return getPrimitiveKotlinType(INT); 631 } 632 633 @NotNull 634 public KotlinType getLongType() { 635 return getPrimitiveKotlinType(LONG); 636 } 637 638 @NotNull 639 public KotlinType getFloatType() { 640 return getPrimitiveKotlinType(FLOAT); 641 } 642 643 @NotNull 644 public KotlinType getDoubleType() { 645 return getPrimitiveKotlinType(DOUBLE); 646 } 647 648 @NotNull 649 public KotlinType getCharType() { 650 return getPrimitiveKotlinType(CHAR); 651 } 652 653 @NotNull 654 public KotlinType getBooleanType() { 655 return getPrimitiveKotlinType(BOOLEAN); 656 } 657 658 @NotNull 659 public KotlinType getUnitType() { 660 return getUnit().getDefaultType(); 661 } 662 663 @NotNull 664 public KotlinType getStringType() { 665 return getString().getDefaultType(); 666 } 667 668 @NotNull 669 public KotlinType getArrayElementType(@NotNull KotlinType arrayType) { 670 if (isArray(arrayType)) { 671 if (arrayType.getArguments().size() != 1) { 672 throw new IllegalStateException(); 673 } 674 return arrayType.getArguments().get(0).getType(); 675 } 676 KotlinType primitiveType = kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType)); 677 if (primitiveType == null) { 678 throw new IllegalStateException("not array: " + arrayType); 679 } 680 return primitiveType; 681 } 682 683 @NotNull 684 public KotlinType getPrimitiveArrayKotlinType(@NotNull PrimitiveType primitiveType) { 685 return primitiveTypeToArrayKotlinType.get(primitiveType); 686 } 687 688 /** 689 * @return {@code null} if not primitive 690 */ 691 @Nullable 692 public KotlinType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) { 693 return primitiveKotlinTypeToKotlinArrayType.get(kotlinType); 694 } 695 696 public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) { 697 return getPrimitiveTypeByArrayClassFqName(arrayFqName) != null; 698 } 699 700 @Nullable 701 public static PrimitiveType getPrimitiveTypeByFqName(@NotNull FqNameUnsafe primitiveClassFqName) { 702 return FQ_NAMES.fqNameToPrimitiveType.get(primitiveClassFqName); 703 } 704 705 @Nullable 706 public static PrimitiveType getPrimitiveTypeByArrayClassFqName(@NotNull FqNameUnsafe primitiveArrayClassFqName) { 707 return FQ_NAMES.arrayClassFqNameToPrimitiveType.get(primitiveArrayClassFqName); 708 } 709 710 @NotNull 711 public KotlinType getArrayType(@NotNull Variance projectionType, @NotNull KotlinType argument) { 712 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument)); 713 return KotlinTypeImpl.create( 714 Annotations.Companion.getEMPTY(), 715 getArray(), 716 false, 717 types 718 ); 719 } 720 721 @NotNull 722 public KotlinType getEnumType(@NotNull KotlinType argument) { 723 Variance projectionType = Variance.INVARIANT; 724 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument)); 725 return KotlinTypeImpl.create( 726 Annotations.Companion.getEMPTY(), 727 getEnum(), 728 false, 729 types 730 ); 731 } 732 733 @NotNull 734 public KotlinType getAnnotationType() { 735 return getAnnotation().getDefaultType(); 736 } 737 738 public static boolean isArray(@NotNull KotlinType type) { 739 return isConstructedFromGivenClass(type, FQ_NAMES.array); 740 } 741 742 public static boolean isArrayOrPrimitiveArray(@NotNull ClassDescriptor descriptor) { 743 return classFqNameEquals(descriptor, FQ_NAMES.array) || getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null; 744 } 745 746 public static boolean isPrimitiveArray(@NotNull KotlinType type) { 747 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 748 return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null; 749 } 750 751 public static boolean isPrimitiveType(@NotNull KotlinType type) { 752 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 753 return !type.isMarkedNullable() && descriptor instanceof ClassDescriptor && isPrimitiveClass((ClassDescriptor) descriptor); 754 } 755 756 public static boolean isPrimitiveClass(@NotNull ClassDescriptor descriptor) { 757 return getPrimitiveTypeByFqName(getFqName(descriptor)) != null; 758 } 759 760 private static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { 761 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 762 return descriptor instanceof ClassDescriptor && classFqNameEquals(descriptor, fqName); 763 } 764 765 private static boolean classFqNameEquals(@NotNull ClassifierDescriptor descriptor, @NotNull FqNameUnsafe fqName) { 766 // Quick check to avoid creation of full FqName instance 767 return descriptor.getName().equals(fqName.shortName()) && 768 fqName.equals(getFqName(descriptor)); 769 } 770 771 private static boolean isNotNullConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { 772 return !type.isMarkedNullable() && isConstructedFromGivenClass(type, fqName); 773 } 774 775 public static boolean isSpecialClassWithNoSupertypes(@NotNull ClassDescriptor descriptor) { 776 return classFqNameEquals(descriptor, FQ_NAMES.any) || classFqNameEquals(descriptor, FQ_NAMES.nothing); 777 } 778 779 public static boolean isAny(@NotNull ClassDescriptor descriptor) { 780 return classFqNameEquals(descriptor, FQ_NAMES.any); 781 } 782 783 public static boolean isAny(@NotNull KotlinType type) { 784 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES.any); 785 } 786 787 public static boolean isBoolean(@NotNull KotlinType type) { 788 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._boolean); 789 } 790 791 public static boolean isBooleanOrNullableBoolean(@NotNull KotlinType type) { 792 return isConstructedFromGivenClass(type, FQ_NAMES._boolean); 793 } 794 795 public static boolean isBoolean(@NotNull ClassDescriptor classDescriptor) { 796 return classFqNameEquals(classDescriptor, FQ_NAMES._boolean); 797 } 798 799 public static boolean isChar(@NotNull KotlinType type) { 800 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._char); 801 } 802 803 public static boolean isInt(@NotNull KotlinType type) { 804 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._int); 805 } 806 807 public static boolean isByte(@NotNull KotlinType type) { 808 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._byte); 809 } 810 811 public static boolean isLong(@NotNull KotlinType type) { 812 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._long); 813 } 814 815 public static boolean isShort(@NotNull KotlinType type) { 816 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._short); 817 } 818 819 public static boolean isFloat(@NotNull KotlinType type) { 820 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._float); 821 } 822 823 public static boolean isDouble(@NotNull KotlinType type) { 824 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._double); 825 } 826 827 private static boolean isConstructedFromGivenClassAndNotNullable(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { 828 return isConstructedFromGivenClass(type, fqName) && !type.isMarkedNullable(); 829 } 830 831 public static boolean isNothing(@NotNull KotlinType type) { 832 return isNothingOrNullableNothing(type) 833 && !type.isMarkedNullable(); 834 } 835 836 public static boolean isNullableNothing(@NotNull KotlinType type) { 837 return isNothingOrNullableNothing(type) 838 && type.isMarkedNullable(); 839 } 840 841 public static boolean isNothingOrNullableNothing(@NotNull KotlinType type) { 842 return isConstructedFromGivenClass(type, FQ_NAMES.nothing); 843 } 844 845 public static boolean isAnyOrNullableAny(@NotNull KotlinType type) { 846 return isConstructedFromGivenClass(type, FQ_NAMES.any); 847 } 848 849 public static boolean isNullableAny(@NotNull KotlinType type) { 850 return isAnyOrNullableAny(type) && type.isMarkedNullable(); 851 } 852 853 public static boolean isDefaultBound(@NotNull KotlinType type) { 854 return isNullableAny(type); 855 } 856 857 public static boolean isUnit(@NotNull KotlinType type) { 858 return isNotNullConstructedFromGivenClass(type, FQ_NAMES.unit); 859 } 860 861 public static boolean isUnitOrNullableUnit(@NotNull KotlinType type) { 862 return isConstructedFromGivenClass(type, FQ_NAMES.unit); 863 } 864 865 public boolean isBooleanOrSubtype(@NotNull KotlinType type) { 866 return KotlinTypeChecker.DEFAULT.isSubtypeOf(type, getBooleanType()); 867 } 868 869 public boolean isMemberOfAny(@NotNull DeclarationDescriptor descriptor) { 870 return descriptor.getContainingDeclaration() == getAny(); 871 } 872 873 public static boolean isString(@Nullable KotlinType type) { 874 return type != null && isNotNullConstructedFromGivenClass(type, FQ_NAMES.string); 875 } 876 877 public static boolean isCollectionOrNullableCollection(@NotNull KotlinType type) { 878 return isConstructedFromGivenClass(type, FQ_NAMES._collection); 879 } 880 881 public static boolean isListOrNullableList(@NotNull KotlinType type) { 882 return isConstructedFromGivenClass(type, FQ_NAMES._list); 883 } 884 885 public static boolean isSetOrNullableSet(@NotNull KotlinType type) { 886 return isConstructedFromGivenClass(type, FQ_NAMES._set); 887 } 888 889 public static boolean isIterableOrNullableIterable(@NotNull KotlinType type) { 890 return isConstructedFromGivenClass(type, FQ_NAMES._iterable); 891 } 892 893 public static boolean isKClass(@NotNull ClassDescriptor descriptor) { 894 return classFqNameEquals(descriptor, FQ_NAMES.kClass); 895 } 896 897 public static boolean isNonPrimitiveArray(@NotNull ClassDescriptor descriptor) { 898 return classFqNameEquals(descriptor, FQ_NAMES.array); 899 } 900 901 public static boolean isCloneable(@NotNull ClassDescriptor descriptor) { 902 return classFqNameEquals(descriptor, FQ_NAMES.cloneable); 903 } 904 905 public static boolean isDeprecated(@NotNull DeclarationDescriptor declarationDescriptor) { 906 if (containsAnnotation(declarationDescriptor, FQ_NAMES.deprecated)) return true; 907 908 if (declarationDescriptor instanceof PropertyDescriptor) { 909 boolean isVar = ((PropertyDescriptor) declarationDescriptor).isVar(); 910 PropertyGetterDescriptor getter = ((PropertyDescriptor) declarationDescriptor).getGetter(); 911 PropertySetterDescriptor setter = ((PropertyDescriptor) declarationDescriptor).getSetter(); 912 return getter != null && isDeprecated(getter) && (!isVar || setter != null && isDeprecated(setter)); 913 } 914 915 return false; 916 } 917 918 public static boolean isSuppressAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) { 919 return isConstructedFromGivenClass(annotationDescriptor.getType(), FQ_NAMES.suppress); 920 } 921 922 private static boolean containsAnnotation(DeclarationDescriptor descriptor, FqName annotationClassFqName) { 923 DeclarationDescriptor original = descriptor.getOriginal(); 924 Annotations annotations = original.getAnnotations(); 925 926 if (annotations.findAnnotation(annotationClassFqName) != null) return true; 927 928 AnnotationUseSiteTarget associatedUseSiteTarget = AnnotationUseSiteTarget.Companion.getAssociatedUseSiteTarget(descriptor); 929 if (associatedUseSiteTarget != null) { 930 if (Annotations.Companion.findUseSiteTargetedAnnotation(annotations, associatedUseSiteTarget, annotationClassFqName) != null) { 931 return true; 932 } 933 } 934 935 return false; 936 } 937 }