001 /* 002 * Copyright 2010-2013 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.jet.lang.resolve; 018 019 import com.google.common.base.Predicate; 020 import com.google.common.collect.Lists; 021 import com.google.common.collect.Sets; 022 import org.jetbrains.annotations.NotNull; 023 import org.jetbrains.annotations.Nullable; 024 import org.jetbrains.jet.lang.descriptors.*; 025 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 026 import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; 027 import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorParent; 028 import org.jetbrains.jet.lang.psi.JetElement; 029 import org.jetbrains.jet.lang.psi.JetFunction; 030 import org.jetbrains.jet.lang.psi.JetParameter; 031 import org.jetbrains.jet.lang.psi.JetProperty; 032 import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; 033 import org.jetbrains.jet.lang.resolve.name.FqName; 034 import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; 035 import org.jetbrains.jet.lang.resolve.name.Name; 036 import org.jetbrains.jet.lang.resolve.scopes.FilteringScope; 037 import org.jetbrains.jet.lang.resolve.scopes.JetScope; 038 import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; 039 import org.jetbrains.jet.lang.types.*; 040 import org.jetbrains.jet.lang.types.checker.JetTypeChecker; 041 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; 042 import org.jetbrains.jet.renderer.DescriptorRenderer; 043 044 import java.util.*; 045 046 import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; 047 import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.DONT_CARE; 048 049 public class DescriptorUtils { 050 051 @NotNull 052 public static <D extends CallableDescriptor> D substituteBounds(@NotNull D functionDescriptor) { 053 List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters(); 054 if (typeParameters.isEmpty()) return functionDescriptor; 055 056 // TODO: this does not handle any recursion in the bounds 057 @SuppressWarnings("unchecked") 058 D substitutedFunction = (D) functionDescriptor.substitute(DescriptorSubstitutor.createUpperBoundsSubstitutor(typeParameters)); 059 assert substitutedFunction != null : "Substituting upper bounds should always be legal"; 060 061 return substitutedFunction; 062 } 063 064 public static Modality convertModality(Modality modality, boolean makeNonAbstract) { 065 if (makeNonAbstract && modality == Modality.ABSTRACT) return Modality.OPEN; 066 return modality; 067 } 068 069 @Nullable 070 public static ReceiverParameterDescriptor getExpectedThisObjectIfNeeded(@NotNull DeclarationDescriptor containingDeclaration) { 071 if (containingDeclaration instanceof ClassDescriptor) { 072 ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; 073 return classDescriptor.getThisAsReceiverParameter(); 074 } 075 else if (containingDeclaration instanceof ScriptDescriptor) { 076 ScriptDescriptor scriptDescriptor = (ScriptDescriptor) containingDeclaration; 077 return scriptDescriptor.getThisAsReceiverParameter(); 078 } 079 return NO_RECEIVER_PARAMETER; 080 } 081 082 /** 083 * The primary case for local extensions is the following: 084 * 085 * I had a locally declared extension function or a local variable of function type called foo 086 * And I called it on my x 087 * Now, someone added function foo() to the class of x 088 * My code should not change 089 * 090 * thus 091 * 092 * local extension prevail over members (and members prevail over all non-local extensions) 093 */ 094 public static boolean isLocal(DeclarationDescriptor containerOfTheCurrentLocality, DeclarationDescriptor candidate) { 095 if (candidate instanceof ValueParameterDescriptor) { 096 return true; 097 } 098 DeclarationDescriptor parent = candidate.getContainingDeclaration(); 099 if (!(parent instanceof FunctionDescriptor)) { 100 return false; 101 } 102 FunctionDescriptor functionDescriptor = (FunctionDescriptor) parent; 103 DeclarationDescriptor current = containerOfTheCurrentLocality; 104 while (current != null) { 105 if (current == functionDescriptor) { 106 return true; 107 } 108 current = current.getContainingDeclaration(); 109 } 110 return false; 111 } 112 113 @NotNull 114 public static FqNameUnsafe getFQName(@NotNull DeclarationDescriptor descriptor) { 115 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); 116 117 if (descriptor instanceof ModuleDescriptor || containingDeclaration instanceof ModuleDescriptor) { 118 return FqName.ROOT.toUnsafe(); 119 } 120 121 if (containingDeclaration == null) { 122 if (descriptor instanceof NamespaceDescriptor) { 123 // TODO: namespace must always have parent 124 if (descriptor.getName().equals(Name.identifier("jet"))) { 125 return FqNameUnsafe.topLevel(Name.identifier("jet")); 126 } 127 if (descriptor.getName().equals(Name.special("<java_root>"))) { 128 return FqName.ROOT.toUnsafe(); 129 } 130 } 131 throw new IllegalStateException("descriptor is not module descriptor and has null containingDeclaration: " + containingDeclaration); 132 } 133 134 if (containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.CLASS_OBJECT) { 135 DeclarationDescriptor classOfClassObject = containingDeclaration.getContainingDeclaration(); 136 assert classOfClassObject != null; 137 return getFQName(classOfClassObject).child(descriptor.getName()); 138 } 139 140 return getFQName(containingDeclaration).child(descriptor.getName()); 141 } 142 143 public static boolean isTopLevelDeclaration(@NotNull DeclarationDescriptor descriptor) { 144 return descriptor.getContainingDeclaration() instanceof NamespaceDescriptor; 145 } 146 147 public static boolean isInSameNamespace(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) { 148 NamespaceDescriptor whatPackage = DescriptorUtils.getParentOfType(first, NamespaceDescriptor.class, false); 149 NamespaceDescriptor fromPackage = DescriptorUtils.getParentOfType(second, NamespaceDescriptor.class, false); 150 return fromPackage != null && whatPackage != null && whatPackage.equals(fromPackage); 151 } 152 153 public static boolean isInSameModule(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) { 154 ModuleDescriptor parentModule = DescriptorUtils.getParentOfType(first, ModuleDescriptorImpl.class, false); 155 ModuleDescriptor fromModule = DescriptorUtils.getParentOfType(second, ModuleDescriptorImpl.class, false); 156 assert parentModule != null && fromModule != null; 157 return parentModule.equals(fromModule); 158 } 159 160 @Nullable 161 public static DeclarationDescriptor findTopLevelParent(@NotNull DeclarationDescriptor declarationDescriptor) { 162 DeclarationDescriptor descriptor = declarationDescriptor; 163 if (declarationDescriptor instanceof PropertyAccessorDescriptor) { 164 descriptor = ((PropertyAccessorDescriptor)descriptor).getCorrespondingProperty(); 165 } 166 while (!(descriptor == null || isTopLevelDeclaration(descriptor))) { 167 descriptor = descriptor.getContainingDeclaration(); 168 } 169 return descriptor; 170 } 171 172 @Nullable 173 public static <D extends DeclarationDescriptor> D getParentOfType(@Nullable DeclarationDescriptor descriptor, @NotNull Class<D> aClass) { 174 return getParentOfType(descriptor, aClass, true); 175 } 176 177 @Nullable 178 public static <D extends DeclarationDescriptor> D getParentOfType(@Nullable DeclarationDescriptor descriptor, @NotNull Class<D> aClass, boolean strict) { 179 if (descriptor == null) return null; 180 if (strict) { 181 descriptor = descriptor.getContainingDeclaration(); 182 } 183 while (descriptor != null) { 184 if (aClass.isInstance(descriptor)) { 185 //noinspection unchecked 186 return (D) descriptor; 187 } 188 descriptor = descriptor.getContainingDeclaration(); 189 } 190 return null; 191 } 192 193 public static boolean isAncestor(@Nullable DeclarationDescriptor ancestor, @NotNull DeclarationDescriptor declarationDescriptor, boolean strict) { 194 if (ancestor == null) return false; 195 DeclarationDescriptor descriptor = strict ? declarationDescriptor.getContainingDeclaration() : declarationDescriptor; 196 while (descriptor != null) { 197 if (ancestor == descriptor) return true; 198 descriptor = descriptor.getContainingDeclaration(); 199 } 200 return false; 201 } 202 203 @Nullable 204 public static VariableDescriptor filterNonExtensionProperty(Collection<VariableDescriptor> variables) { 205 for (VariableDescriptor variable : variables) { 206 if (variable.getReceiverParameter() == null) { 207 return variable; 208 } 209 } 210 return null; 211 } 212 213 @NotNull 214 public static JetType getFunctionExpectedReturnType(@NotNull FunctionDescriptor descriptor, @NotNull JetElement function) { 215 JetType expectedType; 216 if (function instanceof JetFunction) { 217 if (((JetFunction) function).getReturnTypeRef() != null || ((JetFunction) function).hasBlockBody()) { 218 expectedType = descriptor.getReturnType(); 219 } 220 else { 221 expectedType = TypeUtils.NO_EXPECTED_TYPE; 222 } 223 } 224 else { 225 expectedType = descriptor.getReturnType(); 226 } 227 return expectedType != null ? expectedType : TypeUtils.NO_EXPECTED_TYPE; 228 } 229 230 public static boolean isSubclass(@NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) { 231 return isSubtypeOfClass(subClass.getDefaultType(), superClass.getOriginal()); 232 } 233 234 private static boolean isSubtypeOfClass(@NotNull JetType type, @NotNull DeclarationDescriptor superClass) { 235 DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 236 if (descriptor != null && superClass == descriptor.getOriginal()) { 237 return true; 238 } 239 for (JetType superType : type.getConstructor().getSupertypes()) { 240 if (isSubtypeOfClass(superType, superClass)) { 241 return true; 242 } 243 } 244 return false; 245 } 246 247 public static void addSuperTypes(JetType type, Set<JetType> set) { 248 set.add(type); 249 250 for (JetType jetType : type.getConstructor().getSupertypes()) { 251 addSuperTypes(jetType, set); 252 } 253 } 254 255 public static boolean isRootNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { 256 return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor; 257 } 258 259 @NotNull 260 public static List<DeclarationDescriptor> getPathWithoutRootNsAndModule(@NotNull DeclarationDescriptor descriptor) { 261 List<DeclarationDescriptor> path = Lists.newArrayList(); 262 DeclarationDescriptor current = descriptor; 263 while (true) { 264 if (current instanceof NamespaceDescriptor && isRootNamespace((NamespaceDescriptor) current)) { 265 return Lists.reverse(path); 266 } 267 path.add(current); 268 current = current.getContainingDeclaration(); 269 } 270 } 271 272 public static boolean isFunctionLiteral(@NotNull FunctionDescriptor descriptor) { 273 return descriptor instanceof AnonymousFunctionDescriptor; 274 } 275 276 public static boolean isClassObject(@NotNull DeclarationDescriptor descriptor) { 277 return isKindOf(descriptor, ClassKind.CLASS_OBJECT); 278 } 279 280 public static boolean isAnonymous(@Nullable ClassifierDescriptor descriptor) { 281 return isKindOf(descriptor, ClassKind.OBJECT) && descriptor.getName().isSpecial(); 282 } 283 284 public static boolean isEnumEntry(@NotNull DeclarationDescriptor descriptor) { 285 return isKindOf(descriptor, ClassKind.ENUM_ENTRY); 286 } 287 288 public static boolean isEnumClass(@NotNull DeclarationDescriptor descriptor) { 289 return isKindOf(descriptor, ClassKind.ENUM_CLASS); 290 } 291 292 public static boolean isAnnotationClass(@Nullable DeclarationDescriptor descriptor) { 293 return isKindOf(descriptor, ClassKind.ANNOTATION_CLASS); 294 } 295 296 public static boolean isClass(@NotNull DeclarationDescriptor descriptor) { 297 return isKindOf(descriptor, ClassKind.CLASS); 298 } 299 300 public static boolean isKindOf(@NotNull JetType jetType, @NotNull ClassKind classKind) { 301 ClassifierDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); 302 return isKindOf(descriptor, classKind); 303 } 304 305 public static boolean isKindOf(@Nullable DeclarationDescriptor descriptor, @NotNull ClassKind classKind) { 306 if (descriptor instanceof ClassDescriptor) { 307 return ((ClassDescriptor) descriptor).getKind() == classKind; 308 } 309 return false; 310 } 311 312 @NotNull 313 public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) { 314 Collection<JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes(); 315 List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>(); 316 for (JetType type : superclassTypes) { 317 ClassDescriptor result = getClassDescriptorForType(type); 318 if (isNotAny(result)) { 319 superClassDescriptors.add(result); 320 } 321 } 322 return superClassDescriptors; 323 } 324 325 @NotNull 326 public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) { 327 DeclarationDescriptor superClassDescriptor = 328 type.getConstructor().getDeclarationDescriptor(); 329 assert superClassDescriptor instanceof ClassDescriptor 330 : "Superclass descriptor of a type should be of type ClassDescriptor"; 331 return (ClassDescriptor)superClassDescriptor; 332 } 333 334 public static boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) { 335 return !superClassDescriptor.equals(KotlinBuiltIns.getInstance().getAny()); 336 } 337 338 public static boolean inStaticContext(@NotNull DeclarationDescriptor descriptor) { 339 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); 340 if (containingDeclaration instanceof NamespaceDescriptor) { 341 return true; 342 } 343 if (containingDeclaration instanceof ClassDescriptor) { 344 ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; 345 346 if (classDescriptor.getKind().isObject()) { 347 return inStaticContext(classDescriptor.getContainingDeclaration()); 348 } 349 350 } 351 return false; 352 } 353 354 public static boolean isIteratorWithoutRemoveImpl(@NotNull ClassDescriptor classDescriptor) { 355 ClassDescriptor iteratorOfT = KotlinBuiltIns.getInstance().getIterator(); 356 JetType iteratorOfAny = TypeUtils.substituteParameters(iteratorOfT, Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType())); 357 boolean isIterator = JetTypeChecker.INSTANCE.isSubtypeOf(classDescriptor.getDefaultType(), iteratorOfAny); 358 boolean hasRemove = hasMethod(classDescriptor, Name.identifier("remove")); 359 return isIterator && !hasRemove; 360 } 361 362 private static boolean hasMethod(ClassDescriptor classDescriptor, Name name) { 363 Collection<FunctionDescriptor> removeFunctions = classDescriptor.getDefaultType().getMemberScope().getFunctions(name); 364 for (FunctionDescriptor function : removeFunctions) { 365 if (function.getValueParameters().isEmpty() && function.getTypeParameters().isEmpty()) { 366 return true; 367 } 368 } 369 return false; 370 } 371 372 @NotNull 373 public static Name getClassObjectName(@NotNull Name className) { 374 return getClassObjectName(className.asString()); 375 } 376 377 @NotNull 378 public static Name getClassObjectName(@NotNull String className) { 379 return Name.special("<class-object-for-" + className + ">"); 380 } 381 382 public static boolean isEnumClassObject(@NotNull DeclarationDescriptor descriptor) { 383 if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == ClassKind.CLASS_OBJECT) { 384 DeclarationDescriptor containing = descriptor.getContainingDeclaration(); 385 if ((containing instanceof ClassDescriptor) && ((ClassDescriptor) containing).getKind() == ClassKind.ENUM_CLASS) { 386 return true; 387 } 388 } 389 return false; 390 } 391 392 @NotNull 393 public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) { 394 ClassKind classKind = classDescriptor.getKind(); 395 if (classKind == ClassKind.ENUM_CLASS) { 396 return Visibilities.PRIVATE; 397 } 398 if (classKind.isObject()) { 399 return Visibilities.PRIVATE; 400 } 401 assert classKind == ClassKind.CLASS || classKind == ClassKind.TRAIT || classKind == ClassKind.ANNOTATION_CLASS; 402 return Visibilities.PUBLIC; 403 } 404 405 @NotNull 406 public static List<String> getSortedValueArguments( 407 @NotNull AnnotationDescriptor descriptor, 408 @Nullable DescriptorRenderer rendererForTypesIfNecessary 409 ) { 410 List<String> resultList = Lists.newArrayList(); 411 for (Map.Entry<ValueParameterDescriptor, CompileTimeConstant<?>> entry : descriptor.getAllValueArguments().entrySet()) { 412 CompileTimeConstant<?> value = entry.getValue(); 413 String typeSuffix = rendererForTypesIfNecessary == null 414 ? "" 415 : ": " + rendererForTypesIfNecessary.renderType(value.getType(KotlinBuiltIns.getInstance())); 416 resultList.add(entry.getKey().getName().asString() + " = " + value.toString() + typeSuffix); 417 } 418 Collections.sort(resultList); 419 return resultList; 420 } 421 422 @Nullable 423 public static ClassDescriptor getInnerClassByName(@NotNull ClassDescriptor classDescriptor, @NotNull String innerClassName) { 424 ClassifierDescriptor classifier = classDescriptor.getDefaultType().getMemberScope().getClassifier(Name.identifier(innerClassName)); 425 assert classifier instanceof ClassDescriptor : 426 "Inner class " + innerClassName + " in " + classDescriptor + " should be instance of ClassDescriptor, but was: " 427 + (classifier == null ? "null" : classifier.getClass()); 428 return (ClassDescriptor) classifier; 429 } 430 431 @NotNull 432 public static ConstructorDescriptor getConstructorOfDataClass(ClassDescriptor classDescriptor) { 433 ConstructorDescriptor descriptor = getConstructorDescriptorIfOnlyOne(classDescriptor); 434 assert descriptor != null : "Data class must have only one constructor: " + classDescriptor.getConstructors(); 435 return descriptor; 436 } 437 438 @NotNull 439 public static ConstructorDescriptor getConstructorOfSingletonObject(ClassDescriptor classDescriptor) { 440 ConstructorDescriptor descriptor = getConstructorDescriptorIfOnlyOne(classDescriptor); 441 assert descriptor != null : "Class of singleton object must have only one constructor: " + classDescriptor.getConstructors(); 442 return descriptor; 443 } 444 445 @Nullable 446 private static ConstructorDescriptor getConstructorDescriptorIfOnlyOne(ClassDescriptor classDescriptor) { 447 Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors(); 448 return constructors.size() != 1 ? null : constructors.iterator().next(); 449 } 450 451 @Nullable 452 public static JetType getReceiverParameterType(@Nullable ReceiverParameterDescriptor receiverParameterDescriptor) { 453 if (receiverParameterDescriptor == null) { 454 return null; 455 } 456 return receiverParameterDescriptor.getType(); 457 } 458 459 @NotNull 460 public static ReceiverValue safeGetValue(@Nullable ReceiverParameterDescriptor receiverParameterDescriptor) { 461 if (receiverParameterDescriptor == null) { 462 return ReceiverValue.NO_RECEIVER; 463 } 464 return receiverParameterDescriptor.getValue(); 465 } 466 467 468 public static boolean isExternallyAccessible(PropertyDescriptor propertyDescriptor) { 469 return propertyDescriptor.getVisibility() != Visibilities.PRIVATE || isClassObject(propertyDescriptor.getContainingDeclaration()) 470 || isTopLevelDeclaration(propertyDescriptor); 471 } 472 473 @NotNull 474 public static JetType getVarargParameterType(@NotNull JetType elementType) { 475 return getVarargParameterType(elementType, Variance.INVARIANT); 476 } 477 478 @NotNull 479 public static JetType getVarargParameterType(@NotNull JetType elementType, @NotNull Variance projectionKind) { 480 KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); 481 JetType primitiveArrayType = builtIns.getPrimitiveArrayJetTypeByPrimitiveJetType(elementType); 482 if (primitiveArrayType != null) { 483 return primitiveArrayType; 484 } 485 else { 486 return builtIns.getArrayType(projectionKind, elementType); 487 } 488 } 489 490 @NotNull 491 public static List<JetType> getValueParametersTypes(@NotNull List<ValueParameterDescriptor> valueParameters) { 492 List<JetType> parameterTypes = Lists.newArrayList(); 493 for (ValueParameterDescriptor parameter : valueParameters) { 494 parameterTypes.add(parameter.getType()); 495 } 496 return parameterTypes; 497 } 498 499 public static boolean isConstructorOfStaticNestedClass(@Nullable CallableDescriptor descriptor) { 500 return descriptor instanceof ConstructorDescriptor && isStaticNestedClass(descriptor.getContainingDeclaration()); 501 } 502 503 /** 504 * @return true if descriptor is a class inside another class and does not have access to the outer class 505 */ 506 public static boolean isStaticNestedClass(@NotNull DeclarationDescriptor descriptor) { 507 DeclarationDescriptor containing = descriptor.getContainingDeclaration(); 508 return descriptor instanceof ClassDescriptor && 509 containing instanceof ClassDescriptor && 510 !((ClassDescriptor) descriptor).isInner() && 511 !((ClassDescriptor) containing).getKind().isObject(); 512 } 513 514 @Nullable 515 public static ClassDescriptor getContainingClass(@NotNull JetScope scope) { 516 DeclarationDescriptor containingDeclaration = scope.getContainingDeclaration(); 517 return getParentOfType(containingDeclaration, ClassDescriptor.class, false); 518 } 519 520 @NotNull 521 public static JetScope getStaticNestedClassesScope(@NotNull ClassDescriptor descriptor) { 522 JetScope innerClassesScope = descriptor.getUnsubstitutedInnerClassesScope(); 523 return new FilteringScope(innerClassesScope, new Predicate<DeclarationDescriptor>() { 524 @Override 525 public boolean apply(@Nullable DeclarationDescriptor descriptor) { 526 return descriptor instanceof ClassDescriptor && !((ClassDescriptor) descriptor).isInner(); 527 } 528 }); 529 } 530 531 @Nullable 532 public static ClassDescriptor getClassForCorrespondingJavaNamespace(@NotNull NamespaceDescriptor correspondingNamespace) { 533 NamespaceDescriptorParent containingDeclaration = correspondingNamespace.getContainingDeclaration(); 534 if (!(containingDeclaration instanceof NamespaceDescriptor)) { 535 return null; 536 } 537 538 NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) containingDeclaration; 539 540 ClassifierDescriptor classDescriptor = namespaceDescriptor.getMemberScope().getClassifier(correspondingNamespace.getName()); 541 if (classDescriptor != null && classDescriptor instanceof ClassDescriptor) { 542 return (ClassDescriptor) classDescriptor; 543 } 544 545 ClassDescriptor classDescriptorForOuterClass = getClassForCorrespondingJavaNamespace(namespaceDescriptor); 546 if (classDescriptorForOuterClass == null) { 547 return null; 548 } 549 550 ClassifierDescriptor innerClassDescriptor = 551 classDescriptorForOuterClass.getUnsubstitutedInnerClassesScope().getClassifier(correspondingNamespace.getName()); 552 if (innerClassDescriptor instanceof ClassDescriptor) { 553 return (ClassDescriptor) innerClassDescriptor; 554 } 555 return null; 556 } 557 558 public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor functionDescriptor) { 559 List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters(); 560 JetType nullableString = TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getStringType()); 561 return "valueOf".equals(functionDescriptor.getName().asString()) 562 && methodTypeParameters.size() == 1 563 && JetTypeChecker.INSTANCE.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString); 564 } 565 566 public static boolean isEnumValuesMethod(@NotNull FunctionDescriptor functionDescriptor) { 567 List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters(); 568 return "values".equals(functionDescriptor.getName().asString()) 569 && methodTypeParameters.isEmpty(); 570 } 571 572 @NotNull 573 public static Set<ClassDescriptor> getAllSuperClasses(@NotNull ClassDescriptor klass) { 574 Set<JetType> allSupertypes = TypeUtils.getAllSupertypes(klass.getDefaultType()); 575 Set<ClassDescriptor> allSuperclasses = Sets.newHashSet(); 576 for (JetType supertype : allSupertypes) { 577 ClassDescriptor superclass = TypeUtils.getClassDescriptor(supertype); 578 assert superclass != null; 579 allSuperclasses.add(superclass); 580 } 581 return allSuperclasses; 582 } 583 584 @NotNull 585 public static PropertyDescriptor getPropertyDescriptor(@NotNull JetProperty property, @NotNull BindingContext bindingContext) { 586 VariableDescriptor descriptor = bindingContext.get(BindingContext.VARIABLE, property); 587 if (!(descriptor instanceof PropertyDescriptor)) { 588 throw new UnsupportedOperationException("expect a property to have a property descriptor"); 589 } 590 return (PropertyDescriptor) descriptor; 591 } 592 593 594 @NotNull 595 public static PropertyDescriptor getPropertyDescriptor(@NotNull JetParameter constructorParameter, @NotNull BindingContext bindingContext) { 596 assert constructorParameter.getValOrVarNode() != null; 597 PropertyDescriptor descriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, constructorParameter); 598 assert descriptor != null; 599 return descriptor; 600 } 601 }