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