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.Function1; 020 import kotlin.KotlinPackage; 021 import org.jetbrains.annotations.NotNull; 022 import org.jetbrains.annotations.Nullable; 023 import org.jetbrains.kotlin.descriptors.*; 024 import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; 025 import org.jetbrains.kotlin.descriptors.annotations.Annotations; 026 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; 027 import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl; 028 import org.jetbrains.kotlin.name.FqName; 029 import org.jetbrains.kotlin.name.FqNameUnsafe; 030 import org.jetbrains.kotlin.name.Name; 031 import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap; 032 import org.jetbrains.kotlin.resolve.DescriptorUtils; 033 import org.jetbrains.kotlin.resolve.ImportPath; 034 import org.jetbrains.kotlin.resolve.scopes.JetScope; 035 import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeCapabilitiesDeserializer; 036 import org.jetbrains.kotlin.storage.LockBasedStorageManager; 037 import org.jetbrains.kotlin.types.*; 038 import org.jetbrains.kotlin.types.checker.JetTypeChecker; 039 040 import java.io.InputStream; 041 import java.util.*; 042 043 import static kotlin.KotlinPackage.single; 044 import static org.jetbrains.kotlin.builtins.PrimitiveType.*; 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 050 public static final int FUNCTION_TRAIT_COUNT = 23; 051 052 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 053 054 private static volatile KotlinBuiltIns instance = null; 055 056 private static volatile boolean initializing; 057 private static Throwable initializationFailed; 058 059 private static synchronized void initialize() { 060 if (instance == null) { 061 if (initializationFailed != null) { 062 throw new IllegalStateException( 063 "Built-in library initialization failed previously: " + initializationFailed, initializationFailed 064 ); 065 } 066 if (initializing) { 067 throw new IllegalStateException("Built-in library initialization loop"); 068 } 069 initializing = true; 070 try { 071 instance = new KotlinBuiltIns(); 072 instance.doInitialize(); 073 } 074 catch (Throwable e) { 075 initializationFailed = e; 076 throw new IllegalStateException("Built-in library initialization failed. " + 077 "Please ensure you have kotlin-runtime.jar in the classpath: " + e, e); 078 } 079 finally { 080 initializing = false; 081 } 082 } 083 } 084 085 @NotNull 086 public static KotlinBuiltIns getInstance() { 087 if (initializing) { 088 synchronized (KotlinBuiltIns.class) { 089 assert instance != null : "Built-ins are not initialized (note: We are under the same lock as initializing and instance)"; 090 return instance; 091 } 092 } 093 if (instance == null) { 094 initialize(); 095 } 096 return instance; 097 } 098 099 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 100 101 private final ModuleDescriptorImpl builtInsModule; 102 private final BuiltinsPackageFragment builtinsPackageFragment; 103 104 private final Map<PrimitiveType, JetType> primitiveTypeToNullableJetType; 105 private final Map<PrimitiveType, JetType> primitiveTypeToArrayJetType; 106 private final Map<JetType, JetType> primitiveJetTypeToJetArrayType; 107 private final Map<JetType, JetType> jetArrayTypeToPrimitiveJetType; 108 109 public static final FqNames FQ_NAMES = new FqNames(); 110 111 private KotlinBuiltIns() { 112 builtInsModule = new ModuleDescriptorImpl( 113 Name.special("<built-ins module>"), Collections.<ImportPath>emptyList(), PlatformToKotlinClassMap.EMPTY 114 ); 115 116 PackageFragmentProvider packageFragmentProvider = BuiltinsPackage.createBuiltInPackageFragmentProvider( 117 new LockBasedStorageManager(), builtInsModule, Collections.singleton(BUILT_INS_PACKAGE_FQ_NAME), 118 FlexibleTypeCapabilitiesDeserializer.ThrowException.INSTANCE$, new Function1<String, InputStream>() { 119 @Override 120 public InputStream invoke(String path) { 121 return KotlinBuiltIns.class.getClassLoader().getResourceAsStream(path); 122 } 123 } 124 ); 125 126 builtInsModule.initialize(packageFragmentProvider); 127 builtInsModule.addDependencyOnModule(builtInsModule); 128 builtInsModule.seal(); 129 130 builtinsPackageFragment = (BuiltinsPackageFragment) single(packageFragmentProvider.getPackageFragments(BUILT_INS_PACKAGE_FQ_NAME)); 131 132 primitiveTypeToNullableJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class); 133 primitiveTypeToArrayJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class); 134 primitiveJetTypeToJetArrayType = new HashMap<JetType, JetType>(); 135 jetArrayTypeToPrimitiveJetType = new HashMap<JetType, JetType>(); 136 } 137 138 private void doInitialize() { 139 for (PrimitiveType primitive : PrimitiveType.values()) { 140 makePrimitive(primitive); 141 } 142 } 143 144 private void makePrimitive(@NotNull PrimitiveType primitiveType) { 145 JetType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString()); 146 JetType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString()); 147 148 primitiveTypeToNullableJetType.put(primitiveType, TypeUtils.makeNullable(type)); 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 FqName data = fqName("data"); 164 public final FqName deprecated = fqName("deprecated"); 165 public final FqName tailRecursive = fqName("tailRecursive"); 166 public final FqName noinline = fqName("noinline"); 167 168 public final Set<FqNameUnsafe> primitiveTypes; 169 public final Set<FqNameUnsafe> primitiveArrays; 170 { 171 primitiveTypes = new HashSet<FqNameUnsafe>(0); 172 primitiveArrays = new HashSet<FqNameUnsafe>(0); 173 for (PrimitiveType primitiveType : PrimitiveType.values()) { 174 primitiveTypes.add(fqNameUnsafe(primitiveType.getTypeName().asString())); 175 primitiveArrays.add(fqNameUnsafe(primitiveType.getArrayTypeName().asString())); 176 } 177 } 178 179 public final Set<FqNameUnsafe> functionClasses = computeIndexedFqNames("Function", FUNCTION_TRAIT_COUNT); 180 public final Set<FqNameUnsafe> extensionFunctionClasses = computeIndexedFqNames("ExtensionFunction", FUNCTION_TRAIT_COUNT); 181 182 @NotNull 183 private static FqNameUnsafe fqNameUnsafe(@NotNull String simpleName) { 184 return fqName(simpleName).toUnsafe(); 185 } 186 187 private static FqName fqName(String simpleName) { 188 return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName)); 189 } 190 191 @NotNull 192 private static Set<FqNameUnsafe> computeIndexedFqNames(@NotNull String prefix, int count) { 193 Set<FqNameUnsafe> result = new HashSet<FqNameUnsafe>(); 194 for (int i = 0; i < count; i++) { 195 result.add(fqNameUnsafe(prefix + i)); 196 } 197 return result; 198 } 199 } 200 201 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 202 203 @NotNull 204 public ModuleDescriptorImpl getBuiltInsModule() { 205 return builtInsModule; 206 } 207 208 @NotNull 209 public PackageFragmentDescriptor getBuiltInsPackageFragment() { 210 return builtinsPackageFragment; 211 } 212 213 @NotNull 214 public JetScope getBuiltInsPackageScope() { 215 return builtinsPackageFragment.getMemberScope(); 216 } 217 218 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 219 220 // GET CLASS 221 222 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 223 224 @NotNull 225 public ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName) { 226 ClassifierDescriptor classifier = getBuiltInsPackageFragment().getMemberScope().getClassifier(simpleName); 227 assert classifier instanceof ClassDescriptor : "Must be a class descriptor " + simpleName + ", but was " + classifier; 228 return (ClassDescriptor) classifier; 229 } 230 231 @NotNull 232 private ClassDescriptor getBuiltInClassByName(@NotNull String simpleName) { 233 return getBuiltInClassByName(Name.identifier(simpleName)); 234 } 235 236 // Special 237 238 @NotNull 239 public ClassDescriptor getAny() { 240 return getBuiltInClassByName("Any"); 241 } 242 243 @NotNull 244 public ClassDescriptor getNothing() { 245 return getBuiltInClassByName("Nothing"); 246 } 247 248 // Primitive 249 250 @NotNull 251 public ClassDescriptor getPrimitiveClassDescriptor(@NotNull PrimitiveType type) { 252 return getBuiltInClassByName(type.getTypeName().asString()); 253 } 254 255 @NotNull 256 public ClassDescriptor getByte() { 257 return getPrimitiveClassDescriptor(BYTE); 258 } 259 260 @NotNull 261 public ClassDescriptor getShort() { 262 return getPrimitiveClassDescriptor(SHORT); 263 } 264 265 @NotNull 266 public ClassDescriptor getInt() { 267 return getPrimitiveClassDescriptor(INT); 268 } 269 270 @NotNull 271 public ClassDescriptor getLong() { 272 return getPrimitiveClassDescriptor(LONG); 273 } 274 275 @NotNull 276 public ClassDescriptor getFloat() { 277 return getPrimitiveClassDescriptor(FLOAT); 278 } 279 280 @NotNull 281 public ClassDescriptor getDouble() { 282 return getPrimitiveClassDescriptor(DOUBLE); 283 } 284 285 @NotNull 286 public ClassDescriptor getChar() { 287 return getPrimitiveClassDescriptor(CHAR); 288 } 289 290 @NotNull 291 public ClassDescriptor getBoolean() { 292 return getPrimitiveClassDescriptor(BOOLEAN); 293 } 294 295 // Recognized 296 297 @NotNull 298 public Set<DeclarationDescriptor> getIntegralRanges() { 299 return KotlinPackage.<DeclarationDescriptor>setOf( 300 getBuiltInClassByName("ByteRange"), 301 getBuiltInClassByName("ShortRange"), 302 getBuiltInClassByName("CharRange"), 303 getBuiltInClassByName("IntRange") 304 ); 305 } 306 307 @NotNull 308 public ClassDescriptor getArray() { 309 return getBuiltInClassByName("Array"); 310 } 311 312 @NotNull 313 public ClassDescriptor getPrimitiveArrayClassDescriptor(@NotNull PrimitiveType type) { 314 return getBuiltInClassByName(type.getArrayTypeName().asString()); 315 } 316 317 @NotNull 318 public ClassDescriptor getNumber() { 319 return getBuiltInClassByName("Number"); 320 } 321 322 @NotNull 323 public ClassDescriptor getUnit() { 324 return getBuiltInClassByName("Unit"); 325 } 326 327 @NotNull 328 public ClassDescriptor getFunction(int parameterCount) { 329 return getBuiltInClassByName("Function" + parameterCount); 330 } 331 332 @NotNull 333 public ClassDescriptor getExtensionFunction(int parameterCount) { 334 return getBuiltInClassByName("ExtensionFunction" + parameterCount); 335 } 336 337 @NotNull 338 public ClassDescriptor getThrowable() { 339 return getBuiltInClassByName("Throwable"); 340 } 341 342 @NotNull 343 public ClassDescriptor getCloneable() { 344 return getBuiltInClassByName("Cloneable"); 345 } 346 347 @NotNull 348 public ClassDescriptor getDataClassAnnotation() { 349 return getBuiltInClassByName("data"); 350 } 351 352 @NotNull 353 public static FqName getNoinlineClassAnnotationFqName() { 354 return FQ_NAMES.noinline; 355 } 356 357 @NotNull 358 public ClassDescriptor getInlineClassAnnotation() { 359 return getBuiltInClassByName("inline"); 360 } 361 362 @NotNull 363 public ClassDescriptor getInlineOptionsClassAnnotation() { 364 return getBuiltInClassByName("inlineOptions"); 365 } 366 367 @NotNull 368 public ClassDescriptor getDeprecatedAnnotation() { 369 return getBuiltInClassByName("deprecated"); 370 } 371 372 @NotNull 373 public ClassDescriptor getString() { 374 return getBuiltInClassByName("String"); 375 } 376 377 @NotNull 378 public ClassDescriptor getCharSequence() { 379 return getBuiltInClassByName("CharSequence"); 380 } 381 382 @NotNull 383 public ClassDescriptor getComparable() { 384 return getBuiltInClassByName("Comparable"); 385 } 386 387 @NotNull 388 public ClassDescriptor getEnum() { 389 return getBuiltInClassByName("Enum"); 390 } 391 392 @NotNull 393 public ClassDescriptor getAnnotation() { 394 return getBuiltInClassByName("Annotation"); 395 } 396 397 @NotNull 398 public ClassDescriptor getIterator() { 399 return getBuiltInClassByName("Iterator"); 400 } 401 402 @NotNull 403 public ClassDescriptor getIterable() { 404 return getBuiltInClassByName("Iterable"); 405 } 406 407 @NotNull 408 public ClassDescriptor getMutableIterable() { 409 return getBuiltInClassByName("MutableIterable"); 410 } 411 412 @NotNull 413 public ClassDescriptor getMutableIterator() { 414 return getBuiltInClassByName("MutableIterator"); 415 } 416 417 @NotNull 418 public ClassDescriptor getCollection() { 419 return getBuiltInClassByName("Collection"); 420 } 421 422 @NotNull 423 public ClassDescriptor getMutableCollection() { 424 return getBuiltInClassByName("MutableCollection"); 425 } 426 427 @NotNull 428 public ClassDescriptor getList() { 429 return getBuiltInClassByName("List"); 430 } 431 432 @NotNull 433 public ClassDescriptor getMutableList() { 434 return getBuiltInClassByName("MutableList"); 435 } 436 437 @NotNull 438 public ClassDescriptor getSet() { 439 return getBuiltInClassByName("Set"); 440 } 441 442 @NotNull 443 public ClassDescriptor getMutableSet() { 444 return getBuiltInClassByName("MutableSet"); 445 } 446 447 @NotNull 448 public ClassDescriptor getMap() { 449 return getBuiltInClassByName("Map"); 450 } 451 452 @NotNull 453 public ClassDescriptor getMutableMap() { 454 return getBuiltInClassByName("MutableMap"); 455 } 456 457 @NotNull 458 public ClassDescriptor getMapEntry() { 459 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMap(), "Entry"); 460 assert classDescriptor != null : "Can't find Map.Entry"; 461 return classDescriptor; 462 } 463 464 @NotNull 465 public ClassDescriptor getMutableMapEntry() { 466 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMutableMap(), "MutableEntry"); 467 assert classDescriptor != null : "Can't find MutableMap.MutableEntry"; 468 return classDescriptor; 469 } 470 471 @NotNull 472 public ClassDescriptor getListIterator() { 473 return getBuiltInClassByName("ListIterator"); 474 } 475 476 @NotNull 477 public ClassDescriptor getMutableListIterator() { 478 return getBuiltInClassByName("MutableListIterator"); 479 } 480 481 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 482 483 // GET TYPE 484 485 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 486 487 @NotNull 488 private JetType getBuiltInTypeByClassName(@NotNull String classSimpleName) { 489 return getBuiltInClassByName(classSimpleName).getDefaultType(); 490 } 491 492 // Special 493 494 @NotNull 495 public JetType getNothingType() { 496 return getNothing().getDefaultType(); 497 } 498 499 @NotNull 500 public JetType getNullableNothingType() { 501 return TypeUtils.makeNullable(getNothingType()); 502 } 503 504 @NotNull 505 public JetType getAnyType() { 506 return getAny().getDefaultType(); 507 } 508 509 @NotNull 510 public JetType getNullableAnyType() { 511 return TypeUtils.makeNullable(getAnyType()); 512 } 513 514 // Primitive 515 516 @NotNull 517 public JetType getPrimitiveJetType(@NotNull PrimitiveType type) { 518 return getPrimitiveClassDescriptor(type).getDefaultType(); 519 } 520 521 @NotNull 522 public JetType getNullablePrimitiveJetType(@NotNull PrimitiveType primitiveType) { 523 return primitiveTypeToNullableJetType.get(primitiveType); 524 } 525 526 @NotNull 527 public JetType getByteType() { 528 return getPrimitiveJetType(BYTE); 529 } 530 531 @NotNull 532 public JetType getShortType() { 533 return getPrimitiveJetType(SHORT); 534 } 535 536 @NotNull 537 public JetType getIntType() { 538 return getPrimitiveJetType(INT); 539 } 540 541 @NotNull 542 public JetType getLongType() { 543 return getPrimitiveJetType(LONG); 544 } 545 546 @NotNull 547 public JetType getFloatType() { 548 return getPrimitiveJetType(FLOAT); 549 } 550 551 @NotNull 552 public JetType getDoubleType() { 553 return getPrimitiveJetType(DOUBLE); 554 } 555 556 @NotNull 557 public JetType getCharType() { 558 return getPrimitiveJetType(CHAR); 559 } 560 561 @NotNull 562 public JetType getBooleanType() { 563 return getPrimitiveJetType(BOOLEAN); 564 } 565 566 // Recognized 567 568 @NotNull 569 public JetType getUnitType() { 570 return getUnit().getDefaultType(); 571 } 572 573 @NotNull 574 public JetType getStringType() { 575 return getString().getDefaultType(); 576 } 577 578 @NotNull 579 public JetType getArrayElementType(@NotNull JetType arrayType) { 580 if (isArray(arrayType)) { 581 if (arrayType.getArguments().size() != 1) { 582 throw new IllegalStateException(); 583 } 584 return arrayType.getArguments().get(0).getType(); 585 } 586 JetType primitiveType = jetArrayTypeToPrimitiveJetType.get(TypeUtils.makeNotNullable(arrayType)); 587 if (primitiveType == null) { 588 throw new IllegalStateException("not array: " + arrayType); 589 } 590 return primitiveType; 591 } 592 593 @NotNull 594 public JetType getPrimitiveArrayJetType(@NotNull PrimitiveType primitiveType) { 595 return primitiveTypeToArrayJetType.get(primitiveType); 596 } 597 598 /** 599 * @return <code>null</code> if not primitive 600 */ 601 @Nullable 602 public JetType getPrimitiveArrayJetTypeByPrimitiveJetType(@NotNull JetType jetType) { 603 return primitiveJetTypeToJetArrayType.get(jetType); 604 } 605 606 @NotNull 607 public JetType getArrayType(@NotNull Variance projectionType, @NotNull JetType argument) { 608 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument)); 609 return new JetTypeImpl( 610 Annotations.EMPTY, 611 getArray().getTypeConstructor(), 612 false, 613 types, 614 getArray().getMemberScope(types) 615 ); 616 } 617 618 @NotNull 619 public JetType getEnumType(@NotNull JetType argument) { 620 Variance projectionType = Variance.INVARIANT; 621 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument)); 622 return new JetTypeImpl( 623 Annotations.EMPTY, 624 getEnum().getTypeConstructor(), 625 false, 626 types, 627 getEnum().getMemberScope(types) 628 ); 629 } 630 631 @NotNull 632 public JetType getAnnotationType() { 633 return getAnnotation().getDefaultType(); 634 } 635 636 @NotNull 637 public ClassDescriptor getPropertyMetadata() { 638 return getBuiltInClassByName("PropertyMetadata"); 639 } 640 641 @NotNull 642 public ClassDescriptor getPropertyMetadataImpl() { 643 return getBuiltInClassByName("PropertyMetadataImpl"); 644 } 645 646 @NotNull 647 public JetType getFunctionType( 648 @NotNull Annotations annotations, 649 @Nullable JetType receiverType, 650 @NotNull List<JetType> parameterTypes, 651 @NotNull JetType returnType 652 ) { 653 List<TypeProjection> arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType); 654 int size = parameterTypes.size(); 655 ClassDescriptor classDescriptor = receiverType == null ? getFunction(size) : getExtensionFunction(size); 656 TypeConstructor constructor = classDescriptor.getTypeConstructor(); 657 658 return new JetTypeImpl(annotations, constructor, false, arguments, classDescriptor.getMemberScope(arguments)); 659 } 660 661 @NotNull 662 public static List<TypeProjection> getFunctionTypeArgumentProjections( 663 @Nullable JetType receiverType, 664 @NotNull List<JetType> parameterTypes, 665 @NotNull JetType returnType 666 ) { 667 List<TypeProjection> arguments = new ArrayList<TypeProjection>(); 668 if (receiverType != null) { 669 arguments.add(defaultProjection(receiverType)); 670 } 671 for (JetType parameterType : parameterTypes) { 672 arguments.add(defaultProjection(parameterType)); 673 } 674 arguments.add(defaultProjection(returnType)); 675 return arguments; 676 } 677 678 private static TypeProjection defaultProjection(JetType returnType) { 679 return new TypeProjectionImpl(Variance.INVARIANT, returnType); 680 } 681 682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 683 684 // IS TYPE 685 686 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 687 688 public static boolean isArray(@NotNull JetType type) { 689 return isConstructedFromGivenClass(type, FQ_NAMES.array); 690 } 691 692 public static boolean isPrimitiveArray(@NotNull JetType type) { 693 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 694 return descriptor != null && FQ_NAMES.primitiveArrays.contains(DescriptorUtils.getFqName(descriptor)); 695 } 696 697 public static boolean isPrimitiveType(@NotNull JetType type) { 698 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 699 return !type.isMarkedNullable() && descriptor != null && FQ_NAMES.primitiveTypes.contains(DescriptorUtils.getFqName(descriptor)); 700 } 701 702 // Functions 703 704 public static boolean isFunctionOrExtensionFunctionType(@NotNull JetType type) { 705 return isFunctionType(type) || isExtensionFunctionType(type); 706 } 707 708 public static boolean isFunctionType(@NotNull JetType type) { 709 if (isExactFunctionType(type)) return true; 710 711 for (JetType superType : type.getConstructor().getSupertypes()) { 712 if (isFunctionType(superType)) return true; 713 } 714 715 return false; 716 } 717 718 public static boolean isExtensionFunctionType(@NotNull JetType type) { 719 if (isExactExtensionFunctionType(type)) return true; 720 721 for (JetType superType : type.getConstructor().getSupertypes()) { 722 if (isExtensionFunctionType(superType)) return true; 723 } 724 725 return false; 726 } 727 728 public static boolean isExactFunctionOrExtensionFunctionType(@NotNull JetType type) { 729 return isExactFunctionType(type) || isExactExtensionFunctionType(type); 730 } 731 732 public static boolean isExactFunctionType(@NotNull JetType type) { 733 return isTypeConstructorFqNameInSet(type, FQ_NAMES.functionClasses); 734 } 735 736 public static boolean isExactExtensionFunctionType(@NotNull JetType type) { 737 return isTypeConstructorFqNameInSet(type, FQ_NAMES.extensionFunctionClasses); 738 } 739 740 public static boolean isExactFunctionType(@NotNull FqNameUnsafe fqName) { 741 return FQ_NAMES.functionClasses.contains(fqName); 742 } 743 744 public static boolean isExactExtensionFunctionType(@NotNull FqNameUnsafe fqName) { 745 return FQ_NAMES.extensionFunctionClasses.contains(fqName); 746 } 747 748 private static boolean isTypeConstructorFqNameInSet(@NotNull JetType type, @NotNull Set<FqNameUnsafe> classes) { 749 ClassifierDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); 750 751 if (declarationDescriptor == null) return false; 752 753 FqNameUnsafe fqName = DescriptorUtils.getFqName(declarationDescriptor); 754 return classes.contains(fqName); 755 } 756 757 @Nullable 758 public static JetType getReceiverType(@NotNull JetType type) { 759 assert isFunctionOrExtensionFunctionType(type) : type; 760 if (isExtensionFunctionType(type)) { 761 return type.getArguments().get(0).getType(); 762 } 763 return null; 764 } 765 766 @NotNull 767 public static List<ValueParameterDescriptor> getValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull JetType type) { 768 assert isFunctionOrExtensionFunctionType(type); 769 List<TypeProjection> parameterTypes = getParameterTypeProjectionsFromFunctionType(type); 770 List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(parameterTypes.size()); 771 for (int i = 0; i < parameterTypes.size(); i++) { 772 TypeProjection parameterType = parameterTypes.get(i); 773 ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl( 774 functionDescriptor, null, i, Annotations.EMPTY, 775 Name.identifier("p" + (i + 1)), parameterType.getType(), false, null, SourceElement.NO_SOURCE 776 ); 777 valueParameters.add(valueParameterDescriptor); 778 } 779 return valueParameters; 780 } 781 782 @NotNull 783 public static JetType getReturnTypeFromFunctionType(@NotNull JetType type) { 784 assert isFunctionOrExtensionFunctionType(type); 785 List<TypeProjection> arguments = type.getArguments(); 786 return arguments.get(arguments.size() - 1).getType(); 787 } 788 789 @NotNull 790 public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType(@NotNull JetType type) { 791 assert isFunctionOrExtensionFunctionType(type); 792 List<TypeProjection> arguments = type.getArguments(); 793 int first = isExtensionFunctionType(type) ? 1 : 0; 794 int last = arguments.size() - 2; 795 List<TypeProjection> parameterTypes = new ArrayList<TypeProjection>(last - first + 1); 796 for (int i = first; i <= last; i++) { 797 parameterTypes.add(arguments.get(i)); 798 } 799 return parameterTypes; 800 } 801 802 // Recognized & special 803 804 private static boolean isConstructedFromGivenClass(@NotNull JetType type, @NotNull FqNameUnsafe fqName) { 805 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 806 return descriptor != null && fqName.equals(DescriptorUtils.getFqName(descriptor)); 807 } 808 809 private static boolean isNotNullConstructedFromGivenClass(@NotNull JetType type, @NotNull FqNameUnsafe fqName) { 810 return !type.isMarkedNullable() && isConstructedFromGivenClass(type, fqName); 811 } 812 813 public static boolean isSpecialClassWithNoSupertypes(@NotNull ClassDescriptor descriptor) { 814 FqNameUnsafe fqName = DescriptorUtils.getFqName(descriptor); 815 return FQ_NAMES.any.equals(fqName) || FQ_NAMES.nothing.equals(fqName); 816 } 817 818 public static boolean isAny(@NotNull ClassDescriptor descriptor) { 819 return isAny(DescriptorUtils.getFqName(descriptor)); 820 } 821 822 public static boolean isAny(@NotNull FqNameUnsafe fqName) { 823 return FQ_NAMES.any.equals(fqName); 824 } 825 826 public static boolean isNothing(@NotNull JetType type) { 827 return isNothingOrNullableNothing(type) 828 && !type.isMarkedNullable(); 829 } 830 831 public static boolean isNullableNothing(@NotNull JetType type) { 832 return isNothingOrNullableNothing(type) 833 && type.isMarkedNullable(); 834 } 835 836 public static boolean isNothingOrNullableNothing(@NotNull JetType type) { 837 return isConstructedFromGivenClass(type, FQ_NAMES.nothing); 838 } 839 840 public static boolean isAnyOrNullableAny(@NotNull JetType type) { 841 return isConstructedFromGivenClass(type, FQ_NAMES.any); 842 } 843 844 public static boolean isNullableAny(@NotNull JetType type) { 845 return isAnyOrNullableAny(type) && type.isMarkedNullable(); 846 } 847 848 public static boolean isUnit(@NotNull JetType type) { 849 return isNotNullConstructedFromGivenClass(type, FQ_NAMES.unit); 850 } 851 852 public boolean isBooleanOrSubtype(@NotNull JetType type) { 853 return JetTypeChecker.DEFAULT.isSubtypeOf(type, getBooleanType()); 854 } 855 856 public static boolean isString(@Nullable JetType type) { 857 return type != null && isNotNullConstructedFromGivenClass(type, FQ_NAMES.string); 858 } 859 860 public static boolean isCloneable(@NotNull ClassDescriptor descriptor) { 861 return FQ_NAMES.cloneable.equals(DescriptorUtils.getFqName(descriptor)); 862 } 863 864 public static boolean isData(@NotNull ClassDescriptor classDescriptor) { 865 return containsAnnotation(classDescriptor, FQ_NAMES.data); 866 } 867 868 public static boolean isDeprecated(@NotNull DeclarationDescriptor declarationDescriptor) { 869 return containsAnnotation(declarationDescriptor, FQ_NAMES.deprecated); 870 } 871 872 public static boolean isTailRecursive(@NotNull DeclarationDescriptor declarationDescriptor) { 873 return containsAnnotation(declarationDescriptor, FQ_NAMES.tailRecursive); 874 } 875 876 public static boolean isSuppressAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) { 877 return isConstructedFromGivenClass(annotationDescriptor.getType(), FQ_NAMES.suppress); 878 } 879 880 static boolean containsAnnotation(DeclarationDescriptor descriptor, FqName annotationClassFqName) { 881 return descriptor.getOriginal().getAnnotations().findAnnotation(annotationClassFqName) != null; 882 } 883 884 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 885 886 @NotNull 887 public JetType getDefaultBound() { 888 return getNullableAnyType(); 889 } 890 891 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 892 893 // GET FUNCTION 894 895 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 896 897 @NotNull 898 public FunctionDescriptor getIdentityEquals() { 899 return KotlinPackage.first(getBuiltInsPackageFragment().getMemberScope().getFunctions(Name.identifier("identityEquals"))); 900 } 901 }