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.resolve.lazy.descriptors;
018
019 import com.intellij.openapi.util.Computable;
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.lazy.storage.NotNullLazyValue;
027 import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager;
028 import org.jetbrains.jet.lang.resolve.name.Name;
029 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
030 import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
031 import org.jetbrains.jet.lang.types.*;
032 import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
033 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
034 import org.jetbrains.jet.renderer.DescriptorRenderer;
035 import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValue;
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 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 Computable<TypeConstructor>() {
070 @Override
071 public TypeConstructor compute() {
072 return createTypeConstructor();
073 }
074 });
075 this.defaultType = storageManager.createLazyValue(new Computable<JetType>() {
076 @Override
077 public JetType compute() {
078 return createDefaultType();
079 }
080 });
081 this.upperBounds = storageManager.createLazyValue(new Computable<Set<JetType>>() {
082 @Override
083 public Set<JetType> compute() {
084 return resolveUpperBounds();
085 }
086 });
087 this.upperBoundsAsType = storageManager.createLazyValue(new Computable<JetType>() {
088 @Override
089 public JetType compute() {
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.compute();
110 }
111
112 @NotNull
113 protected abstract Set<JetType> resolveUpperBounds();
114
115 @NotNull
116 @Override
117 public JetType getUpperBoundsAsType() {
118 return upperBoundsAsType.compute();
119 }
120
121 @NotNull
122 private JetType computeUpperBoundsAsType() {
123 Set<JetType> upperBounds = getUpperBounds();
124 assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
125 JetType upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
126 if (upperBoundsAsType == null) {
127 upperBoundsAsType = KotlinBuiltIns.getInstance().getNothingType();
128 }
129 return upperBoundsAsType;
130 }
131
132
133 @NotNull
134 @Override
135 public Set<JetType> getLowerBounds() {
136 return Collections.singleton(getLowerBoundsAsType());
137 }
138
139 @NotNull
140 @Override
141 public JetType getLowerBoundsAsType() {
142 return KotlinBuiltIns.getInstance().getNothingType();
143 }
144
145 @NotNull
146 @Override
147 public TypeConstructor getTypeConstructor() {
148 return typeConstructor.compute();
149 }
150
151 @NotNull
152 private TypeConstructor createTypeConstructor() {
153 return new TypeConstructor() {
154 @NotNull
155 @Override
156 public Collection<JetType> getSupertypes() {
157 return AbstractLazyTypeParameterDescriptor.this.getUpperBounds();
158 }
159
160 @NotNull
161 @Override
162 public List<TypeParameterDescriptor> getParameters() {
163 return Collections.emptyList();
164 }
165
166 @Override
167 public boolean isSealed() {
168 return false;
169 }
170
171 @Override
172 public boolean isDenotable() {
173 return true;
174 }
175
176 @Override
177 public ClassifierDescriptor getDeclarationDescriptor() {
178 return AbstractLazyTypeParameterDescriptor.this;
179 }
180
181 @Override
182 public List<AnnotationDescriptor> getAnnotations() {
183 return AbstractLazyTypeParameterDescriptor.this.getAnnotations();
184 }
185
186 @Override
187 public String toString() {
188 return getName().toString();
189 }
190 };
191 }
192
193 @NotNull
194 @Override
195 public JetType getDefaultType() {
196 return defaultType.compute();
197 }
198
199 @NotNull
200 private JetType createDefaultType() {
201 return new JetTypeImpl(getTypeConstructor(), new LazyScopeAdapter(new RecursionIntolerantLazyValue<JetScope>() {
202 @Override
203 protected JetScope compute() {
204 return getUpperBoundsAsType().getMemberScope();
205 }
206 }));
207 }
208
209 @Override
210 public JetType getClassObjectType() {
211 return null;
212 }
213
214 @NotNull
215 @Override
216 public DeclarationDescriptor getOriginal() {
217 return this;
218 }
219
220 @NotNull
221 @Override
222 public DeclarationDescriptor getContainingDeclaration() {
223 return containingDeclaration;
224 }
225
226 @NotNull
227 @Override
228 @Deprecated
229 public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
230 throw new UnsupportedOperationException("Don't call substitute() on type parameters");
231 }
232
233 @Override
234 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
235 return visitor.visitTypeParameterDescriptor(this, data);
236 }
237
238 @Override
239 public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
240 visitor.visitTypeParameterDescriptor(this, null);
241 }
242
243 @Override
244 public int getIndex() {
245 return index;
246 }
247
248 @Override
249 public List<AnnotationDescriptor> getAnnotations() {
250 return Collections.emptyList(); // TODO
251 }
252
253 @NotNull
254 @Override
255 public Name getName() {
256 return name;
257 }
258
259 @Override
260 public String toString() {
261 try {
262 return DescriptorRenderer.DEBUG_TEXT.render(this);
263 }
264 catch (Exception e) {
265 return this.getClass().getName() + "@" + System.identityHashCode(this);
266 }
267 }
268 }