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.descriptors.impl;
018
019 import kotlin.jvm.functions.Function0;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.kotlin.descriptors.*;
022 import org.jetbrains.kotlin.name.Name;
023 import org.jetbrains.kotlin.resolve.scopes.InnerClassesScopeWrapper;
024 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
025 import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope;
026 import org.jetbrains.kotlin.storage.NotNullLazyValue;
027 import org.jetbrains.kotlin.storage.StorageManager;
028 import org.jetbrains.kotlin.types.*;
029
030 import java.util.List;
031
032 public abstract class AbstractClassDescriptor implements ClassDescriptor {
033 private final Name name;
034 protected final NotNullLazyValue<KotlinType> defaultType;
035 private final NotNullLazyValue<MemberScope> unsubstitutedInnerClassesScope;
036 private final NotNullLazyValue<ReceiverParameterDescriptor> thisAsReceiverParameter;
037
038 public AbstractClassDescriptor(@NotNull StorageManager storageManager, @NotNull Name name) {
039 this.name = name;
040 this.defaultType = storageManager.createLazyValue(new Function0<KotlinType>() {
041 @Override
042 public KotlinType invoke() {
043 return TypeUtils.makeUnsubstitutedType(AbstractClassDescriptor.this, getUnsubstitutedMemberScope());
044 }
045 });
046 this.unsubstitutedInnerClassesScope = storageManager.createLazyValue(new Function0<MemberScope>() {
047 @Override
048 public MemberScope invoke() {
049 return new InnerClassesScopeWrapper(getUnsubstitutedMemberScope());
050 }
051 });
052 this.thisAsReceiverParameter = storageManager.createLazyValue(new Function0<ReceiverParameterDescriptor>() {
053 @Override
054 public ReceiverParameterDescriptor invoke() {
055 return new LazyClassReceiverParameterDescriptor(AbstractClassDescriptor.this);
056 }
057 });
058 }
059
060 @NotNull
061 @Override
062 public Name getName() {
063 return name;
064 }
065
066 @NotNull
067 @Override
068 public DeclarationDescriptorWithSource getOriginal() {
069 return this;
070 }
071
072 @NotNull
073 @Override
074 public MemberScope getUnsubstitutedInnerClassesScope() {
075 return unsubstitutedInnerClassesScope.invoke();
076 }
077
078 @NotNull
079 @Override
080 public ReceiverParameterDescriptor getThisAsReceiverParameter() {
081 return thisAsReceiverParameter.invoke();
082 }
083
084 @NotNull
085 @Override
086 public MemberScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments) {
087 assert typeArguments.size() == getTypeConstructor().getParameters().size() : "Illegal number of type arguments: expected "
088 + getTypeConstructor().getParameters().size() + " but was " + typeArguments.size()
089 + " for " + getTypeConstructor() + " " + getTypeConstructor().getParameters();
090 if (typeArguments.isEmpty()) return getUnsubstitutedMemberScope();
091
092 TypeSubstitutor substitutor = TypeConstructorSubstitution.create(getTypeConstructor(), typeArguments).buildSubstitutor();
093 return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor);
094 }
095
096 @NotNull
097 @Override
098 public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution) {
099 if (typeSubstitution.isEmpty()) return getUnsubstitutedMemberScope();
100
101 TypeSubstitutor substitutor = TypeSubstitutor.create(typeSubstitution);
102 return new SubstitutingScope(getUnsubstitutedMemberScope(), substitutor);
103 }
104
105 @NotNull
106 @Override
107 public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
108 if (substitutor.isEmpty()) {
109 return this;
110 }
111 return new LazySubstitutingClassDescriptor(this, substitutor);
112 }
113
114 @NotNull
115 @Override
116 public KotlinType getDefaultType() {
117 return defaultType.invoke();
118 }
119
120 @Override
121 public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
122 visitor.visitClassDescriptor(this, null);
123 }
124
125 @Override
126 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
127 return visitor.visitClassDescriptor(this, data);
128 }
129 }