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