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 }