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.lazy.descriptors;
018
019 import com.google.common.base.Predicate;
020 import com.google.common.collect.Collections2;
021 import com.google.common.collect.Lists;
022 import com.intellij.psi.PsiElement;
023 import com.intellij.psi.PsiNameIdentifierOwner;
024 import kotlin.collections.CollectionsKt;
025 import kotlin.jvm.functions.Function0;
026 import kotlin.jvm.functions.Function1;
027 import org.jetbrains.annotations.NotNull;
028 import org.jetbrains.annotations.Nullable;
029 import org.jetbrains.annotations.ReadOnly;
030 import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
031 import org.jetbrains.kotlin.descriptors.*;
032 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
033 import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
034 import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
035 import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
036 import org.jetbrains.kotlin.lexer.KtTokens;
037 import org.jetbrains.kotlin.name.Name;
038 import org.jetbrains.kotlin.psi.*;
039 import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
040 import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
041 import org.jetbrains.kotlin.resolve.*;
042 import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
043 import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
044 import org.jetbrains.kotlin.resolve.lazy.LazyClassContext;
045 import org.jetbrains.kotlin.resolve.lazy.LazyEntity;
046 import org.jetbrains.kotlin.resolve.lazy.data.KtClassInfoUtil;
047 import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo;
048 import org.jetbrains.kotlin.resolve.lazy.data.KtClassOrObjectInfo;
049 import org.jetbrains.kotlin.resolve.lazy.data.KtObjectInfo;
050 import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider;
051 import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
052 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
053 import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum;
054 import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
055 import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull;
056 import org.jetbrains.kotlin.storage.NotNullLazyValue;
057 import org.jetbrains.kotlin.storage.NullableLazyValue;
058 import org.jetbrains.kotlin.storage.StorageManager;
059 import org.jetbrains.kotlin.types.AbstractClassTypeConstructor;
060 import org.jetbrains.kotlin.types.KotlinType;
061 import org.jetbrains.kotlin.types.TypeConstructor;
062 import org.jetbrains.kotlin.types.TypeUtils;
063
064 import java.util.ArrayList;
065 import java.util.Collection;
066 import java.util.Collections;
067 import java.util.List;
068
069 import static kotlin.collections.CollectionsKt.firstOrNull;
070 import static org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC;
071 import static org.jetbrains.kotlin.diagnostics.Errors.CYCLIC_INHERITANCE_HIERARCHY;
072 import static org.jetbrains.kotlin.diagnostics.Errors.TYPE_PARAMETERS_IN_ENUM;
073 import static org.jetbrains.kotlin.resolve.BindingContext.TYPE;
074 import static org.jetbrains.kotlin.resolve.ModifiersChecker.*;
075
076 public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDescriptorWithResolutionScopes, LazyEntity {
077 private static final Predicate<KotlinType> VALID_SUPERTYPE = new Predicate<KotlinType>() {
078 @Override
079 public boolean apply(KotlinType type) {
080 assert !type.isError() : "Error types must be filtered out in DescriptorResolver";
081 return TypeUtils.getClassDescriptor(type) != null;
082 }
083 };
084 private final LazyClassContext c;
085
086 @Nullable // can be null in KtScript
087 private final KtClassOrObject classOrObject;
088
089 private final ClassMemberDeclarationProvider declarationProvider;
090
091 private final LazyClassTypeConstructor typeConstructor;
092 private final NotNullLazyValue<Modality> modality;
093 private final Visibility visibility;
094 private final ClassKind kind;
095 private final boolean isInner;
096 private final boolean isData;
097 private final boolean isHeader;
098 private final boolean isImpl;
099
100 private final Annotations annotations;
101 private final Annotations danglingAnnotations;
102 private final NullableLazyValue<ClassDescriptorWithResolutionScopes> companionObjectDescriptor;
103 private final MemoizedFunctionToNotNull<KtObjectDeclaration, ClassDescriptor> extraCompanionObjectDescriptors;
104
105 private final LazyClassMemberScope unsubstitutedMemberScope;
106 private final MemberScope staticScope;
107
108 private final NullableLazyValue<Void> forceResolveAllContents;
109 private final boolean isCompanionObject;
110
111 private final ClassResolutionScopesSupport resolutionScopesSupport;
112 private final NotNullLazyValue<List<TypeParameterDescriptor>> parameters;
113
114 private final NotNullLazyValue<LexicalScope> scopeForInitializerResolution;
115
116 private final NotNullLazyValue<Collection<ClassDescriptor>> sealedSubclasses;
117
118 public LazyClassDescriptor(
119 @NotNull final LazyClassContext c,
120 @NotNull DeclarationDescriptor containingDeclaration,
121 @NotNull Name name,
122 @NotNull final KtClassLikeInfo classLikeInfo,
123 boolean isExternal
124 ) {
125 super(c.getStorageManager(), containingDeclaration, name,
126 KotlinSourceElementKt.toSourceElement(classLikeInfo.getCorrespondingClassOrObject()),
127 isExternal
128 );
129 this.c = c;
130
131 classOrObject = classLikeInfo.getCorrespondingClassOrObject();
132 if (classOrObject != null) {
133 this.c.getTrace().record(BindingContext.CLASS, classOrObject, this);
134 }
135 this.c.getTrace().record(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, DescriptorUtils.getFqName(this), this);
136
137 this.declarationProvider = c.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classLikeInfo);
138
139 StorageManager storageManager = c.getStorageManager();
140
141 this.unsubstitutedMemberScope = createMemberScope(c, this.declarationProvider);
142 this.kind = classLikeInfo.getClassKind();
143 this.staticScope = kind == ClassKind.ENUM_CLASS ? new StaticScopeForKotlinEnum(storageManager, this) : MemberScope.Empty.INSTANCE;
144
145 this.typeConstructor = new LazyClassTypeConstructor();
146
147 this.isCompanionObject = classLikeInfo instanceof KtObjectInfo && ((KtObjectInfo) classLikeInfo).isCompanionObject();
148
149 final KtModifierList modifierList = classLikeInfo.getModifierList();
150 if (kind.isSingleton()) {
151 this.modality = storageManager.createLazyValue(new Function0<Modality>() {
152 @Override
153 public Modality invoke() {
154 return Modality.FINAL;
155 }
156 });
157 }
158 else {
159 final Modality defaultModality = kind == ClassKind.INTERFACE ? Modality.ABSTRACT : Modality.FINAL;
160 this.modality = storageManager.createLazyValue(new Function0<Modality>() {
161 @Override
162 public Modality invoke() {
163 return resolveModalityFromModifiers(classOrObject, defaultModality,
164 c.getTrace().getBindingContext(),
165 null,
166 /* allowSealed = */ true);
167 }
168 });
169 }
170
171 boolean isLocal = classOrObject != null && KtPsiUtil.isLocal(classOrObject);
172 Visibility defaultVisibility;
173 if (kind == ClassKind.ENUM_ENTRY || (kind == ClassKind.OBJECT && isCompanionObject)) {
174 defaultVisibility = Visibilities.PUBLIC;
175 }
176 else {
177 defaultVisibility = Visibilities.DEFAULT_VISIBILITY;
178 }
179 this.visibility = isLocal ? Visibilities.LOCAL : resolveVisibilityFromModifiers(modifierList, defaultVisibility);
180
181 this.isInner = isInnerClass(modifierList) && !ModifiersChecker.isIllegalInner(this);
182 this.isData = modifierList != null && modifierList.hasModifier(KtTokens.DATA_KEYWORD);
183 this.isHeader = modifierList != null && modifierList.hasModifier(KtTokens.HEADER_KEYWORD);
184 this.isImpl = modifierList != null && modifierList.hasModifier(KtTokens.IMPL_KEYWORD);
185
186 // Annotation entries are taken from both own annotations (if any) and object literal annotations (if any)
187 List<KtAnnotationEntry> annotationEntries = new ArrayList<KtAnnotationEntry>();
188 if (classOrObject != null && classOrObject.getParent() instanceof KtObjectLiteralExpression) {
189 // TODO: it would be better to have separate ObjectLiteralDescriptor without so much magic
190 annotationEntries.addAll(KtPsiUtilKt.getAnnotationEntries((KtObjectLiteralExpression) classOrObject.getParent()));
191 }
192 if (modifierList != null) {
193 annotationEntries.addAll(modifierList.getAnnotationEntries());
194 }
195 if (!annotationEntries.isEmpty()) {
196 this.annotations = new LazyAnnotations(
197 new LazyAnnotationsContext(
198 c.getAnnotationResolver(),
199 storageManager,
200 c.getTrace()
201 ) {
202 @NotNull
203 @Override
204 public LexicalScope getScope() {
205 return getOuterScope();
206 }
207 },
208 annotationEntries
209 );
210 }
211 else {
212 this.annotations = Annotations.Companion.getEMPTY();
213 }
214
215 List<KtAnnotationEntry> jetDanglingAnnotations = classLikeInfo.getDanglingAnnotations();
216 if (jetDanglingAnnotations.isEmpty()) {
217 this.danglingAnnotations = Annotations.Companion.getEMPTY();
218 }
219 else {
220 this.danglingAnnotations = new LazyAnnotations(
221 new LazyAnnotationsContext(
222 c.getAnnotationResolver(),
223 storageManager,
224 c.getTrace()
225 ) {
226 @NotNull
227 @Override
228 public LexicalScope getScope() {
229 return getScopeForMemberDeclarationResolution();
230 }
231 },
232 jetDanglingAnnotations
233 );
234 }
235
236 this.companionObjectDescriptor = storageManager.createNullableLazyValue(new Function0<ClassDescriptorWithResolutionScopes>() {
237 @Override
238 public ClassDescriptorWithResolutionScopes invoke() {
239 return computeCompanionObjectDescriptor(getCompanionObjectIfAllowed());
240 }
241 });
242 this.extraCompanionObjectDescriptors = storageManager.createMemoizedFunction(new Function1<KtObjectDeclaration, ClassDescriptor>() {
243 @Override
244 public ClassDescriptor invoke(KtObjectDeclaration companionObject) {
245 return computeCompanionObjectDescriptor(companionObject);
246 }
247 });
248 this.forceResolveAllContents = storageManager.createRecursionTolerantNullableLazyValue(new Function0<Void>() {
249 @Override
250 public Void invoke() {
251 doForceResolveAllContents();
252 return null;
253 }
254 }, null);
255
256 this.resolutionScopesSupport = new ClassResolutionScopesSupport(this, storageManager, new Function0<LexicalScope>() {
257 @Override
258 public LexicalScope invoke() {
259 return getOuterScope();
260 }
261 });
262
263 this.parameters = c.getStorageManager().createLazyValue(new Function0<List<TypeParameterDescriptor>>() {
264 @Override
265 public List<TypeParameterDescriptor> invoke() {
266 KtClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
267 KtTypeParameterList typeParameterList = classInfo.getTypeParameterList();
268 if (typeParameterList == null) return Collections.emptyList();
269
270 if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) {
271 c.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
272 }
273
274 List<KtTypeParameter> typeParameters = typeParameterList.getParameters();
275 if (typeParameters.isEmpty()) return Collections.emptyList();
276
277 List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
278
279 for (int i = 0; i < typeParameters.size(); i++) {
280 parameters.add(new LazyTypeParameterDescriptor(c, LazyClassDescriptor.this, typeParameters.get(i), i));
281 }
282
283 return parameters;
284 }
285 });
286
287 this.scopeForInitializerResolution = storageManager.createLazyValue(new Function0<LexicalScope>() {
288 @Override
289 public LexicalScope invoke() {
290 return ClassResolutionScopesSupportKt.scopeForInitializerResolution(LazyClassDescriptor.this,
291 createInitializerScopeParent(),
292 classLikeInfo.getPrimaryConstructorParameters());
293 }
294 });
295
296 this.sealedSubclasses = storageManager.createLazyValue(new Function0<Collection<ClassDescriptor>>() {
297 @Override
298 public Collection<ClassDescriptor> invoke() {
299 // TODO: only consider classes from the same file, not the whole package fragment
300 return DescriptorUtilsKt.computeSealedSubclasses(LazyClassDescriptor.this);
301 }
302 });
303 }
304
305 @NotNull
306 private DeclarationDescriptor createInitializerScopeParent() {
307 ConstructorDescriptor primaryConstructor = getUnsubstitutedPrimaryConstructor();
308 if (primaryConstructor != null) return primaryConstructor;
309
310 return new FunctionDescriptorImpl(
311 LazyClassDescriptor.this, null, Annotations.Companion.getEMPTY(), Name.special("<init-blocks>"),
312 CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE
313 ) {
314 {
315 initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
316 null, Modality.FINAL, Visibilities.PRIVATE);
317 }
318
319 @NotNull
320 @Override
321 protected FunctionDescriptorImpl createSubstitutedCopy(
322 @NotNull DeclarationDescriptor newOwner,
323 @Nullable FunctionDescriptor original,
324 @NotNull Kind kind,
325 @Nullable Name newName,
326 @NotNull Annotations annotations,
327 @NotNull SourceElement source
328 ) {
329 throw new UnsupportedOperationException();
330 }
331 };
332 }
333
334 // NOTE: Called from constructor!
335 @NotNull
336 protected LazyClassMemberScope createMemberScope(
337 @NotNull LazyClassContext c,
338 @NotNull ClassMemberDeclarationProvider declarationProvider
339 ) {
340 return new LazyClassMemberScope(c, declarationProvider, this, c.getTrace());
341 }
342
343 @NotNull
344 @Override
345 public MemberScope getUnsubstitutedMemberScope() {
346 return unsubstitutedMemberScope;
347 }
348
349 @NotNull
350 protected LexicalScope getOuterScope() {
351 return c.getDeclarationScopeProvider().getResolutionScopeForDeclaration(declarationProvider.getOwnerInfo().getScopeAnchor());
352 }
353
354 @Override
355 @NotNull
356 public LexicalScope getScopeForClassHeaderResolution() {
357 return resolutionScopesSupport.getScopeForClassHeaderResolution().invoke();
358 }
359
360 @Override
361 @NotNull
362 public LexicalScope getScopeForConstructorHeaderResolution() {
363 return resolutionScopesSupport.getScopeForConstructorHeaderResolution().invoke();
364 }
365
366 @Override
367 @NotNull
368 public LexicalScope getScopeForCompanionObjectHeaderResolution() {
369 return resolutionScopesSupport.getScopeForCompanionObjectHeaderResolution().invoke();
370 }
371
372 @Override
373 @NotNull
374 public LexicalScope getScopeForMemberDeclarationResolution() {
375 return resolutionScopesSupport.getScopeForMemberDeclarationResolution().invoke();
376 }
377
378 @Override
379 @NotNull
380 public LexicalScope getScopeForStaticMemberDeclarationResolution() {
381 return resolutionScopesSupport.getScopeForStaticMemberDeclarationResolution().invoke();
382 }
383
384 @Override
385 @NotNull
386 public LexicalScope getScopeForInitializerResolution() {
387 return scopeForInitializerResolution.invoke();
388 }
389
390 @NotNull
391 @Override
392 public Collection<CallableMemberDescriptor> getDeclaredCallableMembers() {
393 //noinspection unchecked
394 return (Collection) CollectionsKt.filter(
395 DescriptorUtils.getAllDescriptors(unsubstitutedMemberScope),
396 new Function1<DeclarationDescriptor, Boolean>() {
397 @Override
398 public Boolean invoke(DeclarationDescriptor descriptor) {
399 return descriptor instanceof CallableMemberDescriptor
400 && ((CallableMemberDescriptor) descriptor).getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
401 }
402 }
403 );
404 }
405
406 @NotNull
407 @Override
408 public MemberScope getStaticScope() {
409 return staticScope;
410 }
411
412 @NotNull
413 @Override
414 public Collection<ClassConstructorDescriptor> getConstructors() {
415 return unsubstitutedMemberScope.getConstructors();
416 }
417
418 @Override
419 public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
420 return unsubstitutedMemberScope.getPrimaryConstructor();
421 }
422
423 @NotNull
424 @Override
425 public TypeConstructor getTypeConstructor() {
426 return typeConstructor;
427 }
428
429 @Override
430 public ClassDescriptorWithResolutionScopes getCompanionObjectDescriptor() {
431 return companionObjectDescriptor.invoke();
432 }
433
434 @NotNull
435 @ReadOnly
436 public List<ClassDescriptor> getDescriptorsForExtraCompanionObjects() {
437 final KtObjectDeclaration allowedCompanionObject = getCompanionObjectIfAllowed();
438
439 return CollectionsKt.map(
440 CollectionsKt.filter(
441 declarationProvider.getOwnerInfo().getCompanionObjects(),
442 new Function1<KtObjectDeclaration, Boolean>() {
443 @Override
444 public Boolean invoke(KtObjectDeclaration companionObject) {
445 return companionObject != allowedCompanionObject;
446 }
447 }
448 ),
449 new Function1<KtObjectDeclaration, ClassDescriptor>() {
450 @Override
451 public ClassDescriptor invoke(KtObjectDeclaration companionObject) {
452 return extraCompanionObjectDescriptors.invoke(companionObject);
453 }
454 }
455 );
456 }
457
458 @Nullable
459 private ClassDescriptorWithResolutionScopes computeCompanionObjectDescriptor(@Nullable KtObjectDeclaration companionObject) {
460 if (companionObject == null)
461 return createSyntheticCompanionObjectDescriptor();
462 KtClassLikeInfo companionObjectInfo = getCompanionObjectInfo(companionObject);
463 if (!(companionObjectInfo instanceof KtClassOrObjectInfo)) {
464 return null;
465 }
466 Name name = ((KtClassOrObjectInfo) companionObjectInfo).getName();
467 assert name != null;
468 getUnsubstitutedMemberScope().getContributedClassifier(name, NoLookupLocation.WHEN_GET_COMPANION_OBJECT);
469 ClassDescriptor companionObjectDescriptor = c.getTrace().get(BindingContext.CLASS, companionObject);
470 if (companionObjectDescriptor instanceof ClassDescriptorWithResolutionScopes) {
471 assert DescriptorUtils.isCompanionObject(companionObjectDescriptor) : "Not a companion object: " + companionObjectDescriptor;
472 return (ClassDescriptorWithResolutionScopes)companionObjectDescriptor;
473 }
474 else {
475 return null;
476 }
477 }
478
479 private ClassDescriptorWithResolutionScopes createSyntheticCompanionObjectDescriptor() {
480 Name syntheticCompanionName = c.getSyntheticResolveExtension().getSyntheticCompanionObjectNameIfNeeded(this);
481 if (syntheticCompanionName == null)
482 return null;
483 return new SyntheticClassOrObjectDescriptor(c,
484 /* parentClassOrObject= */ classOrObject,
485 this, syntheticCompanionName, getSource(),
486 /* outerScope= */ getOuterScope(),
487 Modality.FINAL, PUBLIC, ClassKind.OBJECT, true);
488 }
489
490 @Nullable
491 private static KtClassLikeInfo getCompanionObjectInfo(@Nullable KtObjectDeclaration companionObject) {
492 if (companionObject != null) {
493 return KtClassInfoUtil.createClassLikeInfo(companionObject);
494 }
495
496 return null;
497 }
498
499 @Nullable
500 private KtObjectDeclaration getCompanionObjectIfAllowed() {
501 KtObjectDeclaration companionObject = firstOrNull(declarationProvider.getOwnerInfo().getCompanionObjects());
502 return (companionObject != null && isCompanionObjectAllowed()) ? companionObject : null;
503 }
504
505 private boolean isCompanionObjectAllowed() {
506 return !(getKind().isSingleton() || isInner() || DescriptorUtils.isLocal(this));
507 }
508
509 @NotNull
510 @Override
511 public ClassKind getKind() {
512 return kind;
513 }
514
515 @NotNull
516 @Override
517 public Modality getModality() {
518 return modality.invoke();
519 }
520
521 @NotNull
522 @Override
523 public Visibility getVisibility() {
524 return visibility;
525 }
526
527 @Override
528 public boolean isInner() {
529 return isInner;
530 }
531
532 @Override
533 public boolean isData() {
534 return isData;
535 }
536
537 @Override
538 public boolean isCompanionObject() {
539 return isCompanionObject;
540 }
541
542 @Override
543 public boolean isHeader() {
544 return isHeader;
545 }
546
547 @Override
548 public boolean isImpl() {
549 return isImpl;
550 }
551
552 @NotNull
553 @Override
554 public Annotations getAnnotations() {
555 return annotations;
556 }
557
558 @NotNull
559 public Annotations getDanglingAnnotations() {
560 return danglingAnnotations;
561 }
562
563 @NotNull
564 @Override
565 public Collection<ClassDescriptor> getSealedSubclasses() {
566 return sealedSubclasses.invoke();
567 }
568
569 @Override
570 public String toString() {
571 // not using descriptor render to preserve laziness
572 return "lazy class " + getName().toString();
573 }
574
575 @Override
576 public void forceResolveAllContents() {
577 forceResolveAllContents.invoke();
578 }
579
580 private void doForceResolveAllContents() {
581 resolveMemberHeaders();
582 ClassDescriptor companionObjectDescriptor = getCompanionObjectDescriptor();
583 if (companionObjectDescriptor != null) {
584 ForceResolveUtil.forceResolveAllContents(companionObjectDescriptor);
585 }
586
587 ForceResolveUtil.forceResolveAllContents(getConstructors());
588 ForceResolveUtil.forceResolveAllContents(getDescriptorsForExtraCompanionObjects());
589 ForceResolveUtil.forceResolveAllContents(getUnsubstitutedMemberScope());
590 ForceResolveUtil.forceResolveAllContents(getTypeConstructor());
591 }
592
593 // Note: headers of member classes' members are not resolved
594 public void resolveMemberHeaders() {
595 ForceResolveUtil.forceResolveAllContents(getAnnotations());
596 ForceResolveUtil.forceResolveAllContents(getDanglingAnnotations());
597
598 getCompanionObjectDescriptor();
599
600 getDescriptorsForExtraCompanionObjects();
601
602 getConstructors();
603 getContainingDeclaration();
604 getThisAsReceiverParameter();
605 getKind();
606 getModality();
607 getName();
608 getOriginal();
609 getScopeForClassHeaderResolution();
610 getScopeForMemberDeclarationResolution();
611 DescriptorUtils.getAllDescriptors(getUnsubstitutedMemberScope());
612 getScopeForInitializerResolution();
613 getUnsubstitutedInnerClassesScope();
614 getTypeConstructor().getSupertypes();
615 for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
616 typeParameterDescriptor.getUpperBounds();
617 }
618 getUnsubstitutedPrimaryConstructor();
619 getVisibility();
620 }
621
622 @NotNull
623 @Override
624 public List<TypeParameterDescriptor> getDeclaredTypeParameters() {
625 return parameters.invoke();
626 }
627
628 private class LazyClassTypeConstructor extends AbstractClassTypeConstructor {
629 private final NotNullLazyValue<List<TypeParameterDescriptor>> parameters = c.getStorageManager().createLazyValue(new Function0<List<TypeParameterDescriptor>>() {
630 @Override
631 public List<TypeParameterDescriptor> invoke() {
632 return TypeParameterUtilsKt.computeConstructorTypeParameters(LazyClassDescriptor.this);
633 }
634 });
635
636 public LazyClassTypeConstructor() {
637 super(LazyClassDescriptor.this.c.getStorageManager());
638 }
639
640 @NotNull
641 @Override
642 protected Collection<KotlinType> computeSupertypes() {
643 return LazyClassDescriptor.this.computeSupertypes();
644 }
645
646 @Override
647 protected void reportSupertypeLoopError(@NotNull KotlinType type) {
648 ClassifierDescriptor supertypeDescriptor = type.getConstructor().getDeclarationDescriptor();
649 if (supertypeDescriptor instanceof ClassDescriptor) {
650 ClassDescriptor superclass = (ClassDescriptor) supertypeDescriptor;
651 reportCyclicInheritanceHierarchyError(c.getTrace(), LazyClassDescriptor.this, superclass);
652 }
653 }
654
655 private void reportCyclicInheritanceHierarchyError(
656 @NotNull BindingTrace trace,
657 @NotNull ClassDescriptor classDescriptor,
658 @NotNull ClassDescriptor superclass
659 ) {
660 PsiElement psiElement = DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor);
661
662 PsiElement elementToMark = null;
663 if (psiElement instanceof KtClassOrObject) {
664 KtClassOrObject classOrObject = (KtClassOrObject) psiElement;
665 for (KtSuperTypeListEntry delegationSpecifier : classOrObject.getSuperTypeListEntries()) {
666 KtTypeReference typeReference = delegationSpecifier.getTypeReference();
667 if (typeReference == null) continue;
668 KotlinType supertype = trace.get(TYPE, typeReference);
669 if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) {
670 elementToMark = typeReference;
671 }
672 }
673 }
674 if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) {
675 PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement;
676 PsiElement nameIdentifier = namedElement.getNameIdentifier();
677 if (nameIdentifier != null) {
678 elementToMark = nameIdentifier;
679 }
680 }
681 if (elementToMark != null) {
682 trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
683 }
684 }
685
686 @NotNull
687 @Override
688 protected SupertypeLoopChecker getSupertypeLoopChecker() {
689 return c.getSupertypeLoopChecker();
690 }
691
692 @NotNull
693 @Override
694 public List<TypeParameterDescriptor> getParameters() {
695 return parameters.invoke();
696 }
697
698 @Override
699 public boolean isFinal() {
700 return getModality() == Modality.FINAL;
701 }
702
703 @Override
704 public boolean isDenotable() {
705 return true;
706 }
707
708 @Override
709 @NotNull
710 public ClassifierDescriptor getDeclarationDescriptor() {
711 return LazyClassDescriptor.this;
712 }
713
714 @Override
715 public String toString() {
716 return LazyClassDescriptor.this.getName().toString();
717 }
718 }
719
720 @NotNull
721 protected Collection<KotlinType> computeSupertypes() {
722 if (KotlinBuiltIns.isSpecialClassWithNoSupertypes(this)) {
723 return Collections.emptyList();
724 }
725
726 KtClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
727 if (classOrObject == null) {
728 return Collections.<KotlinType>singleton(c.getModuleDescriptor().getBuiltIns().getAnyType());
729 }
730
731 List<KotlinType> allSupertypes =
732 c.getDescriptorResolver()
733 .resolveSupertypes(getScopeForClassHeaderResolution(), this, classOrObject,
734 c.getTrace());
735
736 return Lists.newArrayList(Collections2.filter(allSupertypes, VALID_SUPERTYPE));
737 }
738 }