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