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