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