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