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.resolve;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
022    import org.jetbrains.kotlin.descriptors.*;
023    import org.jetbrains.kotlin.descriptors.annotations.Annotated;
024    import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
025    import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget;
026    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
027    import org.jetbrains.kotlin.incremental.components.LookupLocation;
028    import org.jetbrains.kotlin.name.FqName;
029    import org.jetbrains.kotlin.name.FqNameUnsafe;
030    import org.jetbrains.kotlin.name.Name;
031    import org.jetbrains.kotlin.name.SpecialNames;
032    import org.jetbrains.kotlin.resolve.constants.ConstantValue;
033    import org.jetbrains.kotlin.resolve.constants.StringValue;
034    import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
035    import org.jetbrains.kotlin.resolve.scopes.MemberScope;
036    import org.jetbrains.kotlin.types.ErrorUtils;
037    import org.jetbrains.kotlin.types.KotlinType;
038    import org.jetbrains.kotlin.types.LazyType;
039    import org.jetbrains.kotlin.types.TypeConstructor;
040    import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
041    
042    import java.util.*;
043    
044    import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isAny;
045    import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.*;
046    import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getBuiltIns;
047    
048    public class DescriptorUtils {
049        public static final Name ENUM_VALUES = Name.identifier("values");
050        public static final Name ENUM_VALUE_OF = Name.identifier("valueOf");
051        public static final FqName JVM_NAME = new FqName("kotlin.jvm.JvmName");
052        public static final FqName VOLATILE = new FqName("kotlin.jvm.Volatile");
053        public static final FqName SYNCHRONIZED = new FqName("kotlin.jvm.Synchronized");
054    
055        private DescriptorUtils() {
056        }
057    
058        @Nullable
059        public static ReceiverParameterDescriptor getDispatchReceiverParameterIfNeeded(@NotNull DeclarationDescriptor containingDeclaration) {
060            if (containingDeclaration instanceof ClassDescriptor) {
061                ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
062                return classDescriptor.getThisAsReceiverParameter();
063            }
064            else if (containingDeclaration instanceof ScriptDescriptor) {
065                ScriptDescriptor scriptDescriptor = (ScriptDescriptor) containingDeclaration;
066                return scriptDescriptor.getThisAsReceiverParameter();
067            }
068            return null;
069        }
070    
071        /**
072         * Descriptor may be local itself or have a local ancestor
073         */
074        public static boolean isLocal(@NotNull DeclarationDescriptor descriptor) {
075            DeclarationDescriptor current = descriptor;
076            while (current != null) {
077                if (isAnonymousObject(current) || isDescriptorWithLocalVisibility(current)) {
078                    return true;
079                }
080                current = current.getContainingDeclaration();
081            }
082            return false;
083        }
084    
085        private static boolean isDescriptorWithLocalVisibility(DeclarationDescriptor current) {
086            return current instanceof DeclarationDescriptorWithVisibility &&
087             ((DeclarationDescriptorWithVisibility) current).getVisibility() == Visibilities.LOCAL;
088        }
089    
090        @NotNull
091        public static FqNameUnsafe getFqName(@NotNull DeclarationDescriptor descriptor) {
092            FqName safe = getFqNameSafeIfPossible(descriptor);
093            return safe != null ? safe.toUnsafe() : getFqNameUnsafe(descriptor);
094        }
095    
096        @NotNull
097        public static FqName getFqNameSafe(@NotNull DeclarationDescriptor descriptor) {
098            FqName safe = getFqNameSafeIfPossible(descriptor);
099            return safe != null ? safe : getFqNameUnsafe(descriptor).toSafe();
100        }
101    
102    
103        @Nullable
104        private static FqName getFqNameSafeIfPossible(@NotNull DeclarationDescriptor descriptor) {
105            if (descriptor instanceof ModuleDescriptor || ErrorUtils.isError(descriptor)) {
106                return FqName.ROOT;
107            }
108    
109            if (descriptor instanceof PackageViewDescriptor) {
110                return ((PackageViewDescriptor) descriptor).getFqName();
111            }
112            else if (descriptor instanceof PackageFragmentDescriptor) {
113                return ((PackageFragmentDescriptor) descriptor).getFqName();
114            }
115    
116            return null;
117        }
118    
119        @NotNull
120        private static FqNameUnsafe getFqNameUnsafe(@NotNull DeclarationDescriptor descriptor) {
121            DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
122            assert containingDeclaration != null : "Not package/module descriptor doesn't have containing declaration: " + descriptor;
123            return getFqName(containingDeclaration).child(descriptor.getName());
124        }
125    
126        @NotNull
127        public static FqName getFqNameFromTopLevelClass(@NotNull DeclarationDescriptor descriptor) {
128            DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
129            Name name = descriptor.getName();
130            if (!(containingDeclaration instanceof ClassDescriptor)) {
131                return FqName.topLevel(name);
132            }
133            return getFqNameFromTopLevelClass(containingDeclaration).child(name);
134        }
135    
136        public static boolean isTopLevelDeclaration(@NotNull DeclarationDescriptor descriptor) {
137            return descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor;
138        }
139    
140        public static boolean isExtension(@NotNull CallableDescriptor descriptor) {
141            return (descriptor.getExtensionReceiverParameter() != null);
142        }
143    
144        public static boolean isOverride(@NotNull CallableMemberDescriptor descriptor) {
145            return !descriptor.getOverriddenDescriptors().isEmpty();
146        }
147    
148        /**
149         * @return true iff this is a top-level declaration or a class member with no expected "this" object (e.g. static members in Java,
150         * values() and valueOf() methods of enum classes, etc.)
151         */
152        public static boolean isStaticDeclaration(@NotNull CallableDescriptor descriptor) {
153            if (descriptor instanceof ConstructorDescriptor) return false;
154    
155            DeclarationDescriptor container = descriptor.getContainingDeclaration();
156            return container instanceof PackageFragmentDescriptor ||
157                   (container instanceof ClassDescriptor && descriptor.getDispatchReceiverParameter() == null);
158        }
159    
160        // WARNING! Don't use this method in JVM backend, use JvmCodegenUtil.isCallInsideSameModuleAsDeclared() instead.
161        // The latter handles compilation against compiled part of our module correctly.
162        public static boolean areInSameModule(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) {
163            return getContainingModule(first).equals(getContainingModule(second));
164        }
165    
166        @Nullable
167        public static <D extends DeclarationDescriptor> D getParentOfType(
168                @Nullable DeclarationDescriptor descriptor,
169                @NotNull Class<D> aClass
170        ) {
171            return getParentOfType(descriptor, aClass, true);
172        }
173    
174        @Nullable
175        public static <D extends DeclarationDescriptor> D getParentOfType(
176                @Nullable DeclarationDescriptor descriptor,
177                @NotNull Class<D> aClass,
178                boolean strict
179        ) {
180            if (descriptor == null) return null;
181            if (strict) {
182                descriptor = descriptor.getContainingDeclaration();
183            }
184            while (descriptor != null) {
185                if (aClass.isInstance(descriptor)) {
186                    //noinspection unchecked
187                    return (D) descriptor;
188                }
189                descriptor = descriptor.getContainingDeclaration();
190            }
191            return null;
192        }
193    
194        @NotNull
195        public static ModuleDescriptor getContainingModule(@NotNull DeclarationDescriptor descriptor) {
196            ModuleDescriptor module = getContainingModuleOrNull(descriptor);
197            assert module != null : "Descriptor without a containing module: " + descriptor;
198            return module;
199        }
200    
201        @Nullable
202        public static ModuleDescriptor getContainingModuleOrNull(@NotNull DeclarationDescriptor descriptor) {
203            while (descriptor != null) {
204                if (descriptor instanceof ModuleDescriptor) {
205                    return (ModuleDescriptor) descriptor;
206                }
207                if (descriptor instanceof PackageViewDescriptor) {
208                    return ((PackageViewDescriptor) descriptor).getModule();
209                }
210                //noinspection ConstantConditions
211                descriptor = descriptor.getContainingDeclaration();
212            }
213            return null;
214        }
215    
216        @Nullable
217        public static ClassDescriptor getContainingClass(@NotNull DeclarationDescriptor descriptor) {
218            DeclarationDescriptor containing = descriptor.getContainingDeclaration();
219            while (containing != null) {
220                if (containing instanceof ClassDescriptor && !isCompanionObject(containing)) {
221                    return (ClassDescriptor) containing;
222                }
223                containing = containing.getContainingDeclaration();
224            }
225            return null;
226        }
227    
228        public static boolean isAncestor(
229                @Nullable DeclarationDescriptor ancestor,
230                @NotNull DeclarationDescriptor declarationDescriptor,
231                boolean strict
232        ) {
233            if (ancestor == null) return false;
234            DeclarationDescriptor descriptor = strict ? declarationDescriptor.getContainingDeclaration() : declarationDescriptor;
235            while (descriptor != null) {
236                if (ancestor == descriptor) return true;
237                descriptor = descriptor.getContainingDeclaration();
238            }
239            return false;
240        }
241    
242        public static boolean isDirectSubclass(@NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) {
243            for (KotlinType superType : subClass.getTypeConstructor().getSupertypes()) {
244                if (isSameClass(superType, superClass.getOriginal())) {
245                    return true;
246                }
247            }
248            return false;
249        }
250    
251        public static boolean isSubclass(@NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) {
252            return isSubtypeOfClass(subClass.getDefaultType(), superClass.getOriginal());
253        }
254    
255        private static boolean isSameClass(@NotNull KotlinType type, @NotNull DeclarationDescriptor other) {
256            DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
257            if (descriptor != null) {
258                DeclarationDescriptor originalDescriptor = descriptor.getOriginal();
259                if (originalDescriptor instanceof ClassifierDescriptor
260                    && other instanceof ClassifierDescriptor
261                    && ((ClassifierDescriptor) other).getTypeConstructor().equals(
262                        ((ClassifierDescriptor) originalDescriptor).getTypeConstructor())) {
263                    return true;
264                }
265            }
266            return false;
267        }
268    
269        private static boolean isSubtypeOfClass(@NotNull KotlinType type, @NotNull DeclarationDescriptor superClass) {
270            if (isSameClass(type, superClass)) return true;
271            for (KotlinType superType : type.getConstructor().getSupertypes()) {
272                if (isSubtypeOfClass(superType, superClass)) {
273                    return true;
274                }
275            }
276            return false;
277        }
278    
279        public static boolean isCompanionObject(@Nullable DeclarationDescriptor descriptor) {
280            return isKindOf(descriptor, ClassKind.OBJECT) && ((ClassDescriptor) descriptor).isCompanionObject();
281        }
282    
283        public static boolean isAnonymousObject(@NotNull DeclarationDescriptor descriptor) {
284            return isClass(descriptor) && descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED);
285        }
286    
287        public static boolean isNonCompanionObject(@NotNull DeclarationDescriptor descriptor) {
288            return isKindOf(descriptor, ClassKind.OBJECT) && !((ClassDescriptor) descriptor).isCompanionObject();
289        }
290    
291        public static boolean isObject(@NotNull DeclarationDescriptor descriptor) {
292            return isKindOf(descriptor, ClassKind.OBJECT);
293        }
294    
295        public static boolean isEnumEntry(@NotNull DeclarationDescriptor descriptor) {
296            return isKindOf(descriptor, ClassKind.ENUM_ENTRY);
297        }
298    
299        public static boolean isEnumClass(@Nullable DeclarationDescriptor descriptor) {
300            return isKindOf(descriptor, ClassKind.ENUM_CLASS);
301        }
302    
303        public static boolean isAnnotationClass(@Nullable DeclarationDescriptor descriptor) {
304            return isKindOf(descriptor, ClassKind.ANNOTATION_CLASS);
305        }
306    
307        public static boolean isInterface(@Nullable DeclarationDescriptor descriptor) {
308            return isKindOf(descriptor, ClassKind.INTERFACE);
309        }
310    
311        public static boolean isClass(@Nullable DeclarationDescriptor descriptor) {
312            return isKindOf(descriptor, ClassKind.CLASS);
313        }
314    
315        public static boolean isClassOrEnumClass(@Nullable DeclarationDescriptor descriptor) {
316            return isClass(descriptor) || isEnumClass(descriptor);
317        }
318    
319        private static boolean isKindOf(@Nullable DeclarationDescriptor descriptor, @NotNull ClassKind classKind) {
320            return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == classKind;
321        }
322    
323        @NotNull
324        public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
325            Collection<KotlinType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
326            List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
327            for (KotlinType type : superclassTypes) {
328                ClassDescriptor result = getClassDescriptorForType(type);
329                if (!isAny(result)) {
330                    superClassDescriptors.add(result);
331                }
332            }
333            return superClassDescriptors;
334        }
335    
336        @NotNull
337        public static KotlinType getSuperClassType(@NotNull ClassDescriptor classDescriptor) {
338            Collection<KotlinType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
339            for (KotlinType type : superclassTypes) {
340                ClassDescriptor superClassDescriptor = getClassDescriptorForType(type);
341                if (superClassDescriptor.getKind() != ClassKind.INTERFACE) {
342                    return type;
343                }
344            }
345            return getBuiltIns(classDescriptor).getAnyType();
346        }
347    
348        @Nullable
349        public static ClassDescriptor getSuperClassDescriptor(@NotNull ClassDescriptor classDescriptor) {
350            Collection<KotlinType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
351            for (KotlinType type : superclassTypes) {
352                ClassDescriptor superClassDescriptor = getClassDescriptorForType(type);
353                if (superClassDescriptor.getKind() != ClassKind.INTERFACE) {
354                    return superClassDescriptor;
355                }
356            }
357            return null;
358        }
359    
360        @NotNull
361        public static ClassDescriptor getClassDescriptorForType(@NotNull KotlinType type) {
362            return getClassDescriptorForTypeConstructor(type.getConstructor());
363        }
364    
365        @NotNull
366        public static ClassDescriptor getClassDescriptorForTypeConstructor(@NotNull TypeConstructor typeConstructor) {
367            ClassifierDescriptor descriptor = typeConstructor.getDeclarationDescriptor();
368            assert descriptor instanceof ClassDescriptor
369                : "Classifier descriptor of a type should be of type ClassDescriptor: " + typeConstructor;
370            return (ClassDescriptor) descriptor;
371        }
372    
373        @NotNull
374        public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) {
375            ClassKind classKind = classDescriptor.getKind();
376            if (classKind == ClassKind.ENUM_CLASS || classKind.isSingleton() || classDescriptor.getModality() == Modality.SEALED) {
377                return Visibilities.PRIVATE;
378            }
379            if (isAnonymousObject(classDescriptor)) {
380                return Visibilities.DEFAULT_VISIBILITY;
381            }
382            assert classKind == ClassKind.CLASS || classKind == ClassKind.INTERFACE || classKind == ClassKind.ANNOTATION_CLASS;
383            return Visibilities.PUBLIC;
384        }
385    
386        // TODO: should be internal
387        @Nullable
388        public static ClassDescriptor getInnerClassByName(@NotNull ClassDescriptor classDescriptor, @NotNull String innerClassName, @NotNull LookupLocation location) {
389            ClassifierDescriptor classifier =
390                    classDescriptor.getDefaultType().getMemberScope().getContributedClassifier(Name.identifier(innerClassName), location);
391            assert classifier instanceof ClassDescriptor :
392                    "Inner class " + innerClassName + " in " + classDescriptor + " should be instance of ClassDescriptor, but was: "
393                    + (classifier == null ? "null" : classifier.getClass());
394            return (ClassDescriptor) classifier;
395        }
396    
397        @Nullable
398        public static KotlinType getReceiverParameterType(@Nullable ReceiverParameterDescriptor receiverParameterDescriptor) {
399            return receiverParameterDescriptor == null ? null : receiverParameterDescriptor.getType();
400        }
401    
402        /**
403         * @return true if descriptor is a class inside another class and does not have access to the outer class
404         */
405        public static boolean isStaticNestedClass(@NotNull DeclarationDescriptor descriptor) {
406            DeclarationDescriptor containing = descriptor.getContainingDeclaration();
407            return descriptor instanceof ClassDescriptor &&
408                   containing instanceof ClassDescriptor &&
409                   !((ClassDescriptor) descriptor).isInner();
410        }
411    
412        /**
413         * @return true iff {@code descriptor}'s first non-class container is a package
414         */
415        public static boolean isTopLevelOrInnerClass(@NotNull ClassDescriptor descriptor) {
416            DeclarationDescriptor containing = descriptor.getContainingDeclaration();
417            return isTopLevelDeclaration(descriptor) ||
418                   containing instanceof ClassDescriptor && isTopLevelOrInnerClass((ClassDescriptor) containing);
419        }
420    
421        /**
422         * Given a fake override, finds any declaration of it in the overridden descriptors. Keep in mind that there may be many declarations
423         * of the fake override in the supertypes, this method finds just the only one.
424         * TODO: probably all call-sites of this method are wrong, they should handle all super-declarations
425         */
426        @NotNull
427        public static <D extends CallableMemberDescriptor> D unwrapFakeOverride(@NotNull D descriptor) {
428            while (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
429                Collection<? extends CallableMemberDescriptor> overridden = descriptor.getOverriddenDescriptors();
430                if (overridden.isEmpty()) {
431                    throw new IllegalStateException("Fake override should have at least one overridden descriptor: " + descriptor);
432                }
433                //noinspection unchecked
434                descriptor = (D) overridden.iterator().next();
435            }
436            return descriptor;
437        }
438    
439        public static boolean shouldRecordInitializerForProperty(@NotNull VariableDescriptor variable, @NotNull KotlinType type) {
440            if (variable.isVar() || type.isError()) return false;
441    
442            if (type instanceof LazyType || type.isMarkedNullable()) return true;
443    
444            KotlinBuiltIns builtIns = getBuiltIns(variable);
445            return KotlinBuiltIns.isPrimitiveType(type) ||
446                   KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getStringType(), type) ||
447                   KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getNumber().getDefaultType(), type) ||
448                   KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getAnyType(), type);
449        }
450    
451        public static boolean classCanHaveAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
452            return classDescriptor.getModality() == Modality.ABSTRACT
453                   || classDescriptor.getModality() == Modality.SEALED
454                   || classDescriptor.getKind() == ClassKind.ENUM_CLASS;
455        }
456    
457        public static boolean classCanHaveOpenMembers(@NotNull ClassDescriptor classDescriptor) {
458            return classDescriptor.getModality() != Modality.FINAL || classDescriptor.getKind() == ClassKind.ENUM_CLASS;
459        }
460    
461        @NotNull
462        @SuppressWarnings("unchecked")
463        public static <D extends CallableDescriptor> Set<D> getAllOverriddenDescriptors(@NotNull D f) {
464            Set<D> result = new LinkedHashSet<D>();
465            collectAllOverriddenDescriptors((D) f.getOriginal(), result);
466            return result;
467        }
468    
469        private static <D extends CallableDescriptor> void collectAllOverriddenDescriptors(@NotNull D current, @NotNull Set<D> result) {
470            if (result.contains(current)) return;
471            for (CallableDescriptor callableDescriptor : current.getOriginal().getOverriddenDescriptors()) {
472                @SuppressWarnings("unchecked")
473                D descriptor = (D) callableDescriptor;
474                collectAllOverriddenDescriptors(descriptor, result);
475                result.add(descriptor);
476            }
477        }
478    
479        @NotNull
480        public static <D extends CallableMemberDescriptor> Set<D> getAllOverriddenDeclarations(@NotNull D memberDescriptor) {
481            Set<D> result = new HashSet<D>();
482            for (CallableMemberDescriptor overriddenDeclaration : memberDescriptor.getOverriddenDescriptors()) {
483                CallableMemberDescriptor.Kind kind = overriddenDeclaration.getKind();
484                if (kind == DECLARATION) {
485                    //noinspection unchecked
486                    result.add((D) overriddenDeclaration);
487                }
488                else if (kind == DELEGATION || kind == FAKE_OVERRIDE || kind == SYNTHESIZED) {
489                    //do nothing
490                }
491                else {
492                    throw new AssertionError("Unexpected callable kind " + kind);
493                }
494                //noinspection unchecked
495                result.addAll(getAllOverriddenDeclarations((D) overriddenDeclaration));
496            }
497            return result;
498        }
499    
500        public static boolean isSingletonOrAnonymousObject(@NotNull ClassDescriptor classDescriptor) {
501            return classDescriptor.getKind().isSingleton() || isAnonymousObject(classDescriptor);
502        }
503    
504        public static boolean canHaveDeclaredConstructors(@NotNull ClassDescriptor classDescriptor) {
505            return !isSingletonOrAnonymousObject(classDescriptor) && !isInterface(classDescriptor);
506        }
507    
508        @Nullable
509        public static String getJvmName(@NotNull Annotated annotated) {
510            AnnotationDescriptor jvmNameAnnotation = getAnnotationByFqName(annotated.getAnnotations(), JVM_NAME);
511            if (jvmNameAnnotation == null) return null;
512    
513            Map<ValueParameterDescriptor, ConstantValue<?>> arguments = jvmNameAnnotation.getAllValueArguments();
514            if (arguments.isEmpty()) return null;
515    
516            ConstantValue<?> name = arguments.values().iterator().next();
517            if (!(name instanceof StringValue)) return null;
518    
519            return ((StringValue) name).getValue();
520        }
521    
522        @Nullable
523        public static AnnotationDescriptor getAnnotationByFqName(@NotNull Annotations annotations, @NotNull FqName name) {
524            AnnotationWithTarget annotationWithTarget = Annotations.Companion.findAnyAnnotation(annotations, name);
525            return annotationWithTarget == null ? null : annotationWithTarget.getAnnotation();
526        }
527    
528        @Nullable
529        public static AnnotationDescriptor getJvmNameAnnotation(@NotNull Annotated annotated) {
530            return getAnnotationByFqName(annotated.getAnnotations(), JVM_NAME);
531        }
532    
533        @Nullable
534        public static AnnotationDescriptor getVolatileAnnotation(@NotNull Annotated annotated) {
535            return getAnnotationByFqName(annotated.getAnnotations(), VOLATILE);
536        }
537    
538        @Nullable
539        public static AnnotationDescriptor getSynchronizedAnnotation(@NotNull Annotated annotated) {
540            return getAnnotationByFqName(annotated.getAnnotations(), SYNCHRONIZED);
541        }
542    
543        @NotNull
544        public static SourceFile getContainingSourceFile(@NotNull DeclarationDescriptor descriptor) {
545            if (descriptor instanceof PropertySetterDescriptor) {
546                descriptor = ((PropertySetterDescriptor) descriptor).getCorrespondingProperty();
547            }
548    
549            if (descriptor instanceof DeclarationDescriptorWithSource) {
550                return ((DeclarationDescriptorWithSource) descriptor).getSource().getContainingFile();
551            }
552    
553            return SourceFile.NO_SOURCE_FILE;
554        }
555    
556        @NotNull
557        public static Collection<DeclarationDescriptor> getAllDescriptors(@NotNull MemberScope scope) {
558            return scope.getContributedDescriptors(DescriptorKindFilter.ALL, MemberScope.Companion.getALL_NAME_FILTER());
559        }
560    }