001/* 002 * Copyright 2010-2012 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 017package org.jetbrains.jet.lang.types.lang; 018 019import com.google.common.base.Predicates; 020import com.google.common.collect.ImmutableSet; 021import com.google.common.collect.Lists; 022import com.google.common.collect.Sets; 023import com.intellij.openapi.progress.ProcessCanceledException; 024import com.intellij.openapi.project.Project; 025import com.intellij.openapi.util.io.FileUtil; 026import com.intellij.openapi.util.text.StringUtil; 027import com.intellij.psi.PsiFileFactory; 028import com.intellij.util.LocalTimeCounter; 029import org.jetbrains.annotations.NotNull; 030import org.jetbrains.annotations.Nullable; 031import org.jetbrains.jet.lang.DefaultModuleConfiguration; 032import org.jetbrains.jet.lang.ModuleConfiguration; 033import org.jetbrains.jet.lang.PlatformToKotlinClassMap; 034import org.jetbrains.jet.lang.descriptors.*; 035import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 036import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; 037import org.jetbrains.jet.lang.psi.JetFile; 038import org.jetbrains.jet.lang.resolve.AnalyzingUtils; 039import org.jetbrains.jet.lang.resolve.BindingTraceContext; 040import org.jetbrains.jet.lang.resolve.DescriptorUtils; 041import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer; 042import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; 043import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; 044import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; 045import org.jetbrains.jet.lang.resolve.name.FqName; 046import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; 047import org.jetbrains.jet.lang.resolve.name.Name; 048import org.jetbrains.jet.lang.resolve.scopes.JetScope; 049import org.jetbrains.jet.lang.types.*; 050import org.jetbrains.jet.plugin.JetFileType; 051 052import java.io.IOException; 053import java.io.InputStream; 054import java.io.InputStreamReader; 055import java.util.*; 056 057import static org.jetbrains.jet.lang.types.lang.PrimitiveType.*; 058 059public class KotlinBuiltIns { 060 public static final JetScope STUB = JetScope.EMPTY; 061 062 public static final String BUILT_INS_DIR = "jet"; 063 private static final String BUILT_INS_PACKAGE_NAME_STRING = "jet"; 064 private static final Name BUILT_INS_PACKAGE_NAME = Name.identifier(BUILT_INS_PACKAGE_NAME_STRING); 065 public static final FqName BUILT_INS_PACKAGE_FQ_NAME = FqName.topLevel(BUILT_INS_PACKAGE_NAME); 066 067 private static final List<String> LIBRARY_FILES = Arrays.asList( 068 BUILT_INS_DIR + "/Library.jet", 069 BUILT_INS_DIR + "/Numbers.jet", 070 BUILT_INS_DIR + "/Ranges.jet", 071 BUILT_INS_DIR + "/Progressions.jet", 072 BUILT_INS_DIR + "/Iterators.jet", 073 BUILT_INS_DIR + "/Arrays.jet", 074 BUILT_INS_DIR + "/Enum.jet", 075 BUILT_INS_DIR + "/Collections.jet", 076 BUILT_INS_DIR + "/Any.jet", 077 BUILT_INS_DIR + "/ExtensionFunctions.jet", 078 BUILT_INS_DIR + "/Functions.jet", 079 BUILT_INS_DIR + "/KFunctions.jet", 080 BUILT_INS_DIR + "/KMemberFunctions.jet", 081 BUILT_INS_DIR + "/KExtensionFunctions.jet", 082 BUILT_INS_DIR + "/Nothing.jet", 083 BUILT_INS_DIR + "/Unit.jet" 084 ); 085 086 public static final int FUNCTION_TRAIT_COUNT = 23; 087 088 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 089 090 private static volatile KotlinBuiltIns instance = null; 091 092 private static volatile boolean initializing; 093 private static Throwable initializationFailed; 094 095 public enum InitializationMode { 096 // Multi-threaded mode is used in the IDE 097 MULTI_THREADED, 098 // Single-threaded mode is used in the compiler and IDE-independent tests 099 SINGLE_THREADED 100 } 101 102 // This method must be called at least once per application run, on any project 103 // before any type checking is run 104 public static synchronized void initialize(@NotNull Project project, @NotNull InitializationMode initializationMode) { 105 if (instance == null) { 106 if (initializationFailed != null) { 107 throw new RuntimeException( 108 "builtin library initialization failed previously: " + initializationFailed, initializationFailed); 109 } 110 if (initializing) { 111 throw new IllegalStateException("builtin library initialization loop"); 112 } 113 initializing = true; 114 try { 115 instance = new KotlinBuiltIns(project); 116 instance.initialize(initializationMode == InitializationMode.MULTI_THREADED); 117 } 118 catch (Throwable e) { 119 initializationFailed = e; 120 throw new RuntimeException("builtin library initialization failed: " + e, e); 121 } 122 finally { 123 initializing = false; 124 } 125 } 126 } 127 128 @NotNull // This asserts that initialize() is called before any resolution happens 129 public static KotlinBuiltIns getInstance() { 130 if (initializing) { 131 synchronized (KotlinBuiltIns.class) { 132 assert instance != null : "Built-ins are not initialized (note: We are under the same lock as initializing and instance)"; 133 return instance; 134 } 135 } 136 if (instance == null) { 137 throw new IllegalStateException("Initialize standard library first"); 138 } 139 return instance; 140 } 141 142 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 143 144 private final KotlinCodeAnalyzer analyzer; 145 private final ModuleDescriptorImpl builtInsModule; 146 147 private volatile ImmutableSet<ClassDescriptor> nonPhysicalClasses; 148 149 private final ImmutableSet<ClassDescriptor> functionClassesSet; 150 151 private final ImmutableSet<ClassDescriptor> extensionFunctionClassesSet; 152 153 private final EnumMap<PrimitiveType, ClassDescriptor> primitiveTypeToClass; 154 private final EnumMap<PrimitiveType, ClassDescriptor> primitiveTypeToArrayClass; 155 private final EnumMap<PrimitiveType, JetType> primitiveTypeToJetType; 156 private final EnumMap<PrimitiveType, JetType> primitiveTypeToNullableJetType; 157 private final EnumMap<PrimitiveType, JetType> primitiveTypeToArrayJetType; 158 private final Map<JetType, JetType> primitiveJetTypeToJetArrayType; 159 private final Map<JetType, JetType> jetArrayTypeToPrimitiveJetType; 160 161 private final ClassDescriptor nothingClass; 162 private final ClassDescriptor arrayClass; 163 private final ClassDescriptor deprecatedAnnotationClass; 164 private final ClassDescriptor dataAnnotationClass; 165 private final ClassDescriptor[] functionClasses; 166 167 private volatile JetType anyType; 168 private volatile JetType nullableAnyType; 169 private volatile JetType nothingType; 170 private volatile JetType nullableNothingType; 171 private volatile JetType unitType; 172 private volatile JetType stringType; 173 private volatile JetType annotationType; 174 175 private KotlinBuiltIns(@NotNull Project project) { 176 try { 177 this.builtInsModule = new ModuleDescriptorImpl(Name.special("<built-ins lazy module>"), 178 DefaultModuleConfiguration.DEFAULT_JET_IMPORTS, 179 PlatformToKotlinClassMap.EMPTY); 180 builtInsModule.setModuleConfiguration(ModuleConfiguration.EMPTY); 181 this.analyzer = createLazyResolveSession(project); 182 183 this.functionClassesSet = computeIndexedClasses("Function", FUNCTION_TRAIT_COUNT); 184 this.extensionFunctionClassesSet = computeIndexedClasses("ExtensionFunction", FUNCTION_TRAIT_COUNT); 185 186 this.primitiveTypeToClass = new EnumMap<PrimitiveType, ClassDescriptor>(PrimitiveType.class); 187 this.primitiveTypeToJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class); 188 this.primitiveTypeToNullableJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class); 189 this.primitiveTypeToArrayClass = new EnumMap<PrimitiveType, ClassDescriptor>(PrimitiveType.class); 190 this.primitiveTypeToArrayJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class); 191 this.primitiveJetTypeToJetArrayType = new HashMap<JetType, JetType>(); 192 this.jetArrayTypeToPrimitiveJetType = new HashMap<JetType, JetType>(); 193 194 this.nothingClass = getBuiltInClassByName("Nothing"); 195 this.arrayClass = getBuiltInClassByName("Array"); 196 this.deprecatedAnnotationClass = getBuiltInClassByName("deprecated"); 197 this.dataAnnotationClass = getBuiltInClassByName("data"); 198 this.functionClasses = new ClassDescriptor[FUNCTION_TRAIT_COUNT]; 199 for (int i = 0; i < functionClasses.length; i++) { 200 functionClasses[i] = getBuiltInClassByName("Function" + i); 201 } 202 } 203 catch (IOException e) { 204 throw new IllegalStateException(e); 205 } 206 } 207 208 private void initialize(boolean forceResolveAll) { 209 anyType = getBuiltInTypeByClassName("Any"); 210 nullableAnyType = TypeUtils.makeNullable(anyType); 211 nothingType = getBuiltInTypeByClassName("Nothing"); 212 nullableNothingType = TypeUtils.makeNullable(nothingType); 213 unitType = getBuiltInTypeByClassName("Unit"); 214 stringType = getBuiltInTypeByClassName("String"); 215 annotationType = getBuiltInTypeByClassName("Annotation"); 216 217 for (PrimitiveType primitive : PrimitiveType.values()) { 218 makePrimitive(primitive); 219 } 220 221 nonPhysicalClasses = computeNonPhysicalClasses(); 222 223 if (forceResolveAll) { 224 analyzer.forceResolveAll(); 225 } 226 227 AnalyzingUtils.throwExceptionOnErrors(analyzer.getBindingContext()); 228 } 229 230 @NotNull 231 private KotlinCodeAnalyzer createLazyResolveSession(@NotNull Project project) throws IOException { 232 List<JetFile> files = loadResourcesAsJetFiles(project, LIBRARY_FILES); 233 LockBasedStorageManager storageManager = new LockBasedStorageManager(); 234 return new ResolveSession( 235 project, 236 storageManager, 237 builtInsModule, 238 new FileBasedDeclarationProviderFactory(storageManager, files), 239 ResolveSession.NO_ALIASES, 240 Predicates.in(Sets.newHashSet(new FqNameUnsafe("jet.Any"), new FqNameUnsafe("jet.Nothing"))), 241 new BindingTraceContext()); 242 } 243 244 @NotNull 245 private static List<JetFile> loadResourcesAsJetFiles(@NotNull Project project, @NotNull List<String> libraryFiles) 246 throws IOException, ProcessCanceledException 247 { 248 List<JetFile> files = new LinkedList<JetFile>(); 249 for(String path : libraryFiles) { 250 InputStream stream = KotlinBuiltIns.class.getClassLoader().getResourceAsStream(path); 251 252 if (stream == null) { 253 throw new IllegalStateException("Resource not found in classpath: " + path); 254 } 255 256 //noinspection IOResourceOpenedButNotSafelyClosed 257 String text = FileUtil.loadTextAndClose(new InputStreamReader(stream)); 258 JetFile file = (JetFile) PsiFileFactory.getInstance(project).createFileFromText(path, 259 JetFileType.INSTANCE, StringUtil.convertLineSeparators(text), LocalTimeCounter.currentTime(), true, false); 260 files.add(file); 261 } 262 return files; 263 } 264 265 private void makePrimitive(PrimitiveType primitiveType) { 266 ClassDescriptor theClass = getBuiltInClassByName(primitiveType.getTypeName().asString()); 267 JetType type = new JetTypeImpl(theClass); 268 ClassDescriptor arrayClass = getBuiltInClassByName(primitiveType.getArrayTypeName().asString()); 269 JetType arrayType = new JetTypeImpl(arrayClass); 270 271 primitiveTypeToClass.put(primitiveType, theClass); 272 primitiveTypeToJetType.put(primitiveType, type); 273 primitiveTypeToNullableJetType.put(primitiveType, TypeUtils.makeNullable(type)); 274 primitiveTypeToArrayClass.put(primitiveType, arrayClass); 275 primitiveTypeToArrayJetType.put(primitiveType, arrayType); 276 primitiveJetTypeToJetArrayType.put(type, arrayType); 277 jetArrayTypeToPrimitiveJetType.put(arrayType, type); 278 } 279 280 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 281 282 @NotNull 283 public ModuleDescriptorImpl getBuiltInsModule() { 284 return builtInsModule; 285 } 286 287 @NotNull 288 public NamespaceDescriptor getBuiltInsPackage() { 289 NamespaceDescriptor namespace = getBuiltInsModule().getNamespace(BUILT_INS_PACKAGE_FQ_NAME); 290 assert namespace != null : "Built ins namespace not found: " + BUILT_INS_PACKAGE_FQ_NAME; 291 return namespace; 292 } 293 294 @NotNull 295 public FqName getBuiltInsPackageFqName() { 296 return getBuiltInsPackage().getFqName(); 297 } 298 299 @NotNull 300 public JetScope getBuiltInsScope() { 301 return getBuiltInsPackage().getMemberScope(); 302 } 303 304 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 305 306 // GET CLASS 307 308 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 309 310 @NotNull 311 public ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName) { 312 ClassifierDescriptor classifier = getBuiltInsScope().getClassifier(simpleName); 313 assert classifier instanceof ClassDescriptor : "Must be a class descriptor " + simpleName + ", but was " + classifier; 314 return (ClassDescriptor) classifier; 315 } 316 317 @NotNull 318 private ClassDescriptor getBuiltInClassByName(@NotNull String simpleName) { 319 return getBuiltInClassByName(Name.identifier(simpleName)); 320 } 321 322 // Special 323 324 @NotNull 325 public ClassDescriptor getAny() { 326 return getBuiltInClassByName("Any"); 327 } 328 329 @NotNull 330 public ClassDescriptor getNothing() { 331 return getBuiltInClassByName("Nothing"); 332 } 333 334 // Primitive 335 336 @NotNull 337 public ClassDescriptor getPrimitiveClassDescriptor(@NotNull PrimitiveType type) { 338 return getBuiltInClassByName(type.getTypeName().asString()); 339 } 340 341 @NotNull 342 public ClassDescriptor getByte() { 343 return getPrimitiveClassDescriptor(BYTE); 344 } 345 346 @NotNull 347 public ClassDescriptor getShort() { 348 return getPrimitiveClassDescriptor(SHORT); 349 } 350 351 @NotNull 352 public ClassDescriptor getInt() { 353 return getPrimitiveClassDescriptor(INT); 354 } 355 356 @NotNull 357 public ClassDescriptor getLong() { 358 return getPrimitiveClassDescriptor(LONG); 359 } 360 361 @NotNull 362 public ClassDescriptor getFloat() { 363 return getPrimitiveClassDescriptor(FLOAT); 364 } 365 366 @NotNull 367 public ClassDescriptor getDouble() { 368 return getPrimitiveClassDescriptor(DOUBLE); 369 } 370 371 @NotNull 372 public ClassDescriptor getChar() { 373 return getPrimitiveClassDescriptor(CHAR); 374 } 375 376 @NotNull 377 public ClassDescriptor getBoolean() { 378 return getPrimitiveClassDescriptor(BOOLEAN); 379 } 380 381 // Recognized 382 383 @NotNull 384 public Set<DeclarationDescriptor> getIntegralRanges() { 385 return ImmutableSet.<DeclarationDescriptor>of( 386 getBuiltInClassByName("ByteRange"), 387 getBuiltInClassByName("ShortRange"), 388 getBuiltInClassByName("CharRange"), 389 getBuiltInClassByName("IntRange"), 390 getBuiltInClassByName("LongRange") 391 ); 392 } 393 394 @NotNull 395 public ClassDescriptor getArray() { 396 return getBuiltInClassByName("Array"); 397 } 398 399 @NotNull 400 public ClassDescriptor getPrimitiveArrayClassDescriptor(@NotNull PrimitiveType type) { 401 return getBuiltInClassByName(type.getArrayTypeName().asString()); 402 } 403 404 @NotNull 405 public ClassDescriptor getNumber() { 406 return getBuiltInClassByName("Number"); 407 } 408 409 @NotNull 410 public ClassDescriptor getUnit() { 411 return getBuiltInClassByName("Unit"); 412 } 413 414 @NotNull 415 public ClassDescriptor getFunction(int parameterCount) { 416 return getBuiltInClassByName("Function" + parameterCount); 417 } 418 419 @NotNull 420 public ClassDescriptor getExtensionFunction(int parameterCount) { 421 return getBuiltInClassByName("ExtensionFunction" + parameterCount); 422 } 423 424 @NotNull 425 public ClassDescriptor getKFunction(int parameterCount) { 426 return getBuiltInClassByName("KFunction" + parameterCount); 427 } 428 429 @NotNull 430 public ClassDescriptor getKMemberFunction(int parameterCount) { 431 return getBuiltInClassByName("KMemberFunction" + parameterCount); 432 } 433 434 @NotNull 435 public ClassDescriptor getKExtensionFunction(int parameterCount) { 436 return getBuiltInClassByName("KExtensionFunction" + parameterCount); 437 } 438 439 @NotNull 440 public ClassDescriptor getThrowable() { 441 return getBuiltInClassByName("Throwable"); 442 } 443 444 @NotNull 445 public ClassDescriptor getDataClassAnnotation() { 446 return getBuiltInClassByName("data"); 447 } 448 449 @NotNull 450 public ClassDescriptor getVolatileAnnotationClass() { 451 return getBuiltInClassByName("volatile"); 452 } 453 454 @NotNull 455 public ClassDescriptor getDeprecatedAnnotation() { 456 return getBuiltInClassByName("deprecated"); 457 } 458 459 @NotNull 460 public ClassDescriptor getString() { 461 return getBuiltInClassByName("String"); 462 } 463 464 @NotNull 465 public ClassDescriptor getCharSequence() { 466 return getBuiltInClassByName("CharSequence"); 467 } 468 469 @NotNull 470 public ClassDescriptor getComparable() { 471 return getBuiltInClassByName("Comparable"); 472 } 473 474 @NotNull 475 public ClassDescriptor getEnum() { 476 return getBuiltInClassByName("Enum"); 477 } 478 479 @NotNull 480 public ClassDescriptor getAnnotation() { 481 return getBuiltInClassByName("Annotation"); 482 } 483 484 @NotNull 485 public ClassDescriptor getIterator() { 486 return getBuiltInClassByName("Iterator"); 487 } 488 489 @NotNull 490 public ClassDescriptor getIterable() { 491 return getBuiltInClassByName("Iterable"); 492 } 493 494 @NotNull 495 public ClassDescriptor getMutableIterable() { 496 return getBuiltInClassByName("MutableIterable"); 497 } 498 499 @NotNull 500 public ClassDescriptor getMutableIterator() { 501 return getBuiltInClassByName("MutableIterator"); 502 } 503 504 @NotNull 505 public ClassDescriptor getCollection() { 506 return getBuiltInClassByName("Collection"); 507 } 508 509 @NotNull 510 public ClassDescriptor getMutableCollection() { 511 return getBuiltInClassByName("MutableCollection"); 512 } 513 514 @NotNull 515 public ClassDescriptor getList() { 516 return getBuiltInClassByName("List"); 517 } 518 519 @NotNull 520 public ClassDescriptor getMutableList() { 521 return getBuiltInClassByName("MutableList"); 522 } 523 524 @NotNull 525 public ClassDescriptor getSet() { 526 return getBuiltInClassByName("Set"); 527 } 528 529 @NotNull 530 public ClassDescriptor getMutableSet() { 531 return getBuiltInClassByName("MutableSet"); 532 } 533 534 @NotNull 535 public ClassDescriptor getMap() { 536 return getBuiltInClassByName("Map"); 537 } 538 539 @NotNull 540 public ClassDescriptor getMutableMap() { 541 return getBuiltInClassByName("MutableMap"); 542 } 543 544 @NotNull 545 public ClassDescriptor getMapEntry() { 546 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getBuiltInClassByName("Map"), "Entry"); 547 assert classDescriptor != null : "Can't find Map.Entry"; 548 return classDescriptor; 549 } 550 551 @NotNull 552 public ClassDescriptor getMutableMapEntry() { 553 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getBuiltInClassByName("MutableMap"), "MutableEntry"); 554 assert classDescriptor != null : "Can't find MutableMap.MutableEntry"; 555 return classDescriptor; 556 } 557 558 @NotNull 559 public ClassDescriptor getListIterator() { 560 return getBuiltInClassByName("ListIterator"); 561 } 562 563 @NotNull 564 public ClassDescriptor getMutableListIterator() { 565 return getBuiltInClassByName("MutableListIterator"); 566 } 567 568 /** 569 * Classes that only exist for the Kotlin compiler: they are erased at runtime. 570 * As a consequence they, for example, shouldn't be referred to by other languages 571 * (e.g. Java). 572 */ 573 @NotNull 574 public Set<ClassDescriptor> getNonPhysicalClasses() { 575 return nonPhysicalClasses; 576 } 577 578 @NotNull 579 private ImmutableSet<ClassDescriptor> computeNonPhysicalClasses() { 580 ImmutableSet.Builder<ClassDescriptor> nonPhysical = ImmutableSet.builder(); 581 nonPhysical.add( 582 getAny(), 583 getNothing(), 584 585 getNumber(), 586 getString(), 587 getCharSequence(), 588 getThrowable(), 589 getBuiltInClassByName("Hashable"), 590 591 getIterator(), 592 getIterable(), 593 getCollection(), 594 getList(), 595 getListIterator(), 596 getSet(), 597 getMap(), 598 getMapEntry(), 599 600 getMutableIterator(), 601 getMutableIterable(), 602 getMutableCollection(), 603 getMutableList(), 604 getMutableListIterator(), 605 getMutableSet(), 606 getMutableMap(), 607 getMutableMapEntry(), 608 609 getVolatileAnnotationClass(), 610 getDataClassAnnotation(), 611 getAnnotation(), 612 getComparable(), 613 getEnum(), 614 getArray() 615 ); 616 617 for (PrimitiveType primitiveType : values()) { 618 nonPhysical.add(getPrimitiveClassDescriptor(primitiveType)); 619 nonPhysical.add(getPrimitiveArrayClassDescriptor(primitiveType)); 620 } 621 622 return nonPhysical.build(); 623 } 624 625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 626 627 // GET TYPE 628 629 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 630 631 @NotNull 632 private JetType getBuiltInTypeByClassName(@NotNull String classSimpleName) { 633 // TODO 634 return new JetTypeImpl(getBuiltInClassByName(classSimpleName)); 635 } 636 637 // Special 638 639 @NotNull 640 public JetType getNothingType() { 641 return getBuiltInTypeByClassName("Nothing"); 642 } 643 644 @NotNull 645 public JetType getNullableNothingType() { 646 // TODO 647 return TypeUtils.makeNullable(getNothingType()); 648 } 649 650 @NotNull 651 public JetType getAnyType() { 652 return getBuiltInTypeByClassName("Any"); 653 } 654 655 @NotNull 656 public JetType getNullableAnyType() { 657 // TODO 658 return TypeUtils.makeNullable(getAnyType()); 659 } 660 661 // Primitive 662 663 @NotNull 664 public JetType getPrimitiveJetType(@NotNull PrimitiveType type) { 665 // TODO 666 return new JetTypeImpl(getPrimitiveClassDescriptor(type)); 667 } 668 669 @NotNull 670 public JetType getNullablePrimitiveJetType(@NotNull PrimitiveType primitiveType) { 671 return primitiveTypeToNullableJetType.get(primitiveType); 672 } 673 674 @NotNull 675 public JetType getByteType() { 676 return getPrimitiveJetType(BYTE); 677 } 678 679 @NotNull 680 public JetType getShortType() { 681 return getPrimitiveJetType(SHORT); 682 } 683 684 @NotNull 685 public JetType getIntType() { 686 return getPrimitiveJetType(INT); 687 } 688 689 @NotNull 690 public JetType getLongType() { 691 return getPrimitiveJetType(LONG); 692 } 693 694 @NotNull 695 public JetType getFloatType() { 696 return getPrimitiveJetType(FLOAT); 697 } 698 699 @NotNull 700 public JetType getDoubleType() { 701 return getPrimitiveJetType(DOUBLE); 702 } 703 704 @NotNull 705 public JetType getCharType() { 706 return getPrimitiveJetType(CHAR); 707 } 708 709 @NotNull 710 public JetType getBooleanType() { 711 return getPrimitiveJetType(BOOLEAN); 712 } 713 714 // Recognized 715 716 @NotNull 717 public JetType getUnitType() { 718 return getBuiltInTypeByClassName("Unit"); 719 } 720 721 @NotNull 722 public JetType getStringType() { 723 return getBuiltInTypeByClassName("String"); 724 } 725 726 @NotNull 727 public JetType getArrayElementType(@NotNull JetType arrayType) { 728 if (arrayType.getConstructor().getDeclarationDescriptor() == getArray()) { 729 if (arrayType.getArguments().size() != 1) { 730 throw new IllegalStateException(); 731 } 732 return arrayType.getArguments().get(0).getType(); 733 } 734 JetType primitiveType = jetArrayTypeToPrimitiveJetType.get(TypeUtils.makeNotNullable(arrayType)); 735 if (primitiveType == null) { 736 throw new IllegalStateException("not array: " + arrayType); 737 } 738 return primitiveType; 739 } 740 741 @NotNull 742 public JetType getPrimitiveArrayJetType(@NotNull PrimitiveType primitiveType) { 743 return primitiveTypeToArrayJetType.get(primitiveType); 744 } 745 746 /** 747 * @return <code>null</code> if not primitive 748 */ 749 @Nullable 750 public JetType getPrimitiveArrayJetTypeByPrimitiveJetType(@NotNull JetType jetType) { 751 return primitiveJetTypeToJetArrayType.get(jetType); 752 } 753 754 @NotNull 755 public JetType getArrayType(@NotNull Variance projectionType, @NotNull JetType argument) { 756 List<TypeProjection> types = Collections.singletonList(new TypeProjection(projectionType, argument)); 757 return new JetTypeImpl( 758 Collections.<AnnotationDescriptor>emptyList(), 759 getArray().getTypeConstructor(), 760 false, 761 types, 762 getArray().getMemberScope(types) 763 ); 764 } 765 766 @NotNull 767 public JetType getArrayType(@NotNull JetType argument) { 768 return getArrayType(Variance.INVARIANT, argument); 769 } 770 771 @NotNull 772 public JetType getEnumType(@NotNull JetType argument) { 773 Variance projectionType = Variance.INVARIANT; 774 List<TypeProjection> types = Collections.singletonList(new TypeProjection(projectionType, argument)); 775 return new JetTypeImpl( 776 Collections.<AnnotationDescriptor>emptyList(), 777 getEnum().getTypeConstructor(), 778 false, 779 types, 780 getEnum().getMemberScope(types) 781 ); 782 } 783 784 @NotNull 785 public JetType getAnnotationType() { 786 return getBuiltInTypeByClassName("Annotation"); 787 } 788 789 @NotNull 790 public ClassDescriptor getPropertyMetadata() { 791 return getBuiltInClassByName("PropertyMetadata"); 792 } 793 794 @NotNull 795 public ClassDescriptor getPropertyMetadataImpl() { 796 return getBuiltInClassByName("PropertyMetadataImpl"); 797 } 798 799 @NotNull 800 public JetType getFunctionType( 801 @NotNull List<AnnotationDescriptor> annotations, 802 @Nullable JetType receiverType, 803 @NotNull List<JetType> parameterTypes, 804 @NotNull JetType returnType 805 ) { 806 List<TypeProjection> arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType); 807 int size = parameterTypes.size(); 808 ClassDescriptor classDescriptor = receiverType == null ? getFunction(size) : getExtensionFunction(size); 809 TypeConstructor constructor = classDescriptor.getTypeConstructor(); 810 811 return new JetTypeImpl(annotations, constructor, false, arguments, classDescriptor.getMemberScope(arguments)); 812 } 813 814 @NotNull 815 public JetType getKFunctionType( 816 @NotNull List<AnnotationDescriptor> annotations, 817 @Nullable JetType receiverType, 818 @NotNull List<JetType> parameterTypes, 819 @NotNull JetType returnType, 820 boolean extensionFunction 821 ) { 822 List<TypeProjection> arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType); 823 ClassDescriptor classDescriptor = getCorrespondingKFunctionClass(receiverType, extensionFunction, parameterTypes.size()); 824 825 return new JetTypeImpl( 826 annotations, 827 classDescriptor.getTypeConstructor(), 828 false, 829 arguments, 830 classDescriptor.getMemberScope(arguments) 831 ); 832 } 833 834 @NotNull 835 private ClassDescriptor getCorrespondingKFunctionClass( 836 @Nullable JetType receiverType, 837 boolean extensionFunction, 838 int numberOfParameters 839 ) { 840 if (receiverType == null) { 841 return getKFunction(numberOfParameters); 842 } 843 else if (extensionFunction) { 844 return getKExtensionFunction(numberOfParameters); 845 } 846 else { 847 return getKMemberFunction(numberOfParameters); 848 } 849 } 850 851 @NotNull 852 private static List<TypeProjection> getFunctionTypeArgumentProjections( 853 @Nullable JetType receiverType, 854 @NotNull List<JetType> parameterTypes, 855 @NotNull JetType returnType 856 ) { 857 List<TypeProjection> arguments = new ArrayList<TypeProjection>(); 858 if (receiverType != null) { 859 arguments.add(defaultProjection(receiverType)); 860 } 861 for (JetType parameterType : parameterTypes) { 862 arguments.add(defaultProjection(parameterType)); 863 } 864 arguments.add(defaultProjection(returnType)); 865 return arguments; 866 } 867 868 private static TypeProjection defaultProjection(JetType returnType) { 869 return new TypeProjection(Variance.INVARIANT, returnType); 870 } 871 872 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 873 874 // IS TYPE 875 876 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 877 878 public boolean isArray(@NotNull JetType type) { 879 return getArray().equals(type.getConstructor().getDeclarationDescriptor()); 880 } 881 882 public boolean isPrimitiveArray(@NotNull JetType type) { 883 return jetArrayTypeToPrimitiveJetType.containsKey(TypeUtils.makeNotNullable(type)); 884 } 885 886 public boolean isPrimitiveType(@NotNull JetType type) { 887 return primitiveJetTypeToJetArrayType.containsKey(type); 888 } 889 890 // Functions 891 892 @NotNull 893 private ImmutableSet<ClassDescriptor> computeIndexedClasses(@NotNull String prefix, int count) { 894 ImmutableSet.Builder<ClassDescriptor> builder = ImmutableSet.builder(); 895 for (int i = 0; i < count; i++) { 896 builder.add(getBuiltInClassByName(prefix + i)); 897 } 898 return builder.build(); 899 } 900 901 public boolean isFunctionOrExtensionFunctionType(@NotNull JetType type) { 902 return isFunctionType(type) || isExtensionFunctionType(type); 903 } 904 905 public boolean isFunctionType(@NotNull JetType type) { 906 if (setContainsClassOf(functionClassesSet, type)) return true; 907 908 for (JetType superType : type.getConstructor().getSupertypes()) { 909 if (isFunctionType(superType)) return true; 910 } 911 912 return false; 913 } 914 915 public boolean isExtensionFunctionType(@NotNull JetType type) { 916 if (setContainsClassOf(extensionFunctionClassesSet, type)) return true; 917 918 for (JetType superType : type.getConstructor().getSupertypes()) { 919 if (isExtensionFunctionType(superType)) return true; 920 } 921 922 return false; 923 } 924 925 @Nullable 926 public JetType getReceiverType(@NotNull JetType type) { 927 assert isFunctionOrExtensionFunctionType(type) : type; 928 if (isExtensionFunctionType(type)) { 929 return type.getArguments().get(0).getType(); 930 } 931 return null; 932 } 933 934 @NotNull 935 public List<ValueParameterDescriptor> getValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull JetType type) { 936 assert isFunctionOrExtensionFunctionType(type); 937 List<ValueParameterDescriptor> valueParameters = Lists.newArrayList(); 938 List<TypeProjection> parameterTypes = getParameterTypeProjectionsFromFunctionType(type); 939 for (int i = 0; i < parameterTypes.size(); i++) { 940 TypeProjection parameterType = parameterTypes.get(i); 941 ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl( 942 functionDescriptor, i, Collections.<AnnotationDescriptor>emptyList(), 943 Name.identifier("p" + (i + 1)), parameterType.getType(), false, null); 944 valueParameters.add(valueParameterDescriptor); 945 } 946 return valueParameters; 947 } 948 949 @NotNull 950 public JetType getReturnTypeFromFunctionType(@NotNull JetType type) { 951 assert isFunctionOrExtensionFunctionType(type); 952 List<TypeProjection> arguments = type.getArguments(); 953 return arguments.get(arguments.size() - 1).getType(); 954 } 955 956 @NotNull 957 public List<TypeProjection> getParameterTypeProjectionsFromFunctionType(@NotNull JetType type) { 958 assert isFunctionOrExtensionFunctionType(type); 959 List<TypeProjection> arguments = type.getArguments(); 960 int first = isExtensionFunctionType(type) ? 1 : 0; 961 int last = arguments.size() - 2; 962 List<TypeProjection> parameterTypes = Lists.newArrayList(); 963 for (int i = first; i <= last; i++) { 964 parameterTypes.add(arguments.get(i)); 965 } 966 return parameterTypes; 967 } 968 969 // Recognized & special 970 971 public boolean isNothing(@NotNull JetType type) { 972 return isNothingOrNullableNothing(type) 973 && !type.isNullable(); 974 } 975 976 public boolean isNullableNothing(@NotNull JetType type) { 977 return isNothingOrNullableNothing(type) 978 && type.isNullable(); 979 } 980 981 public boolean isNothingOrNullableNothing(@NotNull JetType type) { 982 return !(type instanceof NamespaceType) 983 && type.getConstructor() == getNothing().getTypeConstructor(); 984 } 985 986 public boolean isAny(@NotNull JetType type) { 987 return !(type instanceof NamespaceType) && 988 type.getConstructor() == getAny().getTypeConstructor(); 989 } 990 991 public boolean isUnit(@NotNull JetType type) { 992 return !(type instanceof NamespaceType) && 993 type.getConstructor() == getUnitType().getConstructor(); 994 } 995 996 public boolean isData(@NotNull ClassDescriptor classDescriptor) { 997 return containsAnnotation(classDescriptor, getDataClassAnnotation()); 998 } 999 1000 public boolean isDeprecated(@NotNull DeclarationDescriptor declarationDescriptor) { 1001 return containsAnnotation(declarationDescriptor, getDeprecatedAnnotation()); 1002 } 1003 1004 private static boolean containsAnnotation(DeclarationDescriptor descriptor, ClassDescriptor annotationClass) { 1005 List<AnnotationDescriptor> annotations = descriptor.getOriginal().getAnnotations(); 1006 if (annotations != null) { 1007 for (AnnotationDescriptor annotation : annotations) { 1008 if (annotationClass.equals(annotation.getType().getConstructor().getDeclarationDescriptor())) { 1009 return true; 1010 } 1011 } 1012 } 1013 return false; 1014 } 1015 1016 public boolean isVolatile(@NotNull PropertyDescriptor descriptor) { 1017 return containsAnnotation(descriptor, getVolatileAnnotationClass()); 1018 } 1019 1020 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1021 1022 @NotNull 1023 public JetType getDefaultBound() { 1024 return getNullableAnyType(); 1025 } 1026 1027 private static boolean setContainsClassOf(ImmutableSet<ClassDescriptor> set, JetType type) { 1028 //noinspection SuspiciousMethodCalls 1029 return set.contains(type.getConstructor().getDeclarationDescriptor()); 1030 } 1031}