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 != null) {
073                if (isAnonymousObject(current) || isDescriptorWithLocalVisibility(current)) {
074                    return true;
075                }
076                current = current.getContainingDeclaration();
077            }
078            return false;
079        }
080    
081        private 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        public static <D extends DeclarationDescriptor> D getParentOfType(
172                @Nullable DeclarationDescriptor descriptor,
173                @NotNull Class<D> aClass,
174                boolean strict
175        ) {
176            if (descriptor == null) return null;
177            if (strict) {
178                descriptor = descriptor.getContainingDeclaration();
179            }
180            while (descriptor != null) {
181                if (aClass.isInstance(descriptor)) {
182                    //noinspection unchecked
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            ModuleDescriptor moduleDescriptor = getParentOfType(descriptor, ModuleDescriptor.class, false);
200            if (moduleDescriptor != null) {
201                return moduleDescriptor;
202            }
203            PackageViewDescriptor packageViewDescriptor = getParentOfType(descriptor, PackageViewDescriptor.class, false);
204            if (packageViewDescriptor != null) {
205                return packageViewDescriptor.getModule();
206            }
207            return null;
208        }
209    
210        @Nullable
211        public static ClassDescriptor getContainingClass(@NotNull DeclarationDescriptor descriptor) {
212            DeclarationDescriptor containing = descriptor.getContainingDeclaration();
213            while (containing != null) {
214                if (containing instanceof ClassDescriptor && !isCompanionObject(containing)) {
215                    return (ClassDescriptor) containing;
216                }
217                containing = containing.getContainingDeclaration();
218            }
219            return null;
220        }
221    
222        public static boolean isAncestor(
223                @Nullable DeclarationDescriptor ancestor,
224                @NotNull DeclarationDescriptor declarationDescriptor,
225                boolean strict
226        ) {
227            if (ancestor == null) return false;
228            DeclarationDescriptor descriptor = strict ? declarationDescriptor.getContainingDeclaration() : declarationDescriptor;
229            while (descriptor != null) {
230                if (ancestor == descriptor) return true;
231                descriptor = descriptor.getContainingDeclaration();
232            }
233            return false;
234        }
235    
236        public static boolean isSubclass(@NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) {
237            return isSubtypeOfClass(subClass.getDefaultType(), superClass.getOriginal());
238        }
239    
240        private static boolean isSubtypeOfClass(@NotNull JetType type, @NotNull DeclarationDescriptor superClass) {
241            DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
242            if (descriptor != null) {
243                DeclarationDescriptor originalDescriptor = descriptor.getOriginal();
244                if (originalDescriptor instanceof ClassifierDescriptor
245                         && superClass instanceof ClassifierDescriptor
246                         && ((ClassifierDescriptor) superClass).getTypeConstructor().equals(((ClassifierDescriptor) originalDescriptor).getTypeConstructor())) {
247                    return true;
248                }
249            }
250    
251            for (JetType superType : type.getConstructor().getSupertypes()) {
252                if (isSubtypeOfClass(superType, superClass)) {
253                    return true;
254                }
255            }
256            return false;
257        }
258    
259        public static boolean isFunctionLiteral(@Nullable DeclarationDescriptor descriptor) {
260            return descriptor instanceof AnonymousFunctionDescriptor;
261        }
262    
263        public static boolean isLocalFunction(@Nullable DeclarationDescriptor descriptor) {
264            if (descriptor != null && descriptor.getClass() == SimpleFunctionDescriptorImpl.class) {
265                return ((SimpleFunctionDescriptorImpl) descriptor).getVisibility() == Visibilities.LOCAL;
266            }
267            return false;
268        }
269    
270        public static boolean isFunctionExpression(@Nullable DeclarationDescriptor descriptor) {
271            return descriptor instanceof FunctionExpressionDescriptor;
272        }
273    
274        public static boolean isCompanionObject(@Nullable DeclarationDescriptor descriptor) {
275            return isKindOf(descriptor, ClassKind.OBJECT) && ((ClassDescriptor) descriptor).isCompanionObject();
276        }
277    
278        public static boolean isAnonymousObject(@NotNull DeclarationDescriptor descriptor) {
279            return isClass(descriptor) && descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED);
280        }
281    
282        public static boolean isNonCompanionObject(@NotNull DeclarationDescriptor descriptor) {
283            return isKindOf(descriptor, ClassKind.OBJECT) && !((ClassDescriptor) descriptor).isCompanionObject();
284        }
285    
286        public static boolean isObject(@NotNull DeclarationDescriptor descriptor) {
287            return isKindOf(descriptor, ClassKind.OBJECT);
288        }
289    
290        public static boolean isEnumEntry(@NotNull DeclarationDescriptor descriptor) {
291            return isKindOf(descriptor, ClassKind.ENUM_ENTRY);
292        }
293    
294        public static boolean isSingleton(@Nullable DeclarationDescriptor classifier) {
295            if (classifier instanceof ClassDescriptor) {
296                ClassDescriptor clazz = (ClassDescriptor) classifier;
297                return clazz.getKind().isSingleton();
298            }
299            return false;
300        }
301    
302        public static boolean isEnumClass(@Nullable DeclarationDescriptor descriptor) {
303            return isKindOf(descriptor, ClassKind.ENUM_CLASS);
304        }
305    
306        public static boolean isAnnotationClass(@Nullable DeclarationDescriptor descriptor) {
307            return isKindOf(descriptor, ClassKind.ANNOTATION_CLASS);
308        }
309    
310        public static boolean isTrait(@Nullable DeclarationDescriptor descriptor) {
311            return isKindOf(descriptor, ClassKind.INTERFACE);
312        }
313    
314        public static boolean isClass(@Nullable DeclarationDescriptor descriptor) {
315            return isKindOf(descriptor, ClassKind.CLASS);
316        }
317    
318        private static boolean isKindOf(@Nullable DeclarationDescriptor descriptor, @NotNull ClassKind classKind) {
319            return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == classKind;
320        }
321    
322        @NotNull
323        public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
324            Collection<JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
325            List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
326            for (JetType type : superclassTypes) {
327                ClassDescriptor result = getClassDescriptorForType(type);
328                if (!isAny(result)) {
329                    superClassDescriptors.add(result);
330                }
331            }
332            return superClassDescriptors;
333        }
334    
335        @NotNull
336        public static JetType getSuperClassType(@NotNull ClassDescriptor classDescriptor) {
337            Collection<JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
338            for (JetType type : superclassTypes) {
339                ClassDescriptor superClassDescriptor = getClassDescriptorForType(type);
340                if (superClassDescriptor.getKind() != ClassKind.INTERFACE) {
341                    return type;
342                }
343            }
344            return getBuiltIns(classDescriptor).getAnyType();
345        }
346    
347        @NotNull
348        public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) {
349            return getClassDescriptorForTypeConstructor(type.getConstructor());
350        }
351    
352        @NotNull
353        public static ClassDescriptor getClassDescriptorForTypeConstructor(@NotNull TypeConstructor typeConstructor) {
354            ClassifierDescriptor descriptor = typeConstructor.getDeclarationDescriptor();
355            assert descriptor instanceof ClassDescriptor
356                : "Classifier descriptor of a type should be of type ClassDescriptor: " + typeConstructor;
357            return (ClassDescriptor) descriptor;
358        }
359    
360        @NotNull
361        public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) {
362            ClassKind classKind = classDescriptor.getKind();
363            if (classKind == ClassKind.ENUM_CLASS || classKind.isSingleton()) {
364                return Visibilities.PRIVATE;
365            }
366            if (isAnonymousObject(classDescriptor)) {
367                return Visibilities.INTERNAL;
368            }
369            assert classKind == ClassKind.CLASS || classKind == ClassKind.INTERFACE || classKind == ClassKind.ANNOTATION_CLASS;
370            return Visibilities.PUBLIC;
371        }
372    
373        @Nullable
374        public static ClassDescriptor getInnerClassByName(@NotNull ClassDescriptor classDescriptor, @NotNull String innerClassName) {
375            ClassifierDescriptor classifier = classDescriptor.getDefaultType().getMemberScope().getClassifier(Name.identifier(innerClassName));
376            assert classifier instanceof ClassDescriptor :
377                    "Inner class " + innerClassName + " in " + classDescriptor + " should be instance of ClassDescriptor, but was: "
378                    + (classifier == null ? "null" : classifier.getClass());
379            return (ClassDescriptor) classifier;
380        }
381    
382        @Nullable
383        public static JetType getReceiverParameterType(@Nullable ReceiverParameterDescriptor receiverParameterDescriptor) {
384            return receiverParameterDescriptor == null ? null : receiverParameterDescriptor.getType();
385        }
386    
387        /**
388         * @return true if descriptor is a class inside another class and does not have access to the outer class
389         */
390        public static boolean isStaticNestedClass(@NotNull DeclarationDescriptor descriptor) {
391            DeclarationDescriptor containing = descriptor.getContainingDeclaration();
392            return descriptor instanceof ClassDescriptor &&
393                   containing instanceof ClassDescriptor &&
394                   !((ClassDescriptor) descriptor).isInner();
395        }
396    
397        @NotNull
398        public static JetScope getStaticNestedClassesScope(@NotNull ClassDescriptor descriptor) {
399            JetScope innerClassesScope = descriptor.getUnsubstitutedInnerClassesScope();
400            return new FilteringScope(innerClassesScope, new Function1<DeclarationDescriptor, Boolean>() {
401                @Override
402                public Boolean invoke(DeclarationDescriptor descriptor) {
403                    return descriptor instanceof ClassDescriptor && !((ClassDescriptor) descriptor).isInner();
404                }
405            });
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        public static <D extends CallableMemberDescriptor> D unwrapFakeOverride(@NotNull D descriptor) {
424            while (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
425                Set<? extends CallableMemberDescriptor> overridden = descriptor.getOverriddenDescriptors();
426                if (overridden.isEmpty()) {
427                    throw new IllegalStateException("Fake override should have at least one overridden descriptor: " + descriptor);
428                }
429                //noinspection unchecked
430                descriptor = (D) overridden.iterator().next();
431            }
432            return descriptor;
433        }
434    
435        public static boolean shouldRecordInitializerForProperty(@NotNull VariableDescriptor variable, @NotNull JetType type) {
436            if (variable.isVar() || type.isError()) return false;
437    
438            if (type instanceof LazyType || type.isMarkedNullable()) return true;
439    
440            KotlinBuiltIns builtIns = getBuiltIns(variable);
441            return KotlinBuiltIns.isPrimitiveType(type) ||
442                   JetTypeChecker.DEFAULT.equalTypes(builtIns.getStringType(), type) ||
443                   JetTypeChecker.DEFAULT.equalTypes(builtIns.getNumber().getDefaultType(), type) ||
444                   JetTypeChecker.DEFAULT.equalTypes(builtIns.getAnyType(), type);
445        }
446    
447        public static boolean classCanHaveAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
448            return classDescriptor.getModality() == Modality.ABSTRACT || classDescriptor.getKind() == ClassKind.ENUM_CLASS;
449        }
450    
451        public static boolean classCanHaveOpenMembers(@NotNull ClassDescriptor classDescriptor) {
452            return classDescriptor.getModality() != Modality.FINAL || classDescriptor.getKind() == ClassKind.ENUM_CLASS;
453        }
454    
455        @NotNull
456        @SuppressWarnings("unchecked")
457        public static <D extends CallableDescriptor> Set<D> getAllOverriddenDescriptors(@NotNull D f) {
458            Set<D> result = new LinkedHashSet<D>();
459            collectAllOverriddenDescriptors((D) f.getOriginal(), result);
460            return result;
461        }
462    
463        private static <D extends CallableDescriptor> void collectAllOverriddenDescriptors(@NotNull D current, @NotNull Set<D> result) {
464            if (result.contains(current)) return;
465            for (CallableDescriptor callableDescriptor : current.getOriginal().getOverriddenDescriptors()) {
466                @SuppressWarnings("unchecked")
467                D descriptor = (D) callableDescriptor;
468                collectAllOverriddenDescriptors(descriptor, result);
469                result.add(descriptor);
470            }
471        }
472    
473        @NotNull
474        public static <D extends CallableMemberDescriptor> Set<D> getAllOverriddenDeclarations(@NotNull D memberDescriptor) {
475            Set<D> result = new HashSet<D>();
476            for (CallableMemberDescriptor overriddenDeclaration : memberDescriptor.getOverriddenDescriptors()) {
477                CallableMemberDescriptor.Kind kind = overriddenDeclaration.getKind();
478                if (kind == DECLARATION) {
479                    //noinspection unchecked
480                    result.add((D) overriddenDeclaration);
481                }
482                else if (kind == DELEGATION || kind == FAKE_OVERRIDE || kind == SYNTHESIZED) {
483                    //do nothing
484                }
485                else {
486                    throw new AssertionError("Unexpected callable kind " + kind);
487                }
488                //noinspection unchecked
489                result.addAll(getAllOverriddenDeclarations((D) overriddenDeclaration));
490            }
491            return result;
492        }
493    
494        public static boolean containsReifiedTypeParameterWithName(@NotNull CallableDescriptor descriptor, @NotNull String name) {
495            for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
496                if (typeParameterDescriptor.isReified() && typeParameterDescriptor.getName().asString().equals(name)) return true;
497            }
498    
499            return false;
500        }
501    
502        public static boolean containsReifiedTypeParameters(@NotNull CallableDescriptor descriptor) {
503            for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
504                if (typeParameterDescriptor.isReified()) return true;
505            }
506    
507            return false;
508        }
509    
510        public static boolean isSingletonOrAnonymousObject(@NotNull ClassDescriptor classDescriptor) {
511            return classDescriptor.getKind().isSingleton() || isAnonymousObject(classDescriptor);
512        }
513    
514        public static boolean canHaveDeclaredConstructors(@NotNull ClassDescriptor classDescriptor) {
515            return !isSingletonOrAnonymousObject(classDescriptor) && !isTrait(classDescriptor);
516        }
517    
518        public static Set<FqName> getPackagesFqNames(ModuleDescriptor module) {
519            Set<FqName> result = getSubPackagesFqNames(module.getPackage(FqName.ROOT));
520            result.add(FqName.ROOT);
521            return result;
522        }
523    
524        public static Set<FqName> getSubPackagesFqNames(PackageViewDescriptor packageView) {
525            Set<FqName> result = new HashSet<FqName>();
526            getSubPackagesFqNames(packageView, result);
527    
528            return result;
529        }
530    
531        private static void getSubPackagesFqNames(PackageViewDescriptor packageView, Set<FqName> result) {
532            FqName fqName = packageView.getFqName();
533            if (!fqName.isRoot()) {
534                result.add(fqName);
535            }
536    
537            for (DeclarationDescriptor descriptor : packageView.getMemberScope().getDescriptors(DescriptorKindFilter.PACKAGES, JetScope.ALL_NAME_FILTER)) {
538                if (descriptor instanceof PackageViewDescriptor) {
539                    getSubPackagesFqNames((PackageViewDescriptor) descriptor, result);
540                }
541            }
542        }
543    
544        public static boolean isJavaLangClass(ClassDescriptor descriptor) {
545            return "java.lang.Class".equals(getFqName(descriptor).asString());
546        }
547    }