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