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