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