001    /*
002     * Copyright 2010-2014 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.DeclarationDescriptor;
023    import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
024    import org.jetbrains.jet.lang.descriptors.SourceElement;
025    import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
026    import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
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.storage.NotNullLazyValue;
034    import org.jetbrains.jet.storage.StorageManager;
035    
036    import java.util.Collections;
037    import java.util.Set;
038    
039    public abstract class AbstractTypeParameterDescriptor extends DeclarationDescriptorNonRootImpl implements TypeParameterDescriptor {
040        private final Variance variance;
041        private final boolean reified;
042        private final int index;
043    
044        private final NotNullLazyValue<TypeConstructor> typeConstructor;
045        private final NotNullLazyValue<JetType> defaultType;
046        private final NotNullLazyValue<Set<JetType>> upperBounds;
047        private final NotNullLazyValue<JetType> upperBoundsAsType;
048    
049        protected AbstractTypeParameterDescriptor(
050                @NotNull final StorageManager storageManager,
051                @NotNull DeclarationDescriptor containingDeclaration,
052                @NotNull Annotations annotations,
053                @NotNull Name name,
054                @NotNull Variance variance,
055                boolean isReified,
056                int index,
057                @NotNull SourceElement source
058        ) {
059            super(containingDeclaration, annotations, name, source);
060            this.variance = variance;
061            this.reified = isReified;
062            this.index = index;
063    
064            this.typeConstructor = storageManager.createLazyValue(new Function0<TypeConstructor>() {
065                @Override
066                public TypeConstructor invoke() {
067                    return createTypeConstructor();
068                }
069            });
070            this.defaultType = storageManager.createLazyValue(new Function0<JetType>() {
071                @Override
072                public JetType invoke() {
073                    return new JetTypeImpl(Annotations.EMPTY, getTypeConstructor(), false, Collections.<TypeProjection>emptyList(),
074                                           new LazyScopeAdapter(storageManager.createLazyValue(
075                                                   new Function0<JetScope>() {
076                                                       @Override
077                                                       public JetScope invoke() {
078                                                           return getUpperBoundsAsType().getMemberScope();
079                                                       }
080                                                   }
081                                           )));
082                }
083            });
084            this.upperBounds = storageManager.createLazyValue(new Function0<Set<JetType>>() {
085                @Override
086                public Set<JetType> invoke() {
087                    return resolveUpperBounds();
088                }
089            });
090            this.upperBoundsAsType = storageManager.createLazyValue(new Function0<JetType>() {
091                @Override
092                public JetType invoke() {
093                    return computeUpperBoundsAsType();
094                }
095            });
096        }
097    
098        @NotNull
099        @ReadOnly
100        protected abstract Set<JetType> resolveUpperBounds();
101    
102        @NotNull
103        protected abstract TypeConstructor createTypeConstructor();
104    
105        @NotNull
106        @Override
107        public Variance getVariance() {
108            return variance;
109        }
110    
111        @Override
112        public boolean isReified() {
113            return reified;
114        }
115    
116        @Override
117        public int getIndex() {
118            return index;
119        }
120    
121        @NotNull
122        @Override
123        public Set<JetType> getUpperBounds() {
124            return upperBounds.invoke();
125        }
126    
127        @NotNull
128        @Override
129        public JetType getUpperBoundsAsType() {
130            return upperBoundsAsType.invoke();
131        }
132    
133        @NotNull
134        private JetType computeUpperBoundsAsType() {
135            Set<JetType> upperBounds = getUpperBounds();
136            assert !upperBounds.isEmpty() : "Upper bound list is empty in " + getName();
137            JetType upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.DEFAULT, upperBounds);
138            return upperBoundsAsType != null ? upperBoundsAsType : KotlinBuiltIns.getInstance().getNothingType();
139        }
140    
141        @NotNull
142        @Override
143        public TypeConstructor getTypeConstructor() {
144            return typeConstructor.invoke();
145        }
146    
147        @NotNull
148        @Override
149        public JetType getDefaultType() {
150            return defaultType.invoke();
151        }
152    
153        @Override
154        public JetType getClassObjectType() {
155            // TODO: class object bounds
156            return null;
157        }
158    
159        @NotNull
160        @Override
161        public Set<JetType> getLowerBounds() {
162            return Collections.singleton(KotlinBuiltIns.getInstance().getNothingType());
163        }
164    
165        @NotNull
166        @Override
167        @Deprecated
168        public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
169            throw new UnsupportedOperationException("Don't call substitute() on type parameters");
170        }
171    
172        @Override
173        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
174            return visitor.visitTypeParameterDescriptor(this, data);
175        }
176    }