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 }