001 /*
002 * Copyright 2010-2013 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.jet.lang.descriptors.impl;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.jet.lang.descriptors.*;
022 import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
023 import org.jetbrains.jet.lang.resolve.name.Name;
024 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
025 import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
026 import org.jetbrains.jet.lang.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 throw new UnsupportedOperationException(); // TODO
110 }
111
112 @NotNull
113 @Override
114 public ReceiverParameterDescriptor getThisAsReceiverParameter() {
115 throw new UnsupportedOperationException(); // TODO
116 }
117
118 @NotNull
119 @Override
120 public Collection<ConstructorDescriptor> getConstructors() {
121 Collection<ConstructorDescriptor> originalConstructors = original.getConstructors();
122 Collection<ConstructorDescriptor> result = new ArrayList<ConstructorDescriptor>(originalConstructors.size());
123 for (ConstructorDescriptor constructor : originalConstructors) {
124 result.add((ConstructorDescriptor) constructor.substitute(getSubstitutor()));
125 }
126 return result;
127 }
128
129 @NotNull
130 @Override
131 public Annotations getAnnotations() {
132 return original.getAnnotations();
133 }
134
135 @NotNull
136 @Override
137 public Name getName() {
138 return original.getName();
139 }
140
141 @NotNull
142 @Override
143 public DeclarationDescriptor getOriginal() {
144 return original.getOriginal();
145 }
146
147 @NotNull
148 @Override
149 public DeclarationDescriptor getContainingDeclaration() {
150 return original.getContainingDeclaration();
151 }
152
153 @NotNull
154 @Override
155 public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
156 if (substitutor.isEmpty()) return this;
157 return new LazySubstitutingClassDescriptor(this, TypeSubstitutor.create(substitutor.getSubstitution(), getSubstitutor().getSubstitution()));
158 }
159
160 @Override
161 public JetType getClassObjectType() {
162 return original.getClassObjectType();
163 }
164
165 @Override
166 public ClassDescriptor getClassObjectDescriptor() {
167 return original.getClassObjectDescriptor();
168 }
169
170 @NotNull
171 @Override
172 public ClassKind getKind() {
173 return original.getKind();
174 }
175
176 @Override
177 @NotNull
178 public Modality getModality() {
179 return original.getModality();
180 }
181
182 @NotNull
183 @Override
184 public Visibility getVisibility() {
185 return original.getVisibility();
186 }
187
188 @Override
189 public boolean isInner() {
190 return original.isInner();
191 }
192
193 @Override
194 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
195 return visitor.visitClassDescriptor(this, data);
196 }
197
198 @Override
199 public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
200 throw new UnsupportedOperationException(); // TODO
201 }
202
203 @NotNull
204 @Override
205 public JetScope getUnsubstitutedInnerClassesScope() {
206 return original.getUnsubstitutedInnerClassesScope();
207 }
208
209 @Nullable
210 @Override
211 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
212 return original.getUnsubstitutedPrimaryConstructor();
213 }
214
215 @NotNull
216 @Override
217 public SourceElement getSource() {
218 return SourceElement.NO_SOURCE;
219 }
220 }