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 FqNameUnsafe kMutableProperty0 = reflect("KMutableProperty0"); 205 public final FqNameUnsafe kMutableProperty1 = reflect("KMutableProperty1"); 206 public final FqNameUnsafe kMutableProperty2 = reflect("KMutableProperty2"); 207 public final ClassId kProperty = ClassId.topLevel(reflect("KProperty").toSafe()); 208 209 public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType; 210 public final Map<FqNameUnsafe, PrimitiveType> arrayClassFqNameToPrimitiveType; 211 { 212 fqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0); 213 arrayClassFqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0); 214 for (PrimitiveType primitiveType : PrimitiveType.values()) { 215 fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType); 216 arrayClassFqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getArrayTypeName().asString()), primitiveType); 217 } 218 } 219 220 @NotNull 221 private static FqNameUnsafe fqNameUnsafe(@NotNull String simpleName) { 222 return fqName(simpleName).toUnsafe(); 223 } 224 225 @NotNull 226 private static FqName fqName(@NotNull String simpleName) { 227 return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)); 228 } 229 230 @NotNull 231 private static FqName collectionsFqName(@NotNull String simpleName) { 232 return COLLECTIONS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)); 233 } 234 235 @NotNull 236 private static FqNameUnsafe reflect(@NotNull String simpleName) { 237 return ReflectionTypesKt.getKOTLIN_REFLECT_FQ_NAME().child(Name.identifier(simpleName)).toUnsafe(); 238 } 239 240 @NotNull 241 private static FqName annotationName(@NotNull String simpleName) { 242 return ANNOTATION_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)); 243 } 244 } 245 246 @NotNull 247 public ModuleDescriptorImpl getBuiltInsModule() { 248 return builtInsModule; 249 } 250 251 @NotNull 252 public Set<BuiltInsPackageFragment> getBuiltInsPackageFragments() { 253 return builtInsPackageFragments; 254 } 255 256 @NotNull 257 public PackageFragmentDescriptor getBuiltInsPackageFragment() { 258 return builtInsPackageFragment; 259 } 260 261 public boolean isBuiltInPackageFragment(@Nullable PackageFragmentDescriptor packageFragment) { 262 return packageFragment != null && packageFragment.getContainingDeclaration() == getBuiltInsModule(); 263 } 264 265 @NotNull 266 public MemberScope getBuiltInsPackageScope() { 267 return builtInsPackageFragment.getMemberScope(); 268 } 269 270 @NotNull 271 private ClassDescriptor getAnnotationClassByName(@NotNull Name simpleName) { 272 return getBuiltInClassByName(simpleName, annotationPackageFragment); 273 } 274 275 @NotNull 276 public ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName) { 277 return getBuiltInClassByName(simpleName, getBuiltInsPackageFragment()); 278 } 279 280 @NotNull 281 private static ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName, @NotNull PackageFragmentDescriptor packageFragment) { 282 ClassDescriptor classDescriptor = getBuiltInClassByNameNullable(simpleName, packageFragment); 283 assert classDescriptor != null : "Built-in class " + simpleName + " is not found"; 284 return classDescriptor; 285 } 286 287 @Nullable 288 public ClassDescriptor getBuiltInClassByNameNullable(@NotNull Name simpleName) { 289 return getBuiltInClassByNameNullable(simpleName, getBuiltInsPackageFragment()); 290 } 291 292 @Nullable 293 public ClassDescriptor getBuiltInClassByFqNameNullable(@NotNull FqName fqName) { 294 if (!fqName.isRoot()) { 295 FqName parent = fqName.parent(); 296 BuiltInsPackageFragment packageFragment = packageNameToPackageFragment.get(parent); 297 if (packageFragment != null) { 298 return getBuiltInClassByNameNullable(fqName.shortName(), packageFragment); 299 } 300 } 301 return null; 302 } 303 304 @Nullable 305 private static ClassDescriptor getBuiltInClassByNameNullable(@NotNull Name simpleName, @NotNull PackageFragmentDescriptor packageFragment) { 306 ClassifierDescriptor classifier = packageFragment.getMemberScope().getContributedClassifier( 307 simpleName, 308 NoLookupLocation.FROM_BUILTINS); 309 310 assert classifier == null || 311 classifier instanceof ClassDescriptor : "Must be a class descriptor " + simpleName + ", but was " + classifier; 312 return (ClassDescriptor) classifier; 313 } 314 315 @NotNull 316 private ClassDescriptor getBuiltInClassByName(@NotNull String simpleName) { 317 return getBuiltInClassByName(Name.identifier(simpleName)); 318 } 319 320 @NotNull 321 private static ClassDescriptor getBuiltInClassByName(@NotNull String simpleName, PackageFragmentDescriptor packageFragment) { 322 return getBuiltInClassByName(Name.identifier(simpleName), packageFragment); 323 } 324 325 @NotNull 326 public ClassDescriptor getAny() { 327 return getBuiltInClassByName("Any"); 328 } 329 330 @NotNull 331 public ClassDescriptor getNothing() { 332 return getBuiltInClassByName("Nothing"); 333 } 334 335 @NotNull 336 public ClassDescriptor getPrimitiveClassDescriptor(@NotNull PrimitiveType type) { 337 return getBuiltInClassByName(type.getTypeName().asString()); 338 } 339 340 @NotNull 341 public ClassDescriptor getByte() { 342 return getPrimitiveClassDescriptor(BYTE); 343 } 344 345 @NotNull 346 public ClassDescriptor getShort() { 347 return getPrimitiveClassDescriptor(SHORT); 348 } 349 350 @NotNull 351 public ClassDescriptor getInt() { 352 return getPrimitiveClassDescriptor(INT); 353 } 354 355 @NotNull 356 public ClassDescriptor getLong() { 357 return getPrimitiveClassDescriptor(LONG); 358 } 359 360 @NotNull 361 public ClassDescriptor getFloat() { 362 return getPrimitiveClassDescriptor(FLOAT); 363 } 364 365 @NotNull 366 public ClassDescriptor getDouble() { 367 return getPrimitiveClassDescriptor(DOUBLE); 368 } 369 370 @NotNull 371 public ClassDescriptor getChar() { 372 return getPrimitiveClassDescriptor(CHAR); 373 } 374 375 @NotNull 376 public ClassDescriptor getBoolean() { 377 return getPrimitiveClassDescriptor(BOOLEAN); 378 } 379 380 @NotNull 381 public Set<DeclarationDescriptor> getIntegralRanges() { 382 return SetsKt.<DeclarationDescriptor>setOf( 383 getBuiltInClassByName("CharRange", rangesPackageFragment), 384 getBuiltInClassByName("IntRange", rangesPackageFragment) 385 // TODO: contains in LongRange should be optimized too 386 ); 387 } 388 389 @NotNull 390 public ClassDescriptor getArray() { 391 return getBuiltInClassByName("Array"); 392 } 393 394 @NotNull 395 public ClassDescriptor getPrimitiveArrayClassDescriptor(@NotNull PrimitiveType type) { 396 return getBuiltInClassByName(type.getArrayTypeName().asString()); 397 } 398 399 @NotNull 400 public ClassDescriptor getNumber() { 401 return getBuiltInClassByName("Number"); 402 } 403 404 @NotNull 405 public ClassDescriptor getUnit() { 406 return getBuiltInClassByName("Unit"); 407 } 408 409 @NotNull 410 public static String getFunctionName(int parameterCount) { 411 return "Function" + parameterCount; 412 } 413 414 @NotNull 415 public ClassDescriptor getFunction(int parameterCount) { 416 return getBuiltInClassByName(getFunctionName(parameterCount)); 417 } 418 419 @NotNull 420 public ClassDescriptor getThrowable() { 421 return getBuiltInClassByName("Throwable"); 422 } 423 424 @NotNull 425 public ClassDescriptor getCloneable() { 426 return getBuiltInClassByName("Cloneable"); 427 } 428 429 @NotNull 430 public ClassDescriptor getDeprecatedAnnotation() { 431 return getBuiltInClassByName(FQ_NAMES.deprecated.shortName()); 432 } 433 434 @Nullable 435 private static ClassDescriptor getEnumEntry(@NotNull ClassDescriptor enumDescriptor, @NotNull String entryName) { 436 ClassifierDescriptor result = enumDescriptor.getUnsubstitutedInnerClassesScope().getContributedClassifier( 437 Name.identifier(entryName), NoLookupLocation.FROM_BUILTINS 438 ); 439 return result instanceof ClassDescriptor ? (ClassDescriptor) result : null; 440 } 441 442 @Nullable 443 public ClassDescriptor getDeprecationLevelEnumEntry(@NotNull String level) { 444 return getEnumEntry(getBuiltInClassByName(FQ_NAMES.deprecationLevel.shortName()), level); 445 } 446 447 @NotNull 448 public ClassDescriptor getTargetAnnotation() { 449 return getAnnotationClassByName(FQ_NAMES.target.shortName()); 450 } 451 452 @NotNull 453 public ClassDescriptor getRetentionAnnotation() { 454 return getAnnotationClassByName(FQ_NAMES.retention.shortName()); 455 } 456 457 @NotNull 458 public ClassDescriptor getRepeatableAnnotation() { 459 return getAnnotationClassByName(FQ_NAMES.repeatable.shortName()); 460 } 461 462 @NotNull 463 public ClassDescriptor getMustBeDocumentedAnnotation() { 464 return getAnnotationClassByName(FQ_NAMES.mustBeDocumented.shortName()); 465 } 466 467 @Nullable 468 public ClassDescriptor getAnnotationTargetEnumEntry(@NotNull KotlinTarget target) { 469 return getEnumEntry(getAnnotationClassByName(FQ_NAMES.annotationTarget.shortName()), target.name()); 470 } 471 472 @Nullable 473 public ClassDescriptor getAnnotationRetentionEnumEntry(@NotNull KotlinRetention retention) { 474 return getEnumEntry(getAnnotationClassByName(FQ_NAMES.annotationRetention.shortName()), retention.name()); 475 } 476 477 @NotNull 478 public ClassDescriptor getString() { 479 return getBuiltInClassByName("String"); 480 } 481 482 @NotNull 483 public ClassDescriptor getCharSequence() { 484 return getBuiltInClassByName("CharSequence"); 485 } 486 487 @NotNull 488 public ClassDescriptor getComparable() { 489 return getBuiltInClassByName("Comparable"); 490 } 491 492 @NotNull 493 public ClassDescriptor getEnum() { 494 return getBuiltInClassByName("Enum"); 495 } 496 497 @NotNull 498 public ClassDescriptor getAnnotation() { 499 return getBuiltInClassByName("Annotation"); 500 } 501 502 @NotNull 503 public ClassDescriptor getIterator() { 504 return getBuiltInClassByName("Iterator", collectionsPackageFragment); 505 } 506 507 @NotNull 508 public ClassDescriptor getIterable() { 509 return getBuiltInClassByName("Iterable", collectionsPackageFragment); 510 } 511 512 @NotNull 513 public ClassDescriptor getMutableIterable() { 514 return getBuiltInClassByName("MutableIterable", collectionsPackageFragment); 515 } 516 517 @NotNull 518 public ClassDescriptor getMutableIterator() { 519 return getBuiltInClassByName("MutableIterator", collectionsPackageFragment); 520 } 521 522 @NotNull 523 public ClassDescriptor getCollection() { 524 return getBuiltInClassByName("Collection", collectionsPackageFragment); 525 } 526 527 @NotNull 528 public ClassDescriptor getMutableCollection() { 529 return getBuiltInClassByName("MutableCollection", collectionsPackageFragment); 530 } 531 532 @NotNull 533 public ClassDescriptor getList() { 534 return getBuiltInClassByName("List", collectionsPackageFragment); 535 } 536 537 @NotNull 538 public ClassDescriptor getMutableList() { 539 return getBuiltInClassByName("MutableList", collectionsPackageFragment); 540 } 541 542 @NotNull 543 public ClassDescriptor getSet() { 544 return getBuiltInClassByName("Set", collectionsPackageFragment); 545 } 546 547 @NotNull 548 public ClassDescriptor getMutableSet() { 549 return getBuiltInClassByName("MutableSet", collectionsPackageFragment); 550 } 551 552 @NotNull 553 public ClassDescriptor getMap() { 554 return getBuiltInClassByName("Map", collectionsPackageFragment); 555 } 556 557 @NotNull 558 public ClassDescriptor getMutableMap() { 559 return getBuiltInClassByName("MutableMap", collectionsPackageFragment); 560 } 561 562 @NotNull 563 public ClassDescriptor getMapEntry() { 564 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMap(), "Entry", NoLookupLocation.FROM_BUILTINS); 565 assert classDescriptor != null : "Can't find Map.Entry"; 566 return classDescriptor; 567 } 568 569 @NotNull 570 public ClassDescriptor getMutableMapEntry() { 571 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMutableMap(), "MutableEntry", NoLookupLocation.FROM_BUILTINS); 572 assert classDescriptor != null : "Can't find MutableMap.MutableEntry"; 573 return classDescriptor; 574 } 575 576 @NotNull 577 public ClassDescriptor getListIterator() { 578 return getBuiltInClassByName("ListIterator", collectionsPackageFragment); 579 } 580 581 @NotNull 582 public ClassDescriptor getMutableListIterator() { 583 return getBuiltInClassByName("MutableListIterator", collectionsPackageFragment); 584 } 585 586 @NotNull 587 private KotlinType getBuiltInTypeByClassName(@NotNull String classSimpleName) { 588 return getBuiltInClassByName(classSimpleName).getDefaultType(); 589 } 590 591 @NotNull 592 public KotlinType getNothingType() { 593 return getNothing().getDefaultType(); 594 } 595 596 @NotNull 597 public KotlinType getNullableNothingType() { 598 return TypeUtils.makeNullable(getNothingType()); 599 } 600 601 @NotNull 602 public KotlinType getAnyType() { 603 return getAny().getDefaultType(); 604 } 605 606 @NotNull 607 public KotlinType getNullableAnyType() { 608 return TypeUtils.makeNullable(getAnyType()); 609 } 610 611 @NotNull 612 public KotlinType getDefaultBound() { 613 return getNullableAnyType(); 614 } 615 616 @NotNull 617 public KotlinType getPrimitiveKotlinType(@NotNull PrimitiveType type) { 618 return getPrimitiveClassDescriptor(type).getDefaultType(); 619 } 620 621 @NotNull 622 public KotlinType getByteType() { 623 return getPrimitiveKotlinType(BYTE); 624 } 625 626 @NotNull 627 public KotlinType getShortType() { 628 return getPrimitiveKotlinType(SHORT); 629 } 630 631 @NotNull 632 public KotlinType getIntType() { 633 return getPrimitiveKotlinType(INT); 634 } 635 636 @NotNull 637 public KotlinType getLongType() { 638 return getPrimitiveKotlinType(LONG); 639 } 640 641 @NotNull 642 public KotlinType getFloatType() { 643 return getPrimitiveKotlinType(FLOAT); 644 } 645 646 @NotNull 647 public KotlinType getDoubleType() { 648 return getPrimitiveKotlinType(DOUBLE); 649 } 650 651 @NotNull 652 public KotlinType getCharType() { 653 return getPrimitiveKotlinType(CHAR); 654 } 655 656 @NotNull 657 public KotlinType getBooleanType() { 658 return getPrimitiveKotlinType(BOOLEAN); 659 } 660 661 @NotNull 662 public KotlinType getUnitType() { 663 return getUnit().getDefaultType(); 664 } 665 666 @NotNull 667 public KotlinType getStringType() { 668 return getString().getDefaultType(); 669 } 670 671 @NotNull 672 public KotlinType getArrayElementType(@NotNull KotlinType arrayType) { 673 if (isArray(arrayType)) { 674 if (arrayType.getArguments().size() != 1) { 675 throw new IllegalStateException(); 676 } 677 return arrayType.getArguments().get(0).getType(); 678 } 679 KotlinType primitiveType = kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType)); 680 if (primitiveType == null) { 681 throw new IllegalStateException("not array: " + arrayType); 682 } 683 return primitiveType; 684 } 685 686 @NotNull 687 public KotlinType getPrimitiveArrayKotlinType(@NotNull PrimitiveType primitiveType) { 688 return primitiveTypeToArrayKotlinType.get(primitiveType); 689 } 690 691 /** 692 * @return {@code null} if not primitive 693 */ 694 @Nullable 695 public KotlinType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) { 696 return primitiveKotlinTypeToKotlinArrayType.get(kotlinType); 697 } 698 699 public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) { 700 return getPrimitiveTypeByArrayClassFqName(arrayFqName) != null; 701 } 702 703 @Nullable 704 public static PrimitiveType getPrimitiveTypeByFqName(@NotNull FqNameUnsafe primitiveClassFqName) { 705 return FQ_NAMES.fqNameToPrimitiveType.get(primitiveClassFqName); 706 } 707 708 @Nullable 709 public static PrimitiveType getPrimitiveTypeByArrayClassFqName(@NotNull FqNameUnsafe primitiveArrayClassFqName) { 710 return FQ_NAMES.arrayClassFqNameToPrimitiveType.get(primitiveArrayClassFqName); 711 } 712 713 @NotNull 714 public KotlinType getArrayType(@NotNull Variance projectionType, @NotNull KotlinType argument) { 715 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument)); 716 return KotlinTypeImpl.create( 717 Annotations.Companion.getEMPTY(), 718 getArray(), 719 false, 720 types 721 ); 722 } 723 724 @NotNull 725 public KotlinType getEnumType(@NotNull KotlinType argument) { 726 Variance projectionType = Variance.INVARIANT; 727 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument)); 728 return KotlinTypeImpl.create( 729 Annotations.Companion.getEMPTY(), 730 getEnum(), 731 false, 732 types 733 ); 734 } 735 736 @NotNull 737 public KotlinType getAnnotationType() { 738 return getAnnotation().getDefaultType(); 739 } 740 741 public static boolean isArray(@NotNull KotlinType type) { 742 return isConstructedFromGivenClass(type, FQ_NAMES.array); 743 } 744 745 public static boolean isArrayOrPrimitiveArray(@NotNull ClassDescriptor descriptor) { 746 return classFqNameEquals(descriptor, FQ_NAMES.array) || getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null; 747 } 748 749 public static boolean isPrimitiveArray(@NotNull KotlinType type) { 750 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 751 return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null; 752 } 753 754 public static boolean isPrimitiveType(@NotNull KotlinType type) { 755 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 756 return !type.isMarkedNullable() && descriptor instanceof ClassDescriptor && isPrimitiveClass((ClassDescriptor) descriptor); 757 } 758 759 public static boolean isPrimitiveClass(@NotNull ClassDescriptor descriptor) { 760 return getPrimitiveTypeByFqName(getFqName(descriptor)) != null; 761 } 762 763 private static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { 764 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 765 return descriptor instanceof ClassDescriptor && classFqNameEquals(descriptor, fqName); 766 } 767 768 private static boolean classFqNameEquals(@NotNull ClassifierDescriptor descriptor, @NotNull FqNameUnsafe fqName) { 769 // Quick check to avoid creation of full FqName instance 770 return descriptor.getName().equals(fqName.shortName()) && 771 fqName.equals(getFqName(descriptor)); 772 } 773 774 private static boolean isNotNullConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { 775 return !type.isMarkedNullable() && isConstructedFromGivenClass(type, fqName); 776 } 777 778 public static boolean isSpecialClassWithNoSupertypes(@NotNull ClassDescriptor descriptor) { 779 return classFqNameEquals(descriptor, FQ_NAMES.any) || classFqNameEquals(descriptor, FQ_NAMES.nothing); 780 } 781 782 public static boolean isAny(@NotNull ClassDescriptor descriptor) { 783 return classFqNameEquals(descriptor, FQ_NAMES.any); 784 } 785 786 public static boolean isAny(@NotNull KotlinType type) { 787 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES.any); 788 } 789 790 public static boolean isBoolean(@NotNull KotlinType type) { 791 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._boolean); 792 } 793 794 public static boolean isBooleanOrNullableBoolean(@NotNull KotlinType type) { 795 return isConstructedFromGivenClass(type, FQ_NAMES._boolean); 796 } 797 798 public static boolean isBoolean(@NotNull ClassDescriptor classDescriptor) { 799 return classFqNameEquals(classDescriptor, FQ_NAMES._boolean); 800 } 801 802 public static boolean isChar(@NotNull KotlinType type) { 803 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._char); 804 } 805 806 public static boolean isInt(@NotNull KotlinType type) { 807 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._int); 808 } 809 810 public static boolean isByte(@NotNull KotlinType type) { 811 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._byte); 812 } 813 814 public static boolean isLong(@NotNull KotlinType type) { 815 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._long); 816 } 817 818 public static boolean isShort(@NotNull KotlinType type) { 819 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._short); 820 } 821 822 public static boolean isFloat(@NotNull KotlinType type) { 823 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._float); 824 } 825 826 public static boolean isDouble(@NotNull KotlinType type) { 827 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._double); 828 } 829 830 private static boolean isConstructedFromGivenClassAndNotNullable(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { 831 return isConstructedFromGivenClass(type, fqName) && !type.isMarkedNullable(); 832 } 833 834 public static boolean isNothing(@NotNull KotlinType type) { 835 return isNothingOrNullableNothing(type) 836 && !type.isMarkedNullable(); 837 } 838 839 public static boolean isNullableNothing(@NotNull KotlinType type) { 840 return isNothingOrNullableNothing(type) 841 && type.isMarkedNullable(); 842 } 843 844 public static boolean isNothingOrNullableNothing(@NotNull KotlinType type) { 845 return isConstructedFromGivenClass(type, FQ_NAMES.nothing); 846 } 847 848 public static boolean isAnyOrNullableAny(@NotNull KotlinType type) { 849 return isConstructedFromGivenClass(type, FQ_NAMES.any); 850 } 851 852 public static boolean isNullableAny(@NotNull KotlinType type) { 853 return isAnyOrNullableAny(type) && type.isMarkedNullable(); 854 } 855 856 public static boolean isDefaultBound(@NotNull KotlinType type) { 857 return isNullableAny(type); 858 } 859 860 public static boolean isUnit(@NotNull KotlinType type) { 861 return isNotNullConstructedFromGivenClass(type, FQ_NAMES.unit); 862 } 863 864 public static boolean isUnitOrNullableUnit(@NotNull KotlinType type) { 865 return isConstructedFromGivenClass(type, FQ_NAMES.unit); 866 } 867 868 public boolean isBooleanOrSubtype(@NotNull KotlinType type) { 869 return KotlinTypeChecker.DEFAULT.isSubtypeOf(type, getBooleanType()); 870 } 871 872 public boolean isMemberOfAny(@NotNull DeclarationDescriptor descriptor) { 873 return descriptor.getContainingDeclaration() == getAny(); 874 } 875 876 public static boolean isString(@Nullable KotlinType type) { 877 return type != null && isNotNullConstructedFromGivenClass(type, FQ_NAMES.string); 878 } 879 880 public static boolean isCharSequenceOrNullableCharSequence(@Nullable KotlinType type) { 881 return type != null && isConstructedFromGivenClass(type, FQ_NAMES.charSequence); 882 } 883 884 public static boolean isStringOrNullableString(@Nullable KotlinType type) { 885 return type != null && isConstructedFromGivenClass(type, FQ_NAMES.string); 886 } 887 888 public static boolean isCollectionOrNullableCollection(@NotNull KotlinType type) { 889 return isConstructedFromGivenClass(type, FQ_NAMES._collection); 890 } 891 892 public static boolean isListOrNullableList(@NotNull KotlinType type) { 893 return isConstructedFromGivenClass(type, FQ_NAMES._list); 894 } 895 896 public static boolean isSetOrNullableSet(@NotNull KotlinType type) { 897 return isConstructedFromGivenClass(type, FQ_NAMES._set); 898 } 899 900 public static boolean isIterableOrNullableIterable(@NotNull KotlinType type) { 901 return isConstructedFromGivenClass(type, FQ_NAMES._iterable); 902 } 903 904 public static boolean isKClass(@NotNull ClassDescriptor descriptor) { 905 return classFqNameEquals(descriptor, FQ_NAMES.kClass); 906 } 907 908 public static boolean isNonPrimitiveArray(@NotNull ClassDescriptor descriptor) { 909 return classFqNameEquals(descriptor, FQ_NAMES.array); 910 } 911 912 public static boolean isCloneable(@NotNull ClassDescriptor descriptor) { 913 return classFqNameEquals(descriptor, FQ_NAMES.cloneable); 914 } 915 916 public static boolean isDeprecated(@NotNull DeclarationDescriptor declarationDescriptor) { 917 if (containsAnnotation(declarationDescriptor, FQ_NAMES.deprecated)) return true; 918 919 if (declarationDescriptor instanceof PropertyDescriptor) { 920 boolean isVar = ((PropertyDescriptor) declarationDescriptor).isVar(); 921 PropertyGetterDescriptor getter = ((PropertyDescriptor) declarationDescriptor).getGetter(); 922 PropertySetterDescriptor setter = ((PropertyDescriptor) declarationDescriptor).getSetter(); 923 return getter != null && isDeprecated(getter) && (!isVar || setter != null && isDeprecated(setter)); 924 } 925 926 return false; 927 } 928 929 public static boolean isSuppressAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) { 930 return isConstructedFromGivenClass(annotationDescriptor.getType(), FQ_NAMES.suppress); 931 } 932 933 private static boolean containsAnnotation(DeclarationDescriptor descriptor, FqName annotationClassFqName) { 934 DeclarationDescriptor original = descriptor.getOriginal(); 935 Annotations annotations = original.getAnnotations(); 936 937 if (annotations.findAnnotation(annotationClassFqName) != null) return true; 938 939 AnnotationUseSiteTarget associatedUseSiteTarget = AnnotationUseSiteTarget.Companion.getAssociatedUseSiteTarget(descriptor); 940 if (associatedUseSiteTarget != null) { 941 if (Annotations.Companion.findUseSiteTargetedAnnotation(annotations, associatedUseSiteTarget, annotationClassFqName) != null) { 942 return true; 943 } 944 } 945 946 return false; 947 } 948 }