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