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