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