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