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