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 jet.Function0;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
022 import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
023 import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
024 import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
025 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
026 import org.jetbrains.jet.lang.resolve.name.Name;
027 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
028 import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
029 import org.jetbrains.jet.lang.types.*;
030 import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
031 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
032 import org.jetbrains.jet.renderer.DescriptorRenderer;
033 import org.jetbrains.jet.storage.NotNullLazyValue;
034 import org.jetbrains.jet.storage.StorageManager;
035
036 import java.util.Collection;
037 import java.util.Collections;
038 import java.util.List;
039 import java.util.Set;
040
041 public abstract class AbstractLazyTypeParameterDescriptor implements TypeParameterDescriptor {
042
043 private final Variance variance;
044 private final boolean reified;
045 private final int index;
046 private final DeclarationDescriptor containingDeclaration;
047 private final Name name;
048
049 private final NotNullLazyValue<TypeConstructor> typeConstructor;
050 private final NotNullLazyValue<JetType> defaultType;
051 private final NotNullLazyValue<Set<JetType>> upperBounds;
052 private final NotNullLazyValue<JetType> upperBoundsAsType;
053
054 public AbstractLazyTypeParameterDescriptor(
055 @NotNull final StorageManager storageManager,
056 @NotNull DeclarationDescriptor containingDeclaration,
057 @NotNull Name name,
058 @NotNull Variance variance,
059 boolean isReified,
060 int index
061 ) {
062 this.variance = variance;
063 this.containingDeclaration = containingDeclaration;
064 this.index = index;
065 this.name = name;
066 this.reified = isReified;
067
068 this.typeConstructor = storageManager.createLazyValue(new Function0<TypeConstructor>() {
069 @Override
070 public TypeConstructor invoke() {
071 return createTypeConstructor();
072 }
073 });
074 this.defaultType = storageManager.createLazyValue(new Function0<JetType>() {
075 @Override
076 public JetType invoke() {
077 return createDefaultType(storageManager);
078 }
079 });
080 this.upperBounds = storageManager.createLazyValue(new Function0<Set<JetType>>() {
081 @Override
082 public Set<JetType> invoke() {
083 return resolveUpperBounds();
084 }
085 });
086 this.upperBoundsAsType = storageManager.createLazyValue(new Function0<JetType>() {
087 @Override
088 public JetType invoke() {
089 return computeUpperBoundsAsType();
090 }
091 });
092 }
093
094 @Override
095 public boolean isReified() {
096 return reified;
097 }
098
099 @NotNull
100 @Override
101 public Variance getVariance() {
102 return variance;
103 }
104
105 @NotNull
106 @Override
107 public Set<JetType> getUpperBounds() {
108 return upperBounds.invoke();
109 }
110
111 @NotNull
112 protected abstract Set<JetType> resolveUpperBounds();
113
114 @NotNull
115 @Override
116 public JetType getUpperBoundsAsType() {
117 return upperBoundsAsType.invoke();
118 }
119
120 @NotNull
121 private JetType computeUpperBoundsAsType() {
122 Set<JetType> upperBounds = getUpperBounds();
123 assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
124 JetType upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
125 if (upperBoundsAsType == null) {
126 upperBoundsAsType = KotlinBuiltIns.getInstance().getNothingType();
127 }
128 return upperBoundsAsType;
129 }
130
131
132 @NotNull
133 @Override
134 public Set<JetType> getLowerBounds() {
135 return Collections.singleton(getLowerBoundsAsType());
136 }
137
138 @NotNull
139 @Override
140 public JetType getLowerBoundsAsType() {
141 return KotlinBuiltIns.getInstance().getNothingType();
142 }
143
144 @NotNull
145 @Override
146 public TypeConstructor getTypeConstructor() {
147 return typeConstructor.invoke();
148 }
149
150 @NotNull
151 private TypeConstructor createTypeConstructor() {
152 return new TypeConstructor() {
153 @NotNull
154 @Override
155 public Collection<JetType> getSupertypes() {
156 return AbstractLazyTypeParameterDescriptor.this.getUpperBounds();
157 }
158
159 @NotNull
160 @Override
161 public List<TypeParameterDescriptor> getParameters() {
162 return Collections.emptyList();
163 }
164
165 @Override
166 public boolean isFinal() {
167 return false;
168 }
169
170 @Override
171 public boolean isDenotable() {
172 return true;
173 }
174
175 @Override
176 public ClassifierDescriptor getDeclarationDescriptor() {
177 return AbstractLazyTypeParameterDescriptor.this;
178 }
179
180 @Override
181 public List<AnnotationDescriptor> getAnnotations() {
182 return AbstractLazyTypeParameterDescriptor.this.getAnnotations();
183 }
184
185 @Override
186 public String toString() {
187 return getName().toString();
188 }
189 };
190 }
191
192 @NotNull
193 @Override
194 public JetType getDefaultType() {
195 return defaultType.invoke();
196 }
197
198 @NotNull
199 private JetType createDefaultType(@NotNull StorageManager storageManager) {
200 return new JetTypeImpl(getTypeConstructor(), new LazyScopeAdapter(storageManager.createLazyValue(
201 new Function0<JetScope>() {
202 @Override
203 public JetScope invoke() {
204 return getUpperBoundsAsType().getMemberScope();
205 }
206 }
207 )));
208 }
209
210 @Override
211 public JetType getClassObjectType() {
212 return null;
213 }
214
215 @NotNull
216 @Override
217 public DeclarationDescriptor getOriginal() {
218 return this;
219 }
220
221 @NotNull
222 @Override
223 public DeclarationDescriptor getContainingDeclaration() {
224 return containingDeclaration;
225 }
226
227 @NotNull
228 @Override
229 @Deprecated
230 public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
231 throw new UnsupportedOperationException("Don't call substitute() on type parameters");
232 }
233
234 @Override
235 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
236 return visitor.visitTypeParameterDescriptor(this, data);
237 }
238
239 @Override
240 public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
241 visitor.visitTypeParameterDescriptor(this, null);
242 }
243
244 @Override
245 public int getIndex() {
246 return index;
247 }
248
249 @Override
250 public List<AnnotationDescriptor> getAnnotations() {
251 return Collections.emptyList(); // TODO
252 }
253
254 @NotNull
255 @Override
256 public Name getName() {
257 return name;
258 }
259
260 @Override
261 public String toString() {
262 try {
263 return DescriptorRenderer.DEBUG_TEXT.render(this);
264 }
265 catch (Exception e) {
266 return this.getClass().getName() + "@" + System.identityHashCode(this);
267 }
268 }
269 }