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