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.Nullable;
022    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
023    import org.jetbrains.kotlin.descriptors.*;
024    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
025    import org.jetbrains.kotlin.name.Name;
026    import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
027    import org.jetbrains.kotlin.resolve.scopes.LazyScopeAdapter;
028    import org.jetbrains.kotlin.resolve.scopes.MemberScope;
029    import org.jetbrains.kotlin.resolve.scopes.TypeIntersectionScope;
030    import org.jetbrains.kotlin.storage.NotNullLazyValue;
031    import org.jetbrains.kotlin.storage.StorageManager;
032    import org.jetbrains.kotlin.types.*;
033    
034    import java.util.Collection;
035    import java.util.Collections;
036    import java.util.List;
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<KotlinType> defaultType;
045    
046        protected AbstractTypeParameterDescriptor(
047                @NotNull final StorageManager storageManager,
048                @NotNull DeclarationDescriptor containingDeclaration,
049                @NotNull Annotations annotations,
050                @NotNull final Name name,
051                @NotNull Variance variance,
052                boolean isReified,
053                int index,
054                @NotNull SourceElement source,
055                @NotNull final SupertypeLoopChecker supertypeLoopChecker
056        ) {
057            super(containingDeclaration, annotations, name, source);
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 new TypeParameterTypeConstructor(storageManager, supertypeLoopChecker);
066                }
067            });
068            this.defaultType = storageManager.createLazyValue(new Function0<KotlinType>() {
069                @Override
070                public KotlinType invoke() {
071                    return KotlinTypeImpl.create(
072                            Annotations.Companion.getEMPTY(),
073                            getTypeConstructor(), false, Collections.<TypeProjection>emptyList(),
074                            new LazyScopeAdapter(storageManager.createLazyValue(
075                                    new Function0<MemberScope>() {
076                                        @Override
077                                        public MemberScope invoke() {
078                                            return TypeIntersectionScope.create("Scope for type parameter " + name.asString(), getUpperBounds());
079                                        }
080                                    }
081                            ))
082                    );
083                }
084            });
085        }
086    
087        protected abstract void reportSupertypeLoopError(@NotNull KotlinType type);
088    
089        @NotNull
090        protected abstract List<KotlinType> resolveUpperBounds();
091    
092        @NotNull
093        @Override
094        public Variance getVariance() {
095            return variance;
096        }
097    
098        @Override
099        public boolean isReified() {
100            return reified;
101        }
102    
103        @Override
104        public int getIndex() {
105            return index;
106        }
107    
108        @Override
109        public boolean isCapturedFromOuterDeclaration() {
110            return false;
111        }
112    
113        @NotNull
114        @Override
115        public List<KotlinType> getUpperBounds() {
116            return ((TypeParameterTypeConstructor) getTypeConstructor()).getSupertypes();
117        }
118    
119        @NotNull
120        @Override
121        public final TypeConstructor getTypeConstructor() {
122            return typeConstructor.invoke();
123        }
124    
125        @NotNull
126        @Override
127        public KotlinType getDefaultType() {
128            return defaultType.invoke();
129        }
130    
131        @NotNull
132        @Override
133        @Deprecated
134        public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
135            throw new UnsupportedOperationException("Don't call substitute() on type parameters");
136        }
137    
138        @Override
139        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
140            return visitor.visitTypeParameterDescriptor(this, data);
141        }
142    
143        private class TypeParameterTypeConstructor extends AbstractTypeConstructor {
144    
145            private final SupertypeLoopChecker supertypeLoopChecker;
146    
147            public TypeParameterTypeConstructor(@NotNull StorageManager storageManager, SupertypeLoopChecker supertypeLoopChecker) {
148                super(storageManager);
149                this.supertypeLoopChecker = supertypeLoopChecker;
150            }
151    
152            @NotNull
153            @Override
154            protected Collection<KotlinType> computeSupertypes() {
155                return resolveUpperBounds();
156            }
157    
158            @NotNull
159            @Override
160            public List<TypeParameterDescriptor> getParameters() {
161                return Collections.emptyList();
162            }
163    
164            @Override
165            public boolean isFinal() {
166                return false;
167            }
168    
169            @Override
170            public boolean isDenotable() {
171                return true;
172            }
173    
174            @NotNull
175            @Override
176            public ClassifierDescriptor getDeclarationDescriptor() {
177                return AbstractTypeParameterDescriptor.this;
178            }
179    
180            @NotNull
181            @Override
182            public Annotations getAnnotations() {
183                return AbstractTypeParameterDescriptor.this.getAnnotations();
184            }
185    
186            @NotNull
187            @Override
188            public KotlinBuiltIns getBuiltIns() {
189                return DescriptorUtilsKt.getBuiltIns(AbstractTypeParameterDescriptor.this);
190            }
191    
192            @Override
193            public String toString() {
194                return getName().toString();
195            }
196    
197            @NotNull
198            @Override
199            protected SupertypeLoopChecker getSupertypeLoopChecker() {
200                return supertypeLoopChecker;
201            }
202    
203            @Override
204            protected void reportSupertypeLoopError(@NotNull KotlinType type) {
205                AbstractTypeParameterDescriptor.this.reportSupertypeLoopError(type);
206            }
207    
208            @Nullable
209            @Override
210            protected KotlinType defaultSupertypeIfEmpty() {
211                return ErrorUtils.createErrorType("Cyclic upper bounds");
212            }
213        }
214    }