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.collections.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 = new ClassTypeConstructorImpl(this, originalTypeConstructor.isFinal(), typeConstructorParameters, supertypes);
088 }
089
090 return typeConstructor;
091 }
092
093 @NotNull
094 @Override
095 public MemberScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments) {
096 MemberScope memberScope = original.getMemberScope(typeArguments);
097 if (originalSubstitutor.isEmpty()) {
098 return memberScope;
099 }
100 return new SubstitutingScope(memberScope, getSubstitutor());
101 }
102
103 @NotNull
104 @Override
105 public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution) {
106 MemberScope memberScope = original.getMemberScope(typeSubstitution);
107 if (originalSubstitutor.isEmpty()) {
108 return memberScope;
109 }
110 return new SubstitutingScope(memberScope, getSubstitutor());
111 }
112
113 @NotNull
114 @Override
115 public MemberScope getUnsubstitutedMemberScope() {
116 MemberScope memberScope = original.getUnsubstitutedMemberScope();
117 if (originalSubstitutor.isEmpty()) {
118 return memberScope;
119 }
120 return new SubstitutingScope(memberScope, getSubstitutor());
121 }
122
123 @NotNull
124 @Override
125 public MemberScope getStaticScope() {
126 return original.getStaticScope();
127 }
128
129 @NotNull
130 @Override
131 public SimpleType getDefaultType() {
132 List<TypeProjection> typeProjections = TypeUtils.getDefaultTypeProjections(getTypeConstructor().getParameters());
133 return KotlinTypeFactory.simpleNotNullType(getAnnotations(), this, typeProjections);
134 }
135
136 @NotNull
137 @Override
138 public ReceiverParameterDescriptor getThisAsReceiverParameter() {
139 throw new UnsupportedOperationException(); // TODO
140 }
141
142 @NotNull
143 @Override
144 public Collection<ClassConstructorDescriptor> getConstructors() {
145 Collection<ClassConstructorDescriptor> originalConstructors = original.getConstructors();
146 Collection<ClassConstructorDescriptor> result = new ArrayList<ClassConstructorDescriptor>(originalConstructors.size());
147 for (ClassConstructorDescriptor constructor : originalConstructors) {
148 ClassConstructorDescriptor copy =
149 constructor.copy(this, constructor.getModality(), constructor.getVisibility(), constructor.getKind(), false);
150 result.add(copy.substitute(getSubstitutor()));
151 }
152 return result;
153 }
154
155 @NotNull
156 @Override
157 public Annotations getAnnotations() {
158 return original.getAnnotations();
159 }
160
161 @NotNull
162 @Override
163 public Name getName() {
164 return original.getName();
165 }
166
167 @NotNull
168 @Override
169 public ClassDescriptor getOriginal() {
170 return original.getOriginal();
171 }
172
173 @NotNull
174 @Override
175 public DeclarationDescriptor getContainingDeclaration() {
176 return original.getContainingDeclaration();
177 }
178
179 @NotNull
180 @Override
181 public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
182 if (substitutor.isEmpty()) return this;
183 return new LazySubstitutingClassDescriptor(this, TypeSubstitutor.createChainedSubstitutor(substitutor.getSubstitution(), getSubstitutor().getSubstitution()));
184 }
185
186 @Override
187 public ClassDescriptor getCompanionObjectDescriptor() {
188 return original.getCompanionObjectDescriptor();
189 }
190
191 @NotNull
192 @Override
193 public ClassKind getKind() {
194 return original.getKind();
195 }
196
197 @Override
198 @NotNull
199 public Modality getModality() {
200 return original.getModality();
201 }
202
203 @NotNull
204 @Override
205 public Visibility getVisibility() {
206 return original.getVisibility();
207 }
208
209 @Override
210 public boolean isInner() {
211 return original.isInner();
212 }
213
214 @Override
215 public boolean isData() {
216 return original.isData();
217 }
218
219 @Override
220 public boolean isExternal() {
221 return original.isExternal();
222 }
223
224 @Override
225 public boolean isCompanionObject() {
226 return original.isCompanionObject();
227 }
228
229 @Override
230 public boolean isHeader() {
231 return original.isHeader();
232 }
233
234 @Override
235 public boolean isImpl() {
236 return original.isImpl();
237 }
238
239 @Override
240 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
241 return visitor.visitClassDescriptor(this, data);
242 }
243
244 @Override
245 public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
246 throw new UnsupportedOperationException(); // TODO
247 }
248
249 @NotNull
250 @Override
251 public MemberScope getUnsubstitutedInnerClassesScope() {
252 return original.getUnsubstitutedInnerClassesScope();
253 }
254
255 @Nullable
256 @Override
257 public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
258 return original.getUnsubstitutedPrimaryConstructor();
259 }
260
261 @NotNull
262 @Override
263 public SourceElement getSource() {
264 return SourceElement.NO_SOURCE;
265 }
266
267 @NotNull
268 @Override
269 public List<TypeParameterDescriptor> getDeclaredTypeParameters() {
270 getSubstitutor();
271 return declaredTypeParameters;
272 }
273
274 @NotNull
275 @Override
276 public Collection<ClassDescriptor> getSealedSubclasses() {
277 return original.getSealedSubclasses();
278 }
279 }