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