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