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    }