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