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