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