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