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