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