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 }