001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.builtins;
018
019 import kotlin.SetsKt;
020 import kotlin.jvm.functions.Function1;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory;
024 import org.jetbrains.kotlin.descriptors.*;
025 import org.jetbrains.kotlin.descriptors.annotations.*;
026 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
027 import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
028 import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
029 import org.jetbrains.kotlin.name.ClassId;
030 import org.jetbrains.kotlin.name.FqName;
031 import org.jetbrains.kotlin.name.FqNameUnsafe;
032 import org.jetbrains.kotlin.name.Name;
033 import org.jetbrains.kotlin.resolve.DescriptorUtils;
034 import org.jetbrains.kotlin.resolve.constants.ConstantValue;
035 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
036 import org.jetbrains.kotlin.serialization.deserialization.AdditionalSupertypes;
037 import org.jetbrains.kotlin.storage.LockBasedStorageManager;
038 import org.jetbrains.kotlin.types.*;
039 import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
040
041 import java.io.InputStream;
042 import java.util.*;
043
044 import static kotlin.CollectionsKt.*;
045 import static kotlin.SetsKt.setOf;
046 import static org.jetbrains.kotlin.builtins.PrimitiveType.*;
047 import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
048
049 public abstract class KotlinBuiltIns {
050 public static final Name BUILT_INS_PACKAGE_NAME = Name.identifier("kotlin");
051 public static final FqName BUILT_INS_PACKAGE_FQ_NAME = FqName.topLevel(BUILT_INS_PACKAGE_NAME);
052 public static final FqName ANNOTATION_PACKAGE_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("annotation"));
053
054 public static final Set<FqName> BUILT_INS_PACKAGE_FQ_NAMES = setOf(
055 BUILT_INS_PACKAGE_FQ_NAME,
056 ANNOTATION_PACKAGE_FQ_NAME,
057 ReflectionTypesKt.getKOTLIN_REFLECT_FQ_NAME()
058 );
059
060 protected final ModuleDescriptorImpl builtInsModule;
061 private final BuiltinsPackageFragment builtinsPackageFragment;
062 private final BuiltinsPackageFragment annotationPackageFragment;
063
064 private final Map<PrimitiveType, KotlinType> primitiveTypeToArrayKotlinType;
065 private final Map<KotlinType, KotlinType> primitiveKotlinTypeToKotlinArrayType;
066 private final Map<KotlinType, KotlinType> kotlinArrayTypeToPrimitiveKotlinType;
067
068 public static final FqNames FQ_NAMES = new FqNames();
069
070 protected KotlinBuiltIns() {
071 LockBasedStorageManager storageManager = new LockBasedStorageManager();
072 builtInsModule = new ModuleDescriptorImpl(
073 Name.special("<built-ins module>"), storageManager, ModuleParameters.Empty.INSTANCE$, this
074 );
075
076 PackageFragmentProvider packageFragmentProvider = BuiltInsPackageFragmentProviderKt.createBuiltInPackageFragmentProvider(
077 storageManager, builtInsModule, BUILT_INS_PACKAGE_FQ_NAMES,
078 new BuiltInFictitiousFunctionClassFactory(storageManager, builtInsModule),
079 getAdditionalSupertypesProvider(),
080 new Function1<String, InputStream>() {
081 @Override
082 public InputStream invoke(String path) {
083 return KotlinBuiltIns.class.getClassLoader().getResourceAsStream(path);
084 }
085 }
086 );
087
088 builtInsModule.initialize(packageFragmentProvider);
089 builtInsModule.setDependencies(builtInsModule);
090
091 builtinsPackageFragment = (BuiltinsPackageFragment) single(packageFragmentProvider.getPackageFragments(BUILT_INS_PACKAGE_FQ_NAME));
092 annotationPackageFragment = (BuiltinsPackageFragment) single(packageFragmentProvider.getPackageFragments(ANNOTATION_PACKAGE_FQ_NAME));
093
094 primitiveTypeToArrayKotlinType = new EnumMap<PrimitiveType, KotlinType>(PrimitiveType.class);
095 primitiveKotlinTypeToKotlinArrayType = new HashMap<KotlinType, KotlinType>();
096 kotlinArrayTypeToPrimitiveKotlinType = new HashMap<KotlinType, KotlinType>();
097 for (PrimitiveType primitive : PrimitiveType.values()) {
098 makePrimitive(primitive);
099 }
100 }
101
102 @NotNull
103 protected AdditionalSupertypes getAdditionalSupertypesProvider() {
104 return AdditionalSupertypes.None.INSTANCE$;
105 }
106
107 private void makePrimitive(@NotNull PrimitiveType primitiveType) {
108 KotlinType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString());
109 KotlinType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString());
110
111 primitiveTypeToArrayKotlinType.put(primitiveType, arrayType);
112 primitiveKotlinTypeToKotlinArrayType.put(type, arrayType);
113 kotlinArrayTypeToPrimitiveKotlinType.put(arrayType, type);
114 }
115
116 public static class FqNames {
117 public final FqNameUnsafe any = fqNameUnsafe("Any");
118 public final FqNameUnsafe nothing = fqNameUnsafe("Nothing");
119 public final FqNameUnsafe cloneable = fqNameUnsafe("Cloneable");
120 public final FqNameUnsafe suppress = fqNameUnsafe("Suppress");
121 public final FqNameUnsafe unit = fqNameUnsafe("Unit");
122 public final FqNameUnsafe string = fqNameUnsafe("String");
123 public final FqNameUnsafe array = fqNameUnsafe("Array");
124
125 public final FqNameUnsafe _boolean = fqNameUnsafe("Boolean");
126 public final FqNameUnsafe _char = fqNameUnsafe("Char");
127 public final FqNameUnsafe _byte = fqNameUnsafe("Byte");
128 public final FqNameUnsafe _short = fqNameUnsafe("Short");
129 public final FqNameUnsafe _int = fqNameUnsafe("Int");
130 public final FqNameUnsafe _long = fqNameUnsafe("Long");
131 public final FqNameUnsafe _float = fqNameUnsafe("Float");
132 public final FqNameUnsafe _double = fqNameUnsafe("Double");
133
134 public final FqNameUnsafe _collection = fqNameUnsafe("Collection");
135 public final FqNameUnsafe _list = fqNameUnsafe("List");
136 public final FqNameUnsafe _set = fqNameUnsafe("Set");
137 public final FqNameUnsafe _iterable = fqNameUnsafe("Iterable");
138
139 public final FqName throwable = fqName("Throwable");
140
141 public final FqName deprecated = fqName("Deprecated");
142 public final FqName extension = fqName("Extension");
143 public final FqName target = annotationName("Target");
144 public final FqName annotationTarget = annotationName("AnnotationTarget");
145 public final FqName annotationRetention = annotationName("AnnotationRetention");
146 public final FqName retention = annotationName("Retention");
147 public final FqName repeatable = annotationName("Repeatable");
148 public final FqName mustBeDocumented = annotationName("MustBeDocumented");
149 public final FqName unsafeVariance = fqName("UnsafeVariance");
150
151 public final FqName mutableList = fqName("MutableList");
152 public final FqName mutableSet = fqName("MutableSet");
153 public final FqName mutableMap = fqName("MutableMap");
154
155 public final FqNameUnsafe kClass = reflect("KClass");
156 public final FqNameUnsafe kCallable = reflect("KCallable");
157 public final ClassId kProperty = ClassId.topLevel(reflect("KProperty").toSafe());
158
159 public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType;
160 public final Map<FqNameUnsafe, PrimitiveType> arrayClassFqNameToPrimitiveType;
161 {
162 fqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
163 arrayClassFqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
164 for (PrimitiveType primitiveType : PrimitiveType.values()) {
165 fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType);
166 arrayClassFqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getArrayTypeName().asString()), primitiveType);
167 }
168 }
169
170 @NotNull
171 private static FqNameUnsafe fqNameUnsafe(@NotNull String simpleName) {
172 return fqName(simpleName).toUnsafe();
173 }
174
175 @NotNull
176 private static FqName fqName(@NotNull String simpleName) {
177 return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName));
178 }
179
180 @NotNull
181 private static FqNameUnsafe reflect(@NotNull String simpleName) {
182 return ReflectionTypesKt.getKOTLIN_REFLECT_FQ_NAME().child(Name.identifier(simpleName)).toUnsafe();
183 }
184
185 @NotNull
186 private static FqName annotationName(@NotNull String simpleName) {
187 return ANNOTATION_PACKAGE_FQ_NAME.child(Name.identifier(simpleName));
188 }
189 }
190
191 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
192
193 @NotNull
194 public ModuleDescriptorImpl getBuiltInsModule() {
195 return builtInsModule;
196 }
197
198 @NotNull
199 public PackageFragmentDescriptor getBuiltInsPackageFragment() {
200 return builtinsPackageFragment;
201 }
202
203 @NotNull
204 public MemberScope getBuiltInsPackageScope() {
205 return builtinsPackageFragment.getMemberScope();
206 }
207
208 @NotNull
209 public MemberScope getAnnotationPackageScope() {
210 return annotationPackageFragment.getMemberScope();
211 }
212
213 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
214
215 // GET CLASS
216
217 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
218
219 @NotNull
220 public ClassDescriptor getAnnotationClassByName(@NotNull Name simpleName) {
221 ClassifierDescriptor classifier = annotationPackageFragment.getMemberScope().getContributedClassifier(simpleName,
222 NoLookupLocation.FROM_BUILTINS);
223 assert classifier instanceof ClassDescriptor : "Must be a class descriptor " + simpleName + ", but was " +
224 (classifier == null ? "null" : classifier.toString());
225 return (ClassDescriptor) classifier;
226 }
227
228 @NotNull
229 public ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName) {
230 ClassDescriptor classDescriptor = getBuiltInClassByNameNullable(simpleName);
231 assert classDescriptor != null : "Built-in class " + simpleName + " is not found";
232 return classDescriptor;
233 }
234
235 @Nullable
236 public ClassDescriptor getBuiltInClassByNameNullable(@NotNull Name simpleName) {
237 ClassifierDescriptor classifier = getBuiltInsPackageFragment().getMemberScope().getContributedClassifier(simpleName,
238 NoLookupLocation.FROM_BUILTINS);
239 assert classifier == null ||
240 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 SetsKt.<DeclarationDescriptor>setOf(
313 getBuiltInClassByName("ByteRange"),
314 getBuiltInClassByName("ShortRange"),
315 getBuiltInClassByName("CharRange"),
316 getBuiltInClassByName("IntRange")
317 );
318 }
319
320 @NotNull
321 public ClassDescriptor getArray() {
322 return getBuiltInClassByName("Array");
323 }
324
325 @NotNull
326 public ClassDescriptor getPrimitiveArrayClassDescriptor(@NotNull PrimitiveType type) {
327 return getBuiltInClassByName(type.getArrayTypeName().asString());
328 }
329
330 @NotNull
331 public ClassDescriptor getNumber() {
332 return getBuiltInClassByName("Number");
333 }
334
335 @NotNull
336 public ClassDescriptor getUnit() {
337 return getBuiltInClassByName("Unit");
338 }
339
340 @NotNull
341 public static String getFunctionName(int parameterCount) {
342 return "Function" + parameterCount;
343 }
344
345 @NotNull
346 public static String getExtensionFunctionName(int parameterCount) {
347 return getFunctionName(parameterCount + 1);
348 }
349
350 @NotNull
351 public ClassDescriptor getFunction(int parameterCount) {
352 return getBuiltInClassByName(getFunctionName(parameterCount));
353 }
354
355 /**
356 * @return the descriptor representing the class kotlin.Function{parameterCount + 1}
357 * @deprecated there are no ExtensionFunction classes anymore, use {@link #getFunction(int)} instead
358 */
359 @Deprecated
360 @NotNull
361 public ClassDescriptor getExtensionFunction(int parameterCount) {
362 return getBuiltInClassByName(getExtensionFunctionName((parameterCount)));
363 }
364
365 @NotNull
366 public ClassDescriptor getThrowable() {
367 return getBuiltInClassByName("Throwable");
368 }
369
370 @NotNull
371 public ClassDescriptor getCloneable() {
372 return getBuiltInClassByName("Cloneable");
373 }
374
375 @NotNull
376 public ClassDescriptor getDeprecatedAnnotation() {
377 return getBuiltInClassByName(FQ_NAMES.deprecated.shortName());
378 }
379
380 @NotNull
381 public ClassDescriptor getTargetAnnotation() {
382 return getAnnotationClassByName(FQ_NAMES.target.shortName());
383 }
384
385 @NotNull
386 public ClassDescriptor getRetentionAnnotation() {
387 return getAnnotationClassByName(FQ_NAMES.retention.shortName());
388 }
389
390 @NotNull
391 public ClassDescriptor getRepeatableAnnotation() {
392 return getAnnotationClassByName(FQ_NAMES.repeatable.shortName());
393 }
394
395 @NotNull
396 public ClassDescriptor getMustBeDocumentedAnnotation() {
397 return getAnnotationClassByName(FQ_NAMES.mustBeDocumented.shortName());
398 }
399
400 @NotNull
401 public ClassDescriptor getAnnotationTargetEnum() {
402 return getAnnotationClassByName(FQ_NAMES.annotationTarget.shortName());
403 }
404
405 @Nullable
406 public ClassDescriptor getAnnotationTargetEnumEntry(@NotNull KotlinTarget target) {
407 ClassifierDescriptor result = getAnnotationTargetEnum().getUnsubstitutedInnerClassesScope().getContributedClassifier(
408 Name.identifier(target.name()), NoLookupLocation.FROM_BUILTINS
409 );
410 return result instanceof ClassDescriptor ? (ClassDescriptor) result : null;
411 }
412
413 @NotNull
414 public ClassDescriptor getAnnotationRetentionEnum() {
415 return getAnnotationClassByName(FQ_NAMES.annotationRetention.shortName());
416 }
417
418 @Nullable
419 public ClassDescriptor getAnnotationRetentionEnumEntry(@NotNull KotlinRetention retention) {
420 ClassifierDescriptor result = getAnnotationRetentionEnum().getUnsubstitutedInnerClassesScope().getContributedClassifier(
421 Name.identifier(retention.name()), NoLookupLocation.FROM_BUILTINS
422 );
423 return result instanceof ClassDescriptor ? (ClassDescriptor) result : null;
424 }
425
426 @NotNull
427 public ClassDescriptor getString() {
428 return getBuiltInClassByName("String");
429 }
430
431 @NotNull
432 public ClassDescriptor getCharSequence() {
433 return getBuiltInClassByName("CharSequence");
434 }
435
436 @NotNull
437 public ClassDescriptor getComparable() {
438 return getBuiltInClassByName("Comparable");
439 }
440
441 @NotNull
442 public ClassDescriptor getEnum() {
443 return getBuiltInClassByName("Enum");
444 }
445
446 @NotNull
447 public ClassDescriptor getAnnotation() {
448 return getBuiltInClassByName("Annotation");
449 }
450
451 @NotNull
452 public ClassDescriptor getIterator() {
453 return getBuiltInClassByName("Iterator");
454 }
455
456 @NotNull
457 public ClassDescriptor getIterable() {
458 return getBuiltInClassByName("Iterable");
459 }
460
461 @NotNull
462 public ClassDescriptor getMutableIterable() {
463 return getBuiltInClassByName("MutableIterable");
464 }
465
466 @NotNull
467 public ClassDescriptor getMutableIterator() {
468 return getBuiltInClassByName("MutableIterator");
469 }
470
471 @NotNull
472 public ClassDescriptor getCollection() {
473 return getBuiltInClassByName("Collection");
474 }
475
476 @NotNull
477 public ClassDescriptor getMutableCollection() {
478 return getBuiltInClassByName("MutableCollection");
479 }
480
481 @NotNull
482 public ClassDescriptor getList() {
483 return getBuiltInClassByName("List");
484 }
485
486 @NotNull
487 public ClassDescriptor getMutableList() {
488 return getBuiltInClassByName("MutableList");
489 }
490
491 @NotNull
492 public ClassDescriptor getSet() {
493 return getBuiltInClassByName("Set");
494 }
495
496 @NotNull
497 public ClassDescriptor getMutableSet() {
498 return getBuiltInClassByName("MutableSet");
499 }
500
501 @NotNull
502 public ClassDescriptor getMap() {
503 return getBuiltInClassByName("Map");
504 }
505
506 @NotNull
507 public ClassDescriptor getMutableMap() {
508 return getBuiltInClassByName("MutableMap");
509 }
510
511 @NotNull
512 public ClassDescriptor getMapEntry() {
513 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMap(), "Entry", NoLookupLocation.FROM_BUILTINS);
514 assert classDescriptor != null : "Can't find Map.Entry";
515 return classDescriptor;
516 }
517
518 @NotNull
519 public ClassDescriptor getMutableMapEntry() {
520 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMutableMap(), "MutableEntry", NoLookupLocation.FROM_BUILTINS);
521 assert classDescriptor != null : "Can't find MutableMap.MutableEntry";
522 return classDescriptor;
523 }
524
525 @NotNull
526 public ClassDescriptor getListIterator() {
527 return getBuiltInClassByName("ListIterator");
528 }
529
530 @NotNull
531 public ClassDescriptor getMutableListIterator() {
532 return getBuiltInClassByName("MutableListIterator");
533 }
534
535 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
536
537 // GET TYPE
538
539 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
540
541 @NotNull
542 private KotlinType getBuiltInTypeByClassName(@NotNull String classSimpleName) {
543 return getBuiltInClassByName(classSimpleName).getDefaultType();
544 }
545
546 // Special
547
548 @NotNull
549 public KotlinType getNothingType() {
550 return getNothing().getDefaultType();
551 }
552
553 @NotNull
554 public KotlinType getNullableNothingType() {
555 return TypeUtils.makeNullable(getNothingType());
556 }
557
558 @NotNull
559 public KotlinType getAnyType() {
560 return getAny().getDefaultType();
561 }
562
563 @NotNull
564 public KotlinType getNullableAnyType() {
565 return TypeUtils.makeNullable(getAnyType());
566 }
567
568 // Primitive
569
570 @NotNull
571 public KotlinType getPrimitiveKotlinType(@NotNull PrimitiveType type) {
572 return getPrimitiveClassDescriptor(type).getDefaultType();
573 }
574
575 @NotNull
576 public KotlinType getByteType() {
577 return getPrimitiveKotlinType(BYTE);
578 }
579
580 @NotNull
581 public KotlinType getShortType() {
582 return getPrimitiveKotlinType(SHORT);
583 }
584
585 @NotNull
586 public KotlinType getIntType() {
587 return getPrimitiveKotlinType(INT);
588 }
589
590 @NotNull
591 public KotlinType getLongType() {
592 return getPrimitiveKotlinType(LONG);
593 }
594
595 @NotNull
596 public KotlinType getFloatType() {
597 return getPrimitiveKotlinType(FLOAT);
598 }
599
600 @NotNull
601 public KotlinType getDoubleType() {
602 return getPrimitiveKotlinType(DOUBLE);
603 }
604
605 @NotNull
606 public KotlinType getCharType() {
607 return getPrimitiveKotlinType(CHAR);
608 }
609
610 @NotNull
611 public KotlinType getBooleanType() {
612 return getPrimitiveKotlinType(BOOLEAN);
613 }
614
615 // Recognized
616
617 @NotNull
618 public KotlinType getUnitType() {
619 return getUnit().getDefaultType();
620 }
621
622 @NotNull
623 public KotlinType getStringType() {
624 return getString().getDefaultType();
625 }
626
627 @NotNull
628 public KotlinType getArrayElementType(@NotNull KotlinType arrayType) {
629 if (isArray(arrayType)) {
630 if (arrayType.getArguments().size() != 1) {
631 throw new IllegalStateException();
632 }
633 return arrayType.getArguments().get(0).getType();
634 }
635 KotlinType primitiveType = kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType));
636 if (primitiveType == null) {
637 throw new IllegalStateException("not array: " + arrayType);
638 }
639 return primitiveType;
640 }
641
642 @NotNull
643 public KotlinType getPrimitiveArrayKotlinType(@NotNull PrimitiveType primitiveType) {
644 return primitiveTypeToArrayKotlinType.get(primitiveType);
645 }
646
647 /**
648 * @return {@code null} if not primitive
649 */
650 @Nullable
651 public KotlinType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) {
652 return primitiveKotlinTypeToKotlinArrayType.get(kotlinType);
653 }
654
655 public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) {
656 return getPrimitiveTypeByArrayClassFqName(arrayFqName) != null;
657 }
658
659 @Nullable
660 public static PrimitiveType getPrimitiveTypeByFqName(@NotNull FqNameUnsafe primitiveClassFqName) {
661 return FQ_NAMES.fqNameToPrimitiveType.get(primitiveClassFqName);
662 }
663
664 @Nullable
665 public static PrimitiveType getPrimitiveTypeByArrayClassFqName(@NotNull FqNameUnsafe primitiveArrayClassFqName) {
666 return FQ_NAMES.arrayClassFqNameToPrimitiveType.get(primitiveArrayClassFqName);
667 }
668
669 @NotNull
670 public KotlinType getArrayType(@NotNull Variance projectionType, @NotNull KotlinType argument) {
671 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument));
672 return KotlinTypeImpl.create(
673 Annotations.Companion.getEMPTY(),
674 getArray(),
675 false,
676 types
677 );
678 }
679
680 @NotNull
681 public KotlinType getEnumType(@NotNull KotlinType argument) {
682 Variance projectionType = Variance.INVARIANT;
683 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument));
684 return KotlinTypeImpl.create(
685 Annotations.Companion.getEMPTY(),
686 getEnum(),
687 false,
688 types
689 );
690 }
691
692 @NotNull
693 public KotlinType getAnnotationType() {
694 return getAnnotation().getDefaultType();
695 }
696
697 @NotNull
698 public AnnotationDescriptor createExtensionAnnotation() {
699 return new AnnotationDescriptorImpl(getBuiltInClassByName(FQ_NAMES.extension.shortName()).getDefaultType(),
700 Collections.<ValueParameterDescriptor, ConstantValue<?>>emptyMap(), SourceElement.NO_SOURCE);
701 }
702
703 private static boolean isTypeAnnotatedWithExtension(@NotNull KotlinType type) {
704 return type.getAnnotations().findAnnotation(FQ_NAMES.extension) != null;
705 }
706
707 @NotNull
708 public KotlinType getFunctionType(
709 @NotNull Annotations annotations,
710 @Nullable KotlinType receiverType,
711 @NotNull List<KotlinType> parameterTypes,
712 @NotNull KotlinType returnType
713 ) {
714 List<TypeProjection> arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType);
715 int size = parameterTypes.size();
716 ClassDescriptor classDescriptor = receiverType == null ? getFunction(size) : getExtensionFunction(size);
717
718 Annotations typeAnnotations = receiverType == null ? annotations : addExtensionAnnotation(annotations);
719
720 return KotlinTypeImpl.create(typeAnnotations, classDescriptor, false, arguments);
721 }
722
723 @NotNull
724 private Annotations addExtensionAnnotation(@NotNull Annotations annotations) {
725 if (annotations.findAnnotation(FQ_NAMES.extension) != null) return annotations;
726
727 // TODO: preserve laziness of given annotations
728 return new AnnotationsImpl(plus(annotations, listOf(createExtensionAnnotation())));
729 }
730
731 @NotNull
732 public static List<TypeProjection> getFunctionTypeArgumentProjections(
733 @Nullable KotlinType receiverType,
734 @NotNull List<KotlinType> parameterTypes,
735 @NotNull KotlinType returnType
736 ) {
737 List<TypeProjection> arguments = new ArrayList<TypeProjection>(parameterTypes.size() + (receiverType != null ? 1 : 0) + 1);
738 if (receiverType != null) {
739 arguments.add(defaultProjection(receiverType));
740 }
741 for (KotlinType parameterType : parameterTypes) {
742 arguments.add(defaultProjection(parameterType));
743 }
744 arguments.add(defaultProjection(returnType));
745 return arguments;
746 }
747
748 private static TypeProjection defaultProjection(KotlinType returnType) {
749 return new TypeProjectionImpl(Variance.INVARIANT, returnType);
750 }
751
752 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
753
754 // IS TYPE
755
756 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
757
758 public static boolean isArray(@NotNull KotlinType type) {
759 return isConstructedFromGivenClass(type, FQ_NAMES.array);
760 }
761
762 public static boolean isPrimitiveArray(@NotNull KotlinType type) {
763 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
764 return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null;
765 }
766
767 public static boolean isPrimitiveType(@NotNull KotlinType type) {
768 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
769 return !type.isMarkedNullable() && descriptor instanceof ClassDescriptor && isPrimitiveClass((ClassDescriptor) descriptor);
770 }
771
772 public static boolean isPrimitiveClass(@NotNull ClassDescriptor descriptor) {
773 return getPrimitiveTypeByFqName(getFqName(descriptor)) != null;
774 }
775
776 // Functions
777
778 public static boolean isFunctionOrExtensionFunctionType(@NotNull KotlinType type) {
779 return isFunctionType(type) || isExtensionFunctionType(type);
780 }
781
782 public static boolean isFunctionType(@NotNull KotlinType type) {
783 if (isExactFunctionType(type)) return true;
784
785 for (KotlinType superType : type.getConstructor().getSupertypes()) {
786 if (isFunctionType(superType)) return true;
787 }
788
789 return false;
790 }
791
792 public static boolean isExtensionFunctionType(@NotNull KotlinType type) {
793 if (isExactExtensionFunctionType(type)) return true;
794
795 for (KotlinType superType : type.getConstructor().getSupertypes()) {
796 if (isExtensionFunctionType(superType)) return true;
797 }
798
799 return false;
800 }
801
802 public static boolean isExactFunctionOrExtensionFunctionType(@NotNull KotlinType type) {
803 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
804 return descriptor != null && isNumberedFunctionClassFqName(getFqName(descriptor));
805 }
806
807 public static boolean isExactFunctionType(@NotNull KotlinType type) {
808 return isExactFunctionOrExtensionFunctionType(type) && !isTypeAnnotatedWithExtension(type);
809 }
810
811 public static boolean isExactExtensionFunctionType(@NotNull KotlinType type) {
812 return isExactFunctionOrExtensionFunctionType(type) && isTypeAnnotatedWithExtension(type);
813 }
814
815 /**
816 * @return true if this is an FQ name of a fictitious class representing the function type,
817 * e.g. kotlin.Function1 (but NOT kotlin.reflect.KFunction1)
818 */
819 public static boolean isNumberedFunctionClassFqName(@NotNull FqNameUnsafe fqName) {
820 List<Name> segments = fqName.pathSegments();
821 if (segments.size() != 2) return false;
822
823 if (!BUILT_INS_PACKAGE_NAME.equals(first(segments))) return false;
824
825 String shortName = last(segments).asString();
826 return BuiltInFictitiousFunctionClassFactory.parseClassName(shortName, BUILT_INS_PACKAGE_FQ_NAME) != null;
827 }
828
829 @Nullable
830 public static KotlinType getReceiverType(@NotNull KotlinType type) {
831 assert isFunctionOrExtensionFunctionType(type) : type;
832 if (isExtensionFunctionType(type)) {
833 // TODO: this is incorrect when a class extends from an extension function and swaps type arguments
834 return type.getArguments().get(0).getType();
835 }
836 return null;
837 }
838
839 @NotNull
840 public static List<ValueParameterDescriptor> getValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull KotlinType type) {
841 assert isFunctionOrExtensionFunctionType(type);
842 List<TypeProjection> parameterTypes = getParameterTypeProjectionsFromFunctionType(type);
843 List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(parameterTypes.size());
844 for (int i = 0; i < parameterTypes.size(); i++) {
845 TypeProjection parameterType = parameterTypes.get(i);
846 ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(
847 functionDescriptor, null, i, Annotations.Companion.getEMPTY(),
848 Name.identifier("p" + (i + 1)), parameterType.getType(),
849 /* declaresDefaultValue = */ false,
850 /* isCrossinline = */ false,
851 /* isNoinline = */ false,
852 null, SourceElement.NO_SOURCE
853 );
854 valueParameters.add(valueParameterDescriptor);
855 }
856 return valueParameters;
857 }
858
859 @NotNull
860 public static KotlinType getReturnTypeFromFunctionType(@NotNull KotlinType type) {
861 assert isFunctionOrExtensionFunctionType(type);
862 List<TypeProjection> arguments = type.getArguments();
863 return arguments.get(arguments.size() - 1).getType();
864 }
865
866 @NotNull
867 public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType(@NotNull KotlinType type) {
868 assert isFunctionOrExtensionFunctionType(type);
869 List<TypeProjection> arguments = type.getArguments();
870 int first = isExtensionFunctionType(type) ? 1 : 0;
871 int last = arguments.size() - 2;
872 // TODO: fix bugs associated with this here and in neighboring methods, see KT-9820
873 assert first <= last + 1 : "Not an exact function type: " + type;
874 List<TypeProjection> parameterTypes = new ArrayList<TypeProjection>(last - first + 1);
875 for (int i = first; i <= last; i++) {
876 parameterTypes.add(arguments.get(i));
877 }
878 return parameterTypes;
879 }
880
881 // Recognized & special
882
883 private static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
884 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
885 return descriptor != null &&
886 /* quick check to avoid creation of full FqName instance */ descriptor.getName().equals(fqName.shortName()) &&
887 fqName.equals(getFqName(descriptor));
888 }
889
890 private static boolean isNotNullConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
891 return !type.isMarkedNullable() && isConstructedFromGivenClass(type, fqName);
892 }
893
894 public static boolean isSpecialClassWithNoSupertypes(@NotNull ClassDescriptor descriptor) {
895 FqNameUnsafe fqName = getFqName(descriptor);
896 return FQ_NAMES.any.equals(fqName) || FQ_NAMES.nothing.equals(fqName);
897 }
898
899 public static boolean isAny(@NotNull ClassDescriptor descriptor) {
900 return isAny(getFqName(descriptor));
901 }
902
903 public static boolean isAny(@NotNull KotlinType type) {
904 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES.any);
905 }
906
907 public static boolean isBoolean(@NotNull KotlinType type) {
908
909 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._boolean);
910 }
911
912 public static boolean isBooleanOrNullableBoolean(@NotNull KotlinType type) {
913 return isConstructedFromGivenClass(type, FQ_NAMES._boolean);
914 }
915
916 public static boolean isBoolean(@NotNull ClassDescriptor classDescriptor) {
917 return FQ_NAMES._boolean.equals(getFqName(classDescriptor));
918 }
919
920 public static boolean isChar(@NotNull KotlinType type) {
921 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._char);
922 }
923
924 public static boolean isInt(@NotNull KotlinType type) {
925 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._int);
926 }
927
928 public static boolean isByte(@NotNull KotlinType type) {
929 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._byte);
930 }
931
932 public static boolean isLong(@NotNull KotlinType type) {
933 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._long);
934 }
935
936 public static boolean isShort(@NotNull KotlinType type) {
937 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._short);
938 }
939
940 public static boolean isFloat(@NotNull KotlinType type) {
941 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._float);
942 }
943
944 public static boolean isDouble(@NotNull KotlinType type) {
945 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._double);
946 }
947
948 private static boolean isConstructedFromGivenClassAndNotNullable(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
949 return isConstructedFromGivenClass(type, fqName) && !type.isMarkedNullable();
950 }
951
952 public static boolean isAny(@NotNull FqNameUnsafe fqName) {
953 return FQ_NAMES.any.equals(fqName);
954 }
955
956 public static boolean isNothing(@NotNull KotlinType type) {
957 return isNothingOrNullableNothing(type)
958 && !type.isMarkedNullable();
959 }
960
961 public static boolean isNullableNothing(@NotNull KotlinType type) {
962 return isNothingOrNullableNothing(type)
963 && type.isMarkedNullable();
964 }
965
966 public static boolean isNothingOrNullableNothing(@NotNull KotlinType type) {
967 return isConstructedFromGivenClass(type, FQ_NAMES.nothing);
968 }
969
970 public static boolean isAnyOrNullableAny(@NotNull KotlinType type) {
971 return isConstructedFromGivenClass(type, FQ_NAMES.any);
972 }
973
974 public static boolean isNullableAny(@NotNull KotlinType type) {
975 return isAnyOrNullableAny(type) && type.isMarkedNullable();
976 }
977
978 public static boolean isDefaultBound(@NotNull KotlinType type) {
979 return isNullableAny(type);
980 }
981
982 public static boolean isUnit(@NotNull KotlinType type) {
983 return isNotNullConstructedFromGivenClass(type, FQ_NAMES.unit);
984 }
985
986 public boolean isBooleanOrSubtype(@NotNull KotlinType type) {
987 return KotlinTypeChecker.DEFAULT.isSubtypeOf(type, getBooleanType());
988 }
989
990 public boolean isMemberOfAny(@NotNull DeclarationDescriptor descriptor) {
991 return descriptor.getContainingDeclaration() == getAny();
992 }
993
994 public static boolean isString(@Nullable KotlinType type) {
995 return type != null && isNotNullConstructedFromGivenClass(type, FQ_NAMES.string);
996 }
997
998 public static boolean isCollectionOrNullableCollection(@NotNull KotlinType type) {
999 return isConstructedFromGivenClass(type, FQ_NAMES._collection);
1000 }
1001
1002 public static boolean isListOrNullableList(@NotNull KotlinType type) {
1003 return isConstructedFromGivenClass(type, FQ_NAMES._list);
1004 }
1005
1006 public static boolean isSetOrNullableSet(@NotNull KotlinType type) {
1007 return isConstructedFromGivenClass(type, FQ_NAMES._set);
1008 }
1009
1010 public static boolean isIterableOrNullableIterable(@NotNull KotlinType type) {
1011 return isConstructedFromGivenClass(type, FQ_NAMES._iterable);
1012 }
1013
1014 public static boolean isKClass(@NotNull ClassDescriptor descriptor) {
1015 return FQ_NAMES.kClass.equals(getFqName(descriptor));
1016 }
1017
1018 public static boolean isNonPrimitiveArray(@NotNull ClassDescriptor descriptor) {
1019 return FQ_NAMES.array.equals(getFqName(descriptor));
1020 }
1021
1022 public static boolean isCloneable(@NotNull ClassDescriptor descriptor) {
1023 return FQ_NAMES.cloneable.equals(getFqName(descriptor));
1024 }
1025
1026 public static boolean isDeprecated(@NotNull DeclarationDescriptor declarationDescriptor) {
1027 if (containsAnnotation(declarationDescriptor, FQ_NAMES.deprecated)) return true;
1028
1029 if (declarationDescriptor instanceof PropertyDescriptor) {
1030 boolean isVar = ((PropertyDescriptor) declarationDescriptor).isVar();
1031 PropertyGetterDescriptor getter = ((PropertyDescriptor) declarationDescriptor).getGetter();
1032 PropertySetterDescriptor setter = ((PropertyDescriptor) declarationDescriptor).getSetter();
1033 return getter != null && isDeprecated(getter) && (!isVar || setter != null && isDeprecated(setter));
1034 }
1035
1036 return false;
1037 }
1038
1039 public static boolean isSuppressAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) {
1040 return isConstructedFromGivenClass(annotationDescriptor.getType(), FQ_NAMES.suppress);
1041 }
1042
1043 private static boolean containsAnnotation(DeclarationDescriptor descriptor, FqName annotationClassFqName) {
1044 DeclarationDescriptor original = descriptor.getOriginal();
1045 Annotations annotations = original.getAnnotations();
1046
1047 if (annotations.findAnnotation(annotationClassFqName) != null) return true;
1048
1049 AnnotationUseSiteTarget associatedUseSiteTarget = AnnotationUseSiteTarget.Companion.getAssociatedUseSiteTarget(descriptor);
1050 if (associatedUseSiteTarget != null) {
1051 if (Annotations.Companion.findUseSiteTargetedAnnotation(annotations, associatedUseSiteTarget, annotationClassFqName) != null) {
1052 return true;
1053 }
1054 }
1055
1056 return false;
1057 }
1058
1059 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1060
1061 @NotNull
1062 public KotlinType getDefaultBound() {
1063 return getNullableAnyType();
1064 }
1065
1066 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1067
1068 // GET FUNCTION
1069
1070 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1071
1072 @NotNull
1073 public FunctionDescriptor getIdentityEquals() {
1074 return first(getBuiltInsPackageFragment().getMemberScope().getContributedFunctions(Name.identifier("identityEquals"),
1075 NoLookupLocation.FROM_BUILTINS));
1076 }
1077 }