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