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