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