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