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