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.CollectionsKt;
020 import kotlin.jvm.functions.Function1;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.descriptors.*;
024 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
025 import org.jetbrains.kotlin.name.Name;
026 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
027 import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope;
028 import org.jetbrains.kotlin.types.*;
029
030 import java.util.ArrayList;
031 import java.util.Collection;
032 import java.util.List;
033
034 public class LazySubstitutingClassDescriptor implements ClassDescriptor {
035 private final ClassDescriptor original;
036 private final TypeSubstitutor originalSubstitutor;
037 private TypeSubstitutor newSubstitutor;
038 private List<TypeParameterDescriptor> typeConstructorParameters;
039 private List<TypeParameterDescriptor> declaredTypeParameters;
040 private TypeConstructor typeConstructor;
041
042 public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, TypeSubstitutor substitutor) {
043 this.original = descriptor;
044 this.originalSubstitutor = substitutor;
045 }
046
047 private TypeSubstitutor getSubstitutor() {
048 if (newSubstitutor == null) {
049 if (originalSubstitutor.isEmpty()) {
050 newSubstitutor = originalSubstitutor;
051 }
052 else {
053 List<TypeParameterDescriptor> originalTypeParameters = original.getTypeConstructor().getParameters();
054 typeConstructorParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
055 newSubstitutor = DescriptorSubstitutor.substituteTypeParameters(
056 originalTypeParameters, originalSubstitutor.getSubstitution(), this, typeConstructorParameters
057 );
058
059 declaredTypeParameters = CollectionsKt.filter(typeConstructorParameters, new Function1<TypeParameterDescriptor, Boolean>() {
060 @Override
061 public Boolean invoke(TypeParameterDescriptor descriptor) {
062 return !descriptor.isCapturedFromOuterDeclaration();
063 }
064 });
065 }
066 }
067 return newSubstitutor;
068 }
069
070 @NotNull
071 @Override
072 public TypeConstructor getTypeConstructor() {
073 TypeConstructor originalTypeConstructor = original.getTypeConstructor();
074 if (originalSubstitutor.isEmpty()) {
075 return originalTypeConstructor;
076 }
077
078 if (typeConstructor == null) {
079 TypeSubstitutor substitutor = getSubstitutor();
080
081 Collection<KotlinType> originalSupertypes = originalTypeConstructor.getSupertypes();
082 Collection<KotlinType> supertypes = new ArrayList<KotlinType>(originalSupertypes.size());
083 for (KotlinType supertype : originalSupertypes) {
084 supertypes.add(substitutor.substitute(supertype, Variance.INVARIANT));
085 }
086
087 typeConstructor = TypeConstructorImpl.createForClass(
088 this,
089 originalTypeConstructor.getAnnotations(),
090 originalTypeConstructor.isFinal(),
091 originalTypeConstructor.toString(),
092 typeConstructorParameters,
093 supertypes
094 );
095 }
096
097 return typeConstructor;
098 }
099
100 @NotNull
101 @Override
102 public MemberScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments) {
103 MemberScope memberScope = original.getMemberScope(typeArguments);
104 if (originalSubstitutor.isEmpty()) {
105 return memberScope;
106 }
107 return new SubstitutingScope(memberScope, getSubstitutor());
108 }
109
110 @NotNull
111 @Override
112 public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution) {
113 MemberScope memberScope = original.getMemberScope(typeSubstitution);
114 if (originalSubstitutor.isEmpty()) {
115 return memberScope;
116 }
117 return new SubstitutingScope(memberScope, getSubstitutor());
118 }
119
120 @NotNull
121 @Override
122 public MemberScope getUnsubstitutedMemberScope() {
123 MemberScope memberScope = original.getUnsubstitutedMemberScope();
124 if (originalSubstitutor.isEmpty()) {
125 return memberScope;
126 }
127 return new SubstitutingScope(memberScope, getSubstitutor());
128 }
129
130 @NotNull
131 @Override
132 public MemberScope getStaticScope() {
133 return original.getStaticScope();
134 }
135
136 @NotNull
137 @Override
138 public KotlinType getDefaultType() {
139 List<TypeProjection> typeProjections = TypeUtils.getDefaultTypeProjections(getTypeConstructor().getParameters());
140 return KotlinTypeImpl.create(
141 getAnnotations(),
142 this,
143 false,
144 typeProjections
145 );
146 }
147
148 @NotNull
149 @Override
150 public ReceiverParameterDescriptor getThisAsReceiverParameter() {
151 throw new UnsupportedOperationException(); // TODO
152 }
153
154 @NotNull
155 @Override
156 public Collection<ConstructorDescriptor> getConstructors() {
157 Collection<ConstructorDescriptor> originalConstructors = original.getConstructors();
158 Collection<ConstructorDescriptor> result = new ArrayList<ConstructorDescriptor>(originalConstructors.size());
159 for (ConstructorDescriptor constructor : originalConstructors) {
160 ConstructorDescriptor copy =
161 constructor.copy(this, constructor.getModality(), constructor.getVisibility(), constructor.getKind(), false);
162 result.add(copy.substitute(getSubstitutor()));
163 }
164 return result;
165 }
166
167 @NotNull
168 @Override
169 public Annotations getAnnotations() {
170 return original.getAnnotations();
171 }
172
173 @NotNull
174 @Override
175 public Name getName() {
176 return original.getName();
177 }
178
179 @NotNull
180 @Override
181 public DeclarationDescriptorWithSource getOriginal() {
182 return original.getOriginal();
183 }
184
185 @NotNull
186 @Override
187 public DeclarationDescriptor getContainingDeclaration() {
188 return original.getContainingDeclaration();
189 }
190
191 @NotNull
192 @Override
193 public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
194 if (substitutor.isEmpty()) return this;
195 return new LazySubstitutingClassDescriptor(this, TypeSubstitutor.createChainedSubstitutor(substitutor.getSubstitution(), getSubstitutor().getSubstitution()));
196 }
197
198 @Override
199 public ClassDescriptor getCompanionObjectDescriptor() {
200 return original.getCompanionObjectDescriptor();
201 }
202
203 @NotNull
204 @Override
205 public ClassKind getKind() {
206 return original.getKind();
207 }
208
209 @Override
210 @NotNull
211 public Modality getModality() {
212 return original.getModality();
213 }
214
215 @NotNull
216 @Override
217 public Visibility getVisibility() {
218 return original.getVisibility();
219 }
220
221 @Override
222 public boolean isInner() {
223 return original.isInner();
224 }
225
226 @Override
227 public boolean isData() {
228 return original.isData();
229 }
230
231 @Override
232 public boolean isCompanionObject() {
233 return original.isCompanionObject();
234 }
235
236 @Override
237 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
238 return visitor.visitClassDescriptor(this, data);
239 }
240
241 @Override
242 public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
243 throw new UnsupportedOperationException(); // TODO
244 }
245
246 @NotNull
247 @Override
248 public MemberScope getUnsubstitutedInnerClassesScope() {
249 return original.getUnsubstitutedInnerClassesScope();
250 }
251
252 @Nullable
253 @Override
254 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
255 return original.getUnsubstitutedPrimaryConstructor();
256 }
257
258 @NotNull
259 @Override
260 public SourceElement getSource() {
261 return SourceElement.NO_SOURCE;
262 }
263
264 @NotNull
265 @Override
266 public List<TypeParameterDescriptor> getDeclaredTypeParameters() {
267 getSubstitutor();
268 return declaredTypeParameters;
269 }
270 }