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